aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@nokia.com>2009-05-25 04:12:11 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-05-25 06:54:13 -0400
commit5a2e9a48b1d6de35ae5efea35d117133c3eb30f2 (patch)
tree264a6320bc0275043cbfe66a2214fd3e8075491b /sound/soc
parent0bc53a67ac831ec84f730a657dbcadd80a589ef5 (diff)
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>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/twl4030.c78
1 files changed, 59 insertions, 19 deletions
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 9197fdd0a29d..17ddcb265134 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -546,27 +546,61 @@ static int micpath_event(struct snd_soc_dapm_widget *w,
546 return 0; 546 return 0;
547} 547}
548 548
549static int handsfree_event(struct snd_soc_dapm_widget *w, 549static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp)
550 struct snd_kcontrol *kcontrol, int event)
551{ 550{
552 struct soc_enum *e = (struct soc_enum *)w->kcontrols->private_value;
553 unsigned char hs_ctl; 551 unsigned char hs_ctl;
554 552
555 hs_ctl = twl4030_read_reg_cache(w->codec, e->reg); 553 hs_ctl = twl4030_read_reg_cache(codec, reg);
556 554
557 if (hs_ctl & TWL4030_HF_CTL_REF_EN) { 555 if (ramp) {
556 /* HF ramp-up */
557 hs_ctl |= TWL4030_HF_CTL_REF_EN;
558 twl4030_write(codec, reg, hs_ctl);
559 udelay(10);
558 hs_ctl |= TWL4030_HF_CTL_RAMP_EN; 560 hs_ctl |= TWL4030_HF_CTL_RAMP_EN;
559 twl4030_write(w->codec, e->reg, hs_ctl); 561 twl4030_write(codec, reg, hs_ctl);
562 udelay(40);
560 hs_ctl |= TWL4030_HF_CTL_LOOP_EN; 563 hs_ctl |= TWL4030_HF_CTL_LOOP_EN;
561 twl4030_write(w->codec, e->reg, hs_ctl);
562 hs_ctl |= TWL4030_HF_CTL_HB_EN; 564 hs_ctl |= TWL4030_HF_CTL_HB_EN;
563 twl4030_write(w->codec, e->reg, hs_ctl); 565 twl4030_write(codec, reg, hs_ctl);
564 } else { 566 } else {
565 hs_ctl &= ~(TWL4030_HF_CTL_RAMP_EN | TWL4030_HF_CTL_LOOP_EN 567 /* HF ramp-down */
566 | TWL4030_HF_CTL_HB_EN); 568 hs_ctl &= ~TWL4030_HF_CTL_LOOP_EN;
567 twl4030_write(w->codec, e->reg, hs_ctl); 569 hs_ctl &= ~TWL4030_HF_CTL_HB_EN;
570 twl4030_write(codec, reg, hs_ctl);
571 hs_ctl &= ~TWL4030_HF_CTL_RAMP_EN;
572 twl4030_write(codec, reg, hs_ctl);
573 udelay(40);
574 hs_ctl &= ~TWL4030_HF_CTL_REF_EN;
575 twl4030_write(codec, reg, hs_ctl);
568 } 576 }
577}
569 578
579static int handsfreelpga_event(struct snd_soc_dapm_widget *w,
580 struct snd_kcontrol *kcontrol, int event)
581{
582 switch (event) {
583 case SND_SOC_DAPM_POST_PMU:
584 handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 1);
585 break;
586 case SND_SOC_DAPM_POST_PMD:
587 handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 0);
588 break;
589 }
590 return 0;
591}
592
593static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
594 struct snd_kcontrol *kcontrol, int event)
595{
596 switch (event) {
597 case SND_SOC_DAPM_POST_PMU:
598 handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 1);
599 break;
600 case SND_SOC_DAPM_POST_PMD:
601 handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 0);
602 break;
603 }
570 return 0; 604 return 0;
571} 605}
572 606
@@ -1190,12 +1224,16 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1190 1224
1191 /* Output MUX controls */ 1225 /* Output MUX controls */
1192 /* HandsfreeL/R */ 1226 /* HandsfreeL/R */
1193 SND_SOC_DAPM_MUX_E("HandsfreeL Mux", TWL4030_REG_HFL_CTL, 5, 0, 1227 SND_SOC_DAPM_MUX("HandsfreeL Mux", SND_SOC_NOPM, 0, 0,
1194 &twl4030_dapm_handsfreel_control, handsfree_event, 1228 &twl4030_dapm_handsfreel_control),
1195 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), 1229 SND_SOC_DAPM_PGA_E("HandsfreeL PGA", SND_SOC_NOPM,
1196 SND_SOC_DAPM_MUX_E("HandsfreeR Mux", TWL4030_REG_HFR_CTL, 5, 0, 1230 0, 0, NULL, 0, handsfreelpga_event,
1197 &twl4030_dapm_handsfreer_control, handsfree_event, 1231 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1198 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), 1232 SND_SOC_DAPM_MUX("HandsfreeR Mux", SND_SOC_NOPM, 5, 0,
1233 &twl4030_dapm_handsfreer_control),
1234 SND_SOC_DAPM_PGA_E("HandsfreeR PGA", SND_SOC_NOPM,
1235 0, 0, NULL, 0, handsfreerpga_event,
1236 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1199 /* Vibra */ 1237 /* Vibra */
1200 SND_SOC_DAPM_MUX("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0, 1238 SND_SOC_DAPM_MUX("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0,
1201 &twl4030_dapm_vibra_control), 1239 &twl4030_dapm_vibra_control),
@@ -1303,11 +1341,13 @@ static const struct snd_soc_dapm_route intercon[] = {
1303 {"HandsfreeL Mux", "AudioL1", "Analog L1 Playback Mixer"}, 1341 {"HandsfreeL Mux", "AudioL1", "Analog L1 Playback Mixer"},
1304 {"HandsfreeL Mux", "AudioL2", "Analog L2 Playback Mixer"}, 1342 {"HandsfreeL Mux", "AudioL2", "Analog L2 Playback Mixer"},
1305 {"HandsfreeL Mux", "AudioR2", "Analog R2 Playback Mixer"}, 1343 {"HandsfreeL Mux", "AudioR2", "Analog R2 Playback Mixer"},
1344 {"HandsfreeL PGA", NULL, "HandsfreeL Mux"},
1306 /* HandsfreeR */ 1345 /* HandsfreeR */
1307 {"HandsfreeR Mux", "Voice", "Analog Voice Playback Mixer"}, 1346 {"HandsfreeR Mux", "Voice", "Analog Voice Playback Mixer"},
1308 {"HandsfreeR Mux", "AudioR1", "Analog R1 Playback Mixer"}, 1347 {"HandsfreeR Mux", "AudioR1", "Analog R1 Playback Mixer"},
1309 {"HandsfreeR Mux", "AudioR2", "Analog R2 Playback Mixer"}, 1348 {"HandsfreeR Mux", "AudioR2", "Analog R2 Playback Mixer"},
1310 {"HandsfreeR Mux", "AudioL2", "Analog L2 Playback Mixer"}, 1349 {"HandsfreeR Mux", "AudioL2", "Analog L2 Playback Mixer"},
1350 {"HandsfreeR PGA", NULL, "HandsfreeR Mux"},
1311 /* Vibra */ 1351 /* Vibra */
1312 {"Vibra Mux", "AudioL1", "DAC Left1"}, 1352 {"Vibra Mux", "AudioL1", "DAC Left1"},
1313 {"Vibra Mux", "AudioR1", "DAC Right1"}, 1353 {"Vibra Mux", "AudioR1", "DAC Right1"},
@@ -1324,8 +1364,8 @@ static const struct snd_soc_dapm_route intercon[] = {
1324 {"HSOR", NULL, "HeadsetR PGA"}, 1364 {"HSOR", NULL, "HeadsetR PGA"},
1325 {"CARKITL", NULL, "CarkitL Mixer"}, 1365 {"CARKITL", NULL, "CarkitL Mixer"},
1326 {"CARKITR", NULL, "CarkitR Mixer"}, 1366 {"CARKITR", NULL, "CarkitR Mixer"},
1327 {"HFL", NULL, "HandsfreeL Mux"}, 1367 {"HFL", NULL, "HandsfreeL PGA"},
1328 {"HFR", NULL, "HandsfreeR Mux"}, 1368 {"HFR", NULL, "HandsfreeR PGA"},
1329 {"Vibra Route", "Audio", "Vibra Mux"}, 1369 {"Vibra Route", "Audio", "Vibra Mux"},
1330 {"VIBRA", NULL, "Vibra Route"}, 1370 {"VIBRA", NULL, "Vibra Route"},
1331 1371