ASoC: ti: davinci-i2s: Link free-run mode to SND_SOC_DAIFMT_[GATED/CONT]
authorBastien Curutchet <bastien.curutchet@bootlin.com>
Tue, 2 Apr 2024 07:12:10 +0000 (09:12 +0200)
committerMark Brown <broonie@kernel.org>
Tue, 9 Apr 2024 15:58:41 +0000 (16:58 +0100)
McBSP has free-running mode where serial clocks continue to run during
emulation halts. This mode is always enabled by the driver.

Set free-running mode when SND_SOC_DAIFMT_CONT is selected by DAI
format, unset it when SND_SOC_DAIFMT_GATED is selected.

Signed-off-by: Bastien Curutchet <bastien.curutchet@bootlin.com>
Acked-by: Peter Ujfalusi <peter.ujfalusi@gmail.com>
Link: https://msgid.link/r/20240402071213.11671-11-bastien.curutchet@bootlin.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/ti/davinci-i2s.c

index 82a0dfa07cec4fda73696666862c8e6023dfbd78..7fb41987175b526698056e1857e4e1d7df4ec40d 100644 (file)
@@ -280,6 +280,7 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
 {
        struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
        unsigned int pcr;
+       unsigned int spcr;
        unsigned int srgr;
        bool inv_fs = false;
        /* Attention srgr is updated by hw_params! */
@@ -288,6 +289,23 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
                DAVINCI_MCBSP_SRGR_FWID(DEFAULT_BITPERSAMPLE - 1);
 
        dev->fmt = fmt;
+
+       spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
+       switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
+       case SND_SOC_DAIFMT_CONT:
+               spcr |= DAVINCI_MCBSP_SPCR_FREE;
+               dev_dbg(dev->dev, "Free-running mode ON\n");
+               break;
+       case SND_SOC_DAIFMT_GATED:
+               spcr &= ~DAVINCI_MCBSP_SPCR_FREE;
+               dev_dbg(dev->dev, "Free-running mode OFF\n");
+               break;
+       default:
+               dev_err(dev->dev, "Invalid clock gating\n");
+               return -EINVAL;
+       }
+       davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
+
        /* set master/slave audio interface */
        switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
        case SND_SOC_DAIFMT_BP_FP:
@@ -452,10 +470,10 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
        /* general line settings */
        spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
        if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
-               spcr |= DAVINCI_MCBSP_SPCR_RINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
+               spcr |= DAVINCI_MCBSP_SPCR_RINTM(3);
                davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
        } else {
-               spcr |= DAVINCI_MCBSP_SPCR_XINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
+               spcr |= DAVINCI_MCBSP_SPCR_XINTM(3);
                davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
        }