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
