summaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-pcm.c
diff options
context:
space:
mode:
authorRander Wang <rander.wang@linux.intel.com>2019-03-08 16:38:57 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-05-10 17:54:05 +0200
commit581a8bd9fa8b7265f858c7f35d658354c9fe028f (patch)
treebdd6f70749e4fd5a496c53b54f03c3fa4776b527 /sound/soc/soc-pcm.c
parentc37f7344075a424fd4c70f0710a4feeed7ac1fb1 (diff)
downloadlinux-stable-581a8bd9fa8b7265f858c7f35d658354c9fe028f.tar.gz
linux-stable-581a8bd9fa8b7265f858c7f35d658354c9fe028f.tar.bz2
linux-stable-581a8bd9fa8b7265f858c7f35d658354c9fe028f.zip
ASoC:soc-pcm:fix a codec fixup issue in TDM case
[ Upstream commit 570f18b6a8d1f0e60e8caf30e66161b6438dcc91 ] On HDaudio platforms, if playback is started when capture is working, there is no audible output. This can be root-caused to the use of the rx|tx_mask to store an HDaudio stream tag. If capture is stared before playback, rx_mask would be non-zero on HDaudio platform, then the channel number of playback, which is in the same codec dai with the capture, would be changed by soc_pcm_codec_params_fixup based on the tx_mask at first, then overwritten by this function based on rx_mask at last. According to the author of tx|rx_mask, tx_mask is for playback and rx_mask is for capture. And stream direction is checked at all other references of tx|rx_mask in ASoC, so here should be an error. This patch checks stream direction for tx|rx_mask for fixup function. This issue would affect not only HDaudio+ASoC, but also I2S codecs if the channel number based on rx_mask is not equal to the one for tx_mask. It could be rarely reproduecd because most drivers in kernel set the same channel number to tx|rx_mask or rx_mask is zero. Tested on all platforms using stream_tag & HDaudio and intel I2S platforms. Signed-off-by: Rander Wang <rander.wang@linux.intel.com> Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'sound/soc/soc-pcm.c')
-rw-r--r--sound/soc/soc-pcm.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index e8b98bfd4cf1..33060af18b5a 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -957,10 +957,13 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
codec_params = *params;
/* fixup params based on TDM slot masks */
- if (codec_dai->tx_mask)
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
+ codec_dai->tx_mask)
soc_pcm_codec_params_fixup(&codec_params,
codec_dai->tx_mask);
- if (codec_dai->rx_mask)
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
+ codec_dai->rx_mask)
soc_pcm_codec_params_fixup(&codec_params,
codec_dai->rx_mask);