aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@nokia.com>2010-08-03 05:01:01 -0400
committerLiam Girdwood <lrg@slimlogic.co.uk>2010-08-03 19:42:39 -0400
commitbda7d2a862e6b788bca2d02d38a07966a9c92e48 (patch)
tree0ddfb02805bc532161bbba899d2fbddebce07d88
parent116bcd9cf22c00c22402c2a2be6ef8e81289a574 (diff)
ASoC: TWL4030: Capture route runtime DAPM ordering fix
Fix the ordering problem in DAPM domain, when the user changes between digital and analog sources during active capture (or loopback) scenario. Before this patch, when the user changed from analog source to digital there were a short time, when the codec enabled analog mic bias (2.2 volts) instead of the correct digital mic bias (1.8 volts) to the digital microphones. This behaviour caused by the former implementation of selecting the correct type of bias. This was done at the POST_REG event of the DAPM_MUX_E("TXx Capture Route") widget. By moving the bias type selection as DAPM_SUPPLY and connecting it to the corresponding digimic widget the problematic situation can be avoided. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
-rw-r--r--sound/soc/codecs/twl4030.c48
1 files changed, 12 insertions, 36 deletions
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index d401c597d38f..7b618bbff884 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -577,36 +577,6 @@ static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control =
577 TWL4030_REG_VSTPGA, 0, 0x29, 0, 577 TWL4030_REG_VSTPGA, 0, 0x29, 0,
578 twl4030_dapm_dbypassv_tlv); 578 twl4030_dapm_dbypassv_tlv);
579 579
580static int micpath_event(struct snd_soc_dapm_widget *w,
581 struct snd_kcontrol *kcontrol, int event)
582{
583 struct soc_enum *e = (struct soc_enum *)w->kcontrols->private_value;
584 unsigned char adcmicsel, micbias_ctl;
585
586 adcmicsel = twl4030_read_reg_cache(w->codec, TWL4030_REG_ADCMICSEL);
587 micbias_ctl = twl4030_read_reg_cache(w->codec, TWL4030_REG_MICBIAS_CTL);
588 /* Prepare the bits for the given TX path:
589 * shift_l == 0: TX1 microphone path
590 * shift_l == 2: TX2 microphone path */
591 if (e->shift_l) {
592 /* TX2 microphone path */
593 if (adcmicsel & TWL4030_TX2IN_SEL)
594 micbias_ctl |= TWL4030_MICBIAS2_CTL; /* digimic */
595 else
596 micbias_ctl &= ~TWL4030_MICBIAS2_CTL;
597 } else {
598 /* TX1 microphone path */
599 if (adcmicsel & TWL4030_TX1IN_SEL)
600 micbias_ctl |= TWL4030_MICBIAS1_CTL; /* digimic */
601 else
602 micbias_ctl &= ~TWL4030_MICBIAS1_CTL;
603 }
604
605 twl4030_write(w->codec, TWL4030_REG_MICBIAS_CTL, micbias_ctl);
606
607 return 0;
608}
609
610/* 580/*
611 * Output PGA builder: 581 * Output PGA builder:
612 * Handle the muting and unmuting of the given output (turning off the 582 * Handle the muting and unmuting of the given output (turning off the
@@ -1430,12 +1400,10 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1430 /* Analog/Digital mic path selection. 1400 /* Analog/Digital mic path selection.
1431 TX1 Left/Right: either analog Left/Right or Digimic0 1401 TX1 Left/Right: either analog Left/Right or Digimic0
1432 TX2 Left/Right: either analog Left/Right or Digimic1 */ 1402 TX2 Left/Right: either analog Left/Right or Digimic1 */
1433 SND_SOC_DAPM_MUX_E("TX1 Capture Route", SND_SOC_NOPM, 0, 0, 1403 SND_SOC_DAPM_MUX("TX1 Capture Route", SND_SOC_NOPM, 0, 0,
1434 &twl4030_dapm_micpathtx1_control, micpath_event, 1404 &twl4030_dapm_micpathtx1_control),
1435 SND_SOC_DAPM_POST_REG), 1405 SND_SOC_DAPM_MUX("TX2 Capture Route", SND_SOC_NOPM, 0, 0,
1436 SND_SOC_DAPM_MUX_E("TX2 Capture Route", SND_SOC_NOPM, 0, 0, 1406 &twl4030_dapm_micpathtx2_control),
1437 &twl4030_dapm_micpathtx2_control, micpath_event,
1438 SND_SOC_DAPM_POST_REG),
1439 1407
1440 /* Analog input mixers for the capture amplifiers */ 1408 /* Analog input mixers for the capture amplifiers */
1441 SND_SOC_DAPM_MIXER("Analog Left", 1409 SND_SOC_DAPM_MIXER("Analog Left",
@@ -1459,6 +1427,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1459 TWL4030_REG_ADCMICSEL, 3, 0, NULL, 0, 1427 TWL4030_REG_ADCMICSEL, 3, 0, NULL, 0,
1460 digimic_event, SND_SOC_DAPM_POST_PMU), 1428 digimic_event, SND_SOC_DAPM_POST_PMU),
1461 1429
1430 SND_SOC_DAPM_SUPPLY("micbias1 select", TWL4030_REG_MICBIAS_CTL, 5, 0,
1431 NULL, 0),
1432 SND_SOC_DAPM_SUPPLY("micbias2 select", TWL4030_REG_MICBIAS_CTL, 6, 0,
1433 NULL, 0),
1434
1462 SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0), 1435 SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0),
1463 SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0), 1436 SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0),
1464 SND_SOC_DAPM_MICBIAS("Headset Mic Bias", TWL4030_REG_MICBIAS_CTL, 2, 0), 1437 SND_SOC_DAPM_MICBIAS("Headset Mic Bias", TWL4030_REG_MICBIAS_CTL, 2, 0),
@@ -1590,6 +1563,9 @@ static const struct snd_soc_dapm_route intercon[] = {
1590 {"Digimic0 Enable", NULL, "DIGIMIC0"}, 1563 {"Digimic0 Enable", NULL, "DIGIMIC0"},
1591 {"Digimic1 Enable", NULL, "DIGIMIC1"}, 1564 {"Digimic1 Enable", NULL, "DIGIMIC1"},
1592 1565
1566 {"DIGIMIC0", NULL, "micbias1 select"},
1567 {"DIGIMIC1", NULL, "micbias2 select"},
1568
1593 /* TX1 Left capture path */ 1569 /* TX1 Left capture path */
1594 {"TX1 Capture Route", "Analog", "ADC Physical Left"}, 1570 {"TX1 Capture Route", "Analog", "ADC Physical Left"},
1595 {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"}, 1571 {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"},