[alsa-devel] [PATCH 1/1] ASoC: TWL4030: Wait RAMP_DELAY on headsetl_event: POST_PMD

Peter Ujfalusi peter.ujfalusi at nokia.com
Mon May 11 13:14:25 CEST 2009


This patch fixes the - agressive - 'tuck' sound heard when
the codec goes to standby mode.

We need to wait for the ramp down completion in case of
headsetl_event:POST_PMD.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi at nokia.com>
---
 sound/soc/codecs/twl4030.c |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index fd392c6..c22f8d6 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -130,6 +130,8 @@ struct twl4030_priv {
 	unsigned int rate;
 	unsigned int sample_bits;
 	unsigned int channels;
+
+	unsigned int sysclk;
 };
 
 /*
@@ -586,6 +588,11 @@ static int headsetl_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *kcontrol, int event)
 {
 	unsigned char hs_gain, hs_pop;
+	struct twl4030_priv *twl4030 = w->codec->private_data;
+	/* Base values for ramp delay calculation: 2^19 - 2^26 */
+	unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304,
+				    8388608, 16777216, 33554432, 67108864};
+	unsigned int ramp_delay;
 
 	/* Save the current volume */
 	hs_gain = twl4030_read_reg_cache(w->codec, TWL4030_REG_HS_GAIN_SET);
@@ -609,6 +616,12 @@ static int headsetl_event(struct snd_soc_dapm_widget *w,
 		/* Do the anti-pop/bias ramp disable according to the TRM */
 		hs_pop &= ~TWL4030_RAMP_EN;
 		twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop);
+
+		/* We need to wait RAMP_DELAY time, otherwise 'tuck' sound can
+		 * be heard on the output */
+		ramp_delay = (hs_pop & TWL4030_RAMP_DELAY) >> 2;
+		mdelay(ramp_base[ramp_delay] / twl4030->sysclk);
+
 		/* Bypass the reg_cache to mute the headset */
 		twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
 					hs_gain & (~0x0f),
@@ -1567,17 +1580,21 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 		int clk_id, unsigned int freq, int dir)
 {
 	struct snd_soc_codec *codec = codec_dai->codec;
+	struct twl4030_priv *twl4030 = codec->private_data;
 	u8 infreq;
 
 	switch (freq) {
 	case 19200000:
 		infreq = TWL4030_APLL_INFREQ_19200KHZ;
+		twl4030->sysclk = 19200;
 		break;
 	case 26000000:
 		infreq = TWL4030_APLL_INFREQ_26000KHZ;
+		twl4030->sysclk = 26000;
 		break;
 	case 38400000:
 		infreq = TWL4030_APLL_INFREQ_38400KHZ;
+		twl4030->sysclk = 38400;
 		break;
 	default:
 		printk(KERN_ERR "TWL4030 set sysclk: unknown rate %d\n",
@@ -1929,6 +1946,9 @@ static int twl4030_probe(struct platform_device *pdev)
 		kfree(codec);
 		return -ENOMEM;
 	}
+	/* Set default sysclk (used by the headsetl_event callback for
+	 * pop-attenuation) */
+	twl4030->sysclk = 26000;
 
 	codec->private_data = twl4030;
 	socdev->card->codec = codec;
-- 
1.6.2.3



More information about the Alsa-devel mailing list