aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8510.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8510.c')
-rw-r--r--sound/soc/codecs/wm8510.c129
1 files changed, 98 insertions, 31 deletions
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 56a049555e2c..c12a54e72e89 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -20,6 +20,7 @@
20#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/of_device.h> 22#include <linux/of_device.h>
23#include <linux/regmap.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
@@ -33,24 +34,75 @@
33 * We can't read the WM8510 register space when we are 34 * We can't read the WM8510 register space when we are
34 * using 2 wire for device control, so we cache them instead. 35 * using 2 wire for device control, so we cache them instead.
35 */ 36 */
36static const u16 wm8510_reg[WM8510_CACHEREGNUM] = { 37static const struct reg_default wm8510_reg_defaults[] = {
37 0x0000, 0x0000, 0x0000, 0x0000, 38 { 1, 0x0000 },
38 0x0050, 0x0000, 0x0140, 0x0000, 39 { 2, 0x0000 },
39 0x0000, 0x0000, 0x0000, 0x00ff, 40 { 3, 0x0000 },
40 0x0000, 0x0000, 0x0100, 0x00ff, 41 { 4, 0x0050 },
41 0x0000, 0x0000, 0x012c, 0x002c, 42 { 5, 0x0000 },
42 0x002c, 0x002c, 0x002c, 0x0000, 43 { 6, 0x0140 },
43 0x0032, 0x0000, 0x0000, 0x0000, 44 { 7, 0x0000 },
44 0x0000, 0x0000, 0x0000, 0x0000, 45 { 8, 0x0000 },
45 0x0038, 0x000b, 0x0032, 0x0000, 46 { 9, 0x0000 },
46 0x0008, 0x000c, 0x0093, 0x00e9, 47 { 10, 0x0000 },
47 0x0000, 0x0000, 0x0000, 0x0000, 48 { 11, 0x00ff },
48 0x0003, 0x0010, 0x0000, 0x0000, 49 { 12, 0x0000 },
49 0x0000, 0x0002, 0x0001, 0x0000, 50 { 13, 0x0000 },
50 0x0000, 0x0000, 0x0039, 0x0000, 51 { 14, 0x0100 },
51 0x0001, 52 { 15, 0x00ff },
53 { 16, 0x0000 },
54 { 17, 0x0000 },
55 { 18, 0x012c },
56 { 19, 0x002c },
57 { 20, 0x002c },
58 { 21, 0x002c },
59 { 22, 0x002c },
60 { 23, 0x0000 },
61 { 24, 0x0032 },
62 { 25, 0x0000 },
63 { 26, 0x0000 },
64 { 27, 0x0000 },
65 { 28, 0x0000 },
66 { 29, 0x0000 },
67 { 30, 0x0000 },
68 { 31, 0x0000 },
69 { 32, 0x0038 },
70 { 33, 0x000b },
71 { 34, 0x0032 },
72 { 35, 0x0000 },
73 { 36, 0x0008 },
74 { 37, 0x000c },
75 { 38, 0x0093 },
76 { 39, 0x00e9 },
77 { 40, 0x0000 },
78 { 41, 0x0000 },
79 { 42, 0x0000 },
80 { 43, 0x0000 },
81 { 44, 0x0003 },
82 { 45, 0x0010 },
83 { 46, 0x0000 },
84 { 47, 0x0000 },
85 { 48, 0x0000 },
86 { 49, 0x0002 },
87 { 50, 0x0001 },
88 { 51, 0x0000 },
89 { 52, 0x0000 },
90 { 53, 0x0000 },
91 { 54, 0x0039 },
92 { 55, 0x0000 },
93 { 56, 0x0001 },
52}; 94};
53 95
96static bool wm8510_volatile(struct device *dev, unsigned int reg)
97{
98 switch (reg) {
99 case WM8510_RESET:
100 return true;
101 default:
102 return false;
103 }
104}
105
54#define WM8510_POWER1_BIASEN 0x08 106#define WM8510_POWER1_BIASEN 0x08
55#define WM8510_POWER1_BUFIOEN 0x10 107#define WM8510_POWER1_BUFIOEN 0x10
56 108
@@ -58,7 +110,7 @@ static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
58 110
59/* codec private data */ 111/* codec private data */
60struct wm8510_priv { 112struct wm8510_priv {
61 enum snd_soc_control_type control_type; 113 struct regmap *regmap;
62}; 114};
63 115
64static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" }; 116static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" };
@@ -454,6 +506,7 @@ static int wm8510_mute(struct snd_soc_dai *dai, int mute)
454static int wm8510_set_bias_level(struct snd_soc_codec *codec, 506static int wm8510_set_bias_level(struct snd_soc_codec *codec,
455 enum snd_soc_bias_level level) 507 enum snd_soc_bias_level level)
456{ 508{
509 struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
457 u16 power1 = snd_soc_read(codec, WM8510_POWER1) & ~0x3; 510 u16 power1 = snd_soc_read(codec, WM8510_POWER1) & ~0x3;
458 511
459 switch (level) { 512 switch (level) {
@@ -467,7 +520,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
467 power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN; 520 power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
468 521
469 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 522 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
470 snd_soc_cache_sync(codec); 523 regcache_sync(wm8510->regmap);
471 524
472 /* Initial cap charge at VMID 5k */ 525 /* Initial cap charge at VMID 5k */
473 snd_soc_write(codec, WM8510_POWER1, power1 | 0x3); 526 snd_soc_write(codec, WM8510_POWER1, power1 | 0x3);
@@ -536,10 +589,9 @@ static int wm8510_resume(struct snd_soc_codec *codec)
536 589
537static int wm8510_probe(struct snd_soc_codec *codec) 590static int wm8510_probe(struct snd_soc_codec *codec)
538{ 591{
539 struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
540 int ret; 592 int ret;
541 593
542 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8510->control_type); 594 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
543 if (ret < 0) { 595 if (ret < 0) {
544 printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n", ret); 596 printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n", ret);
545 return ret; 597 return ret;
@@ -569,9 +621,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8510 = {
569 .suspend = wm8510_suspend, 621 .suspend = wm8510_suspend,
570 .resume = wm8510_resume, 622 .resume = wm8510_resume,
571 .set_bias_level = wm8510_set_bias_level, 623 .set_bias_level = wm8510_set_bias_level,
572 .reg_cache_size = ARRAY_SIZE(wm8510_reg),
573 .reg_word_size = sizeof(u16),
574 .reg_cache_default =wm8510_reg,
575 624
576 .controls = wm8510_snd_controls, 625 .controls = wm8510_snd_controls,
577 .num_controls = ARRAY_SIZE(wm8510_snd_controls), 626 .num_controls = ARRAY_SIZE(wm8510_snd_controls),
@@ -586,23 +635,38 @@ static const struct of_device_id wm8510_of_match[] = {
586 { }, 635 { },
587}; 636};
588 637
638static const struct regmap_config wm8510_regmap = {
639 .reg_bits = 7,
640 .val_bits = 9,
641 .max_register = WM8510_MONOMIX,
642
643 .reg_defaults = wm8510_reg_defaults,
644 .num_reg_defaults = ARRAY_SIZE(wm8510_reg_defaults),
645 .cache_type = REGCACHE_RBTREE,
646
647 .volatile_reg = wm8510_volatile,
648};
649
589#if defined(CONFIG_SPI_MASTER) 650#if defined(CONFIG_SPI_MASTER)
590static int __devinit wm8510_spi_probe(struct spi_device *spi) 651static int __devinit wm8510_spi_probe(struct spi_device *spi)
591{ 652{
592 struct wm8510_priv *wm8510; 653 struct wm8510_priv *wm8510;
593 int ret; 654 int ret;
594 655
595 wm8510 = kzalloc(sizeof(struct wm8510_priv), GFP_KERNEL); 656 wm8510 = devm_kzalloc(&spi->dev, sizeof(struct wm8510_priv),
657 GFP_KERNEL);
596 if (wm8510 == NULL) 658 if (wm8510 == NULL)
597 return -ENOMEM; 659 return -ENOMEM;
598 660
599 wm8510->control_type = SND_SOC_SPI; 661 wm8510->regmap = devm_regmap_init_spi(spi, &wm8510_regmap);
662 if (IS_ERR(wm8510->regmap))
663 return PTR_ERR(wm8510->regmap);
664
600 spi_set_drvdata(spi, wm8510); 665 spi_set_drvdata(spi, wm8510);
601 666
602 ret = snd_soc_register_codec(&spi->dev, 667 ret = snd_soc_register_codec(&spi->dev,
603 &soc_codec_dev_wm8510, &wm8510_dai, 1); 668 &soc_codec_dev_wm8510, &wm8510_dai, 1);
604 if (ret < 0) 669
605 kfree(wm8510);
606 return ret; 670 return ret;
607} 671}
608 672
@@ -630,17 +694,20 @@ static __devinit int wm8510_i2c_probe(struct i2c_client *i2c,
630 struct wm8510_priv *wm8510; 694 struct wm8510_priv *wm8510;
631 int ret; 695 int ret;
632 696
633 wm8510 = kzalloc(sizeof(struct wm8510_priv), GFP_KERNEL); 697 wm8510 = devm_kzalloc(&i2c->dev, sizeof(struct wm8510_priv),
698 GFP_KERNEL);
634 if (wm8510 == NULL) 699 if (wm8510 == NULL)
635 return -ENOMEM; 700 return -ENOMEM;
636 701
702 wm8510->regmap = devm_regmap_init_i2c(i2c, &wm8510_regmap);
703 if (IS_ERR(wm8510->regmap))
704 return PTR_ERR(wm8510->regmap);
705
637 i2c_set_clientdata(i2c, wm8510); 706 i2c_set_clientdata(i2c, wm8510);
638 wm8510->control_type = SND_SOC_I2C;
639 707
640 ret = snd_soc_register_codec(&i2c->dev, 708 ret = snd_soc_register_codec(&i2c->dev,
641 &soc_codec_dev_wm8510, &wm8510_dai, 1); 709 &soc_codec_dev_wm8510, &wm8510_dai, 1);
642 if (ret < 0) 710
643 kfree(wm8510);
644 return ret; 711 return ret;
645} 712}
646 713