aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8904.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2011-12-29 16:12:51 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-01-20 08:58:24 -0500
commit84d0d83180a8db564483f5e2ff58a7661d78858b (patch)
tree022f30dea3d9d0f4064738f6a6fd4dd8ae146c4e /sound/soc/codecs/wm8904.c
parent274eb8f9d8780903ccd40e007928f26c3a8c6e15 (diff)
ASoC: Convert WM8904 to direct regmap API usage
The device has a very sparse register map so should benefit from using a rbtree cache. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm8904.c')
-rw-r--r--sound/soc/codecs/wm8904.c768
1 files changed, 254 insertions, 514 deletions
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 673a2fe585bc..f2a740de3ad1 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,229 @@ 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_ANALOGUE_OUTPUT_BIAS_0:
308 case WM8904_FLL_NCO_TEST_0:
309 case WM8904_FLL_NCO_TEST_1:
310 return true;
311 default:
312 return true;
313 }
600} 314}
601 315
602static int wm8904_reset(struct snd_soc_codec *codec) 316static int wm8904_reset(struct snd_soc_codec *codec)
@@ -2120,7 +1834,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2120 return ret; 1834 return ret;
2121 } 1835 }
2122 1836
2123 snd_soc_cache_sync(codec); 1837 regcache_sync(wm8904->regmap);
2124 1838
2125 /* Enable bias */ 1839 /* Enable bias */
2126 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, 1840 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
@@ -2346,6 +2060,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
2346 2060
2347 codec->cache_sync = 1; 2061 codec->cache_sync = 1;
2348 codec->dapm.idle_bias_off = 1; 2062 codec->dapm.idle_bias_off = 1;
2063 codec->control_data = wm8904->regmap;
2349 2064
2350 switch (wm8904->devtype) { 2065 switch (wm8904->devtype) {
2351 case WM8904: 2066 case WM8904:
@@ -2359,7 +2074,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
2359 return -EINVAL; 2074 return -EINVAL;
2360 } 2075 }
2361 2076
2362 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 2077 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
2363 if (ret != 0) { 2078 if (ret != 0) {
2364 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 2079 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2365 return ret; 2080 return ret;
@@ -2387,7 +2102,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
2387 dev_err(codec->dev, "Failed to read ID register\n"); 2102 dev_err(codec->dev, "Failed to read ID register\n");
2388 goto err_enable; 2103 goto err_enable;
2389 } 2104 }
2390 if (ret != wm8904_reg[WM8904_SW_RESET_AND_ID]) { 2105 if (ret != 0x8904) {
2391 dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret); 2106 dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret);
2392 ret = -EINVAL; 2107 ret = -EINVAL;
2393 goto err_enable; 2108 goto err_enable;
@@ -2493,10 +2208,19 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8904 = {
2493 .suspend = wm8904_suspend, 2208 .suspend = wm8904_suspend,
2494 .resume = wm8904_resume, 2209 .resume = wm8904_resume,
2495 .set_bias_level = wm8904_set_bias_level, 2210 .set_bias_level = wm8904_set_bias_level,
2496 .reg_cache_size = ARRAY_SIZE(wm8904_reg), 2211};
2497 .reg_word_size = sizeof(u16), 2212
2498 .reg_cache_default = wm8904_reg, 2213static const struct regmap_config wm8904_regmap = {
2499 .volatile_register = wm8904_volatile_register, 2214 .reg_bits = 8,
2215 .val_bits = 16,
2216
2217 .max_register = WM8904_MAX_REGISTER,
2218 .volatile_reg = wm8904_volatile_register,
2219 .readable_reg = wm8904_readable_register,
2220
2221 .cache_type = REGCACHE_RBTREE,
2222 .reg_defaults = wm8904_reg_defaults,
2223 .num_reg_defaults = ARRAY_SIZE(wm8904_reg_defaults),
2500}; 2224};
2501 2225
2502static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, 2226static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
@@ -2510,19 +2234,35 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2510 if (wm8904 == NULL) 2234 if (wm8904 == NULL)
2511 return -ENOMEM; 2235 return -ENOMEM;
2512 2236
2237 wm8904->regmap = regmap_init_i2c(i2c, &wm8904_regmap);
2238 if (IS_ERR(wm8904->regmap)) {
2239 ret = PTR_ERR(wm8904->regmap);
2240 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
2241 ret);
2242 return ret;
2243 }
2244
2513 wm8904->devtype = id->driver_data; 2245 wm8904->devtype = id->driver_data;
2514 i2c_set_clientdata(i2c, wm8904); 2246 i2c_set_clientdata(i2c, wm8904);
2515 wm8904->pdata = i2c->dev.platform_data; 2247 wm8904->pdata = i2c->dev.platform_data;
2516 2248
2517 ret = snd_soc_register_codec(&i2c->dev, 2249 ret = snd_soc_register_codec(&i2c->dev,
2518 &soc_codec_dev_wm8904, &wm8904_dai, 1); 2250 &soc_codec_dev_wm8904, &wm8904_dai, 1);
2251 if (ret != 0)
2252 goto err;
2253
2254 return 0;
2519 2255
2256err:
2257 regmap_exit(wm8904->regmap);
2520 return ret; 2258 return ret;
2521} 2259}
2522 2260
2523static __devexit int wm8904_i2c_remove(struct i2c_client *client) 2261static __devexit int wm8904_i2c_remove(struct i2c_client *client)
2524{ 2262{
2263 struct wm8904_priv *wm8904 = i2c_get_clientdata(client);
2525 snd_soc_unregister_codec(&client->dev); 2264 snd_soc_unregister_codec(&client->dev);
2265 regmap_exit(wm8904->regmap);
2526 return 0; 2266 return 0;
2527} 2267}
2528 2268