diff options
author | Candelaria Villareal, Jorge <x0107209@ti.com> | 2009-07-01 20:17:43 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-07-02 06:06:26 -0400 |
commit | 4e49ffd10f01950bd81e8ef368a1ffb484a7d759 (patch) | |
tree | ad1f82c55044d4976cf3d32e187c32ef45386703 | |
parent | 2115d2c17369df4b70fd161623a40ce98c261989 (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.c | 27 | ||||
-rw-r--r-- | sound/soc/codecs/twl4030.h | 2 |
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 | ||
621 | static void headset_ramp(struct snd_soc_codec *codec, int ramp) | 621 | static 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 | ||
657 | static int headsetlpga_event(struct snd_soc_dapm_widget *w, | 684 | static 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; | |||
274 | struct twl4030_setup_data { | 274 | struct 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__ */ |