From: Pierluigi Passaro <[email protected]>
The codec WM8904 can use internal FLL as PLL source.
Whenever the PLL source is not an external MCLK, this source
must be setup during hw_params callback otherwise the BCLK
could be wrongly evaluated.
The SND_SOC_BIAS_PREPARE event is raised after the hw_params
callback, so there is no need to set again PLL and SYSCLK and
actually there's no need at all the set_bias_level function.
Also, when esai is used, a dedicated snd_soc_dai_set_tdm_slot
call is required.
Signed-off-by: Pierluigi Passaro <[email protected]>
Signed-off by: Alifer Moraes <[email protected]>
---
sound/soc/fsl/fsl-asoc-card.c | 47 +++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 5ee945505281..817dbc1ec635 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -23,6 +23,7 @@
#include "imx-audmux.h"
#include "../codecs/sgtl5000.h"
+#include "../codecs/wm8904.h"
#include "../codecs/wm8962.h"
#include "../codecs/wm8960.h"
#include "../codecs/wm8994.h"
@@ -257,6 +258,38 @@ static int fsl_asoc_card_hw_free(struct snd_pcm_substream *substream)
}
}
+ if (of_device_is_compatible(dev->of_node, "fsl,imx-audio-wm8904")) {
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ unsigned int pll_out;
+
+ ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0, 0, 2,
+ params_physical_width(params));
+ if (ret) {
+ dev_err(dev, "failed to set TDM slot for cpu dai\n");
+ return ret;
+ }
+
+ if (priv->sample_format == SNDRV_PCM_FORMAT_S24_LE)
+ pll_out = priv->sample_rate * 384;
+ else
+ pll_out = priv->sample_rate * 256;
+
+ ret = snd_soc_dai_set_pll(codec_dai, codec_priv->pll_id,
+ codec_priv->pll_id,
+ codec_priv->mclk_freq, pll_out);
+ if (ret) {
+ dev_err(dev, "failed to start FLL: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->fll_id,
+ pll_out, SND_SOC_CLOCK_IN);
+ if (ret) {
+ dev_err(dev, "failed to set SYSCLK: %d\n", ret);
+ return ret;
+ }
+ }
+
return 0;
}
@@ -651,6 +684,19 @@ 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_CBP_CFP;
+ } else if (of_device_is_compatible(np, "fsl,imx-audio-wm8904")) {
+ codec_dai_name = "wm8904-hifi";
+ priv->card.set_bias_level = NULL;
+ priv->codec_priv.mclk_id = WM8904_CLK_FLL;
+ priv->codec_priv.fll_id = WM8904_CLK_FLL;
+ priv->codec_priv.pll_id = WM8904_FLL_MCLK;
+ priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
+ if (strstr(cpu_np->name, "esai")) {
+ priv->cpu_priv.sysclk_freq[TX] = priv->codec_priv.mclk_freq;
+ priv->cpu_priv.sysclk_freq[RX] = priv->codec_priv.mclk_freq;
+ priv->cpu_priv.sysclk_dir[TX] = SND_SOC_CLOCK_OUT;
+ priv->cpu_priv.sysclk_dir[RX] = SND_SOC_CLOCK_OUT;
+ }
} else if (of_device_is_compatible(np, "fsl,imx-audio-ac97")) {
codec_dai_name = "ac97-hifi";
priv->dai_fmt = SND_SOC_DAIFMT_AC97;
@@ -900,6 +946,7 @@ static const struct of_device_id fsl_asoc_card_dt_ids[] = {
{ .compatible = "fsl,imx-audio-tlv320aic32x4", },
{ .compatible = "fsl,imx-audio-tlv320aic31xx", },
{ .compatible = "fsl,imx-audio-sgtl5000", },
+ { .compatible = "fsl,imx-audio-wm8904", },
{ .compatible = "fsl,imx-audio-wm8962", },
{ .compatible = "fsl,imx-audio-wm8960", },
{ .compatible = "fsl,imx-audio-mqs", },
--
2.25.1
On Mon, Mar 07, 2022 at 11:10:38AM -0300, Alifer Moraes wrote:
> From: Pierluigi Passaro <[email protected]>
>
> The codec WM8904 can use internal FLL as PLL source.
> Whenever the PLL source is not an external MCLK, this source
> must be setup during hw_params callback otherwise the BCLK
> could be wrongly evaluated.
> The SND_SOC_BIAS_PREPARE event is raised after the hw_params
> callback, so there is no need to set again PLL and SYSCLK and
> actually there's no need at all the set_bias_level function.
> Also, when esai is used, a dedicated snd_soc_dai_set_tdm_slot
> Signed-off by: Alifer Moraes <[email protected]>
>
> Signed-off-by: Pierluigi Passaro <[email protected]>
When you're sending a mail your signoff should come at the end of the
chain of signoffs - see submitting-patches.rst for details.
This breaks an arm64 defconfig build:
/mnt/kernel/sound/soc/fsl/fsl-asoc-card.c: In function 'fsl_asoc_card_hw_free':
/mnt/kernel/sound/soc/fsl/fsl-asoc-card.c:265:37: error: 'struct snd_soc_pcm_runtime' has no member named 'cpu_dai'
265 | ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0, 0, 2,
| ^~
/mnt/kernel/sound/soc/fsl/fsl-asoc-card.c:266:35: error: 'params' undeclared (first use in this function); did you mean 'parameq'?
266 | params_physical_width(params));
| ^~~~~~
| parameq
/mnt/kernel/sound/soc/fsl/fsl-asoc-card.c:266:35: note: each undeclared identifier is reported only once for each function it appears in