aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8996.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8996.c')
-rw-r--r--sound/soc/codecs/wm8996.c945
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
51struct wm8996_priv { 52struct 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)
114WM8996_REGULATOR_EVENT(1) 117WM8996_REGULATOR_EVENT(1)
115WM8996_REGULATOR_EVENT(2) 118WM8996_REGULATOR_EVENT(2)
116 119
117static const u16 wm8996_reg[WM8996_MAX_REGISTER] = { 120static 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
410static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0); 481static 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
1416static int wm8996_readable_register(struct snd_soc_codec *codec, 1487static 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
1624static int wm8996_volatile_register(struct snd_soc_codec *codec, 1694static 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
1649static int wm8996_reset(struct snd_soc_codec *codec) 1718static 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
1654static const int bclk_divs[] = { 1729static 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)
2252static void wm8996_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 2327static 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
2261static int wm8996_gpio_direction_out(struct gpio_chip *chip, 2335static 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
2275static int wm8996_gpio_get(struct gpio_chip *chip, unsigned offset) 2348static 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, &reg);
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
2288static int wm8996_gpio_direction_in(struct gpio_chip *chip, unsigned offset) 2361static 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
2299static struct gpio_chip wm8996_template_chip = { 2371static 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
2309static void wm8996_init_gpio(struct snd_soc_codec *codec) 2381static 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
2328static void wm8996_free_gpio(struct snd_soc_codec *codec) 2399static 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
2338static void wm8996_init_gpio(struct snd_soc_codec *codec) 2408static void wm8996_init_gpio(struct wm8996_priv *wm8996)
2339{ 2409{
2340} 2410}
2341 2411
2342static void wm8996_free_gpio(struct snd_soc_codec *codec) 2412static 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
2772static 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
2696static int wm8996_probe(struct snd_soc_codec *codec) 2784static 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
2991err_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);
2996err_cpvdd:
2997 regulator_put(wm8996->cpvdd);
2998err_get:
2999 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
3000err: 3017err:
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
3042static int wm8996_soc_volatile_register(struct snd_soc_codec *codec,
3043 unsigned int reg)
3044{
3045 return true;
3046}
3047
3027static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { 3048static 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
3053static struct snd_soc_dai_ops wm8996_dai_ops = { 3070static 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, &reg);
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, &reg);
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
3219err_gpiolib:
3220 wm8996_free_gpio(wm8996);
3221err_regmap:
3222 regmap_exit(wm8996->regmap);
3223err_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);
3227err_cpvdd:
3228 regulator_put(wm8996->cpvdd);
3229err_get:
3230 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
3132err_gpio: 3231err_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);
3135err: 3234err:
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