diff options
Diffstat (limited to 'sound/soc/codecs/wm8994.c')
-rw-r--r-- | sound/soc/codecs/wm8994.c | 671 |
1 files changed, 463 insertions, 208 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6c298854900..93d27b66025 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -38,6 +38,11 @@ | |||
38 | #include "wm8994.h" | 38 | #include "wm8994.h" |
39 | #include "wm_hubs.h" | 39 | #include "wm_hubs.h" |
40 | 40 | ||
41 | #define WM1811_JACKDET_MODE_NONE 0x0000 | ||
42 | #define WM1811_JACKDET_MODE_JACK 0x0100 | ||
43 | #define WM1811_JACKDET_MODE_MIC 0x0080 | ||
44 | #define WM1811_JACKDET_MODE_AUDIO 0x0180 | ||
45 | |||
41 | #define WM8994_NUM_DRC 3 | 46 | #define WM8994_NUM_DRC 3 |
42 | #define WM8994_NUM_EQ 3 | 47 | #define WM8994_NUM_EQ 3 |
43 | 48 | ||
@@ -53,103 +58,69 @@ static int wm8994_retune_mobile_base[] = { | |||
53 | WM8994_AIF2_EQ_GAINS_1, | 58 | WM8994_AIF2_EQ_GAINS_1, |
54 | }; | 59 | }; |
55 | 60 | ||
56 | static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) | 61 | static void wm8958_default_micdet(u16 status, void *data); |
57 | { | ||
58 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | ||
59 | struct wm8994 *control = codec->control_data; | ||
60 | |||
61 | switch (reg) { | ||
62 | case WM8994_GPIO_1: | ||
63 | case WM8994_GPIO_2: | ||
64 | case WM8994_GPIO_3: | ||
65 | case WM8994_GPIO_4: | ||
66 | case WM8994_GPIO_5: | ||
67 | case WM8994_GPIO_6: | ||
68 | case WM8994_GPIO_7: | ||
69 | case WM8994_GPIO_8: | ||
70 | case WM8994_GPIO_9: | ||
71 | case WM8994_GPIO_10: | ||
72 | case WM8994_GPIO_11: | ||
73 | case WM8994_INTERRUPT_STATUS_1: | ||
74 | case WM8994_INTERRUPT_STATUS_2: | ||
75 | case WM8994_INTERRUPT_RAW_STATUS_2: | ||
76 | return 1; | ||
77 | |||
78 | case WM8958_DSP2_PROGRAM: | ||
79 | case WM8958_DSP2_CONFIG: | ||
80 | case WM8958_DSP2_EXECCONTROL: | ||
81 | if (control->type == WM8958) | ||
82 | return 1; | ||
83 | else | ||
84 | return 0; | ||
85 | 62 | ||
86 | default: | 63 | static const struct wm8958_micd_rate micdet_rates[] = { |
87 | break; | 64 | { 32768, true, 1, 4 }, |
88 | } | 65 | { 32768, false, 1, 1 }, |
66 | { 44100 * 256, true, 7, 10 }, | ||
67 | { 44100 * 256, false, 7, 10 }, | ||
68 | }; | ||
89 | 69 | ||
90 | if (reg >= WM8994_CACHE_SIZE) | 70 | static const struct wm8958_micd_rate jackdet_rates[] = { |
91 | return 0; | 71 | { 32768, true, 0, 1 }, |
92 | return wm8994_access_masks[reg].readable != 0; | 72 | { 32768, false, 0, 1 }, |
93 | } | 73 | { 44100 * 256, true, 7, 10 }, |
74 | { 44100 * 256, false, 7, 10 }, | ||
75 | }; | ||
94 | 76 | ||
95 | static int wm8994_volatile(struct snd_soc_codec *codec, unsigned int reg) | 77 | static void wm8958_micd_set_rate(struct snd_soc_codec *codec) |
96 | { | 78 | { |
97 | if (reg >= WM8994_CACHE_SIZE) | 79 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
98 | return 1; | 80 | int best, i, sysclk, val; |
99 | 81 | bool idle; | |
100 | switch (reg) { | 82 | const struct wm8958_micd_rate *rates; |
101 | case WM8994_SOFTWARE_RESET: | 83 | int num_rates; |
102 | case WM8994_CHIP_REVISION: | ||
103 | case WM8994_DC_SERVO_1: | ||
104 | case WM8994_DC_SERVO_READBACK: | ||
105 | case WM8994_RATE_STATUS: | ||
106 | case WM8994_LDO_1: | ||
107 | case WM8994_LDO_2: | ||
108 | case WM8958_DSP2_EXECCONTROL: | ||
109 | case WM8958_MIC_DETECT_3: | ||
110 | case WM8994_DC_SERVO_4E: | ||
111 | return 1; | ||
112 | default: | ||
113 | return 0; | ||
114 | } | ||
115 | } | ||
116 | 84 | ||
117 | static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg, | 85 | if (wm8994->jack_cb != wm8958_default_micdet) |
118 | unsigned int value) | 86 | return; |
119 | { | ||
120 | int ret; | ||
121 | 87 | ||
122 | BUG_ON(reg > WM8994_MAX_REGISTER); | 88 | idle = !wm8994->jack_mic; |
123 | 89 | ||
124 | if (!wm8994_volatile(codec, reg)) { | 90 | sysclk = snd_soc_read(codec, WM8994_CLOCKING_1); |
125 | ret = snd_soc_cache_write(codec, reg, value); | 91 | if (sysclk & WM8994_SYSCLK_SRC) |
126 | if (ret != 0) | 92 | sysclk = wm8994->aifclk[1]; |
127 | dev_err(codec->dev, "Cache write to %x failed: %d\n", | 93 | else |
128 | reg, ret); | 94 | sysclk = wm8994->aifclk[0]; |
95 | |||
96 | if (wm8994->pdata && wm8994->pdata->micd_rates) { | ||
97 | rates = wm8994->pdata->micd_rates; | ||
98 | num_rates = wm8994->pdata->num_micd_rates; | ||
99 | } else if (wm8994->jackdet) { | ||
100 | rates = jackdet_rates; | ||
101 | num_rates = ARRAY_SIZE(jackdet_rates); | ||
102 | } else { | ||
103 | rates = micdet_rates; | ||
104 | num_rates = ARRAY_SIZE(micdet_rates); | ||
129 | } | 105 | } |
130 | 106 | ||
131 | return wm8994_reg_write(codec->control_data, reg, value); | 107 | best = 0; |
132 | } | 108 | for (i = 0; i < num_rates; i++) { |
133 | 109 | if (rates[i].idle != idle) | |
134 | static unsigned int wm8994_read(struct snd_soc_codec *codec, | 110 | continue; |
135 | unsigned int reg) | 111 | if (abs(rates[i].sysclk - sysclk) < |
136 | { | 112 | abs(rates[best].sysclk - sysclk)) |
137 | unsigned int val; | 113 | best = i; |
138 | int ret; | 114 | else if (rates[best].idle != idle) |
139 | 115 | best = i; | |
140 | BUG_ON(reg > WM8994_MAX_REGISTER); | ||
141 | |||
142 | if (!wm8994_volatile(codec, reg) && wm8994_readable(codec, reg) && | ||
143 | reg < codec->driver->reg_cache_size) { | ||
144 | ret = snd_soc_cache_read(codec, reg, &val); | ||
145 | if (ret >= 0) | ||
146 | return val; | ||
147 | else | ||
148 | dev_err(codec->dev, "Cache read from %x failed: %d\n", | ||
149 | reg, ret); | ||
150 | } | 116 | } |
151 | 117 | ||
152 | return wm8994_reg_read(codec->control_data, reg); | 118 | val = rates[best].start << WM8958_MICD_BIAS_STARTTIME_SHIFT |
119 | | rates[best].rate << WM8958_MICD_RATE_SHIFT; | ||
120 | |||
121 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | ||
122 | WM8958_MICD_BIAS_STARTTIME_MASK | | ||
123 | WM8958_MICD_RATE_MASK, val); | ||
153 | } | 124 | } |
154 | 125 | ||
155 | static int configure_aif_clock(struct snd_soc_codec *codec, int aif) | 126 | static int configure_aif_clock(struct snd_soc_codec *codec, int aif) |
@@ -221,8 +192,10 @@ static int configure_clock(struct snd_soc_codec *codec) | |||
221 | */ | 192 | */ |
222 | 193 | ||
223 | /* If they're equal it doesn't matter which is used */ | 194 | /* If they're equal it doesn't matter which is used */ |
224 | if (wm8994->aifclk[0] == wm8994->aifclk[1]) | 195 | if (wm8994->aifclk[0] == wm8994->aifclk[1]) { |
196 | wm8958_micd_set_rate(codec); | ||
225 | return 0; | 197 | return 0; |
198 | } | ||
226 | 199 | ||
227 | if (wm8994->aifclk[0] < wm8994->aifclk[1]) | 200 | if (wm8994->aifclk[0] < wm8994->aifclk[1]) |
228 | new = WM8994_SYSCLK_SRC; | 201 | new = WM8994_SYSCLK_SRC; |
@@ -231,10 +204,10 @@ static int configure_clock(struct snd_soc_codec *codec) | |||
231 | 204 | ||
232 | change = snd_soc_update_bits(codec, WM8994_CLOCKING_1, | 205 | change = snd_soc_update_bits(codec, WM8994_CLOCKING_1, |
233 | WM8994_SYSCLK_SRC, new); | 206 | WM8994_SYSCLK_SRC, new); |
234 | if (!change) | 207 | if (change) |
235 | return 0; | 208 | snd_soc_dapm_sync(&codec->dapm); |
236 | 209 | ||
237 | snd_soc_dapm_sync(&codec->dapm); | 210 | wm8958_micd_set_rate(codec); |
238 | 211 | ||
239 | return 0; | 212 | return 0; |
240 | } | 213 | } |
@@ -708,6 +681,74 @@ SOC_SINGLE_TLV("MIXINL IN1RP Boost Volume", WM8994_INPUT_MIXER_1, 8, 1, 0, | |||
708 | mixin_boost_tlv), | 681 | mixin_boost_tlv), |
709 | }; | 682 | }; |
710 | 683 | ||
684 | /* We run all mode setting through a function to enforce audio mode */ | ||
685 | static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode) | ||
686 | { | ||
687 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | ||
688 | |||
689 | if (wm8994->active_refcount) | ||
690 | mode = WM1811_JACKDET_MODE_AUDIO; | ||
691 | |||
692 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
693 | WM1811_JACKDET_MODE_MASK, mode); | ||
694 | |||
695 | if (mode == WM1811_JACKDET_MODE_MIC) | ||
696 | msleep(2); | ||
697 | } | ||
698 | |||
699 | static void active_reference(struct snd_soc_codec *codec) | ||
700 | { | ||
701 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | ||
702 | |||
703 | mutex_lock(&wm8994->accdet_lock); | ||
704 | |||
705 | wm8994->active_refcount++; | ||
706 | |||
707 | dev_dbg(codec->dev, "Active refcount incremented, now %d\n", | ||
708 | wm8994->active_refcount); | ||
709 | |||
710 | if (wm8994->active_refcount == 1) { | ||
711 | /* If we're using jack detection go into audio mode */ | ||
712 | if (wm8994->jackdet && wm8994->jack_cb) { | ||
713 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
714 | WM1811_JACKDET_MODE_MASK, | ||
715 | WM1811_JACKDET_MODE_AUDIO); | ||
716 | msleep(2); | ||
717 | } | ||
718 | } | ||
719 | |||
720 | mutex_unlock(&wm8994->accdet_lock); | ||
721 | } | ||
722 | |||
723 | static void active_dereference(struct snd_soc_codec *codec) | ||
724 | { | ||
725 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | ||
726 | u16 mode; | ||
727 | |||
728 | mutex_lock(&wm8994->accdet_lock); | ||
729 | |||
730 | wm8994->active_refcount--; | ||
731 | |||
732 | dev_dbg(codec->dev, "Active refcount decremented, now %d\n", | ||
733 | wm8994->active_refcount); | ||
734 | |||
735 | if (wm8994->active_refcount == 0) { | ||
736 | /* Go into appropriate detection only mode */ | ||
737 | if (wm8994->jackdet && wm8994->jack_cb) { | ||
738 | if (wm8994->jack_mic || wm8994->mic_detecting) | ||
739 | mode = WM1811_JACKDET_MODE_MIC; | ||
740 | else | ||
741 | mode = WM1811_JACKDET_MODE_JACK; | ||
742 | |||
743 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
744 | WM1811_JACKDET_MODE_MASK, | ||
745 | mode); | ||
746 | } | ||
747 | } | ||
748 | |||
749 | mutex_unlock(&wm8994->accdet_lock); | ||
750 | } | ||
751 | |||
711 | static int clk_sys_event(struct snd_soc_dapm_widget *w, | 752 | static int clk_sys_event(struct snd_soc_dapm_widget *w, |
712 | struct snd_kcontrol *kcontrol, int event) | 753 | struct snd_kcontrol *kcontrol, int event) |
713 | { | 754 | { |
@@ -1325,15 +1366,15 @@ SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0), | |||
1325 | }; | 1366 | }; |
1326 | 1367 | ||
1327 | static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = { | 1368 | static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = { |
1328 | SND_SOC_DAPM_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, | 1369 | SND_SOC_DAPM_VIRT_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, |
1329 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), | 1370 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), |
1330 | SND_SOC_DAPM_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, | 1371 | SND_SOC_DAPM_VIRT_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, |
1331 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), | 1372 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), |
1332 | }; | 1373 | }; |
1333 | 1374 | ||
1334 | static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = { | 1375 | static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = { |
1335 | SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), | 1376 | SND_SOC_DAPM_VIRT_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), |
1336 | SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), | 1377 | SND_SOC_DAPM_VIRT_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), |
1337 | }; | 1378 | }; |
1338 | 1379 | ||
1339 | static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { | 1380 | static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { |
@@ -1768,7 +1809,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
1768 | unsigned int freq_in, unsigned int freq_out) | 1809 | unsigned int freq_in, unsigned int freq_out) |
1769 | { | 1810 | { |
1770 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 1811 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
1771 | struct wm8994 *control = codec->control_data; | 1812 | struct wm8994 *control = wm8994->wm8994; |
1772 | int reg_offset, ret; | 1813 | int reg_offset, ret; |
1773 | struct fll_div fll; | 1814 | struct fll_div fll; |
1774 | u16 reg, aif1, aif2; | 1815 | u16 reg, aif1, aif2; |
@@ -1865,6 +1906,8 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
1865 | if (freq_out) { | 1906 | if (freq_out) { |
1866 | /* Enable VMID if we need it */ | 1907 | /* Enable VMID if we need it */ |
1867 | if (!was_enabled) { | 1908 | if (!was_enabled) { |
1909 | active_reference(codec); | ||
1910 | |||
1868 | switch (control->type) { | 1911 | switch (control->type) { |
1869 | case WM8994: | 1912 | case WM8994: |
1870 | vmid_reference(codec); | 1913 | vmid_reference(codec); |
@@ -1908,6 +1951,8 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
1908 | default: | 1951 | default: |
1909 | break; | 1952 | break; |
1910 | } | 1953 | } |
1954 | |||
1955 | active_dereference(codec); | ||
1911 | } | 1956 | } |
1912 | } | 1957 | } |
1913 | 1958 | ||
@@ -2017,20 +2062,33 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, | |||
2017 | static int wm8994_set_bias_level(struct snd_soc_codec *codec, | 2062 | static int wm8994_set_bias_level(struct snd_soc_codec *codec, |
2018 | enum snd_soc_bias_level level) | 2063 | enum snd_soc_bias_level level) |
2019 | { | 2064 | { |
2020 | struct wm8994 *control = codec->control_data; | ||
2021 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 2065 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2066 | struct wm8994 *control = wm8994->wm8994; | ||
2022 | 2067 | ||
2023 | switch (level) { | 2068 | switch (level) { |
2024 | case SND_SOC_BIAS_ON: | 2069 | case SND_SOC_BIAS_ON: |
2025 | break; | 2070 | break; |
2026 | 2071 | ||
2027 | case SND_SOC_BIAS_PREPARE: | 2072 | case SND_SOC_BIAS_PREPARE: |
2073 | /* MICBIAS into regulating mode */ | ||
2074 | switch (control->type) { | ||
2075 | case WM8958: | ||
2076 | case WM1811: | ||
2077 | snd_soc_update_bits(codec, WM8958_MICBIAS1, | ||
2078 | WM8958_MICB1_MODE, 0); | ||
2079 | snd_soc_update_bits(codec, WM8958_MICBIAS2, | ||
2080 | WM8958_MICB2_MODE, 0); | ||
2081 | break; | ||
2082 | default: | ||
2083 | break; | ||
2084 | } | ||
2085 | |||
2086 | if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) | ||
2087 | active_reference(codec); | ||
2028 | break; | 2088 | break; |
2029 | 2089 | ||
2030 | case SND_SOC_BIAS_STANDBY: | 2090 | case SND_SOC_BIAS_STANDBY: |
2031 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 2091 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
2032 | pm_runtime_get_sync(codec->dev); | ||
2033 | |||
2034 | switch (control->type) { | 2092 | switch (control->type) { |
2035 | case WM8994: | 2093 | case WM8994: |
2036 | if (wm8994->revision < 4) { | 2094 | if (wm8994->revision < 4) { |
@@ -2077,25 +2135,40 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, | |||
2077 | WM8994_LINEOUT2_DISCH); | 2135 | WM8994_LINEOUT2_DISCH); |
2078 | } | 2136 | } |
2079 | 2137 | ||
2138 | if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) | ||
2139 | active_dereference(codec); | ||
2080 | 2140 | ||
2141 | /* MICBIAS into bypass mode on newer devices */ | ||
2142 | switch (control->type) { | ||
2143 | case WM8958: | ||
2144 | case WM1811: | ||
2145 | snd_soc_update_bits(codec, WM8958_MICBIAS1, | ||
2146 | WM8958_MICB1_MODE, | ||
2147 | WM8958_MICB1_MODE); | ||
2148 | snd_soc_update_bits(codec, WM8958_MICBIAS2, | ||
2149 | WM8958_MICB2_MODE, | ||
2150 | WM8958_MICB2_MODE); | ||
2151 | break; | ||
2152 | default: | ||
2153 | break; | ||
2154 | } | ||
2081 | break; | 2155 | break; |
2082 | 2156 | ||
2083 | case SND_SOC_BIAS_OFF: | 2157 | case SND_SOC_BIAS_OFF: |
2084 | if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { | 2158 | if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) |
2085 | wm8994->cur_fw = NULL; | 2159 | wm8994->cur_fw = NULL; |
2086 | |||
2087 | pm_runtime_put(codec->dev); | ||
2088 | } | ||
2089 | break; | 2160 | break; |
2090 | } | 2161 | } |
2091 | codec->dapm.bias_level = level; | 2162 | codec->dapm.bias_level = level; |
2163 | |||
2092 | return 0; | 2164 | return 0; |
2093 | } | 2165 | } |
2094 | 2166 | ||
2095 | static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | 2167 | static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
2096 | { | 2168 | { |
2097 | struct snd_soc_codec *codec = dai->codec; | 2169 | struct snd_soc_codec *codec = dai->codec; |
2098 | struct wm8994 *control = codec->control_data; | 2170 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2171 | struct wm8994 *control = wm8994->wm8994; | ||
2099 | int ms_reg; | 2172 | int ms_reg; |
2100 | int aif1_reg; | 2173 | int aif1_reg; |
2101 | int ms = 0; | 2174 | int ms = 0; |
@@ -2395,7 +2468,8 @@ static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream, | |||
2395 | struct snd_soc_dai *dai) | 2468 | struct snd_soc_dai *dai) |
2396 | { | 2469 | { |
2397 | struct snd_soc_codec *codec = dai->codec; | 2470 | struct snd_soc_codec *codec = dai->codec; |
2398 | struct wm8994 *control = codec->control_data; | 2471 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2472 | struct wm8994 *control = wm8994->wm8994; | ||
2399 | int aif1_reg; | 2473 | int aif1_reg; |
2400 | int aif1 = 0; | 2474 | int aif1 = 0; |
2401 | 2475 | ||
@@ -2536,7 +2610,7 @@ static int wm8994_aif2_probe(struct snd_soc_dai *dai) | |||
2536 | #define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ | 2610 | #define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ |
2537 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) | 2611 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) |
2538 | 2612 | ||
2539 | static struct snd_soc_dai_ops wm8994_aif1_dai_ops = { | 2613 | static const struct snd_soc_dai_ops wm8994_aif1_dai_ops = { |
2540 | .set_sysclk = wm8994_set_dai_sysclk, | 2614 | .set_sysclk = wm8994_set_dai_sysclk, |
2541 | .set_fmt = wm8994_set_dai_fmt, | 2615 | .set_fmt = wm8994_set_dai_fmt, |
2542 | .hw_params = wm8994_hw_params, | 2616 | .hw_params = wm8994_hw_params, |
@@ -2546,7 +2620,7 @@ static struct snd_soc_dai_ops wm8994_aif1_dai_ops = { | |||
2546 | .set_tristate = wm8994_set_tristate, | 2620 | .set_tristate = wm8994_set_tristate, |
2547 | }; | 2621 | }; |
2548 | 2622 | ||
2549 | static struct snd_soc_dai_ops wm8994_aif2_dai_ops = { | 2623 | static const struct snd_soc_dai_ops wm8994_aif2_dai_ops = { |
2550 | .set_sysclk = wm8994_set_dai_sysclk, | 2624 | .set_sysclk = wm8994_set_dai_sysclk, |
2551 | .set_fmt = wm8994_set_dai_fmt, | 2625 | .set_fmt = wm8994_set_dai_fmt, |
2552 | .hw_params = wm8994_hw_params, | 2626 | .hw_params = wm8994_hw_params, |
@@ -2556,7 +2630,7 @@ static struct snd_soc_dai_ops wm8994_aif2_dai_ops = { | |||
2556 | .set_tristate = wm8994_set_tristate, | 2630 | .set_tristate = wm8994_set_tristate, |
2557 | }; | 2631 | }; |
2558 | 2632 | ||
2559 | static struct snd_soc_dai_ops wm8994_aif3_dai_ops = { | 2633 | static const struct snd_soc_dai_ops wm8994_aif3_dai_ops = { |
2560 | .hw_params = wm8994_aif3_hw_params, | 2634 | .hw_params = wm8994_aif3_hw_params, |
2561 | .set_tristate = wm8994_set_tristate, | 2635 | .set_tristate = wm8994_set_tristate, |
2562 | }; | 2636 | }; |
@@ -2623,10 +2697,10 @@ static struct snd_soc_dai_driver wm8994_dai[] = { | |||
2623 | }; | 2697 | }; |
2624 | 2698 | ||
2625 | #ifdef CONFIG_PM | 2699 | #ifdef CONFIG_PM |
2626 | static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state) | 2700 | static int wm8994_suspend(struct snd_soc_codec *codec) |
2627 | { | 2701 | { |
2628 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 2702 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2629 | struct wm8994 *control = codec->control_data; | 2703 | struct wm8994 *control = wm8994->wm8994; |
2630 | int i, ret; | 2704 | int i, ret; |
2631 | 2705 | ||
2632 | switch (control->type) { | 2706 | switch (control->type) { |
@@ -2634,6 +2708,9 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
2634 | snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0); | 2708 | snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0); |
2635 | break; | 2709 | break; |
2636 | case WM1811: | 2710 | case WM1811: |
2711 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
2712 | WM1811_JACKDET_MODE_MASK, 0); | ||
2713 | /* Fall through */ | ||
2637 | case WM8958: | 2714 | case WM8958: |
2638 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | 2715 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, |
2639 | WM8958_MICD_ENA, 0); | 2716 | WM8958_MICD_ENA, 0); |
@@ -2657,14 +2734,14 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
2657 | static int wm8994_resume(struct snd_soc_codec *codec) | 2734 | static int wm8994_resume(struct snd_soc_codec *codec) |
2658 | { | 2735 | { |
2659 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 2736 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2660 | struct wm8994 *control = codec->control_data; | 2737 | struct wm8994 *control = wm8994->wm8994; |
2661 | int i, ret; | 2738 | int i, ret; |
2662 | unsigned int val, mask; | 2739 | unsigned int val, mask; |
2663 | 2740 | ||
2664 | if (wm8994->revision < 4) { | 2741 | if (wm8994->revision < 4) { |
2665 | /* force a HW read */ | 2742 | /* force a HW read */ |
2666 | val = wm8994_reg_read(codec->control_data, | 2743 | ret = regmap_read(control->regmap, |
2667 | WM8994_POWER_MANAGEMENT_5); | 2744 | WM8994_POWER_MANAGEMENT_5, &val); |
2668 | 2745 | ||
2669 | /* modify the cache only */ | 2746 | /* modify the cache only */ |
2670 | codec->cache_only = 1; | 2747 | codec->cache_only = 1; |
@@ -2703,6 +2780,13 @@ static int wm8994_resume(struct snd_soc_codec *codec) | |||
2703 | WM8994_MICD_ENA, WM8994_MICD_ENA); | 2780 | WM8994_MICD_ENA, WM8994_MICD_ENA); |
2704 | break; | 2781 | break; |
2705 | case WM1811: | 2782 | case WM1811: |
2783 | if (wm8994->jackdet && wm8994->jack_cb) { | ||
2784 | /* Restart from idle */ | ||
2785 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
2786 | WM1811_JACKDET_MODE_MASK, | ||
2787 | WM1811_JACKDET_MODE_JACK); | ||
2788 | break; | ||
2789 | } | ||
2706 | case WM8958: | 2790 | case WM8958: |
2707 | if (wm8994->jack_cb) | 2791 | if (wm8994->jack_cb) |
2708 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | 2792 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, |
@@ -2815,8 +2899,8 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) | |||
2815 | }; | 2899 | }; |
2816 | 2900 | ||
2817 | /* We need an array of texts for the enum API */ | 2901 | /* We need an array of texts for the enum API */ |
2818 | wm8994->drc_texts = kmalloc(sizeof(char *) | 2902 | wm8994->drc_texts = devm_kzalloc(wm8994->codec->dev, |
2819 | * pdata->num_drc_cfgs, GFP_KERNEL); | 2903 | sizeof(char *) * pdata->num_drc_cfgs, GFP_KERNEL); |
2820 | if (!wm8994->drc_texts) { | 2904 | if (!wm8994->drc_texts) { |
2821 | dev_err(wm8994->codec->dev, | 2905 | dev_err(wm8994->codec->dev, |
2822 | "Failed to allocate %d DRC config texts\n", | 2906 | "Failed to allocate %d DRC config texts\n", |
@@ -2879,7 +2963,7 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
2879 | { | 2963 | { |
2880 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 2964 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2881 | struct wm8994_micdet *micdet; | 2965 | struct wm8994_micdet *micdet; |
2882 | struct wm8994 *control = codec->control_data; | 2966 | struct wm8994 *control = wm8994->wm8994; |
2883 | int reg; | 2967 | int reg; |
2884 | 2968 | ||
2885 | if (control->type != WM8994) | 2969 | if (control->type != WM8994) |
@@ -2962,21 +3046,136 @@ static void wm8958_default_micdet(u16 status, void *data) | |||
2962 | { | 3046 | { |
2963 | struct snd_soc_codec *codec = data; | 3047 | struct snd_soc_codec *codec = data; |
2964 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 3048 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2965 | int report = 0; | 3049 | int report; |
3050 | |||
3051 | dev_dbg(codec->dev, "MICDET %x\n", status); | ||
3052 | |||
3053 | /* Either nothing present or just starting detection */ | ||
3054 | if (!(status & WM8958_MICD_STS)) { | ||
3055 | if (!wm8994->jackdet) { | ||
3056 | /* If nothing present then clear our statuses */ | ||
3057 | dev_dbg(codec->dev, "Detected open circuit\n"); | ||
3058 | wm8994->jack_mic = false; | ||
3059 | wm8994->mic_detecting = true; | ||
3060 | |||
3061 | wm8958_micd_set_rate(codec); | ||
3062 | |||
3063 | snd_soc_jack_report(wm8994->micdet[0].jack, 0, | ||
3064 | wm8994->btn_mask | | ||
3065 | SND_JACK_HEADSET); | ||
3066 | } | ||
3067 | return; | ||
3068 | } | ||
3069 | |||
3070 | /* If the measurement is showing a high impedence we've got a | ||
3071 | * microphone. | ||
3072 | */ | ||
3073 | if (wm8994->mic_detecting && (status & 0x600)) { | ||
3074 | dev_dbg(codec->dev, "Detected microphone\n"); | ||
3075 | |||
3076 | wm8994->mic_detecting = false; | ||
3077 | wm8994->jack_mic = true; | ||
3078 | |||
3079 | wm8958_micd_set_rate(codec); | ||
3080 | |||
3081 | snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADSET, | ||
3082 | SND_JACK_HEADSET); | ||
3083 | } | ||
3084 | |||
3085 | |||
3086 | if (wm8994->mic_detecting && status & 0x4) { | ||
3087 | dev_dbg(codec->dev, "Detected headphone\n"); | ||
3088 | wm8994->mic_detecting = false; | ||
3089 | |||
3090 | wm8958_micd_set_rate(codec); | ||
3091 | |||
3092 | snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE, | ||
3093 | SND_JACK_HEADSET); | ||
3094 | |||
3095 | /* If we have jackdet that will detect removal */ | ||
3096 | if (wm8994->jackdet) { | ||
3097 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | ||
3098 | WM8958_MICD_ENA, 0); | ||
3099 | |||
3100 | wm1811_jackdet_set_mode(codec, | ||
3101 | WM1811_JACKDET_MODE_JACK); | ||
3102 | } | ||
3103 | } | ||
3104 | |||
3105 | /* Report short circuit as a button */ | ||
3106 | if (wm8994->jack_mic) { | ||
3107 | report = 0; | ||
3108 | if (status & 0x4) | ||
3109 | report |= SND_JACK_BTN_0; | ||
3110 | |||
3111 | if (status & 0x8) | ||
3112 | report |= SND_JACK_BTN_1; | ||
3113 | |||
3114 | if (status & 0x10) | ||
3115 | report |= SND_JACK_BTN_2; | ||
3116 | |||
3117 | if (status & 0x20) | ||
3118 | report |= SND_JACK_BTN_3; | ||
3119 | |||
3120 | if (status & 0x40) | ||
3121 | report |= SND_JACK_BTN_4; | ||
3122 | |||
3123 | if (status & 0x80) | ||
3124 | report |= SND_JACK_BTN_5; | ||
3125 | |||
3126 | snd_soc_jack_report(wm8994->micdet[0].jack, report, | ||
3127 | wm8994->btn_mask); | ||
3128 | } | ||
3129 | } | ||
3130 | |||
3131 | static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | ||
3132 | { | ||
3133 | struct wm8994_priv *wm8994 = data; | ||
3134 | struct snd_soc_codec *codec = wm8994->codec; | ||
3135 | int reg; | ||
3136 | |||
3137 | mutex_lock(&wm8994->accdet_lock); | ||
3138 | |||
3139 | reg = snd_soc_read(codec, WM1811_JACKDET_CTRL); | ||
3140 | if (reg < 0) { | ||
3141 | dev_err(codec->dev, "Failed to read jack status: %d\n", reg); | ||
3142 | mutex_unlock(&wm8994->accdet_lock); | ||
3143 | return IRQ_NONE; | ||
3144 | } | ||
3145 | |||
3146 | dev_dbg(codec->dev, "JACKDET %x\n", reg); | ||
2966 | 3147 | ||
2967 | /* If nothing present then clear our statuses */ | 3148 | if (reg & WM1811_JACKDET_LVL) { |
2968 | if (!(status & WM8958_MICD_STS)) | 3149 | dev_dbg(codec->dev, "Jack detected\n"); |
2969 | goto done; | ||
2970 | 3150 | ||
2971 | report = SND_JACK_MICROPHONE; | 3151 | snd_soc_jack_report(wm8994->micdet[0].jack, |
3152 | SND_JACK_MECHANICAL, SND_JACK_MECHANICAL); | ||
3153 | |||
3154 | /* | ||
3155 | * Start off measument of microphone impedence to find | ||
3156 | * out what's actually there. | ||
3157 | */ | ||
3158 | wm8994->mic_detecting = true; | ||
3159 | wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); | ||
3160 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | ||
3161 | WM8958_MICD_ENA, WM8958_MICD_ENA); | ||
3162 | } else { | ||
3163 | dev_dbg(codec->dev, "Jack not detected\n"); | ||
2972 | 3164 | ||
2973 | /* Everything else is buttons; just assign slots */ | 3165 | snd_soc_jack_report(wm8994->micdet[0].jack, 0, |
2974 | if (status & 0x1c) | 3166 | SND_JACK_MECHANICAL | SND_JACK_HEADSET | |
2975 | report |= SND_JACK_BTN_0; | 3167 | wm8994->btn_mask); |
2976 | 3168 | ||
2977 | done: | 3169 | wm8994->mic_detecting = false; |
2978 | snd_soc_jack_report(wm8994->micdet[0].jack, report, | 3170 | wm8994->jack_mic = false; |
2979 | SND_JACK_BTN_0 | SND_JACK_MICROPHONE); | 3171 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, |
3172 | WM8958_MICD_ENA, 0); | ||
3173 | wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_JACK); | ||
3174 | } | ||
3175 | |||
3176 | mutex_unlock(&wm8994->accdet_lock); | ||
3177 | |||
3178 | return IRQ_HANDLED; | ||
2980 | } | 3179 | } |
2981 | 3180 | ||
2982 | /** | 3181 | /** |
@@ -2999,7 +3198,8 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
2999 | wm8958_micdet_cb cb, void *cb_data) | 3198 | wm8958_micdet_cb cb, void *cb_data) |
3000 | { | 3199 | { |
3001 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 3200 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
3002 | struct wm8994 *control = codec->control_data; | 3201 | struct wm8994 *control = wm8994->wm8994; |
3202 | u16 micd_lvl_sel; | ||
3003 | 3203 | ||
3004 | switch (control->type) { | 3204 | switch (control->type) { |
3005 | case WM1811: | 3205 | case WM1811: |
@@ -3016,15 +3216,50 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
3016 | cb_data = codec; | 3216 | cb_data = codec; |
3017 | } | 3217 | } |
3018 | 3218 | ||
3219 | snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS"); | ||
3220 | |||
3019 | wm8994->micdet[0].jack = jack; | 3221 | wm8994->micdet[0].jack = jack; |
3020 | wm8994->jack_cb = cb; | 3222 | wm8994->jack_cb = cb; |
3021 | wm8994->jack_cb_data = cb_data; | 3223 | wm8994->jack_cb_data = cb_data; |
3022 | 3224 | ||
3023 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | 3225 | wm8994->mic_detecting = true; |
3024 | WM8958_MICD_ENA, WM8958_MICD_ENA); | 3226 | wm8994->jack_mic = false; |
3227 | |||
3228 | wm8958_micd_set_rate(codec); | ||
3229 | |||
3230 | /* Detect microphones and short circuits by default */ | ||
3231 | if (wm8994->pdata->micd_lvl_sel) | ||
3232 | micd_lvl_sel = wm8994->pdata->micd_lvl_sel; | ||
3233 | else | ||
3234 | micd_lvl_sel = 0x41; | ||
3235 | |||
3236 | wm8994->btn_mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | | ||
3237 | SND_JACK_BTN_2 | SND_JACK_BTN_3 | | ||
3238 | SND_JACK_BTN_4 | SND_JACK_BTN_5; | ||
3239 | |||
3240 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_2, | ||
3241 | WM8958_MICD_LVL_SEL_MASK, micd_lvl_sel); | ||
3242 | |||
3243 | WARN_ON(codec->dapm.bias_level > SND_SOC_BIAS_STANDBY); | ||
3244 | |||
3245 | /* | ||
3246 | * If we can use jack detection start off with that, | ||
3247 | * otherwise jump straight to microphone detection. | ||
3248 | */ | ||
3249 | if (wm8994->jackdet) { | ||
3250 | snd_soc_update_bits(codec, WM8994_LDO_1, | ||
3251 | WM8994_LDO1_DISCH, 0); | ||
3252 | wm1811_jackdet_set_mode(codec, | ||
3253 | WM1811_JACKDET_MODE_JACK); | ||
3254 | } else { | ||
3255 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | ||
3256 | WM8958_MICD_ENA, WM8958_MICD_ENA); | ||
3257 | } | ||
3258 | |||
3025 | } else { | 3259 | } else { |
3026 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | 3260 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, |
3027 | WM8958_MICD_ENA, 0); | 3261 | WM8958_MICD_ENA, 0); |
3262 | snd_soc_dapm_disable_pin(&codec->dapm, "CLK_SYS"); | ||
3028 | } | 3263 | } |
3029 | 3264 | ||
3030 | return 0; | 3265 | return 0; |
@@ -3037,6 +3272,18 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3037 | struct snd_soc_codec *codec = wm8994->codec; | 3272 | struct snd_soc_codec *codec = wm8994->codec; |
3038 | int reg, count; | 3273 | int reg, count; |
3039 | 3274 | ||
3275 | mutex_lock(&wm8994->accdet_lock); | ||
3276 | |||
3277 | /* | ||
3278 | * Jack detection may have detected a removal simulataneously | ||
3279 | * with an update of the MICDET status; if so it will have | ||
3280 | * stopped detection and we can ignore this interrupt. | ||
3281 | */ | ||
3282 | if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) { | ||
3283 | mutex_unlock(&wm8994->accdet_lock); | ||
3284 | return IRQ_HANDLED; | ||
3285 | } | ||
3286 | |||
3040 | /* We may occasionally read a detection without an impedence | 3287 | /* We may occasionally read a detection without an impedence |
3041 | * range being provided - if that happens loop again. | 3288 | * range being provided - if that happens loop again. |
3042 | */ | 3289 | */ |
@@ -3044,6 +3291,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3044 | do { | 3291 | do { |
3045 | reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); | 3292 | reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); |
3046 | if (reg < 0) { | 3293 | if (reg < 0) { |
3294 | mutex_unlock(&wm8994->accdet_lock); | ||
3047 | dev_err(codec->dev, | 3295 | dev_err(codec->dev, |
3048 | "Failed to read mic detect status: %d\n", | 3296 | "Failed to read mic detect status: %d\n", |
3049 | reg); | 3297 | reg); |
@@ -3074,6 +3322,8 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3074 | dev_warn(codec->dev, "Accessory detection with no callback\n"); | 3322 | dev_warn(codec->dev, "Accessory detection with no callback\n"); |
3075 | 3323 | ||
3076 | out: | 3324 | out: |
3325 | mutex_unlock(&wm8994->accdet_lock); | ||
3326 | |||
3077 | return IRQ_HANDLED; | 3327 | return IRQ_HANDLED; |
3078 | } | 3328 | } |
3079 | 3329 | ||
@@ -3106,22 +3356,28 @@ static irqreturn_t wm8994_temp_shut(int irq, void *data) | |||
3106 | 3356 | ||
3107 | static int wm8994_codec_probe(struct snd_soc_codec *codec) | 3357 | static int wm8994_codec_probe(struct snd_soc_codec *codec) |
3108 | { | 3358 | { |
3109 | struct wm8994 *control; | 3359 | struct wm8994 *control = dev_get_drvdata(codec->dev->parent); |
3110 | struct wm8994_priv *wm8994; | 3360 | struct wm8994_priv *wm8994; |
3111 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 3361 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
3362 | unsigned int reg; | ||
3112 | int ret, i; | 3363 | int ret, i; |
3113 | 3364 | ||
3114 | codec->control_data = dev_get_drvdata(codec->dev->parent); | 3365 | codec->control_data = control->regmap; |
3115 | control = codec->control_data; | ||
3116 | 3366 | ||
3117 | wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL); | 3367 | wm8994 = devm_kzalloc(codec->dev, sizeof(struct wm8994_priv), |
3368 | GFP_KERNEL); | ||
3118 | if (wm8994 == NULL) | 3369 | if (wm8994 == NULL) |
3119 | return -ENOMEM; | 3370 | return -ENOMEM; |
3120 | snd_soc_codec_set_drvdata(codec, wm8994); | 3371 | snd_soc_codec_set_drvdata(codec, wm8994); |
3121 | 3372 | ||
3373 | snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); | ||
3374 | |||
3375 | wm8994->wm8994 = dev_get_drvdata(codec->dev->parent); | ||
3122 | wm8994->pdata = dev_get_platdata(codec->dev->parent); | 3376 | wm8994->pdata = dev_get_platdata(codec->dev->parent); |
3123 | wm8994->codec = codec; | 3377 | wm8994->codec = codec; |
3124 | 3378 | ||
3379 | mutex_init(&wm8994->accdet_lock); | ||
3380 | |||
3125 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) | 3381 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) |
3126 | init_completion(&wm8994->fll_locked[i]); | 3382 | init_completion(&wm8994->fll_locked[i]); |
3127 | 3383 | ||
@@ -3134,25 +3390,6 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3134 | pm_runtime_enable(codec->dev); | 3390 | pm_runtime_enable(codec->dev); |
3135 | pm_runtime_resume(codec->dev); | 3391 | pm_runtime_resume(codec->dev); |
3136 | 3392 | ||
3137 | /* Read our current status back from the chip - we don't want to | ||
3138 | * reset as this may interfere with the GPIO or LDO operation. */ | ||
3139 | for (i = 0; i < WM8994_CACHE_SIZE; i++) { | ||
3140 | if (!wm8994_readable(codec, i) || wm8994_volatile(codec, i)) | ||
3141 | continue; | ||
3142 | |||
3143 | ret = wm8994_reg_read(codec->control_data, i); | ||
3144 | if (ret <= 0) | ||
3145 | continue; | ||
3146 | |||
3147 | ret = snd_soc_cache_write(codec, i, ret); | ||
3148 | if (ret != 0) { | ||
3149 | dev_err(codec->dev, | ||
3150 | "Failed to initialise cache for 0x%x: %d\n", | ||
3151 | i, ret); | ||
3152 | goto err; | ||
3153 | } | ||
3154 | } | ||
3155 | |||
3156 | /* Set revision-specific configuration */ | 3393 | /* Set revision-specific configuration */ |
3157 | wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); | 3394 | wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); |
3158 | switch (control->type) { | 3395 | switch (control->type) { |
@@ -3200,14 +3437,14 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3200 | break; | 3437 | break; |
3201 | } | 3438 | } |
3202 | 3439 | ||
3203 | wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, | 3440 | wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR, |
3204 | wm8994_fifo_error, "FIFO error", codec); | 3441 | wm8994_fifo_error, "FIFO error", codec); |
3205 | wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, | 3442 | wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN, |
3206 | wm8994_temp_warn, "Thermal warning", codec); | 3443 | wm8994_temp_warn, "Thermal warning", codec); |
3207 | wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, | 3444 | wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT, |
3208 | wm8994_temp_shut, "Thermal shutdown", codec); | 3445 | wm8994_temp_shut, "Thermal shutdown", codec); |
3209 | 3446 | ||
3210 | ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE, | 3447 | ret = wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE, |
3211 | wm_hubs_dcs_done, "DC servo done", | 3448 | wm_hubs_dcs_done, "DC servo done", |
3212 | &wm8994->hubs); | 3449 | &wm8994->hubs); |
3213 | if (ret == 0) | 3450 | if (ret == 0) |
@@ -3227,7 +3464,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3227 | ret); | 3464 | ret); |
3228 | } | 3465 | } |
3229 | 3466 | ||
3230 | ret = wm8994_request_irq(codec->control_data, | 3467 | ret = wm8994_request_irq(wm8994->wm8994, |
3231 | WM8994_IRQ_MIC1_SHRT, | 3468 | WM8994_IRQ_MIC1_SHRT, |
3232 | wm8994_mic_irq, "Mic 1 short", | 3469 | wm8994_mic_irq, "Mic 1 short", |
3233 | wm8994); | 3470 | wm8994); |
@@ -3236,7 +3473,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3236 | "Failed to request Mic1 short IRQ: %d\n", | 3473 | "Failed to request Mic1 short IRQ: %d\n", |
3237 | ret); | 3474 | ret); |
3238 | 3475 | ||
3239 | ret = wm8994_request_irq(codec->control_data, | 3476 | ret = wm8994_request_irq(wm8994->wm8994, |
3240 | WM8994_IRQ_MIC2_DET, | 3477 | WM8994_IRQ_MIC2_DET, |
3241 | wm8994_mic_irq, "Mic 2 detect", | 3478 | wm8994_mic_irq, "Mic 2 detect", |
3242 | wm8994); | 3479 | wm8994); |
@@ -3245,7 +3482,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3245 | "Failed to request Mic2 detect IRQ: %d\n", | 3482 | "Failed to request Mic2 detect IRQ: %d\n", |
3246 | ret); | 3483 | ret); |
3247 | 3484 | ||
3248 | ret = wm8994_request_irq(codec->control_data, | 3485 | ret = wm8994_request_irq(wm8994->wm8994, |
3249 | WM8994_IRQ_MIC2_SHRT, | 3486 | WM8994_IRQ_MIC2_SHRT, |
3250 | wm8994_mic_irq, "Mic 2 short", | 3487 | wm8994_mic_irq, "Mic 2 short", |
3251 | wm8994); | 3488 | wm8994); |
@@ -3270,9 +3507,24 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3270 | } | 3507 | } |
3271 | } | 3508 | } |
3272 | 3509 | ||
3510 | switch (control->type) { | ||
3511 | case WM1811: | ||
3512 | if (wm8994->revision > 1) { | ||
3513 | ret = wm8994_request_irq(wm8994->wm8994, | ||
3514 | WM8994_IRQ_GPIO(6), | ||
3515 | wm1811_jackdet_irq, "JACKDET", | ||
3516 | wm8994); | ||
3517 | if (ret == 0) | ||
3518 | wm8994->jackdet = true; | ||
3519 | } | ||
3520 | break; | ||
3521 | default: | ||
3522 | break; | ||
3523 | } | ||
3524 | |||
3273 | wm8994->fll_locked_irq = true; | 3525 | wm8994->fll_locked_irq = true; |
3274 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) { | 3526 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) { |
3275 | ret = wm8994_request_irq(codec->control_data, | 3527 | ret = wm8994_request_irq(wm8994->wm8994, |
3276 | WM8994_IRQ_FLL1_LOCK + i, | 3528 | WM8994_IRQ_FLL1_LOCK + i, |
3277 | wm8994_fll_locked_irq, "FLL lock", | 3529 | wm8994_fll_locked_irq, "FLL lock", |
3278 | &wm8994->fll_locked[i]); | 3530 | &wm8994->fll_locked[i]); |
@@ -3284,24 +3536,24 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3284 | * configured on init - if a system wants to do this dynamically | 3536 | * configured on init - if a system wants to do this dynamically |
3285 | * at runtime we can deal with that then. | 3537 | * at runtime we can deal with that then. |
3286 | */ | 3538 | */ |
3287 | ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_1); | 3539 | ret = regmap_read(control->regmap, WM8994_GPIO_1, ®); |
3288 | if (ret < 0) { | 3540 | if (ret < 0) { |
3289 | dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret); | 3541 | dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret); |
3290 | goto err_irq; | 3542 | goto err_irq; |
3291 | } | 3543 | } |
3292 | if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { | 3544 | if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { |
3293 | wm8994->lrclk_shared[0] = 1; | 3545 | wm8994->lrclk_shared[0] = 1; |
3294 | wm8994_dai[0].symmetric_rates = 1; | 3546 | wm8994_dai[0].symmetric_rates = 1; |
3295 | } else { | 3547 | } else { |
3296 | wm8994->lrclk_shared[0] = 0; | 3548 | wm8994->lrclk_shared[0] = 0; |
3297 | } | 3549 | } |
3298 | 3550 | ||
3299 | ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_6); | 3551 | ret = regmap_read(control->regmap, WM8994_GPIO_6, ®); |
3300 | if (ret < 0) { | 3552 | if (ret < 0) { |
3301 | dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret); | 3553 | dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret); |
3302 | goto err_irq; | 3554 | goto err_irq; |
3303 | } | 3555 | } |
3304 | if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { | 3556 | if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { |
3305 | wm8994->lrclk_shared[1] = 1; | 3557 | wm8994->lrclk_shared[1] = 1; |
3306 | wm8994_dai[1].symmetric_rates = 1; | 3558 | wm8994_dai[1].symmetric_rates = 1; |
3307 | } else { | 3559 | } else { |
@@ -3368,6 +3620,19 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3368 | break; | 3620 | break; |
3369 | } | 3621 | } |
3370 | 3622 | ||
3623 | /* Put MICBIAS into bypass mode by default on newer devices */ | ||
3624 | switch (control->type) { | ||
3625 | case WM8958: | ||
3626 | case WM1811: | ||
3627 | snd_soc_update_bits(codec, WM8958_MICBIAS1, | ||
3628 | WM8958_MICB1_MODE, WM8958_MICB1_MODE); | ||
3629 | snd_soc_update_bits(codec, WM8958_MICBIAS2, | ||
3630 | WM8958_MICB2_MODE, WM8958_MICB2_MODE); | ||
3631 | break; | ||
3632 | default: | ||
3633 | break; | ||
3634 | } | ||
3635 | |||
3371 | wm8994_update_class_w(codec); | 3636 | wm8994_update_class_w(codec); |
3372 | 3637 | ||
3373 | wm8994_handle_pdata(wm8994); | 3638 | wm8994_handle_pdata(wm8994); |
@@ -3479,28 +3744,29 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3479 | return 0; | 3744 | return 0; |
3480 | 3745 | ||
3481 | err_irq: | 3746 | err_irq: |
3482 | wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); | 3747 | if (wm8994->jackdet) |
3483 | wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); | 3748 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_GPIO(6), wm8994); |
3484 | wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); | 3749 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC2_SHRT, wm8994); |
3750 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC2_DET, wm8994); | ||
3751 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC1_SHRT, wm8994); | ||
3485 | if (wm8994->micdet_irq) | 3752 | if (wm8994->micdet_irq) |
3486 | free_irq(wm8994->micdet_irq, wm8994); | 3753 | free_irq(wm8994->micdet_irq, wm8994); |
3487 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) | 3754 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) |
3488 | wm8994_free_irq(codec->control_data, WM8994_IRQ_FLL1_LOCK + i, | 3755 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FLL1_LOCK + i, |
3489 | &wm8994->fll_locked[i]); | 3756 | &wm8994->fll_locked[i]); |
3490 | wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, | 3757 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE, |
3491 | &wm8994->hubs); | 3758 | &wm8994->hubs); |
3492 | wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec); | 3759 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR, codec); |
3493 | wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, codec); | 3760 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT, codec); |
3494 | wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, codec); | 3761 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN, codec); |
3495 | err: | 3762 | |
3496 | kfree(wm8994); | ||
3497 | return ret; | 3763 | return ret; |
3498 | } | 3764 | } |
3499 | 3765 | ||
3500 | static int wm8994_codec_remove(struct snd_soc_codec *codec) | 3766 | static int wm8994_codec_remove(struct snd_soc_codec *codec) |
3501 | { | 3767 | { |
3502 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 3768 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
3503 | struct wm8994 *control = codec->control_data; | 3769 | struct wm8994 *control = wm8994->wm8994; |
3504 | int i; | 3770 | int i; |
3505 | 3771 | ||
3506 | wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); | 3772 | wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); |
@@ -3508,24 +3774,27 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) | |||
3508 | pm_runtime_disable(codec->dev); | 3774 | pm_runtime_disable(codec->dev); |
3509 | 3775 | ||
3510 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) | 3776 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) |
3511 | wm8994_free_irq(codec->control_data, WM8994_IRQ_FLL1_LOCK + i, | 3777 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FLL1_LOCK + i, |
3512 | &wm8994->fll_locked[i]); | 3778 | &wm8994->fll_locked[i]); |
3513 | 3779 | ||
3514 | wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, | 3780 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE, |
3515 | &wm8994->hubs); | 3781 | &wm8994->hubs); |
3516 | wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec); | 3782 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR, codec); |
3517 | wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, codec); | 3783 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT, codec); |
3518 | wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, codec); | 3784 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN, codec); |
3785 | |||
3786 | if (wm8994->jackdet) | ||
3787 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_GPIO(6), wm8994); | ||
3519 | 3788 | ||
3520 | switch (control->type) { | 3789 | switch (control->type) { |
3521 | case WM8994: | 3790 | case WM8994: |
3522 | if (wm8994->micdet_irq) | 3791 | if (wm8994->micdet_irq) |
3523 | free_irq(wm8994->micdet_irq, wm8994); | 3792 | free_irq(wm8994->micdet_irq, wm8994); |
3524 | wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, | 3793 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC2_DET, |
3525 | wm8994); | 3794 | wm8994); |
3526 | wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, | 3795 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC1_SHRT, |
3527 | wm8994); | 3796 | wm8994); |
3528 | wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, | 3797 | wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC1_DET, |
3529 | wm8994); | 3798 | wm8994); |
3530 | break; | 3799 | break; |
3531 | 3800 | ||
@@ -3542,27 +3811,24 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) | |||
3542 | if (wm8994->enh_eq) | 3811 | if (wm8994->enh_eq) |
3543 | release_firmware(wm8994->enh_eq); | 3812 | release_firmware(wm8994->enh_eq); |
3544 | kfree(wm8994->retune_mobile_texts); | 3813 | kfree(wm8994->retune_mobile_texts); |
3545 | kfree(wm8994->drc_texts); | ||
3546 | kfree(wm8994); | ||
3547 | 3814 | ||
3548 | return 0; | 3815 | return 0; |
3549 | } | 3816 | } |
3550 | 3817 | ||
3818 | static int wm8994_soc_volatile(struct snd_soc_codec *codec, | ||
3819 | unsigned int reg) | ||
3820 | { | ||
3821 | return true; | ||
3822 | } | ||
3823 | |||
3551 | static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { | 3824 | static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { |
3552 | .probe = wm8994_codec_probe, | 3825 | .probe = wm8994_codec_probe, |
3553 | .remove = wm8994_codec_remove, | 3826 | .remove = wm8994_codec_remove, |
3554 | .suspend = wm8994_suspend, | 3827 | .suspend = wm8994_suspend, |
3555 | .resume = wm8994_resume, | 3828 | .resume = wm8994_resume, |
3556 | .read = wm8994_read, | ||
3557 | .write = wm8994_write, | ||
3558 | .readable_register = wm8994_readable, | ||
3559 | .volatile_register = wm8994_volatile, | ||
3560 | .set_bias_level = wm8994_set_bias_level, | 3829 | .set_bias_level = wm8994_set_bias_level, |
3561 | 3830 | .reg_cache_size = WM8994_MAX_REGISTER, | |
3562 | .reg_cache_size = WM8994_CACHE_SIZE, | 3831 | .volatile_register = wm8994_soc_volatile, |
3563 | .reg_cache_default = wm8994_reg_defaults, | ||
3564 | .reg_word_size = 2, | ||
3565 | .compress_type = SND_SOC_RBTREE_COMPRESSION, | ||
3566 | }; | 3832 | }; |
3567 | 3833 | ||
3568 | static int __devinit wm8994_probe(struct platform_device *pdev) | 3834 | static int __devinit wm8994_probe(struct platform_device *pdev) |
@@ -3586,18 +3852,7 @@ static struct platform_driver wm8994_codec_driver = { | |||
3586 | .remove = __devexit_p(wm8994_remove), | 3852 | .remove = __devexit_p(wm8994_remove), |
3587 | }; | 3853 | }; |
3588 | 3854 | ||
3589 | static __init int wm8994_init(void) | 3855 | module_platform_driver(wm8994_codec_driver); |
3590 | { | ||
3591 | return platform_driver_register(&wm8994_codec_driver); | ||
3592 | } | ||
3593 | module_init(wm8994_init); | ||
3594 | |||
3595 | static __exit void wm8994_exit(void) | ||
3596 | { | ||
3597 | platform_driver_unregister(&wm8994_codec_driver); | ||
3598 | } | ||
3599 | module_exit(wm8994_exit); | ||
3600 | |||
3601 | 3856 | ||
3602 | MODULE_DESCRIPTION("ASoC WM8994 driver"); | 3857 | MODULE_DESCRIPTION("ASoC WM8994 driver"); |
3603 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 3858 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |