ASoC: fsl_sai: Don't disable bitclock for i.MX8MP
authorShengjiu Wang <shengjiu.wang@nxp.com>
Tue, 19 Sep 2023 09:42:13 +0000 (17:42 +0800)
committerMark Brown <broonie@kernel.org>
Mon, 25 Sep 2023 12:11:05 +0000 (13:11 +0100)
On i.MX8MP, the BCE and TERE bit are binding with mclk
enablement, if BCE and TERE are cleared the MCLK also be
disabled on output pin, that cause the external codec (wm8960)
in wrong state.

Codec (wm8960) is using the mclk to generate PLL clock,
if mclk is disabled before disabling PLL, the codec (wm8960)
won't generate bclk and frameclk when sysclk switch to
MCLK source in next test case.

The test case:
$aplay -r44100 test1.wav (PLL source)
$aplay -r48000 test2.wav (MCLK source)
aplay: pcm_write:2127: write error: Input/output error

Fixes: 269f399dc19f ("ASoC: fsl_sai: Disable bit clock with transmitter")
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Link: https://lore.kernel.org/r/1695116533-23287-1-git-send-email-shengjiu.wang@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/fsl/fsl_sai.c

index 1e4020fae05abbbb55c403d261a50ba857b31e3e..8a9a30dd31e208d697b67c1a6788bc66e853fc38 100644 (file)
@@ -710,10 +710,15 @@ static void fsl_sai_config_disable(struct fsl_sai *sai, int dir)
 {
        unsigned int ofs = sai->soc_data->reg_offset;
        bool tx = dir == TX;
-       u32 xcsr, count = 100;
+       u32 xcsr, count = 100, mask;
+
+       if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output)
+               mask = FSL_SAI_CSR_TERE;
+       else
+               mask = FSL_SAI_CSR_TERE | FSL_SAI_CSR_BCE;
 
        regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
-                          FSL_SAI_CSR_TERE | FSL_SAI_CSR_BCE, 0);
+                          mask, 0);
 
        /* TERE will remain set till the end of current frame */
        do {