OSDN Git Service

ASoC: fsl-asoc-card: Support configuring dai fmt from DT
authorShengjiu Wang <shengjiu.wang@nxp.com>
Tue, 21 Jul 2020 03:41:49 +0000 (11:41 +0800)
committerMark Brown <broonie@kernel.org>
Thu, 23 Jul 2020 18:52:27 +0000 (19:52 +0100)
Support same propeties as simple card for configuring fmt
from DT.
In order to make this change compatible with old DT, these
properties are optional.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Link: https://lore.kernel.org/r/1595302910-19688-1-git-send-email-shengjiu.wang@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/fsl/fsl-asoc-card.c

index ee80d02..4848ba6 100644 (file)
@@ -531,11 +531,14 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
        struct device_node *cpu_np, *codec_np, *asrc_np;
        struct device_node *np = pdev->dev.of_node;
        struct platform_device *asrc_pdev = NULL;
+       struct device_node *bitclkmaster = NULL;
+       struct device_node *framemaster = NULL;
        struct platform_device *cpu_pdev;
        struct fsl_asoc_card_priv *priv;
        struct device *codec_dev = NULL;
        const char *codec_dai_name;
        const char *codec_dev_name;
+       unsigned int daifmt;
        u32 width;
        int ret;
 
@@ -667,6 +670,31 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
                goto asrc_fail;
        }
 
+       /* Format info from DT is optional. */
+       daifmt = snd_soc_of_parse_daifmt(np, NULL,
+                                        &bitclkmaster, &framemaster);
+       daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
+       if (bitclkmaster || framemaster) {
+               if (codec_np == bitclkmaster)
+                       daifmt |= (codec_np == framemaster) ?
+                               SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
+               else
+                       daifmt |= (codec_np == framemaster) ?
+                               SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
+
+               /* Override dai_fmt with value from DT */
+               priv->dai_fmt = daifmt;
+       }
+
+       /* Change direction according to format */
+       if (priv->dai_fmt & SND_SOC_DAIFMT_CBM_CFM) {
+               priv->cpu_priv.sysclk_dir[TX] = SND_SOC_CLOCK_IN;
+               priv->cpu_priv.sysclk_dir[RX] = SND_SOC_CLOCK_IN;
+       }
+
+       of_node_put(bitclkmaster);
+       of_node_put(framemaster);
+
        if (!fsl_asoc_card_is_ac97(priv) && !codec_dev) {
                dev_err(&pdev->dev, "failed to find codec device\n");
                ret = -EPROBE_DEFER;