aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/twl4030.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/twl4030.c')
-rw-r--r--sound/soc/codecs/twl4030.c260
1 files changed, 173 insertions, 87 deletions
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 4dbb853eef5a..4df7c6c61c76 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -225,55 +225,11 @@ static void twl4030_codec_mute(struct snd_soc_codec *codec, int mute)
225 return; 225 return;
226 226
227 if (mute) { 227 if (mute) {
228 /* Bypass the reg_cache and mute the volumes
229 * Headset mute is done in it's own event handler
230 * Things to mute: Earpiece, PreDrivL/R, CarkitL/R
231 */
232 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_EAR_CTL);
233 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
234 reg_val & (~TWL4030_EAR_GAIN),
235 TWL4030_REG_EAR_CTL);
236
237 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PREDL_CTL);
238 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
239 reg_val & (~TWL4030_PREDL_GAIN),
240 TWL4030_REG_PREDL_CTL);
241 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PREDR_CTL);
242 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
243 reg_val & (~TWL4030_PREDR_GAIN),
244 TWL4030_REG_PREDL_CTL);
245
246 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKL_CTL);
247 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
248 reg_val & (~TWL4030_PRECKL_GAIN),
249 TWL4030_REG_PRECKL_CTL);
250 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKR_CTL);
251 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
252 reg_val & (~TWL4030_PRECKR_GAIN),
253 TWL4030_REG_PRECKR_CTL);
254
255 /* Disable PLL */ 228 /* Disable PLL */
256 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL); 229 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
257 reg_val &= ~TWL4030_APLL_EN; 230 reg_val &= ~TWL4030_APLL_EN;
258 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val); 231 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val);
259 } else { 232 } else {
260 /* Restore the volumes
261 * Headset mute is done in it's own event handler
262 * Things to restore: Earpiece, PreDrivL/R, CarkitL/R
263 */
264 twl4030_write(codec, TWL4030_REG_EAR_CTL,
265 twl4030_read_reg_cache(codec, TWL4030_REG_EAR_CTL));
266
267 twl4030_write(codec, TWL4030_REG_PREDL_CTL,
268 twl4030_read_reg_cache(codec, TWL4030_REG_PREDL_CTL));
269 twl4030_write(codec, TWL4030_REG_PREDR_CTL,
270 twl4030_read_reg_cache(codec, TWL4030_REG_PREDR_CTL));
271
272 twl4030_write(codec, TWL4030_REG_PRECKL_CTL,
273 twl4030_read_reg_cache(codec, TWL4030_REG_PRECKL_CTL));
274 twl4030_write(codec, TWL4030_REG_PRECKR_CTL,
275 twl4030_read_reg_cache(codec, TWL4030_REG_PRECKR_CTL));
276
277 /* Enable PLL */ 233 /* Enable PLL */
278 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL); 234 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
279 reg_val |= TWL4030_APLL_EN; 235 reg_val |= TWL4030_APLL_EN;
@@ -443,16 +399,20 @@ SOC_DAPM_ENUM("Route", twl4030_vibrapath_enum);
443 399
444/* Left analog microphone selection */ 400/* Left analog microphone selection */
445static const struct snd_kcontrol_new twl4030_dapm_analoglmic_controls[] = { 401static const struct snd_kcontrol_new twl4030_dapm_analoglmic_controls[] = {
446 SOC_DAPM_SINGLE("Main mic", TWL4030_REG_ANAMICL, 0, 1, 0), 402 SOC_DAPM_SINGLE("Main Mic Capture Switch",
447 SOC_DAPM_SINGLE("Headset mic", TWL4030_REG_ANAMICL, 1, 1, 0), 403 TWL4030_REG_ANAMICL, 0, 1, 0),
448 SOC_DAPM_SINGLE("AUXL", TWL4030_REG_ANAMICL, 2, 1, 0), 404 SOC_DAPM_SINGLE("Headset Mic Capture Switch",
449 SOC_DAPM_SINGLE("Carkit mic", TWL4030_REG_ANAMICL, 3, 1, 0), 405 TWL4030_REG_ANAMICL, 1, 1, 0),
406 SOC_DAPM_SINGLE("AUXL Capture Switch",
407 TWL4030_REG_ANAMICL, 2, 1, 0),
408 SOC_DAPM_SINGLE("Carkit Mic Capture Switch",
409 TWL4030_REG_ANAMICL, 3, 1, 0),
450}; 410};
451 411
452/* Right analog microphone selection */ 412/* Right analog microphone selection */
453static const struct snd_kcontrol_new twl4030_dapm_analogrmic_controls[] = { 413static const struct snd_kcontrol_new twl4030_dapm_analogrmic_controls[] = {
454 SOC_DAPM_SINGLE("Sub mic", TWL4030_REG_ANAMICR, 0, 1, 0), 414 SOC_DAPM_SINGLE("Sub Mic Capture Switch", TWL4030_REG_ANAMICR, 0, 1, 0),
455 SOC_DAPM_SINGLE("AUXR", TWL4030_REG_ANAMICR, 2, 1, 0), 415 SOC_DAPM_SINGLE("AUXR Capture Switch", TWL4030_REG_ANAMICR, 2, 1, 0),
456}; 416};
457 417
458/* TX1 L/R Analog/Digital microphone selection */ 418/* TX1 L/R Analog/Digital microphone selection */
@@ -560,6 +520,41 @@ static int micpath_event(struct snd_soc_dapm_widget *w,
560 return 0; 520 return 0;
561} 521}
562 522
523/*
524 * Output PGA builder:
525 * Handle the muting and unmuting of the given output (turning off the
526 * amplifier associated with the output pin)
527 * On mute bypass the reg_cache and mute the volume
528 * On unmute: restore the register content
529 * Outputs handled in this way: Earpiece, PreDrivL/R, CarkitL/R
530 */
531#define TWL4030_OUTPUT_PGA(pin_name, reg, mask) \
532static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \
533 struct snd_kcontrol *kcontrol, int event) \
534{ \
535 u8 reg_val; \
536 \
537 switch (event) { \
538 case SND_SOC_DAPM_POST_PMU: \
539 twl4030_write(w->codec, reg, \
540 twl4030_read_reg_cache(w->codec, reg)); \
541 break; \
542 case SND_SOC_DAPM_POST_PMD: \
543 reg_val = twl4030_read_reg_cache(w->codec, reg); \
544 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \
545 reg_val & (~mask), \
546 reg); \
547 break; \
548 } \
549 return 0; \
550}
551
552TWL4030_OUTPUT_PGA(earpiece, TWL4030_REG_EAR_CTL, TWL4030_EAR_GAIN);
553TWL4030_OUTPUT_PGA(predrivel, TWL4030_REG_PREDL_CTL, TWL4030_PREDL_GAIN);
554TWL4030_OUTPUT_PGA(predriver, TWL4030_REG_PREDR_CTL, TWL4030_PREDR_GAIN);
555TWL4030_OUTPUT_PGA(carkitl, TWL4030_REG_PRECKL_CTL, TWL4030_PRECKL_GAIN);
556TWL4030_OUTPUT_PGA(carkitr, TWL4030_REG_PRECKR_CTL, TWL4030_PRECKR_GAIN);
557
563static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp) 558static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp)
564{ 559{
565 unsigned char hs_ctl; 560 unsigned char hs_ctl;
@@ -620,6 +615,9 @@ static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
620 615
621static void headset_ramp(struct snd_soc_codec *codec, int ramp) 616static void headset_ramp(struct snd_soc_codec *codec, int ramp)
622{ 617{
618 struct snd_soc_device *socdev = codec->socdev;
619 struct twl4030_setup_data *setup = socdev->codec_data;
620
623 unsigned char hs_gain, hs_pop; 621 unsigned char hs_gain, hs_pop;
624 struct twl4030_priv *twl4030 = codec->private_data; 622 struct twl4030_priv *twl4030 = codec->private_data;
625 /* Base values for ramp delay calculation: 2^19 - 2^26 */ 623 /* Base values for ramp delay calculation: 2^19 - 2^26 */
@@ -629,6 +627,17 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
629 hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET); 627 hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET);
630 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); 628 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
631 629
630 /* Enable external mute control, this dramatically reduces
631 * the pop-noise */
632 if (setup && setup->hs_extmute) {
633 if (setup->set_hs_extmute) {
634 setup->set_hs_extmute(1);
635 } else {
636 hs_pop |= TWL4030_EXTMUTE;
637 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
638 }
639 }
640
632 if (ramp) { 641 if (ramp) {
633 /* Headset ramp-up according to the TRM */ 642 /* Headset ramp-up according to the TRM */
634 hs_pop |= TWL4030_VMID_EN; 643 hs_pop |= TWL4030_VMID_EN;
@@ -636,6 +645,9 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
636 twl4030_write(codec, TWL4030_REG_HS_GAIN_SET, hs_gain); 645 twl4030_write(codec, TWL4030_REG_HS_GAIN_SET, hs_gain);
637 hs_pop |= TWL4030_RAMP_EN; 646 hs_pop |= TWL4030_RAMP_EN;
638 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 647 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
648 /* Wait ramp delay time + 1, so the VMID can settle */
649 mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
650 twl4030->sysclk) + 1);
639 } else { 651 } else {
640 /* Headset ramp-down _not_ according to 652 /* Headset ramp-down _not_ according to
641 * the TRM, but in a way that it is working */ 653 * the TRM, but in a way that it is working */
@@ -652,6 +664,16 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
652 hs_pop &= ~TWL4030_VMID_EN; 664 hs_pop &= ~TWL4030_VMID_EN;
653 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 665 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
654 } 666 }
667
668 /* Disable external mute */
669 if (setup && setup->hs_extmute) {
670 if (setup->set_hs_extmute) {
671 setup->set_hs_extmute(0);
672 } else {
673 hs_pop &= ~TWL4030_EXTMUTE;
674 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
675 }
676 }
655} 677}
656 678
657static int headsetlpga_event(struct snd_soc_dapm_widget *w, 679static int headsetlpga_event(struct snd_soc_dapm_widget *w,
@@ -712,7 +734,19 @@ static int bypass_event(struct snd_soc_dapm_widget *w,
712 734
713 reg = twl4030_read_reg_cache(w->codec, m->reg); 735 reg = twl4030_read_reg_cache(w->codec, m->reg);
714 736
715 if (m->reg <= TWL4030_REG_ARXR2_APGA_CTL) { 737 /*
738 * bypass_state[0:3] - analog HiFi bypass
739 * bypass_state[4] - analog voice bypass
740 * bypass_state[5] - digital voice bypass
741 * bypass_state[6:7] - digital HiFi bypass
742 */
743 if (m->reg == TWL4030_REG_VSTPGA) {
744 /* Voice digital bypass */
745 if (reg)
746 twl4030->bypass_state |= (1 << 5);
747 else
748 twl4030->bypass_state &= ~(1 << 5);
749 } else if (m->reg <= TWL4030_REG_ARXR2_APGA_CTL) {
716 /* Analog bypass */ 750 /* Analog bypass */
717 if (reg & (1 << m->shift)) 751 if (reg & (1 << m->shift))
718 twl4030->bypass_state |= 752 twl4030->bypass_state |=
@@ -726,12 +760,6 @@ static int bypass_event(struct snd_soc_dapm_widget *w,
726 twl4030->bypass_state |= (1 << 4); 760 twl4030->bypass_state |= (1 << 4);
727 else 761 else
728 twl4030->bypass_state &= ~(1 << 4); 762 twl4030->bypass_state &= ~(1 << 4);
729 } else if (m->reg == TWL4030_REG_VSTPGA) {
730 /* Voice digital bypass */
731 if (reg)
732 twl4030->bypass_state |= (1 << 5);
733 else
734 twl4030->bypass_state &= ~(1 << 5);
735 } else { 763 } else {
736 /* Digital bypass */ 764 /* Digital bypass */
737 if (reg & (0x7 << m->shift)) 765 if (reg & (0x7 << m->shift))
@@ -924,7 +952,7 @@ static const struct soc_enum twl4030_op_modes_enum =
924 ARRAY_SIZE(twl4030_op_modes_texts), 952 ARRAY_SIZE(twl4030_op_modes_texts),
925 twl4030_op_modes_texts); 953 twl4030_op_modes_texts);
926 954
927int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, 955static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
928 struct snd_ctl_elem_value *ucontrol) 956 struct snd_ctl_elem_value *ucontrol)
929{ 957{
930 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 958 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
@@ -1005,6 +1033,16 @@ static DECLARE_TLV_DB_SCALE(digital_capture_tlv, 0, 100, 0);
1005 */ 1033 */
1006static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0); 1034static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0);
1007 1035
1036/* AVADC clock priority */
1037static const char *twl4030_avadc_clk_priority_texts[] = {
1038 "Voice high priority", "HiFi high priority"
1039};
1040
1041static const struct soc_enum twl4030_avadc_clk_priority_enum =
1042 SOC_ENUM_SINGLE(TWL4030_REG_AVADC_CTL, 2,
1043 ARRAY_SIZE(twl4030_avadc_clk_priority_texts),
1044 twl4030_avadc_clk_priority_texts);
1045
1008static const char *twl4030_rampdelay_texts[] = { 1046static const char *twl4030_rampdelay_texts[] = {
1009 "27/20/14 ms", "55/40/27 ms", "109/81/55 ms", "218/161/109 ms", 1047 "27/20/14 ms", "55/40/27 ms", "109/81/55 ms", "218/161/109 ms",
1010 "437/323/218 ms", "874/645/437 ms", "1748/1291/874 ms", 1048 "437/323/218 ms", "874/645/437 ms", "1748/1291/874 ms",
@@ -1106,6 +1144,8 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = {
1106 SOC_DOUBLE_TLV("Analog Capture Volume", TWL4030_REG_ANAMIC_GAIN, 1144 SOC_DOUBLE_TLV("Analog Capture Volume", TWL4030_REG_ANAMIC_GAIN,
1107 0, 3, 5, 0, input_gain_tlv), 1145 0, 3, 5, 0, input_gain_tlv),
1108 1146
1147 SOC_ENUM("AVADC Clock Priority", twl4030_avadc_clk_priority_enum),
1148
1109 SOC_ENUM("HS ramp delay", twl4030_rampdelay_enum), 1149 SOC_ENUM("HS ramp delay", twl4030_rampdelay_enum),
1110 1150
1111 SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum), 1151 SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum),
@@ -1208,13 +1248,22 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1208 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, 1248 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
1209 &twl4030_dapm_earpiece_controls[0], 1249 &twl4030_dapm_earpiece_controls[0],
1210 ARRAY_SIZE(twl4030_dapm_earpiece_controls)), 1250 ARRAY_SIZE(twl4030_dapm_earpiece_controls)),
1251 SND_SOC_DAPM_PGA_E("Earpiece PGA", SND_SOC_NOPM,
1252 0, 0, NULL, 0, earpiecepga_event,
1253 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1211 /* PreDrivL/R */ 1254 /* PreDrivL/R */
1212 SND_SOC_DAPM_MIXER("PredriveL Mixer", SND_SOC_NOPM, 0, 0, 1255 SND_SOC_DAPM_MIXER("PredriveL Mixer", SND_SOC_NOPM, 0, 0,
1213 &twl4030_dapm_predrivel_controls[0], 1256 &twl4030_dapm_predrivel_controls[0],
1214 ARRAY_SIZE(twl4030_dapm_predrivel_controls)), 1257 ARRAY_SIZE(twl4030_dapm_predrivel_controls)),
1258 SND_SOC_DAPM_PGA_E("PredriveL PGA", SND_SOC_NOPM,
1259 0, 0, NULL, 0, predrivelpga_event,
1260 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1215 SND_SOC_DAPM_MIXER("PredriveR Mixer", SND_SOC_NOPM, 0, 0, 1261 SND_SOC_DAPM_MIXER("PredriveR Mixer", SND_SOC_NOPM, 0, 0,
1216 &twl4030_dapm_predriver_controls[0], 1262 &twl4030_dapm_predriver_controls[0],
1217 ARRAY_SIZE(twl4030_dapm_predriver_controls)), 1263 ARRAY_SIZE(twl4030_dapm_predriver_controls)),
1264 SND_SOC_DAPM_PGA_E("PredriveR PGA", SND_SOC_NOPM,
1265 0, 0, NULL, 0, predriverpga_event,
1266 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1218 /* HeadsetL/R */ 1267 /* HeadsetL/R */
1219 SND_SOC_DAPM_MIXER("HeadsetL Mixer", SND_SOC_NOPM, 0, 0, 1268 SND_SOC_DAPM_MIXER("HeadsetL Mixer", SND_SOC_NOPM, 0, 0,
1220 &twl4030_dapm_hsol_controls[0], 1269 &twl4030_dapm_hsol_controls[0],
@@ -1232,22 +1281,28 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1232 SND_SOC_DAPM_MIXER("CarkitL Mixer", SND_SOC_NOPM, 0, 0, 1281 SND_SOC_DAPM_MIXER("CarkitL Mixer", SND_SOC_NOPM, 0, 0,
1233 &twl4030_dapm_carkitl_controls[0], 1282 &twl4030_dapm_carkitl_controls[0],
1234 ARRAY_SIZE(twl4030_dapm_carkitl_controls)), 1283 ARRAY_SIZE(twl4030_dapm_carkitl_controls)),
1284 SND_SOC_DAPM_PGA_E("CarkitL PGA", SND_SOC_NOPM,
1285 0, 0, NULL, 0, carkitlpga_event,
1286 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1235 SND_SOC_DAPM_MIXER("CarkitR Mixer", SND_SOC_NOPM, 0, 0, 1287 SND_SOC_DAPM_MIXER("CarkitR Mixer", SND_SOC_NOPM, 0, 0,
1236 &twl4030_dapm_carkitr_controls[0], 1288 &twl4030_dapm_carkitr_controls[0],
1237 ARRAY_SIZE(twl4030_dapm_carkitr_controls)), 1289 ARRAY_SIZE(twl4030_dapm_carkitr_controls)),
1290 SND_SOC_DAPM_PGA_E("CarkitR PGA", SND_SOC_NOPM,
1291 0, 0, NULL, 0, carkitrpga_event,
1292 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1238 1293
1239 /* Output MUX controls */ 1294 /* Output MUX controls */
1240 /* HandsfreeL/R */ 1295 /* HandsfreeL/R */
1241 SND_SOC_DAPM_MUX("HandsfreeL Mux", SND_SOC_NOPM, 0, 0, 1296 SND_SOC_DAPM_MUX("HandsfreeL Mux", SND_SOC_NOPM, 0, 0,
1242 &twl4030_dapm_handsfreel_control), 1297 &twl4030_dapm_handsfreel_control),
1243 SND_SOC_DAPM_SWITCH("HandsfreeL Switch", SND_SOC_NOPM, 0, 0, 1298 SND_SOC_DAPM_SWITCH("HandsfreeL", SND_SOC_NOPM, 0, 0,
1244 &twl4030_dapm_handsfreelmute_control), 1299 &twl4030_dapm_handsfreelmute_control),
1245 SND_SOC_DAPM_PGA_E("HandsfreeL PGA", SND_SOC_NOPM, 1300 SND_SOC_DAPM_PGA_E("HandsfreeL PGA", SND_SOC_NOPM,
1246 0, 0, NULL, 0, handsfreelpga_event, 1301 0, 0, NULL, 0, handsfreelpga_event,
1247 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), 1302 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1248 SND_SOC_DAPM_MUX("HandsfreeR Mux", SND_SOC_NOPM, 5, 0, 1303 SND_SOC_DAPM_MUX("HandsfreeR Mux", SND_SOC_NOPM, 5, 0,
1249 &twl4030_dapm_handsfreer_control), 1304 &twl4030_dapm_handsfreer_control),
1250 SND_SOC_DAPM_SWITCH("HandsfreeR Switch", SND_SOC_NOPM, 0, 0, 1305 SND_SOC_DAPM_SWITCH("HandsfreeR", SND_SOC_NOPM, 0, 0,
1251 &twl4030_dapm_handsfreermute_control), 1306 &twl4030_dapm_handsfreermute_control),
1252 SND_SOC_DAPM_PGA_E("HandsfreeR PGA", SND_SOC_NOPM, 1307 SND_SOC_DAPM_PGA_E("HandsfreeR PGA", SND_SOC_NOPM,
1253 0, 0, NULL, 0, handsfreerpga_event, 1308 0, 0, NULL, 0, handsfreerpga_event,
@@ -1282,11 +1337,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1282 SND_SOC_DAPM_POST_REG), 1337 SND_SOC_DAPM_POST_REG),
1283 1338
1284 /* Analog input mixers for the capture amplifiers */ 1339 /* Analog input mixers for the capture amplifiers */
1285 SND_SOC_DAPM_MIXER("Analog Left Capture Route", 1340 SND_SOC_DAPM_MIXER("Analog Left",
1286 TWL4030_REG_ANAMICL, 4, 0, 1341 TWL4030_REG_ANAMICL, 4, 0,
1287 &twl4030_dapm_analoglmic_controls[0], 1342 &twl4030_dapm_analoglmic_controls[0],
1288 ARRAY_SIZE(twl4030_dapm_analoglmic_controls)), 1343 ARRAY_SIZE(twl4030_dapm_analoglmic_controls)),
1289 SND_SOC_DAPM_MIXER("Analog Right Capture Route", 1344 SND_SOC_DAPM_MIXER("Analog Right",
1290 TWL4030_REG_ANAMICR, 4, 0, 1345 TWL4030_REG_ANAMICR, 4, 0,
1291 &twl4030_dapm_analogrmic_controls[0], 1346 &twl4030_dapm_analogrmic_controls[0],
1292 ARRAY_SIZE(twl4030_dapm_analogrmic_controls)), 1347 ARRAY_SIZE(twl4030_dapm_analogrmic_controls)),
@@ -1326,16 +1381,19 @@ static const struct snd_soc_dapm_route intercon[] = {
1326 {"Earpiece Mixer", "AudioL1", "Analog L1 Playback Mixer"}, 1381 {"Earpiece Mixer", "AudioL1", "Analog L1 Playback Mixer"},
1327 {"Earpiece Mixer", "AudioL2", "Analog L2 Playback Mixer"}, 1382 {"Earpiece Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1328 {"Earpiece Mixer", "AudioR1", "Analog R1 Playback Mixer"}, 1383 {"Earpiece Mixer", "AudioR1", "Analog R1 Playback Mixer"},
1384 {"Earpiece PGA", NULL, "Earpiece Mixer"},
1329 /* PreDrivL */ 1385 /* PreDrivL */
1330 {"PredriveL Mixer", "Voice", "Analog Voice Playback Mixer"}, 1386 {"PredriveL Mixer", "Voice", "Analog Voice Playback Mixer"},
1331 {"PredriveL Mixer", "AudioL1", "Analog L1 Playback Mixer"}, 1387 {"PredriveL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
1332 {"PredriveL Mixer", "AudioL2", "Analog L2 Playback Mixer"}, 1388 {"PredriveL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1333 {"PredriveL Mixer", "AudioR2", "Analog R2 Playback Mixer"}, 1389 {"PredriveL Mixer", "AudioR2", "Analog R2 Playback Mixer"},
1390 {"PredriveL PGA", NULL, "PredriveL Mixer"},
1334 /* PreDrivR */ 1391 /* PreDrivR */
1335 {"PredriveR Mixer", "Voice", "Analog Voice Playback Mixer"}, 1392 {"PredriveR Mixer", "Voice", "Analog Voice Playback Mixer"},
1336 {"PredriveR Mixer", "AudioR1", "Analog R1 Playback Mixer"}, 1393 {"PredriveR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
1337 {"PredriveR Mixer", "AudioR2", "Analog R2 Playback Mixer"}, 1394 {"PredriveR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
1338 {"PredriveR Mixer", "AudioL2", "Analog L2 Playback Mixer"}, 1395 {"PredriveR Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1396 {"PredriveR PGA", NULL, "PredriveR Mixer"},
1339 /* HeadsetL */ 1397 /* HeadsetL */
1340 {"HeadsetL Mixer", "Voice", "Analog Voice Playback Mixer"}, 1398 {"HeadsetL Mixer", "Voice", "Analog Voice Playback Mixer"},
1341 {"HeadsetL Mixer", "AudioL1", "Analog L1 Playback Mixer"}, 1399 {"HeadsetL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
@@ -1350,24 +1408,26 @@ static const struct snd_soc_dapm_route intercon[] = {
1350 {"CarkitL Mixer", "Voice", "Analog Voice Playback Mixer"}, 1408 {"CarkitL Mixer", "Voice", "Analog Voice Playback Mixer"},
1351 {"CarkitL Mixer", "AudioL1", "Analog L1 Playback Mixer"}, 1409 {"CarkitL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
1352 {"CarkitL Mixer", "AudioL2", "Analog L2 Playback Mixer"}, 1410 {"CarkitL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1411 {"CarkitL PGA", NULL, "CarkitL Mixer"},
1353 /* CarkitR */ 1412 /* CarkitR */
1354 {"CarkitR Mixer", "Voice", "Analog Voice Playback Mixer"}, 1413 {"CarkitR Mixer", "Voice", "Analog Voice Playback Mixer"},
1355 {"CarkitR Mixer", "AudioR1", "Analog R1 Playback Mixer"}, 1414 {"CarkitR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
1356 {"CarkitR Mixer", "AudioR2", "Analog R2 Playback Mixer"}, 1415 {"CarkitR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
1416 {"CarkitR PGA", NULL, "CarkitR Mixer"},
1357 /* HandsfreeL */ 1417 /* HandsfreeL */
1358 {"HandsfreeL Mux", "Voice", "Analog Voice Playback Mixer"}, 1418 {"HandsfreeL Mux", "Voice", "Analog Voice Playback Mixer"},
1359 {"HandsfreeL Mux", "AudioL1", "Analog L1 Playback Mixer"}, 1419 {"HandsfreeL Mux", "AudioL1", "Analog L1 Playback Mixer"},
1360 {"HandsfreeL Mux", "AudioL2", "Analog L2 Playback Mixer"}, 1420 {"HandsfreeL Mux", "AudioL2", "Analog L2 Playback Mixer"},
1361 {"HandsfreeL Mux", "AudioR2", "Analog R2 Playback Mixer"}, 1421 {"HandsfreeL Mux", "AudioR2", "Analog R2 Playback Mixer"},
1362 {"HandsfreeL Switch", "Switch", "HandsfreeL Mux"}, 1422 {"HandsfreeL", "Switch", "HandsfreeL Mux"},
1363 {"HandsfreeL PGA", NULL, "HandsfreeL Switch"}, 1423 {"HandsfreeL PGA", NULL, "HandsfreeL"},
1364 /* HandsfreeR */ 1424 /* HandsfreeR */
1365 {"HandsfreeR Mux", "Voice", "Analog Voice Playback Mixer"}, 1425 {"HandsfreeR Mux", "Voice", "Analog Voice Playback Mixer"},
1366 {"HandsfreeR Mux", "AudioR1", "Analog R1 Playback Mixer"}, 1426 {"HandsfreeR Mux", "AudioR1", "Analog R1 Playback Mixer"},
1367 {"HandsfreeR Mux", "AudioR2", "Analog R2 Playback Mixer"}, 1427 {"HandsfreeR Mux", "AudioR2", "Analog R2 Playback Mixer"},
1368 {"HandsfreeR Mux", "AudioL2", "Analog L2 Playback Mixer"}, 1428 {"HandsfreeR Mux", "AudioL2", "Analog L2 Playback Mixer"},
1369 {"HandsfreeR Switch", "Switch", "HandsfreeR Mux"}, 1429 {"HandsfreeR", "Switch", "HandsfreeR Mux"},
1370 {"HandsfreeR PGA", NULL, "HandsfreeR Switch"}, 1430 {"HandsfreeR PGA", NULL, "HandsfreeR"},
1371 /* Vibra */ 1431 /* Vibra */
1372 {"Vibra Mux", "AudioL1", "DAC Left1"}, 1432 {"Vibra Mux", "AudioL1", "DAC Left1"},
1373 {"Vibra Mux", "AudioR1", "DAC Right1"}, 1433 {"Vibra Mux", "AudioR1", "DAC Right1"},
@@ -1377,29 +1437,29 @@ static const struct snd_soc_dapm_route intercon[] = {
1377 /* outputs */ 1437 /* outputs */
1378 {"OUTL", NULL, "Analog L2 Playback Mixer"}, 1438 {"OUTL", NULL, "Analog L2 Playback Mixer"},
1379 {"OUTR", NULL, "Analog R2 Playback Mixer"}, 1439 {"OUTR", NULL, "Analog R2 Playback Mixer"},
1380 {"EARPIECE", NULL, "Earpiece Mixer"}, 1440 {"EARPIECE", NULL, "Earpiece PGA"},
1381 {"PREDRIVEL", NULL, "PredriveL Mixer"}, 1441 {"PREDRIVEL", NULL, "PredriveL PGA"},
1382 {"PREDRIVER", NULL, "PredriveR Mixer"}, 1442 {"PREDRIVER", NULL, "PredriveR PGA"},
1383 {"HSOL", NULL, "HeadsetL PGA"}, 1443 {"HSOL", NULL, "HeadsetL PGA"},
1384 {"HSOR", NULL, "HeadsetR PGA"}, 1444 {"HSOR", NULL, "HeadsetR PGA"},
1385 {"CARKITL", NULL, "CarkitL Mixer"}, 1445 {"CARKITL", NULL, "CarkitL PGA"},
1386 {"CARKITR", NULL, "CarkitR Mixer"}, 1446 {"CARKITR", NULL, "CarkitR PGA"},
1387 {"HFL", NULL, "HandsfreeL PGA"}, 1447 {"HFL", NULL, "HandsfreeL PGA"},
1388 {"HFR", NULL, "HandsfreeR PGA"}, 1448 {"HFR", NULL, "HandsfreeR PGA"},
1389 {"Vibra Route", "Audio", "Vibra Mux"}, 1449 {"Vibra Route", "Audio", "Vibra Mux"},
1390 {"VIBRA", NULL, "Vibra Route"}, 1450 {"VIBRA", NULL, "Vibra Route"},
1391 1451
1392 /* Capture path */ 1452 /* Capture path */
1393 {"Analog Left Capture Route", "Main mic", "MAINMIC"}, 1453 {"Analog Left", "Main Mic Capture Switch", "MAINMIC"},
1394 {"Analog Left Capture Route", "Headset mic", "HSMIC"}, 1454 {"Analog Left", "Headset Mic Capture Switch", "HSMIC"},
1395 {"Analog Left Capture Route", "AUXL", "AUXL"}, 1455 {"Analog Left", "AUXL Capture Switch", "AUXL"},
1396 {"Analog Left Capture Route", "Carkit mic", "CARKITMIC"}, 1456 {"Analog Left", "Carkit Mic Capture Switch", "CARKITMIC"},
1397 1457
1398 {"Analog Right Capture Route", "Sub mic", "SUBMIC"}, 1458 {"Analog Right", "Sub Mic Capture Switch", "SUBMIC"},
1399 {"Analog Right Capture Route", "AUXR", "AUXR"}, 1459 {"Analog Right", "AUXR Capture Switch", "AUXR"},
1400 1460
1401 {"ADC Physical Left", NULL, "Analog Left Capture Route"}, 1461 {"ADC Physical Left", NULL, "Analog Left"},
1402 {"ADC Physical Right", NULL, "Analog Right Capture Route"}, 1462 {"ADC Physical Right", NULL, "Analog Right"},
1403 1463
1404 {"Digimic0 Enable", NULL, "DIGIMIC0"}, 1464 {"Digimic0 Enable", NULL, "DIGIMIC0"},
1405 {"Digimic1 Enable", NULL, "DIGIMIC1"}, 1465 {"Digimic1 Enable", NULL, "DIGIMIC1"},
@@ -1423,11 +1483,11 @@ static const struct snd_soc_dapm_route intercon[] = {
1423 {"ADC Virtual Right2", NULL, "TX2 Capture Route"}, 1483 {"ADC Virtual Right2", NULL, "TX2 Capture Route"},
1424 1484
1425 /* Analog bypass routes */ 1485 /* Analog bypass routes */
1426 {"Right1 Analog Loopback", "Switch", "Analog Right Capture Route"}, 1486 {"Right1 Analog Loopback", "Switch", "Analog Right"},
1427 {"Left1 Analog Loopback", "Switch", "Analog Left Capture Route"}, 1487 {"Left1 Analog Loopback", "Switch", "Analog Left"},
1428 {"Right2 Analog Loopback", "Switch", "Analog Right Capture Route"}, 1488 {"Right2 Analog Loopback", "Switch", "Analog Right"},
1429 {"Left2 Analog Loopback", "Switch", "Analog Left Capture Route"}, 1489 {"Left2 Analog Loopback", "Switch", "Analog Left"},
1430 {"Voice Analog Loopback", "Switch", "Analog Left Capture Route"}, 1490 {"Voice Analog Loopback", "Switch", "Analog Left"},
1431 1491
1432 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"}, 1492 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"},
1433 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"}, 1493 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"},
@@ -1609,8 +1669,6 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1609 1669
1610 /* If the substream has 4 channel, do the necessary setup */ 1670 /* If the substream has 4 channel, do the necessary setup */
1611 if (params_channels(params) == 4) { 1671 if (params_channels(params) == 4) {
1612 u8 format, mode;
1613
1614 format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); 1672 format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1615 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE); 1673 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
1616 1674
@@ -1806,6 +1864,19 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
1806 return 0; 1864 return 0;
1807} 1865}
1808 1866
1867static int twl4030_set_tristate(struct snd_soc_dai *dai, int tristate)
1868{
1869 struct snd_soc_codec *codec = dai->codec;
1870 u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1871
1872 if (tristate)
1873 reg |= TWL4030_AIF_TRI_EN;
1874 else
1875 reg &= ~TWL4030_AIF_TRI_EN;
1876
1877 return twl4030_write(codec, TWL4030_REG_AUDIO_IF, reg);
1878}
1879
1809/* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R 1880/* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R
1810 * (VTXL, VTXR) for uplink has to be enabled/disabled. */ 1881 * (VTXL, VTXR) for uplink has to be enabled/disabled. */
1811static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction, 1882static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction,
@@ -1948,7 +2019,7 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
1948 2019
1949 /* set master/slave audio interface */ 2020 /* set master/slave audio interface */
1950 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 2021 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1951 case SND_SOC_DAIFMT_CBS_CFM: 2022 case SND_SOC_DAIFMT_CBM_CFM:
1952 format &= ~(TWL4030_VIF_SLAVE_EN); 2023 format &= ~(TWL4030_VIF_SLAVE_EN);
1953 break; 2024 break;
1954 case SND_SOC_DAIFMT_CBS_CFS: 2025 case SND_SOC_DAIFMT_CBS_CFS:
@@ -1980,6 +2051,19 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
1980 return 0; 2051 return 0;
1981} 2052}
1982 2053
2054static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate)
2055{
2056 struct snd_soc_codec *codec = dai->codec;
2057 u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF);
2058
2059 if (tristate)
2060 reg |= TWL4030_VIF_TRI_EN;
2061 else
2062 reg &= ~TWL4030_VIF_TRI_EN;
2063
2064 return twl4030_write(codec, TWL4030_REG_VOICE_IF, reg);
2065}
2066
1983#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000) 2067#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
1984#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE) 2068#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
1985 2069
@@ -1989,6 +2073,7 @@ static struct snd_soc_dai_ops twl4030_dai_ops = {
1989 .hw_params = twl4030_hw_params, 2073 .hw_params = twl4030_hw_params,
1990 .set_sysclk = twl4030_set_dai_sysclk, 2074 .set_sysclk = twl4030_set_dai_sysclk,
1991 .set_fmt = twl4030_set_dai_fmt, 2075 .set_fmt = twl4030_set_dai_fmt,
2076 .set_tristate = twl4030_set_tristate,
1992}; 2077};
1993 2078
1994static struct snd_soc_dai_ops twl4030_dai_voice_ops = { 2079static struct snd_soc_dai_ops twl4030_dai_voice_ops = {
@@ -1997,6 +2082,7 @@ static struct snd_soc_dai_ops twl4030_dai_voice_ops = {
1997 .hw_params = twl4030_voice_hw_params, 2082 .hw_params = twl4030_voice_hw_params,
1998 .set_sysclk = twl4030_voice_set_dai_sysclk, 2083 .set_sysclk = twl4030_voice_set_dai_sysclk,
1999 .set_fmt = twl4030_voice_set_dai_fmt, 2084 .set_fmt = twl4030_voice_set_dai_fmt,
2085 .set_tristate = twl4030_voice_set_tristate,
2000}; 2086};
2001 2087
2002struct snd_soc_dai twl4030_dai[] = { 2088struct snd_soc_dai twl4030_dai[] = {