summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorAlan Tull <r80115@freescale.com>2009-03-06 14:42:08 -0600
committerJustin Waters <justin.waters@timesys.com>2009-10-13 11:02:32 -0400
commit245ac43c9a678cb96c154bfbe4e0b3bfc66ff7c8 (patch)
tree1d6f0310b5cf33fa1b3a9da948a36113b6d44a96 /sound
parenta9b77a6d55c817cde72153cc9cb39526b3f0599c (diff)
ENGR00110076 sgtl5000: fix audio pops
From the SGTL5000 spec, in the CHIP_ANA_POWER reg, the headphone and line out should be powered up before powering up the vag. To power down, power down the vag first, then delay, then power down headphone and line out. Signed-off-by: Alan Tull <r80115@freescale.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/sgtl5000.c49
1 files changed, 27 insertions, 22 deletions
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 962491cd3be7..6b9dfe8de529 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -18,7 +18,6 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
-#include <sound/tlv.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
@@ -649,12 +648,28 @@ static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
u16 reg;
pr_debug("dapm level %d\n", level);
switch (level) {
- case SND_SOC_BIAS_ON: /* full On */
+ case SND_SOC_BIAS_ON: /* full On */
case SND_SOC_BIAS_PREPARE: /* partial On */
+ if ((codec->bias_level == SND_SOC_BIAS_ON) ||
+ (codec->bias_level == SND_SOC_BIAS_PREPARE))
+ break;
+
+ /* must power up hp/line out before vag & dac to
+ avoid pops. */
reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_POWER);
- reg |= SGTL5000_HP_POWERUP;
- reg |= SGTL5000_LINE_OUT_POWERUP;
- sgtl5000_write(codec, SGTL5000_CHIP_ANA_POWER, reg);
+ if ((reg & SGTL5000_HP_POWERUP) == 0) {
+ reg |= SGTL5000_HP_POWERUP;
+ reg |= SGTL5000_LINE_OUT_POWERUP;
+ sgtl5000_write(codec, SGTL5000_CHIP_ANA_POWER, reg);
+ msleep(10);
+
+ reg |= SGTL5000_VAG_POWERUP;
+ reg |= SGTL5000_REFTOP_POWERUP;
+ reg |= SGTL5000_DAC_POWERUP;
+ reg |= SGTL5000_ADC_POWERUP;
+ sgtl5000_write(codec, SGTL5000_CHIP_ANA_POWER, reg);
+ msleep(400);
+ }
reg = sgtl5000_read(codec, SGTL5000_CHIP_MIC_CTRL);
reg &= ~SGTL5000_BIAS_R_MASK;
@@ -677,29 +692,19 @@ static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
reg &= ~SGTL5000_HP_ZCD_EN;
reg &= ~SGTL5000_ADC_ZCD_EN;
sgtl5000_write(codec, SGTL5000_CHIP_ANA_CTRL, reg);
-
- reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_POWER);
- if (codec->bias_level == SND_SOC_BIAS_OFF) {
- reg |= SGTL5000_VAG_POWERUP;
- reg |= SGTL5000_REFTOP_POWERUP;
- reg |= SGTL5000_DAC_POWERUP;
- reg |= SGTL5000_ADC_POWERUP;
- }
- /*reg &= ~SGTL5000_PLL_POWERUP;
- reg &= ~SGTL5000_VCOAMP_POWERUP; */
- reg &= ~SGTL5000_HP_POWERUP;
- reg &= ~SGTL5000_CAPLESS_HP_POWERUP;
- reg &= ~SGTL5000_LINE_OUT_POWERUP;
- sgtl5000_write(codec, SGTL5000_CHIP_ANA_POWER, reg);
-
- msleep(400);
-
break;
case SND_SOC_BIAS_OFF: /* Off, without power */
+ /* must power down hp/line out after vag & dac to
+ avoid pops. */
reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_POWER);
reg &= ~SGTL5000_VAG_POWERUP;
reg &= ~SGTL5000_REFTOP_POWERUP;
+ sgtl5000_write(codec, SGTL5000_CHIP_ANA_POWER, reg);
+ msleep(600);
+
+ reg &= ~SGTL5000_HP_POWERUP;
+ reg &= ~SGTL5000_LINE_OUT_POWERUP;
reg &= ~SGTL5000_DAC_POWERUP;
reg &= ~SGTL5000_ADC_POWERUP;
sgtl5000_write(codec, SGTL5000_CHIP_ANA_POWER, reg);