[PATCH 2/2] ASoC: fsl-asoc-card: add support for generic I2S slave use-case

Arnaud Ferraris arnaud.ferraris at collabora.com
Fri Jul 3 00:11:15 AEST 2020


This commit implements support for generic codecs with the SoC acting as
I2S slave, by implementing the new `fsl,imx-audio-i2s-slave` compatible
and related properties.

This is particularly useful when using a Bluetooth controller acting as
I2S master, but other simple or dummy codecs might benefit from it too.

Signed-off-by: Arnaud Ferraris <arnaud.ferraris at collabora.com>
---
 sound/soc/fsl/fsl-asoc-card.c | 46 ++++++++++++++++++++++++++---------
 1 file changed, 35 insertions(+), 11 deletions(-)

diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 57ea1b072326..6076b963c873 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -166,12 +166,15 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream,
 		return 0;
 
 	/* Specific configurations of DAIs starts from here */
-	ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), cpu_priv->sysclk_id[tx],
-				     cpu_priv->sysclk_freq[tx],
-				     cpu_priv->sysclk_dir[tx]);
-	if (ret && ret != -ENOTSUPP) {
-		dev_err(dev, "failed to set sysclk for cpu dai\n");
-		return ret;
+	if (cpu_priv->sysclk_freq[tx] > 0) {
+		ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0),
+					     cpu_priv->sysclk_id[tx],
+					     cpu_priv->sysclk_freq[tx],
+					     cpu_priv->sysclk_dir[tx]);
+		if (ret && ret != -ENOTSUPP) {
+			dev_err(dev, "failed to set sysclk for cpu dai\n");
+			return ret;
+		}
 	}
 
 	if (cpu_priv->slot_width) {
@@ -475,11 +478,14 @@ static int fsl_asoc_card_late_probe(struct snd_soc_card *card)
 		return 0;
 	}
 
-	ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->mclk_id,
-				     codec_priv->mclk_freq, SND_SOC_CLOCK_IN);
-	if (ret && ret != -ENOTSUPP) {
-		dev_err(dev, "failed to set sysclk in %s\n", __func__);
-		return ret;
+	if (codec_priv->mclk_freq > 0) {
+		ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->mclk_id,
+					     codec_priv->mclk_freq,
+					     SND_SOC_CLOCK_IN);
+		if (ret && ret != -ENOTSUPP) {
+			dev_err(dev, "failed to set sysclk in %s\n", __func__);
+			return ret;
+		}
 	}
 
 	return 0;
@@ -620,6 +626,23 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 		priv->cpu_priv.slot_width = 32;
 		priv->card.dapm_routes = audio_map_tx;
 		priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_tx);
+	} else if (of_device_is_compatible(np, "fsl,imx-audio-i2s-slave")) {
+		ret = of_property_read_string(np, "audio-codec-dai-name",
+					      &codec_dai_name);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to get codec DAI name\n");
+			ret = -EINVAL;
+			goto asrc_fail;
+		}
+		ret = of_property_read_u32(np, "audio-slot-width",
+					   &priv->cpu_priv.slot_width);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to get slot width\n");
+			ret = -EINVAL;
+			goto asrc_fail;
+		}
+		priv->card.set_bias_level = NULL;
+		priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
 	} else {
 		dev_err(&pdev->dev, "unknown Device Tree compatible\n");
 		ret = -EINVAL;
@@ -763,6 +786,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 
 static const struct of_device_id fsl_asoc_card_dt_ids[] = {
 	{ .compatible = "fsl,imx-audio-ac97", },
+	{ .compatible = "fsl,imx-audio-i2s-slave", },
 	{ .compatible = "fsl,imx-audio-cs42888", },
 	{ .compatible = "fsl,imx-audio-cs427x", },
 	{ .compatible = "fsl,imx-audio-sgtl5000", },
-- 
2.27.0



More information about the Linuxppc-dev mailing list