aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCandelaria Villareal, Jorge <x0107209@ti.com>2009-07-01 20:17:43 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-07-02 06:06:26 -0400
commit4e49ffd10f01950bd81e8ef368a1ffb484a7d759 (patch)
treead1f82c55044d4976cf3d32e187c32ef45386703
parent2115d2c17369df4b70fd161623a40ce98c261989 (diff)
ASoC: TWL4030: Add EXTMUTE to reduce pop-noise effect
According to TRM, an external FET controlled by a 1.8V output signal can be used to reduce the pop-noise heard when the audio amplifier is switched on. It is suggested that GPIO6 of TWL4030 be used, but any other gpio can be used instead. This is indicated in machine driver with the following twl4030_setup_data members: -hs_extmute. Set to 1 if board has support for EXTMUTE. -set_hs_extmute. Set to a callback funcion to control an external gpio line. Set to NULL if MUTE[GPIO6] pin is used. Codec driver takes care of enabling and disabling this output during the headset pop attenuation sequence. Also add a delay to let VMID settle in ramp up sequence. Signed-off-by: Jorge Eduardo Candelaria <x0107209@ti.com> Acked-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/codecs/twl4030.c27
-rw-r--r--sound/soc/codecs/twl4030.h2
2 files changed, 29 insertions, 0 deletions
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 49ceb620678c..6da94cadd157 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -620,6 +620,9 @@ static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
620 620
621static void headset_ramp(struct snd_soc_codec *codec, int ramp) 621static void headset_ramp(struct snd_soc_codec *codec, int ramp)
622{ 622{
623 struct snd_soc_device *socdev = codec->socdev;
624 struct twl4030_setup_data *setup = socdev->codec_data;
625
623 unsigned char hs_gain, hs_pop; 626 unsigned char hs_gain, hs_pop;
624 struct twl4030_priv *twl4030 = codec->private_data; 627 struct twl4030_priv *twl4030 = codec->private_data;
625 /* Base values for ramp delay calculation: 2^19 - 2^26 */ 628 /* Base values for ramp delay calculation: 2^19 - 2^26 */
@@ -629,6 +632,17 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
629 hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET); 632 hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET);
630 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); 633 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
631 634
635 /* Enable external mute control, this dramatically reduces
636 * the pop-noise */
637 if (setup && setup->hs_extmute) {
638 if (setup->set_hs_extmute) {
639 setup->set_hs_extmute(1);
640 } else {
641 hs_pop |= TWL4030_EXTMUTE;
642 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
643 }
644 }
645
632 if (ramp) { 646 if (ramp) {
633 /* Headset ramp-up according to the TRM */ 647 /* Headset ramp-up according to the TRM */
634 hs_pop |= TWL4030_VMID_EN; 648 hs_pop |= TWL4030_VMID_EN;
@@ -636,6 +650,9 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
636 twl4030_write(codec, TWL4030_REG_HS_GAIN_SET, hs_gain); 650 twl4030_write(codec, TWL4030_REG_HS_GAIN_SET, hs_gain);
637 hs_pop |= TWL4030_RAMP_EN; 651 hs_pop |= TWL4030_RAMP_EN;
638 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 652 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
653 /* Wait ramp delay time + 1, so the VMID can settle */
654 mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
655 twl4030->sysclk) + 1);
639 } else { 656 } else {
640 /* Headset ramp-down _not_ according to 657 /* Headset ramp-down _not_ according to
641 * the TRM, but in a way that it is working */ 658 * the TRM, but in a way that it is working */
@@ -652,6 +669,16 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
652 hs_pop &= ~TWL4030_VMID_EN; 669 hs_pop &= ~TWL4030_VMID_EN;
653 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 670 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
654 } 671 }
672
673 /* Disable external mute */
674 if (setup && setup->hs_extmute) {
675 if (setup->set_hs_extmute) {
676 setup->set_hs_extmute(0);
677 } else {
678 hs_pop &= ~TWL4030_EXTMUTE;
679 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
680 }
681 }
655} 682}
656 683
657static int headsetlpga_event(struct snd_soc_dapm_widget *w, 684static int headsetlpga_event(struct snd_soc_dapm_widget *w,
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index fe5f395d9e4f..2b4bfa23f985 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -274,6 +274,8 @@ extern struct snd_soc_codec_device soc_codec_dev_twl4030;
274struct twl4030_setup_data { 274struct twl4030_setup_data {
275 unsigned int ramp_delay_value; 275 unsigned int ramp_delay_value;
276 unsigned int sysclk; 276 unsigned int sysclk;
277 unsigned int hs_extmute:1;
278 void (*set_hs_extmute)(int mute);
277}; 279};
278 280
279#endif /* End of __TWL4030_AUDIO_H__ */ 281#endif /* End of __TWL4030_AUDIO_H__ */