]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ASoC: cs42xx8: add error checks for constraints in TDM mode
authorShengjiu Wang <shengjiu.wang@nxp.com>
Wed, 25 Feb 2026 10:09:07 +0000 (18:09 +0800)
committerMark Brown <broonie@kernel.org>
Sun, 1 Mar 2026 16:08:04 +0000 (16:08 +0000)
In the TDM format the ADC and DAC serial ports will only operate as a
slave, the sysclk should not be less than 256FS and Quad-Speed Mode (100
to 200 kHz sample rates) is not supported by ADC. So add error checks
for these constraints.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Link: https://patch.msgid.link/20260225100907.686470-1-shengjiu.wang@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/cs42xx8.c

index f6b8fe7d53e2cf2c0455cc7a70385f747ec58087..12fe9b3e2525efff0c58c05ee443a5d6a7f6c56f 100644 (file)
@@ -40,6 +40,7 @@ struct cs42xx8_priv {
        struct clk *clk;
 
        bool slave_mode;
+       bool is_tdm_mode;
        unsigned long sysclk;
        u32 tx_channels;
        struct gpio_desc *gpiod_reset;
@@ -214,6 +215,8 @@ static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai,
        struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
        u32 val;
 
+       cs42xx8->is_tdm_mode = false;
+
        /* Set DAI format */
        switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_LEFT_J:
@@ -227,6 +230,7 @@ static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai,
                break;
        case SND_SOC_DAIFMT_DSP_A:
                val = CS42XX8_INTF_DAC_DIF_TDM | CS42XX8_INTF_ADC_DIF_TDM;
+               cs42xx8->is_tdm_mode = true;
                break;
        default:
                dev_err(component->dev, "unsupported dai format\n");
@@ -250,6 +254,11 @@ static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
+       if (cs42xx8->is_tdm_mode && !cs42xx8->slave_mode) {
+               dev_err(component->dev, "TDM mode is supported only in slave mode\n");
+               return -EINVAL;
+       }
+
        return 0;
 }
 
@@ -332,6 +341,19 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
 
        cs42xx8->rate[tx] = params_rate(params);
 
+       if (cs42xx8->is_tdm_mode) {
+               if (cs42xx8->sysclk < 256 * cs42xx8->rate[tx]) {
+                       dev_err(component->dev, "Unsupported sysclk in TDM mode\n");
+                       return -EINVAL;
+               }
+
+               if (!tx && cs42xx8->rate[tx] > 100000) {
+                       dev_err(component->dev,
+                               "ADC does not support Quad-Speed Mode in TDM mode\n");
+                       return -EINVAL;
+               }
+       }
+
        mask = CS42XX8_FUNCMOD_MFREQ_MASK;
        val = cs42xx8_ratios[i].mfreq;