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 3/5] ASoC: fsl-asoc-card: add channel and rate constraints for CS42888
Date: Fri, 24 Apr 2026 18:38:04 +0800 [thread overview]
Message-ID: <20260424103806.2276780-4-shengjiu.wang@nxp.com> (raw)
In-Reply-To: <20260424103806.2276780-1-shengjiu.wang@nxp.com>
The CS42888 codec has 4 I2S lanes with 2 channels per lane. Using odd
channel counts (3, 5, 7) causes data misalignment in the I2S frame,
resulting in incorrect channel mapping. Only mono and even channel
counts (1, 2, 4, 6, 8) work correctly.
Additionally, the fixed system clock on i.MX platforms limits supported
sample rates. With 12.288 MHz MCLK, only 48kHz family rates (48k, 96k,
192k) achieve valid MCLK:LRCK ratios. With 11.2896 MHz MCLK, only 44k
family rates are supported.
Add a startup callback to apply PCM constraints for both channels and
rates, preventing userspace from requesting unsupported configurations.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
sound/soc/fsl/fsl-asoc-card.c | 67 +++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index e08e135886f7..50d7a5f2d79e 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -40,6 +40,18 @@
/* Default DAI format without Master and Slave flag */
#define DAI_FMT_BASE (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF)
+static const u32 cs42888_rates_48k[] = {
+ 48000, 96000, 192000,
+};
+
+static const u32 cs42888_rates_44k[] = {
+ 44100, 88200, 176400,
+};
+
+static const u32 cs42888_channels[] = {
+ 1, 2, 4, 6, 8,
+};
+
/**
* struct codec_priv - CODEC private data
* @mclk: Main clock of the CODEC
@@ -93,6 +105,10 @@ 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
+ * @support_rates: array of supported rates
+ * @support_channels: array of supported channels
+ * @num_rates: Number of entries in support_rates array
+ * @num_channels: Number of entries in support_channels array
* @name: Card name
*/
@@ -110,6 +126,10 @@ struct fsl_asoc_card_priv {
u32 asrc_rate;
snd_pcm_format_t asrc_format;
u32 dai_fmt;
+ const u32 *support_rates;
+ const u32 *support_channels;
+ u32 num_rates;
+ u32 num_channels;
char name[32];
};
@@ -291,7 +311,41 @@ static int fsl_asoc_card_hw_free(struct snd_pcm_substream *substream)
return 0;
}
+static int fsl_asoc_card_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ static struct snd_pcm_hw_constraint_list constraint_rates;
+ static struct snd_pcm_hw_constraint_list constraint_channels;
+ int ret;
+
+ constraint_channels.list = priv->support_channels;
+ constraint_channels.count = priv->num_channels;
+ constraint_rates.list = priv->support_rates;
+ constraint_rates.count = priv->num_rates;
+
+ if (constraint_channels.count) {
+ ret = snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraint_channels);
+ if (ret)
+ return ret;
+ }
+
+ if (constraint_rates.count) {
+ ret = snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &constraint_rates);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
static const struct snd_soc_ops fsl_asoc_card_ops = {
+ .startup = fsl_asoc_card_startup,
.hw_params = fsl_asoc_card_hw_params,
.hw_free = fsl_asoc_card_hw_free,
};
@@ -753,6 +807,19 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
priv->cpu_priv.sysclk_dir[RX] = SND_SOC_CLOCK_OUT;
priv->cpu_priv.slot_width = 32;
priv->dai_fmt |= SND_SOC_DAIFMT_CBC_CFC;
+ priv->support_channels = cs42888_channels;
+ priv->num_channels = ARRAY_SIZE(cs42888_channels);
+ if (priv->codec_priv[0].mclk_freq % 12288000 == 0) {
+ priv->support_rates = cs42888_rates_48k;
+ priv->num_rates = ARRAY_SIZE(cs42888_rates_48k);
+ } else if (priv->codec_priv[0].mclk_freq % 11289600 == 0) {
+ priv->support_rates = cs42888_rates_44k;
+ priv->num_rates = ARRAY_SIZE(cs42888_rates_44k);
+ } else {
+ /* Unknown MCLK, no rate constraints */
+ dev_warn(&pdev->dev, "Unknown MCLK frequency %lu, no rate constraints\n",
+ priv->codec_priv[0].mclk_freq);
+ }
} else if (of_device_is_compatible(np, "fsl,imx-audio-cs427x")) {
codec_dai_name[0] = "cs4271-hifi";
priv->codec_priv[0].mclk_id = CS427x_SYSCLK_MCLK;
--
2.34.1
next prev parent reply other threads:[~2026-04-24 10:37 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-24 10:38 [PATCH 0/5] ASoC: fsl-asoc-card: Add some improvements Shengjiu Wang
2026-04-24 10:38 ` [PATCH 1/5] ASoC: fsl-asoc-card: enable dpcm_merged_chan flag for ASRC frontend Shengjiu Wang
2026-04-24 10:38 ` [PATCH 2/5] ASoC: fsl-asoc-card: enable ignore_pmdown_time for ASRC case Shengjiu Wang
2026-04-24 10:38 ` Shengjiu Wang [this message]
2026-04-24 16:09 ` [PATCH 3/5] ASoC: fsl-asoc-card: add channel and rate constraints for CS42888 Mark Brown
2026-04-27 10:47 ` Shengjiu Wang
2026-04-24 10:38 ` [PATCH 4/5] ASoC: fsl-asoc-card: exclude S20_3LE format due to clock limitations Shengjiu Wang
2026-04-24 10:38 ` [PATCH 5/5] ASoC: fsl-asoc-card: reduce WM8904 PLL ratio to meet frequency limit Shengjiu Wang
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=20260424103806.2276780-4-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