diff options
author | Peter Ujfalusi <peter.ujfalusi@nokia.com> | 2009-10-28 04:57:04 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-10-28 06:04:21 -0400 |
commit | 78e08e2f209e5e7777e81919d32cfcddad126cfa (patch) | |
tree | ebdb55f705be7a74f994e9d6b7fc1c10a1a073ad /sound/soc/codecs/twl4030.c | |
parent | 7dea7c01dac9b74faa9afa93fc9bb5f2d37521dc (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.c | 128 |
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] = { | |||
122 | struct twl4030_priv { | 122 | struct 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 | ||
728 | static 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) | |||
1521 | static int twl4030_set_bias_level(struct snd_soc_codec *codec, | 1462 | static 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); |