From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current daifmt setting method in simple-card driver is placed to many places, and using un-readable/confusable method. This patch adds new asoc_simple_card_parse_daifmt() and tidyup code.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- This patch is based on mark/topic/simple
sound/soc/generic/simple-card.c | 140 +++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 72 deletions(-)
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index a887707..bca379c 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -173,6 +173,55 @@ asoc_simple_card_sub_parse_of(struct device_node *np, return 0; }
+static int asoc_simple_card_parse_daifmt(struct device_node *node, + struct simple_card_data *priv, + struct device_node *cpu, + struct device_node *codec, + char *prefix, int idx) +{ + struct device *dev = simple_priv_to_dev(priv); + struct device_node *bitclkmaster = NULL; + struct device_node *framemaster = NULL; + struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx); + struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai; + struct asoc_simple_dai *codec_dai = &dai_props->codec_dai; + unsigned int daifmt; + + daifmt = snd_soc_of_parse_daifmt(node, prefix, + &bitclkmaster, &framemaster); + daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK; + + if (strlen(prefix) && !bitclkmaster && !framemaster) { + /* + * No dai-link level and master setting was not found from + * sound node level, revert back to legacy DT parsing and + * take the settings from codec node. + */ + dev_dbg(dev, "Revert to legacy daifmt parsing\n"); + + cpu_dai->fmt = codec_dai->fmt = + snd_soc_of_parse_daifmt(codec, NULL, NULL, NULL) | + (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK); + } else { + if (codec == bitclkmaster) + daifmt |= (codec == framemaster) ? + SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS; + else + daifmt |= (codec == framemaster) ? + SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS; + + cpu_dai->fmt = daifmt; + codec_dai->fmt = daifmt; + } + + if (bitclkmaster) + of_node_put(bitclkmaster); + if (framemaster) + of_node_put(framemaster); + + return 0; +} + static int asoc_simple_card_dai_link_of(struct device_node *node, struct simple_card_data *priv, int idx, @@ -181,10 +230,8 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, struct device *dev = simple_priv_to_dev(priv); struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx); struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx); - struct device_node *np = NULL; - struct device_node *bitclkmaster = NULL; - struct device_node *framemaster = NULL; - unsigned int daifmt; + struct device_node *cpu = NULL; + struct device_node *codec = NULL; char *name; char prop[128]; char *prefix = ""; @@ -194,85 +241,36 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, if (is_top_level_node) prefix = "simple-audio-card,";
- daifmt = snd_soc_of_parse_daifmt(node, prefix, - &bitclkmaster, &framemaster); - daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK; - snprintf(prop, sizeof(prop), "%scpu", prefix); - np = of_get_child_by_name(node, prop); - if (!np) { + cpu = of_get_child_by_name(node, prop); + + snprintf(prop, sizeof(prop), "%scodec", prefix); + codec = of_get_child_by_name(node, prop); + + if (!cpu || !codec) { ret = -EINVAL; dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop); goto dai_link_of_err; }
- ret = asoc_simple_card_sub_parse_of(np, &dai_props->cpu_dai, + ret = asoc_simple_card_parse_daifmt(node, priv, + cpu, codec, prefix, idx); + if (ret < 0) + goto dai_link_of_err; + + ret = asoc_simple_card_sub_parse_of(cpu, &dai_props->cpu_dai, &dai_link->cpu_of_node, &dai_link->cpu_dai_name, &cpu_args); if (ret < 0) goto dai_link_of_err;
- dai_props->cpu_dai.fmt = daifmt; - switch (((np == bitclkmaster) << 4) | (np == framemaster)) { - case 0x11: - dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBS_CFS; - break; - case 0x10: - dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBS_CFM; - break; - case 0x01: - dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBM_CFS; - break; - default: - dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBM_CFM; - break; - } - - of_node_put(np); - snprintf(prop, sizeof(prop), "%scodec", prefix); - np = of_get_child_by_name(node, prop); - if (!np) { - ret = -EINVAL; - dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop); - goto dai_link_of_err; - } - - ret = asoc_simple_card_sub_parse_of(np, &dai_props->codec_dai, + ret = asoc_simple_card_sub_parse_of(codec, &dai_props->codec_dai, &dai_link->codec_of_node, &dai_link->codec_dai_name, NULL); if (ret < 0) goto dai_link_of_err;
- if (strlen(prefix) && !bitclkmaster && !framemaster) { - /* - * No DAI link level and master setting was found - * from sound node level, revert back to legacy DT - * parsing and take the settings from codec node. - */ - dev_dbg(dev, "%s: Revert to legacy daifmt parsing\n", - __func__); - dai_props->cpu_dai.fmt = dai_props->codec_dai.fmt = - snd_soc_of_parse_daifmt(np, NULL, NULL, NULL) | - (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK); - } else { - dai_props->codec_dai.fmt = daifmt; - switch (((np == bitclkmaster) << 4) | (np == framemaster)) { - case 0x11: - dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBM_CFM; - break; - case 0x10: - dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBM_CFS; - break; - case 0x01: - dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBS_CFM; - break; - default: - dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBS_CFS; - break; - } - } - if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) { ret = -EINVAL; goto dai_link_of_err; @@ -315,12 +313,10 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, dai_link->cpu_dai_name = NULL;
dai_link_of_err: - if (np) - of_node_put(np); - if (bitclkmaster) - of_node_put(bitclkmaster); - if (framemaster) - of_node_put(framemaster); + if (cpu) + of_node_put(cpu); + if (codec) + of_node_put(codec); return ret; }