diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-02-12 13:21:57 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-02-13 14:38:21 -0500 |
commit | d2dc0a7782d3f257789e8650b3fa2586b96c6436 (patch) | |
tree | a092894ca0fbcc78a9c2e6e850cc67edb7881fe8 /sound/soc/codecs/wm8988.c | |
parent | 2dbc34d827d17e2f4926d4424b5e41c25c70238a (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.c | 140 |
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 | */ |
36 | static const u16 wm8988_reg[] = { | 36 | static 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 | ||
72 | static 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 */ |
51 | struct wm8988_priv { | 116 | struct 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) | |||
661 | static int wm8988_set_bias_level(struct snd_soc_codec *codec, | 726 | static 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 | ||
731 | static int wm8988_suspend(struct snd_soc_codec *codec) | 797 | static 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 | ||
863 | static 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) |
797 | static int __devinit wm8988_spi_probe(struct spi_device *spi) | 876 | static 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 | ||
816 | static int __devexit wm8988_spi_remove(struct spi_device *spi) | 903 | static 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 | ||
852 | static __devexit int wm8988_i2c_remove(struct i2c_client *client) | 950 | static __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 | ||