diff options
Diffstat (limited to 'sound/soc/codecs/wm8994.c')
-rw-r--r-- | sound/soc/codecs/wm8994.c | 290 |
1 files changed, 113 insertions, 177 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6c1fe3afd4b5..2f9870aa0cf1 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -70,8 +70,8 @@ static const struct wm8958_micd_rate micdet_rates[] = { | |||
70 | static const struct wm8958_micd_rate jackdet_rates[] = { | 70 | static const struct wm8958_micd_rate jackdet_rates[] = { |
71 | { 32768, true, 0, 1 }, | 71 | { 32768, true, 0, 1 }, |
72 | { 32768, false, 0, 1 }, | 72 | { 32768, false, 0, 1 }, |
73 | { 44100 * 256, true, 7, 10 }, | 73 | { 44100 * 256, true, 10, 10 }, |
74 | { 44100 * 256, false, 7, 10 }, | 74 | { 44100 * 256, false, 7, 8 }, |
75 | }; | 75 | }; |
76 | 76 | ||
77 | static void wm8958_micd_set_rate(struct snd_soc_codec *codec) | 77 | static void wm8958_micd_set_rate(struct snd_soc_codec *codec) |
@@ -82,7 +82,8 @@ static void wm8958_micd_set_rate(struct snd_soc_codec *codec) | |||
82 | const struct wm8958_micd_rate *rates; | 82 | const struct wm8958_micd_rate *rates; |
83 | int num_rates; | 83 | int num_rates; |
84 | 84 | ||
85 | if (wm8994->jack_cb != wm8958_default_micdet) | 85 | if (!(wm8994->pdata && wm8994->pdata->micd_rates) && |
86 | wm8994->jack_cb != wm8958_default_micdet) | ||
86 | return; | 87 | return; |
87 | 88 | ||
88 | idle = !wm8994->jack_mic; | 89 | idle = !wm8994->jack_mic; |
@@ -118,6 +119,10 @@ static void wm8958_micd_set_rate(struct snd_soc_codec *codec) | |||
118 | val = rates[best].start << WM8958_MICD_BIAS_STARTTIME_SHIFT | 119 | val = rates[best].start << WM8958_MICD_BIAS_STARTTIME_SHIFT |
119 | | rates[best].rate << WM8958_MICD_RATE_SHIFT; | 120 | | rates[best].rate << WM8958_MICD_RATE_SHIFT; |
120 | 121 | ||
122 | dev_dbg(codec->dev, "MICD rate %d,%d for %dHz %s\n", | ||
123 | rates[best].start, rates[best].rate, sysclk, | ||
124 | idle ? "idle" : "active"); | ||
125 | |||
121 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | 126 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, |
122 | WM8958_MICD_BIAS_STARTTIME_MASK | | 127 | WM8958_MICD_BIAS_STARTTIME_MASK | |
123 | WM8958_MICD_RATE_MASK, val); | 128 | WM8958_MICD_RATE_MASK, val); |
@@ -398,7 +403,7 @@ static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block) | |||
398 | wm8994->dac_rates[iface]); | 403 | wm8994->dac_rates[iface]); |
399 | 404 | ||
400 | /* The EQ will be disabled while reconfiguring it, remember the | 405 | /* The EQ will be disabled while reconfiguring it, remember the |
401 | * current configuration. | 406 | * current configuration. |
402 | */ | 407 | */ |
403 | save = snd_soc_read(codec, base); | 408 | save = snd_soc_read(codec, base); |
404 | save &= WM8994_AIF1DAC1_EQ_ENA; | 409 | save &= WM8994_AIF1DAC1_EQ_ENA; |
@@ -689,6 +694,9 @@ static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode) | |||
689 | if (!wm8994->jackdet || !wm8994->jack_cb) | 694 | if (!wm8994->jackdet || !wm8994->jack_cb) |
690 | return; | 695 | return; |
691 | 696 | ||
697 | if (!wm8994->jackdet || !wm8994->jack_cb) | ||
698 | return; | ||
699 | |||
692 | if (wm8994->active_refcount) | 700 | if (wm8994->active_refcount) |
693 | mode = WM1811_JACKDET_MODE_AUDIO; | 701 | mode = WM1811_JACKDET_MODE_AUDIO; |
694 | 702 | ||
@@ -784,7 +792,7 @@ static void vmid_reference(struct snd_soc_codec *codec) | |||
784 | 792 | ||
785 | switch (wm8994->vmid_mode) { | 793 | switch (wm8994->vmid_mode) { |
786 | default: | 794 | default: |
787 | WARN_ON(0 == "Invalid VMID mode"); | 795 | WARN_ON(NULL == "Invalid VMID mode"); |
788 | case WM8994_VMID_NORMAL: | 796 | case WM8994_VMID_NORMAL: |
789 | /* Startup bias, VMID ramp & buffer */ | 797 | /* Startup bias, VMID ramp & buffer */ |
790 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | 798 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, |
@@ -937,27 +945,12 @@ static int vmid_event(struct snd_soc_dapm_widget *w, | |||
937 | return 0; | 945 | return 0; |
938 | } | 946 | } |
939 | 947 | ||
940 | static void wm8994_update_class_w(struct snd_soc_codec *codec) | 948 | static bool wm8994_check_class_w_digital(struct snd_soc_codec *codec) |
941 | { | 949 | { |
942 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | ||
943 | int enable = 1; | ||
944 | int source = 0; /* GCC flow analysis can't track enable */ | 950 | int source = 0; /* GCC flow analysis can't track enable */ |
945 | int reg, reg_r; | 951 | int reg, reg_r; |
946 | 952 | ||
947 | /* Only support direct DAC->headphone paths */ | 953 | /* We also need the same AIF source for L/R and only one path */ |
948 | reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_1); | ||
949 | if (!(reg & WM8994_DAC1L_TO_HPOUT1L)) { | ||
950 | dev_vdbg(codec->dev, "HPL connected to output mixer\n"); | ||
951 | enable = 0; | ||
952 | } | ||
953 | |||
954 | reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_2); | ||
955 | if (!(reg & WM8994_DAC1R_TO_HPOUT1R)) { | ||
956 | dev_vdbg(codec->dev, "HPR connected to output mixer\n"); | ||
957 | enable = 0; | ||
958 | } | ||
959 | |||
960 | /* We also need the same setting for L/R and only one path */ | ||
961 | reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING); | 954 | reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING); |
962 | switch (reg) { | 955 | switch (reg) { |
963 | case WM8994_AIF2DACL_TO_DAC1L: | 956 | case WM8994_AIF2DACL_TO_DAC1L: |
@@ -974,30 +967,20 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec) | |||
974 | break; | 967 | break; |
975 | default: | 968 | default: |
976 | dev_vdbg(codec->dev, "DAC mixer setting: %x\n", reg); | 969 | dev_vdbg(codec->dev, "DAC mixer setting: %x\n", reg); |
977 | enable = 0; | 970 | return false; |
978 | break; | ||
979 | } | 971 | } |
980 | 972 | ||
981 | reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING); | 973 | reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING); |
982 | if (reg_r != reg) { | 974 | if (reg_r != reg) { |
983 | dev_vdbg(codec->dev, "Left and right DAC mixers different\n"); | 975 | dev_vdbg(codec->dev, "Left and right DAC mixers different\n"); |
984 | enable = 0; | 976 | return false; |
985 | } | 977 | } |
986 | 978 | ||
987 | if (enable) { | 979 | /* Set the source up */ |
988 | dev_dbg(codec->dev, "Class W enabled\n"); | 980 | snd_soc_update_bits(codec, WM8994_CLASS_W_1, |
989 | snd_soc_update_bits(codec, WM8994_CLASS_W_1, | 981 | WM8994_CP_DYN_SRC_SEL_MASK, source); |
990 | WM8994_CP_DYN_PWR | | 982 | |
991 | WM8994_CP_DYN_SRC_SEL_MASK, | 983 | return true; |
992 | source | WM8994_CP_DYN_PWR); | ||
993 | wm8994->hubs.class_w = true; | ||
994 | |||
995 | } else { | ||
996 | dev_dbg(codec->dev, "Class W disabled\n"); | ||
997 | snd_soc_update_bits(codec, WM8994_CLASS_W_1, | ||
998 | WM8994_CP_DYN_PWR, 0); | ||
999 | wm8994->hubs.class_w = false; | ||
1000 | } | ||
1001 | } | 984 | } |
1002 | 985 | ||
1003 | static int aif1clk_ev(struct snd_soc_dapm_widget *w, | 986 | static int aif1clk_ev(struct snd_soc_dapm_widget *w, |
@@ -1280,45 +1263,6 @@ static int dac_ev(struct snd_soc_dapm_widget *w, | |||
1280 | return 0; | 1263 | return 0; |
1281 | } | 1264 | } |
1282 | 1265 | ||
1283 | static const char *hp_mux_text[] = { | ||
1284 | "Mixer", | ||
1285 | "DAC", | ||
1286 | }; | ||
1287 | |||
1288 | #define WM8994_HP_ENUM(xname, xenum) \ | ||
1289 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
1290 | .info = snd_soc_info_enum_double, \ | ||
1291 | .get = snd_soc_dapm_get_enum_double, \ | ||
1292 | .put = wm8994_put_hp_enum, \ | ||
1293 | .private_value = (unsigned long)&xenum } | ||
1294 | |||
1295 | static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol, | ||
1296 | struct snd_ctl_elem_value *ucontrol) | ||
1297 | { | ||
1298 | struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); | ||
1299 | struct snd_soc_dapm_widget *w = wlist->widgets[0]; | ||
1300 | struct snd_soc_codec *codec = w->codec; | ||
1301 | int ret; | ||
1302 | |||
1303 | ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol); | ||
1304 | |||
1305 | wm8994_update_class_w(codec); | ||
1306 | |||
1307 | return ret; | ||
1308 | } | ||
1309 | |||
1310 | static const struct soc_enum hpl_enum = | ||
1311 | SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_1, 8, 2, hp_mux_text); | ||
1312 | |||
1313 | static const struct snd_kcontrol_new hpl_mux = | ||
1314 | WM8994_HP_ENUM("Left Headphone Mux", hpl_enum); | ||
1315 | |||
1316 | static const struct soc_enum hpr_enum = | ||
1317 | SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_2, 8, 2, hp_mux_text); | ||
1318 | |||
1319 | static const struct snd_kcontrol_new hpr_mux = | ||
1320 | WM8994_HP_ENUM("Right Headphone Mux", hpr_enum); | ||
1321 | |||
1322 | static const char *adc_mux_text[] = { | 1266 | static const char *adc_mux_text[] = { |
1323 | "ADC", | 1267 | "ADC", |
1324 | "DMIC", | 1268 | "DMIC", |
@@ -1430,7 +1374,7 @@ static int wm8994_put_class_w(struct snd_kcontrol *kcontrol, | |||
1430 | 1374 | ||
1431 | ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol); | 1375 | ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol); |
1432 | 1376 | ||
1433 | wm8994_update_class_w(codec); | 1377 | wm_hubs_update_class_w(codec); |
1434 | 1378 | ||
1435 | return ret; | 1379 | return ret; |
1436 | } | 1380 | } |
@@ -1524,7 +1468,7 @@ static const struct snd_kcontrol_new wm8958_aif3adc_mux = | |||
1524 | SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum); | 1468 | SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum); |
1525 | 1469 | ||
1526 | static const char *mono_pcm_out_text[] = { | 1470 | static const char *mono_pcm_out_text[] = { |
1527 | "None", "AIF2ADCL", "AIF2ADCR", | 1471 | "None", "AIF2ADCL", "AIF2ADCR", |
1528 | }; | 1472 | }; |
1529 | 1473 | ||
1530 | static const struct soc_enum mono_pcm_out_enum = | 1474 | static const struct soc_enum mono_pcm_out_enum = |
@@ -1573,9 +1517,9 @@ SND_SOC_DAPM_MIXER_E("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0, | |||
1573 | SND_SOC_DAPM_MIXER_E("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0, | 1517 | SND_SOC_DAPM_MIXER_E("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0, |
1574 | right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer), | 1518 | right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer), |
1575 | late_enable_ev, SND_SOC_DAPM_PRE_PMU), | 1519 | late_enable_ev, SND_SOC_DAPM_PRE_PMU), |
1576 | SND_SOC_DAPM_MUX_E("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux, | 1520 | SND_SOC_DAPM_MUX_E("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &wm_hubs_hpl_mux, |
1577 | late_enable_ev, SND_SOC_DAPM_PRE_PMU), | 1521 | late_enable_ev, SND_SOC_DAPM_PRE_PMU), |
1578 | SND_SOC_DAPM_MUX_E("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux, | 1522 | SND_SOC_DAPM_MUX_E("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &wm_hubs_hpr_mux, |
1579 | late_enable_ev, SND_SOC_DAPM_PRE_PMU), | 1523 | late_enable_ev, SND_SOC_DAPM_PRE_PMU), |
1580 | 1524 | ||
1581 | SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev) | 1525 | SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev) |
@@ -1591,8 +1535,8 @@ SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0, | |||
1591 | left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)), | 1535 | left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)), |
1592 | SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0, | 1536 | SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0, |
1593 | right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)), | 1537 | right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)), |
1594 | SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux), | 1538 | SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &wm_hubs_hpl_mux), |
1595 | SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux), | 1539 | SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &wm_hubs_hpr_mux), |
1596 | }; | 1540 | }; |
1597 | 1541 | ||
1598 | static const struct snd_soc_dapm_widget wm8994_dac_revd_widgets[] = { | 1542 | static const struct snd_soc_dapm_widget wm8994_dac_revd_widgets[] = { |
@@ -1732,6 +1676,7 @@ SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8994_aif3adc_mux), | |||
1732 | }; | 1676 | }; |
1733 | 1677 | ||
1734 | static const struct snd_soc_dapm_widget wm8958_dapm_widgets[] = { | 1678 | static const struct snd_soc_dapm_widget wm8958_dapm_widgets[] = { |
1679 | SND_SOC_DAPM_SUPPLY("AIF3", WM8994_POWER_MANAGEMENT_6, 5, 1, NULL, 0), | ||
1735 | SND_SOC_DAPM_MUX("Mono PCM Out Mux", SND_SOC_NOPM, 0, 0, &mono_pcm_out_mux), | 1680 | SND_SOC_DAPM_MUX("Mono PCM Out Mux", SND_SOC_NOPM, 0, 0, &mono_pcm_out_mux), |
1736 | SND_SOC_DAPM_MUX("AIF2DACL Mux", SND_SOC_NOPM, 0, 0, &aif2dacl_src_mux), | 1681 | SND_SOC_DAPM_MUX("AIF2DACL Mux", SND_SOC_NOPM, 0, 0, &aif2dacl_src_mux), |
1737 | SND_SOC_DAPM_MUX("AIF2DACR Mux", SND_SOC_NOPM, 0, 0, &aif2dacr_src_mux), | 1682 | SND_SOC_DAPM_MUX("AIF2DACR Mux", SND_SOC_NOPM, 0, 0, &aif2dacr_src_mux), |
@@ -1972,6 +1917,9 @@ static const struct snd_soc_dapm_route wm8958_intercon[] = { | |||
1972 | { "AIF2DACR Mux", "AIF2", "AIF2DAC Mux" }, | 1917 | { "AIF2DACR Mux", "AIF2", "AIF2DAC Mux" }, |
1973 | { "AIF2DACR Mux", "AIF3", "AIF3DACDAT" }, | 1918 | { "AIF2DACR Mux", "AIF3", "AIF3DACDAT" }, |
1974 | 1919 | ||
1920 | { "AIF3DACDAT", NULL, "AIF3" }, | ||
1921 | { "AIF3ADCDAT", NULL, "AIF3" }, | ||
1922 | |||
1975 | { "Mono PCM Out Mux", "AIF2ADCL", "AIF2ADCL" }, | 1923 | { "Mono PCM Out Mux", "AIF2ADCL", "AIF2ADCL" }, |
1976 | { "Mono PCM Out Mux", "AIF2ADCR", "AIF2ADCR" }, | 1924 | { "Mono PCM Out Mux", "AIF2ADCR", "AIF2ADCR" }, |
1977 | 1925 | ||
@@ -2068,24 +2016,20 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
2068 | struct wm8994 *control = wm8994->wm8994; | 2016 | struct wm8994 *control = wm8994->wm8994; |
2069 | int reg_offset, ret; | 2017 | int reg_offset, ret; |
2070 | struct fll_div fll; | 2018 | struct fll_div fll; |
2071 | u16 reg, aif1, aif2; | 2019 | u16 reg, clk1, aif_reg, aif_src; |
2072 | unsigned long timeout; | 2020 | unsigned long timeout; |
2073 | bool was_enabled; | 2021 | bool was_enabled; |
2074 | 2022 | ||
2075 | aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1) | ||
2076 | & WM8994_AIF1CLK_ENA; | ||
2077 | |||
2078 | aif2 = snd_soc_read(codec, WM8994_AIF2_CLOCKING_1) | ||
2079 | & WM8994_AIF2CLK_ENA; | ||
2080 | |||
2081 | switch (id) { | 2023 | switch (id) { |
2082 | case WM8994_FLL1: | 2024 | case WM8994_FLL1: |
2083 | reg_offset = 0; | 2025 | reg_offset = 0; |
2084 | id = 0; | 2026 | id = 0; |
2027 | aif_src = 0x10; | ||
2085 | break; | 2028 | break; |
2086 | case WM8994_FLL2: | 2029 | case WM8994_FLL2: |
2087 | reg_offset = 0x20; | 2030 | reg_offset = 0x20; |
2088 | id = 1; | 2031 | id = 1; |
2032 | aif_src = 0x18; | ||
2089 | break; | 2033 | break; |
2090 | default: | 2034 | default: |
2091 | return -EINVAL; | 2035 | return -EINVAL; |
@@ -2127,16 +2071,33 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
2127 | if (ret < 0) | 2071 | if (ret < 0) |
2128 | return ret; | 2072 | return ret; |
2129 | 2073 | ||
2130 | /* Gate the AIF clocks while we reclock */ | 2074 | /* Make sure that we're not providing SYSCLK right now */ |
2131 | snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, | 2075 | clk1 = snd_soc_read(codec, WM8994_CLOCKING_1); |
2132 | WM8994_AIF1CLK_ENA, 0); | 2076 | if (clk1 & WM8994_SYSCLK_SRC) |
2133 | snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, | 2077 | aif_reg = WM8994_AIF2_CLOCKING_1; |
2134 | WM8994_AIF2CLK_ENA, 0); | 2078 | else |
2079 | aif_reg = WM8994_AIF1_CLOCKING_1; | ||
2080 | reg = snd_soc_read(codec, aif_reg); | ||
2081 | |||
2082 | if ((reg & WM8994_AIF1CLK_ENA) && | ||
2083 | (reg & WM8994_AIF1CLK_SRC_MASK) == aif_src) { | ||
2084 | dev_err(codec->dev, "FLL%d is currently providing SYSCLK\n", | ||
2085 | id + 1); | ||
2086 | return -EBUSY; | ||
2087 | } | ||
2135 | 2088 | ||
2136 | /* We always need to disable the FLL while reconfiguring */ | 2089 | /* We always need to disable the FLL while reconfiguring */ |
2137 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset, | 2090 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset, |
2138 | WM8994_FLL1_ENA, 0); | 2091 | WM8994_FLL1_ENA, 0); |
2139 | 2092 | ||
2093 | if (wm8994->fll_byp && src == WM8994_FLL_SRC_BCLK && | ||
2094 | freq_in == freq_out && freq_out) { | ||
2095 | dev_dbg(codec->dev, "Bypassing FLL%d\n", id + 1); | ||
2096 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset, | ||
2097 | WM8958_FLL1_BYP, WM8958_FLL1_BYP); | ||
2098 | goto out; | ||
2099 | } | ||
2100 | |||
2140 | reg = (fll.outdiv << WM8994_FLL1_OUTDIV_SHIFT) | | 2101 | reg = (fll.outdiv << WM8994_FLL1_OUTDIV_SHIFT) | |
2141 | (fll.fll_fratio << WM8994_FLL1_FRATIO_SHIFT); | 2102 | (fll.fll_fratio << WM8994_FLL1_FRATIO_SHIFT); |
2142 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_2 + reg_offset, | 2103 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_2 + reg_offset, |
@@ -2151,6 +2112,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
2151 | fll.n << WM8994_FLL1_N_SHIFT); | 2112 | fll.n << WM8994_FLL1_N_SHIFT); |
2152 | 2113 | ||
2153 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset, | 2114 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset, |
2115 | WM8958_FLL1_BYP | | ||
2154 | WM8994_FLL1_REFCLK_DIV_MASK | | 2116 | WM8994_FLL1_REFCLK_DIV_MASK | |
2155 | WM8994_FLL1_REFCLK_SRC_MASK, | 2117 | WM8994_FLL1_REFCLK_SRC_MASK, |
2156 | (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) | | 2118 | (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) | |
@@ -2213,16 +2175,11 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
2213 | } | 2175 | } |
2214 | } | 2176 | } |
2215 | 2177 | ||
2178 | out: | ||
2216 | wm8994->fll[id].in = freq_in; | 2179 | wm8994->fll[id].in = freq_in; |
2217 | wm8994->fll[id].out = freq_out; | 2180 | wm8994->fll[id].out = freq_out; |
2218 | wm8994->fll[id].src = src; | 2181 | wm8994->fll[id].src = src; |
2219 | 2182 | ||
2220 | /* Enable any gated AIF clocks */ | ||
2221 | snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, | ||
2222 | WM8994_AIF1CLK_ENA, aif1); | ||
2223 | snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, | ||
2224 | WM8994_AIF2CLK_ENA, aif2); | ||
2225 | |||
2226 | configure_clock(codec); | 2183 | configure_clock(codec); |
2227 | 2184 | ||
2228 | return 0; | 2185 | return 0; |
@@ -2290,7 +2247,7 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, | |||
2290 | 2247 | ||
2291 | case WM8994_SYSCLK_OPCLK: | 2248 | case WM8994_SYSCLK_OPCLK: |
2292 | /* Special case - a division (times 10) is given and | 2249 | /* Special case - a division (times 10) is given and |
2293 | * no effect on main clocking. | 2250 | * no effect on main clocking. |
2294 | */ | 2251 | */ |
2295 | if (freq) { | 2252 | if (freq) { |
2296 | for (i = 0; i < ARRAY_SIZE(opclk_divs); i++) | 2253 | for (i = 0; i < ARRAY_SIZE(opclk_divs); i++) |
@@ -2792,33 +2749,6 @@ static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream, | |||
2792 | return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1); | 2749 | return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1); |
2793 | } | 2750 | } |
2794 | 2751 | ||
2795 | static void wm8994_aif_shutdown(struct snd_pcm_substream *substream, | ||
2796 | struct snd_soc_dai *dai) | ||
2797 | { | ||
2798 | struct snd_soc_codec *codec = dai->codec; | ||
2799 | int rate_reg = 0; | ||
2800 | |||
2801 | switch (dai->id) { | ||
2802 | case 1: | ||
2803 | rate_reg = WM8994_AIF1_RATE; | ||
2804 | break; | ||
2805 | case 2: | ||
2806 | rate_reg = WM8994_AIF2_RATE; | ||
2807 | break; | ||
2808 | default: | ||
2809 | break; | ||
2810 | } | ||
2811 | |||
2812 | /* If the DAI is idle then configure the divider tree for the | ||
2813 | * lowest output rate to save a little power if the clock is | ||
2814 | * still active (eg, because it is system clock). | ||
2815 | */ | ||
2816 | if (rate_reg && !dai->playback_active && !dai->capture_active) | ||
2817 | snd_soc_update_bits(codec, rate_reg, | ||
2818 | WM8994_AIF1_SR_MASK | | ||
2819 | WM8994_AIF1CLK_RATE_MASK, 0x9); | ||
2820 | } | ||
2821 | |||
2822 | static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute) | 2752 | static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute) |
2823 | { | 2753 | { |
2824 | struct snd_soc_codec *codec = codec_dai->codec; | 2754 | struct snd_soc_codec *codec = codec_dai->codec; |
@@ -2860,10 +2790,6 @@ static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate) | |||
2860 | reg = WM8994_AIF2_MASTER_SLAVE; | 2790 | reg = WM8994_AIF2_MASTER_SLAVE; |
2861 | mask = WM8994_AIF2_TRI; | 2791 | mask = WM8994_AIF2_TRI; |
2862 | break; | 2792 | break; |
2863 | case 3: | ||
2864 | reg = WM8994_POWER_MANAGEMENT_6; | ||
2865 | mask = WM8994_AIF3_TRI; | ||
2866 | break; | ||
2867 | default: | 2793 | default: |
2868 | return -EINVAL; | 2794 | return -EINVAL; |
2869 | } | 2795 | } |
@@ -2900,7 +2826,6 @@ static const struct snd_soc_dai_ops wm8994_aif1_dai_ops = { | |||
2900 | .set_sysclk = wm8994_set_dai_sysclk, | 2826 | .set_sysclk = wm8994_set_dai_sysclk, |
2901 | .set_fmt = wm8994_set_dai_fmt, | 2827 | .set_fmt = wm8994_set_dai_fmt, |
2902 | .hw_params = wm8994_hw_params, | 2828 | .hw_params = wm8994_hw_params, |
2903 | .shutdown = wm8994_aif_shutdown, | ||
2904 | .digital_mute = wm8994_aif_mute, | 2829 | .digital_mute = wm8994_aif_mute, |
2905 | .set_pll = wm8994_set_fll, | 2830 | .set_pll = wm8994_set_fll, |
2906 | .set_tristate = wm8994_set_tristate, | 2831 | .set_tristate = wm8994_set_tristate, |
@@ -2910,7 +2835,6 @@ static const struct snd_soc_dai_ops wm8994_aif2_dai_ops = { | |||
2910 | .set_sysclk = wm8994_set_dai_sysclk, | 2835 | .set_sysclk = wm8994_set_dai_sysclk, |
2911 | .set_fmt = wm8994_set_dai_fmt, | 2836 | .set_fmt = wm8994_set_dai_fmt, |
2912 | .hw_params = wm8994_hw_params, | 2837 | .hw_params = wm8994_hw_params, |
2913 | .shutdown = wm8994_aif_shutdown, | ||
2914 | .digital_mute = wm8994_aif_mute, | 2838 | .digital_mute = wm8994_aif_mute, |
2915 | .set_pll = wm8994_set_fll, | 2839 | .set_pll = wm8994_set_fll, |
2916 | .set_tristate = wm8994_set_tristate, | 2840 | .set_tristate = wm8994_set_tristate, |
@@ -2918,7 +2842,6 @@ static const struct snd_soc_dai_ops wm8994_aif2_dai_ops = { | |||
2918 | 2842 | ||
2919 | static const struct snd_soc_dai_ops wm8994_aif3_dai_ops = { | 2843 | static const struct snd_soc_dai_ops wm8994_aif3_dai_ops = { |
2920 | .hw_params = wm8994_aif3_hw_params, | 2844 | .hw_params = wm8994_aif3_hw_params, |
2921 | .set_tristate = wm8994_set_tristate, | ||
2922 | }; | 2845 | }; |
2923 | 2846 | ||
2924 | static struct snd_soc_dai_driver wm8994_dai[] = { | 2847 | static struct snd_soc_dai_driver wm8994_dai[] = { |
@@ -3126,14 +3049,14 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) | |||
3126 | 3049 | ||
3127 | /* Expand the array... */ | 3050 | /* Expand the array... */ |
3128 | t = krealloc(wm8994->retune_mobile_texts, | 3051 | t = krealloc(wm8994->retune_mobile_texts, |
3129 | sizeof(char *) * | 3052 | sizeof(char *) * |
3130 | (wm8994->num_retune_mobile_texts + 1), | 3053 | (wm8994->num_retune_mobile_texts + 1), |
3131 | GFP_KERNEL); | 3054 | GFP_KERNEL); |
3132 | if (t == NULL) | 3055 | if (t == NULL) |
3133 | continue; | 3056 | continue; |
3134 | 3057 | ||
3135 | /* ...store the new entry... */ | 3058 | /* ...store the new entry... */ |
3136 | t[wm8994->num_retune_mobile_texts] = | 3059 | t[wm8994->num_retune_mobile_texts] = |
3137 | pdata->retune_mobile_cfgs[i].name; | 3060 | pdata->retune_mobile_cfgs[i].name; |
3138 | 3061 | ||
3139 | /* ...and remember the new version. */ | 3062 | /* ...and remember the new version. */ |
@@ -3304,25 +3227,25 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
3304 | } | 3227 | } |
3305 | EXPORT_SYMBOL_GPL(wm8994_mic_detect); | 3228 | EXPORT_SYMBOL_GPL(wm8994_mic_detect); |
3306 | 3229 | ||
3307 | static irqreturn_t wm8994_mic_irq(int irq, void *data) | 3230 | static void wm8994_mic_work(struct work_struct *work) |
3308 | { | 3231 | { |
3309 | struct wm8994_priv *priv = data; | 3232 | struct wm8994_priv *priv = container_of(work, |
3310 | struct snd_soc_codec *codec = priv->codec; | 3233 | struct wm8994_priv, |
3311 | int reg; | 3234 | mic_work.work); |
3235 | struct regmap *regmap = priv->wm8994->regmap; | ||
3236 | struct device *dev = priv->wm8994->dev; | ||
3237 | unsigned int reg; | ||
3238 | int ret; | ||
3312 | int report; | 3239 | int report; |
3313 | 3240 | ||
3314 | #ifndef CONFIG_SND_SOC_WM8994_MODULE | 3241 | ret = regmap_read(regmap, WM8994_INTERRUPT_RAW_STATUS_2, ®); |
3315 | trace_snd_soc_jack_irq(dev_name(codec->dev)); | 3242 | if (ret < 0) { |
3316 | #endif | 3243 | dev_err(dev, "Failed to read microphone status: %d\n", |
3317 | 3244 | ret); | |
3318 | reg = snd_soc_read(codec, WM8994_INTERRUPT_RAW_STATUS_2); | 3245 | return; |
3319 | if (reg < 0) { | ||
3320 | dev_err(codec->dev, "Failed to read microphone status: %d\n", | ||
3321 | reg); | ||
3322 | return IRQ_HANDLED; | ||
3323 | } | 3246 | } |
3324 | 3247 | ||
3325 | dev_dbg(codec->dev, "Microphone status: %x\n", reg); | 3248 | dev_dbg(dev, "Microphone status: %x\n", reg); |
3326 | 3249 | ||
3327 | report = 0; | 3250 | report = 0; |
3328 | if (reg & WM8994_MIC1_DET_STS) { | 3251 | if (reg & WM8994_MIC1_DET_STS) { |
@@ -3361,6 +3284,20 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data) | |||
3361 | 3284 | ||
3362 | snd_soc_jack_report(priv->micdet[1].jack, report, | 3285 | snd_soc_jack_report(priv->micdet[1].jack, report, |
3363 | SND_JACK_HEADSET | SND_JACK_BTN_0); | 3286 | SND_JACK_HEADSET | SND_JACK_BTN_0); |
3287 | } | ||
3288 | |||
3289 | static irqreturn_t wm8994_mic_irq(int irq, void *data) | ||
3290 | { | ||
3291 | struct wm8994_priv *priv = data; | ||
3292 | struct snd_soc_codec *codec = priv->codec; | ||
3293 | |||
3294 | #ifndef CONFIG_SND_SOC_WM8994_MODULE | ||
3295 | trace_snd_soc_jack_irq(dev_name(codec->dev)); | ||
3296 | #endif | ||
3297 | |||
3298 | pm_wakeup_event(codec->dev, 300); | ||
3299 | |||
3300 | schedule_delayed_work(&priv->mic_work, msecs_to_jiffies(250)); | ||
3364 | 3301 | ||
3365 | return IRQ_HANDLED; | 3302 | return IRQ_HANDLED; |
3366 | } | 3303 | } |
@@ -3415,9 +3352,6 @@ static void wm8958_default_micdet(u16 status, void *data) | |||
3415 | 3352 | ||
3416 | wm8958_micd_set_rate(codec); | 3353 | wm8958_micd_set_rate(codec); |
3417 | 3354 | ||
3418 | snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE, | ||
3419 | SND_JACK_HEADSET); | ||
3420 | |||
3421 | /* If we have jackdet that will detect removal */ | 3355 | /* If we have jackdet that will detect removal */ |
3422 | if (wm8994->jackdet) { | 3356 | if (wm8994->jackdet) { |
3423 | mutex_lock(&wm8994->accdet_lock); | 3357 | mutex_lock(&wm8994->accdet_lock); |
@@ -3430,14 +3364,13 @@ static void wm8958_default_micdet(u16 status, void *data) | |||
3430 | 3364 | ||
3431 | mutex_unlock(&wm8994->accdet_lock); | 3365 | mutex_unlock(&wm8994->accdet_lock); |
3432 | 3366 | ||
3433 | if (wm8994->pdata->jd_ext_cap) { | 3367 | if (wm8994->pdata->jd_ext_cap) |
3434 | mutex_lock(&codec->mutex); | ||
3435 | snd_soc_dapm_disable_pin(&codec->dapm, | 3368 | snd_soc_dapm_disable_pin(&codec->dapm, |
3436 | "MICBIAS2"); | 3369 | "MICBIAS2"); |
3437 | snd_soc_dapm_sync(&codec->dapm); | ||
3438 | mutex_unlock(&codec->mutex); | ||
3439 | } | ||
3440 | } | 3370 | } |
3371 | |||
3372 | snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE, | ||
3373 | SND_JACK_HEADSET); | ||
3441 | } | 3374 | } |
3442 | 3375 | ||
3443 | /* Report short circuit as a button */ | 3376 | /* Report short circuit as a button */ |
@@ -3489,6 +3422,8 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3489 | if (present) { | 3422 | if (present) { |
3490 | dev_dbg(codec->dev, "Jack detected\n"); | 3423 | dev_dbg(codec->dev, "Jack detected\n"); |
3491 | 3424 | ||
3425 | wm8958_micd_set_rate(codec); | ||
3426 | |||
3492 | snd_soc_update_bits(codec, WM8958_MICBIAS2, | 3427 | snd_soc_update_bits(codec, WM8958_MICBIAS2, |
3493 | WM8958_MICB2_DISCH, 0); | 3428 | WM8958_MICB2_DISCH, 0); |
3494 | 3429 | ||
@@ -3526,16 +3461,11 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3526 | 3461 | ||
3527 | /* If required for an external cap force MICBIAS on */ | 3462 | /* If required for an external cap force MICBIAS on */ |
3528 | if (wm8994->pdata->jd_ext_cap) { | 3463 | if (wm8994->pdata->jd_ext_cap) { |
3529 | mutex_lock(&codec->mutex); | ||
3530 | |||
3531 | if (present) | 3464 | if (present) |
3532 | snd_soc_dapm_force_enable_pin(&codec->dapm, | 3465 | snd_soc_dapm_force_enable_pin(&codec->dapm, |
3533 | "MICBIAS2"); | 3466 | "MICBIAS2"); |
3534 | else | 3467 | else |
3535 | snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); | 3468 | snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); |
3536 | |||
3537 | snd_soc_dapm_sync(&codec->dapm); | ||
3538 | mutex_unlock(&codec->mutex); | ||
3539 | } | 3469 | } |
3540 | 3470 | ||
3541 | if (present) | 3471 | if (present) |
@@ -3740,6 +3670,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3740 | wm8994->codec = codec; | 3670 | wm8994->codec = codec; |
3741 | 3671 | ||
3742 | mutex_init(&wm8994->accdet_lock); | 3672 | mutex_init(&wm8994->accdet_lock); |
3673 | INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work); | ||
3743 | 3674 | ||
3744 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) | 3675 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) |
3745 | init_completion(&wm8994->fll_locked[i]); | 3676 | init_completion(&wm8994->fll_locked[i]); |
@@ -3783,13 +3714,22 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3783 | case WM8958: | 3714 | case WM8958: |
3784 | wm8994->hubs.dcs_readback_mode = 1; | 3715 | wm8994->hubs.dcs_readback_mode = 1; |
3785 | wm8994->hubs.hp_startup_mode = 1; | 3716 | wm8994->hubs.hp_startup_mode = 1; |
3717 | |||
3718 | switch (wm8994->revision) { | ||
3719 | case 0: | ||
3720 | break; | ||
3721 | default: | ||
3722 | wm8994->fll_byp = true; | ||
3723 | break; | ||
3724 | } | ||
3786 | break; | 3725 | break; |
3787 | 3726 | ||
3788 | case WM1811: | 3727 | case WM1811: |
3789 | wm8994->hubs.dcs_readback_mode = 2; | 3728 | wm8994->hubs.dcs_readback_mode = 2; |
3790 | wm8994->hubs.no_series_update = 1; | 3729 | wm8994->hubs.no_series_update = 1; |
3791 | wm8994->hubs.hp_startup_mode = 1; | 3730 | wm8994->hubs.hp_startup_mode = 1; |
3792 | wm8994->hubs.no_cache_class_w = true; | 3731 | wm8994->hubs.no_cache_dac_hp_direct = true; |
3732 | wm8994->fll_byp = true; | ||
3793 | 3733 | ||
3794 | switch (wm8994->revision) { | 3734 | switch (wm8994->revision) { |
3795 | case 0: | 3735 | case 0: |
@@ -4010,7 +3950,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
4010 | break; | 3950 | break; |
4011 | } | 3951 | } |
4012 | 3952 | ||
4013 | wm8994_update_class_w(codec); | 3953 | wm8994->hubs.check_class_w_digital = wm8994_check_class_w_digital; |
3954 | wm_hubs_update_class_w(codec); | ||
4014 | 3955 | ||
4015 | wm8994_handle_pdata(wm8994); | 3956 | wm8994_handle_pdata(wm8994); |
4016 | 3957 | ||
@@ -4075,7 +4016,6 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
4075 | ARRAY_SIZE(wm8994_dac_widgets)); | 4016 | ARRAY_SIZE(wm8994_dac_widgets)); |
4076 | break; | 4017 | break; |
4077 | } | 4018 | } |
4078 | |||
4079 | 4019 | ||
4080 | wm_hubs_add_analogue_routes(codec, 0, 0); | 4020 | wm_hubs_add_analogue_routes(codec, 0, 0); |
4081 | snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); | 4021 | snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); |
@@ -4140,7 +4080,7 @@ err_irq: | |||
4140 | return ret; | 4080 | return ret; |
4141 | } | 4081 | } |
4142 | 4082 | ||
4143 | static int wm8994_codec_remove(struct snd_soc_codec *codec) | 4083 | static int wm8994_codec_remove(struct snd_soc_codec *codec) |
4144 | { | 4084 | { |
4145 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 4085 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
4146 | struct wm8994 *control = wm8994->wm8994; | 4086 | struct wm8994 *control = wm8994->wm8994; |
@@ -4181,14 +4121,10 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) | |||
4181 | free_irq(wm8994->micdet_irq, wm8994); | 4121 | free_irq(wm8994->micdet_irq, wm8994); |
4182 | break; | 4122 | break; |
4183 | } | 4123 | } |
4184 | if (wm8994->mbc) | 4124 | release_firmware(wm8994->mbc); |
4185 | release_firmware(wm8994->mbc); | 4125 | release_firmware(wm8994->mbc_vss); |
4186 | if (wm8994->mbc_vss) | 4126 | release_firmware(wm8994->enh_eq); |
4187 | release_firmware(wm8994->mbc_vss); | ||
4188 | if (wm8994->enh_eq) | ||
4189 | release_firmware(wm8994->enh_eq); | ||
4190 | kfree(wm8994->retune_mobile_texts); | 4127 | kfree(wm8994->retune_mobile_texts); |
4191 | |||
4192 | return 0; | 4128 | return 0; |
4193 | } | 4129 | } |
4194 | 4130 | ||