aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8996.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8996.c')
-rw-r--r--sound/soc/codecs/wm8996.c321
1 files changed, 254 insertions, 67 deletions
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index 0cdb9d105671..645c980d6b80 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -41,12 +41,11 @@
41#define HPOUT2L 4 41#define HPOUT2L 4
42#define HPOUT2R 8 42#define HPOUT2R 8
43 43
44#define WM8996_NUM_SUPPLIES 4 44#define WM8996_NUM_SUPPLIES 3
45static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = { 45static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = {
46 "DBVDD", 46 "DBVDD",
47 "AVDD1", 47 "AVDD1",
48 "AVDD2", 48 "AVDD2",
49 "CPVDD",
50}; 49};
51 50
52struct wm8996_priv { 51struct wm8996_priv {
@@ -71,6 +70,8 @@ struct wm8996_priv {
71 70
72 struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES]; 71 struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES];
73 struct notifier_block disable_nb[WM8996_NUM_SUPPLIES]; 72 struct notifier_block disable_nb[WM8996_NUM_SUPPLIES];
73 struct regulator *cpvdd;
74 int bg_ena;
74 75
75 struct wm8996_pdata pdata; 76 struct wm8996_pdata pdata;
76 77
@@ -112,7 +113,6 @@ static int wm8996_regulator_event_##n(struct notifier_block *nb, \
112WM8996_REGULATOR_EVENT(0) 113WM8996_REGULATOR_EVENT(0)
113WM8996_REGULATOR_EVENT(1) 114WM8996_REGULATOR_EVENT(1)
114WM8996_REGULATOR_EVENT(2) 115WM8996_REGULATOR_EVENT(2)
115WM8996_REGULATOR_EVENT(3)
116 116
117static const u16 wm8996_reg[WM8996_MAX_REGISTER] = { 117static const u16 wm8996_reg[WM8996_MAX_REGISTER] = {
118 [WM8996_SOFTWARE_RESET] = 0x8996, 118 [WM8996_SOFTWARE_RESET] = 0x8996,
@@ -414,6 +414,7 @@ static const DECLARE_TLV_DB_SCALE(out_digital_tlv, -1200, 150, 0);
414static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0); 414static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0);
415static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0); 415static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0);
416static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 416static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
417static const DECLARE_TLV_DB_SCALE(threedstereo_tlv, -1600, 183, 1);
417 418
418static const char *sidetone_hpf_text[] = { 419static const char *sidetone_hpf_text[] = {
419 "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz" 420 "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz"
@@ -608,6 +609,14 @@ SOC_SINGLE("DAC High Performance Switch", WM8996_OVERSAMPLING, 0, 1, 0),
608SOC_SINGLE("DAC Soft Mute Switch", WM8996_DAC_SOFTMUTE, 1, 1, 0), 609SOC_SINGLE("DAC Soft Mute Switch", WM8996_DAC_SOFTMUTE, 1, 1, 0),
609SOC_SINGLE("DAC Slow Soft Mute Switch", WM8996_DAC_SOFTMUTE, 0, 1, 0), 610SOC_SINGLE("DAC Slow Soft Mute Switch", WM8996_DAC_SOFTMUTE, 0, 1, 0),
610 611
612SOC_SINGLE("DSP1 3D Stereo Switch", WM8996_DSP1_RX_FILTERS_2, 8, 1, 0),
613SOC_SINGLE("DSP2 3D Stereo Switch", WM8996_DSP2_RX_FILTERS_2, 8, 1, 0),
614
615SOC_SINGLE_TLV("DSP1 3D Stereo Volume", WM8996_DSP1_RX_FILTERS_2, 10, 15,
616 0, threedstereo_tlv),
617SOC_SINGLE_TLV("DSP2 3D Stereo Volume", WM8996_DSP2_RX_FILTERS_2, 10, 15,
618 0, threedstereo_tlv),
619
611SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8996_DAC1_HPOUT1_VOLUME, 0, 4, 620SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8996_DAC1_HPOUT1_VOLUME, 0, 4,
612 8, 0, out_digital_tlv), 621 8, 0, out_digital_tlv),
613SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8996_DAC2_HPOUT2_VOLUME, 0, 4, 622SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8996_DAC2_HPOUT2_VOLUME, 0, 4,
@@ -632,6 +641,14 @@ SOC_DOUBLE_R("Speaker ZC Switch", WM8996_LEFT_PDM_SPEAKER,
632 641
633SOC_SINGLE("DSP1 EQ Switch", WM8996_DSP1_RX_EQ_GAINS_1, 0, 1, 0), 642SOC_SINGLE("DSP1 EQ Switch", WM8996_DSP1_RX_EQ_GAINS_1, 0, 1, 0),
634SOC_SINGLE("DSP2 EQ Switch", WM8996_DSP2_RX_EQ_GAINS_1, 0, 1, 0), 643SOC_SINGLE("DSP2 EQ Switch", WM8996_DSP2_RX_EQ_GAINS_1, 0, 1, 0),
644
645SOC_SINGLE("DSP1 DRC TXL Switch", WM8996_DSP1_DRC_1, 0, 1, 0),
646SOC_SINGLE("DSP1 DRC TXR Switch", WM8996_DSP1_DRC_1, 1, 1, 0),
647SOC_SINGLE("DSP1 DRC RX Switch", WM8996_DSP1_DRC_1, 2, 1, 0),
648
649SOC_SINGLE("DSP2 DRC TXL Switch", WM8996_DSP2_DRC_1, 0, 1, 0),
650SOC_SINGLE("DSP2 DRC TXR Switch", WM8996_DSP2_DRC_1, 1, 1, 0),
651SOC_SINGLE("DSP2 DRC RX Switch", WM8996_DSP2_DRC_1, 2, 1, 0),
635}; 652};
636 653
637static const struct snd_kcontrol_new wm8996_eq_controls[] = { 654static const struct snd_kcontrol_new wm8996_eq_controls[] = {
@@ -658,19 +675,75 @@ SOC_SINGLE_TLV("DSP2 EQ B5 Volume", WM8996_DSP2_RX_EQ_GAINS_2, 6, 31, 0,
658 eq_tlv), 675 eq_tlv),
659}; 676};
660 677
678static void wm8996_bg_enable(struct snd_soc_codec *codec)
679{
680 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
681
682 wm8996->bg_ena++;
683 if (wm8996->bg_ena == 1) {
684 snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
685 WM8996_BG_ENA, WM8996_BG_ENA);
686 msleep(2);
687 }
688}
689
690static void wm8996_bg_disable(struct snd_soc_codec *codec)
691{
692 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
693
694 wm8996->bg_ena--;
695 if (!wm8996->bg_ena)
696 snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
697 WM8996_BG_ENA, 0);
698}
699
700static int bg_event(struct snd_soc_dapm_widget *w,
701 struct snd_kcontrol *kcontrol, int event)
702{
703 struct snd_soc_codec *codec = w->codec;
704 int ret = 0;
705
706 switch (event) {
707 case SND_SOC_DAPM_PRE_PMU:
708 wm8996_bg_enable(codec);
709 break;
710 case SND_SOC_DAPM_POST_PMD:
711 wm8996_bg_disable(codec);
712 break;
713 default:
714 BUG();
715 ret = -EINVAL;
716 }
717
718 return ret;
719}
720
661static int cp_event(struct snd_soc_dapm_widget *w, 721static int cp_event(struct snd_soc_dapm_widget *w,
662 struct snd_kcontrol *kcontrol, int event) 722 struct snd_kcontrol *kcontrol, int event)
663{ 723{
724 struct snd_soc_codec *codec = w->codec;
725 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
726 int ret = 0;
727
664 switch (event) { 728 switch (event) {
729 case SND_SOC_DAPM_PRE_PMU:
730 ret = regulator_enable(wm8996->cpvdd);
731 if (ret != 0)
732 dev_err(codec->dev, "Failed to enable CPVDD: %d\n",
733 ret);
734 break;
665 case SND_SOC_DAPM_POST_PMU: 735 case SND_SOC_DAPM_POST_PMU:
666 msleep(5); 736 msleep(5);
667 break; 737 break;
738 case SND_SOC_DAPM_POST_PMD:
739 regulator_disable_deferred(wm8996->cpvdd, 20);
740 break;
668 default: 741 default:
669 BUG(); 742 BUG();
670 return -EINVAL; 743 ret = -EINVAL;
671 } 744 }
672 745
673 return 0; 746 return ret;
674} 747}
675 748
676static int rmv_short_event(struct snd_soc_dapm_widget *w, 749static int rmv_short_event(struct snd_soc_dapm_widget *w,
@@ -698,7 +771,7 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask)
698{ 771{
699 struct i2c_client *i2c = to_i2c_client(codec->dev); 772 struct i2c_client *i2c = to_i2c_client(codec->dev);
700 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 773 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
701 int i, ret; 774 int ret;
702 unsigned long timeout = 200; 775 unsigned long timeout = 200;
703 776
704 snd_soc_write(codec, WM8996_DC_SERVO_2, mask); 777 snd_soc_write(codec, WM8996_DC_SERVO_2, mask);
@@ -713,15 +786,12 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask)
713 786
714 } else { 787 } else {
715 msleep(1); 788 msleep(1);
716 if (--i) { 789 timeout--;
717 timeout = 0;
718 break;
719 }
720 } 790 }
721 791
722 ret = snd_soc_read(codec, WM8996_DC_SERVO_2); 792 ret = snd_soc_read(codec, WM8996_DC_SERVO_2);
723 dev_dbg(codec->dev, "DC servo state: %x\n", ret); 793 dev_dbg(codec->dev, "DC servo state: %x\n", ret);
724 } while (ret & mask); 794 } while (timeout && ret & mask);
725 795
726 if (timeout == 0) 796 if (timeout == 0)
727 dev_err(codec->dev, "DC servo timed out for %x\n", mask); 797 dev_err(codec->dev, "DC servo timed out for %x\n", mask);
@@ -979,9 +1049,12 @@ SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0),
979SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0), 1049SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0),
980SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0), 1050SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0),
981SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event, 1051SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event,
982 SND_SOC_DAPM_POST_PMU), 1052 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
983 1053SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event,
1054 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
984SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0), 1055SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
1056SND_SOC_DAPM_SUPPLY("MICB1 Audio", WM8996_MICBIAS_1, 4, 1, NULL, 0),
1057SND_SOC_DAPM_SUPPLY("MICB2 Audio", WM8996_MICBIAS_2, 4, 1, NULL, 0),
985SND_SOC_DAPM_MICBIAS("MICB2", WM8996_POWER_MANAGEMENT_1, 9, 0), 1058SND_SOC_DAPM_MICBIAS("MICB2", WM8996_POWER_MANAGEMENT_1, 9, 0),
986SND_SOC_DAPM_MICBIAS("MICB1", WM8996_POWER_MANAGEMENT_1, 8, 0), 1059SND_SOC_DAPM_MICBIAS("MICB1", WM8996_POWER_MANAGEMENT_1, 8, 0),
987 1060
@@ -1035,14 +1108,14 @@ SND_SOC_DAPM_DAC("DAC2R", NULL, WM8996_POWER_MANAGEMENT_5, 2, 0),
1035SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0), 1108SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0),
1036SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0), 1109SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0),
1037 1110
1038SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 1, 1111SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 0,
1039 WM8996_POWER_MANAGEMENT_4, 9, 0), 1112 WM8996_POWER_MANAGEMENT_4, 9, 0),
1040SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 2, 1113SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 1,
1041 WM8996_POWER_MANAGEMENT_4, 8, 0), 1114 WM8996_POWER_MANAGEMENT_4, 8, 0),
1042 1115
1043SND_SOC_DAPM_AIF_IN("AIF2TX1", "AIF2 Capture", 1, 1116SND_SOC_DAPM_AIF_OUT("AIF2TX1", "AIF2 Capture", 0,
1044 WM8996_POWER_MANAGEMENT_6, 9, 0), 1117 WM8996_POWER_MANAGEMENT_6, 9, 0),
1045SND_SOC_DAPM_AIF_IN("AIF2TX0", "AIF2 Capture", 2, 1118SND_SOC_DAPM_AIF_OUT("AIF2TX0", "AIF2 Capture", 1,
1046 WM8996_POWER_MANAGEMENT_6, 8, 0), 1119 WM8996_POWER_MANAGEMENT_6, 8, 0),
1047 1120
1048SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5, 1121SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5,
@@ -1137,17 +1210,23 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1137 { "Charge Pump", NULL, "SYSCLK" }, 1210 { "Charge Pump", NULL, "SYSCLK" },
1138 1211
1139 { "MICB1", NULL, "LDO2" }, 1212 { "MICB1", NULL, "LDO2" },
1213 { "MICB1", NULL, "MICB1 Audio" },
1214 { "MICB1", NULL, "Bandgap" },
1140 { "MICB2", NULL, "LDO2" }, 1215 { "MICB2", NULL, "LDO2" },
1216 { "MICB2", NULL, "MICB2 Audio" },
1217 { "MICB2", NULL, "Bandgap" },
1141 1218
1142 { "IN1L PGA", NULL, "IN2LN" }, 1219 { "IN1L PGA", NULL, "IN2LN" },
1143 { "IN1L PGA", NULL, "IN2LP" }, 1220 { "IN1L PGA", NULL, "IN2LP" },
1144 { "IN1L PGA", NULL, "IN1LN" }, 1221 { "IN1L PGA", NULL, "IN1LN" },
1145 { "IN1L PGA", NULL, "IN1LP" }, 1222 { "IN1L PGA", NULL, "IN1LP" },
1223 { "IN1L PGA", NULL, "Bandgap" },
1146 1224
1147 { "IN1R PGA", NULL, "IN2RN" }, 1225 { "IN1R PGA", NULL, "IN2RN" },
1148 { "IN1R PGA", NULL, "IN2RP" }, 1226 { "IN1R PGA", NULL, "IN2RP" },
1149 { "IN1R PGA", NULL, "IN1RN" }, 1227 { "IN1R PGA", NULL, "IN1RN" },
1150 { "IN1R PGA", NULL, "IN1RP" }, 1228 { "IN1R PGA", NULL, "IN1RP" },
1229 { "IN1R PGA", NULL, "Bandgap" },
1151 1230
1152 { "ADCL", NULL, "IN1L PGA" }, 1231 { "ADCL", NULL, "IN1L PGA" },
1153 1232
@@ -1281,6 +1360,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1281 { "DAC2R", NULL, "DAC2R Mixer" }, 1360 { "DAC2R", NULL, "DAC2R Mixer" },
1282 1361
1283 { "HPOUT2L PGA", NULL, "Charge Pump" }, 1362 { "HPOUT2L PGA", NULL, "Charge Pump" },
1363 { "HPOUT2L PGA", NULL, "Bandgap" },
1284 { "HPOUT2L PGA", NULL, "DAC2L" }, 1364 { "HPOUT2L PGA", NULL, "DAC2L" },
1285 { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" }, 1365 { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" },
1286 { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" }, 1366 { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" },
@@ -1288,6 +1368,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1288 { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" }, 1368 { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" },
1289 1369
1290 { "HPOUT2R PGA", NULL, "Charge Pump" }, 1370 { "HPOUT2R PGA", NULL, "Charge Pump" },
1371 { "HPOUT2R PGA", NULL, "Bandgap" },
1291 { "HPOUT2R PGA", NULL, "DAC2R" }, 1372 { "HPOUT2R PGA", NULL, "DAC2R" },
1292 { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" }, 1373 { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" },
1293 { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" }, 1374 { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" },
@@ -1295,6 +1376,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1295 { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" }, 1376 { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" },
1296 1377
1297 { "HPOUT1L PGA", NULL, "Charge Pump" }, 1378 { "HPOUT1L PGA", NULL, "Charge Pump" },
1379 { "HPOUT1L PGA", NULL, "Bandgap" },
1298 { "HPOUT1L PGA", NULL, "DAC1L" }, 1380 { "HPOUT1L PGA", NULL, "DAC1L" },
1299 { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" }, 1381 { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" },
1300 { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" }, 1382 { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" },
@@ -1302,6 +1384,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1302 { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" }, 1384 { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" },
1303 1385
1304 { "HPOUT1R PGA", NULL, "Charge Pump" }, 1386 { "HPOUT1R PGA", NULL, "Charge Pump" },
1387 { "HPOUT1R PGA", NULL, "Bandgap" },
1305 { "HPOUT1R PGA", NULL, "DAC1R" }, 1388 { "HPOUT1R PGA", NULL, "DAC1R" },
1306 { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" }, 1389 { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" },
1307 { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" }, 1390 { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" },
@@ -1620,14 +1703,7 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec,
1620 1703
1621 switch (level) { 1704 switch (level) {
1622 case SND_SOC_BIAS_ON: 1705 case SND_SOC_BIAS_ON:
1623 break;
1624
1625 case SND_SOC_BIAS_PREPARE: 1706 case SND_SOC_BIAS_PREPARE:
1626 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
1627 snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
1628 WM8996_BG_ENA, WM8996_BG_ENA);
1629 msleep(2);
1630 }
1631 break; 1707 break;
1632 1708
1633 case SND_SOC_BIAS_STANDBY: 1709 case SND_SOC_BIAS_STANDBY:
@@ -1650,9 +1726,6 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec,
1650 codec->cache_only = false; 1726 codec->cache_only = false;
1651 snd_soc_cache_sync(codec); 1727 snd_soc_cache_sync(codec);
1652 } 1728 }
1653
1654 snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
1655 WM8996_BG_ENA, 0);
1656 break; 1729 break;
1657 1730
1658 case SND_SOC_BIAS_OFF: 1731 case SND_SOC_BIAS_OFF:
@@ -1847,7 +1920,7 @@ static int wm8996_hw_params(struct snd_pcm_substream *substream,
1847 snd_soc_update_bits(codec, lrclk_reg, WM8996_AIF1RX_RATE_MASK, 1920 snd_soc_update_bits(codec, lrclk_reg, WM8996_AIF1RX_RATE_MASK,
1848 lrclk); 1921 lrclk);
1849 snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_2, 1922 snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_2,
1850 WM8996_DSP1_DIV_SHIFT << dsp_shift, dsp); 1923 WM8996_DSP1_DIV_MASK << dsp_shift, dsp);
1851 1924
1852 return 0; 1925 return 0;
1853} 1926}
@@ -2041,7 +2114,7 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2041 struct i2c_client *i2c = to_i2c_client(codec->dev); 2114 struct i2c_client *i2c = to_i2c_client(codec->dev);
2042 struct _fll_div fll_div; 2115 struct _fll_div fll_div;
2043 unsigned long timeout; 2116 unsigned long timeout;
2044 int ret, reg; 2117 int ret, reg, retry;
2045 2118
2046 /* Any change? */ 2119 /* Any change? */
2047 if (source == wm8996->fll_src && Fref == wm8996->fll_fref && 2120 if (source == wm8996->fll_src && Fref == wm8996->fll_fref &&
@@ -2057,6 +2130,8 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2057 snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1, 2130 snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1,
2058 WM8996_FLL_ENA, 0); 2131 WM8996_FLL_ENA, 0);
2059 2132
2133 wm8996_bg_disable(codec);
2134
2060 return 0; 2135 return 0;
2061 } 2136 }
2062 2137
@@ -2111,6 +2186,11 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2111 2186
2112 snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda); 2187 snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda);
2113 2188
2189 /* Enable the bandgap if it's not already enabled */
2190 ret = snd_soc_read(codec, WM8996_FLL_CONTROL_1);
2191 if (!(ret & WM8996_FLL_ENA))
2192 wm8996_bg_enable(codec);
2193
2114 /* Clear any pending completions (eg, from failed startups) */ 2194 /* Clear any pending completions (eg, from failed startups) */
2115 try_wait_for_completion(&wm8996->fll_lock); 2195 try_wait_for_completion(&wm8996->fll_lock);
2116 2196
@@ -2128,17 +2208,29 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2128 else 2208 else
2129 timeout = msecs_to_jiffies(2); 2209 timeout = msecs_to_jiffies(2);
2130 2210
2131 /* Allow substantially longer if we've actually got the IRQ */ 2211 /* Allow substantially longer if we've actually got the IRQ, poll
2212 * at a slightly higher rate if we don't.
2213 */
2132 if (i2c->irq) 2214 if (i2c->irq)
2133 timeout *= 1000; 2215 timeout *= 10;
2216 else
2217 timeout /= 2;
2134 2218
2135 ret = wait_for_completion_timeout(&wm8996->fll_lock, timeout); 2219 for (retry = 0; retry < 10; retry++) {
2220 ret = wait_for_completion_timeout(&wm8996->fll_lock,
2221 timeout);
2222 if (ret != 0) {
2223 WARN_ON(!i2c->irq);
2224 break;
2225 }
2136 2226
2137 if (ret == 0 && i2c->irq) { 2227 ret = snd_soc_read(codec, WM8996_INTERRUPT_RAW_STATUS_2);
2228 if (ret & WM8996_FLL_LOCK_STS)
2229 break;
2230 }
2231 if (retry == 10) {
2138 dev_err(codec->dev, "Timed out waiting for FLL\n"); 2232 dev_err(codec->dev, "Timed out waiting for FLL\n");
2139 ret = -ETIMEDOUT; 2233 ret = -ETIMEDOUT;
2140 } else {
2141 ret = 0;
2142 } 2234 }
2143 2235
2144 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); 2236 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
@@ -2297,12 +2389,94 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2297 2389
2298 /* Enable interrupts and we're off */ 2390 /* Enable interrupts and we're off */
2299 snd_soc_update_bits(codec, WM8996_INTERRUPT_STATUS_2_MASK, 2391 snd_soc_update_bits(codec, WM8996_INTERRUPT_STATUS_2_MASK,
2300 WM8996_IM_MICD_EINT, 0); 2392 WM8996_IM_MICD_EINT | WM8996_HP_DONE_EINT, 0);
2301 2393
2302 return 0; 2394 return 0;
2303} 2395}
2304EXPORT_SYMBOL_GPL(wm8996_detect); 2396EXPORT_SYMBOL_GPL(wm8996_detect);
2305 2397
2398static void wm8996_hpdet_irq(struct snd_soc_codec *codec)
2399{
2400 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
2401 int val, reg, report;
2402
2403 /* Assume headphone in error conditions; we need to report
2404 * something or we stall our state machine.
2405 */
2406 report = SND_JACK_HEADPHONE;
2407
2408 reg = snd_soc_read(codec, WM8996_HEADPHONE_DETECT_2);
2409 if (reg < 0) {
2410 dev_err(codec->dev, "Failed to read HPDET status\n");
2411 goto out;
2412 }
2413
2414 if (!(reg & WM8996_HP_DONE)) {
2415 dev_err(codec->dev, "Got HPDET IRQ but HPDET is busy\n");
2416 goto out;
2417 }
2418
2419 val = reg & WM8996_HP_LVL_MASK;
2420
2421 dev_dbg(codec->dev, "HPDET measured %d ohms\n", val);
2422
2423 /* If we've got high enough impedence then report as line,
2424 * otherwise assume headphone.
2425 */
2426 if (val >= 126)
2427 report = SND_JACK_LINEOUT;
2428 else
2429 report = SND_JACK_HEADPHONE;
2430
2431out:
2432 if (wm8996->jack_mic)
2433 report |= SND_JACK_MICROPHONE;
2434
2435 snd_soc_jack_report(wm8996->jack, report,
2436 SND_JACK_LINEOUT | SND_JACK_HEADSET);
2437
2438 wm8996->detecting = false;
2439
2440 /* If the output isn't running re-clamp it */
2441 if (!(snd_soc_read(codec, WM8996_POWER_MANAGEMENT_1) &
2442 (WM8996_HPOUT1L_ENA | WM8996_HPOUT1R_RMV_SHORT)))
2443 snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1,
2444 WM8996_HPOUT1L_RMV_SHORT |
2445 WM8996_HPOUT1R_RMV_SHORT, 0);
2446
2447 /* Go back to looking at the microphone */
2448 snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_1,
2449 WM8996_JD_MODE_MASK, 0);
2450 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, WM8996_MICD_ENA,
2451 WM8996_MICD_ENA);
2452
2453 snd_soc_dapm_disable_pin(&codec->dapm, "Bandgap");
2454 snd_soc_dapm_sync(&codec->dapm);
2455}
2456
2457static void wm8996_hpdet_start(struct snd_soc_codec *codec)
2458{
2459 /* Unclamp the output, we can't measure while we're shorting it */
2460 snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1,
2461 WM8996_HPOUT1L_RMV_SHORT |
2462 WM8996_HPOUT1R_RMV_SHORT,
2463 WM8996_HPOUT1L_RMV_SHORT |
2464 WM8996_HPOUT1R_RMV_SHORT);
2465
2466 /* We need bandgap for HPDET */
2467 snd_soc_dapm_force_enable_pin(&codec->dapm, "Bandgap");
2468 snd_soc_dapm_sync(&codec->dapm);
2469
2470 /* Go into headphone detect left mode */
2471 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, WM8996_MICD_ENA, 0);
2472 snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_1,
2473 WM8996_JD_MODE_MASK, 1);
2474
2475 /* Trigger a measurement */
2476 snd_soc_update_bits(codec, WM8996_HEADPHONE_DETECT_1,
2477 WM8996_HP_POLL, WM8996_HP_POLL);
2478}
2479
2306static void wm8996_micd(struct snd_soc_codec *codec) 2480static void wm8996_micd(struct snd_soc_codec *codec)
2307{ 2481{
2308 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 2482 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
@@ -2323,28 +2497,36 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2323 wm8996->jack_mic = false; 2497 wm8996->jack_mic = false;
2324 wm8996->detecting = true; 2498 wm8996->detecting = true;
2325 snd_soc_jack_report(wm8996->jack, 0, 2499 snd_soc_jack_report(wm8996->jack, 0,
2326 SND_JACK_HEADSET | SND_JACK_BTN_0); 2500 SND_JACK_LINEOUT | SND_JACK_HEADSET |
2501 SND_JACK_BTN_0);
2502
2327 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, 2503 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
2328 WM8996_MICD_RATE_MASK, 2504 WM8996_MICD_RATE_MASK,
2329 WM8996_MICD_RATE_MASK); 2505 WM8996_MICD_RATE_MASK);
2330 return; 2506 return;
2331 } 2507 }
2332 2508
2333 /* If the measurement is very high we've got a microphone but 2509 /* If the measurement is very high we've got a microphone,
2334 * do a little debounce to account for mechanical issues. 2510 * either we just detected one or if we already reported then
2511 * we've got a button release event.
2335 */ 2512 */
2336 if (val & 0x400) { 2513 if (val & 0x400) {
2337 dev_dbg(codec->dev, "Microphone detected\n"); 2514 if (wm8996->detecting) {
2338 snd_soc_jack_report(wm8996->jack, SND_JACK_HEADSET, 2515 dev_dbg(codec->dev, "Microphone detected\n");
2339 SND_JACK_HEADSET | SND_JACK_BTN_0); 2516 wm8996->jack_mic = true;
2340 wm8996->jack_mic = true; 2517 wm8996_hpdet_start(codec);
2341 wm8996->detecting = false; 2518
2342 2519 /* Increase poll rate to give better responsiveness
2343 /* Increase poll rate to give better responsiveness 2520 * for buttons */
2344 * for buttons */ 2521 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
2345 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, 2522 WM8996_MICD_RATE_MASK,
2346 WM8996_MICD_RATE_MASK, 2523 5 << WM8996_MICD_RATE_SHIFT);
2347 5 << WM8996_MICD_RATE_SHIFT); 2524 } else {
2525 dev_dbg(codec->dev, "Mic button up\n");
2526 snd_soc_jack_report(wm8996->jack, 0, SND_JACK_BTN_0);
2527 }
2528
2529 return;
2348 } 2530 }
2349 2531
2350 /* If we detected a lower impedence during initial startup 2532 /* If we detected a lower impedence during initial startup
@@ -2376,15 +2558,11 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2376 if (val & 0x3fc) { 2558 if (val & 0x3fc) {
2377 if (wm8996->jack_mic) { 2559 if (wm8996->jack_mic) {
2378 dev_dbg(codec->dev, "Mic button detected\n"); 2560 dev_dbg(codec->dev, "Mic button detected\n");
2379 snd_soc_jack_report(wm8996->jack, 2561 snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0,
2380 SND_JACK_HEADSET | SND_JACK_BTN_0,
2381 SND_JACK_HEADSET | SND_JACK_BTN_0);
2382 } else {
2383 dev_dbg(codec->dev, "Headphone detected\n");
2384 snd_soc_jack_report(wm8996->jack,
2385 SND_JACK_HEADPHONE,
2386 SND_JACK_HEADSET |
2387 SND_JACK_BTN_0); 2562 SND_JACK_BTN_0);
2563 } else if (wm8996->detecting) {
2564 dev_dbg(codec->dev, "Headphone detected\n");
2565 wm8996_hpdet_start(codec);
2388 2566
2389 /* Increase the detection rate a bit for 2567 /* Increase the detection rate a bit for
2390 * responsiveness. 2568 * responsiveness.
@@ -2392,8 +2570,6 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2392 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, 2570 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
2393 WM8996_MICD_RATE_MASK, 2571 WM8996_MICD_RATE_MASK,
2394 7 << WM8996_MICD_RATE_SHIFT); 2572 7 << WM8996_MICD_RATE_SHIFT);
2395
2396 wm8996->detecting = false;
2397 } 2573 }
2398 } 2574 }
2399} 2575}
@@ -2412,6 +2588,9 @@ static irqreturn_t wm8996_irq(int irq, void *data)
2412 } 2588 }
2413 irq_val &= ~snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2_MASK); 2589 irq_val &= ~snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2_MASK);
2414 2590
2591 if (!irq_val)
2592 return IRQ_NONE;
2593
2415 snd_soc_write(codec, WM8996_INTERRUPT_STATUS_2, irq_val); 2594 snd_soc_write(codec, WM8996_INTERRUPT_STATUS_2, irq_val);
2416 2595
2417 if (irq_val & (WM8996_DCS_DONE_01_EINT | WM8996_DCS_DONE_23_EINT)) { 2596 if (irq_val & (WM8996_DCS_DONE_01_EINT | WM8996_DCS_DONE_23_EINT)) {
@@ -2430,10 +2609,10 @@ static irqreturn_t wm8996_irq(int irq, void *data)
2430 if (irq_val & WM8996_MICD_EINT) 2609 if (irq_val & WM8996_MICD_EINT)
2431 wm8996_micd(codec); 2610 wm8996_micd(codec);
2432 2611
2433 if (irq_val) 2612 if (irq_val & WM8996_HP_DONE_EINT)
2434 return IRQ_HANDLED; 2613 wm8996_hpdet_irq(codec);
2435 else 2614
2436 return IRQ_NONE; 2615 return IRQ_HANDLED;
2437} 2616}
2438 2617
2439static irqreturn_t wm8996_edge_irq(int irq, void *data) 2618static irqreturn_t wm8996_edge_irq(int irq, void *data)
@@ -2527,7 +2706,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2527 init_completion(&wm8996->fll_lock); 2706 init_completion(&wm8996->fll_lock);
2528 2707
2529 dapm->idle_bias_off = true; 2708 dapm->idle_bias_off = true;
2530 dapm->bias_level = SND_SOC_BIAS_OFF;
2531 2709
2532 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); 2710 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
2533 if (ret != 0) { 2711 if (ret != 0) {
@@ -2548,7 +2726,13 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2548 wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0; 2726 wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0;
2549 wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1; 2727 wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1;
2550 wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2; 2728 wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2;
2551 wm8996->disable_nb[3].notifier_call = wm8996_regulator_event_3; 2729
2730 wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD");
2731 if (IS_ERR(wm8996->cpvdd)) {
2732 ret = PTR_ERR(wm8996->cpvdd);
2733 dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
2734 goto err_get;
2735 }
2552 2736
2553 /* This should really be moved into the regulator core */ 2737 /* This should really be moved into the regulator core */
2554 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) { 2738 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) {
@@ -2565,7 +2749,7 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2565 wm8996->supplies); 2749 wm8996->supplies);
2566 if (ret != 0) { 2750 if (ret != 0) {
2567 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); 2751 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
2568 goto err_get; 2752 goto err_cpvdd;
2569 } 2753 }
2570 2754
2571 if (wm8996->pdata.ldo_ena >= 0) { 2755 if (wm8996->pdata.ldo_ena >= 0) {
@@ -2808,6 +2992,8 @@ err_enable:
2808 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 2992 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
2809 2993
2810 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 2994 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
2995err_cpvdd:
2996 regulator_put(wm8996->cpvdd);
2811err_get: 2997err_get:
2812 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 2998 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
2813err: 2999err:
@@ -2831,6 +3017,7 @@ static int wm8996_remove(struct snd_soc_codec *codec)
2831 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) 3017 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
2832 regulator_unregister_notifier(wm8996->supplies[i].consumer, 3018 regulator_unregister_notifier(wm8996->supplies[i].consumer,
2833 &wm8996->disable_nb[i]); 3019 &wm8996->disable_nb[i]);
3020 regulator_put(wm8996->cpvdd);
2834 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 3021 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
2835 3022
2836 return 0; 3023 return 0;