LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Shengjiu Wang <shengjiu.wang@nxp.com>
To: shengjiu.wang@gmail.com, Xiubo.Lee@gmail.com, festevam@gmail.com,
	nicoleotsuka@gmail.com, lgirdwood@gmail.com, broonie@kernel.org,
	perex@perex.cz, tiwai@suse.com, linux-sound@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org
Subject: [PATCH v2 4/5] ASoC: fsl-asoc-card: exclude S20_3LE format for WM8960/WM8962 + SAI
Date: Wed, 29 Apr 2026 18:00:26 +0800	[thread overview]
Message-ID: <20260429100028.2739711-5-shengjiu.wang@nxp.com> (raw)
In-Reply-To: <20260429100028.2739711-1-shengjiu.wang@nxp.com>

S20_3LE format cannot be used with WM8960/WM8962 codecs when paired
with SAI, due to two distinct BCLK generation limitations:

1. Codec Master Mode:
   When WM8960/WM8962 generates BCLK, it cannot produce the exact
   1.92 MHz required for S20_3LE at 48kHz stereo (48000 × 2 × 20).
   The codec uses fixed dividers from SYSCLK (12.288 MHz), and the
   required divider (6.4) is not available. The closest divider is 6,
   producing 2.048 MHz, which causes right channel corruption.

2. SAI Master Mode:
   SAI derive BCLK from MCLK using integer dividers only. S20_3LE
   requires non-integer divider ratios with standard MCLK frequencies.
   For example, 48kHz stereo needs 1.920 MHz BCLK, which requires a
   divider of 6.4 from 12.288 MHz MCLK (not an integer).

Exclude S20_3LE format for WM8960/WM8962 when used with SAI to prevent
these issues. Users should use S16_LE, S24_LE, or S32_LE instead.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
 sound/soc/fsl/fsl-asoc-card.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 90414ac10032..44083d15f6e5 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -122,6 +122,7 @@ struct cpu_priv {
  * @asrc_rate: ASRC sample rate used by Back-Ends
  * @asrc_format: ASRC sample format used by Back-Ends
  * @dai_fmt: DAI format between CPU and CODEC
+ * @exclude_format: excluded format;
  * @name: Card name
  */
 
@@ -141,6 +142,7 @@ struct fsl_asoc_card_priv {
 	u32 asrc_rate;
 	snd_pcm_format_t asrc_format;
 	u32 dai_fmt;
+	u64 exclude_format;
 	char name[32];
 };
 
@@ -329,6 +331,14 @@ static int fsl_asoc_card_startup(struct snd_pcm_substream *substream)
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	int ret;
 
+	if (priv->exclude_format && !rtd->dai_link->no_pcm) {
+		ret = snd_pcm_hw_constraint_mask64(runtime,
+						   SNDRV_PCM_HW_PARAM_FORMAT,
+						   ~priv->exclude_format);
+		if (ret)
+			return ret;
+	}
+
 	if (priv->constraint_channels) {
 		ret = snd_pcm_hw_constraint_list(runtime, 0,
 						 SNDRV_PCM_HW_PARAM_CHANNELS,
@@ -850,11 +860,30 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 		priv->codec_priv[0].fll_id = WM8962_SYSCLK_FLL;
 		priv->codec_priv[0].pll_id = WM8962_FLL;
 		priv->dai_fmt |= SND_SOC_DAIFMT_CBP_CFP;
+		/*
+		 * WM8962 has same BCLK generation limitations as WM8960.
+		 * See WM8960 section for detailed explanation.
+		 */
+		if (of_node_name_eq(cpu_np, "sai"))
+			priv->exclude_format = SNDRV_PCM_FMTBIT_S20_3LE;
 	} else if (of_device_is_compatible(np, "fsl,imx-audio-wm8960")) {
 		codec_dai_name[0] = "wm8960-hifi";
 		priv->codec_priv[0].fll_id = WM8960_SYSCLK_AUTO;
 		priv->codec_priv[0].pll_id = WM8960_SYSCLK_AUTO;
 		priv->dai_fmt |= SND_SOC_DAIFMT_CBP_CFP;
+		/*
+		 * WM8960 in master mode cannot generate exact 1.92 MHz BCLK
+		 * required for S20_3LE (48kHz × 2ch × 20bit). Closest available
+		 * is 2.048 MHz (SYSCLK/6), which causes right channel corruption.
+		 *
+		 * In SAI master mode, SAI derive BCLK from MCLK using integer
+		 * dividers only. S20_3LE requires non-integer divider ratios
+		 * with standard MCLK frequencies. For example, 48kHz stereo
+		 * needs 1.920 MHz BCLK, which requires a divider of 6.4 from
+		 * 12.288 MHz MCLK (not an integer).
+		 */
+		if (of_node_name_eq(cpu_np, "sai"))
+			priv->exclude_format = SNDRV_PCM_FMTBIT_S20_3LE;
 	} else if (of_device_is_compatible(np, "fsl,imx-audio-ac97")) {
 		codec_dai_name[0] = "ac97-hifi";
 		priv->dai_fmt = SND_SOC_DAIFMT_AC97;
-- 
2.34.1



  parent reply	other threads:[~2026-04-29  9:59 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-29 10:00 [PATCH v2 0/5] ASoC: fsl-asoc-card: Add some improvements Shengjiu Wang
2026-04-29 10:00 ` [PATCH v2 1/5] ASoC: fsl-asoc-card: enable dpcm_merged_chan flag for ASRC frontend Shengjiu Wang
2026-04-29 10:00 ` [PATCH v2 2/5] ASoC: fsl-asoc-card: enable ignore_pmdown_time for ASRC case Shengjiu Wang
2026-04-29 10:00 ` [PATCH v2 3/5] ASoC: fsl-asoc-card: add channel and rate constraints for CS42888 Shengjiu Wang
2026-04-29 10:00 ` Shengjiu Wang [this message]
2026-04-29 10:00 ` [PATCH v2 5/5] ASoC: fsl-asoc-card: reduce WM8904 PLL ratio to meet frequency limit Shengjiu Wang
2026-04-30 12:08 ` [PATCH v2 0/5] ASoC: fsl-asoc-card: Add some improvements Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260429100028.2739711-5-shengjiu.wang@nxp.com \
    --to=shengjiu.wang@nxp.com \
    --cc=Xiubo.Lee@gmail.com \
    --cc=broonie@kernel.org \
    --cc=festevam@gmail.com \
    --cc=lgirdwood@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=nicoleotsuka@gmail.com \
    --cc=perex@perex.cz \
    --cc=shengjiu.wang@gmail.com \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox