]>
Commit | Line | Data |
---|---|---|
7264e8a9 SL |
1 | From 63233ede4779d7d8993abd85214df5433e3b90a9 Mon Sep 17 00:00:00 2001 |
2 | From: Rander Wang <rander.wang@linux.intel.com> | |
3 | Date: Fri, 8 Mar 2019 16:38:57 +0800 | |
4 | Subject: ASoC:soc-pcm:fix a codec fixup issue in TDM case | |
5 | ||
6 | [ Upstream commit 570f18b6a8d1f0e60e8caf30e66161b6438dcc91 ] | |
7 | ||
8 | On HDaudio platforms, if playback is started when capture is working, | |
9 | there is no audible output. | |
10 | ||
11 | This can be root-caused to the use of the rx|tx_mask to store an HDaudio | |
12 | stream tag. | |
13 | ||
14 | If capture is stared before playback, rx_mask would be non-zero on HDaudio | |
15 | platform, then the channel number of playback, which is in the same codec | |
16 | dai with the capture, would be changed by soc_pcm_codec_params_fixup based | |
17 | on the tx_mask at first, then overwritten by this function based on rx_mask | |
18 | at last. | |
19 | ||
20 | According to the author of tx|rx_mask, tx_mask is for playback and rx_mask | |
21 | is for capture. And stream direction is checked at all other references of | |
22 | tx|rx_mask in ASoC, so here should be an error. This patch checks stream | |
23 | direction for tx|rx_mask for fixup function. | |
24 | ||
25 | This issue would affect not only HDaudio+ASoC, but also I2S codecs if the | |
26 | channel number based on rx_mask is not equal to the one for tx_mask. It could | |
27 | be rarely reproduecd because most drivers in kernel set the same channel number | |
28 | to tx|rx_mask or rx_mask is zero. | |
29 | ||
30 | Tested on all platforms using stream_tag & HDaudio and intel I2S platforms. | |
31 | ||
32 | Signed-off-by: Rander Wang <rander.wang@linux.intel.com> | |
33 | Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> | |
34 | Signed-off-by: Mark Brown <broonie@kernel.org> | |
35 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
36 | --- | |
37 | sound/soc/soc-pcm.c | 7 +++++-- | |
38 | 1 file changed, 5 insertions(+), 2 deletions(-) | |
39 | ||
40 | diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c | |
41 | index f99eb8f442829..1c0d44c86c018 100644 | |
42 | --- a/sound/soc/soc-pcm.c | |
43 | +++ b/sound/soc/soc-pcm.c | |
44 | @@ -882,10 +882,13 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, | |
45 | codec_params = *params; | |
46 | ||
47 | /* fixup params based on TDM slot masks */ | |
48 | - if (codec_dai->tx_mask) | |
49 | + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && | |
50 | + codec_dai->tx_mask) | |
51 | soc_pcm_codec_params_fixup(&codec_params, | |
52 | codec_dai->tx_mask); | |
53 | - if (codec_dai->rx_mask) | |
54 | + | |
55 | + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE && | |
56 | + codec_dai->rx_mask) | |
57 | soc_pcm_codec_params_fixup(&codec_params, | |
58 | codec_dai->rx_mask); | |
59 | ||
60 | -- | |
61 | 2.20.1 | |
62 |