[PATCH 1/2] ASoC: bindings: fsl-asoc-card: Add compatible string for MQS

Subsystems: open firmware and flattened device tree bindings, sound - soc layer / dynamic audio power management (asoc), the rest

STALE2241d

4 messages, 3 authors, 2020-06-17 · open the first message on its own page

[PATCH 1/2] ASoC: bindings: fsl-asoc-card: Add compatible string for MQS

From: Shengjiu Wang <hidden>
Date: 2020-06-16 07:41:51

Add compatible string "fsl,imx-audio-mqs" for MQS

Signed-off-by: Shengjiu Wang <redacted>
---
 Documentation/devicetree/bindings/sound/fsl-asoc-card.txt | 2 ++
 1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
index c60a5732d29c..6417c5dffa9a 100644
--- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
@@ -34,6 +34,8 @@ The compatible list for this generic sound card currently:
 
  "fsl,imx-audio-wm8960"
 
+ "fsl,imx-audio-mqs"
+
 Required properties:
 
   - compatible		: Contains one of entries in the compatible list.
-- 
2.21.0

[PATCH 2/2] ASoC: fsl-asoc-card: Add MQS support

From: Shengjiu Wang <hidden>
Date: 2020-06-16 07:41:56

The MQS codec isn't an i2c device, so add a new platform device for it.

MQS only support playback, so add a new audio map.

Add there maybe "model" property or no "audio-routing" property in
devicetree, so add some enhancement for these two property.

Signed-off-by: Shengjiu Wang <redacted>
---
 sound/soc/fsl/fsl-asoc-card.c | 70 ++++++++++++++++++++++++++---------
 1 file changed, 52 insertions(+), 18 deletions(-)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 00be73900888..2ac8cb9ddd10 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -119,6 +119,13 @@ static const struct snd_soc_dapm_route audio_map_ac97[] = {
 	{"ASRC-Capture",  NULL, "AC97 Capture"},
 };
 
+static const struct snd_soc_dapm_route audio_map_tx[] = {
+	/* 1st half -- Normal DAPM routes */
+	{"Playback",  NULL, "CPU-Playback"},
+	/* 2nd half -- ASRC DAPM routes */
+	{"CPU-Playback",  NULL, "ASRC-Playback"},
+};
+
 /* Add all possible widgets into here without being redundant */
 static const struct snd_soc_dapm_widget fsl_asoc_card_dapm_widgets[] = {
 	SND_SOC_DAPM_LINE("Line Out Jack", NULL),
@@ -482,6 +489,7 @@ 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 *codec_pdev = NULL; /* used for non i2c device*/
 	struct platform_device *asrc_pdev = NULL;
 	struct platform_device *cpu_pdev;
 	struct fsl_asoc_card_priv *priv;
@@ -512,10 +520,13 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 	}
 
 	codec_np = of_parse_phandle(np, "audio-codec", 0);
-	if (codec_np)
+	if (codec_np) {
 		codec_dev = of_find_i2c_device_by_node(codec_np);
-	else
+		if (!codec_dev)
+			codec_pdev = of_find_device_by_node(codec_np);
+	} else {
 		codec_dev = NULL;
+	}
 
 	asrc_np = of_parse_phandle(np, "audio-asrc", 0);
 	if (asrc_np)
@@ -525,6 +536,13 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 	if (codec_dev) {
 		struct clk *codec_clk = clk_get(&codec_dev->dev, NULL);
 
+		if (!IS_ERR(codec_clk)) {
+			priv->codec_priv.mclk_freq = clk_get_rate(codec_clk);
+			clk_put(codec_clk);
+		}
+	} else if (codec_pdev) {
+		struct clk *codec_clk = clk_get(&codec_pdev->dev, NULL);
+
 		if (!IS_ERR(codec_clk)) {
 			priv->codec_priv.mclk_freq = clk_get_rate(codec_clk);
 			clk_put(codec_clk);
@@ -538,6 +556,11 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 	/* Assign a default DAI format, and allow each card to overwrite it */
 	priv->dai_fmt = DAI_FMT_BASE;
 
+	memcpy(priv->dai_link, fsl_asoc_card_dai,
+	       sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link));
+
+	priv->card.dapm_routes = audio_map;
+	priv->card.num_dapm_routes = ARRAY_SIZE(audio_map);
 	/* Diversify the card configurations */
 	if (of_device_is_compatible(np, "fsl,imx-audio-cs42888")) {
 		codec_dai_name = "cs42888";
@@ -573,13 +596,25 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 		codec_dai_name = "ac97-hifi";
 		priv->card.set_bias_level = NULL;
 		priv->dai_fmt = SND_SOC_DAIFMT_AC97;
+		priv->card.dapm_routes = audio_map_ac97;
+		priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_ac97);
+	} else if (of_device_is_compatible(np, "fsl,imx-audio-mqs")) {
+		codec_dai_name = "fsl-mqs-dai";
+		priv->card.set_bias_level = NULL;
+		priv->dai_fmt = SND_SOC_DAIFMT_LEFT_J |
+				SND_SOC_DAIFMT_CBS_CFS |
+				SND_SOC_DAIFMT_NB_NF;
+		priv->dai_link[1].dpcm_playback = 1;
+		priv->dai_link[2].dpcm_playback = 1;
+		priv->card.dapm_routes = audio_map_tx;
+		priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_tx);
 	} else {
 		dev_err(&pdev->dev, "unknown Device Tree compatible\n");
 		ret = -EINVAL;
 		goto asrc_fail;
 	}
 
-	if (!fsl_asoc_card_is_ac97(priv) && !codec_dev) {
+	if (!fsl_asoc_card_is_ac97(priv) && !codec_dev && !codec_pdev) {
 		dev_err(&pdev->dev, "failed to find codec device\n");
 		ret = -EPROBE_DEFER;
 		goto asrc_fail;
@@ -601,19 +636,18 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 		priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
 	}
 
-	snprintf(priv->name, sizeof(priv->name), "%s-audio",
-		 fsl_asoc_card_is_ac97(priv) ? "ac97" :
-		 codec_dev->name);
-
 	/* Initialize sound card */
 	priv->pdev = pdev;
 	priv->card.dev = &pdev->dev;
-	priv->card.name = priv->name;
+	ret = snd_soc_of_parse_card_name(&priv->card, "model");
+	if (ret) {
+		snprintf(priv->name, sizeof(priv->name), "%s-audio",
+			 fsl_asoc_card_is_ac97(priv) ? "ac97" :
+			 (codec_dev ? codec_dev->name : codec_pdev->name));
+		priv->card.name = priv->name;
+	}
 	priv->card.dai_link = priv->dai_link;
-	priv->card.dapm_routes = fsl_asoc_card_is_ac97(priv) ?
-				 audio_map_ac97 : audio_map;
 	priv->card.late_probe = fsl_asoc_card_late_probe;
-	priv->card.num_dapm_routes = ARRAY_SIZE(audio_map);
 	priv->card.dapm_widgets = fsl_asoc_card_dapm_widgets;
 	priv->card.num_dapm_widgets = ARRAY_SIZE(fsl_asoc_card_dapm_widgets);
 
@@ -621,13 +655,12 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 	if (!asrc_pdev)
 		priv->card.num_dapm_routes /= 2;
 
-	memcpy(priv->dai_link, fsl_asoc_card_dai,
-	       sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link));
-
-	ret = snd_soc_of_parse_audio_routing(&priv->card, "audio-routing");
-	if (ret) {
-		dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret);
-		goto asrc_fail;
+	if (of_property_read_bool(np, "audio-routing")) {
+		ret = snd_soc_of_parse_audio_routing(&priv->card, "audio-routing");
+		if (ret) {
+			dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret);
+			goto asrc_fail;
+		}
 	}
 
 	/* Normal DAI Link */
@@ -724,6 +757,7 @@ static const struct of_device_id fsl_asoc_card_dt_ids[] = {
 	{ .compatible = "fsl,imx-audio-sgtl5000", },
 	{ .compatible = "fsl,imx-audio-wm8962", },
 	{ .compatible = "fsl,imx-audio-wm8960", },
+	{ .compatible = "fsl,imx-audio-mqs", },
 	{}
 };
 MODULE_DEVICE_TABLE(of, fsl_asoc_card_dt_ids);
-- 
2.21.0

Re: [PATCH 2/2] ASoC: fsl-asoc-card: Add MQS support

From: Nicolin Chen <nicoleotsuka@gmail.com>
Date: 2020-06-17 00:49:07

On Tue, Jun 16, 2020 at 03:30:37PM +0800, Shengjiu Wang wrote:
The MQS codec isn't an i2c device, so add a new platform device for it.

MQS only support playback, so add a new audio map.

Add there maybe "model" property or no "audio-routing" property insertions
"Add" => "And"
quoted hunk
devicetree, so add some enhancement for these two property.

Signed-off-by: Shengjiu Wang <redacted>
---
 sound/soc/fsl/fsl-asoc-card.c | 70 ++++++++++++++++++++++++++---------
 1 file changed, 52 insertions(+), 18 deletions(-)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 00be73900888..2ac8cb9ddd10 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
quoted hunk
@@ -482,6 +489,7 @@ 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 *codec_pdev = NULL; /* used for non i2c device*/
Having both codec_pdev and codec_dev duplicates things. Actually
only a couple of places really need "codec_dev" -- most of them
need codec_dev->dev pointer instead. So we could have a cleanup:

-	struct i2c_client *codec_dev;
+	struct device *codec_dev = NULL;
quoted hunk
@@ -512,10 +520,13 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 	}
 
 	codec_np = of_parse_phandle(np, "audio-codec", 0);
-	if (codec_np)
+	if (codec_np) {
 		codec_dev = of_find_i2c_device_by_node(codec_np);
-	else
+		if (!codec_dev)
+			codec_pdev = of_find_device_by_node(codec_np);
+	} else {
 		codec_dev = NULL;
+	}
Here can have something like (feel free to simplify):

	if (codec_np) {
		struct platform_device *codec_pdev;
		struct i2c_client *codec_i2c;

		codec_i2c = of_find_i2c_device_by_node(codec_np);
		if (codec_i2c)
			codec_dev = &codec_i2c->dev;

		if (!codec_dev) {
			codec_pdev = of_find_device_by_node(codec_np);
			codec_dev = &codec_pdev->dev;
		}
	}
quoted hunk
 	asrc_np = of_parse_phandle(np, "audio-asrc", 0);
 	if (asrc_np)
@@ -525,6 +536,13 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 	if (codec_dev) {
 		struct clk *codec_clk = clk_get(&codec_dev->dev, NULL);
Then here:

-  		struct clk *codec_clk = clk_get(&codec_dev->dev, NULL);
+  		struct clk *codec_clk = clk_get(codec_dev, NULL);
quoted hunk
@@ -538,6 +556,11 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 	/* Assign a default DAI format, and allow each card to overwrite it */
 	priv->dai_fmt = DAI_FMT_BASE;
 
+	memcpy(priv->dai_link, fsl_asoc_card_dai,
+	       sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link));
quoted hunk
@@ -573,13 +596,25 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 		codec_dai_name = "ac97-hifi";
 		priv->card.set_bias_level = NULL;
 		priv->dai_fmt = SND_SOC_DAIFMT_AC97;
+		priv->card.dapm_routes = audio_map_ac97;
+		priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_ac97);
+	} else if (of_device_is_compatible(np, "fsl,imx-audio-mqs")) {
+		codec_dai_name = "fsl-mqs-dai";
+		priv->card.set_bias_level = NULL;
+		priv->dai_fmt = SND_SOC_DAIFMT_LEFT_J |
+				SND_SOC_DAIFMT_CBS_CFS |
+				SND_SOC_DAIFMT_NB_NF;
+		priv->dai_link[1].dpcm_playback = 1;
+		priv->dai_link[2].dpcm_playback = 1;
dpcm_playback = 1? That's the default value in fsl_asoc_card_dai.
quoted hunk
@@ -601,19 +636,18 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 		priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
 	}
 
-	snprintf(priv->name, sizeof(priv->name), "%s-audio",
-		 fsl_asoc_card_is_ac97(priv) ? "ac97" :
-		 codec_dev->name);
-
 	/* Initialize sound card */
 	priv->pdev = pdev;
 	priv->card.dev = &pdev->dev;
-	priv->card.name = priv->name;
+	ret = snd_soc_of_parse_card_name(&priv->card, "model");
+	if (ret) {
+		snprintf(priv->name, sizeof(priv->name), "%s-audio",
+			 fsl_asoc_card_is_ac97(priv) ? "ac97" :
+			 (codec_dev ? codec_dev->name : codec_pdev->name));
We can just use dev_name() if codec_dev is struct device *
Or having a codec_dev_name to cache codec_pdev/i2c->name.
-	ret = snd_soc_of_parse_audio_routing(&priv->card, "audio-routing");
-	if (ret) {
-		dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret);
-		goto asrc_fail;
+	if (of_property_read_bool(np, "audio-routing")) {
+		ret = snd_soc_of_parse_audio_routing(&priv->card, "audio-routing");
+		if (ret) {
+			dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret);
+			goto asrc_fail;
Hmm...audio-routing is a required property in DT binding doc.
So you might need to update that too.

Re: [PATCH 2/2] ASoC: fsl-asoc-card: Add MQS support

From: Shengjiu Wang <shengjiu.wang@gmail.com>
Date: 2020-06-17 03:32:13

On Wed, Jun 17, 2020 at 8:50 AM Nicolin Chen [off-list ref] wrote:
On Tue, Jun 16, 2020 at 03:30:37PM +0800, Shengjiu Wang wrote:
quoted
The MQS codec isn't an i2c device, so add a new platform device for it.

MQS only support playback, so add a new audio map.

Add there maybe "model" property or no "audio-routing" property insertions
"Add" => "And"
quoted
devicetree, so add some enhancement for these two property.

Signed-off-by: Shengjiu Wang <redacted>
---
 sound/soc/fsl/fsl-asoc-card.c | 70 ++++++++++++++++++++++++++---------
 1 file changed, 52 insertions(+), 18 deletions(-)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 00be73900888..2ac8cb9ddd10 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
quoted
@@ -482,6 +489,7 @@ 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 *codec_pdev = NULL; /* used for non i2c device*/
Having both codec_pdev and codec_dev duplicates things. Actually
only a couple of places really need "codec_dev" -- most of them
need codec_dev->dev pointer instead. So we could have a cleanup:

-       struct i2c_client *codec_dev;
+       struct device *codec_dev = NULL;
quoted
@@ -512,10 +520,13 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
      }

      codec_np = of_parse_phandle(np, "audio-codec", 0);
-     if (codec_np)
+     if (codec_np) {
              codec_dev = of_find_i2c_device_by_node(codec_np);
-     else
+             if (!codec_dev)
+                     codec_pdev = of_find_device_by_node(codec_np);
+     } else {
              codec_dev = NULL;
+     }
Here can have something like (feel free to simplify):

        if (codec_np) {
                struct platform_device *codec_pdev;
                struct i2c_client *codec_i2c;

                codec_i2c = of_find_i2c_device_by_node(codec_np);
                if (codec_i2c)
                        codec_dev = &codec_i2c->dev;

                if (!codec_dev) {
                        codec_pdev = of_find_device_by_node(codec_np);
                        codec_dev = &codec_pdev->dev;
                }
        }
quoted
      asrc_np = of_parse_phandle(np, "audio-asrc", 0);
      if (asrc_np)
@@ -525,6 +536,13 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
      if (codec_dev) {
              struct clk *codec_clk = clk_get(&codec_dev->dev, NULL);
Then here:

-               struct clk *codec_clk = clk_get(&codec_dev->dev, NULL);
+               struct clk *codec_clk = clk_get(codec_dev, NULL);
quoted
@@ -538,6 +556,11 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
      /* Assign a default DAI format, and allow each card to overwrite it */
      priv->dai_fmt = DAI_FMT_BASE;

+     memcpy(priv->dai_link, fsl_asoc_card_dai,
+            sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link));
quoted
@@ -573,13 +596,25 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
              codec_dai_name = "ac97-hifi";
              priv->card.set_bias_level = NULL;
              priv->dai_fmt = SND_SOC_DAIFMT_AC97;
+             priv->card.dapm_routes = audio_map_ac97;
+             priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_ac97);
+     } else if (of_device_is_compatible(np, "fsl,imx-audio-mqs")) {
+             codec_dai_name = "fsl-mqs-dai";
+             priv->card.set_bias_level = NULL;
+             priv->dai_fmt = SND_SOC_DAIFMT_LEFT_J |
+                             SND_SOC_DAIFMT_CBS_CFS |
+                             SND_SOC_DAIFMT_NB_NF;
+             priv->dai_link[1].dpcm_playback = 1;
+             priv->dai_link[2].dpcm_playback = 1;
dpcm_playback = 1? That's the default value in fsl_asoc_card_dai.
ah,  should be dpcm_capture = 0.
quoted
@@ -601,19 +636,18 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
              priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
      }

-     snprintf(priv->name, sizeof(priv->name), "%s-audio",
-              fsl_asoc_card_is_ac97(priv) ? "ac97" :
-              codec_dev->name);
-
      /* Initialize sound card */
      priv->pdev = pdev;
      priv->card.dev = &pdev->dev;
-     priv->card.name = priv->name;
+     ret = snd_soc_of_parse_card_name(&priv->card, "model");
+     if (ret) {
+             snprintf(priv->name, sizeof(priv->name), "%s-audio",
+                      fsl_asoc_card_is_ac97(priv) ? "ac97" :
+                      (codec_dev ? codec_dev->name : codec_pdev->name));
We can just use dev_name() if codec_dev is struct device *
Or having a codec_dev_name to cache codec_pdev/i2c->name.
quoted
-     ret = snd_soc_of_parse_audio_routing(&priv->card, "audio-routing");
-     if (ret) {
-             dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret);
-             goto asrc_fail;
+     if (of_property_read_bool(np, "audio-routing")) {
+             ret = snd_soc_of_parse_audio_routing(&priv->card, "audio-routing");
+             if (ret) {
+                     dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret);
+                     goto asrc_fail;
Hmm...audio-routing is a required property in DT binding doc.
So you might need to update that too.
will update them in v2.

best regards
wang shengjiu
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help