All of lore.kernel.org
 help / color / mirror / Atom feed
* Applied "ASoC: fsl-asoc-card: add AC'97 support" to the asoc tree
@ 2015-09-16 20:01 Mark Brown
  2015-09-17  7:41 ` Nicolin Chen
  0 siblings, 1 reply; 6+ messages in thread
From: Mark Brown @ 2015-09-16 20:01 UTC (permalink / raw)
  To: Maciej Szmigiero, Mark Brown; +Cc: alsa-devel

The patch

   ASoC: fsl-asoc-card: add AC'97 support

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From e06b508481e1916b25038289b945104009d774c9 Mon Sep 17 00:00:00 2001
From: "Maciej S. Szmigiero" <mail@maciej.szmigiero.name>
Date: Mon, 31 Aug 2015 17:11:35 +0200
Subject: [PATCH] ASoC: fsl-asoc-card: add AC'97 support

Add AC'97 support to fsl-asoc-card using generic
ASoC AC'97 CODEC.

The SSI controller will silently enable any TX
AC'97 slots that have their bits set in SLOTREQ
received from CODEC and then will redirect some
of playback samples there.

That's why it is important to make sure that
any of CODEC playback slots that can pull samples
are set to slots 3/4 (standard PCM playback slots).
Currently, this applies to S/PDIF slots as they
were seen to pull samples sometimes even with
S/PDIF output being disabled.

Signed-off-by: Maciej Szmigiero <mail@maciej.szmigiero.name>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 .../devicetree/bindings/sound/fsl-asoc-card.txt    |  10 +-
 sound/soc/fsl/fsl-asoc-card.c                      | 145 ++++++++++++++++-----
 2 files changed, 120 insertions(+), 35 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
index a96774c..ce55c0a 100644
--- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
@@ -13,13 +13,15 @@ So having this generic sound card allows all Freescale SoC users to benefit
 from the simplification of a new card support and the capability of the wide
 sample rates support through ASRC.
 
-Note: The card is initially designed for those sound cards who use I2S and
-      PCM DAI formats. However, it'll be also possible to support those non
-      I2S/PCM type sound cards, such as S/PDIF audio and HDMI audio, as long
-      as the driver has been properly upgraded.
+Note: The card is initially designed for those sound cards who use AC'97, I2S
+      and PCM DAI formats. However, it'll be also possible to support those non
+      AC'97/I2S/PCM type sound cards, such as S/PDIF audio and HDMI audio, as
+      long as the driver has been properly upgraded.
 
 
 The compatible list for this generic sound card currently:
+ "fsl,imx-audio-ac97"
+
  "fsl,imx-audio-cs42888"
 
  "fsl,imx-audio-wm8962"
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 5aeb6ed..86aa498 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -14,6 +14,9 @@
 #include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/of_platform.h>
+#if IS_ENABLED(CONFIG_SND_AC97_CODEC)
+#include <sound/ac97_codec.h>
+#endif
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 
@@ -115,6 +118,11 @@ static const struct snd_soc_dapm_widget fsl_asoc_card_dapm_widgets[] = {
 	SND_SOC_DAPM_MIC("DMIC", NULL),
 };
 
+static bool fsl_asoc_card_is_ac97(struct fsl_asoc_card_priv *priv)
+{
+	return priv->dai_fmt == SND_SOC_DAIFMT_AC97;
+}
+
 static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream,
 				   struct snd_pcm_hw_params *params)
 {
@@ -133,7 +141,9 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream,
 	 * set_bias_level(), bypass the remaining settings in hw_params().
 	 * Note: (dai_fmt & CBM_CFM) includes CBM_CFM and CBM_CFS.
 	 */
-	if (priv->card.set_bias_level && priv->dai_fmt & SND_SOC_DAIFMT_CBM_CFM)
+	if ((priv->card.set_bias_level &&
+	     priv->dai_fmt & SND_SOC_DAIFMT_CBM_CFM) ||
+	    fsl_asoc_card_is_ac97(priv))
 		return 0;
 
 	/* Specific configurations of DAIs starts from here */
@@ -300,7 +310,7 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
 	ext_port--;
 
 	/*
-	 * Use asynchronous mode (6 wires) for all cases.
+	 * Use asynchronous mode (6 wires) for all cases except AC97.
 	 * If only 4 wires are needed, just set SSI into
 	 * synchronous mode and enable 4 PADs in IOMUX.
 	 */
@@ -346,15 +356,30 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
 			   IMX_AUDMUX_V2_PTCR_TCLKDIR;
 		break;
 	default:
-		return -EINVAL;
+		if (!fsl_asoc_card_is_ac97(priv))
+			return -EINVAL;
+	}
+
+	if (fsl_asoc_card_is_ac97(priv)) {
+		int_ptcr = IMX_AUDMUX_V2_PTCR_SYN |
+			   IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) |
+			   IMX_AUDMUX_V2_PTCR_TCLKDIR;
+		ext_ptcr = IMX_AUDMUX_V2_PTCR_SYN |
+			   IMX_AUDMUX_V2_PTCR_TFSEL(int_port) |
+			   IMX_AUDMUX_V2_PTCR_TFSDIR;
 	}
 
 	/* Asynchronous mode can not be set along with RCLKDIR */
-	ret = imx_audmux_v2_configure_port(int_port, 0,
-					   IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port));
-	if (ret) {
-		dev_err(dev, "audmux internal port setup failed\n");
-		return ret;
+	if (!fsl_asoc_card_is_ac97(priv)) {
+		unsigned int pdcr =
+				IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port);
+
+		ret = imx_audmux_v2_configure_port(int_port, 0,
+						   pdcr);
+		if (ret) {
+			dev_err(dev, "audmux internal port setup failed\n");
+			return ret;
+		}
 	}
 
 	ret = imx_audmux_v2_configure_port(int_port, int_ptcr,
@@ -364,11 +389,16 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
 		return ret;
 	}
 
-	ret = imx_audmux_v2_configure_port(ext_port, 0,
-					   IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
-	if (ret) {
-		dev_err(dev, "audmux external port setup failed\n");
-		return ret;
+	if (!fsl_asoc_card_is_ac97(priv)) {
+		unsigned int pdcr =
+				IMX_AUDMUX_V2_PDCR_RXDSEL(int_port);
+
+		ret = imx_audmux_v2_configure_port(ext_port, 0,
+						   pdcr);
+		if (ret) {
+			dev_err(dev, "audmux external port setup failed\n");
+			return ret;
+		}
 	}
 
 	ret = imx_audmux_v2_configure_port(ext_port, ext_ptcr,
@@ -389,6 +419,23 @@ static int fsl_asoc_card_late_probe(struct snd_soc_card *card)
 	struct device *dev = card->dev;
 	int ret;
 
+	if (fsl_asoc_card_is_ac97(priv)) {
+#if IS_ENABLED(CONFIG_SND_AC97_CODEC)
+		struct snd_soc_codec *codec = card->rtd[0].codec;
+		struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+
+		/*
+		 * Use slots 3/4 for S/PDIF so SSI won't try to enable
+		 * other slots and send some samples there
+		 * due to SLOTREQ bits for S/PDIF received from codec
+		 */
+		snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
+				     AC97_EA_SPSA_SLOT_MASK, AC97_EA_SPSA_3_4);
+#endif
+
+		return 0;
+	}
+
 	ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->mclk_id,
 				     codec_priv->mclk_freq, SND_SOC_CLOCK_IN);
 	if (ret) {
@@ -404,10 +451,9 @@ 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 platform_device *cpu_pdev;
+	struct platform_device *cpu_pdev, *codec_pdev;
 	struct fsl_asoc_card_priv *priv;
-	struct i2c_client *codec_dev;
-	struct clk *codec_clk;
+	struct i2c_client *codec_i2c_dev;
 	const char *codec_dai_name;
 	u32 width;
 	int ret;
@@ -420,9 +466,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 	/* Give a chance to old DT binding */
 	if (!cpu_np)
 		cpu_np = of_parse_phandle(np, "ssi-controller", 0);
-	codec_np = of_parse_phandle(np, "audio-codec", 0);
-	if (!cpu_np || !codec_np) {
-		dev_err(&pdev->dev, "phandle missing or invalid\n");
+	if (!cpu_np) {
+		dev_err(&pdev->dev, "CPU phandle missing or invalid\n");
 		ret = -EINVAL;
 		goto fail;
 	}
@@ -434,11 +479,13 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 		goto fail;
 	}
 
-	codec_dev = of_find_i2c_device_by_node(codec_np);
-	if (!codec_dev) {
-		dev_err(&pdev->dev, "failed to find codec platform device\n");
-		ret = -EINVAL;
-		goto fail;
+	codec_np = of_parse_phandle(np, "audio-codec", 0);
+	if (codec_np) {
+		codec_pdev = of_find_device_by_node(codec_np);
+		codec_i2c_dev = of_find_i2c_device_by_node(codec_np);
+	} else {
+		codec_pdev = NULL;
+		codec_i2c_dev = NULL;
 	}
 
 	asrc_np = of_parse_phandle(np, "audio-asrc", 0);
@@ -446,10 +493,13 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 		asrc_pdev = of_find_device_by_node(asrc_np);
 
 	/* Get the MCLK rate only, and leave it controlled by CODEC drivers */
-	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);
+	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);
+		}
 	}
 
 	/* Default sample rate and format, will be updated in hw_params() */
@@ -486,11 +536,21 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 		priv->codec_priv.fll_id = WM8960_SYSCLK_AUTO;
 		priv->codec_priv.pll_id = WM8960_SYSCLK_AUTO;
 		priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
+	} else if (of_device_is_compatible(np, "fsl,imx-audio-ac97")) {
+		codec_dai_name = "ac97-hifi";
+		priv->card.set_bias_level = NULL;
+		priv->dai_fmt = SND_SOC_DAIFMT_AC97;
 	} else {
 		dev_err(&pdev->dev, "unknown Device Tree compatible\n");
 		return -EINVAL;
 	}
 
+	if (!fsl_asoc_card_is_ac97(priv) && !codec_pdev) {
+		dev_err(&pdev->dev, "failed to find codec platform device\n");
+		ret = -EINVAL;
+		goto asrc_fail;
+	}
+
 	/* Common settings for corresponding Freescale CPU DAI driver */
 	if (strstr(cpu_np->name, "ssi")) {
 		/* Only SSI needs to configure AUDMUX */
@@ -507,7 +567,9 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 		priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
 	}
 
-	sprintf(priv->name, "%s-audio", codec_dev->name);
+	snprintf(priv->name, sizeof(priv->name), "%s-audio",
+		 fsl_asoc_card_is_ac97(priv) ? "ac97" :
+		 codec_i2c_dev ? codec_i2c_dev->name : codec_pdev->name);
 
 	/* Initialize sound card */
 	priv->pdev = pdev;
@@ -531,8 +593,26 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 
 	/* Normal DAI Link */
 	priv->dai_link[0].cpu_of_node = cpu_np;
-	priv->dai_link[0].codec_of_node = codec_np;
 	priv->dai_link[0].codec_dai_name = codec_dai_name;
+
+	if (!fsl_asoc_card_is_ac97(priv))
+		priv->dai_link[0].codec_of_node = codec_np;
+	else {
+		u32 idx;
+
+		ret = of_property_read_u32(cpu_np, "cell-index", &idx);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"cannot get CPU index property\n");
+			goto asrc_fail;
+		}
+
+		priv->dai_link[0].codec_name =
+				devm_kasprintf(&pdev->dev, GFP_KERNEL,
+					       "ac97-codec.%u",
+					       (unsigned int)idx);
+	}
+
 	priv->dai_link[0].platform_of_node = cpu_np;
 	priv->dai_link[0].dai_fmt = priv->dai_fmt;
 	priv->card.num_links = 1;
@@ -543,6 +623,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 		priv->dai_link[1].platform_of_node = asrc_np;
 		priv->dai_link[2].codec_dai_name = codec_dai_name;
 		priv->dai_link[2].codec_of_node = codec_np;
+		priv->dai_link[2].codec_name =
+				priv->dai_link[0].codec_name;
 		priv->dai_link[2].cpu_of_node = cpu_np;
 		priv->dai_link[2].dai_fmt = priv->dai_fmt;
 		priv->card.num_links = 3;
@@ -578,14 +660,15 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 
 asrc_fail:
 	of_node_put(asrc_np);
-fail:
 	of_node_put(codec_np);
+fail:
 	of_node_put(cpu_np);
 
 	return ret;
 }
 
 static const struct of_device_id fsl_asoc_card_dt_ids[] = {
+	{ .compatible = "fsl,imx-audio-ac97", },
 	{ .compatible = "fsl,imx-audio-cs42888", },
 	{ .compatible = "fsl,imx-audio-sgtl5000", },
 	{ .compatible = "fsl,imx-audio-wm8962", },
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: Applied "ASoC: fsl-asoc-card: add AC'97 support" to the asoc tree
  2015-09-16 20:01 Applied "ASoC: fsl-asoc-card: add AC'97 support" to the asoc tree Mark Brown
@ 2015-09-17  7:41 ` Nicolin Chen
  2015-09-17 10:37   ` Mark Brown
  0 siblings, 1 reply; 6+ messages in thread
From: Nicolin Chen @ 2015-09-17  7:41 UTC (permalink / raw)
  To: Mark Brown; +Cc: Maciej Szmigiero, alsa-devel

Hi Mark,

On Wed, Sep 16, 2015 at 09:01:53PM +0100, Mark Brown wrote:
> The patch
> 
>    ASoC: fsl-asoc-card: add AC'97 support
> 
> has been applied to the asoc tree at
> 
>    git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 
> 
> All being well this means that it will be integrated into the linux-next
> tree (usually sometime in the next 24 hours) and sent to Linus during
> the next merge window (or sooner if it is a bug fix), however if
> problems are discovered then the patch may be dropped or reverted.  

This patch breaks my previous function:
[    2.020415] wm8962 3-001a: customer id 0 revision D
[    2.076388] fsl-asoc-card sound: failed to find codec platform device
[    2.086166] fsl-asoc-card: probe of sound failed with error -22

It's actually weird that I didn't see the patch in my mailbox at all
(I searched for it in my Gmail just now) as I found that Maciej put
me in the CC list: http://www.spinics.net/lists/kernel/msg2066060.html

Is it possible for you to revert it provisionally?

Sorry for the inconvenience
Nicolin

> You may get further e-mails resulting from automated or manual testing
> and review of the tree, please engage with people reporting problems and
> send followup patches addressing any issues that are reported if needed.
> 
> If any updates are required or you are submitting further changes they
> should be sent as incremental updates against current git, existing
> patches will not be replaced.
> 
> Please add any relevant lists and maintainers to the CCs when replying
> to this mail.
> 
> Thanks,
> Mark
> 
> From e06b508481e1916b25038289b945104009d774c9 Mon Sep 17 00:00:00 2001
> From: "Maciej S. Szmigiero" <mail@maciej.szmigiero.name>
> Date: Mon, 31 Aug 2015 17:11:35 +0200
> Subject: [PATCH] ASoC: fsl-asoc-card: add AC'97 support
> 
> Add AC'97 support to fsl-asoc-card using generic
> ASoC AC'97 CODEC.
> 
> The SSI controller will silently enable any TX
> AC'97 slots that have their bits set in SLOTREQ
> received from CODEC and then will redirect some
> of playback samples there.
> 
> That's why it is important to make sure that
> any of CODEC playback slots that can pull samples
> are set to slots 3/4 (standard PCM playback slots).
> Currently, this applies to S/PDIF slots as they
> were seen to pull samples sometimes even with
> S/PDIF output being disabled.
> 
> Signed-off-by: Maciej Szmigiero <mail@maciej.szmigiero.name>
> Signed-off-by: Mark Brown <broonie@kernel.org>
> ---
>  .../devicetree/bindings/sound/fsl-asoc-card.txt    |  10 +-
>  sound/soc/fsl/fsl-asoc-card.c                      | 145 ++++++++++++++++-----
>  2 files changed, 120 insertions(+), 35 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
> index a96774c..ce55c0a 100644
> --- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
> +++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
> @@ -13,13 +13,15 @@ So having this generic sound card allows all Freescale SoC users to benefit
>  from the simplification of a new card support and the capability of the wide
>  sample rates support through ASRC.
>  
> -Note: The card is initially designed for those sound cards who use I2S and
> -      PCM DAI formats. However, it'll be also possible to support those non
> -      I2S/PCM type sound cards, such as S/PDIF audio and HDMI audio, as long
> -      as the driver has been properly upgraded.
> +Note: The card is initially designed for those sound cards who use AC'97, I2S
> +      and PCM DAI formats. However, it'll be also possible to support those non
> +      AC'97/I2S/PCM type sound cards, such as S/PDIF audio and HDMI audio, as
> +      long as the driver has been properly upgraded.
>  
>  
>  The compatible list for this generic sound card currently:
> + "fsl,imx-audio-ac97"
> +
>   "fsl,imx-audio-cs42888"
>  
>   "fsl,imx-audio-wm8962"
> diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
> index 5aeb6ed..86aa498 100644
> --- a/sound/soc/fsl/fsl-asoc-card.c
> +++ b/sound/soc/fsl/fsl-asoc-card.c
> @@ -14,6 +14,9 @@
>  #include <linux/i2c.h>
>  #include <linux/module.h>
>  #include <linux/of_platform.h>
> +#if IS_ENABLED(CONFIG_SND_AC97_CODEC)
> +#include <sound/ac97_codec.h>
> +#endif
>  #include <sound/pcm_params.h>
>  #include <sound/soc.h>
>  
> @@ -115,6 +118,11 @@ static const struct snd_soc_dapm_widget fsl_asoc_card_dapm_widgets[] = {
>  	SND_SOC_DAPM_MIC("DMIC", NULL),
>  };
>  
> +static bool fsl_asoc_card_is_ac97(struct fsl_asoc_card_priv *priv)
> +{
> +	return priv->dai_fmt == SND_SOC_DAIFMT_AC97;
> +}
> +
>  static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream,
>  				   struct snd_pcm_hw_params *params)
>  {
> @@ -133,7 +141,9 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream,
>  	 * set_bias_level(), bypass the remaining settings in hw_params().
>  	 * Note: (dai_fmt & CBM_CFM) includes CBM_CFM and CBM_CFS.
>  	 */
> -	if (priv->card.set_bias_level && priv->dai_fmt & SND_SOC_DAIFMT_CBM_CFM)
> +	if ((priv->card.set_bias_level &&
> +	     priv->dai_fmt & SND_SOC_DAIFMT_CBM_CFM) ||
> +	    fsl_asoc_card_is_ac97(priv))
>  		return 0;
>  
>  	/* Specific configurations of DAIs starts from here */
> @@ -300,7 +310,7 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
>  	ext_port--;
>  
>  	/*
> -	 * Use asynchronous mode (6 wires) for all cases.
> +	 * Use asynchronous mode (6 wires) for all cases except AC97.
>  	 * If only 4 wires are needed, just set SSI into
>  	 * synchronous mode and enable 4 PADs in IOMUX.
>  	 */
> @@ -346,15 +356,30 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
>  			   IMX_AUDMUX_V2_PTCR_TCLKDIR;
>  		break;
>  	default:
> -		return -EINVAL;
> +		if (!fsl_asoc_card_is_ac97(priv))
> +			return -EINVAL;
> +	}
> +
> +	if (fsl_asoc_card_is_ac97(priv)) {
> +		int_ptcr = IMX_AUDMUX_V2_PTCR_SYN |
> +			   IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) |
> +			   IMX_AUDMUX_V2_PTCR_TCLKDIR;
> +		ext_ptcr = IMX_AUDMUX_V2_PTCR_SYN |
> +			   IMX_AUDMUX_V2_PTCR_TFSEL(int_port) |
> +			   IMX_AUDMUX_V2_PTCR_TFSDIR;
>  	}
>  
>  	/* Asynchronous mode can not be set along with RCLKDIR */
> -	ret = imx_audmux_v2_configure_port(int_port, 0,
> -					   IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port));
> -	if (ret) {
> -		dev_err(dev, "audmux internal port setup failed\n");
> -		return ret;
> +	if (!fsl_asoc_card_is_ac97(priv)) {
> +		unsigned int pdcr =
> +				IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port);
> +
> +		ret = imx_audmux_v2_configure_port(int_port, 0,
> +						   pdcr);
> +		if (ret) {
> +			dev_err(dev, "audmux internal port setup failed\n");
> +			return ret;
> +		}
>  	}
>  
>  	ret = imx_audmux_v2_configure_port(int_port, int_ptcr,
> @@ -364,11 +389,16 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
>  		return ret;
>  	}
>  
> -	ret = imx_audmux_v2_configure_port(ext_port, 0,
> -					   IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
> -	if (ret) {
> -		dev_err(dev, "audmux external port setup failed\n");
> -		return ret;
> +	if (!fsl_asoc_card_is_ac97(priv)) {
> +		unsigned int pdcr =
> +				IMX_AUDMUX_V2_PDCR_RXDSEL(int_port);
> +
> +		ret = imx_audmux_v2_configure_port(ext_port, 0,
> +						   pdcr);
> +		if (ret) {
> +			dev_err(dev, "audmux external port setup failed\n");
> +			return ret;
> +		}
>  	}
>  
>  	ret = imx_audmux_v2_configure_port(ext_port, ext_ptcr,
> @@ -389,6 +419,23 @@ static int fsl_asoc_card_late_probe(struct snd_soc_card *card)
>  	struct device *dev = card->dev;
>  	int ret;
>  
> +	if (fsl_asoc_card_is_ac97(priv)) {
> +#if IS_ENABLED(CONFIG_SND_AC97_CODEC)
> +		struct snd_soc_codec *codec = card->rtd[0].codec;
> +		struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
> +
> +		/*
> +		 * Use slots 3/4 for S/PDIF so SSI won't try to enable
> +		 * other slots and send some samples there
> +		 * due to SLOTREQ bits for S/PDIF received from codec
> +		 */
> +		snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
> +				     AC97_EA_SPSA_SLOT_MASK, AC97_EA_SPSA_3_4);
> +#endif
> +
> +		return 0;
> +	}
> +
>  	ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->mclk_id,
>  				     codec_priv->mclk_freq, SND_SOC_CLOCK_IN);
>  	if (ret) {
> @@ -404,10 +451,9 @@ 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 platform_device *cpu_pdev;
> +	struct platform_device *cpu_pdev, *codec_pdev;
>  	struct fsl_asoc_card_priv *priv;
> -	struct i2c_client *codec_dev;
> -	struct clk *codec_clk;
> +	struct i2c_client *codec_i2c_dev;
>  	const char *codec_dai_name;
>  	u32 width;
>  	int ret;
> @@ -420,9 +466,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
>  	/* Give a chance to old DT binding */
>  	if (!cpu_np)
>  		cpu_np = of_parse_phandle(np, "ssi-controller", 0);
> -	codec_np = of_parse_phandle(np, "audio-codec", 0);
> -	if (!cpu_np || !codec_np) {
> -		dev_err(&pdev->dev, "phandle missing or invalid\n");
> +	if (!cpu_np) {
> +		dev_err(&pdev->dev, "CPU phandle missing or invalid\n");
>  		ret = -EINVAL;
>  		goto fail;
>  	}
> @@ -434,11 +479,13 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
>  		goto fail;
>  	}
>  
> -	codec_dev = of_find_i2c_device_by_node(codec_np);
> -	if (!codec_dev) {
> -		dev_err(&pdev->dev, "failed to find codec platform device\n");
> -		ret = -EINVAL;
> -		goto fail;
> +	codec_np = of_parse_phandle(np, "audio-codec", 0);
> +	if (codec_np) {
> +		codec_pdev = of_find_device_by_node(codec_np);
> +		codec_i2c_dev = of_find_i2c_device_by_node(codec_np);
> +	} else {
> +		codec_pdev = NULL;
> +		codec_i2c_dev = NULL;
>  	}
>  
>  	asrc_np = of_parse_phandle(np, "audio-asrc", 0);
> @@ -446,10 +493,13 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
>  		asrc_pdev = of_find_device_by_node(asrc_np);
>  
>  	/* Get the MCLK rate only, and leave it controlled by CODEC drivers */
> -	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);
> +	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);
> +		}
>  	}
>  
>  	/* Default sample rate and format, will be updated in hw_params() */
> @@ -486,11 +536,21 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
>  		priv->codec_priv.fll_id = WM8960_SYSCLK_AUTO;
>  		priv->codec_priv.pll_id = WM8960_SYSCLK_AUTO;
>  		priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
> +	} else if (of_device_is_compatible(np, "fsl,imx-audio-ac97")) {
> +		codec_dai_name = "ac97-hifi";
> +		priv->card.set_bias_level = NULL;
> +		priv->dai_fmt = SND_SOC_DAIFMT_AC97;
>  	} else {
>  		dev_err(&pdev->dev, "unknown Device Tree compatible\n");
>  		return -EINVAL;
>  	}
>  
> +	if (!fsl_asoc_card_is_ac97(priv) && !codec_pdev) {
> +		dev_err(&pdev->dev, "failed to find codec platform device\n");
> +		ret = -EINVAL;
> +		goto asrc_fail;
> +	}
> +
>  	/* Common settings for corresponding Freescale CPU DAI driver */
>  	if (strstr(cpu_np->name, "ssi")) {
>  		/* Only SSI needs to configure AUDMUX */
> @@ -507,7 +567,9 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
>  		priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
>  	}
>  
> -	sprintf(priv->name, "%s-audio", codec_dev->name);
> +	snprintf(priv->name, sizeof(priv->name), "%s-audio",
> +		 fsl_asoc_card_is_ac97(priv) ? "ac97" :
> +		 codec_i2c_dev ? codec_i2c_dev->name : codec_pdev->name);
>  
>  	/* Initialize sound card */
>  	priv->pdev = pdev;
> @@ -531,8 +593,26 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
>  
>  	/* Normal DAI Link */
>  	priv->dai_link[0].cpu_of_node = cpu_np;
> -	priv->dai_link[0].codec_of_node = codec_np;
>  	priv->dai_link[0].codec_dai_name = codec_dai_name;
> +
> +	if (!fsl_asoc_card_is_ac97(priv))
> +		priv->dai_link[0].codec_of_node = codec_np;
> +	else {
> +		u32 idx;
> +
> +		ret = of_property_read_u32(cpu_np, "cell-index", &idx);
> +		if (ret) {
> +			dev_err(&pdev->dev,
> +				"cannot get CPU index property\n");
> +			goto asrc_fail;
> +		}
> +
> +		priv->dai_link[0].codec_name =
> +				devm_kasprintf(&pdev->dev, GFP_KERNEL,
> +					       "ac97-codec.%u",
> +					       (unsigned int)idx);
> +	}
> +
>  	priv->dai_link[0].platform_of_node = cpu_np;
>  	priv->dai_link[0].dai_fmt = priv->dai_fmt;
>  	priv->card.num_links = 1;
> @@ -543,6 +623,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
>  		priv->dai_link[1].platform_of_node = asrc_np;
>  		priv->dai_link[2].codec_dai_name = codec_dai_name;
>  		priv->dai_link[2].codec_of_node = codec_np;
> +		priv->dai_link[2].codec_name =
> +				priv->dai_link[0].codec_name;
>  		priv->dai_link[2].cpu_of_node = cpu_np;
>  		priv->dai_link[2].dai_fmt = priv->dai_fmt;
>  		priv->card.num_links = 3;
> @@ -578,14 +660,15 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
>  
>  asrc_fail:
>  	of_node_put(asrc_np);
> -fail:
>  	of_node_put(codec_np);
> +fail:
>  	of_node_put(cpu_np);
>  
>  	return ret;
>  }
>  
>  static const struct of_device_id fsl_asoc_card_dt_ids[] = {
> +	{ .compatible = "fsl,imx-audio-ac97", },
>  	{ .compatible = "fsl,imx-audio-cs42888", },
>  	{ .compatible = "fsl,imx-audio-sgtl5000", },
>  	{ .compatible = "fsl,imx-audio-wm8962", },
> -- 
> 2.5.0
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Applied "ASoC: fsl-asoc-card: add AC'97 support" to the asoc tree
  2015-09-17  7:41 ` Nicolin Chen
@ 2015-09-17 10:37   ` Mark Brown
  2015-09-17 18:02     ` Nicolin Chen
  0 siblings, 1 reply; 6+ messages in thread
From: Mark Brown @ 2015-09-17 10:37 UTC (permalink / raw)
  To: Nicolin Chen; +Cc: Maciej Szmigiero, alsa-devel


[-- Attachment #1.1: Type: text/plain, Size: 586 bytes --]

On Thu, Sep 17, 2015 at 12:41:49AM -0700, Nicolin Chen wrote:

> This patch breaks my previous function:
> [    2.020415] wm8962 3-001a: customer id 0 revision D
> [    2.076388] fsl-asoc-card sound: failed to find codec platform device
> [    2.086166] fsl-asoc-card: probe of sound failed with error -22

> It's actually weird that I didn't see the patch in my mailbox at all
> (I searched for it in my Gmail just now) as I found that Maciej put
> me in the CC list: http://www.spinics.net/lists/kernel/msg2066060.html

> Is it possible for you to revert it provisionally?

OK, done.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Applied "ASoC: fsl-asoc-card: add AC'97 support" to the asoc tree
  2015-09-17 10:37   ` Mark Brown
@ 2015-09-17 18:02     ` Nicolin Chen
  2015-09-17 18:48       ` Maciej S. Szmigiero
  0 siblings, 1 reply; 6+ messages in thread
From: Nicolin Chen @ 2015-09-17 18:02 UTC (permalink / raw)
  To: Mark Brown; +Cc: Maciej Szmigiero, alsa-devel

On Thu, Sep 17, 2015 at 11:37:09AM +0100, Mark Brown wrote:
> On Thu, Sep 17, 2015 at 12:41:49AM -0700, Nicolin Chen wrote:
> 
> > This patch breaks my previous function:
> > [    2.020415] wm8962 3-001a: customer id 0 revision D
> > [    2.076388] fsl-asoc-card sound: failed to find codec platform device
> > [    2.086166] fsl-asoc-card: probe of sound failed with error -22
> 
> > It's actually weird that I didn't see the patch in my mailbox at all
> > (I searched for it in my Gmail just now) as I found that Maciej put
> > me in the CC list: http://www.spinics.net/lists/kernel/msg2066060.html
> 
> > Is it possible for you to revert it provisionally?
> 
> OK, done.

Thank you

@Maciej

Is it possible for you to fix the issue and send a v2? The problem
should be related to the codec_pdev and codec_i2c_dev in your patch
as the driver use codec_i2c_dev to fetch the device not codec_pdev.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Applied "ASoC: fsl-asoc-card: add AC'97 support" to the asoc tree
  2015-09-17 18:02     ` Nicolin Chen
@ 2015-09-17 18:48       ` Maciej S. Szmigiero
  0 siblings, 0 replies; 6+ messages in thread
From: Maciej S. Szmigiero @ 2015-09-17 18:48 UTC (permalink / raw)
  To: Nicolin Chen, Mark Brown; +Cc: alsa-devel

Hi Nicolin,

On 17.09.2015 20:02, Nicolin Chen wrote:
> On Thu, Sep 17, 2015 at 11:37:09AM +0100, Mark Brown wrote:
>> On Thu, Sep 17, 2015 at 12:41:49AM -0700, Nicolin Chen wrote:
>>
>>> This patch breaks my previous function:
>>> [    2.020415] wm8962 3-001a: customer id 0 revision D
>>> [    2.076388] fsl-asoc-card sound: failed to find codec platform device
>>> [    2.086166] fsl-asoc-card: probe of sound failed with error -22
>>
>>> It's actually weird that I didn't see the patch in my mailbox at all
>>> (I searched for it in my Gmail just now) as I found that Maciej put
>>> me in the CC list: http://www.spinics.net/lists/kernel/msg2066060.html
>>
>>> Is it possible for you to revert it provisionally?
>>
>> OK, done.
> 
> Thank you
> 
> @Maciej
> 
> Is it possible for you to fix the issue and send a v2? The problem
> should be related to the codec_pdev and codec_i2c_dev in your patch
> as the driver use codec_i2c_dev to fetch the device not codec_pdev.

Thanks for catching it.

Yes, I will send updated patch tomorrow.

Best regards,
Maciej Szmigiero

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Applied "ASoC: fsl-asoc-card: add AC'97 support" to the asoc tree
@ 2015-10-22 23:09 Mark Brown
  0 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2015-10-22 23:09 UTC (permalink / raw)
  To: Maciej Szmigiero, Mark Brown; +Cc: alsa-devel

The patch

   ASoC: fsl-asoc-card: add AC'97 support

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 50760cad9de969fe85b24465afe6396b8bbc6a3f Mon Sep 17 00:00:00 2001
From: "Maciej S. Szmigiero" <mail@maciej.szmigiero.name>
Date: Sat, 19 Sep 2015 02:00:25 +0200
Subject: [PATCH] ASoC: fsl-asoc-card: add AC'97 support

Add AC'97 support to fsl-asoc-card using generic
ASoC AC'97 CODEC.

The SSI controller will silently enable any TX
AC'97 slots that have their bits set in SLOTREQ
received from CODEC and then will redirect some
of playback samples there.

That's why it is important to make sure that
any of CODEC playback slots that can pull samples
are set to slots 3/4 (standard PCM playback slots).
Currently, this applies to S/PDIF slots as they
were seen to pull samples sometimes even with
S/PDIF output being disabled.

Signed-off-by: Maciej Szmigiero <mail@maciej.szmigiero.name>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 .../devicetree/bindings/sound/fsl-asoc-card.txt    |  10 +-
 sound/soc/fsl/fsl-asoc-card.c                      | 140 ++++++++++++++++-----
 2 files changed, 116 insertions(+), 34 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
index a96774c..ce55c0a 100644
--- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
@@ -13,13 +13,15 @@ So having this generic sound card allows all Freescale SoC users to benefit
 from the simplification of a new card support and the capability of the wide
 sample rates support through ASRC.
 
-Note: The card is initially designed for those sound cards who use I2S and
-      PCM DAI formats. However, it'll be also possible to support those non
-      I2S/PCM type sound cards, such as S/PDIF audio and HDMI audio, as long
-      as the driver has been properly upgraded.
+Note: The card is initially designed for those sound cards who use AC'97, I2S
+      and PCM DAI formats. However, it'll be also possible to support those non
+      AC'97/I2S/PCM type sound cards, such as S/PDIF audio and HDMI audio, as
+      long as the driver has been properly upgraded.
 
 
 The compatible list for this generic sound card currently:
+ "fsl,imx-audio-ac97"
+
  "fsl,imx-audio-cs42888"
 
  "fsl,imx-audio-wm8962"
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 5aeb6ed..33628a0 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -14,6 +14,9 @@
 #include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/of_platform.h>
+#if IS_ENABLED(CONFIG_SND_AC97_CODEC)
+#include <sound/ac97_codec.h>
+#endif
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 
@@ -115,6 +118,11 @@ static const struct snd_soc_dapm_widget fsl_asoc_card_dapm_widgets[] = {
 	SND_SOC_DAPM_MIC("DMIC", NULL),
 };
 
+static bool fsl_asoc_card_is_ac97(struct fsl_asoc_card_priv *priv)
+{
+	return priv->dai_fmt == SND_SOC_DAIFMT_AC97;
+}
+
 static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream,
 				   struct snd_pcm_hw_params *params)
 {
@@ -133,7 +141,9 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream,
 	 * set_bias_level(), bypass the remaining settings in hw_params().
 	 * Note: (dai_fmt & CBM_CFM) includes CBM_CFM and CBM_CFS.
 	 */
-	if (priv->card.set_bias_level && priv->dai_fmt & SND_SOC_DAIFMT_CBM_CFM)
+	if ((priv->card.set_bias_level &&
+	     priv->dai_fmt & SND_SOC_DAIFMT_CBM_CFM) ||
+	    fsl_asoc_card_is_ac97(priv))
 		return 0;
 
 	/* Specific configurations of DAIs starts from here */
@@ -300,7 +310,7 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
 	ext_port--;
 
 	/*
-	 * Use asynchronous mode (6 wires) for all cases.
+	 * Use asynchronous mode (6 wires) for all cases except AC97.
 	 * If only 4 wires are needed, just set SSI into
 	 * synchronous mode and enable 4 PADs in IOMUX.
 	 */
@@ -346,15 +356,30 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
 			   IMX_AUDMUX_V2_PTCR_TCLKDIR;
 		break;
 	default:
-		return -EINVAL;
+		if (!fsl_asoc_card_is_ac97(priv))
+			return -EINVAL;
+	}
+
+	if (fsl_asoc_card_is_ac97(priv)) {
+		int_ptcr = IMX_AUDMUX_V2_PTCR_SYN |
+			   IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) |
+			   IMX_AUDMUX_V2_PTCR_TCLKDIR;
+		ext_ptcr = IMX_AUDMUX_V2_PTCR_SYN |
+			   IMX_AUDMUX_V2_PTCR_TFSEL(int_port) |
+			   IMX_AUDMUX_V2_PTCR_TFSDIR;
 	}
 
 	/* Asynchronous mode can not be set along with RCLKDIR */
-	ret = imx_audmux_v2_configure_port(int_port, 0,
-					   IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port));
-	if (ret) {
-		dev_err(dev, "audmux internal port setup failed\n");
-		return ret;
+	if (!fsl_asoc_card_is_ac97(priv)) {
+		unsigned int pdcr =
+				IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port);
+
+		ret = imx_audmux_v2_configure_port(int_port, 0,
+						   pdcr);
+		if (ret) {
+			dev_err(dev, "audmux internal port setup failed\n");
+			return ret;
+		}
 	}
 
 	ret = imx_audmux_v2_configure_port(int_port, int_ptcr,
@@ -364,11 +389,16 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
 		return ret;
 	}
 
-	ret = imx_audmux_v2_configure_port(ext_port, 0,
-					   IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
-	if (ret) {
-		dev_err(dev, "audmux external port setup failed\n");
-		return ret;
+	if (!fsl_asoc_card_is_ac97(priv)) {
+		unsigned int pdcr =
+				IMX_AUDMUX_V2_PDCR_RXDSEL(int_port);
+
+		ret = imx_audmux_v2_configure_port(ext_port, 0,
+						   pdcr);
+		if (ret) {
+			dev_err(dev, "audmux external port setup failed\n");
+			return ret;
+		}
 	}
 
 	ret = imx_audmux_v2_configure_port(ext_port, ext_ptcr,
@@ -389,6 +419,23 @@ static int fsl_asoc_card_late_probe(struct snd_soc_card *card)
 	struct device *dev = card->dev;
 	int ret;
 
+	if (fsl_asoc_card_is_ac97(priv)) {
+#if IS_ENABLED(CONFIG_SND_AC97_CODEC)
+		struct snd_soc_codec *codec = card->rtd[0].codec;
+		struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+
+		/*
+		 * Use slots 3/4 for S/PDIF so SSI won't try to enable
+		 * other slots and send some samples there
+		 * due to SLOTREQ bits for S/PDIF received from codec
+		 */
+		snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
+				     AC97_EA_SPSA_SLOT_MASK, AC97_EA_SPSA_3_4);
+#endif
+
+		return 0;
+	}
+
 	ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->mclk_id,
 				     codec_priv->mclk_freq, SND_SOC_CLOCK_IN);
 	if (ret) {
@@ -407,7 +454,6 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 	struct platform_device *cpu_pdev;
 	struct fsl_asoc_card_priv *priv;
 	struct i2c_client *codec_dev;
-	struct clk *codec_clk;
 	const char *codec_dai_name;
 	u32 width;
 	int ret;
@@ -420,9 +466,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 	/* Give a chance to old DT binding */
 	if (!cpu_np)
 		cpu_np = of_parse_phandle(np, "ssi-controller", 0);
-	codec_np = of_parse_phandle(np, "audio-codec", 0);
-	if (!cpu_np || !codec_np) {
-		dev_err(&pdev->dev, "phandle missing or invalid\n");
+	if (!cpu_np) {
+		dev_err(&pdev->dev, "CPU phandle missing or invalid\n");
 		ret = -EINVAL;
 		goto fail;
 	}
@@ -434,22 +479,24 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 		goto fail;
 	}
 
-	codec_dev = of_find_i2c_device_by_node(codec_np);
-	if (!codec_dev) {
-		dev_err(&pdev->dev, "failed to find codec platform device\n");
-		ret = -EINVAL;
-		goto fail;
-	}
+	codec_np = of_parse_phandle(np, "audio-codec", 0);
+	if (codec_np)
+		codec_dev = of_find_i2c_device_by_node(codec_np);
+	else
+		codec_dev = NULL;
 
 	asrc_np = of_parse_phandle(np, "audio-asrc", 0);
 	if (asrc_np)
 		asrc_pdev = of_find_device_by_node(asrc_np);
 
 	/* Get the MCLK rate only, and leave it controlled by CODEC drivers */
-	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);
+	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);
+		}
 	}
 
 	/* Default sample rate and format, will be updated in hw_params() */
@@ -486,11 +533,21 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 		priv->codec_priv.fll_id = WM8960_SYSCLK_AUTO;
 		priv->codec_priv.pll_id = WM8960_SYSCLK_AUTO;
 		priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
+	} else if (of_device_is_compatible(np, "fsl,imx-audio-ac97")) {
+		codec_dai_name = "ac97-hifi";
+		priv->card.set_bias_level = NULL;
+		priv->dai_fmt = SND_SOC_DAIFMT_AC97;
 	} else {
 		dev_err(&pdev->dev, "unknown Device Tree compatible\n");
 		return -EINVAL;
 	}
 
+	if (!fsl_asoc_card_is_ac97(priv) && !codec_dev) {
+		dev_err(&pdev->dev, "failed to find codec device\n");
+		ret = -EINVAL;
+		goto asrc_fail;
+	}
+
 	/* Common settings for corresponding Freescale CPU DAI driver */
 	if (strstr(cpu_np->name, "ssi")) {
 		/* Only SSI needs to configure AUDMUX */
@@ -507,7 +564,9 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 		priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
 	}
 
-	sprintf(priv->name, "%s-audio", codec_dev->name);
+	snprintf(priv->name, sizeof(priv->name), "%s-audio",
+		 fsl_asoc_card_is_ac97(priv) ? "ac97" :
+		 codec_dev->name);
 
 	/* Initialize sound card */
 	priv->pdev = pdev;
@@ -531,8 +590,26 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 
 	/* Normal DAI Link */
 	priv->dai_link[0].cpu_of_node = cpu_np;
-	priv->dai_link[0].codec_of_node = codec_np;
 	priv->dai_link[0].codec_dai_name = codec_dai_name;
+
+	if (!fsl_asoc_card_is_ac97(priv))
+		priv->dai_link[0].codec_of_node = codec_np;
+	else {
+		u32 idx;
+
+		ret = of_property_read_u32(cpu_np, "cell-index", &idx);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"cannot get CPU index property\n");
+			goto asrc_fail;
+		}
+
+		priv->dai_link[0].codec_name =
+				devm_kasprintf(&pdev->dev, GFP_KERNEL,
+					       "ac97-codec.%u",
+					       (unsigned int)idx);
+	}
+
 	priv->dai_link[0].platform_of_node = cpu_np;
 	priv->dai_link[0].dai_fmt = priv->dai_fmt;
 	priv->card.num_links = 1;
@@ -543,6 +620,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 		priv->dai_link[1].platform_of_node = asrc_np;
 		priv->dai_link[2].codec_dai_name = codec_dai_name;
 		priv->dai_link[2].codec_of_node = codec_np;
+		priv->dai_link[2].codec_name =
+				priv->dai_link[0].codec_name;
 		priv->dai_link[2].cpu_of_node = cpu_np;
 		priv->dai_link[2].dai_fmt = priv->dai_fmt;
 		priv->card.num_links = 3;
@@ -578,14 +657,15 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 
 asrc_fail:
 	of_node_put(asrc_np);
-fail:
 	of_node_put(codec_np);
+fail:
 	of_node_put(cpu_np);
 
 	return ret;
 }
 
 static const struct of_device_id fsl_asoc_card_dt_ids[] = {
+	{ .compatible = "fsl,imx-audio-ac97", },
 	{ .compatible = "fsl,imx-audio-cs42888", },
 	{ .compatible = "fsl,imx-audio-sgtl5000", },
 	{ .compatible = "fsl,imx-audio-wm8962", },
-- 
2.6.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-10-22 23:09 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-16 20:01 Applied "ASoC: fsl-asoc-card: add AC'97 support" to the asoc tree Mark Brown
2015-09-17  7:41 ` Nicolin Chen
2015-09-17 10:37   ` Mark Brown
2015-09-17 18:02     ` Nicolin Chen
2015-09-17 18:48       ` Maciej S. Szmigiero
2015-10-22 23:09 Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.