diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-10-18 14:49:03 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-11-08 09:14:02 -0500 |
commit | 7cfa467b74bb252cc3b74a1a1995c54fe43f90d5 (patch) | |
tree | f85adbfcf8105382ef513a79ac9a11b05725a741 /sound/soc/codecs/wm9081.c | |
parent | bd132ec585c498ee27d7eedf8569703606743928 (diff) |
ASoC: Convert WM9081 to direct regmap API usage
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm9081.c')
-rw-r--r-- | sound/soc/codecs/wm9081.c | 278 |
1 files changed, 180 insertions, 98 deletions
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 7563a91c9ed3..a8fc0659e4ac 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/pm.h> | 19 | #include <linux/pm.h> |
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/regmap.h> | ||
22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
23 | #include <sound/core.h> | 24 | #include <sound/core.h> |
24 | #include <sound/pcm.h> | 25 | #include <sound/pcm.h> |
@@ -30,69 +31,61 @@ | |||
30 | #include <sound/wm9081.h> | 31 | #include <sound/wm9081.h> |
31 | #include "wm9081.h" | 32 | #include "wm9081.h" |
32 | 33 | ||
33 | static u16 wm9081_reg_defaults[] = { | 34 | static struct reg_default wm9081_reg[] = { |
34 | 0x0000, /* R0 - Software Reset */ | 35 | { 0, 0x9081 }, /* R0 - Software Reset */ |
35 | 0x0000, /* R1 */ | 36 | { 2, 0x00B9 }, /* R2 - Analogue Lineout */ |
36 | 0x00B9, /* R2 - Analogue Lineout */ | 37 | { 3, 0x00B9 }, /* R3 - Analogue Speaker PGA */ |
37 | 0x00B9, /* R3 - Analogue Speaker PGA */ | 38 | { 4, 0x0001 }, /* R4 - VMID Control */ |
38 | 0x0001, /* R4 - VMID Control */ | 39 | { 5, 0x0068 }, /* R5 - Bias Control 1 */ |
39 | 0x0068, /* R5 - Bias Control 1 */ | 40 | { 7, 0x0000 }, /* R7 - Analogue Mixer */ |
40 | 0x0000, /* R6 */ | 41 | { 8, 0x0000 }, /* R8 - Anti Pop Control */ |
41 | 0x0000, /* R7 - Analogue Mixer */ | 42 | { 9, 0x01DB }, /* R9 - Analogue Speaker 1 */ |
42 | 0x0000, /* R8 - Anti Pop Control */ | 43 | { 10, 0x0018 }, /* R10 - Analogue Speaker 2 */ |
43 | 0x01DB, /* R9 - Analogue Speaker 1 */ | 44 | { 11, 0x0180 }, /* R11 - Power Management */ |
44 | 0x0018, /* R10 - Analogue Speaker 2 */ | 45 | { 12, 0x0000 }, /* R12 - Clock Control 1 */ |
45 | 0x0180, /* R11 - Power Management */ | 46 | { 13, 0x0038 }, /* R13 - Clock Control 2 */ |
46 | 0x0000, /* R12 - Clock Control 1 */ | 47 | { 14, 0x4000 }, /* R14 - Clock Control 3 */ |
47 | 0x0038, /* R13 - Clock Control 2 */ | 48 | { 16, 0x0000 }, /* R16 - FLL Control 1 */ |
48 | 0x4000, /* R14 - Clock Control 3 */ | 49 | { 17, 0x0200 }, /* R17 - FLL Control 2 */ |
49 | 0x0000, /* R15 */ | 50 | { 18, 0x0000 }, /* R18 - FLL Control 3 */ |
50 | 0x0000, /* R16 - FLL Control 1 */ | 51 | { 19, 0x0204 }, /* R19 - FLL Control 4 */ |
51 | 0x0200, /* R17 - FLL Control 2 */ | 52 | { 20, 0x0000 }, /* R20 - FLL Control 5 */ |
52 | 0x0000, /* R18 - FLL Control 3 */ | 53 | { 22, 0x0000 }, /* R22 - Audio Interface 1 */ |
53 | 0x0204, /* R19 - FLL Control 4 */ | 54 | { 23, 0x0002 }, /* R23 - Audio Interface 2 */ |
54 | 0x0000, /* R20 - FLL Control 5 */ | 55 | { 24, 0x0008 }, /* R24 - Audio Interface 3 */ |
55 | 0x0000, /* R21 */ | 56 | { 25, 0x0022 }, /* R25 - Audio Interface 4 */ |
56 | 0x0000, /* R22 - Audio Interface 1 */ | 57 | { 27, 0x0006 }, /* R27 - Interrupt Status Mask */ |
57 | 0x0002, /* R23 - Audio Interface 2 */ | 58 | { 28, 0x0000 }, /* R28 - Interrupt Polarity */ |
58 | 0x0008, /* R24 - Audio Interface 3 */ | 59 | { 29, 0x0000 }, /* R29 - Interrupt Control */ |
59 | 0x0022, /* R25 - Audio Interface 4 */ | 60 | { 30, 0x00C0 }, /* R30 - DAC Digital 1 */ |
60 | 0x0000, /* R26 - Interrupt Status */ | 61 | { 31, 0x0008 }, /* R31 - DAC Digital 2 */ |
61 | 0x0006, /* R27 - Interrupt Status Mask */ | 62 | { 32, 0x09AF }, /* R32 - DRC 1 */ |
62 | 0x0000, /* R28 - Interrupt Polarity */ | 63 | { 33, 0x4201 }, /* R33 - DRC 2 */ |
63 | 0x0000, /* R29 - Interrupt Control */ | 64 | { 34, 0x0000 }, /* R34 - DRC 3 */ |
64 | 0x00C0, /* R30 - DAC Digital 1 */ | 65 | { 35, 0x0000 }, /* R35 - DRC 4 */ |
65 | 0x0008, /* R31 - DAC Digital 2 */ | 66 | { 38, 0x0000 }, /* R38 - Write Sequencer 1 */ |
66 | 0x09AF, /* R32 - DRC 1 */ | 67 | { 39, 0x0000 }, /* R39 - Write Sequencer 2 */ |
67 | 0x4201, /* R33 - DRC 2 */ | 68 | { 40, 0x0002 }, /* R40 - MW Slave 1 */ |
68 | 0x0000, /* R34 - DRC 3 */ | 69 | { 42, 0x0000 }, /* R42 - EQ 1 */ |
69 | 0x0000, /* R35 - DRC 4 */ | 70 | { 43, 0x0000 }, /* R43 - EQ 2 */ |
70 | 0x0000, /* R36 */ | 71 | { 44, 0x0FCA }, /* R44 - EQ 3 */ |
71 | 0x0000, /* R37 */ | 72 | { 45, 0x0400 }, /* R45 - EQ 4 */ |
72 | 0x0000, /* R38 - Write Sequencer 1 */ | 73 | { 46, 0x00B8 }, /* R46 - EQ 5 */ |
73 | 0x0000, /* R39 - Write Sequencer 2 */ | 74 | { 47, 0x1EB5 }, /* R47 - EQ 6 */ |
74 | 0x0002, /* R40 - MW Slave 1 */ | 75 | { 48, 0xF145 }, /* R48 - EQ 7 */ |
75 | 0x0000, /* R41 */ | 76 | { 49, 0x0B75 }, /* R49 - EQ 8 */ |
76 | 0x0000, /* R42 - EQ 1 */ | 77 | { 50, 0x01C5 }, /* R50 - EQ 9 */ |
77 | 0x0000, /* R43 - EQ 2 */ | 78 | { 51, 0x169E }, /* R51 - EQ 10 */ |
78 | 0x0FCA, /* R44 - EQ 3 */ | 79 | { 52, 0xF829 }, /* R52 - EQ 11 */ |
79 | 0x0400, /* R45 - EQ 4 */ | 80 | { 53, 0x07AD }, /* R53 - EQ 12 */ |
80 | 0x00B8, /* R46 - EQ 5 */ | 81 | { 54, 0x1103 }, /* R54 - EQ 13 */ |
81 | 0x1EB5, /* R47 - EQ 6 */ | 82 | { 55, 0x1C58 }, /* R55 - EQ 14 */ |
82 | 0xF145, /* R48 - EQ 7 */ | 83 | { 56, 0xF373 }, /* R56 - EQ 15 */ |
83 | 0x0B75, /* R49 - EQ 8 */ | 84 | { 57, 0x0A54 }, /* R57 - EQ 16 */ |
84 | 0x01C5, /* R50 - EQ 9 */ | 85 | { 58, 0x0558 }, /* R58 - EQ 17 */ |
85 | 0x169E, /* R51 - EQ 10 */ | 86 | { 59, 0x0564 }, /* R59 - EQ 18 */ |
86 | 0xF829, /* R52 - EQ 11 */ | 87 | { 60, 0x0559 }, /* R60 - EQ 19 */ |
87 | 0x07AD, /* R53 - EQ 12 */ | 88 | { 61, 0x4000 }, /* R61 - EQ 20 */ |
88 | 0x1103, /* R54 - EQ 13 */ | ||
89 | 0x1C58, /* R55 - EQ 14 */ | ||
90 | 0xF373, /* R56 - EQ 15 */ | ||
91 | 0x0A54, /* R57 - EQ 16 */ | ||
92 | 0x0558, /* R58 - EQ 17 */ | ||
93 | 0x0564, /* R59 - EQ 18 */ | ||
94 | 0x0559, /* R60 - EQ 19 */ | ||
95 | 0x4000, /* R61 - EQ 20 */ | ||
96 | }; | 89 | }; |
97 | 90 | ||
98 | static struct { | 91 | static struct { |
@@ -156,7 +149,7 @@ static struct { | |||
156 | }; | 149 | }; |
157 | 150 | ||
158 | struct wm9081_priv { | 151 | struct wm9081_priv { |
159 | enum snd_soc_control_type control_type; | 152 | struct regmap *regmap; |
160 | int sysclk_source; | 153 | int sysclk_source; |
161 | int mclk_rate; | 154 | int mclk_rate; |
162 | int sysclk_rate; | 155 | int sysclk_rate; |
@@ -169,20 +162,84 @@ struct wm9081_priv { | |||
169 | struct wm9081_pdata pdata; | 162 | struct wm9081_pdata pdata; |
170 | }; | 163 | }; |
171 | 164 | ||
172 | static int wm9081_volatile_register(struct snd_soc_codec *codec, unsigned int reg) | 165 | static bool wm9081_volatile_register(struct device *dev, unsigned int reg) |
173 | { | 166 | { |
174 | switch (reg) { | 167 | switch (reg) { |
175 | case WM9081_SOFTWARE_RESET: | 168 | case WM9081_SOFTWARE_RESET: |
176 | case WM9081_INTERRUPT_STATUS: | 169 | case WM9081_INTERRUPT_STATUS: |
177 | return 1; | 170 | return true; |
178 | default: | 171 | default: |
179 | return 0; | 172 | return false; |
180 | } | 173 | } |
181 | } | 174 | } |
182 | 175 | ||
183 | static int wm9081_reset(struct snd_soc_codec *codec) | 176 | static bool wm9081_readable_register(struct device *dev, unsigned int reg) |
184 | { | 177 | { |
185 | return snd_soc_write(codec, WM9081_SOFTWARE_RESET, 0); | 178 | switch (reg) { |
179 | case WM9081_SOFTWARE_RESET: | ||
180 | case WM9081_ANALOGUE_LINEOUT: | ||
181 | case WM9081_ANALOGUE_SPEAKER_PGA: | ||
182 | case WM9081_VMID_CONTROL: | ||
183 | case WM9081_BIAS_CONTROL_1: | ||
184 | case WM9081_ANALOGUE_MIXER: | ||
185 | case WM9081_ANTI_POP_CONTROL: | ||
186 | case WM9081_ANALOGUE_SPEAKER_1: | ||
187 | case WM9081_ANALOGUE_SPEAKER_2: | ||
188 | case WM9081_POWER_MANAGEMENT: | ||
189 | case WM9081_CLOCK_CONTROL_1: | ||
190 | case WM9081_CLOCK_CONTROL_2: | ||
191 | case WM9081_CLOCK_CONTROL_3: | ||
192 | case WM9081_FLL_CONTROL_1: | ||
193 | case WM9081_FLL_CONTROL_2: | ||
194 | case WM9081_FLL_CONTROL_3: | ||
195 | case WM9081_FLL_CONTROL_4: | ||
196 | case WM9081_FLL_CONTROL_5: | ||
197 | case WM9081_AUDIO_INTERFACE_1: | ||
198 | case WM9081_AUDIO_INTERFACE_2: | ||
199 | case WM9081_AUDIO_INTERFACE_3: | ||
200 | case WM9081_AUDIO_INTERFACE_4: | ||
201 | case WM9081_INTERRUPT_STATUS: | ||
202 | case WM9081_INTERRUPT_STATUS_MASK: | ||
203 | case WM9081_INTERRUPT_POLARITY: | ||
204 | case WM9081_INTERRUPT_CONTROL: | ||
205 | case WM9081_DAC_DIGITAL_1: | ||
206 | case WM9081_DAC_DIGITAL_2: | ||
207 | case WM9081_DRC_1: | ||
208 | case WM9081_DRC_2: | ||
209 | case WM9081_DRC_3: | ||
210 | case WM9081_DRC_4: | ||
211 | case WM9081_WRITE_SEQUENCER_1: | ||
212 | case WM9081_WRITE_SEQUENCER_2: | ||
213 | case WM9081_MW_SLAVE_1: | ||
214 | case WM9081_EQ_1: | ||
215 | case WM9081_EQ_2: | ||
216 | case WM9081_EQ_3: | ||
217 | case WM9081_EQ_4: | ||
218 | case WM9081_EQ_5: | ||
219 | case WM9081_EQ_6: | ||
220 | case WM9081_EQ_7: | ||
221 | case WM9081_EQ_8: | ||
222 | case WM9081_EQ_9: | ||
223 | case WM9081_EQ_10: | ||
224 | case WM9081_EQ_11: | ||
225 | case WM9081_EQ_12: | ||
226 | case WM9081_EQ_13: | ||
227 | case WM9081_EQ_14: | ||
228 | case WM9081_EQ_15: | ||
229 | case WM9081_EQ_16: | ||
230 | case WM9081_EQ_17: | ||
231 | case WM9081_EQ_18: | ||
232 | case WM9081_EQ_19: | ||
233 | case WM9081_EQ_20: | ||
234 | return true; | ||
235 | default: | ||
236 | return false; | ||
237 | } | ||
238 | } | ||
239 | |||
240 | static int wm9081_reset(struct regmap *map) | ||
241 | { | ||
242 | return regmap_write(map, WM9081_SOFTWARE_RESET, 0x9081); | ||
186 | } | 243 | } |
187 | 244 | ||
188 | static const DECLARE_TLV_DB_SCALE(drc_in_tlv, -4500, 75, 0); | 245 | static const DECLARE_TLV_DB_SCALE(drc_in_tlv, -4500, 75, 0); |
@@ -1215,25 +1272,14 @@ static int wm9081_probe(struct snd_soc_codec *codec) | |||
1215 | int ret; | 1272 | int ret; |
1216 | u16 reg; | 1273 | u16 reg; |
1217 | 1274 | ||
1218 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm9081->control_type); | 1275 | codec->control_data = wm9081->regmap; |
1276 | |||
1277 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
1219 | if (ret != 0) { | 1278 | if (ret != 0) { |
1220 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 1279 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
1221 | return ret; | 1280 | return ret; |
1222 | } | 1281 | } |
1223 | 1282 | ||
1224 | reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET); | ||
1225 | if (reg != 0x9081) { | ||
1226 | dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg); | ||
1227 | ret = -EINVAL; | ||
1228 | return ret; | ||
1229 | } | ||
1230 | |||
1231 | ret = wm9081_reset(codec); | ||
1232 | if (ret < 0) { | ||
1233 | dev_err(codec->dev, "Failed to issue reset\n"); | ||
1234 | return ret; | ||
1235 | } | ||
1236 | |||
1237 | reg = 0; | 1283 | reg = 0; |
1238 | if (wm9081->pdata.irq_high) | 1284 | if (wm9081->pdata.irq_high) |
1239 | reg |= WM9081_IRQ_POL; | 1285 | reg |= WM9081_IRQ_POL; |
@@ -1277,15 +1323,9 @@ static int wm9081_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
1277 | 1323 | ||
1278 | static int wm9081_resume(struct snd_soc_codec *codec) | 1324 | static int wm9081_resume(struct snd_soc_codec *codec) |
1279 | { | 1325 | { |
1280 | u16 *reg_cache = codec->reg_cache; | 1326 | struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); |
1281 | int i; | ||
1282 | |||
1283 | for (i = 0; i < codec->driver->reg_cache_size; i++) { | ||
1284 | if (i == WM9081_SOFTWARE_RESET) | ||
1285 | continue; | ||
1286 | 1327 | ||
1287 | snd_soc_write(codec, i, reg_cache[i]); | 1328 | regcache_sync(wm9081->regmap); |
1288 | } | ||
1289 | 1329 | ||
1290 | wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1330 | wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1291 | 1331 | ||
@@ -1305,11 +1345,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { | |||
1305 | .set_sysclk = wm9081_set_sysclk, | 1345 | .set_sysclk = wm9081_set_sysclk, |
1306 | .set_bias_level = wm9081_set_bias_level, | 1346 | .set_bias_level = wm9081_set_bias_level, |
1307 | 1347 | ||
1308 | .reg_cache_size = ARRAY_SIZE(wm9081_reg_defaults), | ||
1309 | .reg_word_size = sizeof(u16), | ||
1310 | .reg_cache_default = wm9081_reg_defaults, | ||
1311 | .volatile_register = wm9081_volatile_register, | ||
1312 | |||
1313 | .controls = wm9081_snd_controls, | 1348 | .controls = wm9081_snd_controls, |
1314 | .num_controls = ARRAY_SIZE(wm9081_snd_controls), | 1349 | .num_controls = ARRAY_SIZE(wm9081_snd_controls), |
1315 | .dapm_widgets = wm9081_dapm_widgets, | 1350 | .dapm_widgets = wm9081_dapm_widgets, |
@@ -1318,11 +1353,24 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { | |||
1318 | .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths), | 1353 | .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths), |
1319 | }; | 1354 | }; |
1320 | 1355 | ||
1356 | static const struct regmap_config wm9081_regmap = { | ||
1357 | .reg_bits = 8, | ||
1358 | .val_bits = 16, | ||
1359 | |||
1360 | .max_register = WM9081_MAX_REGISTER, | ||
1361 | .reg_defaults = wm9081_reg, | ||
1362 | .num_reg_defaults = ARRAY_SIZE(wm9081_reg), | ||
1363 | .volatile_reg = wm9081_volatile_register, | ||
1364 | .readable_reg = wm9081_readable_register, | ||
1365 | .cache_type = REGCACHE_RBTREE, | ||
1366 | }; | ||
1367 | |||
1321 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1368 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
1322 | static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, | 1369 | static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, |
1323 | const struct i2c_device_id *id) | 1370 | const struct i2c_device_id *id) |
1324 | { | 1371 | { |
1325 | struct wm9081_priv *wm9081; | 1372 | struct wm9081_priv *wm9081; |
1373 | unsigned int reg; | ||
1326 | int ret; | 1374 | int ret; |
1327 | 1375 | ||
1328 | wm9081 = kzalloc(sizeof(struct wm9081_priv), GFP_KERNEL); | 1376 | wm9081 = kzalloc(sizeof(struct wm9081_priv), GFP_KERNEL); |
@@ -1330,7 +1378,30 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, | |||
1330 | return -ENOMEM; | 1378 | return -ENOMEM; |
1331 | 1379 | ||
1332 | i2c_set_clientdata(i2c, wm9081); | 1380 | i2c_set_clientdata(i2c, wm9081); |
1333 | wm9081->control_type = SND_SOC_I2C; | 1381 | |
1382 | wm9081->regmap = regmap_init_i2c(i2c, &wm9081_regmap); | ||
1383 | if (IS_ERR(wm9081->regmap)) { | ||
1384 | ret = PTR_ERR(wm9081->regmap); | ||
1385 | dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); | ||
1386 | goto err; | ||
1387 | } | ||
1388 | |||
1389 | ret = regmap_read(wm9081->regmap, WM9081_SOFTWARE_RESET, ®); | ||
1390 | if (ret != 0) { | ||
1391 | dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); | ||
1392 | goto err_regmap; | ||
1393 | } | ||
1394 | if (reg != 0x9081) { | ||
1395 | dev_err(&i2c->dev, "Device is not a WM9081: ID=0x%x\n", reg); | ||
1396 | ret = -EINVAL; | ||
1397 | goto err_regmap; | ||
1398 | } | ||
1399 | |||
1400 | ret = wm9081_reset(wm9081->regmap); | ||
1401 | if (ret < 0) { | ||
1402 | dev_err(&i2c->dev, "Failed to issue reset\n"); | ||
1403 | goto err_regmap; | ||
1404 | } | ||
1334 | 1405 | ||
1335 | if (dev_get_platdata(&i2c->dev)) | 1406 | if (dev_get_platdata(&i2c->dev)) |
1336 | memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), | 1407 | memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), |
@@ -1339,13 +1410,24 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, | |||
1339 | ret = snd_soc_register_codec(&i2c->dev, | 1410 | ret = snd_soc_register_codec(&i2c->dev, |
1340 | &soc_codec_dev_wm9081, &wm9081_dai, 1); | 1411 | &soc_codec_dev_wm9081, &wm9081_dai, 1); |
1341 | if (ret < 0) | 1412 | if (ret < 0) |
1342 | kfree(wm9081); | 1413 | goto err_regmap; |
1414 | |||
1415 | return 0; | ||
1416 | |||
1417 | err_regmap: | ||
1418 | regmap_exit(wm9081->regmap); | ||
1419 | err: | ||
1420 | kfree(wm9081); | ||
1421 | |||
1343 | return ret; | 1422 | return ret; |
1344 | } | 1423 | } |
1345 | 1424 | ||
1346 | static __devexit int wm9081_i2c_remove(struct i2c_client *client) | 1425 | static __devexit int wm9081_i2c_remove(struct i2c_client *client) |
1347 | { | 1426 | { |
1427 | struct wm9081_priv *wm9081 = i2c_get_clientdata(client); | ||
1428 | |||
1348 | snd_soc_unregister_codec(&client->dev); | 1429 | snd_soc_unregister_codec(&client->dev); |
1430 | regmap_exit(wm9081->regmap); | ||
1349 | kfree(i2c_get_clientdata(client)); | 1431 | kfree(i2c_get_clientdata(client)); |
1350 | return 0; | 1432 | return 0; |
1351 | } | 1433 | } |