ASoC: TWL4030: Handsfree pop removal redesign
Move the HandsfreeL/R (IHFL/R) pop removal code from the DAPM_MUX_E to a more appropriate DAPM_PGA_E widget. Also fix the power-up sequence to match with the TRM. The power-down sequence is not described in the TRM, so do it in a way, which seams like the correct sequence. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
committed by
Mark Brown
parent
0bc53a67ac
commit
5a2e9a48b1
@@ -546,27 +546,61 @@ static int micpath_event(struct snd_soc_dapm_widget *w,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handsfree_event(struct snd_soc_dapm_widget *w,
|
static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp)
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
|
||||||
{
|
{
|
||||||
struct soc_enum *e = (struct soc_enum *)w->kcontrols->private_value;
|
|
||||||
unsigned char hs_ctl;
|
unsigned char hs_ctl;
|
||||||
|
|
||||||
hs_ctl = twl4030_read_reg_cache(w->codec, e->reg);
|
hs_ctl = twl4030_read_reg_cache(codec, reg);
|
||||||
|
|
||||||
if (hs_ctl & TWL4030_HF_CTL_REF_EN) {
|
if (ramp) {
|
||||||
|
/* HF ramp-up */
|
||||||
|
hs_ctl |= TWL4030_HF_CTL_REF_EN;
|
||||||
|
twl4030_write(codec, reg, hs_ctl);
|
||||||
|
udelay(10);
|
||||||
hs_ctl |= TWL4030_HF_CTL_RAMP_EN;
|
hs_ctl |= TWL4030_HF_CTL_RAMP_EN;
|
||||||
twl4030_write(w->codec, e->reg, hs_ctl);
|
twl4030_write(codec, reg, hs_ctl);
|
||||||
|
udelay(40);
|
||||||
hs_ctl |= TWL4030_HF_CTL_LOOP_EN;
|
hs_ctl |= TWL4030_HF_CTL_LOOP_EN;
|
||||||
twl4030_write(w->codec, e->reg, hs_ctl);
|
|
||||||
hs_ctl |= TWL4030_HF_CTL_HB_EN;
|
hs_ctl |= TWL4030_HF_CTL_HB_EN;
|
||||||
twl4030_write(w->codec, e->reg, hs_ctl);
|
twl4030_write(codec, reg, hs_ctl);
|
||||||
} else {
|
} else {
|
||||||
hs_ctl &= ~(TWL4030_HF_CTL_RAMP_EN | TWL4030_HF_CTL_LOOP_EN
|
/* HF ramp-down */
|
||||||
| TWL4030_HF_CTL_HB_EN);
|
hs_ctl &= ~TWL4030_HF_CTL_LOOP_EN;
|
||||||
twl4030_write(w->codec, e->reg, hs_ctl);
|
hs_ctl &= ~TWL4030_HF_CTL_HB_EN;
|
||||||
|
twl4030_write(codec, reg, hs_ctl);
|
||||||
|
hs_ctl &= ~TWL4030_HF_CTL_RAMP_EN;
|
||||||
|
twl4030_write(codec, reg, hs_ctl);
|
||||||
|
udelay(40);
|
||||||
|
hs_ctl &= ~TWL4030_HF_CTL_REF_EN;
|
||||||
|
twl4030_write(codec, reg, hs_ctl);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handsfreelpga_event(struct snd_soc_dapm_widget *w,
|
||||||
|
struct snd_kcontrol *kcontrol, int event)
|
||||||
|
{
|
||||||
|
switch (event) {
|
||||||
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
|
handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 1);
|
||||||
|
break;
|
||||||
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
|
handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
|
||||||
|
struct snd_kcontrol *kcontrol, int event)
|
||||||
|
{
|
||||||
|
switch (event) {
|
||||||
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
|
handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 1);
|
||||||
|
break;
|
||||||
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
|
handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1190,12 +1224,16 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
|
|||||||
|
|
||||||
/* Output MUX controls */
|
/* Output MUX controls */
|
||||||
/* HandsfreeL/R */
|
/* HandsfreeL/R */
|
||||||
SND_SOC_DAPM_MUX_E("HandsfreeL Mux", TWL4030_REG_HFL_CTL, 5, 0,
|
SND_SOC_DAPM_MUX("HandsfreeL Mux", SND_SOC_NOPM, 0, 0,
|
||||||
&twl4030_dapm_handsfreel_control, handsfree_event,
|
&twl4030_dapm_handsfreel_control),
|
||||||
SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
|
SND_SOC_DAPM_PGA_E("HandsfreeL PGA", SND_SOC_NOPM,
|
||||||
SND_SOC_DAPM_MUX_E("HandsfreeR Mux", TWL4030_REG_HFR_CTL, 5, 0,
|
0, 0, NULL, 0, handsfreelpga_event,
|
||||||
&twl4030_dapm_handsfreer_control, handsfree_event,
|
SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
|
||||||
SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
|
SND_SOC_DAPM_MUX("HandsfreeR Mux", SND_SOC_NOPM, 5, 0,
|
||||||
|
&twl4030_dapm_handsfreer_control),
|
||||||
|
SND_SOC_DAPM_PGA_E("HandsfreeR PGA", SND_SOC_NOPM,
|
||||||
|
0, 0, NULL, 0, handsfreerpga_event,
|
||||||
|
SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
|
||||||
/* Vibra */
|
/* Vibra */
|
||||||
SND_SOC_DAPM_MUX("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0,
|
SND_SOC_DAPM_MUX("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0,
|
||||||
&twl4030_dapm_vibra_control),
|
&twl4030_dapm_vibra_control),
|
||||||
@@ -1303,11 +1341,13 @@ static const struct snd_soc_dapm_route intercon[] = {
|
|||||||
{"HandsfreeL Mux", "AudioL1", "Analog L1 Playback Mixer"},
|
{"HandsfreeL Mux", "AudioL1", "Analog L1 Playback Mixer"},
|
||||||
{"HandsfreeL Mux", "AudioL2", "Analog L2 Playback Mixer"},
|
{"HandsfreeL Mux", "AudioL2", "Analog L2 Playback Mixer"},
|
||||||
{"HandsfreeL Mux", "AudioR2", "Analog R2 Playback Mixer"},
|
{"HandsfreeL Mux", "AudioR2", "Analog R2 Playback Mixer"},
|
||||||
|
{"HandsfreeL PGA", NULL, "HandsfreeL Mux"},
|
||||||
/* HandsfreeR */
|
/* HandsfreeR */
|
||||||
{"HandsfreeR Mux", "Voice", "Analog Voice Playback Mixer"},
|
{"HandsfreeR Mux", "Voice", "Analog Voice Playback Mixer"},
|
||||||
{"HandsfreeR Mux", "AudioR1", "Analog R1 Playback Mixer"},
|
{"HandsfreeR Mux", "AudioR1", "Analog R1 Playback Mixer"},
|
||||||
{"HandsfreeR Mux", "AudioR2", "Analog R2 Playback Mixer"},
|
{"HandsfreeR Mux", "AudioR2", "Analog R2 Playback Mixer"},
|
||||||
{"HandsfreeR Mux", "AudioL2", "Analog L2 Playback Mixer"},
|
{"HandsfreeR Mux", "AudioL2", "Analog L2 Playback Mixer"},
|
||||||
|
{"HandsfreeR PGA", NULL, "HandsfreeR Mux"},
|
||||||
/* Vibra */
|
/* Vibra */
|
||||||
{"Vibra Mux", "AudioL1", "DAC Left1"},
|
{"Vibra Mux", "AudioL1", "DAC Left1"},
|
||||||
{"Vibra Mux", "AudioR1", "DAC Right1"},
|
{"Vibra Mux", "AudioR1", "DAC Right1"},
|
||||||
@@ -1324,8 +1364,8 @@ static const struct snd_soc_dapm_route intercon[] = {
|
|||||||
{"HSOR", NULL, "HeadsetR PGA"},
|
{"HSOR", NULL, "HeadsetR PGA"},
|
||||||
{"CARKITL", NULL, "CarkitL Mixer"},
|
{"CARKITL", NULL, "CarkitL Mixer"},
|
||||||
{"CARKITR", NULL, "CarkitR Mixer"},
|
{"CARKITR", NULL, "CarkitR Mixer"},
|
||||||
{"HFL", NULL, "HandsfreeL Mux"},
|
{"HFL", NULL, "HandsfreeL PGA"},
|
||||||
{"HFR", NULL, "HandsfreeR Mux"},
|
{"HFR", NULL, "HandsfreeR PGA"},
|
||||||
{"Vibra Route", "Audio", "Vibra Mux"},
|
{"Vibra Route", "Audio", "Vibra Mux"},
|
||||||
{"VIBRA", NULL, "Vibra Route"},
|
{"VIBRA", NULL, "Vibra Route"},
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user