From d7c5b86e5163f6e359d13056fff11e17cf7ccb1a Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Sat, 14 Mar 2020 19:54:32 +0530 Subject: [PATCH] ASoC: tegra: use sample size of 32 for S24_LE I2S bit clock is derived from PLLA_OUT0 and sample size of 24 bits results in fractional value. Clock is not accurate because of this and noisy playback is observed. To avoid this sample size of 32 bits can be used to derive I2S bit clock. This means there are additional bit clocks (8 cycles) per channel which are ignored. Codec picks up data for the other channel when LRCK toggles. The same is true for capture as well. For I2S Tegra-Slave mode this problem is not seen because the clock signals are driven from the codec and above fix is not necessary for it. Bug 200594265 Bug 2845498 Change-Id: Ifa17e65a814fab060ab4762d19edfe34420524ce Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2303591 (cherry picked from commit 1bc9e1904454b359361da6682517952fd0108b46) Signed-off-by: Sameer Pujar Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.4/+/2312716 Reviewed-by: automaticguardword Reviewed-by: Mohan Kumar D Reviewed-by: Sharad Gupta Reviewed-by: mobile promotions GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions --- sound/soc/tegra/tegra210_i2s.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sound/soc/tegra/tegra210_i2s.c b/sound/soc/tegra/tegra210_i2s.c index 27f10f29..ebd0a917 100644 --- a/sound/soc/tegra/tegra210_i2s.c +++ b/sound/soc/tegra/tegra210_i2s.c @@ -539,7 +539,17 @@ static int tegra210_i2s_hw_params(struct snd_pcm_substream *substream, break; case SNDRV_PCM_FORMAT_S24_LE: val = I2S_BITS_24; - sample_size = 24; + + /* + * I2S bit clock is derived from PLLA_OUT0 and size of + * 24 bits results in fractional value and the clock + * is not accurate with this. To have integer clock + * division below is used. It means there are additional + * bit clocks (8 cycles) which are ignored. Codec picks + * up data for other channel when LRCK signal toggles. + */ + sample_size = 32; + cif_conf.audio_bits = TEGRA_ACIF_BITS_24; cif_conf.client_bits = TEGRA_ACIF_BITS_24; break;