diff options
Diffstat (limited to 'sound/soc/codecs/twl4030.c')
-rw-r--r-- | sound/soc/codecs/twl4030.c | 203 |
1 files changed, 144 insertions, 59 deletions
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 520ffd6536c3..b4fcdb01fc49 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
@@ -124,6 +124,8 @@ struct twl4030_priv { | |||
124 | struct snd_soc_codec codec; | 124 | struct snd_soc_codec codec; |
125 | 125 | ||
126 | unsigned int codec_powered; | 126 | unsigned int codec_powered; |
127 | |||
128 | /* reference counts of AIF/APLL users */ | ||
127 | unsigned int apll_enabled; | 129 | unsigned int apll_enabled; |
128 | 130 | ||
129 | struct snd_pcm_substream *master_substream; | 131 | struct snd_pcm_substream *master_substream; |
@@ -136,9 +138,11 @@ struct twl4030_priv { | |||
136 | 138 | ||
137 | unsigned int sysclk; | 139 | unsigned int sysclk; |
138 | 140 | ||
139 | /* Headset output state handling */ | 141 | /* Output (with associated amp) states */ |
140 | unsigned int hsl_enabled; | 142 | u8 hsl_enabled, hsr_enabled; |
141 | unsigned int hsr_enabled; | 143 | u8 earpiece_enabled; |
144 | u8 predrivel_enabled, predriver_enabled; | ||
145 | u8 carkitl_enabled, carkitr_enabled; | ||
142 | }; | 146 | }; |
143 | 147 | ||
144 | /* | 148 | /* |
@@ -174,17 +178,52 @@ static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec, | |||
174 | static int twl4030_write(struct snd_soc_codec *codec, | 178 | static int twl4030_write(struct snd_soc_codec *codec, |
175 | unsigned int reg, unsigned int value) | 179 | unsigned int reg, unsigned int value) |
176 | { | 180 | { |
181 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | ||
182 | int write_to_reg = 0; | ||
183 | |||
177 | twl4030_write_reg_cache(codec, reg, value); | 184 | twl4030_write_reg_cache(codec, reg, value); |
178 | if (likely(reg < TWL4030_REG_SW_SHADOW)) | 185 | if (likely(reg < TWL4030_REG_SW_SHADOW)) { |
179 | return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, | 186 | /* Decide if the given register can be written */ |
180 | reg); | 187 | switch (reg) { |
181 | else | 188 | case TWL4030_REG_EAR_CTL: |
182 | return 0; | 189 | if (twl4030->earpiece_enabled) |
190 | write_to_reg = 1; | ||
191 | break; | ||
192 | case TWL4030_REG_PREDL_CTL: | ||
193 | if (twl4030->predrivel_enabled) | ||
194 | write_to_reg = 1; | ||
195 | break; | ||
196 | case TWL4030_REG_PREDR_CTL: | ||
197 | if (twl4030->predriver_enabled) | ||
198 | write_to_reg = 1; | ||
199 | break; | ||
200 | case TWL4030_REG_PRECKL_CTL: | ||
201 | if (twl4030->carkitl_enabled) | ||
202 | write_to_reg = 1; | ||
203 | break; | ||
204 | case TWL4030_REG_PRECKR_CTL: | ||
205 | if (twl4030->carkitr_enabled) | ||
206 | write_to_reg = 1; | ||
207 | break; | ||
208 | case TWL4030_REG_HS_GAIN_SET: | ||
209 | if (twl4030->hsl_enabled || twl4030->hsr_enabled) | ||
210 | write_to_reg = 1; | ||
211 | break; | ||
212 | default: | ||
213 | /* All other register can be written */ | ||
214 | write_to_reg = 1; | ||
215 | break; | ||
216 | } | ||
217 | if (write_to_reg) | ||
218 | return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
219 | value, reg); | ||
220 | } | ||
221 | return 0; | ||
183 | } | 222 | } |
184 | 223 | ||
185 | static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) | 224 | static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) |
186 | { | 225 | { |
187 | struct twl4030_priv *twl4030 = codec->private_data; | 226 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
188 | int mode; | 227 | int mode; |
189 | 228 | ||
190 | if (enable == twl4030->codec_powered) | 229 | if (enable == twl4030->codec_powered) |
@@ -222,28 +261,28 @@ static void twl4030_init_chip(struct snd_soc_codec *codec) | |||
222 | 261 | ||
223 | static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable) | 262 | static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable) |
224 | { | 263 | { |
225 | struct twl4030_priv *twl4030 = codec->private_data; | 264 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
226 | int status; | 265 | int status = -1; |
227 | 266 | ||
228 | if (enable == twl4030->apll_enabled) | 267 | if (enable) { |
229 | return; | 268 | twl4030->apll_enabled++; |
230 | 269 | if (twl4030->apll_enabled == 1) | |
231 | if (enable) | 270 | status = twl4030_codec_enable_resource( |
232 | /* Enable PLL */ | 271 | TWL4030_CODEC_RES_APLL); |
233 | status = twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL); | 272 | } else { |
234 | else | 273 | twl4030->apll_enabled--; |
235 | /* Disable PLL */ | 274 | if (!twl4030->apll_enabled) |
236 | status = twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL); | 275 | status = twl4030_codec_disable_resource( |
276 | TWL4030_CODEC_RES_APLL); | ||
277 | } | ||
237 | 278 | ||
238 | if (status >= 0) | 279 | if (status >= 0) |
239 | twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status); | 280 | twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status); |
240 | |||
241 | twl4030->apll_enabled = enable; | ||
242 | } | 281 | } |
243 | 282 | ||
244 | static void twl4030_power_up(struct snd_soc_codec *codec) | 283 | static void twl4030_power_up(struct snd_soc_codec *codec) |
245 | { | 284 | { |
246 | struct twl4030_priv *twl4030 = codec->private_data; | 285 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
247 | u8 anamicl, regmisc1, byte; | 286 | u8 anamicl, regmisc1, byte; |
248 | int i = 0; | 287 | int i = 0; |
249 | 288 | ||
@@ -526,26 +565,26 @@ static int micpath_event(struct snd_soc_dapm_widget *w, | |||
526 | * Output PGA builder: | 565 | * Output PGA builder: |
527 | * Handle the muting and unmuting of the given output (turning off the | 566 | * Handle the muting and unmuting of the given output (turning off the |
528 | * amplifier associated with the output pin) | 567 | * amplifier associated with the output pin) |
529 | * On mute bypass the reg_cache and mute the volume | 568 | * On mute bypass the reg_cache and write 0 to the register |
530 | * On unmute: restore the register content | 569 | * On unmute: restore the register content from the reg_cache |
531 | * Outputs handled in this way: Earpiece, PreDrivL/R, CarkitL/R | 570 | * Outputs handled in this way: Earpiece, PreDrivL/R, CarkitL/R |
532 | */ | 571 | */ |
533 | #define TWL4030_OUTPUT_PGA(pin_name, reg, mask) \ | 572 | #define TWL4030_OUTPUT_PGA(pin_name, reg, mask) \ |
534 | static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \ | 573 | static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \ |
535 | struct snd_kcontrol *kcontrol, int event) \ | 574 | struct snd_kcontrol *kcontrol, int event) \ |
536 | { \ | 575 | { \ |
537 | u8 reg_val; \ | 576 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); \ |
538 | \ | 577 | \ |
539 | switch (event) { \ | 578 | switch (event) { \ |
540 | case SND_SOC_DAPM_POST_PMU: \ | 579 | case SND_SOC_DAPM_POST_PMU: \ |
580 | twl4030->pin_name##_enabled = 1; \ | ||
541 | twl4030_write(w->codec, reg, \ | 581 | twl4030_write(w->codec, reg, \ |
542 | twl4030_read_reg_cache(w->codec, reg)); \ | 582 | twl4030_read_reg_cache(w->codec, reg)); \ |
543 | break; \ | 583 | break; \ |
544 | case SND_SOC_DAPM_POST_PMD: \ | 584 | case SND_SOC_DAPM_POST_PMD: \ |
545 | reg_val = twl4030_read_reg_cache(w->codec, reg); \ | 585 | twl4030->pin_name##_enabled = 0; \ |
546 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \ | 586 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \ |
547 | reg_val & (~mask), \ | 587 | 0, reg); \ |
548 | reg); \ | ||
549 | break; \ | 588 | break; \ |
550 | } \ | 589 | } \ |
551 | return 0; \ | 590 | return 0; \ |
@@ -636,13 +675,38 @@ static int apll_event(struct snd_soc_dapm_widget *w, | |||
636 | return 0; | 675 | return 0; |
637 | } | 676 | } |
638 | 677 | ||
678 | static int aif_event(struct snd_soc_dapm_widget *w, | ||
679 | struct snd_kcontrol *kcontrol, int event) | ||
680 | { | ||
681 | u8 audio_if; | ||
682 | |||
683 | audio_if = twl4030_read_reg_cache(w->codec, TWL4030_REG_AUDIO_IF); | ||
684 | switch (event) { | ||
685 | case SND_SOC_DAPM_PRE_PMU: | ||
686 | /* Enable AIF */ | ||
687 | /* enable the PLL before we use it to clock the DAI */ | ||
688 | twl4030_apll_enable(w->codec, 1); | ||
689 | |||
690 | twl4030_write(w->codec, TWL4030_REG_AUDIO_IF, | ||
691 | audio_if | TWL4030_AIF_EN); | ||
692 | break; | ||
693 | case SND_SOC_DAPM_POST_PMD: | ||
694 | /* disable the DAI before we stop it's source PLL */ | ||
695 | twl4030_write(w->codec, TWL4030_REG_AUDIO_IF, | ||
696 | audio_if & ~TWL4030_AIF_EN); | ||
697 | twl4030_apll_enable(w->codec, 0); | ||
698 | break; | ||
699 | } | ||
700 | return 0; | ||
701 | } | ||
702 | |||
639 | static void headset_ramp(struct snd_soc_codec *codec, int ramp) | 703 | static void headset_ramp(struct snd_soc_codec *codec, int ramp) |
640 | { | 704 | { |
641 | struct snd_soc_device *socdev = codec->socdev; | 705 | struct snd_soc_device *socdev = codec->socdev; |
642 | struct twl4030_setup_data *setup = socdev->codec_data; | 706 | struct twl4030_setup_data *setup = socdev->codec_data; |
643 | 707 | ||
644 | unsigned char hs_gain, hs_pop; | 708 | unsigned char hs_gain, hs_pop; |
645 | struct twl4030_priv *twl4030 = codec->private_data; | 709 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
646 | /* Base values for ramp delay calculation: 2^19 - 2^26 */ | 710 | /* Base values for ramp delay calculation: 2^19 - 2^26 */ |
647 | unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304, | 711 | unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304, |
648 | 8388608, 16777216, 33554432, 67108864}; | 712 | 8388608, 16777216, 33554432, 67108864}; |
@@ -665,7 +729,10 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) | |||
665 | /* Headset ramp-up according to the TRM */ | 729 | /* Headset ramp-up according to the TRM */ |
666 | hs_pop |= TWL4030_VMID_EN; | 730 | hs_pop |= TWL4030_VMID_EN; |
667 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); | 731 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); |
668 | twl4030_write(codec, TWL4030_REG_HS_GAIN_SET, hs_gain); | 732 | /* Actually write to the register */ |
733 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
734 | hs_gain, | ||
735 | TWL4030_REG_HS_GAIN_SET); | ||
669 | hs_pop |= TWL4030_RAMP_EN; | 736 | hs_pop |= TWL4030_RAMP_EN; |
670 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); | 737 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); |
671 | /* Wait ramp delay time + 1, so the VMID can settle */ | 738 | /* Wait ramp delay time + 1, so the VMID can settle */ |
@@ -702,7 +769,7 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) | |||
702 | static int headsetlpga_event(struct snd_soc_dapm_widget *w, | 769 | static int headsetlpga_event(struct snd_soc_dapm_widget *w, |
703 | struct snd_kcontrol *kcontrol, int event) | 770 | struct snd_kcontrol *kcontrol, int event) |
704 | { | 771 | { |
705 | struct twl4030_priv *twl4030 = w->codec->private_data; | 772 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); |
706 | 773 | ||
707 | switch (event) { | 774 | switch (event) { |
708 | case SND_SOC_DAPM_POST_PMU: | 775 | case SND_SOC_DAPM_POST_PMU: |
@@ -726,7 +793,7 @@ static int headsetlpga_event(struct snd_soc_dapm_widget *w, | |||
726 | static int headsetrpga_event(struct snd_soc_dapm_widget *w, | 793 | static int headsetrpga_event(struct snd_soc_dapm_widget *w, |
727 | struct snd_kcontrol *kcontrol, int event) | 794 | struct snd_kcontrol *kcontrol, int event) |
728 | { | 795 | { |
729 | struct twl4030_priv *twl4030 = w->codec->private_data; | 796 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); |
730 | 797 | ||
731 | switch (event) { | 798 | switch (event) { |
732 | case SND_SOC_DAPM_POST_PMU: | 799 | case SND_SOC_DAPM_POST_PMU: |
@@ -918,7 +985,7 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, | |||
918 | struct snd_ctl_elem_value *ucontrol) | 985 | struct snd_ctl_elem_value *ucontrol) |
919 | { | 986 | { |
920 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 987 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
921 | struct twl4030_priv *twl4030 = codec->private_data; | 988 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
922 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | 989 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
923 | unsigned short val; | 990 | unsigned short val; |
924 | unsigned short mask, bitmask; | 991 | unsigned short mask, bitmask; |
@@ -1036,6 +1103,16 @@ static const struct soc_enum twl4030_vibradir_enum = | |||
1036 | ARRAY_SIZE(twl4030_vibradir_texts), | 1103 | ARRAY_SIZE(twl4030_vibradir_texts), |
1037 | twl4030_vibradir_texts); | 1104 | twl4030_vibradir_texts); |
1038 | 1105 | ||
1106 | /* Digimic Left and right swapping */ | ||
1107 | static const char *twl4030_digimicswap_texts[] = { | ||
1108 | "Not swapped", "Swapped", | ||
1109 | }; | ||
1110 | |||
1111 | static const struct soc_enum twl4030_digimicswap_enum = | ||
1112 | SOC_ENUM_SINGLE(TWL4030_REG_MISC_SET_1, 0, | ||
1113 | ARRAY_SIZE(twl4030_digimicswap_texts), | ||
1114 | twl4030_digimicswap_texts); | ||
1115 | |||
1039 | static const struct snd_kcontrol_new twl4030_snd_controls[] = { | 1116 | static const struct snd_kcontrol_new twl4030_snd_controls[] = { |
1040 | /* Codec operation mode control */ | 1117 | /* Codec operation mode control */ |
1041 | SOC_ENUM_EXT("Codec Operation Mode", twl4030_op_modes_enum, | 1118 | SOC_ENUM_EXT("Codec Operation Mode", twl4030_op_modes_enum, |
@@ -1112,6 +1189,8 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = { | |||
1112 | 1189 | ||
1113 | SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum), | 1190 | SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum), |
1114 | SOC_ENUM("Vibra H-bridge direction", twl4030_vibradir_enum), | 1191 | SOC_ENUM("Vibra H-bridge direction", twl4030_vibradir_enum), |
1192 | |||
1193 | SOC_ENUM("Digimic LR Swap", twl4030_digimicswap_enum), | ||
1115 | }; | 1194 | }; |
1116 | 1195 | ||
1117 | static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { | 1196 | static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { |
@@ -1128,8 +1207,6 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { | |||
1128 | SND_SOC_DAPM_INPUT("DIGIMIC1"), | 1207 | SND_SOC_DAPM_INPUT("DIGIMIC1"), |
1129 | 1208 | ||
1130 | /* Outputs */ | 1209 | /* Outputs */ |
1131 | SND_SOC_DAPM_OUTPUT("OUTL"), | ||
1132 | SND_SOC_DAPM_OUTPUT("OUTR"), | ||
1133 | SND_SOC_DAPM_OUTPUT("EARPIECE"), | 1210 | SND_SOC_DAPM_OUTPUT("EARPIECE"), |
1134 | SND_SOC_DAPM_OUTPUT("PREDRIVEL"), | 1211 | SND_SOC_DAPM_OUTPUT("PREDRIVEL"), |
1135 | SND_SOC_DAPM_OUTPUT("PREDRIVER"), | 1212 | SND_SOC_DAPM_OUTPUT("PREDRIVER"), |
@@ -1141,6 +1218,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { | |||
1141 | SND_SOC_DAPM_OUTPUT("HFR"), | 1218 | SND_SOC_DAPM_OUTPUT("HFR"), |
1142 | SND_SOC_DAPM_OUTPUT("VIBRA"), | 1219 | SND_SOC_DAPM_OUTPUT("VIBRA"), |
1143 | 1220 | ||
1221 | /* AIF and APLL clocks for running DAIs (including loopback) */ | ||
1222 | SND_SOC_DAPM_OUTPUT("Virtual HiFi OUT"), | ||
1223 | SND_SOC_DAPM_INPUT("Virtual HiFi IN"), | ||
1224 | SND_SOC_DAPM_OUTPUT("Virtual Voice OUT"), | ||
1225 | |||
1144 | /* DACs */ | 1226 | /* DACs */ |
1145 | SND_SOC_DAPM_DAC("DAC Right1", "Right Front HiFi Playback", | 1227 | SND_SOC_DAPM_DAC("DAC Right1", "Right Front HiFi Playback", |
1146 | SND_SOC_NOPM, 0, 0), | 1228 | SND_SOC_NOPM, 0, 0), |
@@ -1204,7 +1286,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { | |||
1204 | SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event, | 1286 | SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event, |
1205 | SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD), | 1287 | SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD), |
1206 | 1288 | ||
1207 | SND_SOC_DAPM_SUPPLY("AIF Enable", TWL4030_REG_AUDIO_IF, 0, 0, NULL, 0), | 1289 | SND_SOC_DAPM_SUPPLY("AIF Enable", SND_SOC_NOPM, 0, 0, aif_event, |
1290 | SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD), | ||
1208 | 1291 | ||
1209 | /* Output MIXER controls */ | 1292 | /* Output MIXER controls */ |
1210 | /* Earpiece */ | 1293 | /* Earpiece */ |
@@ -1334,10 +1417,6 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
1334 | {"Digital Voice Playback Mixer", NULL, "DAC Voice"}, | 1417 | {"Digital Voice Playback Mixer", NULL, "DAC Voice"}, |
1335 | 1418 | ||
1336 | /* Supply for the digital part (APLL) */ | 1419 | /* Supply for the digital part (APLL) */ |
1337 | {"Digital R1 Playback Mixer", NULL, "APLL Enable"}, | ||
1338 | {"Digital L1 Playback Mixer", NULL, "APLL Enable"}, | ||
1339 | {"Digital R2 Playback Mixer", NULL, "APLL Enable"}, | ||
1340 | {"Digital L2 Playback Mixer", NULL, "APLL Enable"}, | ||
1341 | {"Digital Voice Playback Mixer", NULL, "APLL Enable"}, | 1420 | {"Digital Voice Playback Mixer", NULL, "APLL Enable"}, |
1342 | 1421 | ||
1343 | {"Digital R1 Playback Mixer", NULL, "AIF Enable"}, | 1422 | {"Digital R1 Playback Mixer", NULL, "AIF Enable"}, |
@@ -1411,8 +1490,14 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
1411 | {"Vibra Mux", "AudioR2", "DAC Right2"}, | 1490 | {"Vibra Mux", "AudioR2", "DAC Right2"}, |
1412 | 1491 | ||
1413 | /* outputs */ | 1492 | /* outputs */ |
1414 | {"OUTL", NULL, "Analog L2 Playback Mixer"}, | 1493 | /* Must be always connected (for AIF and APLL) */ |
1415 | {"OUTR", NULL, "Analog R2 Playback Mixer"}, | 1494 | {"Virtual HiFi OUT", NULL, "Digital L1 Playback Mixer"}, |
1495 | {"Virtual HiFi OUT", NULL, "Digital R1 Playback Mixer"}, | ||
1496 | {"Virtual HiFi OUT", NULL, "Digital L2 Playback Mixer"}, | ||
1497 | {"Virtual HiFi OUT", NULL, "Digital R2 Playback Mixer"}, | ||
1498 | /* Must be always connected (for APLL) */ | ||
1499 | {"Virtual Voice OUT", NULL, "Digital Voice Playback Mixer"}, | ||
1500 | /* Physical outputs */ | ||
1416 | {"EARPIECE", NULL, "Earpiece PGA"}, | 1501 | {"EARPIECE", NULL, "Earpiece PGA"}, |
1417 | {"PREDRIVEL", NULL, "PredriveL PGA"}, | 1502 | {"PREDRIVEL", NULL, "PredriveL PGA"}, |
1418 | {"PREDRIVER", NULL, "PredriveR PGA"}, | 1503 | {"PREDRIVER", NULL, "PredriveR PGA"}, |
@@ -1426,6 +1511,12 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
1426 | {"VIBRA", NULL, "Vibra Route"}, | 1511 | {"VIBRA", NULL, "Vibra Route"}, |
1427 | 1512 | ||
1428 | /* Capture path */ | 1513 | /* Capture path */ |
1514 | /* Must be always connected (for AIF and APLL) */ | ||
1515 | {"ADC Virtual Left1", NULL, "Virtual HiFi IN"}, | ||
1516 | {"ADC Virtual Right1", NULL, "Virtual HiFi IN"}, | ||
1517 | {"ADC Virtual Left2", NULL, "Virtual HiFi IN"}, | ||
1518 | {"ADC Virtual Right2", NULL, "Virtual HiFi IN"}, | ||
1519 | /* Physical inputs */ | ||
1429 | {"Analog Left", "Main Mic Capture Switch", "MAINMIC"}, | 1520 | {"Analog Left", "Main Mic Capture Switch", "MAINMIC"}, |
1430 | {"Analog Left", "Headset Mic Capture Switch", "HSMIC"}, | 1521 | {"Analog Left", "Headset Mic Capture Switch", "HSMIC"}, |
1431 | {"Analog Left", "AUXL Capture Switch", "AUXL"}, | 1522 | {"Analog Left", "AUXL Capture Switch", "AUXL"}, |
@@ -1458,11 +1549,6 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
1458 | {"ADC Virtual Left2", NULL, "TX2 Capture Route"}, | 1549 | {"ADC Virtual Left2", NULL, "TX2 Capture Route"}, |
1459 | {"ADC Virtual Right2", NULL, "TX2 Capture Route"}, | 1550 | {"ADC Virtual Right2", NULL, "TX2 Capture Route"}, |
1460 | 1551 | ||
1461 | {"ADC Virtual Left1", NULL, "APLL Enable"}, | ||
1462 | {"ADC Virtual Right1", NULL, "APLL Enable"}, | ||
1463 | {"ADC Virtual Left2", NULL, "APLL Enable"}, | ||
1464 | {"ADC Virtual Right2", NULL, "APLL Enable"}, | ||
1465 | |||
1466 | {"ADC Virtual Left1", NULL, "AIF Enable"}, | 1552 | {"ADC Virtual Left1", NULL, "AIF Enable"}, |
1467 | {"ADC Virtual Right1", NULL, "AIF Enable"}, | 1553 | {"ADC Virtual Right1", NULL, "AIF Enable"}, |
1468 | {"ADC Virtual Left2", NULL, "AIF Enable"}, | 1554 | {"ADC Virtual Left2", NULL, "AIF Enable"}, |
@@ -1588,7 +1674,7 @@ static int twl4030_startup(struct snd_pcm_substream *substream, | |||
1588 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 1674 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
1589 | struct snd_soc_device *socdev = rtd->socdev; | 1675 | struct snd_soc_device *socdev = rtd->socdev; |
1590 | struct snd_soc_codec *codec = socdev->card->codec; | 1676 | struct snd_soc_codec *codec = socdev->card->codec; |
1591 | struct twl4030_priv *twl4030 = codec->private_data; | 1677 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
1592 | 1678 | ||
1593 | if (twl4030->master_substream) { | 1679 | if (twl4030->master_substream) { |
1594 | twl4030->slave_substream = substream; | 1680 | twl4030->slave_substream = substream; |
@@ -1619,7 +1705,7 @@ static void twl4030_shutdown(struct snd_pcm_substream *substream, | |||
1619 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 1705 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
1620 | struct snd_soc_device *socdev = rtd->socdev; | 1706 | struct snd_soc_device *socdev = rtd->socdev; |
1621 | struct snd_soc_codec *codec = socdev->card->codec; | 1707 | struct snd_soc_codec *codec = socdev->card->codec; |
1622 | struct twl4030_priv *twl4030 = codec->private_data; | 1708 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
1623 | 1709 | ||
1624 | if (twl4030->master_substream == substream) | 1710 | if (twl4030->master_substream == substream) |
1625 | twl4030->master_substream = twl4030->slave_substream; | 1711 | twl4030->master_substream = twl4030->slave_substream; |
@@ -1645,7 +1731,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, | |||
1645 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 1731 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
1646 | struct snd_soc_device *socdev = rtd->socdev; | 1732 | struct snd_soc_device *socdev = rtd->socdev; |
1647 | struct snd_soc_codec *codec = socdev->card->codec; | 1733 | struct snd_soc_codec *codec = socdev->card->codec; |
1648 | struct twl4030_priv *twl4030 = codec->private_data; | 1734 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
1649 | u8 mode, old_mode, format, old_format; | 1735 | u8 mode, old_mode, format, old_format; |
1650 | 1736 | ||
1651 | /* If the substream has 4 channel, do the necessary setup */ | 1737 | /* If the substream has 4 channel, do the necessary setup */ |
@@ -1765,7 +1851,7 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
1765 | int clk_id, unsigned int freq, int dir) | 1851 | int clk_id, unsigned int freq, int dir) |
1766 | { | 1852 | { |
1767 | struct snd_soc_codec *codec = codec_dai->codec; | 1853 | struct snd_soc_codec *codec = codec_dai->codec; |
1768 | struct twl4030_priv *twl4030 = codec->private_data; | 1854 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
1769 | 1855 | ||
1770 | switch (freq) { | 1856 | switch (freq) { |
1771 | case 19200000: | 1857 | case 19200000: |
@@ -1880,7 +1966,7 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream, | |||
1880 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 1966 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
1881 | struct snd_soc_device *socdev = rtd->socdev; | 1967 | struct snd_soc_device *socdev = rtd->socdev; |
1882 | struct snd_soc_codec *codec = socdev->card->codec; | 1968 | struct snd_soc_codec *codec = socdev->card->codec; |
1883 | struct twl4030_priv *twl4030 = codec->private_data; | 1969 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
1884 | u8 mode; | 1970 | u8 mode; |
1885 | 1971 | ||
1886 | /* If the system master clock is not 26MHz, the voice PCM interface is | 1972 | /* If the system master clock is not 26MHz, the voice PCM interface is |
@@ -1962,7 +2048,7 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
1962 | int clk_id, unsigned int freq, int dir) | 2048 | int clk_id, unsigned int freq, int dir) |
1963 | { | 2049 | { |
1964 | struct snd_soc_codec *codec = codec_dai->codec; | 2050 | struct snd_soc_codec *codec = codec_dai->codec; |
1965 | struct twl4030_priv *twl4030 = codec->private_data; | 2051 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
1966 | 2052 | ||
1967 | if (freq != 26000000) { | 2053 | if (freq != 26000000) { |
1968 | dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice" | 2054 | dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice" |
@@ -2108,7 +2194,6 @@ static int twl4030_soc_resume(struct platform_device *pdev) | |||
2108 | struct snd_soc_codec *codec = socdev->card->codec; | 2194 | struct snd_soc_codec *codec = socdev->card->codec; |
2109 | 2195 | ||
2110 | twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 2196 | twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
2111 | twl4030_set_bias_level(codec, codec->suspend_bias_level); | ||
2112 | return 0; | 2197 | return 0; |
2113 | } | 2198 | } |
2114 | 2199 | ||
@@ -2125,7 +2210,7 @@ static int twl4030_soc_probe(struct platform_device *pdev) | |||
2125 | BUG_ON(!twl4030_codec); | 2210 | BUG_ON(!twl4030_codec); |
2126 | 2211 | ||
2127 | codec = twl4030_codec; | 2212 | codec = twl4030_codec; |
2128 | twl4030 = codec->private_data; | 2213 | twl4030 = snd_soc_codec_get_drvdata(codec); |
2129 | socdev->card->codec = codec; | 2214 | socdev->card->codec = codec; |
2130 | 2215 | ||
2131 | /* Configuration for headset ramp delay from setup data */ | 2216 | /* Configuration for headset ramp delay from setup data */ |
@@ -2188,7 +2273,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev) | |||
2188 | } | 2273 | } |
2189 | 2274 | ||
2190 | codec = &twl4030->codec; | 2275 | codec = &twl4030->codec; |
2191 | codec->private_data = twl4030; | 2276 | snd_soc_codec_set_drvdata(codec, twl4030); |
2192 | codec->dev = &pdev->dev; | 2277 | codec->dev = &pdev->dev; |
2193 | twl4030_dai[0].dev = &pdev->dev; | 2278 | twl4030_dai[0].dev = &pdev->dev; |
2194 | twl4030_dai[1].dev = &pdev->dev; | 2279 | twl4030_dai[1].dev = &pdev->dev; |