diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-09-12 08:15:22 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-09-18 23:23:47 -0400 |
commit | 2cbde7abfdd8c3e2c1293b7096477e8bcf10b755 (patch) | |
tree | a815d11d75c00cb640a6998cf74625d961127daf | |
parent | 22bab8ceda6ea2885c6315d07c37b4ef69aefb0c (diff) |
ASoC: wm8776: Convert to direct regmap API usage
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r-- | sound/soc/codecs/wm8776.c | 75 |
1 files changed, 60 insertions, 15 deletions
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 879c356a9045..c32249ddb2e0 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.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/of_device.h> | 21 | #include <linux/of_device.h> |
22 | #include <linux/regmap.h> | ||
22 | #include <linux/spi/spi.h> | 23 | #include <linux/spi/spi.h> |
23 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
24 | #include <sound/core.h> | 25 | #include <sound/core.h> |
@@ -37,18 +38,46 @@ enum wm8776_chip_type { | |||
37 | 38 | ||
38 | /* codec private data */ | 39 | /* codec private data */ |
39 | struct wm8776_priv { | 40 | struct wm8776_priv { |
40 | enum snd_soc_control_type control_type; | 41 | struct regmap *regmap; |
41 | int sysclk[2]; | 42 | int sysclk[2]; |
42 | }; | 43 | }; |
43 | 44 | ||
44 | static const u16 wm8776_reg[WM8776_CACHEREGNUM] = { | 45 | static const struct reg_default wm8776_reg_defaults[] = { |
45 | 0x79, 0x79, 0x79, 0xff, 0xff, /* 4 */ | 46 | { 0, 0x79 }, |
46 | 0xff, 0x00, 0x90, 0x00, 0x00, /* 9 */ | 47 | { 1, 0x79 }, |
47 | 0x22, 0x22, 0x22, 0x08, 0xcf, /* 14 */ | 48 | { 2, 0x79 }, |
48 | 0xcf, 0x7b, 0x00, 0x32, 0x00, /* 19 */ | 49 | { 3, 0xff }, |
49 | 0xa6, 0x01, 0x01 | 50 | { 4, 0xff }, |
51 | { 5, 0xff }, | ||
52 | { 6, 0x00 }, | ||
53 | { 7, 0x90 }, | ||
54 | { 8, 0x00 }, | ||
55 | { 9, 0x00 }, | ||
56 | { 10, 0x22 }, | ||
57 | { 11, 0x22 }, | ||
58 | { 12, 0x22 }, | ||
59 | { 13, 0x08 }, | ||
60 | { 14, 0xcf }, | ||
61 | { 15, 0xcf }, | ||
62 | { 16, 0x7b }, | ||
63 | { 17, 0x00 }, | ||
64 | { 18, 0x32 }, | ||
65 | { 19, 0x00 }, | ||
66 | { 20, 0xa6 }, | ||
67 | { 21, 0x01 }, | ||
68 | { 22, 0x01 }, | ||
50 | }; | 69 | }; |
51 | 70 | ||
71 | static bool wm8776_volatile(struct device *dev, unsigned int reg) | ||
72 | { | ||
73 | switch (reg) { | ||
74 | case WM8776_RESET: | ||
75 | return true; | ||
76 | default: | ||
77 | return false; | ||
78 | } | ||
79 | } | ||
80 | |||
52 | static int wm8776_reset(struct snd_soc_codec *codec) | 81 | static int wm8776_reset(struct snd_soc_codec *codec) |
53 | { | 82 | { |
54 | return snd_soc_write(codec, WM8776_RESET, 0); | 83 | return snd_soc_write(codec, WM8776_RESET, 0); |
@@ -306,6 +335,8 @@ static int wm8776_set_sysclk(struct snd_soc_dai *dai, | |||
306 | static int wm8776_set_bias_level(struct snd_soc_codec *codec, | 335 | static int wm8776_set_bias_level(struct snd_soc_codec *codec, |
307 | enum snd_soc_bias_level level) | 336 | enum snd_soc_bias_level level) |
308 | { | 337 | { |
338 | struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec); | ||
339 | |||
309 | switch (level) { | 340 | switch (level) { |
310 | case SND_SOC_BIAS_ON: | 341 | case SND_SOC_BIAS_ON: |
311 | break; | 342 | break; |
@@ -313,7 +344,7 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec, | |||
313 | break; | 344 | break; |
314 | case SND_SOC_BIAS_STANDBY: | 345 | case SND_SOC_BIAS_STANDBY: |
315 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 346 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
316 | snd_soc_cache_sync(codec); | 347 | regcache_sync(wm8776->regmap); |
317 | 348 | ||
318 | /* Disable the global powerdown; DAPM does the rest */ | 349 | /* Disable the global powerdown; DAPM does the rest */ |
319 | snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0); | 350 | snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0); |
@@ -396,10 +427,9 @@ static int wm8776_resume(struct snd_soc_codec *codec) | |||
396 | 427 | ||
397 | static int wm8776_probe(struct snd_soc_codec *codec) | 428 | static int wm8776_probe(struct snd_soc_codec *codec) |
398 | { | 429 | { |
399 | struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec); | ||
400 | int ret = 0; | 430 | int ret = 0; |
401 | 431 | ||
402 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8776->control_type); | 432 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
403 | if (ret < 0) { | 433 | if (ret < 0) { |
404 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 434 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
405 | return ret; | 435 | return ret; |
@@ -434,9 +464,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8776 = { | |||
434 | .suspend = wm8776_suspend, | 464 | .suspend = wm8776_suspend, |
435 | .resume = wm8776_resume, | 465 | .resume = wm8776_resume, |
436 | .set_bias_level = wm8776_set_bias_level, | 466 | .set_bias_level = wm8776_set_bias_level, |
437 | .reg_cache_size = ARRAY_SIZE(wm8776_reg), | ||
438 | .reg_word_size = sizeof(u16), | ||
439 | .reg_cache_default = wm8776_reg, | ||
440 | 467 | ||
441 | .controls = wm8776_snd_controls, | 468 | .controls = wm8776_snd_controls, |
442 | .num_controls = ARRAY_SIZE(wm8776_snd_controls), | 469 | .num_controls = ARRAY_SIZE(wm8776_snd_controls), |
@@ -452,6 +479,18 @@ static const struct of_device_id wm8776_of_match[] = { | |||
452 | }; | 479 | }; |
453 | MODULE_DEVICE_TABLE(of, wm8776_of_match); | 480 | MODULE_DEVICE_TABLE(of, wm8776_of_match); |
454 | 481 | ||
482 | static const struct regmap_config wm8776_regmap = { | ||
483 | .reg_bits = 7, | ||
484 | .val_bits = 9, | ||
485 | .max_register = WM8776_RESET, | ||
486 | |||
487 | .reg_defaults = wm8776_reg_defaults, | ||
488 | .num_reg_defaults = ARRAY_SIZE(wm8776_reg_defaults), | ||
489 | .cache_type = REGCACHE_RBTREE, | ||
490 | |||
491 | .volatile_reg = wm8776_volatile, | ||
492 | }; | ||
493 | |||
455 | #if defined(CONFIG_SPI_MASTER) | 494 | #if defined(CONFIG_SPI_MASTER) |
456 | static int __devinit wm8776_spi_probe(struct spi_device *spi) | 495 | static int __devinit wm8776_spi_probe(struct spi_device *spi) |
457 | { | 496 | { |
@@ -463,7 +502,10 @@ static int __devinit wm8776_spi_probe(struct spi_device *spi) | |||
463 | if (wm8776 == NULL) | 502 | if (wm8776 == NULL) |
464 | return -ENOMEM; | 503 | return -ENOMEM; |
465 | 504 | ||
466 | wm8776->control_type = SND_SOC_SPI; | 505 | wm8776->regmap = devm_regmap_init_spi(spi, &wm8776_regmap); |
506 | if (IS_ERR(wm8776->regmap)) | ||
507 | return PTR_ERR(wm8776->regmap); | ||
508 | |||
467 | spi_set_drvdata(spi, wm8776); | 509 | spi_set_drvdata(spi, wm8776); |
468 | 510 | ||
469 | ret = snd_soc_register_codec(&spi->dev, | 511 | ret = snd_soc_register_codec(&spi->dev, |
@@ -501,8 +543,11 @@ static __devinit int wm8776_i2c_probe(struct i2c_client *i2c, | |||
501 | if (wm8776 == NULL) | 543 | if (wm8776 == NULL) |
502 | return -ENOMEM; | 544 | return -ENOMEM; |
503 | 545 | ||
546 | wm8776->regmap = devm_regmap_init_i2c(i2c, &wm8776_regmap); | ||
547 | if (IS_ERR(wm8776->regmap)) | ||
548 | return PTR_ERR(wm8776->regmap); | ||
549 | |||
504 | i2c_set_clientdata(i2c, wm8776); | 550 | i2c_set_clientdata(i2c, wm8776); |
505 | wm8776->control_type = SND_SOC_I2C; | ||
506 | 551 | ||
507 | ret = snd_soc_register_codec(&i2c->dev, | 552 | ret = snd_soc_register_codec(&i2c->dev, |
508 | &soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai)); | 553 | &soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai)); |