diff options
Diffstat (limited to 'sound/soc/codecs/wm8996.c')
-rw-r--r-- | sound/soc/codecs/wm8996.c | 945 |
1 files changed, 524 insertions, 421 deletions
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index a33b04d17195..d8da10fe5b52 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/gcd.h> | 19 | #include <linux/gcd.h> |
20 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
21 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
22 | #include <linux/regmap.h> | ||
22 | #include <linux/regulator/consumer.h> | 23 | #include <linux/regulator/consumer.h> |
23 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
24 | #include <linux/workqueue.h> | 25 | #include <linux/workqueue.h> |
@@ -49,6 +50,8 @@ static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = { | |||
49 | }; | 50 | }; |
50 | 51 | ||
51 | struct wm8996_priv { | 52 | struct wm8996_priv { |
53 | struct device *dev; | ||
54 | struct regmap *regmap; | ||
52 | struct snd_soc_codec *codec; | 55 | struct snd_soc_codec *codec; |
53 | 56 | ||
54 | int ldo1ena; | 57 | int ldo1ena; |
@@ -105,7 +108,7 @@ static int wm8996_regulator_event_##n(struct notifier_block *nb, \ | |||
105 | struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \ | 108 | struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \ |
106 | disable_nb[n]); \ | 109 | disable_nb[n]); \ |
107 | if (event & REGULATOR_EVENT_DISABLE) { \ | 110 | if (event & REGULATOR_EVENT_DISABLE) { \ |
108 | wm8996->codec->cache_sync = 1; \ | 111 | regcache_cache_only(wm8996->regmap, true); \ |
109 | } \ | 112 | } \ |
110 | return 0; \ | 113 | return 0; \ |
111 | } | 114 | } |
@@ -114,297 +117,365 @@ WM8996_REGULATOR_EVENT(0) | |||
114 | WM8996_REGULATOR_EVENT(1) | 117 | WM8996_REGULATOR_EVENT(1) |
115 | WM8996_REGULATOR_EVENT(2) | 118 | WM8996_REGULATOR_EVENT(2) |
116 | 119 | ||
117 | static const u16 wm8996_reg[WM8996_MAX_REGISTER] = { | 120 | static struct reg_default wm8996_reg[] = { |
118 | [WM8996_SOFTWARE_RESET] = 0x8996, | 121 | { WM8996_SOFTWARE_RESET, 0x8996 }, |
119 | [WM8996_POWER_MANAGEMENT_7] = 0x10, | 122 | { WM8996_POWER_MANAGEMENT_1, 0x0 }, |
120 | [WM8996_DAC1_HPOUT1_VOLUME] = 0x88, | 123 | { WM8996_POWER_MANAGEMENT_2, 0x0 }, |
121 | [WM8996_DAC2_HPOUT2_VOLUME] = 0x88, | 124 | { WM8996_POWER_MANAGEMENT_3, 0x0 }, |
122 | [WM8996_DAC1_LEFT_VOLUME] = 0x2c0, | 125 | { WM8996_POWER_MANAGEMENT_4, 0x0 }, |
123 | [WM8996_DAC1_RIGHT_VOLUME] = 0x2c0, | 126 | { WM8996_POWER_MANAGEMENT_5, 0x0 }, |
124 | [WM8996_DAC2_LEFT_VOLUME] = 0x2c0, | 127 | { WM8996_POWER_MANAGEMENT_6, 0x0 }, |
125 | [WM8996_DAC2_RIGHT_VOLUME] = 0x2c0, | 128 | { WM8996_POWER_MANAGEMENT_7, 0x10 }, |
126 | [WM8996_OUTPUT1_LEFT_VOLUME] = 0x80, | 129 | { WM8996_POWER_MANAGEMENT_8, 0x0 }, |
127 | [WM8996_OUTPUT1_RIGHT_VOLUME] = 0x80, | 130 | { WM8996_LEFT_LINE_INPUT_VOLUME, 0x0 }, |
128 | [WM8996_OUTPUT2_LEFT_VOLUME] = 0x80, | 131 | { WM8996_RIGHT_LINE_INPUT_VOLUME, 0x0 }, |
129 | [WM8996_OUTPUT2_RIGHT_VOLUME] = 0x80, | 132 | { WM8996_LINE_INPUT_CONTROL, 0x0 }, |
130 | [WM8996_MICBIAS_1] = 0x39, | 133 | { WM8996_DAC1_HPOUT1_VOLUME, 0x88 }, |
131 | [WM8996_MICBIAS_2] = 0x39, | 134 | { WM8996_DAC2_HPOUT2_VOLUME, 0x88 }, |
132 | [WM8996_LDO_1] = 0x3, | 135 | { WM8996_DAC1_LEFT_VOLUME, 0x2c0 }, |
133 | [WM8996_LDO_2] = 0x13, | 136 | { WM8996_DAC1_RIGHT_VOLUME, 0x2c0 }, |
134 | [WM8996_ACCESSORY_DETECT_MODE_1] = 0x4, | 137 | { WM8996_DAC2_LEFT_VOLUME, 0x2c0 }, |
135 | [WM8996_HEADPHONE_DETECT_1] = 0x20, | 138 | { WM8996_DAC2_RIGHT_VOLUME, 0x2c0 }, |
136 | [WM8996_MIC_DETECT_1] = 0x7600, | 139 | { WM8996_OUTPUT1_LEFT_VOLUME, 0x80 }, |
137 | [WM8996_MIC_DETECT_2] = 0xbf, | 140 | { WM8996_OUTPUT1_RIGHT_VOLUME, 0x80 }, |
138 | [WM8996_CHARGE_PUMP_1] = 0x1f25, | 141 | { WM8996_OUTPUT2_LEFT_VOLUME, 0x80 }, |
139 | [WM8996_CHARGE_PUMP_2] = 0xab19, | 142 | { WM8996_OUTPUT2_RIGHT_VOLUME, 0x80 }, |
140 | [WM8996_DC_SERVO_5] = 0x2a2a, | 143 | { WM8996_MICBIAS_1, 0x39 }, |
141 | [WM8996_CONTROL_INTERFACE_1] = 0x8004, | 144 | { WM8996_MICBIAS_2, 0x39 }, |
142 | [WM8996_CLOCKING_1] = 0x10, | 145 | { WM8996_LDO_1, 0x3 }, |
143 | [WM8996_AIF_RATE] = 0x83, | 146 | { WM8996_LDO_2, 0x13 }, |
144 | [WM8996_FLL_CONTROL_4] = 0x5dc0, | 147 | { WM8996_ACCESSORY_DETECT_MODE_1, 0x4 }, |
145 | [WM8996_FLL_CONTROL_5] = 0xc84, | 148 | { WM8996_ACCESSORY_DETECT_MODE_2, 0x0 }, |
146 | [WM8996_FLL_EFS_2] = 0x2, | 149 | { WM8996_HEADPHONE_DETECT_1, 0x20 }, |
147 | [WM8996_AIF1_TX_LRCLK_1] = 0x80, | 150 | { WM8996_HEADPHONE_DETECT_2, 0x0 }, |
148 | [WM8996_AIF1_TX_LRCLK_2] = 0x8, | 151 | { WM8996_MIC_DETECT_1, 0x7600 }, |
149 | [WM8996_AIF1_RX_LRCLK_1] = 0x80, | 152 | { WM8996_MIC_DETECT_2, 0xbf }, |
150 | [WM8996_AIF1TX_DATA_CONFIGURATION_1] = 0x1818, | 153 | { WM8996_CHARGE_PUMP_1, 0x1f25 }, |
151 | [WM8996_AIF1RX_DATA_CONFIGURATION] = 0x1818, | 154 | { WM8996_CHARGE_PUMP_2, 0xab19 }, |
152 | [WM8996_AIF1TX_TEST] = 0x7, | 155 | { WM8996_DC_SERVO_1, 0x0 }, |
153 | [WM8996_AIF2_TX_LRCLK_1] = 0x80, | 156 | { WM8996_DC_SERVO_2, 0x0 }, |
154 | [WM8996_AIF2_TX_LRCLK_2] = 0x8, | 157 | { WM8996_DC_SERVO_3, 0x0 }, |
155 | [WM8996_AIF2_RX_LRCLK_1] = 0x80, | 158 | { WM8996_DC_SERVO_5, 0x2a2a }, |
156 | [WM8996_AIF2TX_DATA_CONFIGURATION_1] = 0x1818, | 159 | { WM8996_DC_SERVO_6, 0x0 }, |
157 | [WM8996_AIF2RX_DATA_CONFIGURATION] = 0x1818, | 160 | { WM8996_DC_SERVO_7, 0x0 }, |
158 | [WM8996_AIF2TX_TEST] = 0x1, | 161 | { WM8996_ANALOGUE_HP_1, 0x0 }, |
159 | [WM8996_DSP1_TX_LEFT_VOLUME] = 0xc0, | 162 | { WM8996_ANALOGUE_HP_2, 0x0 }, |
160 | [WM8996_DSP1_TX_RIGHT_VOLUME] = 0xc0, | 163 | { WM8996_CONTROL_INTERFACE_1, 0x8004 }, |
161 | [WM8996_DSP1_RX_LEFT_VOLUME] = 0xc0, | 164 | { WM8996_WRITE_SEQUENCER_CTRL_1, 0x0 }, |
162 | [WM8996_DSP1_RX_RIGHT_VOLUME] = 0xc0, | 165 | { WM8996_WRITE_SEQUENCER_CTRL_2, 0x0 }, |
163 | [WM8996_DSP1_TX_FILTERS] = 0x2000, | 166 | { WM8996_AIF_CLOCKING_1, 0x0 }, |
164 | [WM8996_DSP1_RX_FILTERS_1] = 0x200, | 167 | { WM8996_AIF_CLOCKING_2, 0x0 }, |
165 | [WM8996_DSP1_RX_FILTERS_2] = 0x10, | 168 | { WM8996_CLOCKING_1, 0x10 }, |
166 | [WM8996_DSP1_DRC_1] = 0x98, | 169 | { WM8996_CLOCKING_2, 0x0 }, |
167 | [WM8996_DSP1_DRC_2] = 0x845, | 170 | { WM8996_AIF_RATE, 0x83 }, |
168 | [WM8996_DSP1_RX_EQ_GAINS_1] = 0x6318, | 171 | { WM8996_FLL_CONTROL_1, 0x0 }, |
169 | [WM8996_DSP1_RX_EQ_GAINS_2] = 0x6300, | 172 | { WM8996_FLL_CONTROL_2, 0x0 }, |
170 | [WM8996_DSP1_RX_EQ_BAND_1_A] = 0xfca, | 173 | { WM8996_FLL_CONTROL_3, 0x0 }, |
171 | [WM8996_DSP1_RX_EQ_BAND_1_B] = 0x400, | 174 | { WM8996_FLL_CONTROL_4, 0x5dc0 }, |
172 | [WM8996_DSP1_RX_EQ_BAND_1_PG] = 0xd8, | 175 | { WM8996_FLL_CONTROL_5, 0xc84 }, |
173 | [WM8996_DSP1_RX_EQ_BAND_2_A] = 0x1eb5, | 176 | { WM8996_FLL_EFS_1, 0x0 }, |
174 | [WM8996_DSP1_RX_EQ_BAND_2_B] = 0xf145, | 177 | { WM8996_FLL_EFS_2, 0x2 }, |
175 | [WM8996_DSP1_RX_EQ_BAND_2_C] = 0xb75, | 178 | { WM8996_AIF1_CONTROL, 0x0 }, |
176 | [WM8996_DSP1_RX_EQ_BAND_2_PG] = 0x1c5, | 179 | { WM8996_AIF1_BCLK, 0x0 }, |
177 | [WM8996_DSP1_RX_EQ_BAND_3_A] = 0x1c58, | 180 | { WM8996_AIF1_TX_LRCLK_1, 0x80 }, |
178 | [WM8996_DSP1_RX_EQ_BAND_3_B] = 0xf373, | 181 | { WM8996_AIF1_TX_LRCLK_2, 0x8 }, |
179 | [WM8996_DSP1_RX_EQ_BAND_3_C] = 0xa54, | 182 | { WM8996_AIF1_RX_LRCLK_1, 0x80 }, |
180 | [WM8996_DSP1_RX_EQ_BAND_3_PG] = 0x558, | 183 | { WM8996_AIF1_RX_LRCLK_2, 0x0 }, |
181 | [WM8996_DSP1_RX_EQ_BAND_4_A] = 0x168e, | 184 | { WM8996_AIF1TX_DATA_CONFIGURATION_1, 0x1818 }, |
182 | [WM8996_DSP1_RX_EQ_BAND_4_B] = 0xf829, | 185 | { WM8996_AIF1TX_DATA_CONFIGURATION_2, 0 }, |
183 | [WM8996_DSP1_RX_EQ_BAND_4_C] = 0x7ad, | 186 | { WM8996_AIF1RX_DATA_CONFIGURATION, 0x1818 }, |
184 | [WM8996_DSP1_RX_EQ_BAND_4_PG] = 0x1103, | 187 | { WM8996_AIF1TX_CHANNEL_0_CONFIGURATION, 0x0 }, |
185 | [WM8996_DSP1_RX_EQ_BAND_5_A] = 0x564, | 188 | { WM8996_AIF1TX_CHANNEL_1_CONFIGURATION, 0x0 }, |
186 | [WM8996_DSP1_RX_EQ_BAND_5_B] = 0x559, | 189 | { WM8996_AIF1TX_CHANNEL_2_CONFIGURATION, 0x0 }, |
187 | [WM8996_DSP1_RX_EQ_BAND_5_PG] = 0x4000, | 190 | { WM8996_AIF1TX_CHANNEL_3_CONFIGURATION, 0x0 }, |
188 | [WM8996_DSP2_TX_LEFT_VOLUME] = 0xc0, | 191 | { WM8996_AIF1TX_CHANNEL_4_CONFIGURATION, 0x0 }, |
189 | [WM8996_DSP2_TX_RIGHT_VOLUME] = 0xc0, | 192 | { WM8996_AIF1TX_CHANNEL_5_CONFIGURATION, 0x0 }, |
190 | [WM8996_DSP2_RX_LEFT_VOLUME] = 0xc0, | 193 | { WM8996_AIF1RX_CHANNEL_0_CONFIGURATION, 0x0 }, |
191 | [WM8996_DSP2_RX_RIGHT_VOLUME] = 0xc0, | 194 | { WM8996_AIF1RX_CHANNEL_1_CONFIGURATION, 0x0 }, |
192 | [WM8996_DSP2_TX_FILTERS] = 0x2000, | 195 | { WM8996_AIF1RX_CHANNEL_2_CONFIGURATION, 0x0 }, |
193 | [WM8996_DSP2_RX_FILTERS_1] = 0x200, | 196 | { WM8996_AIF1RX_CHANNEL_3_CONFIGURATION, 0x0 }, |
194 | [WM8996_DSP2_RX_FILTERS_2] = 0x10, | 197 | { WM8996_AIF1RX_CHANNEL_4_CONFIGURATION, 0x0 }, |
195 | [WM8996_DSP2_DRC_1] = 0x98, | 198 | { WM8996_AIF1RX_CHANNEL_5_CONFIGURATION, 0x0 }, |
196 | [WM8996_DSP2_DRC_2] = 0x845, | 199 | { WM8996_AIF1RX_MONO_CONFIGURATION, 0x0 }, |
197 | [WM8996_DSP2_RX_EQ_GAINS_1] = 0x6318, | 200 | { WM8996_AIF1TX_TEST, 0x7 }, |
198 | [WM8996_DSP2_RX_EQ_GAINS_2] = 0x6300, | 201 | { WM8996_AIF2_CONTROL, 0x0 }, |
199 | [WM8996_DSP2_RX_EQ_BAND_1_A] = 0xfca, | 202 | { WM8996_AIF2_BCLK, 0x0 }, |
200 | [WM8996_DSP2_RX_EQ_BAND_1_B] = 0x400, | 203 | { WM8996_AIF2_TX_LRCLK_1, 0x80 }, |
201 | [WM8996_DSP2_RX_EQ_BAND_1_PG] = 0xd8, | 204 | { WM8996_AIF2_TX_LRCLK_2, 0x8 }, |
202 | [WM8996_DSP2_RX_EQ_BAND_2_A] = 0x1eb5, | 205 | { WM8996_AIF2_RX_LRCLK_1, 0x80 }, |
203 | [WM8996_DSP2_RX_EQ_BAND_2_B] = 0xf145, | 206 | { WM8996_AIF2_RX_LRCLK_2, 0x0 }, |
204 | [WM8996_DSP2_RX_EQ_BAND_2_C] = 0xb75, | 207 | { WM8996_AIF2TX_DATA_CONFIGURATION_1, 0x1818 }, |
205 | [WM8996_DSP2_RX_EQ_BAND_2_PG] = 0x1c5, | 208 | { WM8996_AIF2RX_DATA_CONFIGURATION, 0x1818 }, |
206 | [WM8996_DSP2_RX_EQ_BAND_3_A] = 0x1c58, | 209 | { WM8996_AIF2RX_DATA_CONFIGURATION, 0x0 }, |
207 | [WM8996_DSP2_RX_EQ_BAND_3_B] = 0xf373, | 210 | { WM8996_AIF2TX_CHANNEL_0_CONFIGURATION, 0x0 }, |
208 | [WM8996_DSP2_RX_EQ_BAND_3_C] = 0xa54, | 211 | { WM8996_AIF2TX_CHANNEL_1_CONFIGURATION, 0x0 }, |
209 | [WM8996_DSP2_RX_EQ_BAND_3_PG] = 0x558, | 212 | { WM8996_AIF2RX_CHANNEL_0_CONFIGURATION, 0x0 }, |
210 | [WM8996_DSP2_RX_EQ_BAND_4_A] = 0x168e, | 213 | { WM8996_AIF2RX_CHANNEL_1_CONFIGURATION, 0x0 }, |
211 | [WM8996_DSP2_RX_EQ_BAND_4_B] = 0xf829, | 214 | { WM8996_AIF2RX_MONO_CONFIGURATION, 0x0 }, |
212 | [WM8996_DSP2_RX_EQ_BAND_4_C] = 0x7ad, | 215 | { WM8996_AIF2TX_TEST, 0x1 }, |
213 | [WM8996_DSP2_RX_EQ_BAND_4_PG] = 0x1103, | 216 | { WM8996_DSP1_TX_LEFT_VOLUME, 0xc0 }, |
214 | [WM8996_DSP2_RX_EQ_BAND_5_A] = 0x564, | 217 | { WM8996_DSP1_TX_RIGHT_VOLUME, 0xc0 }, |
215 | [WM8996_DSP2_RX_EQ_BAND_5_B] = 0x559, | 218 | { WM8996_DSP1_RX_LEFT_VOLUME, 0xc0 }, |
216 | [WM8996_DSP2_RX_EQ_BAND_5_PG] = 0x4000, | 219 | { WM8996_DSP1_RX_RIGHT_VOLUME, 0xc0 }, |
217 | [WM8996_OVERSAMPLING] = 0xd, | 220 | { WM8996_DSP1_TX_FILTERS, 0x2000 }, |
218 | [WM8996_SIDETONE] = 0x1040, | 221 | { WM8996_DSP1_RX_FILTERS_1, 0x200 }, |
219 | [WM8996_GPIO_1] = 0xa101, | 222 | { WM8996_DSP1_RX_FILTERS_2, 0x10 }, |
220 | [WM8996_GPIO_2] = 0xa101, | 223 | { WM8996_DSP1_DRC_1, 0x98 }, |
221 | [WM8996_GPIO_3] = 0xa101, | 224 | { WM8996_DSP1_DRC_2, 0x845 }, |
222 | [WM8996_GPIO_4] = 0xa101, | 225 | { WM8996_DSP1_RX_EQ_GAINS_1, 0x6318 }, |
223 | [WM8996_GPIO_5] = 0xa101, | 226 | { WM8996_DSP1_RX_EQ_GAINS_2, 0x6300 }, |
224 | [WM8996_PULL_CONTROL_2] = 0x140, | 227 | { WM8996_DSP1_RX_EQ_BAND_1_A, 0xfca }, |
225 | [WM8996_INTERRUPT_STATUS_1_MASK] = 0x1f, | 228 | { WM8996_DSP1_RX_EQ_BAND_1_B, 0x400 }, |
226 | [WM8996_INTERRUPT_STATUS_2_MASK] = 0x1ecf, | 229 | { WM8996_DSP1_RX_EQ_BAND_1_PG, 0xd8 }, |
227 | [WM8996_RIGHT_PDM_SPEAKER] = 0x1, | 230 | { WM8996_DSP1_RX_EQ_BAND_2_A, 0x1eb5 }, |
228 | [WM8996_PDM_SPEAKER_MUTE_SEQUENCE] = 0x69, | 231 | { WM8996_DSP1_RX_EQ_BAND_2_B, 0xf145 }, |
229 | [WM8996_PDM_SPEAKER_VOLUME] = 0x66, | 232 | { WM8996_DSP1_RX_EQ_BAND_2_C, 0xb75 }, |
230 | [WM8996_WRITE_SEQUENCER_0] = 0x1, | 233 | { WM8996_DSP1_RX_EQ_BAND_2_PG, 0x1c5 }, |
231 | [WM8996_WRITE_SEQUENCER_1] = 0x1, | 234 | { WM8996_DSP1_RX_EQ_BAND_3_A, 0x1c58 }, |
232 | [WM8996_WRITE_SEQUENCER_3] = 0x6, | 235 | { WM8996_DSP1_RX_EQ_BAND_3_B, 0xf373 }, |
233 | [WM8996_WRITE_SEQUENCER_4] = 0x40, | 236 | { WM8996_DSP1_RX_EQ_BAND_3_C, 0xa54 }, |
234 | [WM8996_WRITE_SEQUENCER_5] = 0x1, | 237 | { WM8996_DSP1_RX_EQ_BAND_3_PG, 0x558 }, |
235 | [WM8996_WRITE_SEQUENCER_6] = 0xf, | 238 | { WM8996_DSP1_RX_EQ_BAND_4_A, 0x168e }, |
236 | [WM8996_WRITE_SEQUENCER_7] = 0x6, | 239 | { WM8996_DSP1_RX_EQ_BAND_4_B, 0xf829 }, |
237 | [WM8996_WRITE_SEQUENCER_8] = 0x1, | 240 | { WM8996_DSP1_RX_EQ_BAND_4_C, 0x7ad }, |
238 | [WM8996_WRITE_SEQUENCER_9] = 0x3, | 241 | { WM8996_DSP1_RX_EQ_BAND_4_PG, 0x1103 }, |
239 | [WM8996_WRITE_SEQUENCER_10] = 0x104, | 242 | { WM8996_DSP1_RX_EQ_BAND_5_A, 0x564 }, |
240 | [WM8996_WRITE_SEQUENCER_12] = 0x60, | 243 | { WM8996_DSP1_RX_EQ_BAND_5_B, 0x559 }, |
241 | [WM8996_WRITE_SEQUENCER_13] = 0x11, | 244 | { WM8996_DSP1_RX_EQ_BAND_5_PG, 0x4000 }, |
242 | [WM8996_WRITE_SEQUENCER_14] = 0x401, | 245 | { WM8996_DSP2_TX_LEFT_VOLUME, 0xc0 }, |
243 | [WM8996_WRITE_SEQUENCER_16] = 0x50, | 246 | { WM8996_DSP2_TX_RIGHT_VOLUME, 0xc0 }, |
244 | [WM8996_WRITE_SEQUENCER_17] = 0x3, | 247 | { WM8996_DSP2_RX_LEFT_VOLUME, 0xc0 }, |
245 | [WM8996_WRITE_SEQUENCER_18] = 0x100, | 248 | { WM8996_DSP2_RX_RIGHT_VOLUME, 0xc0 }, |
246 | [WM8996_WRITE_SEQUENCER_20] = 0x51, | 249 | { WM8996_DSP2_TX_FILTERS, 0x2000 }, |
247 | [WM8996_WRITE_SEQUENCER_21] = 0x3, | 250 | { WM8996_DSP2_RX_FILTERS_1, 0x200 }, |
248 | [WM8996_WRITE_SEQUENCER_22] = 0x104, | 251 | { WM8996_DSP2_RX_FILTERS_2, 0x10 }, |
249 | [WM8996_WRITE_SEQUENCER_23] = 0xa, | 252 | { WM8996_DSP2_DRC_1, 0x98 }, |
250 | [WM8996_WRITE_SEQUENCER_24] = 0x60, | 253 | { WM8996_DSP2_DRC_2, 0x845 }, |
251 | [WM8996_WRITE_SEQUENCER_25] = 0x3b, | 254 | { WM8996_DSP2_RX_EQ_GAINS_1, 0x6318 }, |
252 | [WM8996_WRITE_SEQUENCER_26] = 0x502, | 255 | { WM8996_DSP2_RX_EQ_GAINS_2, 0x6300 }, |
253 | [WM8996_WRITE_SEQUENCER_27] = 0x100, | 256 | { WM8996_DSP2_RX_EQ_BAND_1_A, 0xfca }, |
254 | [WM8996_WRITE_SEQUENCER_28] = 0x2fff, | 257 | { WM8996_DSP2_RX_EQ_BAND_1_B, 0x400 }, |
255 | [WM8996_WRITE_SEQUENCER_32] = 0x2fff, | 258 | { WM8996_DSP2_RX_EQ_BAND_1_PG, 0xd8 }, |
256 | [WM8996_WRITE_SEQUENCER_36] = 0x2fff, | 259 | { WM8996_DSP2_RX_EQ_BAND_2_A, 0x1eb5 }, |
257 | [WM8996_WRITE_SEQUENCER_40] = 0x2fff, | 260 | { WM8996_DSP2_RX_EQ_BAND_2_B, 0xf145 }, |
258 | [WM8996_WRITE_SEQUENCER_44] = 0x2fff, | 261 | { WM8996_DSP2_RX_EQ_BAND_2_C, 0xb75 }, |
259 | [WM8996_WRITE_SEQUENCER_48] = 0x2fff, | 262 | { WM8996_DSP2_RX_EQ_BAND_2_PG, 0x1c5 }, |
260 | [WM8996_WRITE_SEQUENCER_52] = 0x2fff, | 263 | { WM8996_DSP2_RX_EQ_BAND_3_A, 0x1c58 }, |
261 | [WM8996_WRITE_SEQUENCER_56] = 0x2fff, | 264 | { WM8996_DSP2_RX_EQ_BAND_3_B, 0xf373 }, |
262 | [WM8996_WRITE_SEQUENCER_60] = 0x2fff, | 265 | { WM8996_DSP2_RX_EQ_BAND_3_C, 0xa54 }, |
263 | [WM8996_WRITE_SEQUENCER_64] = 0x1, | 266 | { WM8996_DSP2_RX_EQ_BAND_3_PG, 0x558 }, |
264 | [WM8996_WRITE_SEQUENCER_65] = 0x1, | 267 | { WM8996_DSP2_RX_EQ_BAND_4_A, 0x168e }, |
265 | [WM8996_WRITE_SEQUENCER_67] = 0x6, | 268 | { WM8996_DSP2_RX_EQ_BAND_4_B, 0xf829 }, |
266 | [WM8996_WRITE_SEQUENCER_68] = 0x40, | 269 | { WM8996_DSP2_RX_EQ_BAND_4_C, 0x7ad }, |
267 | [WM8996_WRITE_SEQUENCER_69] = 0x1, | 270 | { WM8996_DSP2_RX_EQ_BAND_4_PG, 0x1103 }, |
268 | [WM8996_WRITE_SEQUENCER_70] = 0xf, | 271 | { WM8996_DSP2_RX_EQ_BAND_5_A, 0x564 }, |
269 | [WM8996_WRITE_SEQUENCER_71] = 0x6, | 272 | { WM8996_DSP2_RX_EQ_BAND_5_B, 0x559 }, |
270 | [WM8996_WRITE_SEQUENCER_72] = 0x1, | 273 | { WM8996_DSP2_RX_EQ_BAND_5_PG, 0x4000 }, |
271 | [WM8996_WRITE_SEQUENCER_73] = 0x3, | 274 | { WM8996_DAC1_MIXER_VOLUMES, 0x0 }, |
272 | [WM8996_WRITE_SEQUENCER_74] = 0x104, | 275 | { WM8996_DAC1_LEFT_MIXER_ROUTING, 0x0 }, |
273 | [WM8996_WRITE_SEQUENCER_76] = 0x60, | 276 | { WM8996_DAC1_RIGHT_MIXER_ROUTING, 0x0 }, |
274 | [WM8996_WRITE_SEQUENCER_77] = 0x11, | 277 | { WM8996_DAC2_MIXER_VOLUMES, 0x0 }, |
275 | [WM8996_WRITE_SEQUENCER_78] = 0x401, | 278 | { WM8996_DAC2_LEFT_MIXER_ROUTING, 0x0 }, |
276 | [WM8996_WRITE_SEQUENCER_80] = 0x50, | 279 | { WM8996_DAC2_RIGHT_MIXER_ROUTING, 0x0 }, |
277 | [WM8996_WRITE_SEQUENCER_81] = 0x3, | 280 | { WM8996_DSP1_TX_LEFT_MIXER_ROUTING, 0x0 }, |
278 | [WM8996_WRITE_SEQUENCER_82] = 0x100, | 281 | { WM8996_DSP1_TX_RIGHT_MIXER_ROUTING, 0x0 }, |
279 | [WM8996_WRITE_SEQUENCER_84] = 0x60, | 282 | { WM8996_DSP2_TX_LEFT_MIXER_ROUTING, 0x0 }, |
280 | [WM8996_WRITE_SEQUENCER_85] = 0x3b, | 283 | { WM8996_DSP2_TX_RIGHT_MIXER_ROUTING, 0x0 }, |
281 | [WM8996_WRITE_SEQUENCER_86] = 0x502, | 284 | { WM8996_DSP_TX_MIXER_SELECT, 0x0 }, |
282 | [WM8996_WRITE_SEQUENCER_87] = 0x100, | 285 | { WM8996_DAC_SOFTMUTE, 0x0 }, |
283 | [WM8996_WRITE_SEQUENCER_88] = 0x2fff, | 286 | { WM8996_OVERSAMPLING, 0xd }, |
284 | [WM8996_WRITE_SEQUENCER_92] = 0x2fff, | 287 | { WM8996_SIDETONE, 0x1040 }, |
285 | [WM8996_WRITE_SEQUENCER_96] = 0x2fff, | 288 | { WM8996_GPIO_1, 0xa101 }, |
286 | [WM8996_WRITE_SEQUENCER_100] = 0x2fff, | 289 | { WM8996_GPIO_2, 0xa101 }, |
287 | [WM8996_WRITE_SEQUENCER_104] = 0x2fff, | 290 | { WM8996_GPIO_3, 0xa101 }, |
288 | [WM8996_WRITE_SEQUENCER_108] = 0x2fff, | 291 | { WM8996_GPIO_4, 0xa101 }, |
289 | [WM8996_WRITE_SEQUENCER_112] = 0x2fff, | 292 | { WM8996_GPIO_5, 0xa101 }, |
290 | [WM8996_WRITE_SEQUENCER_116] = 0x2fff, | 293 | { WM8996_PULL_CONTROL_1, 0x0 }, |
291 | [WM8996_WRITE_SEQUENCER_120] = 0x2fff, | 294 | { WM8996_PULL_CONTROL_2, 0x140 }, |
292 | [WM8996_WRITE_SEQUENCER_124] = 0x2fff, | 295 | { WM8996_INTERRUPT_STATUS_1_MASK, 0x1f }, |
293 | [WM8996_WRITE_SEQUENCER_128] = 0x1, | 296 | { WM8996_INTERRUPT_STATUS_2_MASK, 0x1ecf }, |
294 | [WM8996_WRITE_SEQUENCER_129] = 0x1, | 297 | { WM8996_LEFT_PDM_SPEAKER, 0x0 }, |
295 | [WM8996_WRITE_SEQUENCER_131] = 0x6, | 298 | { WM8996_RIGHT_PDM_SPEAKER, 0x1 }, |
296 | [WM8996_WRITE_SEQUENCER_132] = 0x40, | 299 | { WM8996_PDM_SPEAKER_MUTE_SEQUENCE, 0x69 }, |
297 | [WM8996_WRITE_SEQUENCER_133] = 0x1, | 300 | { WM8996_PDM_SPEAKER_VOLUME, 0x66 }, |
298 | [WM8996_WRITE_SEQUENCER_134] = 0xf, | 301 | { WM8996_WRITE_SEQUENCER_0, 0x1 }, |
299 | [WM8996_WRITE_SEQUENCER_135] = 0x6, | 302 | { WM8996_WRITE_SEQUENCER_1, 0x1 }, |
300 | [WM8996_WRITE_SEQUENCER_136] = 0x1, | 303 | { WM8996_WRITE_SEQUENCER_3, 0x6 }, |
301 | [WM8996_WRITE_SEQUENCER_137] = 0x3, | 304 | { WM8996_WRITE_SEQUENCER_4, 0x40 }, |
302 | [WM8996_WRITE_SEQUENCER_138] = 0x106, | 305 | { WM8996_WRITE_SEQUENCER_5, 0x1 }, |
303 | [WM8996_WRITE_SEQUENCER_140] = 0x61, | 306 | { WM8996_WRITE_SEQUENCER_6, 0xf }, |
304 | [WM8996_WRITE_SEQUENCER_141] = 0x11, | 307 | { WM8996_WRITE_SEQUENCER_7, 0x6 }, |
305 | [WM8996_WRITE_SEQUENCER_142] = 0x401, | 308 | { WM8996_WRITE_SEQUENCER_8, 0x1 }, |
306 | [WM8996_WRITE_SEQUENCER_144] = 0x50, | 309 | { WM8996_WRITE_SEQUENCER_9, 0x3 }, |
307 | [WM8996_WRITE_SEQUENCER_145] = 0x3, | 310 | { WM8996_WRITE_SEQUENCER_10, 0x104 }, |
308 | [WM8996_WRITE_SEQUENCER_146] = 0x102, | 311 | { WM8996_WRITE_SEQUENCER_12, 0x60 }, |
309 | [WM8996_WRITE_SEQUENCER_148] = 0x51, | 312 | { WM8996_WRITE_SEQUENCER_13, 0x11 }, |
310 | [WM8996_WRITE_SEQUENCER_149] = 0x3, | 313 | { WM8996_WRITE_SEQUENCER_14, 0x401 }, |
311 | [WM8996_WRITE_SEQUENCER_150] = 0x106, | 314 | { WM8996_WRITE_SEQUENCER_16, 0x50 }, |
312 | [WM8996_WRITE_SEQUENCER_151] = 0xa, | 315 | { WM8996_WRITE_SEQUENCER_17, 0x3 }, |
313 | [WM8996_WRITE_SEQUENCER_152] = 0x61, | 316 | { WM8996_WRITE_SEQUENCER_18, 0x100 }, |
314 | [WM8996_WRITE_SEQUENCER_153] = 0x3b, | 317 | { WM8996_WRITE_SEQUENCER_20, 0x51 }, |
315 | [WM8996_WRITE_SEQUENCER_154] = 0x502, | 318 | { WM8996_WRITE_SEQUENCER_21, 0x3 }, |
316 | [WM8996_WRITE_SEQUENCER_155] = 0x100, | 319 | { WM8996_WRITE_SEQUENCER_22, 0x104 }, |
317 | [WM8996_WRITE_SEQUENCER_156] = 0x2fff, | 320 | { WM8996_WRITE_SEQUENCER_23, 0xa }, |
318 | [WM8996_WRITE_SEQUENCER_160] = 0x2fff, | 321 | { WM8996_WRITE_SEQUENCER_24, 0x60 }, |
319 | [WM8996_WRITE_SEQUENCER_164] = 0x2fff, | 322 | { WM8996_WRITE_SEQUENCER_25, 0x3b }, |
320 | [WM8996_WRITE_SEQUENCER_168] = 0x2fff, | 323 | { WM8996_WRITE_SEQUENCER_26, 0x502 }, |
321 | [WM8996_WRITE_SEQUENCER_172] = 0x2fff, | 324 | { WM8996_WRITE_SEQUENCER_27, 0x100 }, |
322 | [WM8996_WRITE_SEQUENCER_176] = 0x2fff, | 325 | { WM8996_WRITE_SEQUENCER_28, 0x2fff }, |
323 | [WM8996_WRITE_SEQUENCER_180] = 0x2fff, | 326 | { WM8996_WRITE_SEQUENCER_32, 0x2fff }, |
324 | [WM8996_WRITE_SEQUENCER_184] = 0x2fff, | 327 | { WM8996_WRITE_SEQUENCER_36, 0x2fff }, |
325 | [WM8996_WRITE_SEQUENCER_188] = 0x2fff, | 328 | { WM8996_WRITE_SEQUENCER_40, 0x2fff }, |
326 | [WM8996_WRITE_SEQUENCER_192] = 0x1, | 329 | { WM8996_WRITE_SEQUENCER_44, 0x2fff }, |
327 | [WM8996_WRITE_SEQUENCER_193] = 0x1, | 330 | { WM8996_WRITE_SEQUENCER_48, 0x2fff }, |
328 | [WM8996_WRITE_SEQUENCER_195] = 0x6, | 331 | { WM8996_WRITE_SEQUENCER_52, 0x2fff }, |
329 | [WM8996_WRITE_SEQUENCER_196] = 0x40, | 332 | { WM8996_WRITE_SEQUENCER_56, 0x2fff }, |
330 | [WM8996_WRITE_SEQUENCER_197] = 0x1, | 333 | { WM8996_WRITE_SEQUENCER_60, 0x2fff }, |
331 | [WM8996_WRITE_SEQUENCER_198] = 0xf, | 334 | { WM8996_WRITE_SEQUENCER_64, 0x1 }, |
332 | [WM8996_WRITE_SEQUENCER_199] = 0x6, | 335 | { WM8996_WRITE_SEQUENCER_65, 0x1 }, |
333 | [WM8996_WRITE_SEQUENCER_200] = 0x1, | 336 | { WM8996_WRITE_SEQUENCER_67, 0x6 }, |
334 | [WM8996_WRITE_SEQUENCER_201] = 0x3, | 337 | { WM8996_WRITE_SEQUENCER_68, 0x40 }, |
335 | [WM8996_WRITE_SEQUENCER_202] = 0x106, | 338 | { WM8996_WRITE_SEQUENCER_69, 0x1 }, |
336 | [WM8996_WRITE_SEQUENCER_204] = 0x61, | 339 | { WM8996_WRITE_SEQUENCER_70, 0xf }, |
337 | [WM8996_WRITE_SEQUENCER_205] = 0x11, | 340 | { WM8996_WRITE_SEQUENCER_71, 0x6 }, |
338 | [WM8996_WRITE_SEQUENCER_206] = 0x401, | 341 | { WM8996_WRITE_SEQUENCER_72, 0x1 }, |
339 | [WM8996_WRITE_SEQUENCER_208] = 0x50, | 342 | { WM8996_WRITE_SEQUENCER_73, 0x3 }, |
340 | [WM8996_WRITE_SEQUENCER_209] = 0x3, | 343 | { WM8996_WRITE_SEQUENCER_74, 0x104 }, |
341 | [WM8996_WRITE_SEQUENCER_210] = 0x102, | 344 | { WM8996_WRITE_SEQUENCER_76, 0x60 }, |
342 | [WM8996_WRITE_SEQUENCER_212] = 0x61, | 345 | { WM8996_WRITE_SEQUENCER_77, 0x11 }, |
343 | [WM8996_WRITE_SEQUENCER_213] = 0x3b, | 346 | { WM8996_WRITE_SEQUENCER_78, 0x401 }, |
344 | [WM8996_WRITE_SEQUENCER_214] = 0x502, | 347 | { WM8996_WRITE_SEQUENCER_80, 0x50 }, |
345 | [WM8996_WRITE_SEQUENCER_215] = 0x100, | 348 | { WM8996_WRITE_SEQUENCER_81, 0x3 }, |
346 | [WM8996_WRITE_SEQUENCER_216] = 0x2fff, | 349 | { WM8996_WRITE_SEQUENCER_82, 0x100 }, |
347 | [WM8996_WRITE_SEQUENCER_220] = 0x2fff, | 350 | { WM8996_WRITE_SEQUENCER_84, 0x60 }, |
348 | [WM8996_WRITE_SEQUENCER_224] = 0x2fff, | 351 | { WM8996_WRITE_SEQUENCER_85, 0x3b }, |
349 | [WM8996_WRITE_SEQUENCER_228] = 0x2fff, | 352 | { WM8996_WRITE_SEQUENCER_86, 0x502 }, |
350 | [WM8996_WRITE_SEQUENCER_232] = 0x2fff, | 353 | { WM8996_WRITE_SEQUENCER_87, 0x100 }, |
351 | [WM8996_WRITE_SEQUENCER_236] = 0x2fff, | 354 | { WM8996_WRITE_SEQUENCER_88, 0x2fff }, |
352 | [WM8996_WRITE_SEQUENCER_240] = 0x2fff, | 355 | { WM8996_WRITE_SEQUENCER_92, 0x2fff }, |
353 | [WM8996_WRITE_SEQUENCER_244] = 0x2fff, | 356 | { WM8996_WRITE_SEQUENCER_96, 0x2fff }, |
354 | [WM8996_WRITE_SEQUENCER_248] = 0x2fff, | 357 | { WM8996_WRITE_SEQUENCER_100, 0x2fff }, |
355 | [WM8996_WRITE_SEQUENCER_252] = 0x2fff, | 358 | { WM8996_WRITE_SEQUENCER_104, 0x2fff }, |
356 | [WM8996_WRITE_SEQUENCER_256] = 0x60, | 359 | { WM8996_WRITE_SEQUENCER_108, 0x2fff }, |
357 | [WM8996_WRITE_SEQUENCER_258] = 0x601, | 360 | { WM8996_WRITE_SEQUENCER_112, 0x2fff }, |
358 | [WM8996_WRITE_SEQUENCER_260] = 0x50, | 361 | { WM8996_WRITE_SEQUENCER_116, 0x2fff }, |
359 | [WM8996_WRITE_SEQUENCER_262] = 0x100, | 362 | { WM8996_WRITE_SEQUENCER_120, 0x2fff }, |
360 | [WM8996_WRITE_SEQUENCER_264] = 0x1, | 363 | { WM8996_WRITE_SEQUENCER_124, 0x2fff }, |
361 | [WM8996_WRITE_SEQUENCER_266] = 0x104, | 364 | { WM8996_WRITE_SEQUENCER_128, 0x1 }, |
362 | [WM8996_WRITE_SEQUENCER_267] = 0x100, | 365 | { WM8996_WRITE_SEQUENCER_129, 0x1 }, |
363 | [WM8996_WRITE_SEQUENCER_268] = 0x2fff, | 366 | { WM8996_WRITE_SEQUENCER_131, 0x6 }, |
364 | [WM8996_WRITE_SEQUENCER_272] = 0x2fff, | 367 | { WM8996_WRITE_SEQUENCER_132, 0x40 }, |
365 | [WM8996_WRITE_SEQUENCER_276] = 0x2fff, | 368 | { WM8996_WRITE_SEQUENCER_133, 0x1 }, |
366 | [WM8996_WRITE_SEQUENCER_280] = 0x2fff, | 369 | { WM8996_WRITE_SEQUENCER_134, 0xf }, |
367 | [WM8996_WRITE_SEQUENCER_284] = 0x2fff, | 370 | { WM8996_WRITE_SEQUENCER_135, 0x6 }, |
368 | [WM8996_WRITE_SEQUENCER_288] = 0x2fff, | 371 | { WM8996_WRITE_SEQUENCER_136, 0x1 }, |
369 | [WM8996_WRITE_SEQUENCER_292] = 0x2fff, | 372 | { WM8996_WRITE_SEQUENCER_137, 0x3 }, |
370 | [WM8996_WRITE_SEQUENCER_296] = 0x2fff, | 373 | { WM8996_WRITE_SEQUENCER_138, 0x106 }, |
371 | [WM8996_WRITE_SEQUENCER_300] = 0x2fff, | 374 | { WM8996_WRITE_SEQUENCER_140, 0x61 }, |
372 | [WM8996_WRITE_SEQUENCER_304] = 0x2fff, | 375 | { WM8996_WRITE_SEQUENCER_141, 0x11 }, |
373 | [WM8996_WRITE_SEQUENCER_308] = 0x2fff, | 376 | { WM8996_WRITE_SEQUENCER_142, 0x401 }, |
374 | [WM8996_WRITE_SEQUENCER_312] = 0x2fff, | 377 | { WM8996_WRITE_SEQUENCER_144, 0x50 }, |
375 | [WM8996_WRITE_SEQUENCER_316] = 0x2fff, | 378 | { WM8996_WRITE_SEQUENCER_145, 0x3 }, |
376 | [WM8996_WRITE_SEQUENCER_320] = 0x61, | 379 | { WM8996_WRITE_SEQUENCER_146, 0x102 }, |
377 | [WM8996_WRITE_SEQUENCER_322] = 0x601, | 380 | { WM8996_WRITE_SEQUENCER_148, 0x51 }, |
378 | [WM8996_WRITE_SEQUENCER_324] = 0x50, | 381 | { WM8996_WRITE_SEQUENCER_149, 0x3 }, |
379 | [WM8996_WRITE_SEQUENCER_326] = 0x102, | 382 | { WM8996_WRITE_SEQUENCER_150, 0x106 }, |
380 | [WM8996_WRITE_SEQUENCER_328] = 0x1, | 383 | { WM8996_WRITE_SEQUENCER_151, 0xa }, |
381 | [WM8996_WRITE_SEQUENCER_330] = 0x106, | 384 | { WM8996_WRITE_SEQUENCER_152, 0x61 }, |
382 | [WM8996_WRITE_SEQUENCER_331] = 0x100, | 385 | { WM8996_WRITE_SEQUENCER_153, 0x3b }, |
383 | [WM8996_WRITE_SEQUENCER_332] = 0x2fff, | 386 | { WM8996_WRITE_SEQUENCER_154, 0x502 }, |
384 | [WM8996_WRITE_SEQUENCER_336] = 0x2fff, | 387 | { WM8996_WRITE_SEQUENCER_155, 0x100 }, |
385 | [WM8996_WRITE_SEQUENCER_340] = 0x2fff, | 388 | { WM8996_WRITE_SEQUENCER_156, 0x2fff }, |
386 | [WM8996_WRITE_SEQUENCER_344] = 0x2fff, | 389 | { WM8996_WRITE_SEQUENCER_160, 0x2fff }, |
387 | [WM8996_WRITE_SEQUENCER_348] = 0x2fff, | 390 | { WM8996_WRITE_SEQUENCER_164, 0x2fff }, |
388 | [WM8996_WRITE_SEQUENCER_352] = 0x2fff, | 391 | { WM8996_WRITE_SEQUENCER_168, 0x2fff }, |
389 | [WM8996_WRITE_SEQUENCER_356] = 0x2fff, | 392 | { WM8996_WRITE_SEQUENCER_172, 0x2fff }, |
390 | [WM8996_WRITE_SEQUENCER_360] = 0x2fff, | 393 | { WM8996_WRITE_SEQUENCER_176, 0x2fff }, |
391 | [WM8996_WRITE_SEQUENCER_364] = 0x2fff, | 394 | { WM8996_WRITE_SEQUENCER_180, 0x2fff }, |
392 | [WM8996_WRITE_SEQUENCER_368] = 0x2fff, | 395 | { WM8996_WRITE_SEQUENCER_184, 0x2fff }, |
393 | [WM8996_WRITE_SEQUENCER_372] = 0x2fff, | 396 | { WM8996_WRITE_SEQUENCER_188, 0x2fff }, |
394 | [WM8996_WRITE_SEQUENCER_376] = 0x2fff, | 397 | { WM8996_WRITE_SEQUENCER_192, 0x1 }, |
395 | [WM8996_WRITE_SEQUENCER_380] = 0x2fff, | 398 | { WM8996_WRITE_SEQUENCER_193, 0x1 }, |
396 | [WM8996_WRITE_SEQUENCER_384] = 0x60, | 399 | { WM8996_WRITE_SEQUENCER_195, 0x6 }, |
397 | [WM8996_WRITE_SEQUENCER_386] = 0x601, | 400 | { WM8996_WRITE_SEQUENCER_196, 0x40 }, |
398 | [WM8996_WRITE_SEQUENCER_388] = 0x61, | 401 | { WM8996_WRITE_SEQUENCER_197, 0x1 }, |
399 | [WM8996_WRITE_SEQUENCER_390] = 0x601, | 402 | { WM8996_WRITE_SEQUENCER_198, 0xf }, |
400 | [WM8996_WRITE_SEQUENCER_392] = 0x50, | 403 | { WM8996_WRITE_SEQUENCER_199, 0x6 }, |
401 | [WM8996_WRITE_SEQUENCER_394] = 0x300, | 404 | { WM8996_WRITE_SEQUENCER_200, 0x1 }, |
402 | [WM8996_WRITE_SEQUENCER_396] = 0x1, | 405 | { WM8996_WRITE_SEQUENCER_201, 0x3 }, |
403 | [WM8996_WRITE_SEQUENCER_398] = 0x304, | 406 | { WM8996_WRITE_SEQUENCER_202, 0x106 }, |
404 | [WM8996_WRITE_SEQUENCER_400] = 0x40, | 407 | { WM8996_WRITE_SEQUENCER_204, 0x61 }, |
405 | [WM8996_WRITE_SEQUENCER_402] = 0xf, | 408 | { WM8996_WRITE_SEQUENCER_205, 0x11 }, |
406 | [WM8996_WRITE_SEQUENCER_404] = 0x1, | 409 | { WM8996_WRITE_SEQUENCER_206, 0x401 }, |
407 | [WM8996_WRITE_SEQUENCER_407] = 0x100, | 410 | { WM8996_WRITE_SEQUENCER_208, 0x50 }, |
411 | { WM8996_WRITE_SEQUENCER_209, 0x3 }, | ||
412 | { WM8996_WRITE_SEQUENCER_210, 0x102 }, | ||
413 | { WM8996_WRITE_SEQUENCER_212, 0x61 }, | ||
414 | { WM8996_WRITE_SEQUENCER_213, 0x3b }, | ||
415 | { WM8996_WRITE_SEQUENCER_214, 0x502 }, | ||
416 | { WM8996_WRITE_SEQUENCER_215, 0x100 }, | ||
417 | { WM8996_WRITE_SEQUENCER_216, 0x2fff }, | ||
418 | { WM8996_WRITE_SEQUENCER_220, 0x2fff }, | ||
419 | { WM8996_WRITE_SEQUENCER_224, 0x2fff }, | ||
420 | { WM8996_WRITE_SEQUENCER_228, 0x2fff }, | ||
421 | { WM8996_WRITE_SEQUENCER_232, 0x2fff }, | ||
422 | { WM8996_WRITE_SEQUENCER_236, 0x2fff }, | ||
423 | { WM8996_WRITE_SEQUENCER_240, 0x2fff }, | ||
424 | { WM8996_WRITE_SEQUENCER_244, 0x2fff }, | ||
425 | { WM8996_WRITE_SEQUENCER_248, 0x2fff }, | ||
426 | { WM8996_WRITE_SEQUENCER_252, 0x2fff }, | ||
427 | { WM8996_WRITE_SEQUENCER_256, 0x60 }, | ||
428 | { WM8996_WRITE_SEQUENCER_258, 0x601 }, | ||
429 | { WM8996_WRITE_SEQUENCER_260, 0x50 }, | ||
430 | { WM8996_WRITE_SEQUENCER_262, 0x100 }, | ||
431 | { WM8996_WRITE_SEQUENCER_264, 0x1 }, | ||
432 | { WM8996_WRITE_SEQUENCER_266, 0x104 }, | ||
433 | { WM8996_WRITE_SEQUENCER_267, 0x100 }, | ||
434 | { WM8996_WRITE_SEQUENCER_268, 0x2fff }, | ||
435 | { WM8996_WRITE_SEQUENCER_272, 0x2fff }, | ||
436 | { WM8996_WRITE_SEQUENCER_276, 0x2fff }, | ||
437 | { WM8996_WRITE_SEQUENCER_280, 0x2fff }, | ||
438 | { WM8996_WRITE_SEQUENCER_284, 0x2fff }, | ||
439 | { WM8996_WRITE_SEQUENCER_288, 0x2fff }, | ||
440 | { WM8996_WRITE_SEQUENCER_292, 0x2fff }, | ||
441 | { WM8996_WRITE_SEQUENCER_296, 0x2fff }, | ||
442 | { WM8996_WRITE_SEQUENCER_300, 0x2fff }, | ||
443 | { WM8996_WRITE_SEQUENCER_304, 0x2fff }, | ||
444 | { WM8996_WRITE_SEQUENCER_308, 0x2fff }, | ||
445 | { WM8996_WRITE_SEQUENCER_312, 0x2fff }, | ||
446 | { WM8996_WRITE_SEQUENCER_316, 0x2fff }, | ||
447 | { WM8996_WRITE_SEQUENCER_320, 0x61 }, | ||
448 | { WM8996_WRITE_SEQUENCER_322, 0x601 }, | ||
449 | { WM8996_WRITE_SEQUENCER_324, 0x50 }, | ||
450 | { WM8996_WRITE_SEQUENCER_326, 0x102 }, | ||
451 | { WM8996_WRITE_SEQUENCER_328, 0x1 }, | ||
452 | { WM8996_WRITE_SEQUENCER_330, 0x106 }, | ||
453 | { WM8996_WRITE_SEQUENCER_331, 0x100 }, | ||
454 | { WM8996_WRITE_SEQUENCER_332, 0x2fff }, | ||
455 | { WM8996_WRITE_SEQUENCER_336, 0x2fff }, | ||
456 | { WM8996_WRITE_SEQUENCER_340, 0x2fff }, | ||
457 | { WM8996_WRITE_SEQUENCER_344, 0x2fff }, | ||
458 | { WM8996_WRITE_SEQUENCER_348, 0x2fff }, | ||
459 | { WM8996_WRITE_SEQUENCER_352, 0x2fff }, | ||
460 | { WM8996_WRITE_SEQUENCER_356, 0x2fff }, | ||
461 | { WM8996_WRITE_SEQUENCER_360, 0x2fff }, | ||
462 | { WM8996_WRITE_SEQUENCER_364, 0x2fff }, | ||
463 | { WM8996_WRITE_SEQUENCER_368, 0x2fff }, | ||
464 | { WM8996_WRITE_SEQUENCER_372, 0x2fff }, | ||
465 | { WM8996_WRITE_SEQUENCER_376, 0x2fff }, | ||
466 | { WM8996_WRITE_SEQUENCER_380, 0x2fff }, | ||
467 | { WM8996_WRITE_SEQUENCER_384, 0x60 }, | ||
468 | { WM8996_WRITE_SEQUENCER_386, 0x601 }, | ||
469 | { WM8996_WRITE_SEQUENCER_388, 0x61 }, | ||
470 | { WM8996_WRITE_SEQUENCER_390, 0x601 }, | ||
471 | { WM8996_WRITE_SEQUENCER_392, 0x50 }, | ||
472 | { WM8996_WRITE_SEQUENCER_394, 0x300 }, | ||
473 | { WM8996_WRITE_SEQUENCER_396, 0x1 }, | ||
474 | { WM8996_WRITE_SEQUENCER_398, 0x304 }, | ||
475 | { WM8996_WRITE_SEQUENCER_400, 0x40 }, | ||
476 | { WM8996_WRITE_SEQUENCER_402, 0xf }, | ||
477 | { WM8996_WRITE_SEQUENCER_404, 0x1 }, | ||
478 | { WM8996_WRITE_SEQUENCER_407, 0x100 }, | ||
408 | }; | 479 | }; |
409 | 480 | ||
410 | static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0); | 481 | static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0); |
@@ -1413,8 +1484,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = { | |||
1413 | { "SPKDAT", NULL, "SPKR PGA" }, | 1484 | { "SPKDAT", NULL, "SPKR PGA" }, |
1414 | }; | 1485 | }; |
1415 | 1486 | ||
1416 | static int wm8996_readable_register(struct snd_soc_codec *codec, | 1487 | static bool wm8996_readable_register(struct device *dev, unsigned int reg) |
1417 | unsigned int reg) | ||
1418 | { | 1488 | { |
1419 | /* Due to the sparseness of the register map the compiler | 1489 | /* Due to the sparseness of the register map the compiler |
1420 | * output from an explicit switch statement ends up being much | 1490 | * output from an explicit switch statement ends up being much |
@@ -1621,8 +1691,7 @@ static int wm8996_readable_register(struct snd_soc_codec *codec, | |||
1621 | } | 1691 | } |
1622 | } | 1692 | } |
1623 | 1693 | ||
1624 | static int wm8996_volatile_register(struct snd_soc_codec *codec, | 1694 | static bool wm8996_volatile_register(struct device *dev, unsigned int reg) |
1625 | unsigned int reg) | ||
1626 | { | 1695 | { |
1627 | switch (reg) { | 1696 | switch (reg) { |
1628 | case WM8996_SOFTWARE_RESET: | 1697 | case WM8996_SOFTWARE_RESET: |
@@ -1646,9 +1715,15 @@ static int wm8996_volatile_register(struct snd_soc_codec *codec, | |||
1646 | } | 1715 | } |
1647 | } | 1716 | } |
1648 | 1717 | ||
1649 | static int wm8996_reset(struct snd_soc_codec *codec) | 1718 | static int wm8996_reset(struct wm8996_priv *wm8996) |
1650 | { | 1719 | { |
1651 | return snd_soc_write(codec, WM8996_SOFTWARE_RESET, 0x8915); | 1720 | if (wm8996->pdata.ldo_ena > 0) { |
1721 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); | ||
1722 | return 0; | ||
1723 | } else { | ||
1724 | return regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET, | ||
1725 | 0x8915); | ||
1726 | } | ||
1652 | } | 1727 | } |
1653 | 1728 | ||
1654 | static const int bclk_divs[] = { | 1729 | static const int bclk_divs[] = { |
@@ -1723,13 +1798,13 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec, | |||
1723 | msleep(5); | 1798 | msleep(5); |
1724 | } | 1799 | } |
1725 | 1800 | ||
1726 | codec->cache_only = false; | 1801 | regcache_cache_only(codec->control_data, false); |
1727 | snd_soc_cache_sync(codec); | 1802 | regcache_sync(codec->control_data); |
1728 | } | 1803 | } |
1729 | break; | 1804 | break; |
1730 | 1805 | ||
1731 | case SND_SOC_BIAS_OFF: | 1806 | case SND_SOC_BIAS_OFF: |
1732 | codec->cache_only = true; | 1807 | regcache_cache_only(codec->control_data, true); |
1733 | if (wm8996->pdata.ldo_ena >= 0) | 1808 | if (wm8996->pdata.ldo_ena >= 0) |
1734 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); | 1809 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); |
1735 | regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), | 1810 | regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), |
@@ -2252,48 +2327,45 @@ static inline struct wm8996_priv *gpio_to_wm8996(struct gpio_chip *chip) | |||
2252 | static void wm8996_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | 2327 | static void wm8996_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
2253 | { | 2328 | { |
2254 | struct wm8996_priv *wm8996 = gpio_to_wm8996(chip); | 2329 | struct wm8996_priv *wm8996 = gpio_to_wm8996(chip); |
2255 | struct snd_soc_codec *codec = wm8996->codec; | ||
2256 | 2330 | ||
2257 | snd_soc_update_bits(codec, WM8996_GPIO_1 + offset, | 2331 | regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset, |
2258 | WM8996_GP1_LVL, !!value << WM8996_GP1_LVL_SHIFT); | 2332 | WM8996_GP1_LVL, !!value << WM8996_GP1_LVL_SHIFT); |
2259 | } | 2333 | } |
2260 | 2334 | ||
2261 | static int wm8996_gpio_direction_out(struct gpio_chip *chip, | 2335 | static int wm8996_gpio_direction_out(struct gpio_chip *chip, |
2262 | unsigned offset, int value) | 2336 | unsigned offset, int value) |
2263 | { | 2337 | { |
2264 | struct wm8996_priv *wm8996 = gpio_to_wm8996(chip); | 2338 | struct wm8996_priv *wm8996 = gpio_to_wm8996(chip); |
2265 | struct snd_soc_codec *codec = wm8996->codec; | ||
2266 | int val; | 2339 | int val; |
2267 | 2340 | ||
2268 | val = (1 << WM8996_GP1_FN_SHIFT) | (!!value << WM8996_GP1_LVL_SHIFT); | 2341 | val = (1 << WM8996_GP1_FN_SHIFT) | (!!value << WM8996_GP1_LVL_SHIFT); |
2269 | 2342 | ||
2270 | return snd_soc_update_bits(codec, WM8996_GPIO_1 + offset, | 2343 | return regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset, |
2271 | WM8996_GP1_FN_MASK | WM8996_GP1_DIR | | 2344 | WM8996_GP1_FN_MASK | WM8996_GP1_DIR | |
2272 | WM8996_GP1_LVL, val); | 2345 | WM8996_GP1_LVL, val); |
2273 | } | 2346 | } |
2274 | 2347 | ||
2275 | static int wm8996_gpio_get(struct gpio_chip *chip, unsigned offset) | 2348 | static int wm8996_gpio_get(struct gpio_chip *chip, unsigned offset) |
2276 | { | 2349 | { |
2277 | struct wm8996_priv *wm8996 = gpio_to_wm8996(chip); | 2350 | struct wm8996_priv *wm8996 = gpio_to_wm8996(chip); |
2278 | struct snd_soc_codec *codec = wm8996->codec; | 2351 | unsigned int reg; |
2279 | int ret; | 2352 | int ret; |
2280 | 2353 | ||
2281 | ret = snd_soc_read(codec, WM8996_GPIO_1 + offset); | 2354 | ret = regmap_read(wm8996->regmap, WM8996_GPIO_1 + offset, ®); |
2282 | if (ret < 0) | 2355 | if (ret < 0) |
2283 | return ret; | 2356 | return ret; |
2284 | 2357 | ||
2285 | return (ret & WM8996_GP1_LVL) != 0; | 2358 | return (reg & WM8996_GP1_LVL) != 0; |
2286 | } | 2359 | } |
2287 | 2360 | ||
2288 | static int wm8996_gpio_direction_in(struct gpio_chip *chip, unsigned offset) | 2361 | static int wm8996_gpio_direction_in(struct gpio_chip *chip, unsigned offset) |
2289 | { | 2362 | { |
2290 | struct wm8996_priv *wm8996 = gpio_to_wm8996(chip); | 2363 | struct wm8996_priv *wm8996 = gpio_to_wm8996(chip); |
2291 | struct snd_soc_codec *codec = wm8996->codec; | ||
2292 | 2364 | ||
2293 | return snd_soc_update_bits(codec, WM8996_GPIO_1 + offset, | 2365 | return regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset, |
2294 | WM8996_GP1_FN_MASK | WM8996_GP1_DIR, | 2366 | WM8996_GP1_FN_MASK | WM8996_GP1_DIR, |
2295 | (1 << WM8996_GP1_FN_SHIFT) | | 2367 | (1 << WM8996_GP1_FN_SHIFT) | |
2296 | (1 << WM8996_GP1_DIR_SHIFT)); | 2368 | (1 << WM8996_GP1_DIR_SHIFT)); |
2297 | } | 2369 | } |
2298 | 2370 | ||
2299 | static struct gpio_chip wm8996_template_chip = { | 2371 | static struct gpio_chip wm8996_template_chip = { |
@@ -2306,14 +2378,13 @@ static struct gpio_chip wm8996_template_chip = { | |||
2306 | .can_sleep = 1, | 2378 | .can_sleep = 1, |
2307 | }; | 2379 | }; |
2308 | 2380 | ||
2309 | static void wm8996_init_gpio(struct snd_soc_codec *codec) | 2381 | static void wm8996_init_gpio(struct wm8996_priv *wm8996) |
2310 | { | 2382 | { |
2311 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | ||
2312 | int ret; | 2383 | int ret; |
2313 | 2384 | ||
2314 | wm8996->gpio_chip = wm8996_template_chip; | 2385 | wm8996->gpio_chip = wm8996_template_chip; |
2315 | wm8996->gpio_chip.ngpio = 5; | 2386 | wm8996->gpio_chip.ngpio = 5; |
2316 | wm8996->gpio_chip.dev = codec->dev; | 2387 | wm8996->gpio_chip.dev = wm8996->dev; |
2317 | 2388 | ||
2318 | if (wm8996->pdata.gpio_base) | 2389 | if (wm8996->pdata.gpio_base) |
2319 | wm8996->gpio_chip.base = wm8996->pdata.gpio_base; | 2390 | wm8996->gpio_chip.base = wm8996->pdata.gpio_base; |
@@ -2322,24 +2393,23 @@ static void wm8996_init_gpio(struct snd_soc_codec *codec) | |||
2322 | 2393 | ||
2323 | ret = gpiochip_add(&wm8996->gpio_chip); | 2394 | ret = gpiochip_add(&wm8996->gpio_chip); |
2324 | if (ret != 0) | 2395 | if (ret != 0) |
2325 | dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret); | 2396 | dev_err(wm8996->dev, "Failed to add GPIOs: %d\n", ret); |
2326 | } | 2397 | } |
2327 | 2398 | ||
2328 | static void wm8996_free_gpio(struct snd_soc_codec *codec) | 2399 | static void wm8996_free_gpio(struct wm8996_priv *wm8996) |
2329 | { | 2400 | { |
2330 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | ||
2331 | int ret; | 2401 | int ret; |
2332 | 2402 | ||
2333 | ret = gpiochip_remove(&wm8996->gpio_chip); | 2403 | ret = gpiochip_remove(&wm8996->gpio_chip); |
2334 | if (ret != 0) | 2404 | if (ret != 0) |
2335 | dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret); | 2405 | dev_err(wm8996->dev, "Failed to remove GPIOs: %d\n", ret); |
2336 | } | 2406 | } |
2337 | #else | 2407 | #else |
2338 | static void wm8996_init_gpio(struct snd_soc_codec *codec) | 2408 | static void wm8996_init_gpio(struct wm8996_priv *wm8996) |
2339 | { | 2409 | { |
2340 | } | 2410 | } |
2341 | 2411 | ||
2342 | static void wm8996_free_gpio(struct snd_soc_codec *codec) | 2412 | static void wm8996_free_gpio(struct wm8996_priv *wm8996) |
2343 | { | 2413 | { |
2344 | } | 2414 | } |
2345 | #endif | 2415 | #endif |
@@ -2502,8 +2572,10 @@ static void wm8996_micd(struct snd_soc_codec *codec) | |||
2502 | SND_JACK_BTN_0); | 2572 | SND_JACK_BTN_0); |
2503 | 2573 | ||
2504 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, | 2574 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, |
2505 | WM8996_MICD_RATE_MASK, | 2575 | WM8996_MICD_RATE_MASK | |
2506 | WM8996_MICD_RATE_MASK); | 2576 | WM8996_MICD_BIAS_STARTTIME_MASK, |
2577 | WM8996_MICD_RATE_MASK | | ||
2578 | 9 << WM8996_MICD_BIAS_STARTTIME_SHIFT); | ||
2507 | return; | 2579 | return; |
2508 | } | 2580 | } |
2509 | 2581 | ||
@@ -2520,8 +2592,10 @@ static void wm8996_micd(struct snd_soc_codec *codec) | |||
2520 | /* Increase poll rate to give better responsiveness | 2592 | /* Increase poll rate to give better responsiveness |
2521 | * for buttons */ | 2593 | * for buttons */ |
2522 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, | 2594 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, |
2523 | WM8996_MICD_RATE_MASK, | 2595 | WM8996_MICD_RATE_MASK | |
2524 | 5 << WM8996_MICD_RATE_SHIFT); | 2596 | WM8996_MICD_BIAS_STARTTIME_MASK, |
2597 | 5 << WM8996_MICD_RATE_SHIFT | | ||
2598 | 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT); | ||
2525 | } else { | 2599 | } else { |
2526 | dev_dbg(codec->dev, "Mic button up\n"); | 2600 | dev_dbg(codec->dev, "Mic button up\n"); |
2527 | snd_soc_jack_report(wm8996->jack, 0, SND_JACK_BTN_0); | 2601 | snd_soc_jack_report(wm8996->jack, 0, SND_JACK_BTN_0); |
@@ -2569,8 +2643,10 @@ static void wm8996_micd(struct snd_soc_codec *codec) | |||
2569 | * responsiveness. | 2643 | * responsiveness. |
2570 | */ | 2644 | */ |
2571 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, | 2645 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, |
2572 | WM8996_MICD_RATE_MASK, | 2646 | WM8996_MICD_RATE_MASK | |
2573 | 7 << WM8996_MICD_RATE_SHIFT); | 2647 | WM8996_MICD_BIAS_STARTTIME_MASK, |
2648 | 7 << WM8996_MICD_RATE_SHIFT | | ||
2649 | 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT); | ||
2574 | } | 2650 | } |
2575 | } | 2651 | } |
2576 | } | 2652 | } |
@@ -2693,6 +2769,18 @@ static void wm8996_retune_mobile_pdata(struct snd_soc_codec *codec) | |||
2693 | "Failed to add ReTune Mobile controls: %d\n", ret); | 2769 | "Failed to add ReTune Mobile controls: %d\n", ret); |
2694 | } | 2770 | } |
2695 | 2771 | ||
2772 | static const struct regmap_config wm8996_regmap = { | ||
2773 | .reg_bits = 16, | ||
2774 | .val_bits = 16, | ||
2775 | |||
2776 | .max_register = WM8996_MAX_REGISTER, | ||
2777 | .reg_defaults = wm8996_reg, | ||
2778 | .num_reg_defaults = ARRAY_SIZE(wm8996_reg), | ||
2779 | .volatile_reg = wm8996_volatile_register, | ||
2780 | .readable_reg = wm8996_readable_register, | ||
2781 | .cache_type = REGCACHE_RBTREE, | ||
2782 | }; | ||
2783 | |||
2696 | static int wm8996_probe(struct snd_soc_codec *codec) | 2784 | static int wm8996_probe(struct snd_soc_codec *codec) |
2697 | { | 2785 | { |
2698 | int ret; | 2786 | int ret; |
@@ -2708,19 +2796,11 @@ static int wm8996_probe(struct snd_soc_codec *codec) | |||
2708 | 2796 | ||
2709 | dapm->idle_bias_off = true; | 2797 | dapm->idle_bias_off = true; |
2710 | 2798 | ||
2711 | ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); | 2799 | codec->control_data = wm8996->regmap; |
2712 | if (ret != 0) { | ||
2713 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
2714 | goto err; | ||
2715 | } | ||
2716 | |||
2717 | for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) | ||
2718 | wm8996->supplies[i].supply = wm8996_supply_names[i]; | ||
2719 | 2800 | ||
2720 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8996->supplies), | 2801 | ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); |
2721 | wm8996->supplies); | ||
2722 | if (ret != 0) { | 2802 | if (ret != 0) { |
2723 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | 2803 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
2724 | goto err; | 2804 | goto err; |
2725 | } | 2805 | } |
2726 | 2806 | ||
@@ -2728,13 +2808,6 @@ static int wm8996_probe(struct snd_soc_codec *codec) | |||
2728 | wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1; | 2808 | wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1; |
2729 | wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2; | 2809 | wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2; |
2730 | 2810 | ||
2731 | wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD"); | ||
2732 | if (IS_ERR(wm8996->cpvdd)) { | ||
2733 | ret = PTR_ERR(wm8996->cpvdd); | ||
2734 | dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret); | ||
2735 | goto err_get; | ||
2736 | } | ||
2737 | |||
2738 | /* This should really be moved into the regulator core */ | 2811 | /* This should really be moved into the regulator core */ |
2739 | for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) { | 2812 | for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) { |
2740 | ret = regulator_register_notifier(wm8996->supplies[i].consumer, | 2813 | ret = regulator_register_notifier(wm8996->supplies[i].consumer, |
@@ -2746,50 +2819,7 @@ static int wm8996_probe(struct snd_soc_codec *codec) | |||
2746 | } | 2819 | } |
2747 | } | 2820 | } |
2748 | 2821 | ||
2749 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies), | 2822 | regcache_cache_only(codec->control_data, true); |
2750 | wm8996->supplies); | ||
2751 | if (ret != 0) { | ||
2752 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | ||
2753 | goto err_cpvdd; | ||
2754 | } | ||
2755 | |||
2756 | if (wm8996->pdata.ldo_ena >= 0) { | ||
2757 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1); | ||
2758 | msleep(5); | ||
2759 | } | ||
2760 | |||
2761 | ret = snd_soc_read(codec, WM8996_SOFTWARE_RESET); | ||
2762 | if (ret < 0) { | ||
2763 | dev_err(codec->dev, "Failed to read ID register: %d\n", ret); | ||
2764 | goto err_enable; | ||
2765 | } | ||
2766 | if (ret != 0x8915) { | ||
2767 | dev_err(codec->dev, "Device is not a WM8996, ID %x\n", ret); | ||
2768 | ret = -EINVAL; | ||
2769 | goto err_enable; | ||
2770 | } | ||
2771 | |||
2772 | ret = snd_soc_read(codec, WM8996_CHIP_REVISION); | ||
2773 | if (ret < 0) { | ||
2774 | dev_err(codec->dev, "Failed to read device revision: %d\n", | ||
2775 | ret); | ||
2776 | goto err_enable; | ||
2777 | } | ||
2778 | |||
2779 | dev_info(codec->dev, "revision %c\n", | ||
2780 | (ret & WM8996_CHIP_REV_MASK) + 'A'); | ||
2781 | |||
2782 | if (wm8996->pdata.ldo_ena >= 0) { | ||
2783 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); | ||
2784 | } else { | ||
2785 | ret = wm8996_reset(codec); | ||
2786 | if (ret < 0) { | ||
2787 | dev_err(codec->dev, "Failed to issue reset\n"); | ||
2788 | goto err_enable; | ||
2789 | } | ||
2790 | } | ||
2791 | |||
2792 | codec->cache_only = true; | ||
2793 | 2823 | ||
2794 | /* Apply platform data settings */ | 2824 | /* Apply platform data settings */ |
2795 | snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL, | 2825 | snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL, |
@@ -2947,10 +2977,6 @@ static int wm8996_probe(struct snd_soc_codec *codec) | |||
2947 | WM8996_AIF2TX_LRCLK_MODE, | 2977 | WM8996_AIF2TX_LRCLK_MODE, |
2948 | WM8996_AIF2TX_LRCLK_MODE); | 2978 | WM8996_AIF2TX_LRCLK_MODE); |
2949 | 2979 | ||
2950 | regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); | ||
2951 | |||
2952 | wm8996_init_gpio(codec); | ||
2953 | |||
2954 | if (i2c->irq) { | 2980 | if (i2c->irq) { |
2955 | if (wm8996->pdata.irq_flags) | 2981 | if (wm8996->pdata.irq_flags) |
2956 | irq_flags = wm8996->pdata.irq_flags; | 2982 | irq_flags = wm8996->pdata.irq_flags; |
@@ -2988,15 +3014,6 @@ static int wm8996_probe(struct snd_soc_codec *codec) | |||
2988 | 3014 | ||
2989 | return 0; | 3015 | return 0; |
2990 | 3016 | ||
2991 | err_enable: | ||
2992 | if (wm8996->pdata.ldo_ena >= 0) | ||
2993 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); | ||
2994 | |||
2995 | regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); | ||
2996 | err_cpvdd: | ||
2997 | regulator_put(wm8996->cpvdd); | ||
2998 | err_get: | ||
2999 | regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); | ||
3000 | err: | 3017 | err: |
3001 | return ret; | 3018 | return ret; |
3002 | } | 3019 | } |
@@ -3013,8 +3030,6 @@ static int wm8996_remove(struct snd_soc_codec *codec) | |||
3013 | if (i2c->irq) | 3030 | if (i2c->irq) |
3014 | free_irq(i2c->irq, codec); | 3031 | free_irq(i2c->irq, codec); |
3015 | 3032 | ||
3016 | wm8996_free_gpio(codec); | ||
3017 | |||
3018 | for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) | 3033 | for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) |
3019 | regulator_unregister_notifier(wm8996->supplies[i].consumer, | 3034 | regulator_unregister_notifier(wm8996->supplies[i].consumer, |
3020 | &wm8996->disable_nb[i]); | 3035 | &wm8996->disable_nb[i]); |
@@ -3024,17 +3039,17 @@ static int wm8996_remove(struct snd_soc_codec *codec) | |||
3024 | return 0; | 3039 | return 0; |
3025 | } | 3040 | } |
3026 | 3041 | ||
3042 | static int wm8996_soc_volatile_register(struct snd_soc_codec *codec, | ||
3043 | unsigned int reg) | ||
3044 | { | ||
3045 | return true; | ||
3046 | } | ||
3047 | |||
3027 | static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { | 3048 | static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { |
3028 | .probe = wm8996_probe, | 3049 | .probe = wm8996_probe, |
3029 | .remove = wm8996_remove, | 3050 | .remove = wm8996_remove, |
3030 | .set_bias_level = wm8996_set_bias_level, | 3051 | .set_bias_level = wm8996_set_bias_level, |
3031 | .seq_notifier = wm8996_seq_notifier, | 3052 | .seq_notifier = wm8996_seq_notifier, |
3032 | .reg_cache_size = WM8996_MAX_REGISTER + 1, | ||
3033 | .reg_word_size = sizeof(u16), | ||
3034 | .reg_cache_default = wm8996_reg, | ||
3035 | .volatile_register = wm8996_volatile_register, | ||
3036 | .readable_register = wm8996_readable_register, | ||
3037 | .compress_type = SND_SOC_RBTREE_COMPRESSION, | ||
3038 | .controls = wm8996_snd_controls, | 3053 | .controls = wm8996_snd_controls, |
3039 | .num_controls = ARRAY_SIZE(wm8996_snd_controls), | 3054 | .num_controls = ARRAY_SIZE(wm8996_snd_controls), |
3040 | .dapm_widgets = wm8996_dapm_widgets, | 3055 | .dapm_widgets = wm8996_dapm_widgets, |
@@ -3042,6 +3057,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { | |||
3042 | .dapm_routes = wm8996_dapm_routes, | 3057 | .dapm_routes = wm8996_dapm_routes, |
3043 | .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes), | 3058 | .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes), |
3044 | .set_pll = wm8996_set_fll, | 3059 | .set_pll = wm8996_set_fll, |
3060 | .reg_cache_size = WM8996_MAX_REGISTER, | ||
3061 | .volatile_register = wm8996_soc_volatile_register, | ||
3045 | }; | 3062 | }; |
3046 | 3063 | ||
3047 | #define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ | 3064 | #define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ |
@@ -3050,7 +3067,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { | |||
3050 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\ | 3067 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\ |
3051 | SNDRV_PCM_FMTBIT_S32_LE) | 3068 | SNDRV_PCM_FMTBIT_S32_LE) |
3052 | 3069 | ||
3053 | static struct snd_soc_dai_ops wm8996_dai_ops = { | 3070 | static const struct snd_soc_dai_ops wm8996_dai_ops = { |
3054 | .set_fmt = wm8996_set_fmt, | 3071 | .set_fmt = wm8996_set_fmt, |
3055 | .hw_params = wm8996_hw_params, | 3072 | .hw_params = wm8996_hw_params, |
3056 | .set_sysclk = wm8996_set_sysclk, | 3073 | .set_sysclk = wm8996_set_sysclk, |
@@ -3099,13 +3116,16 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, | |||
3099 | const struct i2c_device_id *id) | 3116 | const struct i2c_device_id *id) |
3100 | { | 3117 | { |
3101 | struct wm8996_priv *wm8996; | 3118 | struct wm8996_priv *wm8996; |
3102 | int ret; | 3119 | int ret, i; |
3120 | unsigned int reg; | ||
3103 | 3121 | ||
3104 | wm8996 = kzalloc(sizeof(struct wm8996_priv), GFP_KERNEL); | 3122 | wm8996 = devm_kzalloc(&i2c->dev, sizeof(struct wm8996_priv), |
3123 | GFP_KERNEL); | ||
3105 | if (wm8996 == NULL) | 3124 | if (wm8996 == NULL) |
3106 | return -ENOMEM; | 3125 | return -ENOMEM; |
3107 | 3126 | ||
3108 | i2c_set_clientdata(i2c, wm8996); | 3127 | i2c_set_clientdata(i2c, wm8996); |
3128 | wm8996->dev = &i2c->dev; | ||
3109 | 3129 | ||
3110 | if (dev_get_platdata(&i2c->dev)) | 3130 | if (dev_get_platdata(&i2c->dev)) |
3111 | memcpy(&wm8996->pdata, dev_get_platdata(&i2c->dev), | 3131 | memcpy(&wm8996->pdata, dev_get_platdata(&i2c->dev), |
@@ -3121,19 +3141,97 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, | |||
3121 | } | 3141 | } |
3122 | } | 3142 | } |
3123 | 3143 | ||
3144 | for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) | ||
3145 | wm8996->supplies[i].supply = wm8996_supply_names[i]; | ||
3146 | |||
3147 | ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies), | ||
3148 | wm8996->supplies); | ||
3149 | if (ret != 0) { | ||
3150 | dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); | ||
3151 | goto err_gpio; | ||
3152 | } | ||
3153 | |||
3154 | wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD"); | ||
3155 | if (IS_ERR(wm8996->cpvdd)) { | ||
3156 | ret = PTR_ERR(wm8996->cpvdd); | ||
3157 | dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret); | ||
3158 | goto err_get; | ||
3159 | } | ||
3160 | |||
3161 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies), | ||
3162 | wm8996->supplies); | ||
3163 | if (ret != 0) { | ||
3164 | dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); | ||
3165 | goto err_cpvdd; | ||
3166 | } | ||
3167 | |||
3168 | if (wm8996->pdata.ldo_ena > 0) { | ||
3169 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1); | ||
3170 | msleep(5); | ||
3171 | } | ||
3172 | |||
3173 | wm8996->regmap = regmap_init_i2c(i2c, &wm8996_regmap); | ||
3174 | if (IS_ERR(wm8996->regmap)) { | ||
3175 | ret = PTR_ERR(wm8996->regmap); | ||
3176 | dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); | ||
3177 | goto err_enable; | ||
3178 | } | ||
3179 | |||
3180 | ret = regmap_read(wm8996->regmap, WM8996_SOFTWARE_RESET, ®); | ||
3181 | if (ret < 0) { | ||
3182 | dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret); | ||
3183 | goto err_regmap; | ||
3184 | } | ||
3185 | if (reg != 0x8915) { | ||
3186 | dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", ret); | ||
3187 | ret = -EINVAL; | ||
3188 | goto err_regmap; | ||
3189 | } | ||
3190 | |||
3191 | ret = regmap_read(wm8996->regmap, WM8996_CHIP_REVISION, ®); | ||
3192 | if (ret < 0) { | ||
3193 | dev_err(&i2c->dev, "Failed to read device revision: %d\n", | ||
3194 | ret); | ||
3195 | goto err_regmap; | ||
3196 | } | ||
3197 | |||
3198 | dev_info(&i2c->dev, "revision %c\n", | ||
3199 | (reg & WM8996_CHIP_REV_MASK) + 'A'); | ||
3200 | |||
3201 | regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); | ||
3202 | |||
3203 | ret = wm8996_reset(wm8996); | ||
3204 | if (ret < 0) { | ||
3205 | dev_err(&i2c->dev, "Failed to issue reset\n"); | ||
3206 | goto err_regmap; | ||
3207 | } | ||
3208 | |||
3209 | wm8996_init_gpio(wm8996); | ||
3210 | |||
3124 | ret = snd_soc_register_codec(&i2c->dev, | 3211 | ret = snd_soc_register_codec(&i2c->dev, |
3125 | &soc_codec_dev_wm8996, wm8996_dai, | 3212 | &soc_codec_dev_wm8996, wm8996_dai, |
3126 | ARRAY_SIZE(wm8996_dai)); | 3213 | ARRAY_SIZE(wm8996_dai)); |
3127 | if (ret < 0) | 3214 | if (ret < 0) |
3128 | goto err_gpio; | 3215 | goto err_gpiolib; |
3129 | 3216 | ||
3130 | return ret; | 3217 | return ret; |
3131 | 3218 | ||
3219 | err_gpiolib: | ||
3220 | wm8996_free_gpio(wm8996); | ||
3221 | err_regmap: | ||
3222 | regmap_exit(wm8996->regmap); | ||
3223 | err_enable: | ||
3224 | if (wm8996->pdata.ldo_ena > 0) | ||
3225 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); | ||
3226 | regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); | ||
3227 | err_cpvdd: | ||
3228 | regulator_put(wm8996->cpvdd); | ||
3229 | err_get: | ||
3230 | regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); | ||
3132 | err_gpio: | 3231 | err_gpio: |
3133 | if (wm8996->pdata.ldo_ena > 0) | 3232 | if (wm8996->pdata.ldo_ena > 0) |
3134 | gpio_free(wm8996->pdata.ldo_ena); | 3233 | gpio_free(wm8996->pdata.ldo_ena); |
3135 | err: | 3234 | err: |
3136 | kfree(wm8996); | ||
3137 | 3235 | ||
3138 | return ret; | 3236 | return ret; |
3139 | } | 3237 | } |
@@ -3143,9 +3241,14 @@ static __devexit int wm8996_i2c_remove(struct i2c_client *client) | |||
3143 | struct wm8996_priv *wm8996 = i2c_get_clientdata(client); | 3241 | struct wm8996_priv *wm8996 = i2c_get_clientdata(client); |
3144 | 3242 | ||
3145 | snd_soc_unregister_codec(&client->dev); | 3243 | snd_soc_unregister_codec(&client->dev); |
3146 | if (wm8996->pdata.ldo_ena > 0) | 3244 | wm8996_free_gpio(wm8996); |
3245 | regulator_put(wm8996->cpvdd); | ||
3246 | regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); | ||
3247 | regmap_exit(wm8996->regmap); | ||
3248 | if (wm8996->pdata.ldo_ena > 0) { | ||
3249 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); | ||
3147 | gpio_free(wm8996->pdata.ldo_ena); | 3250 | gpio_free(wm8996->pdata.ldo_ena); |
3148 | kfree(i2c_get_clientdata(client)); | 3251 | } |
3149 | return 0; | 3252 | return 0; |
3150 | } | 3253 | } |
3151 | 3254 | ||