From 5da3305cdfe2ed44c011dd0cf76c67b9aec0a654 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Thu, 12 Jul 2018 16:39:43 +0100 Subject: [PATCH] ASoC: tegra-alt: Fix support for I2S mono playback Mono playback via the RT5658 codec on the Jetson TX1/TX2/Xavier is distorted. Although the RT5658 codec is configured for standard I2S timings (implying 2 channels), the Tegra XBAR should convert the mono audio track from one channel to two channels. The problem is caused because the 'CHANNEL_BIT_CNT' field in the I2S Timing Register is being configured incorrectly. For mono playback in I2S mode (or LRCK mode) the CHANNEL_BIT_CNT is being set to 31 instead of 15 by fixing this mono playback works as expected. Please note that the 'bitcnt' value programmed into the I2S Timing Register is verified to see that it is not bigger than the mask for the CHANNEL_BIT_CNT field. However, this is done before we shift the bitcnt by 1 for I2S mode. Therefore, ensure the bitcnt is shifted by 1 before we do the check. Mono playback has been tested by playing the following audio clip ... aplay -D hw:1,0 /usr/share/sounds/alsa/Front_Center.wav Bug 2257806 Change-Id: I4d306ccef891282e96c300d90bad2a5b6efc9968 Signed-off-by: Jon Hunter Reviewed-on: https://git-master.nvidia.com/r/1777096 Reviewed-by: Sameer Pujar GVS: Gerrit_Virtual_Submit Reviewed-by: Bibek Basu Reviewed-by: mobile promotions Tested-by: mobile promotions --- sound/soc/tegra-alt/tegra210_i2s_alt.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sound/soc/tegra-alt/tegra210_i2s_alt.c b/sound/soc/tegra-alt/tegra210_i2s_alt.c index 9ec53951..2fd93a4b 100644 --- a/sound/soc/tegra-alt/tegra210_i2s_alt.c +++ b/sound/soc/tegra-alt/tegra210_i2s_alt.c @@ -629,6 +629,9 @@ static int tegra210_i2s_hw_params(struct snd_pcm_substream *substream, bitcnt = (i2sclock / srate) - 1; + if (frame_format == TEGRA210_I2S_FRAME_FORMAT_LRCK) + bitcnt >>= 1; + if ((bitcnt < 0) || (bitcnt > TEGRA210_I2S_TIMING_CHANNEL_BIT_CNT_MASK)) { dev_err(dev, "Can't set channel bit count\n"); @@ -641,11 +644,7 @@ static int tegra210_i2s_hw_params(struct snd_pcm_substream *substream, return ret; } - if ((frame_format == TEGRA210_I2S_FRAME_FORMAT_LRCK) && (channels > 1)) { - val = (bitcnt >> 1) << - TEGRA210_I2S_TIMING_CHANNEL_BIT_CNT_SHIFT; - } else - val = bitcnt << TEGRA210_I2S_TIMING_CHANNEL_BIT_CNT_SHIFT; + val = bitcnt << TEGRA210_I2S_TIMING_CHANNEL_BIT_CNT_SHIFT; if (i2sclock % (2 * srate)) val |= TEGRA210_I2S_TIMING_NON_SYM_EN;