aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8988.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-02-12 13:21:57 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-02-13 14:38:21 -0500
commitd2dc0a7782d3f257789e8650b3fa2586b96c6436 (patch)
treea092894ca0fbcc78a9c2e6e850cc67edb7881fe8 /sound/soc/codecs/wm8988.c
parent2dbc34d827d17e2f4926d4424b5e41c25c70238a (diff)
ASoC: wm8988: Convert to direct regmap API usage
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm8988.c')
-rw-r--r--sound/soc/codecs/wm8988.c140
1 files changed, 120 insertions, 20 deletions
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 4ef9d4cb7d7c..2470321a0eea 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -33,24 +33,89 @@
33 * We can't read the WM8988 register space when we 33 * We can't read the WM8988 register space when we
34 * are using 2 wire for device control, so we cache them instead. 34 * are using 2 wire for device control, so we cache them instead.
35 */ 35 */
36static const u16 wm8988_reg[] = { 36static const struct reg_default wm8988_reg_defaults[] = {
37 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ 37 { 0, 0x0097 },
38 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ 38 { 1, 0x0097 },
39 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ 39 { 2, 0x0079 },
40 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ 40 { 3, 0x0079 },
41 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ 41 { 5, 0x0008 },
42 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ 42 { 7, 0x000a },
43 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ 43 { 8, 0x0000 },
44 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ 44 { 10, 0x00ff },
45 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ 45 { 11, 0x00ff },
46 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ 46 { 12, 0x000f },
47 0x0079, 0x0079, 0x0079, /* 40 */ 47 { 13, 0x000f },
48 { 16, 0x0000 },
49 { 17, 0x007b },
50 { 18, 0x0000 },
51 { 19, 0x0032 },
52 { 20, 0x0000 },
53 { 21, 0x00c3 },
54 { 22, 0x00c3 },
55 { 23, 0x00c0 },
56 { 24, 0x0000 },
57 { 25, 0x0000 },
58 { 26, 0x0000 },
59 { 27, 0x0000 },
60 { 31, 0x0000 },
61 { 32, 0x0000 },
62 { 33, 0x0000 },
63 { 34, 0x0050 },
64 { 35, 0x0050 },
65 { 36, 0x0050 },
66 { 37, 0x0050 },
67 { 40, 0x0079 },
68 { 41, 0x0079 },
69 { 42, 0x0079 },
48}; 70};
49 71
72static bool wm8988_writeable(struct device *dev, unsigned int reg)
73{
74 switch (reg) {
75 case WM8988_LINVOL:
76 case WM8988_RINVOL:
77 case WM8988_LOUT1V:
78 case WM8988_ROUT1V:
79 case WM8988_ADCDAC:
80 case WM8988_IFACE:
81 case WM8988_SRATE:
82 case WM8988_LDAC:
83 case WM8988_RDAC:
84 case WM8988_BASS:
85 case WM8988_TREBLE:
86 case WM8988_RESET:
87 case WM8988_3D:
88 case WM8988_ALC1:
89 case WM8988_ALC2:
90 case WM8988_ALC3:
91 case WM8988_NGATE:
92 case WM8988_LADC:
93 case WM8988_RADC:
94 case WM8988_ADCTL1:
95 case WM8988_ADCTL2:
96 case WM8988_PWR1:
97 case WM8988_PWR2:
98 case WM8988_ADCTL3:
99 case WM8988_ADCIN:
100 case WM8988_LADCIN:
101 case WM8988_RADCIN:
102 case WM8988_LOUTM1:
103 case WM8988_LOUTM2:
104 case WM8988_ROUTM1:
105 case WM8988_ROUTM2:
106 case WM8988_LOUT2V:
107 case WM8988_ROUT2V:
108 case WM8988_LPPB:
109 return true;
110 default:
111 return false;
112 }
113}
114
50/* codec private data */ 115/* codec private data */
51struct wm8988_priv { 116struct wm8988_priv {
117 struct regmap *regmap;
52 unsigned int sysclk; 118 unsigned int sysclk;
53 enum snd_soc_control_type control_type;
54 struct snd_pcm_hw_constraint_list *sysclk_constraints; 119 struct snd_pcm_hw_constraint_list *sysclk_constraints;
55}; 120};
56 121
@@ -661,6 +726,7 @@ static int wm8988_mute(struct snd_soc_dai *dai, int mute)
661static int wm8988_set_bias_level(struct snd_soc_codec *codec, 726static int wm8988_set_bias_level(struct snd_soc_codec *codec,
662 enum snd_soc_bias_level level) 727 enum snd_soc_bias_level level)
663{ 728{
729 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
664 u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1; 730 u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1;
665 731
666 switch (level) { 732 switch (level) {
@@ -674,7 +740,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
674 740
675 case SND_SOC_BIAS_STANDBY: 741 case SND_SOC_BIAS_STANDBY:
676 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 742 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
677 snd_soc_cache_sync(codec); 743 regcache_sync(wm8988->regmap);
678 744
679 /* VREF, VMID=2x5k */ 745 /* VREF, VMID=2x5k */
680 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); 746 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1);
@@ -730,7 +796,10 @@ static struct snd_soc_dai_driver wm8988_dai = {
730 796
731static int wm8988_suspend(struct snd_soc_codec *codec) 797static int wm8988_suspend(struct snd_soc_codec *codec)
732{ 798{
799 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
800
733 wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); 801 wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF);
802 regcache_mark_dirty(wm8988->regmap);
734 return 0; 803 return 0;
735} 804}
736 805
@@ -745,7 +814,8 @@ static int wm8988_probe(struct snd_soc_codec *codec)
745 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); 814 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
746 int ret = 0; 815 int ret = 0;
747 816
748 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type); 817 codec->control_data = wm8988->regmap;
818 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
749 if (ret < 0) { 819 if (ret < 0) {
750 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 820 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
751 return ret; 821 return ret;
@@ -781,9 +851,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8988 = {
781 .suspend = wm8988_suspend, 851 .suspend = wm8988_suspend,
782 .resume = wm8988_resume, 852 .resume = wm8988_resume,
783 .set_bias_level = wm8988_set_bias_level, 853 .set_bias_level = wm8988_set_bias_level,
784 .reg_cache_size = ARRAY_SIZE(wm8988_reg),
785 .reg_word_size = sizeof(u16),
786 .reg_cache_default = wm8988_reg,
787 854
788 .controls = wm8988_snd_controls, 855 .controls = wm8988_snd_controls,
789 .num_controls = ARRAY_SIZE(wm8988_snd_controls), 856 .num_controls = ARRAY_SIZE(wm8988_snd_controls),
@@ -793,6 +860,18 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8988 = {
793 .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes), 860 .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes),
794}; 861};
795 862
863static struct regmap_config wm8988_regmap = {
864 .reg_bits = 7,
865 .val_bits = 9,
866
867 .max_register = WM8988_LPPB,
868 .writeable_reg = wm8988_writeable,
869
870 .cache_type = REGCACHE_RBTREE,
871 .reg_defaults = wm8988_reg_defaults,
872 .num_reg_defaults = ARRAY_SIZE(wm8988_reg_defaults),
873};
874
796#if defined(CONFIG_SPI_MASTER) 875#if defined(CONFIG_SPI_MASTER)
797static int __devinit wm8988_spi_probe(struct spi_device *spi) 876static int __devinit wm8988_spi_probe(struct spi_device *spi)
798{ 877{
@@ -804,18 +883,28 @@ static int __devinit wm8988_spi_probe(struct spi_device *spi)
804 if (wm8988 == NULL) 883 if (wm8988 == NULL)
805 return -ENOMEM; 884 return -ENOMEM;
806 885
807 wm8988->control_type = SND_SOC_SPI; 886 wm8988->regmap = regmap_init_spi(spi, &wm8988_regmap);
887 if (IS_ERR(wm8988->regmap)) {
888 ret = PTR_ERR(wm8988->regmap);
889 dev_err(&spi->dev, "Failed to init regmap: %d\n", ret);
890 return ret;
891 }
892
808 spi_set_drvdata(spi, wm8988); 893 spi_set_drvdata(spi, wm8988);
809 894
810 ret = snd_soc_register_codec(&spi->dev, 895 ret = snd_soc_register_codec(&spi->dev,
811 &soc_codec_dev_wm8988, &wm8988_dai, 1); 896 &soc_codec_dev_wm8988, &wm8988_dai, 1);
897 if (ret != 0)
898 regmap_exit(wm8988->regmap);
812 899
813 return ret; 900 return ret;
814} 901}
815 902
816static int __devexit wm8988_spi_remove(struct spi_device *spi) 903static int __devexit wm8988_spi_remove(struct spi_device *spi)
817{ 904{
905 struct wm8988_priv *wm8988 = spi_get_drvdata(spi);
818 snd_soc_unregister_codec(&spi->dev); 906 snd_soc_unregister_codec(&spi->dev);
907 regmap_exit(wm8988->regmap);
819 return 0; 908 return 0;
820} 909}
821 910
@@ -842,16 +931,27 @@ static __devinit int wm8988_i2c_probe(struct i2c_client *i2c,
842 return -ENOMEM; 931 return -ENOMEM;
843 932
844 i2c_set_clientdata(i2c, wm8988); 933 i2c_set_clientdata(i2c, wm8988);
845 wm8988->control_type = SND_SOC_I2C; 934
935 wm8988->regmap = regmap_init_i2c(i2c, &wm8988_regmap);
936 if (IS_ERR(wm8988->regmap)) {
937 ret = PTR_ERR(wm8988->regmap);
938 dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
939 return ret;
940 }
846 941
847 ret = snd_soc_register_codec(&i2c->dev, 942 ret = snd_soc_register_codec(&i2c->dev,
848 &soc_codec_dev_wm8988, &wm8988_dai, 1); 943 &soc_codec_dev_wm8988, &wm8988_dai, 1);
944 if (ret != 0)
945 regmap_exit(wm8988->regmap);
946
849 return ret; 947 return ret;
850} 948}
851 949
852static __devexit int wm8988_i2c_remove(struct i2c_client *client) 950static __devexit int wm8988_i2c_remove(struct i2c_client *client)
853{ 951{
952 struct wm8988_priv *wm8988 = i2c_get_clientdata(client);
854 snd_soc_unregister_codec(&client->dev); 953 snd_soc_unregister_codec(&client->dev);
954 regmap_exit(wm8988->regmap);
855 return 0; 955 return 0;
856} 956}
857 957