ASoC: cs42xx8: fix the noise in the right dac channel when playback mono wav with record in background
diff mbox

Message ID 09c04620e3394cb10fe3e170947c6f426d51f8be.1448331450.git.zidan.wang@freescale.com
State Accepted
Commit 1f1e60c9cdd573be271130e44a23efed48e0578d
Headers show

Commit Message

Zidan Wang Nov. 24, 2015, 2:18 a.m. UTC
When playback mono wav with record in background, there will be some
nosie in the right dac channel. It seems that the ADC data has been
routed to the dac channel.

The cs42888 have 8 dac channels, it's appropriate to mute the unused
dac channels, and the noise will disappear.

Steps to reproduce this issue:
arecord -D hw:0,0 -f S16_LE -r 48000 -c 1 a.wav &
aplay -Dhw:0,0 audio48k16M.wav

Signed-off-by: Zidan Wang <zidan.wang@freescale.com>
---
 sound/soc/codecs/cs42xx8.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

Patch
diff mbox

diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c
index d562e1b..1179101 100644
--- a/sound/soc/codecs/cs42xx8.c
+++ b/sound/soc/codecs/cs42xx8.c
@@ -44,6 +44,7 @@  struct cs42xx8_priv {
 
 	bool slave_mode;
 	unsigned long sysclk;
+	u32 tx_channels;
 };
 
 /* -127.5dB to 0dB with step of 0.5dB */
@@ -257,6 +258,9 @@  static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
 	u32 ratio = cs42xx8->sysclk / params_rate(params);
 	u32 i, fm, val, mask;
 
+	if (tx)
+		cs42xx8->tx_channels = params_channels(params);
+
 	for (i = 0; i < ARRAY_SIZE(cs42xx8_ratios); i++) {
 		if (cs42xx8_ratios[i].ratio == ratio)
 			break;
@@ -283,9 +287,11 @@  static int cs42xx8_digital_mute(struct snd_soc_dai *dai, int mute)
 {
 	struct snd_soc_codec *codec = dai->codec;
 	struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+	u8 dac_unmute = cs42xx8->tx_channels ?
+		        ~((0x1 << cs42xx8->tx_channels) - 1) : 0;
 
-	regmap_update_bits(cs42xx8->regmap, CS42XX8_DACMUTE,
-			   CS42XX8_DACMUTE_ALL, mute ? CS42XX8_DACMUTE_ALL : 0);
+	regmap_write(cs42xx8->regmap, CS42XX8_DACMUTE,
+		     mute ? CS42XX8_DACMUTE_ALL : dac_unmute);
 
 	return 0;
 }