aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8904.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8904.c')
-rw-r--r--sound/soc/codecs/wm8904.c856
1 files changed, 296 insertions, 560 deletions
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index f31c754c8865..65d525d74c54 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -17,6 +17,7 @@
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/regmap.h>
20#include <linux/regulator/consumer.h> 21#include <linux/regulator/consumer.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
@@ -47,6 +48,7 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
47 48
48/* codec private data */ 49/* codec private data */
49struct wm8904_priv { 50struct wm8904_priv {
51 struct regmap *regmap;
50 52
51 enum wm8904_type devtype; 53 enum wm8904_type devtype;
52 54
@@ -86,517 +88,230 @@ struct wm8904_priv {
86 int dcs_state[WM8904_NUM_DCS_CHANNELS]; 88 int dcs_state[WM8904_NUM_DCS_CHANNELS];
87}; 89};
88 90
89static const u16 wm8904_reg[WM8904_MAX_REGISTER + 1] = { 91static const struct reg_default wm8904_reg_defaults[] = {
90 0x8904, /* R0 - SW Reset and ID */ 92 { 4, 0x0018 }, /* R4 - Bias Control 0 */
91 0x0000, /* R1 - Revision */ 93 { 5, 0x0000 }, /* R5 - VMID Control 0 */
92 0x0000, /* R2 */ 94 { 6, 0x0000 }, /* R6 - Mic Bias Control 0 */
93 0x0000, /* R3 */ 95 { 7, 0x0000 }, /* R7 - Mic Bias Control 1 */
94 0x0018, /* R4 - Bias Control 0 */ 96 { 8, 0x0001 }, /* R8 - Analogue DAC 0 */
95 0x0000, /* R5 - VMID Control 0 */ 97 { 9, 0x9696 }, /* R9 - mic Filter Control */
96 0x0000, /* R6 - Mic Bias Control 0 */ 98 { 10, 0x0001 }, /* R10 - Analogue ADC 0 */
97 0x0000, /* R7 - Mic Bias Control 1 */ 99 { 12, 0x0000 }, /* R12 - Power Management 0 */
98 0x0001, /* R8 - Analogue DAC 0 */ 100 { 14, 0x0000 }, /* R14 - Power Management 2 */
99 0x9696, /* R9 - mic Filter Control */ 101 { 15, 0x0000 }, /* R15 - Power Management 3 */
100 0x0001, /* R10 - Analogue ADC 0 */ 102 { 18, 0x0000 }, /* R18 - Power Management 6 */
101 0x0000, /* R11 */ 103 { 19, 0x945E }, /* R20 - Clock Rates 0 */
102 0x0000, /* R12 - Power Management 0 */ 104 { 21, 0x0C05 }, /* R21 - Clock Rates 1 */
103 0x0000, /* R13 */ 105 { 22, 0x0006 }, /* R22 - Clock Rates 2 */
104 0x0000, /* R14 - Power Management 2 */ 106 { 24, 0x0050 }, /* R24 - Audio Interface 0 */
105 0x0000, /* R15 - Power Management 3 */ 107 { 25, 0x000A }, /* R25 - Audio Interface 1 */
106 0x0000, /* R16 */ 108 { 26, 0x00E4 }, /* R26 - Audio Interface 2 */
107 0x0000, /* R17 */ 109 { 27, 0x0040 }, /* R27 - Audio Interface 3 */
108 0x0000, /* R18 - Power Management 6 */ 110 { 30, 0x00C0 }, /* R30 - DAC Digital Volume Left */
109 0x0000, /* R19 */ 111 { 31, 0x00C0 }, /* R31 - DAC Digital Volume Right */
110 0x945E, /* R20 - Clock Rates 0 */ 112 { 32, 0x0000 }, /* R32 - DAC Digital 0 */
111 0x0C05, /* R21 - Clock Rates 1 */ 113 { 33, 0x0008 }, /* R33 - DAC Digital 1 */
112 0x0006, /* R22 - Clock Rates 2 */ 114 { 36, 0x00C0 }, /* R36 - ADC Digital Volume Left */
113 0x0000, /* R23 */ 115 { 37, 0x00C0 }, /* R37 - ADC Digital Volume Right */
114 0x0050, /* R24 - Audio Interface 0 */ 116 { 38, 0x0010 }, /* R38 - ADC Digital 0 */
115 0x000A, /* R25 - Audio Interface 1 */ 117 { 39, 0x0000 }, /* R39 - Digital Microphone 0 */
116 0x00E4, /* R26 - Audio Interface 2 */ 118 { 40, 0x01AF }, /* R40 - DRC 0 */
117 0x0040, /* R27 - Audio Interface 3 */ 119 { 41, 0x3248 }, /* R41 - DRC 1 */
118 0x0000, /* R28 */ 120 { 42, 0x0000 }, /* R42 - DRC 2 */
119 0x0000, /* R29 */ 121 { 43, 0x0000 }, /* R43 - DRC 3 */
120 0x00C0, /* R30 - DAC Digital Volume Left */ 122 { 44, 0x0085 }, /* R44 - Analogue Left Input 0 */
121 0x00C0, /* R31 - DAC Digital Volume Right */ 123 { 45, 0x0085 }, /* R45 - Analogue Right Input 0 */
122 0x0000, /* R32 - DAC Digital 0 */ 124 { 46, 0x0044 }, /* R46 - Analogue Left Input 1 */
123 0x0008, /* R33 - DAC Digital 1 */ 125 { 47, 0x0044 }, /* R47 - Analogue Right Input 1 */
124 0x0000, /* R34 */ 126 { 57, 0x002D }, /* R57 - Analogue OUT1 Left */
125 0x0000, /* R35 */ 127 { 58, 0x002D }, /* R58 - Analogue OUT1 Right */
126 0x00C0, /* R36 - ADC Digital Volume Left */ 128 { 59, 0x0039 }, /* R59 - Analogue OUT2 Left */
127 0x00C0, /* R37 - ADC Digital Volume Right */ 129 { 60, 0x0039 }, /* R60 - Analogue OUT2 Right */
128 0x0010, /* R38 - ADC Digital 0 */ 130 { 61, 0x0000 }, /* R61 - Analogue OUT12 ZC */
129 0x0000, /* R39 - Digital Microphone 0 */ 131 { 67, 0x0000 }, /* R67 - DC Servo 0 */
130 0x01AF, /* R40 - DRC 0 */ 132 { 69, 0xAAAA }, /* R69 - DC Servo 2 */
131 0x3248, /* R41 - DRC 1 */ 133 { 71, 0xAAAA }, /* R71 - DC Servo 4 */
132 0x0000, /* R42 - DRC 2 */ 134 { 72, 0xAAAA }, /* R72 - DC Servo 5 */
133 0x0000, /* R43 - DRC 3 */ 135 { 90, 0x0000 }, /* R90 - Analogue HP 0 */
134 0x0085, /* R44 - Analogue Left Input 0 */ 136 { 94, 0x0000 }, /* R94 - Analogue Lineout 0 */
135 0x0085, /* R45 - Analogue Right Input 0 */ 137 { 98, 0x0000 }, /* R98 - Charge Pump 0 */
136 0x0044, /* R46 - Analogue Left Input 1 */ 138 { 104, 0x0004 }, /* R104 - Class W 0 */
137 0x0044, /* R47 - Analogue Right Input 1 */ 139 { 108, 0x0000 }, /* R108 - Write Sequencer 0 */
138 0x0000, /* R48 */ 140 { 109, 0x0000 }, /* R109 - Write Sequencer 1 */
139 0x0000, /* R49 */ 141 { 110, 0x0000 }, /* R110 - Write Sequencer 2 */
140 0x0000, /* R50 */ 142 { 111, 0x0000 }, /* R111 - Write Sequencer 3 */
141 0x0000, /* R51 */ 143 { 112, 0x0000 }, /* R112 - Write Sequencer 4 */
142 0x0000, /* R52 */ 144 { 116, 0x0000 }, /* R116 - FLL Control 1 */
143 0x0000, /* R53 */ 145 { 117, 0x0007 }, /* R117 - FLL Control 2 */
144 0x0000, /* R54 */ 146 { 118, 0x0000 }, /* R118 - FLL Control 3 */
145 0x0000, /* R55 */ 147 { 119, 0x2EE0 }, /* R119 - FLL Control 4 */
146 0x0000, /* R56 */ 148 { 120, 0x0004 }, /* R120 - FLL Control 5 */
147 0x002D, /* R57 - Analogue OUT1 Left */ 149 { 121, 0x0014 }, /* R121 - GPIO Control 1 */
148 0x002D, /* R58 - Analogue OUT1 Right */ 150 { 122, 0x0010 }, /* R122 - GPIO Control 2 */
149 0x0039, /* R59 - Analogue OUT2 Left */ 151 { 123, 0x0010 }, /* R123 - GPIO Control 3 */
150 0x0039, /* R60 - Analogue OUT2 Right */ 152 { 124, 0x0000 }, /* R124 - GPIO Control 4 */
151 0x0000, /* R61 - Analogue OUT12 ZC */ 153 { 126, 0x0000 }, /* R126 - Digital Pulls */
152 0x0000, /* R62 */ 154 { 128, 0xFFFF }, /* R128 - Interrupt Status Mask */
153 0x0000, /* R63 */ 155 { 129, 0x0000 }, /* R129 - Interrupt Polarity */
154 0x0000, /* R64 */ 156 { 130, 0x0000 }, /* R130 - Interrupt Debounce */
155 0x0000, /* R65 */ 157 { 134, 0x0000 }, /* R134 - EQ1 */
156 0x0000, /* R66 */ 158 { 135, 0x000C }, /* R135 - EQ2 */
157 0x0000, /* R67 - DC Servo 0 */ 159 { 136, 0x000C }, /* R136 - EQ3 */
158 0x0000, /* R68 - DC Servo 1 */ 160 { 137, 0x000C }, /* R137 - EQ4 */
159 0xAAAA, /* R69 - DC Servo 2 */ 161 { 138, 0x000C }, /* R138 - EQ5 */
160 0x0000, /* R70 */ 162 { 139, 0x000C }, /* R139 - EQ6 */
161 0xAAAA, /* R71 - DC Servo 4 */ 163 { 140, 0x0FCA }, /* R140 - EQ7 */
162 0xAAAA, /* R72 - DC Servo 5 */ 164 { 141, 0x0400 }, /* R141 - EQ8 */
163 0x0000, /* R73 - DC Servo 6 */ 165 { 142, 0x00D8 }, /* R142 - EQ9 */
164 0x0000, /* R74 - DC Servo 7 */ 166 { 143, 0x1EB5 }, /* R143 - EQ10 */
165 0x0000, /* R75 - DC Servo 8 */ 167 { 144, 0xF145 }, /* R144 - EQ11 */
166 0x0000, /* R76 - DC Servo 9 */ 168 { 145, 0x0B75 }, /* R145 - EQ12 */
167 0x0000, /* R77 - DC Servo Readback 0 */ 169 { 146, 0x01C5 }, /* R146 - EQ13 */
168 0x0000, /* R78 */ 170 { 147, 0x1C58 }, /* R147 - EQ14 */
169 0x0000, /* R79 */ 171 { 148, 0xF373 }, /* R148 - EQ15 */
170 0x0000, /* R80 */ 172 { 149, 0x0A54 }, /* R149 - EQ16 */
171 0x0000, /* R81 */ 173 { 150, 0x0558 }, /* R150 - EQ17 */
172 0x0000, /* R82 */ 174 { 151, 0x168E }, /* R151 - EQ18 */
173 0x0000, /* R83 */ 175 { 152, 0xF829 }, /* R152 - EQ19 */
174 0x0000, /* R84 */ 176 { 153, 0x07AD }, /* R153 - EQ20 */
175 0x0000, /* R85 */ 177 { 154, 0x1103 }, /* R154 - EQ21 */
176 0x0000, /* R86 */ 178 { 155, 0x0564 }, /* R155 - EQ22 */
177 0x0000, /* R87 */ 179 { 156, 0x0559 }, /* R156 - EQ23 */
178 0x0000, /* R88 */ 180 { 157, 0x4000 }, /* R157 - EQ24 */
179 0x0000, /* R89 */ 181 { 161, 0x0000 }, /* R161 - Control Interface Test 1 */
180 0x0000, /* R90 - Analogue HP 0 */ 182 { 204, 0x0000 }, /* R204 - Analogue Output Bias 0 */
181 0x0000, /* R91 */ 183 { 247, 0x0000 }, /* R247 - FLL NCO Test 0 */
182 0x0000, /* R92 */ 184 { 248, 0x0019 }, /* R248 - FLL NCO Test 1 */
183 0x0000, /* R93 */
184 0x0000, /* R94 - Analogue Lineout 0 */
185 0x0000, /* R95 */
186 0x0000, /* R96 */
187 0x0000, /* R97 */
188 0x0000, /* R98 - Charge Pump 0 */
189 0x0000, /* R99 */
190 0x0000, /* R100 */
191 0x0000, /* R101 */
192 0x0000, /* R102 */
193 0x0000, /* R103 */
194 0x0004, /* R104 - Class W 0 */
195 0x0000, /* R105 */
196 0x0000, /* R106 */
197 0x0000, /* R107 */
198 0x0000, /* R108 - Write Sequencer 0 */
199 0x0000, /* R109 - Write Sequencer 1 */
200 0x0000, /* R110 - Write Sequencer 2 */
201 0x0000, /* R111 - Write Sequencer 3 */
202 0x0000, /* R112 - Write Sequencer 4 */
203 0x0000, /* R113 */
204 0x0000, /* R114 */
205 0x0000, /* R115 */
206 0x0000, /* R116 - FLL Control 1 */
207 0x0007, /* R117 - FLL Control 2 */
208 0x0000, /* R118 - FLL Control 3 */
209 0x2EE0, /* R119 - FLL Control 4 */
210 0x0004, /* R120 - FLL Control 5 */
211 0x0014, /* R121 - GPIO Control 1 */
212 0x0010, /* R122 - GPIO Control 2 */
213 0x0010, /* R123 - GPIO Control 3 */
214 0x0000, /* R124 - GPIO Control 4 */
215 0x0000, /* R125 */
216 0x0000, /* R126 - Digital Pulls */
217 0x0000, /* R127 - Interrupt Status */
218 0xFFFF, /* R128 - Interrupt Status Mask */
219 0x0000, /* R129 - Interrupt Polarity */
220 0x0000, /* R130 - Interrupt Debounce */
221 0x0000, /* R131 */
222 0x0000, /* R132 */
223 0x0000, /* R133 */
224 0x0000, /* R134 - EQ1 */
225 0x000C, /* R135 - EQ2 */
226 0x000C, /* R136 - EQ3 */
227 0x000C, /* R137 - EQ4 */
228 0x000C, /* R138 - EQ5 */
229 0x000C, /* R139 - EQ6 */
230 0x0FCA, /* R140 - EQ7 */
231 0x0400, /* R141 - EQ8 */
232 0x00D8, /* R142 - EQ9 */
233 0x1EB5, /* R143 - EQ10 */
234 0xF145, /* R144 - EQ11 */
235 0x0B75, /* R145 - EQ12 */
236 0x01C5, /* R146 - EQ13 */
237 0x1C58, /* R147 - EQ14 */
238 0xF373, /* R148 - EQ15 */
239 0x0A54, /* R149 - EQ16 */
240 0x0558, /* R150 - EQ17 */
241 0x168E, /* R151 - EQ18 */
242 0xF829, /* R152 - EQ19 */
243 0x07AD, /* R153 - EQ20 */
244 0x1103, /* R154 - EQ21 */
245 0x0564, /* R155 - EQ22 */
246 0x0559, /* R156 - EQ23 */
247 0x4000, /* R157 - EQ24 */
248 0x0000, /* R158 */
249 0x0000, /* R159 */
250 0x0000, /* R160 */
251 0x0000, /* R161 - Control Interface Test 1 */
252 0x0000, /* R162 */
253 0x0000, /* R163 */
254 0x0000, /* R164 */
255 0x0000, /* R165 */
256 0x0000, /* R166 */
257 0x0000, /* R167 */
258 0x0000, /* R168 */
259 0x0000, /* R169 */
260 0x0000, /* R170 */
261 0x0000, /* R171 */
262 0x0000, /* R172 */
263 0x0000, /* R173 */
264 0x0000, /* R174 */
265 0x0000, /* R175 */
266 0x0000, /* R176 */
267 0x0000, /* R177 */
268 0x0000, /* R178 */
269 0x0000, /* R179 */
270 0x0000, /* R180 */
271 0x0000, /* R181 */
272 0x0000, /* R182 */
273 0x0000, /* R183 */
274 0x0000, /* R184 */
275 0x0000, /* R185 */
276 0x0000, /* R186 */
277 0x0000, /* R187 */
278 0x0000, /* R188 */
279 0x0000, /* R189 */
280 0x0000, /* R190 */
281 0x0000, /* R191 */
282 0x0000, /* R192 */
283 0x0000, /* R193 */
284 0x0000, /* R194 */
285 0x0000, /* R195 */
286 0x0000, /* R196 */
287 0x0000, /* R197 */
288 0x0000, /* R198 */
289 0x0000, /* R199 */
290 0x0000, /* R200 */
291 0x0000, /* R201 */
292 0x0000, /* R202 */
293 0x0000, /* R203 */
294 0x0000, /* R204 - Analogue Output Bias 0 */
295 0x0000, /* R205 */
296 0x0000, /* R206 */
297 0x0000, /* R207 */
298 0x0000, /* R208 */
299 0x0000, /* R209 */
300 0x0000, /* R210 */
301 0x0000, /* R211 */
302 0x0000, /* R212 */
303 0x0000, /* R213 */
304 0x0000, /* R214 */
305 0x0000, /* R215 */
306 0x0000, /* R216 */
307 0x0000, /* R217 */
308 0x0000, /* R218 */
309 0x0000, /* R219 */
310 0x0000, /* R220 */
311 0x0000, /* R221 */
312 0x0000, /* R222 */
313 0x0000, /* R223 */
314 0x0000, /* R224 */
315 0x0000, /* R225 */
316 0x0000, /* R226 */
317 0x0000, /* R227 */
318 0x0000, /* R228 */
319 0x0000, /* R229 */
320 0x0000, /* R230 */
321 0x0000, /* R231 */
322 0x0000, /* R232 */
323 0x0000, /* R233 */
324 0x0000, /* R234 */
325 0x0000, /* R235 */
326 0x0000, /* R236 */
327 0x0000, /* R237 */
328 0x0000, /* R238 */
329 0x0000, /* R239 */
330 0x0000, /* R240 */
331 0x0000, /* R241 */
332 0x0000, /* R242 */
333 0x0000, /* R243 */
334 0x0000, /* R244 */
335 0x0000, /* R245 */
336 0x0000, /* R246 */
337 0x0000, /* R247 - FLL NCO Test 0 */
338 0x0019, /* R248 - FLL NCO Test 1 */
339}; 185};
340 186
341static struct { 187static bool wm8904_volatile_register(struct device *dev, unsigned int reg)
342 int readable; 188{
343 int writable; 189 switch (reg) {
344 int vol; 190 case WM8904_SW_RESET_AND_ID:
345} wm8904_access[] = { 191 case WM8904_REVISION:
346 { 0xFFFF, 0xFFFF, 1 }, /* R0 - SW Reset and ID */ 192 case WM8904_DC_SERVO_1:
347 { 0x0000, 0x0000, 0 }, /* R1 - Revision */ 193 case WM8904_DC_SERVO_6:
348 { 0x0000, 0x0000, 0 }, /* R2 */ 194 case WM8904_DC_SERVO_7:
349 { 0x0000, 0x0000, 0 }, /* R3 */ 195 case WM8904_DC_SERVO_8:
350 { 0x001F, 0x001F, 0 }, /* R4 - Bias Control 0 */ 196 case WM8904_DC_SERVO_9:
351 { 0x0047, 0x0047, 0 }, /* R5 - VMID Control 0 */ 197 case WM8904_DC_SERVO_READBACK_0:
352 { 0x007F, 0x007F, 0 }, /* R6 - Mic Bias Control 0 */ 198 case WM8904_INTERRUPT_STATUS:
353 { 0xC007, 0xC007, 0 }, /* R7 - Mic Bias Control 1 */ 199 return true;
354 { 0x001E, 0x001E, 0 }, /* R8 - Analogue DAC 0 */ 200 default:
355 { 0xFFFF, 0xFFFF, 0 }, /* R9 - mic Filter Control */ 201 return false;
356 { 0x0001, 0x0001, 0 }, /* R10 - Analogue ADC 0 */ 202 }
357 { 0x0000, 0x0000, 0 }, /* R11 */ 203}
358 { 0x0003, 0x0003, 0 }, /* R12 - Power Management 0 */
359 { 0x0000, 0x0000, 0 }, /* R13 */
360 { 0x0003, 0x0003, 0 }, /* R14 - Power Management 2 */
361 { 0x0003, 0x0003, 0 }, /* R15 - Power Management 3 */
362 { 0x0000, 0x0000, 0 }, /* R16 */
363 { 0x0000, 0x0000, 0 }, /* R17 */
364 { 0x000F, 0x000F, 0 }, /* R18 - Power Management 6 */
365 { 0x0000, 0x0000, 0 }, /* R19 */
366 { 0x7001, 0x7001, 0 }, /* R20 - Clock Rates 0 */
367 { 0x3C07, 0x3C07, 0 }, /* R21 - Clock Rates 1 */
368 { 0xD00F, 0xD00F, 0 }, /* R22 - Clock Rates 2 */
369 { 0x0000, 0x0000, 0 }, /* R23 */
370 { 0x1FFF, 0x1FFF, 0 }, /* R24 - Audio Interface 0 */
371 { 0x3DDF, 0x3DDF, 0 }, /* R25 - Audio Interface 1 */
372 { 0x0F1F, 0x0F1F, 0 }, /* R26 - Audio Interface 2 */
373 { 0x0FFF, 0x0FFF, 0 }, /* R27 - Audio Interface 3 */
374 { 0x0000, 0x0000, 0 }, /* R28 */
375 { 0x0000, 0x0000, 0 }, /* R29 */
376 { 0x00FF, 0x01FF, 0 }, /* R30 - DAC Digital Volume Left */
377 { 0x00FF, 0x01FF, 0 }, /* R31 - DAC Digital Volume Right */
378 { 0x0FFF, 0x0FFF, 0 }, /* R32 - DAC Digital 0 */
379 { 0x1E4E, 0x1E4E, 0 }, /* R33 - DAC Digital 1 */
380 { 0x0000, 0x0000, 0 }, /* R34 */
381 { 0x0000, 0x0000, 0 }, /* R35 */
382 { 0x00FF, 0x01FF, 0 }, /* R36 - ADC Digital Volume Left */
383 { 0x00FF, 0x01FF, 0 }, /* R37 - ADC Digital Volume Right */
384 { 0x0073, 0x0073, 0 }, /* R38 - ADC Digital 0 */
385 { 0x1800, 0x1800, 0 }, /* R39 - Digital Microphone 0 */
386 { 0xDFEF, 0xDFEF, 0 }, /* R40 - DRC 0 */
387 { 0xFFFF, 0xFFFF, 0 }, /* R41 - DRC 1 */
388 { 0x003F, 0x003F, 0 }, /* R42 - DRC 2 */
389 { 0x07FF, 0x07FF, 0 }, /* R43 - DRC 3 */
390 { 0x009F, 0x009F, 0 }, /* R44 - Analogue Left Input 0 */
391 { 0x009F, 0x009F, 0 }, /* R45 - Analogue Right Input 0 */
392 { 0x007F, 0x007F, 0 }, /* R46 - Analogue Left Input 1 */
393 { 0x007F, 0x007F, 0 }, /* R47 - Analogue Right Input 1 */
394 { 0x0000, 0x0000, 0 }, /* R48 */
395 { 0x0000, 0x0000, 0 }, /* R49 */
396 { 0x0000, 0x0000, 0 }, /* R50 */
397 { 0x0000, 0x0000, 0 }, /* R51 */
398 { 0x0000, 0x0000, 0 }, /* R52 */
399 { 0x0000, 0x0000, 0 }, /* R53 */
400 { 0x0000, 0x0000, 0 }, /* R54 */
401 { 0x0000, 0x0000, 0 }, /* R55 */
402 { 0x0000, 0x0000, 0 }, /* R56 */
403 { 0x017F, 0x01FF, 0 }, /* R57 - Analogue OUT1 Left */
404 { 0x017F, 0x01FF, 0 }, /* R58 - Analogue OUT1 Right */
405 { 0x017F, 0x01FF, 0 }, /* R59 - Analogue OUT2 Left */
406 { 0x017F, 0x01FF, 0 }, /* R60 - Analogue OUT2 Right */
407 { 0x000F, 0x000F, 0 }, /* R61 - Analogue OUT12 ZC */
408 { 0x0000, 0x0000, 0 }, /* R62 */
409 { 0x0000, 0x0000, 0 }, /* R63 */
410 { 0x0000, 0x0000, 0 }, /* R64 */
411 { 0x0000, 0x0000, 0 }, /* R65 */
412 { 0x0000, 0x0000, 0 }, /* R66 */
413 { 0x000F, 0x000F, 0 }, /* R67 - DC Servo 0 */
414 { 0xFFFF, 0xFFFF, 1 }, /* R68 - DC Servo 1 */
415 { 0x0F0F, 0x0F0F, 0 }, /* R69 - DC Servo 2 */
416 { 0x0000, 0x0000, 0 }, /* R70 */
417 { 0x007F, 0x007F, 0 }, /* R71 - DC Servo 4 */
418 { 0x007F, 0x007F, 0 }, /* R72 - DC Servo 5 */
419 { 0x00FF, 0x00FF, 1 }, /* R73 - DC Servo 6 */
420 { 0x00FF, 0x00FF, 1 }, /* R74 - DC Servo 7 */
421 { 0x00FF, 0x00FF, 1 }, /* R75 - DC Servo 8 */
422 { 0x00FF, 0x00FF, 1 }, /* R76 - DC Servo 9 */
423 { 0x0FFF, 0x0000, 1 }, /* R77 - DC Servo Readback 0 */
424 { 0x0000, 0x0000, 0 }, /* R78 */
425 { 0x0000, 0x0000, 0 }, /* R79 */
426 { 0x0000, 0x0000, 0 }, /* R80 */
427 { 0x0000, 0x0000, 0 }, /* R81 */
428 { 0x0000, 0x0000, 0 }, /* R82 */
429 { 0x0000, 0x0000, 0 }, /* R83 */
430 { 0x0000, 0x0000, 0 }, /* R84 */
431 { 0x0000, 0x0000, 0 }, /* R85 */
432 { 0x0000, 0x0000, 0 }, /* R86 */
433 { 0x0000, 0x0000, 0 }, /* R87 */
434 { 0x0000, 0x0000, 0 }, /* R88 */
435 { 0x0000, 0x0000, 0 }, /* R89 */
436 { 0x00FF, 0x00FF, 0 }, /* R90 - Analogue HP 0 */
437 { 0x0000, 0x0000, 0 }, /* R91 */
438 { 0x0000, 0x0000, 0 }, /* R92 */
439 { 0x0000, 0x0000, 0 }, /* R93 */
440 { 0x00FF, 0x00FF, 0 }, /* R94 - Analogue Lineout 0 */
441 { 0x0000, 0x0000, 0 }, /* R95 */
442 { 0x0000, 0x0000, 0 }, /* R96 */
443 { 0x0000, 0x0000, 0 }, /* R97 */
444 { 0x0001, 0x0001, 0 }, /* R98 - Charge Pump 0 */
445 { 0x0000, 0x0000, 0 }, /* R99 */
446 { 0x0000, 0x0000, 0 }, /* R100 */
447 { 0x0000, 0x0000, 0 }, /* R101 */
448 { 0x0000, 0x0000, 0 }, /* R102 */
449 { 0x0000, 0x0000, 0 }, /* R103 */
450 { 0x0001, 0x0001, 0 }, /* R104 - Class W 0 */
451 { 0x0000, 0x0000, 0 }, /* R105 */
452 { 0x0000, 0x0000, 0 }, /* R106 */
453 { 0x0000, 0x0000, 0 }, /* R107 */
454 { 0x011F, 0x011F, 0 }, /* R108 - Write Sequencer 0 */
455 { 0x7FFF, 0x7FFF, 0 }, /* R109 - Write Sequencer 1 */
456 { 0x4FFF, 0x4FFF, 0 }, /* R110 - Write Sequencer 2 */
457 { 0x003F, 0x033F, 0 }, /* R111 - Write Sequencer 3 */
458 { 0x03F1, 0x0000, 0 }, /* R112 - Write Sequencer 4 */
459 { 0x0000, 0x0000, 0 }, /* R113 */
460 { 0x0000, 0x0000, 0 }, /* R114 */
461 { 0x0000, 0x0000, 0 }, /* R115 */
462 { 0x0007, 0x0007, 0 }, /* R116 - FLL Control 1 */
463 { 0x3F77, 0x3F77, 0 }, /* R117 - FLL Control 2 */
464 { 0xFFFF, 0xFFFF, 0 }, /* R118 - FLL Control 3 */
465 { 0x7FEF, 0x7FEF, 0 }, /* R119 - FLL Control 4 */
466 { 0x001B, 0x001B, 0 }, /* R120 - FLL Control 5 */
467 { 0x003F, 0x003F, 0 }, /* R121 - GPIO Control 1 */
468 { 0x003F, 0x003F, 0 }, /* R122 - GPIO Control 2 */
469 { 0x003F, 0x003F, 0 }, /* R123 - GPIO Control 3 */
470 { 0x038F, 0x038F, 0 }, /* R124 - GPIO Control 4 */
471 { 0x0000, 0x0000, 0 }, /* R125 */
472 { 0x00FF, 0x00FF, 0 }, /* R126 - Digital Pulls */
473 { 0x07FF, 0x03FF, 1 }, /* R127 - Interrupt Status */
474 { 0x03FF, 0x03FF, 0 }, /* R128 - Interrupt Status Mask */
475 { 0x03FF, 0x03FF, 0 }, /* R129 - Interrupt Polarity */
476 { 0x03FF, 0x03FF, 0 }, /* R130 - Interrupt Debounce */
477 { 0x0000, 0x0000, 0 }, /* R131 */
478 { 0x0000, 0x0000, 0 }, /* R132 */
479 { 0x0000, 0x0000, 0 }, /* R133 */
480 { 0x0001, 0x0001, 0 }, /* R134 - EQ1 */
481 { 0x001F, 0x001F, 0 }, /* R135 - EQ2 */
482 { 0x001F, 0x001F, 0 }, /* R136 - EQ3 */
483 { 0x001F, 0x001F, 0 }, /* R137 - EQ4 */
484 { 0x001F, 0x001F, 0 }, /* R138 - EQ5 */
485 { 0x001F, 0x001F, 0 }, /* R139 - EQ6 */
486 { 0xFFFF, 0xFFFF, 0 }, /* R140 - EQ7 */
487 { 0xFFFF, 0xFFFF, 0 }, /* R141 - EQ8 */
488 { 0xFFFF, 0xFFFF, 0 }, /* R142 - EQ9 */
489 { 0xFFFF, 0xFFFF, 0 }, /* R143 - EQ10 */
490 { 0xFFFF, 0xFFFF, 0 }, /* R144 - EQ11 */
491 { 0xFFFF, 0xFFFF, 0 }, /* R145 - EQ12 */
492 { 0xFFFF, 0xFFFF, 0 }, /* R146 - EQ13 */
493 { 0xFFFF, 0xFFFF, 0 }, /* R147 - EQ14 */
494 { 0xFFFF, 0xFFFF, 0 }, /* R148 - EQ15 */
495 { 0xFFFF, 0xFFFF, 0 }, /* R149 - EQ16 */
496 { 0xFFFF, 0xFFFF, 0 }, /* R150 - EQ17 */
497 { 0xFFFF, 0xFFFF, 0 }, /* R151wm8523_dai - EQ18 */
498 { 0xFFFF, 0xFFFF, 0 }, /* R152 - EQ19 */
499 { 0xFFFF, 0xFFFF, 0 }, /* R153 - EQ20 */
500 { 0xFFFF, 0xFFFF, 0 }, /* R154 - EQ21 */
501 { 0xFFFF, 0xFFFF, 0 }, /* R155 - EQ22 */
502 { 0xFFFF, 0xFFFF, 0 }, /* R156 - EQ23 */
503 { 0xFFFF, 0xFFFF, 0 }, /* R157 - EQ24 */
504 { 0x0000, 0x0000, 0 }, /* R158 */
505 { 0x0000, 0x0000, 0 }, /* R159 */
506 { 0x0000, 0x0000, 0 }, /* R160 */
507 { 0x0002, 0x0002, 0 }, /* R161 - Control Interface Test 1 */
508 { 0x0000, 0x0000, 0 }, /* R162 */
509 { 0x0000, 0x0000, 0 }, /* R163 */
510 { 0x0000, 0x0000, 0 }, /* R164 */
511 { 0x0000, 0x0000, 0 }, /* R165 */
512 { 0x0000, 0x0000, 0 }, /* R166 */
513 { 0x0000, 0x0000, 0 }, /* R167 */
514 { 0x0000, 0x0000, 0 }, /* R168 */
515 { 0x0000, 0x0000, 0 }, /* R169 */
516 { 0x0000, 0x0000, 0 }, /* R170 */
517 { 0x0000, 0x0000, 0 }, /* R171 */
518 { 0x0000, 0x0000, 0 }, /* R172 */
519 { 0x0000, 0x0000, 0 }, /* R173 */
520 { 0x0000, 0x0000, 0 }, /* R174 */
521 { 0x0000, 0x0000, 0 }, /* R175 */
522 { 0x0000, 0x0000, 0 }, /* R176 */
523 { 0x0000, 0x0000, 0 }, /* R177 */
524 { 0x0000, 0x0000, 0 }, /* R178 */
525 { 0x0000, 0x0000, 0 }, /* R179 */
526 { 0x0000, 0x0000, 0 }, /* R180 */
527 { 0x0000, 0x0000, 0 }, /* R181 */
528 { 0x0000, 0x0000, 0 }, /* R182 */
529 { 0x0000, 0x0000, 0 }, /* R183 */
530 { 0x0000, 0x0000, 0 }, /* R184 */
531 { 0x0000, 0x0000, 0 }, /* R185 */
532 { 0x0000, 0x0000, 0 }, /* R186 */
533 { 0x0000, 0x0000, 0 }, /* R187 */
534 { 0x0000, 0x0000, 0 }, /* R188 */
535 { 0x0000, 0x0000, 0 }, /* R189 */
536 { 0x0000, 0x0000, 0 }, /* R190 */
537 { 0x0000, 0x0000, 0 }, /* R191 */
538 { 0x0000, 0x0000, 0 }, /* R192 */
539 { 0x0000, 0x0000, 0 }, /* R193 */
540 { 0x0000, 0x0000, 0 }, /* R194 */
541 { 0x0000, 0x0000, 0 }, /* R195 */
542 { 0x0000, 0x0000, 0 }, /* R196 */
543 { 0x0000, 0x0000, 0 }, /* R197 */
544 { 0x0000, 0x0000, 0 }, /* R198 */
545 { 0x0000, 0x0000, 0 }, /* R199 */
546 { 0x0000, 0x0000, 0 }, /* R200 */
547 { 0x0000, 0x0000, 0 }, /* R201 */
548 { 0x0000, 0x0000, 0 }, /* R202 */
549 { 0x0000, 0x0000, 0 }, /* R203 */
550 { 0x0070, 0x0070, 0 }, /* R204 - Analogue Output Bias 0 */
551 { 0x0000, 0x0000, 0 }, /* R205 */
552 { 0x0000, 0x0000, 0 }, /* R206 */
553 { 0x0000, 0x0000, 0 }, /* R207 */
554 { 0x0000, 0x0000, 0 }, /* R208 */
555 { 0x0000, 0x0000, 0 }, /* R209 */
556 { 0x0000, 0x0000, 0 }, /* R210 */
557 { 0x0000, 0x0000, 0 }, /* R211 */
558 { 0x0000, 0x0000, 0 }, /* R212 */
559 { 0x0000, 0x0000, 0 }, /* R213 */
560 { 0x0000, 0x0000, 0 }, /* R214 */
561 { 0x0000, 0x0000, 0 }, /* R215 */
562 { 0x0000, 0x0000, 0 }, /* R216 */
563 { 0x0000, 0x0000, 0 }, /* R217 */
564 { 0x0000, 0x0000, 0 }, /* R218 */
565 { 0x0000, 0x0000, 0 }, /* R219 */
566 { 0x0000, 0x0000, 0 }, /* R220 */
567 { 0x0000, 0x0000, 0 }, /* R221 */
568 { 0x0000, 0x0000, 0 }, /* R222 */
569 { 0x0000, 0x0000, 0 }, /* R223 */
570 { 0x0000, 0x0000, 0 }, /* R224 */
571 { 0x0000, 0x0000, 0 }, /* R225 */
572 { 0x0000, 0x0000, 0 }, /* R226 */
573 { 0x0000, 0x0000, 0 }, /* R227 */
574 { 0x0000, 0x0000, 0 }, /* R228 */
575 { 0x0000, 0x0000, 0 }, /* R229 */
576 { 0x0000, 0x0000, 0 }, /* R230 */
577 { 0x0000, 0x0000, 0 }, /* R231 */
578 { 0x0000, 0x0000, 0 }, /* R232 */
579 { 0x0000, 0x0000, 0 }, /* R233 */
580 { 0x0000, 0x0000, 0 }, /* R234 */
581 { 0x0000, 0x0000, 0 }, /* R235 */
582 { 0x0000, 0x0000, 0 }, /* R236 */
583 { 0x0000, 0x0000, 0 }, /* R237 */
584 { 0x0000, 0x0000, 0 }, /* R238 */
585 { 0x0000, 0x0000, 0 }, /* R239 */
586 { 0x0000, 0x0000, 0 }, /* R240 */
587 { 0x0000, 0x0000, 0 }, /* R241 */
588 { 0x0000, 0x0000, 0 }, /* R242 */
589 { 0x0000, 0x0000, 0 }, /* R243 */
590 { 0x0000, 0x0000, 0 }, /* R244 */
591 { 0x0000, 0x0000, 0 }, /* R245 */
592 { 0x0000, 0x0000, 0 }, /* R246 */
593 { 0x0001, 0x0001, 0 }, /* R247 - FLL NCO Test 0 */
594 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */
595};
596 204
597static int wm8904_volatile_register(struct snd_soc_codec *codec, unsigned int reg) 205static bool wm8904_readable_register(struct device *dev, unsigned int reg)
598{ 206{
599 return wm8904_access[reg].vol; 207 switch (reg) {
208 case WM8904_SW_RESET_AND_ID:
209 case WM8904_REVISION:
210 case WM8904_BIAS_CONTROL_0:
211 case WM8904_VMID_CONTROL_0:
212 case WM8904_MIC_BIAS_CONTROL_0:
213 case WM8904_MIC_BIAS_CONTROL_1:
214 case WM8904_ANALOGUE_DAC_0:
215 case WM8904_MIC_FILTER_CONTROL:
216 case WM8904_ANALOGUE_ADC_0:
217 case WM8904_POWER_MANAGEMENT_0:
218 case WM8904_POWER_MANAGEMENT_2:
219 case WM8904_POWER_MANAGEMENT_3:
220 case WM8904_POWER_MANAGEMENT_6:
221 case WM8904_CLOCK_RATES_0:
222 case WM8904_CLOCK_RATES_1:
223 case WM8904_CLOCK_RATES_2:
224 case WM8904_AUDIO_INTERFACE_0:
225 case WM8904_AUDIO_INTERFACE_1:
226 case WM8904_AUDIO_INTERFACE_2:
227 case WM8904_AUDIO_INTERFACE_3:
228 case WM8904_DAC_DIGITAL_VOLUME_LEFT:
229 case WM8904_DAC_DIGITAL_VOLUME_RIGHT:
230 case WM8904_DAC_DIGITAL_0:
231 case WM8904_DAC_DIGITAL_1:
232 case WM8904_ADC_DIGITAL_VOLUME_LEFT:
233 case WM8904_ADC_DIGITAL_VOLUME_RIGHT:
234 case WM8904_ADC_DIGITAL_0:
235 case WM8904_DIGITAL_MICROPHONE_0:
236 case WM8904_DRC_0:
237 case WM8904_DRC_1:
238 case WM8904_DRC_2:
239 case WM8904_DRC_3:
240 case WM8904_ANALOGUE_LEFT_INPUT_0:
241 case WM8904_ANALOGUE_RIGHT_INPUT_0:
242 case WM8904_ANALOGUE_LEFT_INPUT_1:
243 case WM8904_ANALOGUE_RIGHT_INPUT_1:
244 case WM8904_ANALOGUE_OUT1_LEFT:
245 case WM8904_ANALOGUE_OUT1_RIGHT:
246 case WM8904_ANALOGUE_OUT2_LEFT:
247 case WM8904_ANALOGUE_OUT2_RIGHT:
248 case WM8904_ANALOGUE_OUT12_ZC:
249 case WM8904_DC_SERVO_0:
250 case WM8904_DC_SERVO_1:
251 case WM8904_DC_SERVO_2:
252 case WM8904_DC_SERVO_4:
253 case WM8904_DC_SERVO_5:
254 case WM8904_DC_SERVO_6:
255 case WM8904_DC_SERVO_7:
256 case WM8904_DC_SERVO_8:
257 case WM8904_DC_SERVO_9:
258 case WM8904_DC_SERVO_READBACK_0:
259 case WM8904_ANALOGUE_HP_0:
260 case WM8904_ANALOGUE_LINEOUT_0:
261 case WM8904_CHARGE_PUMP_0:
262 case WM8904_CLASS_W_0:
263 case WM8904_WRITE_SEQUENCER_0:
264 case WM8904_WRITE_SEQUENCER_1:
265 case WM8904_WRITE_SEQUENCER_2:
266 case WM8904_WRITE_SEQUENCER_3:
267 case WM8904_WRITE_SEQUENCER_4:
268 case WM8904_FLL_CONTROL_1:
269 case WM8904_FLL_CONTROL_2:
270 case WM8904_FLL_CONTROL_3:
271 case WM8904_FLL_CONTROL_4:
272 case WM8904_FLL_CONTROL_5:
273 case WM8904_GPIO_CONTROL_1:
274 case WM8904_GPIO_CONTROL_2:
275 case WM8904_GPIO_CONTROL_3:
276 case WM8904_GPIO_CONTROL_4:
277 case WM8904_DIGITAL_PULLS:
278 case WM8904_INTERRUPT_STATUS:
279 case WM8904_INTERRUPT_STATUS_MASK:
280 case WM8904_INTERRUPT_POLARITY:
281 case WM8904_INTERRUPT_DEBOUNCE:
282 case WM8904_EQ1:
283 case WM8904_EQ2:
284 case WM8904_EQ3:
285 case WM8904_EQ4:
286 case WM8904_EQ5:
287 case WM8904_EQ6:
288 case WM8904_EQ7:
289 case WM8904_EQ8:
290 case WM8904_EQ9:
291 case WM8904_EQ10:
292 case WM8904_EQ11:
293 case WM8904_EQ12:
294 case WM8904_EQ13:
295 case WM8904_EQ14:
296 case WM8904_EQ15:
297 case WM8904_EQ16:
298 case WM8904_EQ17:
299 case WM8904_EQ18:
300 case WM8904_EQ19:
301 case WM8904_EQ20:
302 case WM8904_EQ21:
303 case WM8904_EQ22:
304 case WM8904_EQ23:
305 case WM8904_EQ24:
306 case WM8904_CONTROL_INTERFACE_TEST_1:
307 case WM8904_ADC_TEST_0:
308 case WM8904_ANALOGUE_OUTPUT_BIAS_0:
309 case WM8904_FLL_NCO_TEST_0:
310 case WM8904_FLL_NCO_TEST_1:
311 return true;
312 default:
313 return true;
314 }
600} 315}
601 316
602static int wm8904_reset(struct snd_soc_codec *codec) 317static int wm8904_reset(struct snd_soc_codec *codec)
@@ -855,6 +570,29 @@ static const char *hpf_mode_text[] = {
855static const struct soc_enum hpf_mode = 570static const struct soc_enum hpf_mode =
856 SOC_ENUM_SINGLE(WM8904_ADC_DIGITAL_0, 5, 4, hpf_mode_text); 571 SOC_ENUM_SINGLE(WM8904_ADC_DIGITAL_0, 5, 4, hpf_mode_text);
857 572
573static int wm8904_adc_osr_put(struct snd_kcontrol *kcontrol,
574 struct snd_ctl_elem_value *ucontrol)
575{
576 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
577 unsigned int val;
578 int ret;
579
580 ret = snd_soc_put_volsw(kcontrol, ucontrol);
581 if (ret < 0)
582 return ret;
583
584 if (ucontrol->value.integer.value[0])
585 val = 0;
586 else
587 val = WM8904_ADC_128_OSR_TST_MODE | WM8904_ADC_BIASX1P5;
588
589 snd_soc_update_bits(codec, WM8904_ADC_TEST_0,
590 WM8904_ADC_128_OSR_TST_MODE | WM8904_ADC_BIASX1P5,
591 val);
592
593 return ret;
594}
595
858static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = { 596static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = {
859SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT, 597SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT,
860 WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv), 598 WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv),
@@ -871,7 +609,12 @@ SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0,
871SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0), 609SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0),
872SOC_ENUM("High Pass Filter Mode", hpf_mode), 610SOC_ENUM("High Pass Filter Mode", hpf_mode),
873 611
874SOC_SINGLE("ADC 128x OSR Switch", WM8904_ANALOGUE_ADC_0, 0, 1, 0), 612{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
613 .name = "ADC 128x OSR Switch",
614 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,
615 .put = wm8904_adc_osr_put,
616 .private_value = SOC_SINGLE_VALUE(WM8904_ANALOGUE_ADC_0, 0, 1, 0),
617},
875}; 618};
876 619
877static const char *drc_path_text[] = { 620static const char *drc_path_text[] = {
@@ -1433,11 +1176,11 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
1433 1176
1434 switch (wm8904->devtype) { 1177 switch (wm8904->devtype) {
1435 case WM8904: 1178 case WM8904:
1436 snd_soc_add_controls(codec, wm8904_adc_snd_controls, 1179 snd_soc_add_codec_controls(codec, wm8904_adc_snd_controls,
1437 ARRAY_SIZE(wm8904_adc_snd_controls)); 1180 ARRAY_SIZE(wm8904_adc_snd_controls));
1438 snd_soc_add_controls(codec, wm8904_dac_snd_controls, 1181 snd_soc_add_codec_controls(codec, wm8904_dac_snd_controls,
1439 ARRAY_SIZE(wm8904_dac_snd_controls)); 1182 ARRAY_SIZE(wm8904_dac_snd_controls));
1440 snd_soc_add_controls(codec, wm8904_snd_controls, 1183 snd_soc_add_codec_controls(codec, wm8904_snd_controls,
1441 ARRAY_SIZE(wm8904_snd_controls)); 1184 ARRAY_SIZE(wm8904_snd_controls));
1442 1185
1443 snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets, 1186 snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets,
@@ -1458,7 +1201,7 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
1458 break; 1201 break;
1459 1202
1460 case WM8912: 1203 case WM8912:
1461 snd_soc_add_controls(codec, wm8904_dac_snd_controls, 1204 snd_soc_add_codec_controls(codec, wm8904_dac_snd_controls,
1462 ARRAY_SIZE(wm8904_dac_snd_controls)); 1205 ARRAY_SIZE(wm8904_dac_snd_controls));
1463 1206
1464 snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets, 1207 snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets,
@@ -2088,32 +1831,6 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
2088 return 0; 1831 return 0;
2089} 1832}
2090 1833
2091static void wm8904_sync_cache(struct snd_soc_codec *codec)
2092{
2093 u16 *reg_cache = codec->reg_cache;
2094 int i;
2095
2096 if (!codec->cache_sync)
2097 return;
2098
2099 codec->cache_only = 0;
2100
2101 /* Sync back cached values if they're different from the
2102 * hardware default.
2103 */
2104 for (i = 1; i < codec->driver->reg_cache_size; i++) {
2105 if (!wm8904_access[i].writable)
2106 continue;
2107
2108 if (reg_cache[i] == wm8904_reg[i])
2109 continue;
2110
2111 snd_soc_write(codec, i, reg_cache[i]);
2112 }
2113
2114 codec->cache_sync = 0;
2115}
2116
2117static int wm8904_set_bias_level(struct snd_soc_codec *codec, 1834static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2118 enum snd_soc_bias_level level) 1835 enum snd_soc_bias_level level)
2119{ 1836{
@@ -2146,7 +1863,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2146 return ret; 1863 return ret;
2147 } 1864 }
2148 1865
2149 wm8904_sync_cache(codec); 1866 regcache_sync(wm8904->regmap);
2150 1867
2151 /* Enable bias */ 1868 /* Enable bias */
2152 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, 1869 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
@@ -2303,7 +2020,7 @@ static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec)
2303 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts; 2020 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts;
2304 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts; 2021 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts;
2305 2022
2306 ret = snd_soc_add_controls(codec, &control, 1); 2023 ret = snd_soc_add_codec_controls(codec, &control, 1);
2307 if (ret != 0) 2024 if (ret != 0)
2308 dev_err(codec->dev, 2025 dev_err(codec->dev,
2309 "Failed to add ReTune Mobile control: %d\n", ret); 2026 "Failed to add ReTune Mobile control: %d\n", ret);
@@ -2316,7 +2033,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
2316 int ret, i; 2033 int ret, i;
2317 2034
2318 if (!pdata) { 2035 if (!pdata) {
2319 snd_soc_add_controls(codec, wm8904_eq_controls, 2036 snd_soc_add_codec_controls(codec, wm8904_eq_controls,
2320 ARRAY_SIZE(wm8904_eq_controls)); 2037 ARRAY_SIZE(wm8904_eq_controls));
2321 return; 2038 return;
2322 } 2039 }
@@ -2344,7 +2061,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
2344 wm8904->drc_enum.max = pdata->num_drc_cfgs; 2061 wm8904->drc_enum.max = pdata->num_drc_cfgs;
2345 wm8904->drc_enum.texts = wm8904->drc_texts; 2062 wm8904->drc_enum.texts = wm8904->drc_texts;
2346 2063
2347 ret = snd_soc_add_controls(codec, &control, 1); 2064 ret = snd_soc_add_codec_controls(codec, &control, 1);
2348 if (ret != 0) 2065 if (ret != 0)
2349 dev_err(codec->dev, 2066 dev_err(codec->dev,
2350 "Failed to add DRC mode control: %d\n", ret); 2067 "Failed to add DRC mode control: %d\n", ret);
@@ -2358,7 +2075,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
2358 if (pdata->num_retune_mobile_cfgs) 2075 if (pdata->num_retune_mobile_cfgs)
2359 wm8904_handle_retune_mobile_pdata(codec); 2076 wm8904_handle_retune_mobile_pdata(codec);
2360 else 2077 else
2361 snd_soc_add_controls(codec, wm8904_eq_controls, 2078 snd_soc_add_codec_controls(codec, wm8904_eq_controls,
2362 ARRAY_SIZE(wm8904_eq_controls)); 2079 ARRAY_SIZE(wm8904_eq_controls));
2363} 2080}
2364 2081
@@ -2371,7 +2088,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
2371 int ret, i; 2088 int ret, i;
2372 2089
2373 codec->cache_sync = 1; 2090 codec->cache_sync = 1;
2374 codec->dapm.idle_bias_off = 1; 2091 codec->control_data = wm8904->regmap;
2375 2092
2376 switch (wm8904->devtype) { 2093 switch (wm8904->devtype) {
2377 case WM8904: 2094 case WM8904:
@@ -2385,7 +2102,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
2385 return -EINVAL; 2102 return -EINVAL;
2386 } 2103 }
2387 2104
2388 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 2105 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
2389 if (ret != 0) { 2106 if (ret != 0) {
2390 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 2107 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2391 return ret; 2108 return ret;
@@ -2413,7 +2130,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
2413 dev_err(codec->dev, "Failed to read ID register\n"); 2130 dev_err(codec->dev, "Failed to read ID register\n");
2414 goto err_enable; 2131 goto err_enable;
2415 } 2132 }
2416 if (ret != wm8904_reg[WM8904_SW_RESET_AND_ID]) { 2133 if (ret != 0x8904) {
2417 dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret); 2134 dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret);
2418 ret = -EINVAL; 2135 ret = -EINVAL;
2419 goto err_enable; 2136 goto err_enable;
@@ -2519,38 +2236,62 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8904 = {
2519 .suspend = wm8904_suspend, 2236 .suspend = wm8904_suspend,
2520 .resume = wm8904_resume, 2237 .resume = wm8904_resume,
2521 .set_bias_level = wm8904_set_bias_level, 2238 .set_bias_level = wm8904_set_bias_level,
2522 .reg_cache_size = ARRAY_SIZE(wm8904_reg), 2239 .idle_bias_off = true,
2523 .reg_word_size = sizeof(u16), 2240};
2524 .reg_cache_default = wm8904_reg, 2241
2525 .volatile_register = wm8904_volatile_register, 2242static const struct regmap_config wm8904_regmap = {
2243 .reg_bits = 8,
2244 .val_bits = 16,
2245
2246 .max_register = WM8904_MAX_REGISTER,
2247 .volatile_reg = wm8904_volatile_register,
2248 .readable_reg = wm8904_readable_register,
2249
2250 .cache_type = REGCACHE_RBTREE,
2251 .reg_defaults = wm8904_reg_defaults,
2252 .num_reg_defaults = ARRAY_SIZE(wm8904_reg_defaults),
2526}; 2253};
2527 2254
2528#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2529static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, 2255static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2530 const struct i2c_device_id *id) 2256 const struct i2c_device_id *id)
2531{ 2257{
2532 struct wm8904_priv *wm8904; 2258 struct wm8904_priv *wm8904;
2533 int ret; 2259 int ret;
2534 2260
2535 wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL); 2261 wm8904 = devm_kzalloc(&i2c->dev, sizeof(struct wm8904_priv),
2262 GFP_KERNEL);
2536 if (wm8904 == NULL) 2263 if (wm8904 == NULL)
2537 return -ENOMEM; 2264 return -ENOMEM;
2538 2265
2266 wm8904->regmap = regmap_init_i2c(i2c, &wm8904_regmap);
2267 if (IS_ERR(wm8904->regmap)) {
2268 ret = PTR_ERR(wm8904->regmap);
2269 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
2270 ret);
2271 return ret;
2272 }
2273
2539 wm8904->devtype = id->driver_data; 2274 wm8904->devtype = id->driver_data;
2540 i2c_set_clientdata(i2c, wm8904); 2275 i2c_set_clientdata(i2c, wm8904);
2541 wm8904->pdata = i2c->dev.platform_data; 2276 wm8904->pdata = i2c->dev.platform_data;
2542 2277
2543 ret = snd_soc_register_codec(&i2c->dev, 2278 ret = snd_soc_register_codec(&i2c->dev,
2544 &soc_codec_dev_wm8904, &wm8904_dai, 1); 2279 &soc_codec_dev_wm8904, &wm8904_dai, 1);
2545 if (ret < 0) 2280 if (ret != 0)
2546 kfree(wm8904); 2281 goto err;
2282
2283 return 0;
2284
2285err:
2286 regmap_exit(wm8904->regmap);
2547 return ret; 2287 return ret;
2548} 2288}
2549 2289
2550static __devexit int wm8904_i2c_remove(struct i2c_client *client) 2290static __devexit int wm8904_i2c_remove(struct i2c_client *client)
2551{ 2291{
2292 struct wm8904_priv *wm8904 = i2c_get_clientdata(client);
2552 snd_soc_unregister_codec(&client->dev); 2293 snd_soc_unregister_codec(&client->dev);
2553 kfree(i2c_get_clientdata(client)); 2294 regmap_exit(wm8904->regmap);
2554 return 0; 2295 return 0;
2555} 2296}
2556 2297
@@ -2571,27 +2312,22 @@ static struct i2c_driver wm8904_i2c_driver = {
2571 .remove = __devexit_p(wm8904_i2c_remove), 2312 .remove = __devexit_p(wm8904_i2c_remove),
2572 .id_table = wm8904_i2c_id, 2313 .id_table = wm8904_i2c_id,
2573}; 2314};
2574#endif
2575 2315
2576static int __init wm8904_modinit(void) 2316static int __init wm8904_modinit(void)
2577{ 2317{
2578 int ret = 0; 2318 int ret = 0;
2579#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2580 ret = i2c_add_driver(&wm8904_i2c_driver); 2319 ret = i2c_add_driver(&wm8904_i2c_driver);
2581 if (ret != 0) { 2320 if (ret != 0) {
2582 printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n", 2321 printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n",
2583 ret); 2322 ret);
2584 } 2323 }
2585#endif
2586 return ret; 2324 return ret;
2587} 2325}
2588module_init(wm8904_modinit); 2326module_init(wm8904_modinit);
2589 2327
2590static void __exit wm8904_exit(void) 2328static void __exit wm8904_exit(void)
2591{ 2329{
2592#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2593 i2c_del_driver(&wm8904_i2c_driver); 2330 i2c_del_driver(&wm8904_i2c_driver);
2594#endif
2595} 2331}
2596module_exit(wm8904_exit); 2332module_exit(wm8904_exit);
2597 2333