diff options
Diffstat (limited to 'sound/soc/codecs/wm8728.c')
-rw-r--r-- | sound/soc/codecs/wm8728.c | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 1467f97dce21..00a12a0c3919 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/regmap.h> | ||
20 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
22 | #include <linux/of_device.h> | 23 | #include <linux/of_device.h> |
@@ -35,16 +36,16 @@ | |||
35 | * the volume update bits, mute the output and enable infinite zero | 36 | * the volume update bits, mute the output and enable infinite zero |
36 | * detect. | 37 | * detect. |
37 | */ | 38 | */ |
38 | static const u16 wm8728_reg_defaults[] = { | 39 | static const struct reg_default wm8728_reg_defaults[] = { |
39 | 0x1ff, | 40 | { 0, 0x1ff }, |
40 | 0x1ff, | 41 | { 1, 0x1ff }, |
41 | 0x001, | 42 | { 2, 0x001 }, |
42 | 0x100, | 43 | { 3, 0x100 }, |
43 | }; | 44 | }; |
44 | 45 | ||
45 | /* codec private data */ | 46 | /* codec private data */ |
46 | struct wm8728_priv { | 47 | struct wm8728_priv { |
47 | enum snd_soc_control_type control_type; | 48 | struct regmap *regmap; |
48 | }; | 49 | }; |
49 | 50 | ||
50 | static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1); | 51 | static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1); |
@@ -162,8 +163,8 @@ static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
162 | static int wm8728_set_bias_level(struct snd_soc_codec *codec, | 163 | static int wm8728_set_bias_level(struct snd_soc_codec *codec, |
163 | enum snd_soc_bias_level level) | 164 | enum snd_soc_bias_level level) |
164 | { | 165 | { |
166 | struct wm8728_priv *wm8728 = snd_soc_codec_get_drvdata(codec); | ||
165 | u16 reg; | 167 | u16 reg; |
166 | int i; | ||
167 | 168 | ||
168 | switch (level) { | 169 | switch (level) { |
169 | case SND_SOC_BIAS_ON: | 170 | case SND_SOC_BIAS_ON: |
@@ -175,9 +176,7 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec, | |||
175 | snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4); | 176 | snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4); |
176 | 177 | ||
177 | /* ..then sync in the register cache. */ | 178 | /* ..then sync in the register cache. */ |
178 | for (i = 0; i < ARRAY_SIZE(wm8728_reg_defaults); i++) | 179 | regcache_sync(wm8728->regmap); |
179 | snd_soc_write(codec, i, | ||
180 | snd_soc_read(codec, i)); | ||
181 | } | 180 | } |
182 | break; | 181 | break; |
183 | 182 | ||
@@ -229,10 +228,9 @@ static int wm8728_resume(struct snd_soc_codec *codec) | |||
229 | 228 | ||
230 | static int wm8728_probe(struct snd_soc_codec *codec) | 229 | static int wm8728_probe(struct snd_soc_codec *codec) |
231 | { | 230 | { |
232 | struct wm8728_priv *wm8728 = snd_soc_codec_get_drvdata(codec); | ||
233 | int ret; | 231 | int ret; |
234 | 232 | ||
235 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8728->control_type); | 233 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
236 | if (ret < 0) { | 234 | if (ret < 0) { |
237 | printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n", | 235 | printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n", |
238 | ret); | 236 | ret); |
@@ -257,9 +255,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8728 = { | |||
257 | .suspend = wm8728_suspend, | 255 | .suspend = wm8728_suspend, |
258 | .resume = wm8728_resume, | 256 | .resume = wm8728_resume, |
259 | .set_bias_level = wm8728_set_bias_level, | 257 | .set_bias_level = wm8728_set_bias_level, |
260 | .reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults), | ||
261 | .reg_word_size = sizeof(u16), | ||
262 | .reg_cache_default = wm8728_reg_defaults, | ||
263 | .controls = wm8728_snd_controls, | 258 | .controls = wm8728_snd_controls, |
264 | .num_controls = ARRAY_SIZE(wm8728_snd_controls), | 259 | .num_controls = ARRAY_SIZE(wm8728_snd_controls), |
265 | .dapm_widgets = wm8728_dapm_widgets, | 260 | .dapm_widgets = wm8728_dapm_widgets, |
@@ -274,30 +269,43 @@ static const struct of_device_id wm8728_of_match[] = { | |||
274 | }; | 269 | }; |
275 | MODULE_DEVICE_TABLE(of, wm8728_of_match); | 270 | MODULE_DEVICE_TABLE(of, wm8728_of_match); |
276 | 271 | ||
272 | static const struct regmap_config wm8728_regmap = { | ||
273 | .reg_bits = 7, | ||
274 | .val_bits = 9, | ||
275 | .max_register = WM8728_IFCTL, | ||
276 | |||
277 | .reg_defaults = wm8728_reg_defaults, | ||
278 | .num_reg_defaults = ARRAY_SIZE(wm8728_reg_defaults), | ||
279 | .cache_type = REGCACHE_RBTREE, | ||
280 | }; | ||
281 | |||
277 | #if defined(CONFIG_SPI_MASTER) | 282 | #if defined(CONFIG_SPI_MASTER) |
278 | static int __devinit wm8728_spi_probe(struct spi_device *spi) | 283 | static int __devinit wm8728_spi_probe(struct spi_device *spi) |
279 | { | 284 | { |
280 | struct wm8728_priv *wm8728; | 285 | struct wm8728_priv *wm8728; |
281 | int ret; | 286 | int ret; |
282 | 287 | ||
283 | wm8728 = kzalloc(sizeof(struct wm8728_priv), GFP_KERNEL); | 288 | wm8728 = devm_kzalloc(&spi->dev, sizeof(struct wm8728_priv), |
289 | GFP_KERNEL); | ||
284 | if (wm8728 == NULL) | 290 | if (wm8728 == NULL) |
285 | return -ENOMEM; | 291 | return -ENOMEM; |
286 | 292 | ||
287 | wm8728->control_type = SND_SOC_SPI; | 293 | wm8728->regmap = devm_regmap_init_spi(spi, &wm8728_regmap); |
294 | if (IS_ERR(wm8728->regmap)) | ||
295 | return PTR_ERR(wm8728->regmap); | ||
296 | |||
288 | spi_set_drvdata(spi, wm8728); | 297 | spi_set_drvdata(spi, wm8728); |
289 | 298 | ||
290 | ret = snd_soc_register_codec(&spi->dev, | 299 | ret = snd_soc_register_codec(&spi->dev, |
291 | &soc_codec_dev_wm8728, &wm8728_dai, 1); | 300 | &soc_codec_dev_wm8728, &wm8728_dai, 1); |
292 | if (ret < 0) | 301 | |
293 | kfree(wm8728); | ||
294 | return ret; | 302 | return ret; |
295 | } | 303 | } |
296 | 304 | ||
297 | static int __devexit wm8728_spi_remove(struct spi_device *spi) | 305 | static int __devexit wm8728_spi_remove(struct spi_device *spi) |
298 | { | 306 | { |
299 | snd_soc_unregister_codec(&spi->dev); | 307 | snd_soc_unregister_codec(&spi->dev); |
300 | kfree(spi_get_drvdata(spi)); | 308 | |
301 | return 0; | 309 | return 0; |
302 | } | 310 | } |
303 | 311 | ||
@@ -319,24 +327,26 @@ static __devinit int wm8728_i2c_probe(struct i2c_client *i2c, | |||
319 | struct wm8728_priv *wm8728; | 327 | struct wm8728_priv *wm8728; |
320 | int ret; | 328 | int ret; |
321 | 329 | ||
322 | wm8728 = kzalloc(sizeof(struct wm8728_priv), GFP_KERNEL); | 330 | wm8728 = devm_kzalloc(&i2c->dev, sizeof(struct wm8728_priv), |
331 | GFP_KERNEL); | ||
323 | if (wm8728 == NULL) | 332 | if (wm8728 == NULL) |
324 | return -ENOMEM; | 333 | return -ENOMEM; |
325 | 334 | ||
335 | wm8728->regmap = devm_regmap_init_i2c(i2c, &wm8728_regmap); | ||
336 | if (IS_ERR(wm8728->regmap)) | ||
337 | return PTR_ERR(wm8728->regmap); | ||
338 | |||
326 | i2c_set_clientdata(i2c, wm8728); | 339 | i2c_set_clientdata(i2c, wm8728); |
327 | wm8728->control_type = SND_SOC_I2C; | ||
328 | 340 | ||
329 | ret = snd_soc_register_codec(&i2c->dev, | 341 | ret = snd_soc_register_codec(&i2c->dev, |
330 | &soc_codec_dev_wm8728, &wm8728_dai, 1); | 342 | &soc_codec_dev_wm8728, &wm8728_dai, 1); |
331 | if (ret < 0) | 343 | |
332 | kfree(wm8728); | ||
333 | return ret; | 344 | return ret; |
334 | } | 345 | } |
335 | 346 | ||
336 | static __devexit int wm8728_i2c_remove(struct i2c_client *client) | 347 | static __devexit int wm8728_i2c_remove(struct i2c_client *client) |
337 | { | 348 | { |
338 | snd_soc_unregister_codec(&client->dev); | 349 | snd_soc_unregister_codec(&client->dev); |
339 | kfree(i2c_get_clientdata(client)); | ||
340 | return 0; | 350 | return 0; |
341 | } | 351 | } |
342 | 352 | ||