WM8904 has a 27 MHz PLL frequency limit. The current S24_LE PLL ratio
of 384 exceeds this at high sample rates (96 kHz × 384 = 36.864 MHz).

Reduce the ratio to 192 for WM8904, keeping PLL within limits at all
supported rates (96 kHz × 192 = 18.432 MHz).

Add codec-specific pll_ratio_s24 field, default 384, override to 192
for WM8904.

Signed-off-by: Shengjiu Wang <[email protected]>
---
 sound/soc/fsl/fsl-asoc-card.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 44083d15f6e5..709543308fe9 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -75,6 +75,9 @@ static const struct snd_pcm_hw_constraint_list 
cs42888_channel_constraints = {
  * @mclk_id: MCLK (or main clock) id for set_sysclk()
  * @fll_id: FLL (or secordary clock) id for set_sysclk()
  * @pll_id: PLL id for set_pll()
+ * @pll_ratio_s24: PLL output ratio for S24_LE format (PLL_freq = sample_rate 
× ratio)
+ *                 Default is 384, but some codecs (e.g., WM8904) require 
lower values
+ *                 to stay within PLL frequency limits
  */
 struct codec_priv {
        struct clk *mclk;
@@ -83,6 +86,7 @@ struct codec_priv {
        u32 mclk_id;
        int fll_id;
        int pll_id;
+       int pll_ratio_s24;
 };
 
 /**
@@ -255,7 +259,7 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream 
*substream,
 
                if (codec_priv->pll_id >= 0 && codec_priv->fll_id >= 0) {
                        if (priv->sample_format == SNDRV_PCM_FORMAT_S24_LE)
-                               pll_out = priv->sample_rate * 384;
+                               pll_out = priv->sample_rate * 
codec_priv->pll_ratio_s24;
                        else
                                pll_out = priv->sample_rate * 256;
 
@@ -815,6 +819,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
        for (codec_idx = 0; codec_idx < 2; codec_idx++) {
                priv->codec_priv[codec_idx].fll_id = -1;
                priv->codec_priv[codec_idx].pll_id = -1;
+               priv->codec_priv[codec_idx].pll_ratio_s24 = 384;
        }
 
        /* Diversify the card configurations */
@@ -935,6 +940,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
                priv->codec_priv[0].mclk_id = WM8904_FLL_MCLK;
                priv->codec_priv[0].fll_id = WM8904_CLK_FLL;
                priv->codec_priv[0].pll_id = WM8904_FLL_MCLK;
+               priv->codec_priv[0].pll_ratio_s24 = 192;
                priv->dai_fmt |= SND_SOC_DAIFMT_CBP_CFP;
        } else if (of_device_is_compatible(np, "fsl,imx-audio-spdif")) {
                ret = fsl_asoc_card_spdif_init(codec_np, cpu_np, 
codec_dai_name, priv);
-- 
2.34.1


Reply via email to