Commit 246693ba7b0b824a970f9431486ad88c18e0ce2d

Authored by Bard Liao
Committed by Mark Brown
1 parent 54ac045026

ASoC: rt5640: change widget sequence for depop

Signed-off-by: Bard Liao <bardliao@realtek.com>
Tested-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Mark Brown <broonie@linaro.org>

Showing 2 changed files with 175 additions and 54 deletions Side-by-side Diff

sound/soc/codecs/rt5640.c
... ... @@ -50,8 +50,6 @@
50 50  
51 51 static struct reg_default init_list[] = {
52 52 {RT5640_PR_BASE + 0x3d, 0x3600},
53   - {RT5640_PR_BASE + 0x1c, 0x0D21},
54   - {RT5640_PR_BASE + 0x1b, 0x0000},
55 53 {RT5640_PR_BASE + 0x12, 0x0aa8},
56 54 {RT5640_PR_BASE + 0x14, 0x0aaa},
57 55 {RT5640_PR_BASE + 0x20, 0x6110},
58 56  
... ... @@ -384,15 +382,11 @@
384 382  
385 383 static const struct snd_kcontrol_new rt5640_snd_controls[] = {
386 384 /* Speaker Output Volume */
387   - SOC_DOUBLE("Speaker Playback Switch", RT5640_SPK_VOL,
388   - RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1),
389 385 SOC_DOUBLE("Speaker Channel Switch", RT5640_SPK_VOL,
390 386 RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1),
391 387 SOC_DOUBLE_TLV("Speaker Playback Volume", RT5640_SPK_VOL,
392 388 RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv),
393 389 /* Headphone Output Volume */
394   - SOC_DOUBLE("HP Playback Switch", RT5640_HP_VOL,
395   - RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1),
396 390 SOC_DOUBLE("HP Channel Switch", RT5640_HP_VOL,
397 391 RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1),
398 392 SOC_DOUBLE_TLV("HP Playback Volume", RT5640_HP_VOL,
... ... @@ -737,6 +731,22 @@
737 731 RT5640_M_BST1_MM_SFT, 1, 1),
738 732 };
739 733  
  734 +static const struct snd_kcontrol_new spk_l_enable_control =
  735 + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_SPK_VOL,
  736 + RT5640_L_MUTE_SFT, 1, 1);
  737 +
  738 +static const struct snd_kcontrol_new spk_r_enable_control =
  739 + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_SPK_VOL,
  740 + RT5640_R_MUTE_SFT, 1, 1);
  741 +
  742 +static const struct snd_kcontrol_new hp_l_enable_control =
  743 + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_HP_VOL,
  744 + RT5640_L_MUTE_SFT, 1, 1);
  745 +
  746 +static const struct snd_kcontrol_new hp_r_enable_control =
  747 + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_HP_VOL,
  748 + RT5640_R_MUTE_SFT, 1, 1);
  749 +
740 750 /* Stereo ADC source */
741 751 static const char * const rt5640_stereo_adc1_src[] = {
742 752 "DIG MIX", "ADC"
... ... @@ -868,33 +878,6 @@
868 878 static const struct snd_kcontrol_new rt5640_sdi_mux =
869 879 SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum);
870 880  
871   -static int spk_event(struct snd_soc_dapm_widget *w,
872   - struct snd_kcontrol *kcontrol, int event)
873   -{
874   - struct snd_soc_codec *codec = w->codec;
875   - struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
876   -
877   - switch (event) {
878   - case SND_SOC_DAPM_POST_PMU:
879   - regmap_update_bits(rt5640->regmap, RT5640_PWR_DIG1,
880   - 0x0001, 0x0001);
881   - regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + 0x1c,
882   - 0xf000, 0xf000);
883   - break;
884   -
885   - case SND_SOC_DAPM_PRE_PMD:
886   - regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + 0x1c,
887   - 0xf000, 0x0000);
888   - regmap_update_bits(rt5640->regmap, RT5640_PWR_DIG1,
889   - 0x0001, 0x0000);
890   - break;
891   -
892   - default:
893   - return 0;
894   - }
895   - return 0;
896   -}
897   -
898 881 static int rt5640_set_dmic1_event(struct snd_soc_dapm_widget *w,
899 882 struct snd_kcontrol *kcontrol, int event)
900 883 {
... ... @@ -943,6 +926,117 @@
943 926 return 0;
944 927 }
945 928  
  929 +void hp_amp_power_on(struct snd_soc_codec *codec)
  930 +{
  931 + struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
  932 +
  933 + /* depop parameters */
  934 + regmap_update_bits(rt5640->regmap, RT5640_PR_BASE +
  935 + RT5640_CHPUMP_INT_REG1, 0x0700, 0x0200);
  936 + regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M2,
  937 + RT5640_DEPOP_MASK, RT5640_DEPOP_MAN);
  938 + regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M1,
  939 + RT5640_HP_CP_MASK | RT5640_HP_SG_MASK | RT5640_HP_CB_MASK,
  940 + RT5640_HP_CP_PU | RT5640_HP_SG_DIS | RT5640_HP_CB_PU);
  941 + regmap_write(rt5640->regmap, RT5640_PR_BASE + RT5640_HP_DCC_INT1,
  942 + 0x9f00);
  943 + /* headphone amp power on */
  944 + regmap_update_bits(rt5640->regmap, RT5640_PWR_ANLG1,
  945 + RT5640_PWR_FV1 | RT5640_PWR_FV2, 0);
  946 + regmap_update_bits(rt5640->regmap, RT5640_PWR_ANLG1,
  947 + RT5640_PWR_HA,
  948 + RT5640_PWR_HA);
  949 + usleep_range(10000, 15000);
  950 + regmap_update_bits(rt5640->regmap, RT5640_PWR_ANLG1,
  951 + RT5640_PWR_FV1 | RT5640_PWR_FV2 ,
  952 + RT5640_PWR_FV1 | RT5640_PWR_FV2);
  953 +}
  954 +
  955 +static void rt5640_pmu_depop(struct snd_soc_codec *codec)
  956 +{
  957 + struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
  958 +
  959 + regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M2,
  960 + RT5640_DEPOP_MASK | RT5640_DIG_DP_MASK,
  961 + RT5640_DEPOP_AUTO | RT5640_DIG_DP_EN);
  962 + regmap_update_bits(rt5640->regmap, RT5640_CHARGE_PUMP,
  963 + RT5640_PM_HP_MASK, RT5640_PM_HP_HV);
  964 +
  965 + regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M3,
  966 + RT5640_CP_FQ1_MASK | RT5640_CP_FQ2_MASK | RT5640_CP_FQ3_MASK,
  967 + (RT5640_CP_FQ_192_KHZ << RT5640_CP_FQ1_SFT) |
  968 + (RT5640_CP_FQ_12_KHZ << RT5640_CP_FQ2_SFT) |
  969 + (RT5640_CP_FQ_192_KHZ << RT5640_CP_FQ3_SFT));
  970 +
  971 + regmap_write(rt5640->regmap, RT5640_PR_BASE +
  972 + RT5640_MAMP_INT_REG2, 0x1c00);
  973 + regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M1,
  974 + RT5640_HP_CP_MASK | RT5640_HP_SG_MASK,
  975 + RT5640_HP_CP_PD | RT5640_HP_SG_EN);
  976 + regmap_update_bits(rt5640->regmap, RT5640_PR_BASE +
  977 + RT5640_CHPUMP_INT_REG1, 0x0700, 0x0400);
  978 +}
  979 +
  980 +static int rt5640_hp_event(struct snd_soc_dapm_widget *w,
  981 + struct snd_kcontrol *kcontrol, int event)
  982 +{
  983 + struct snd_soc_codec *codec = w->codec;
  984 + struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
  985 +
  986 + switch (event) {
  987 + case SND_SOC_DAPM_POST_PMU:
  988 + rt5640_pmu_depop(codec);
  989 + rt5640->hp_mute = 0;
  990 + break;
  991 +
  992 + case SND_SOC_DAPM_PRE_PMD:
  993 + rt5640->hp_mute = 1;
  994 + usleep_range(70000, 75000);
  995 + break;
  996 +
  997 + default:
  998 + return 0;
  999 + }
  1000 +
  1001 + return 0;
  1002 +}
  1003 +
  1004 +static int rt5640_hp_power_event(struct snd_soc_dapm_widget *w,
  1005 + struct snd_kcontrol *kcontrol, int event)
  1006 +{
  1007 + struct snd_soc_codec *codec = w->codec;
  1008 +
  1009 + switch (event) {
  1010 + case SND_SOC_DAPM_POST_PMU:
  1011 + hp_amp_power_on(codec);
  1012 + break;
  1013 + default:
  1014 + return 0;
  1015 + }
  1016 +
  1017 + return 0;
  1018 +}
  1019 +
  1020 +static int rt5640_hp_post_event(struct snd_soc_dapm_widget *w,
  1021 + struct snd_kcontrol *kcontrol, int event)
  1022 +{
  1023 + struct snd_soc_codec *codec = w->codec;
  1024 + struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
  1025 +
  1026 + switch (event) {
  1027 + case SND_SOC_DAPM_POST_PMU:
  1028 + if (!rt5640->hp_mute)
  1029 + usleep_range(80000, 85000);
  1030 +
  1031 + break;
  1032 +
  1033 + default:
  1034 + return 0;
  1035 + }
  1036 +
  1037 + return 0;
  1038 +}
  1039 +
946 1040 static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
947 1041 SND_SOC_DAPM_SUPPLY("PLL1", RT5640_PWR_ANLG2,
948 1042 RT5640_PWR_PLL_BIT, 0, NULL, 0),
949 1043  
950 1044  
... ... @@ -1132,15 +1226,28 @@
1132 1226 rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)),
1133 1227 SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1,
1134 1228 RT5640_PWR_MA_BIT, 0, NULL, 0),
1135   - SND_SOC_DAPM_SUPPLY("Improve HP Amp Drv", RT5640_PWR_ANLG1,
1136   - SND_SOC_NOPM, 0, NULL, 0),
1137   - SND_SOC_DAPM_PGA("HP L Amp", RT5640_PWR_ANLG1,
  1229 + SND_SOC_DAPM_SUPPLY_S("Improve HP Amp Drv", 1, SND_SOC_NOPM,
  1230 + 0, 0, rt5640_hp_power_event, SND_SOC_DAPM_POST_PMU),
  1231 + SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0,
  1232 + rt5640_hp_event,
  1233 + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
  1234 + SND_SOC_DAPM_SUPPLY("HP L Amp", RT5640_PWR_ANLG1,
1138 1235 RT5640_PWR_HP_L_BIT, 0, NULL, 0),
1139   - SND_SOC_DAPM_PGA("HP R Amp", RT5640_PWR_ANLG1,
  1236 + SND_SOC_DAPM_SUPPLY("HP R Amp", RT5640_PWR_ANLG1,
1140 1237 RT5640_PWR_HP_R_BIT, 0, NULL, 0),
1141 1238 SND_SOC_DAPM_SUPPLY("Improve SPK Amp Drv", RT5640_PWR_DIG1,
1142   - SND_SOC_NOPM, 0, spk_event,
1143   - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
  1239 + RT5640_PWR_CLS_D_BIT, 0, NULL, 0),
  1240 +
  1241 + /* Output Switch */
  1242 + SND_SOC_DAPM_SWITCH("Speaker L Playback", SND_SOC_NOPM, 0, 0,
  1243 + &spk_l_enable_control),
  1244 + SND_SOC_DAPM_SWITCH("Speaker R Playback", SND_SOC_NOPM, 0, 0,
  1245 + &spk_r_enable_control),
  1246 + SND_SOC_DAPM_SWITCH("HP L Playback", SND_SOC_NOPM, 0, 0,
  1247 + &hp_l_enable_control),
  1248 + SND_SOC_DAPM_SWITCH("HP R Playback", SND_SOC_NOPM, 0, 0,
  1249 + &hp_r_enable_control),
  1250 + SND_SOC_DAPM_POST("HP Post", rt5640_hp_post_event),
1144 1251 /* Output Lines */
1145 1252 SND_SOC_DAPM_OUTPUT("SPOLP"),
1146 1253 SND_SOC_DAPM_OUTPUT("SPOLN"),
1147 1254  
... ... @@ -1381,9 +1488,11 @@
1381 1488 {"HPO MIX L", "HPO MIX DAC2 Switch", "DAC L2"},
1382 1489 {"HPO MIX L", "HPO MIX DAC1 Switch", "DAC L1"},
1383 1490 {"HPO MIX L", "HPO MIX HPVOL Switch", "HPOVOL L"},
  1491 + {"HPO MIX L", NULL, "HP L Amp"},
1384 1492 {"HPO MIX R", "HPO MIX DAC2 Switch", "DAC R2"},
1385 1493 {"HPO MIX R", "HPO MIX DAC1 Switch", "DAC R1"},
1386 1494 {"HPO MIX R", "HPO MIX HPVOL Switch", "HPOVOL R"},
  1495 + {"HPO MIX R", NULL, "HP R Amp"},
1387 1496  
1388 1497 {"LOUT MIX", "DAC L1 Switch", "DAC L1"},
1389 1498 {"LOUT MIX", "DAC R1 Switch", "DAC R1"},
1390 1499  
... ... @@ -1396,13 +1505,15 @@
1396 1505 {"Mono MIX", "OUTVOL L Switch", "OUTVOL L"},
1397 1506 {"Mono MIX", "BST1 Switch", "BST1"},
1398 1507  
1399   - {"HP L Amp", NULL, "HPO MIX L"},
1400   - {"HP R Amp", NULL, "HPO MIX R"},
  1508 + {"HP Amp", NULL, "HPO MIX L"},
  1509 + {"HP Amp", NULL, "HPO MIX R"},
1401 1510  
1402   - {"SPOLP", NULL, "SPOL MIX"},
1403   - {"SPOLN", NULL, "SPOL MIX"},
1404   - {"SPORP", NULL, "SPOR MIX"},
1405   - {"SPORN", NULL, "SPOR MIX"},
  1511 + {"Speaker L Playback", "Switch", "SPOL MIX"},
  1512 + {"Speaker R Playback", "Switch", "SPOR MIX"},
  1513 + {"SPOLP", NULL, "Speaker L Playback"},
  1514 + {"SPOLN", NULL, "Speaker L Playback"},
  1515 + {"SPORP", NULL, "Speaker R Playback"},
  1516 + {"SPORN", NULL, "Speaker R Playback"},
1406 1517  
1407 1518 {"SPOLP", NULL, "Improve SPK Amp Drv"},
1408 1519 {"SPOLN", NULL, "Improve SPK Amp Drv"},
... ... @@ -1412,8 +1523,10 @@
1412 1523 {"HPOL", NULL, "Improve HP Amp Drv"},
1413 1524 {"HPOR", NULL, "Improve HP Amp Drv"},
1414 1525  
1415   - {"HPOL", NULL, "HP L Amp"},
1416   - {"HPOR", NULL, "HP R Amp"},
  1526 + {"HP L Playback", "Switch", "HP Amp"},
  1527 + {"HP R Playback", "Switch", "HP Amp"},
  1528 + {"HPOL", NULL, "HP L Playback"},
  1529 + {"HPOR", NULL, "HP R Playback"},
1417 1530 {"LOUTL", NULL, "LOUT MIX"},
1418 1531 {"LOUTR", NULL, "LOUT MIX"},
1419 1532 {"MONOP", NULL, "Mono MIX"},
1420 1533  
... ... @@ -1792,17 +1905,13 @@
1792 1905 RT5640_PWR_BG | RT5640_PWR_VREF2,
1793 1906 RT5640_PWR_VREF1 | RT5640_PWR_MB |
1794 1907 RT5640_PWR_BG | RT5640_PWR_VREF2);
1795   - mdelay(10);
  1908 + usleep_range(10000, 15000);
1796 1909 snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
1797 1910 RT5640_PWR_FV1 | RT5640_PWR_FV2,
1798 1911 RT5640_PWR_FV1 | RT5640_PWR_FV2);
1799 1912 regcache_sync(rt5640->regmap);
1800 1913 snd_soc_update_bits(codec, RT5640_DUMMY1,
1801 1914 0x0301, 0x0301);
1802   - snd_soc_update_bits(codec, RT5640_DEPOP_M1,
1803   - 0x001d, 0x0019);
1804   - snd_soc_update_bits(codec, RT5640_DEPOP_M2,
1805   - 0x2000, 0x2000);
1806 1915 snd_soc_update_bits(codec, RT5640_MICBIAS,
1807 1916 0x0030, 0x0030);
1808 1917 }
... ... @@ -1846,8 +1955,6 @@
1846 1955 rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF);
1847 1956  
1848 1957 snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301);
1849   - snd_soc_update_bits(codec, RT5640_DEPOP_M1, 0x001d, 0x0019);
1850   - snd_soc_update_bits(codec, RT5640_DEPOP_M2, 0x2000, 0x2000);
1851 1958 snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030);
1852 1959 snd_soc_update_bits(codec, RT5640_DSP_PATH2, 0xfc00, 0x0c00);
1853 1960  
... ... @@ -2068,6 +2175,8 @@
2068 2175 if (rt5640->pdata.in2_diff)
2069 2176 regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4,
2070 2177 RT5640_IN_DF2, RT5640_IN_DF2);
  2178 +
  2179 + rt5640->hp_mute = 1;
2071 2180  
2072 2181 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640,
2073 2182 rt5640_dai, ARRAY_SIZE(rt5640_dai));
sound/soc/codecs/rt5640.h
... ... @@ -145,6 +145,8 @@
145 145  
146 146  
147 147 /* Index of Codec Private Register definition */
  148 +#define RT5640_CHPUMP_INT_REG1 0x24
  149 +#define RT5640_MAMP_INT_REG2 0x37
148 150 #define RT5640_3D_SPK 0x63
149 151 #define RT5640_WND_1 0x6c
150 152 #define RT5640_WND_2 0x6d
... ... @@ -153,6 +155,7 @@
153 155 #define RT5640_WND_5 0x70
154 156 #define RT5640_WND_8 0x73
155 157 #define RT5640_DIP_SPK_INF 0x75
  158 +#define RT5640_HP_DCC_INT1 0x77
156 159 #define RT5640_EQ_BW_LOP 0xa0
157 160 #define RT5640_EQ_GN_LOP 0xa1
158 161 #define RT5640_EQ_FC_BP1 0xa2
... ... @@ -1201,6 +1204,14 @@
1201 1204 #define RT5640_CP_FQ2_SFT 4
1202 1205 #define RT5640_CP_FQ3_MASK (0x7)
1203 1206 #define RT5640_CP_FQ3_SFT 0
  1207 +#define RT5640_CP_FQ_1_5_KHZ 0
  1208 +#define RT5640_CP_FQ_3_KHZ 1
  1209 +#define RT5640_CP_FQ_6_KHZ 2
  1210 +#define RT5640_CP_FQ_12_KHZ 3
  1211 +#define RT5640_CP_FQ_24_KHZ 4
  1212 +#define RT5640_CP_FQ_48_KHZ 5
  1213 +#define RT5640_CP_FQ_96_KHZ 6
  1214 +#define RT5640_CP_FQ_192_KHZ 7
1204 1215  
1205 1216 /* HPOUT charge pump (0x91) */
1206 1217 #define RT5640_OSW_L_MASK (0x1 << 11)
... ... @@ -2087,6 +2098,7 @@
2087 2098 int pll_out;
2088 2099  
2089 2100 int dmic_en;
  2101 + bool hp_mute;
2090 2102 };
2091 2103  
2092 2104 #endif