summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorAlan Tull <r80115@freescale.com>2009-08-04 12:47:31 -0500
committerRob Herring <r.herring@freescale.com>2009-08-07 09:47:33 -0500
commitd08b32e8daa88a0de645bd94209f5f2669a775c8 (patch)
tree79db3cf02aa0da7b4327c89fd16305ac396cad79 /sound
parent257059a3a26f2d507a9d10dfee0cff2ba1c2c21d (diff)
ENGR00114820-2 sgtl5000: pop fixes
- This fixes pops that happened after audio playback. These pops were caused by zcd and DAC being turned off. - Enable zcd and leave it enabled. - Turn on DAC early, leave it on. - We were turning on analog sections during first playback, now turn them on during initialization instead to avoid delay. Signed-off-by: Alan Tull <r80115@freescale.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/sgtl5000.c50
1 files changed, 24 insertions, 26 deletions
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index d3f4ecdd34da..eb983d0f8b58 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -258,7 +258,8 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
SND_SOC_DAPM_MUX("DAC Mux", SND_SOC_NOPM, 0, 0, &dac_mux),
SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_DIG_POWER, 6, 0),
- SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_DIG_POWER, 5, 0),
+ SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_DIG_POWER,
+ SND_SOC_NOPM, 0),
};
static const struct snd_soc_dapm_route audio_map[] = {
@@ -648,8 +649,12 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
}
sgtl5000_write(codec, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
sgtl5000_write(codec, SGTL5000_CHIP_I2S_CTRL, i2s_ctl);
+
+ /* sgtl5000 pops sometimes when powering off the DAC. So we
+ power it up here and leave it powered up */
reg = sgtl5000_read(codec, SGTL5000_CHIP_DIG_POWER);
- reg |= SGTL5000_I2S_IN_POWERUP | SGTL5000_I2S_OUT_POWERUP;
+ reg |= SGTL5000_I2S_IN_POWERUP | SGTL5000_I2S_OUT_POWERUP |
+ SGTL5000_DAC_EN;
sgtl5000_write(codec, SGTL5000_CHIP_DIG_POWER, reg);
return 0;
}
@@ -666,8 +671,21 @@ static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
(codec->bias_level == SND_SOC_BIAS_PREPARE))
break;
+ reg = sgtl5000_read(codec, SGTL5000_CHIP_MIC_CTRL);
+ reg &= ~SGTL5000_BIAS_R_MASK;
+ reg |= SGTL5000_BIAS_R_4k << SGTL5000_BIAS_R_SHIFT;
+ sgtl5000_write(codec, SGTL5000_CHIP_MIC_CTRL, reg);
+ break;
+
+ case SND_SOC_BIAS_STANDBY: /* Off, with power */
+ reg = sgtl5000_read(codec, SGTL5000_CHIP_MIC_CTRL);
+ reg &= ~SGTL5000_BIAS_R_MASK;
+ reg |= SGTL5000_BIAS_R_off;
+ sgtl5000_write(codec, SGTL5000_CHIP_MIC_CTRL, reg);
+
/* must power up hp/line out before vag & dac to
- avoid pops. */
+ avoid pops. We leave most of sgtl5000 powered up
+ unless we go to suspend to avoid pops. */
reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_POWER);
if ((reg & SGTL5000_HP_POWERUP) == 0) {
reg |= SGTL5000_HP_POWERUP;
@@ -682,28 +700,6 @@ static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
sgtl5000_write(codec, SGTL5000_CHIP_ANA_POWER, reg);
msleep(400);
}
-
- reg = sgtl5000_read(codec, SGTL5000_CHIP_MIC_CTRL);
- reg &= ~SGTL5000_BIAS_R_MASK;
- reg |= SGTL5000_BIAS_R_4k << SGTL5000_BIAS_R_SHIFT;
- sgtl5000_write(codec, SGTL5000_CHIP_MIC_CTRL, reg);
-
- reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_CTRL);
- reg |= SGTL5000_HP_ZCD_EN;
- reg |= SGTL5000_ADC_ZCD_EN;
- sgtl5000_write(codec, SGTL5000_CHIP_ANA_CTRL, reg);
- break;
-
- case SND_SOC_BIAS_STANDBY: /* Off, with power */
- reg = sgtl5000_read(codec, SGTL5000_CHIP_MIC_CTRL);
- reg &= ~SGTL5000_BIAS_R_MASK;
- reg |= SGTL5000_BIAS_R_off;
- sgtl5000_write(codec, SGTL5000_CHIP_MIC_CTRL, reg);
-
- reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_CTRL);
- reg &= ~SGTL5000_HP_ZCD_EN;
- reg &= ~SGTL5000_ADC_ZCD_EN;
- sgtl5000_write(codec, SGTL5000_CHIP_ANA_CTRL, reg);
break;
case SND_SOC_BIAS_OFF: /* Off, without power */
@@ -965,7 +961,9 @@ static int sgtl5000_init(struct snd_soc_device *socdev)
| (0xf << SGTL5000_ADC_VOL_RIGHT_SHIFT);
sgtl5000_write(codec, SGTL5000_CHIP_ANA_ADC_CTRL, reg);
- reg = SGTL5000_LINE_OUT_MUTE | SGTL5000_HP_MUTE;
+ reg = SGTL5000_LINE_OUT_MUTE | SGTL5000_HP_MUTE |
+ SGTL5000_HP_ZCD_EN | SGTL5000_ADC_ZCD_EN;
+
sgtl5000_write(codec, SGTL5000_CHIP_ANA_CTRL, reg);
sgtl5000_write(codec, SGTL5000_CHIP_MIC_CTRL, 0);