diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-09-10 04:27:45 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-09-10 05:25:46 -0400 |
commit | b9288f49dc5ac8342cc34163093c9f7d096b6378 (patch) | |
tree | 089c2ee2336e796adef254c06c7bfdd2300d7240 /sound/soc/codecs/wm8523.c | |
parent | 719b0c593cbb2a199e977b4dcca1d096a4a0d6a7 (diff) |
ASoC: wm8523: Convert to direct regmap API usage
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm8523.c')
-rw-r--r-- | sound/soc/codecs/wm8523.c | 69 |
1 files changed, 38 insertions, 31 deletions
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index c4c64e225c42..d7d5fe6866a6 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.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 <linux/of_device.h> | 23 | #include <linux/of_device.h> |
@@ -39,33 +40,31 @@ static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = { | |||
39 | 40 | ||
40 | /* codec private data */ | 41 | /* codec private data */ |
41 | struct wm8523_priv { | 42 | struct wm8523_priv { |
42 | enum snd_soc_control_type control_type; | 43 | struct regmap *regmap; |
43 | struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES]; | 44 | struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES]; |
44 | unsigned int sysclk; | 45 | unsigned int sysclk; |
45 | unsigned int rate_constraint_list[WM8523_NUM_RATES]; | 46 | unsigned int rate_constraint_list[WM8523_NUM_RATES]; |
46 | struct snd_pcm_hw_constraint_list rate_constraint; | 47 | struct snd_pcm_hw_constraint_list rate_constraint; |
47 | }; | 48 | }; |
48 | 49 | ||
49 | static const u16 wm8523_reg[WM8523_REGISTER_COUNT] = { | 50 | static const struct reg_default wm8523_reg_defaults[] = { |
50 | 0x8523, /* R0 - DEVICE_ID */ | 51 | { 2, 0x0000 }, /* R2 - PSCTRL1 */ |
51 | 0x0001, /* R1 - REVISION */ | 52 | { 3, 0x1812 }, /* R3 - AIF_CTRL1 */ |
52 | 0x0000, /* R2 - PSCTRL1 */ | 53 | { 4, 0x0000 }, /* R4 - AIF_CTRL2 */ |
53 | 0x1812, /* R3 - AIF_CTRL1 */ | 54 | { 5, 0x0001 }, /* R5 - DAC_CTRL3 */ |
54 | 0x0000, /* R4 - AIF_CTRL2 */ | 55 | { 6, 0x0190 }, /* R6 - DAC_GAINL */ |
55 | 0x0001, /* R5 - DAC_CTRL3 */ | 56 | { 7, 0x0190 }, /* R7 - DAC_GAINR */ |
56 | 0x0190, /* R6 - DAC_GAINL */ | 57 | { 8, 0x0000 }, /* R8 - ZERO_DETECT */ |
57 | 0x0190, /* R7 - DAC_GAINR */ | ||
58 | 0x0000, /* R8 - ZERO_DETECT */ | ||
59 | }; | 58 | }; |
60 | 59 | ||
61 | static int wm8523_volatile_register(struct snd_soc_codec *codec, unsigned int reg) | 60 | static bool wm8523_volatile_register(struct device *dev, unsigned int reg) |
62 | { | 61 | { |
63 | switch (reg) { | 62 | switch (reg) { |
64 | case WM8523_DEVICE_ID: | 63 | case WM8523_DEVICE_ID: |
65 | case WM8523_REVISION: | 64 | case WM8523_REVISION: |
66 | return 1; | 65 | return true; |
67 | default: | 66 | default: |
68 | return 0; | 67 | return false; |
69 | } | 68 | } |
70 | } | 69 | } |
71 | 70 | ||
@@ -301,8 +300,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec, | |||
301 | enum snd_soc_bias_level level) | 300 | enum snd_soc_bias_level level) |
302 | { | 301 | { |
303 | struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); | 302 | struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); |
304 | u16 *reg_cache = codec->reg_cache; | 303 | int ret; |
305 | int ret, i; | ||
306 | 304 | ||
307 | switch (level) { | 305 | switch (level) { |
308 | case SND_SOC_BIAS_ON: | 306 | case SND_SOC_BIAS_ON: |
@@ -325,16 +323,13 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec, | |||
325 | return ret; | 323 | return ret; |
326 | } | 324 | } |
327 | 325 | ||
326 | /* Sync back default/cached values */ | ||
327 | regcache_sync(wm8523->regmap); | ||
328 | |||
328 | /* Initial power up */ | 329 | /* Initial power up */ |
329 | snd_soc_update_bits(codec, WM8523_PSCTRL1, | 330 | snd_soc_update_bits(codec, WM8523_PSCTRL1, |
330 | WM8523_SYS_ENA_MASK, 1); | 331 | WM8523_SYS_ENA_MASK, 1); |
331 | 332 | ||
332 | /* Sync back default/cached values */ | ||
333 | for (i = WM8523_AIF_CTRL1; | ||
334 | i < WM8523_MAX_REGISTER; i++) | ||
335 | snd_soc_write(codec, i, reg_cache[i]); | ||
336 | |||
337 | |||
338 | msleep(100); | 333 | msleep(100); |
339 | } | 334 | } |
340 | 335 | ||
@@ -408,7 +403,7 @@ static int wm8523_probe(struct snd_soc_codec *codec) | |||
408 | wm8523->rate_constraint.count = | 403 | wm8523->rate_constraint.count = |
409 | ARRAY_SIZE(wm8523->rate_constraint_list); | 404 | ARRAY_SIZE(wm8523->rate_constraint_list); |
410 | 405 | ||
411 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8523->control_type); | 406 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); |
412 | if (ret != 0) { | 407 | if (ret != 0) { |
413 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 408 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
414 | return ret; | 409 | return ret; |
@@ -426,7 +421,7 @@ static int wm8523_probe(struct snd_soc_codec *codec) | |||
426 | dev_err(codec->dev, "Failed to read ID register\n"); | 421 | dev_err(codec->dev, "Failed to read ID register\n"); |
427 | goto err_enable; | 422 | goto err_enable; |
428 | } | 423 | } |
429 | if (ret != wm8523_reg[WM8523_DEVICE_ID]) { | 424 | if (ret != 0x8523) { |
430 | dev_err(codec->dev, "Device is not a WM8523, ID is %x\n", ret); | 425 | dev_err(codec->dev, "Device is not a WM8523, ID is %x\n", ret); |
431 | ret = -EINVAL; | 426 | ret = -EINVAL; |
432 | goto err_enable; | 427 | goto err_enable; |
@@ -467,8 +462,6 @@ err_get: | |||
467 | 462 | ||
468 | static int wm8523_remove(struct snd_soc_codec *codec) | 463 | static int wm8523_remove(struct snd_soc_codec *codec) |
469 | { | 464 | { |
470 | struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); | ||
471 | |||
472 | wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF); | 465 | wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF); |
473 | return 0; | 466 | return 0; |
474 | } | 467 | } |
@@ -479,10 +472,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8523 = { | |||
479 | .suspend = wm8523_suspend, | 472 | .suspend = wm8523_suspend, |
480 | .resume = wm8523_resume, | 473 | .resume = wm8523_resume, |
481 | .set_bias_level = wm8523_set_bias_level, | 474 | .set_bias_level = wm8523_set_bias_level, |
482 | .reg_cache_size = WM8523_REGISTER_COUNT, | ||
483 | .reg_word_size = sizeof(u16), | ||
484 | .reg_cache_default = wm8523_reg, | ||
485 | .volatile_register = wm8523_volatile_register, | ||
486 | 475 | ||
487 | .controls = wm8523_controls, | 476 | .controls = wm8523_controls, |
488 | .num_controls = ARRAY_SIZE(wm8523_controls), | 477 | .num_controls = ARRAY_SIZE(wm8523_controls), |
@@ -497,6 +486,18 @@ static const struct of_device_id wm8523_of_match[] = { | |||
497 | { }, | 486 | { }, |
498 | }; | 487 | }; |
499 | 488 | ||
489 | static const struct regmap_config wm8523_regmap = { | ||
490 | .reg_bits = 8, | ||
491 | .val_bits = 16, | ||
492 | .max_register = WM8523_ZERO_DETECT, | ||
493 | |||
494 | .reg_defaults = wm8523_reg_defaults, | ||
495 | .num_reg_defaults = ARRAY_SIZE(wm8523_reg_defaults), | ||
496 | .cache_type = REGCACHE_RBTREE, | ||
497 | |||
498 | .volatile_reg = wm8523_volatile_register, | ||
499 | }; | ||
500 | |||
500 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 501 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
501 | static __devinit int wm8523_i2c_probe(struct i2c_client *i2c, | 502 | static __devinit int wm8523_i2c_probe(struct i2c_client *i2c, |
502 | const struct i2c_device_id *id) | 503 | const struct i2c_device_id *id) |
@@ -509,6 +510,13 @@ static __devinit int wm8523_i2c_probe(struct i2c_client *i2c, | |||
509 | if (wm8523 == NULL) | 510 | if (wm8523 == NULL) |
510 | return -ENOMEM; | 511 | return -ENOMEM; |
511 | 512 | ||
513 | wm8523->regmap = devm_regmap_init_i2c(i2c, &wm8523_regmap); | ||
514 | if (IS_ERR(wm8523->regmap)) { | ||
515 | ret = PTR_ERR(wm8523->regmap); | ||
516 | dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret); | ||
517 | return ret; | ||
518 | } | ||
519 | |||
512 | for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++) | 520 | for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++) |
513 | wm8523->supplies[i].supply = wm8523_supply_names[i]; | 521 | wm8523->supplies[i].supply = wm8523_supply_names[i]; |
514 | 522 | ||
@@ -520,7 +528,6 @@ static __devinit int wm8523_i2c_probe(struct i2c_client *i2c, | |||
520 | } | 528 | } |
521 | 529 | ||
522 | i2c_set_clientdata(i2c, wm8523); | 530 | i2c_set_clientdata(i2c, wm8523); |
523 | wm8523->control_type = SND_SOC_I2C; | ||
524 | 531 | ||
525 | ret = snd_soc_register_codec(&i2c->dev, | 532 | ret = snd_soc_register_codec(&i2c->dev, |
526 | &soc_codec_dev_wm8523, &wm8523_dai, 1); | 533 | &soc_codec_dev_wm8523, &wm8523_dai, 1); |