aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/twl4030.c
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@nokia.com>2009-10-28 04:57:04 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-10-28 06:04:21 -0400
commit78e08e2f209e5e7777e81919d32cfcddad126cfa (patch)
treeebdb55f705be7a74f994e9d6b7fc1c10a1a073ad /sound/soc/codecs/twl4030.c
parent7dea7c01dac9b74faa9afa93fc9bb5f2d37521dc (diff)
ASoC: TWL4030: Remove bypass tracking
Since ASoC core now handling the codec bias differently there is no need to do the tracking of bypass switch states anymore. Handling of the common bit for analog loopbacks is done with DAPM_SUPPLY for the bypass paths. Now this bit is only enabled when there is a complete analog bypass path, compared to the previous implementation, when the global switch was enabled if there were any of the analog bypass switch was on (regardless if there were complete path or not) Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/twl4030.c')
-rw-r--r--sound/soc/codecs/twl4030.c128
1 files changed, 30 insertions, 98 deletions
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 5c5a4c0a424f..24002269f03a 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -122,7 +122,6 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
122struct twl4030_priv { 122struct twl4030_priv {
123 struct snd_soc_codec codec; 123 struct snd_soc_codec codec;
124 124
125 unsigned int bypass_state;
126 unsigned int codec_powered; 125 unsigned int codec_powered;
127 unsigned int codec_muted; 126 unsigned int codec_muted;
128 127
@@ -725,67 +724,6 @@ static int headsetrpga_event(struct snd_soc_dapm_widget *w,
725 return 0; 724 return 0;
726} 725}
727 726
728static int bypass_event(struct snd_soc_dapm_widget *w,
729 struct snd_kcontrol *kcontrol, int event)
730{
731 struct soc_mixer_control *m =
732 (struct soc_mixer_control *)w->kcontrols->private_value;
733 struct twl4030_priv *twl4030 = w->codec->private_data;
734 unsigned char reg, misc;
735
736 reg = twl4030_read_reg_cache(w->codec, m->reg);
737
738 /*
739 * bypass_state[0:3] - analog HiFi bypass
740 * bypass_state[4] - analog voice bypass
741 * bypass_state[5] - digital voice bypass
742 * bypass_state[6:7] - digital HiFi bypass
743 */
744 if (m->reg == TWL4030_REG_VSTPGA) {
745 /* Voice digital bypass */
746 if (reg)
747 twl4030->bypass_state |= (1 << 5);
748 else
749 twl4030->bypass_state &= ~(1 << 5);
750 } else if (m->reg <= TWL4030_REG_ARXR2_APGA_CTL) {
751 /* Analog bypass */
752 if (reg & (1 << m->shift))
753 twl4030->bypass_state |=
754 (1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
755 else
756 twl4030->bypass_state &=
757 ~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
758 } else if (m->reg == TWL4030_REG_VDL_APGA_CTL) {
759 /* Analog voice bypass */
760 if (reg & (1 << m->shift))
761 twl4030->bypass_state |= (1 << 4);
762 else
763 twl4030->bypass_state &= ~(1 << 4);
764 } else {
765 /* Digital bypass */
766 if (reg & (0x7 << m->shift))
767 twl4030->bypass_state |= (1 << (m->shift ? 7 : 6));
768 else
769 twl4030->bypass_state &= ~(1 << (m->shift ? 7 : 6));
770 }
771
772 /* Enable master analog loopback mode if any analog switch is enabled*/
773 misc = twl4030_read_reg_cache(w->codec, TWL4030_REG_MISC_SET_1);
774 if (twl4030->bypass_state & 0x1F)
775 misc |= TWL4030_FMLOOP_EN;
776 else
777 misc &= ~TWL4030_FMLOOP_EN;
778 twl4030_write(w->codec, TWL4030_REG_MISC_SET_1, misc);
779
780 if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) {
781 if (twl4030->bypass_state)
782 twl4030_codec_mute(w->codec, 0);
783 else
784 twl4030_codec_mute(w->codec, 1);
785 }
786 return 0;
787}
788
789/* 727/*
790 * Some of the gain controls in TWL (mostly those which are associated with 728 * Some of the gain controls in TWL (mostly those which are associated with
791 * the outputs) are implemented in an interesting way: 729 * the outputs) are implemented in an interesting way:
@@ -1193,32 +1131,28 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1193 SND_SOC_NOPM, 0, 0), 1131 SND_SOC_NOPM, 0, 0),
1194 1132
1195 /* Analog bypasses */ 1133 /* Analog bypasses */
1196 SND_SOC_DAPM_SWITCH_E("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0, 1134 SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1197 &twl4030_dapm_abypassr1_control, bypass_event, 1135 &twl4030_dapm_abypassr1_control),
1198 SND_SOC_DAPM_POST_REG), 1136 SND_SOC_DAPM_SWITCH("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1199 SND_SOC_DAPM_SWITCH_E("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0, 1137 &twl4030_dapm_abypassl1_control),
1200 &twl4030_dapm_abypassl1_control, 1138 SND_SOC_DAPM_SWITCH("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0,
1201 bypass_event, SND_SOC_DAPM_POST_REG), 1139 &twl4030_dapm_abypassr2_control),
1202 SND_SOC_DAPM_SWITCH_E("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0, 1140 SND_SOC_DAPM_SWITCH("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0,
1203 &twl4030_dapm_abypassr2_control, 1141 &twl4030_dapm_abypassl2_control),
1204 bypass_event, SND_SOC_DAPM_POST_REG), 1142 SND_SOC_DAPM_SWITCH("Voice Analog Loopback", SND_SOC_NOPM, 0, 0,
1205 SND_SOC_DAPM_SWITCH_E("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0, 1143 &twl4030_dapm_abypassv_control),
1206 &twl4030_dapm_abypassl2_control, 1144
1207 bypass_event, SND_SOC_DAPM_POST_REG), 1145 /* Master analog loopback switch */
1208 SND_SOC_DAPM_SWITCH_E("Voice Analog Loopback", SND_SOC_NOPM, 0, 0, 1146 SND_SOC_DAPM_SUPPLY("FM Loop Enable", TWL4030_REG_MISC_SET_1, 5, 0,
1209 &twl4030_dapm_abypassv_control, 1147 NULL, 0),
1210 bypass_event, SND_SOC_DAPM_POST_REG),
1211 1148
1212 /* Digital bypasses */ 1149 /* Digital bypasses */
1213 SND_SOC_DAPM_SWITCH_E("Left Digital Loopback", SND_SOC_NOPM, 0, 0, 1150 SND_SOC_DAPM_SWITCH("Left Digital Loopback", SND_SOC_NOPM, 0, 0,
1214 &twl4030_dapm_dbypassl_control, bypass_event, 1151 &twl4030_dapm_dbypassl_control),
1215 SND_SOC_DAPM_POST_REG), 1152 SND_SOC_DAPM_SWITCH("Right Digital Loopback", SND_SOC_NOPM, 0, 0,
1216 SND_SOC_DAPM_SWITCH_E("Right Digital Loopback", SND_SOC_NOPM, 0, 0, 1153 &twl4030_dapm_dbypassr_control),
1217 &twl4030_dapm_dbypassr_control, bypass_event, 1154 SND_SOC_DAPM_SWITCH("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
1218 SND_SOC_DAPM_POST_REG), 1155 &twl4030_dapm_dbypassv_control),
1219 SND_SOC_DAPM_SWITCH_E("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
1220 &twl4030_dapm_dbypassv_control, bypass_event,
1221 SND_SOC_DAPM_POST_REG),
1222 1156
1223 /* Digital mixers, power control for the physical DACs */ 1157 /* Digital mixers, power control for the physical DACs */
1224 SND_SOC_DAPM_MIXER("Digital R1 Playback Mixer", 1158 SND_SOC_DAPM_MIXER("Digital R1 Playback Mixer",
@@ -1490,6 +1424,13 @@ static const struct snd_soc_dapm_route intercon[] = {
1490 {"Left2 Analog Loopback", "Switch", "Analog Left"}, 1424 {"Left2 Analog Loopback", "Switch", "Analog Left"},
1491 {"Voice Analog Loopback", "Switch", "Analog Left"}, 1425 {"Voice Analog Loopback", "Switch", "Analog Left"},
1492 1426
1427 /* Supply for the Analog loopbacks */
1428 {"Right1 Analog Loopback", NULL, "FM Loop Enable"},
1429 {"Left1 Analog Loopback", NULL, "FM Loop Enable"},
1430 {"Right2 Analog Loopback", NULL, "FM Loop Enable"},
1431 {"Left2 Analog Loopback", NULL, "FM Loop Enable"},
1432 {"Voice Analog Loopback", NULL, "FM Loop Enable"},
1433
1493 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"}, 1434 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"},
1494 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"}, 1435 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"},
1495 {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"}, 1436 {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"},
@@ -1521,25 +1462,16 @@ static int twl4030_add_widgets(struct snd_soc_codec *codec)
1521static int twl4030_set_bias_level(struct snd_soc_codec *codec, 1462static int twl4030_set_bias_level(struct snd_soc_codec *codec,
1522 enum snd_soc_bias_level level) 1463 enum snd_soc_bias_level level)
1523{ 1464{
1524 struct twl4030_priv *twl4030 = codec->private_data;
1525
1526 switch (level) { 1465 switch (level) {
1527 case SND_SOC_BIAS_ON: 1466 case SND_SOC_BIAS_ON:
1528 twl4030_codec_mute(codec, 0); 1467 twl4030_codec_mute(codec, 0);
1529 break; 1468 break;
1530 case SND_SOC_BIAS_PREPARE: 1469 case SND_SOC_BIAS_PREPARE:
1531 twl4030_power_up(codec);
1532 if (twl4030->bypass_state)
1533 twl4030_codec_mute(codec, 0);
1534 else
1535 twl4030_codec_mute(codec, 1);
1536 break; 1470 break;
1537 case SND_SOC_BIAS_STANDBY: 1471 case SND_SOC_BIAS_STANDBY:
1538 twl4030_power_up(codec); 1472 if (codec->bias_level == SND_SOC_BIAS_OFF)
1539 if (twl4030->bypass_state) 1473 twl4030_power_up(codec);
1540 twl4030_codec_mute(codec, 0); 1474 twl4030_codec_mute(codec, 1);
1541 else
1542 twl4030_codec_mute(codec, 1);
1543 break; 1475 break;
1544 case SND_SOC_BIAS_OFF: 1476 case SND_SOC_BIAS_OFF:
1545 twl4030_power_down(codec); 1477 twl4030_power_down(codec);