aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8903.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2011-12-02 13:33:32 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-12-03 06:00:07 -0500
commitee244ce4ea5651989229d7f287f777f68104a59a (patch)
treeb81b02c044f9be7f2b6c8efa2b0fd8bcd67fe0d0 /sound/soc/codecs/wm8903.c
parent82ae55dbcc4a37a4288346795755da5e07c09d33 (diff)
ASoC: Convert WM8903 to direct regmap API usage
Converting to an rbtree cache as regcache doesn't have a flat cache. Since the top of the register map is fairly sparse this should be an overall win. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Tested-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'sound/soc/codecs/wm8903.c')
-rw-r--r--sound/soc/codecs/wm8903.c378
1 files changed, 196 insertions, 182 deletions
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index d840cbfc34ac..0b12a5525c15 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -23,6 +23,7 @@
23#include <linux/gpio.h> 23#include <linux/gpio.h>
24#include <linux/pm.h> 24#include <linux/pm.h>
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include <linux/regmap.h>
26#include <linux/slab.h> 27#include <linux/slab.h>
27#include <sound/core.h> 28#include <sound/core.h>
28#include <sound/jack.h> 29#include <sound/jack.h>
@@ -37,184 +38,84 @@
37#include "wm8903.h" 38#include "wm8903.h"
38 39
39/* Register defaults at reset */ 40/* Register defaults at reset */
40static u16 wm8903_reg_defaults[] = { 41static const struct reg_default wm8903_reg_defaults[] = {
41 0x8903, /* R0 - SW Reset and ID */ 42 { 4, 0x0018 }, /* R4 - Bias Control 0 */
42 0x0000, /* R1 - Revision Number */ 43 { 5, 0x0000 }, /* R5 - VMID Control 0 */
43 0x0000, /* R2 */ 44 { 6, 0x0000 }, /* R6 - Mic Bias Control 0 */
44 0x0000, /* R3 */ 45 { 8, 0x0001 }, /* R8 - Analogue DAC 0 */
45 0x0018, /* R4 - Bias Control 0 */ 46 { 10, 0x0001 }, /* R10 - Analogue ADC 0 */
46 0x0000, /* R5 - VMID Control 0 */ 47 { 12, 0x0000 }, /* R12 - Power Management 0 */
47 0x0000, /* R6 - Mic Bias Control 0 */ 48 { 13, 0x0000 }, /* R13 - Power Management 1 */
48 0x0000, /* R7 */ 49 { 14, 0x0000 }, /* R14 - Power Management 2 */
49 0x0001, /* R8 - Analogue DAC 0 */ 50 { 15, 0x0000 }, /* R15 - Power Management 3 */
50 0x0000, /* R9 */ 51 { 16, 0x0000 }, /* R16 - Power Management 4 */
51 0x0001, /* R10 - Analogue ADC 0 */ 52 { 17, 0x0000 }, /* R17 - Power Management 5 */
52 0x0000, /* R11 */ 53 { 18, 0x0000 }, /* R18 - Power Management 6 */
53 0x0000, /* R12 - Power Management 0 */ 54 { 20, 0x0400 }, /* R20 - Clock Rates 0 */
54 0x0000, /* R13 - Power Management 1 */ 55 { 21, 0x0D07 }, /* R21 - Clock Rates 1 */
55 0x0000, /* R14 - Power Management 2 */ 56 { 22, 0x0000 }, /* R22 - Clock Rates 2 */
56 0x0000, /* R15 - Power Management 3 */ 57 { 24, 0x0050 }, /* R24 - Audio Interface 0 */
57 0x0000, /* R16 - Power Management 4 */ 58 { 25, 0x0242 }, /* R25 - Audio Interface 1 */
58 0x0000, /* R17 - Power Management 5 */ 59 { 26, 0x0008 }, /* R26 - Audio Interface 2 */
59 0x0000, /* R18 - Power Management 6 */ 60 { 27, 0x0022 }, /* R27 - Audio Interface 3 */
60 0x0000, /* R19 */ 61 { 30, 0x00C0 }, /* R30 - DAC Digital Volume Left */
61 0x0400, /* R20 - Clock Rates 0 */ 62 { 31, 0x00C0 }, /* R31 - DAC Digital Volume Right */
62 0x0D07, /* R21 - Clock Rates 1 */ 63 { 32, 0x0000 }, /* R32 - DAC Digital 0 */
63 0x0000, /* R22 - Clock Rates 2 */ 64 { 33, 0x0000 }, /* R33 - DAC Digital 1 */
64 0x0000, /* R23 */ 65 { 36, 0x00C0 }, /* R36 - ADC Digital Volume Left */
65 0x0050, /* R24 - Audio Interface 0 */ 66 { 37, 0x00C0 }, /* R37 - ADC Digital Volume Right */
66 0x0242, /* R25 - Audio Interface 1 */ 67 { 38, 0x0000 }, /* R38 - ADC Digital 0 */
67 0x0008, /* R26 - Audio Interface 2 */ 68 { 39, 0x0073 }, /* R39 - Digital Microphone 0 */
68 0x0022, /* R27 - Audio Interface 3 */ 69 { 40, 0x09BF }, /* R40 - DRC 0 */
69 0x0000, /* R28 */ 70 { 41, 0x3241 }, /* R41 - DRC 1 */
70 0x0000, /* R29 */ 71 { 42, 0x0020 }, /* R42 - DRC 2 */
71 0x00C0, /* R30 - DAC Digital Volume Left */ 72 { 43, 0x0000 }, /* R43 - DRC 3 */
72 0x00C0, /* R31 - DAC Digital Volume Right */ 73 { 44, 0x0085 }, /* R44 - Analogue Left Input 0 */
73 0x0000, /* R32 - DAC Digital 0 */ 74 { 45, 0x0085 }, /* R45 - Analogue Right Input 0 */
74 0x0000, /* R33 - DAC Digital 1 */ 75 { 46, 0x0044 }, /* R46 - Analogue Left Input 1 */
75 0x0000, /* R34 */ 76 { 47, 0x0044 }, /* R47 - Analogue Right Input 1 */
76 0x0000, /* R35 */ 77 { 50, 0x0008 }, /* R50 - Analogue Left Mix 0 */
77 0x00C0, /* R36 - ADC Digital Volume Left */ 78 { 51, 0x0004 }, /* R51 - Analogue Right Mix 0 */
78 0x00C0, /* R37 - ADC Digital Volume Right */ 79 { 52, 0x0000 }, /* R52 - Analogue Spk Mix Left 0 */
79 0x0000, /* R38 - ADC Digital 0 */ 80 { 53, 0x0000 }, /* R53 - Analogue Spk Mix Left 1 */
80 0x0073, /* R39 - Digital Microphone 0 */ 81 { 54, 0x0000 }, /* R54 - Analogue Spk Mix Right 0 */
81 0x09BF, /* R40 - DRC 0 */ 82 { 55, 0x0000 }, /* R55 - Analogue Spk Mix Right 1 */
82 0x3241, /* R41 - DRC 1 */ 83 { 57, 0x002D }, /* R57 - Analogue OUT1 Left */
83 0x0020, /* R42 - DRC 2 */ 84 { 58, 0x002D }, /* R58 - Analogue OUT1 Right */
84 0x0000, /* R43 - DRC 3 */ 85 { 59, 0x0039 }, /* R59 - Analogue OUT2 Left */
85 0x0085, /* R44 - Analogue Left Input 0 */ 86 { 60, 0x0039 }, /* R60 - Analogue OUT2 Right */
86 0x0085, /* R45 - Analogue Right Input 0 */ 87 { 62, 0x0139 }, /* R62 - Analogue OUT3 Left */
87 0x0044, /* R46 - Analogue Left Input 1 */ 88 { 63, 0x0139 }, /* R63 - Analogue OUT3 Right */
88 0x0044, /* R47 - Analogue Right Input 1 */ 89 { 64, 0x0000 }, /* R65 - Analogue SPK Output Control 0 */
89 0x0000, /* R48 */ 90 { 67, 0x0010 }, /* R67 - DC Servo 0 */
90 0x0000, /* R49 */ 91 { 69, 0x00A4 }, /* R69 - DC Servo 2 */
91 0x0008, /* R50 - Analogue Left Mix 0 */ 92 { 90, 0x0000 }, /* R90 - Analogue HP 0 */
92 0x0004, /* R51 - Analogue Right Mix 0 */ 93 { 94, 0x0000 }, /* R94 - Analogue Lineout 0 */
93 0x0000, /* R52 - Analogue Spk Mix Left 0 */ 94 { 98, 0x0000 }, /* R98 - Charge Pump 0 */
94 0x0000, /* R53 - Analogue Spk Mix Left 1 */ 95 { 104, 0x0000 }, /* R104 - Class W 0 */
95 0x0000, /* R54 - Analogue Spk Mix Right 0 */ 96 { 108, 0x0000 }, /* R108 - Write Sequencer 0 */
96 0x0000, /* R55 - Analogue Spk Mix Right 1 */ 97 { 109, 0x0000 }, /* R109 - Write Sequencer 1 */
97 0x0000, /* R56 */ 98 { 110, 0x0000 }, /* R110 - Write Sequencer 2 */
98 0x002D, /* R57 - Analogue OUT1 Left */ 99 { 111, 0x0000 }, /* R111 - Write Sequencer 3 */
99 0x002D, /* R58 - Analogue OUT1 Right */ 100 { 112, 0x0000 }, /* R112 - Write Sequencer 4 */
100 0x0039, /* R59 - Analogue OUT2 Left */ 101 { 114, 0x0000 }, /* R114 - Control Interface */
101 0x0039, /* R60 - Analogue OUT2 Right */ 102 { 116, 0x00A8 }, /* R116 - GPIO Control 1 */
102 0x0100, /* R61 */ 103 { 117, 0x00A8 }, /* R117 - GPIO Control 2 */
103 0x0139, /* R62 - Analogue OUT3 Left */ 104 { 118, 0x00A8 }, /* R118 - GPIO Control 3 */
104 0x0139, /* R63 - Analogue OUT3 Right */ 105 { 119, 0x0220 }, /* R119 - GPIO Control 4 */
105 0x0000, /* R64 */ 106 { 120, 0x01A0 }, /* R120 - GPIO Control 5 */
106 0x0000, /* R65 - Analogue SPK Output Control 0 */ 107 { 122, 0xFFFF }, /* R122 - Interrupt Status 1 Mask */
107 0x0000, /* R66 */ 108 { 123, 0x0000 }, /* R123 - Interrupt Polarity 1 */
108 0x0010, /* R67 - DC Servo 0 */ 109 { 126, 0x0000 }, /* R126 - Interrupt Control */
109 0x0100, /* R68 */ 110 { 129, 0x0000 }, /* R129 - Control Interface Test 1 */
110 0x00A4, /* R69 - DC Servo 2 */ 111 { 149, 0x6810 }, /* R149 - Charge Pump Test 1 */
111 0x0807, /* R70 */ 112 { 164, 0x0028 }, /* R164 - Clock Rate Test 4 */
112 0x0000, /* R71 */ 113 { 172, 0x0000 }, /* R172 - Analogue Output Bias 0 */
113 0x0000, /* R72 */
114 0x0000, /* R73 */
115 0x0000, /* R74 */
116 0x0000, /* R75 */
117 0x0000, /* R76 */
118 0x0000, /* R77 */
119 0x0000, /* R78 */
120 0x000E, /* R79 */
121 0x0000, /* R80 */
122 0x0000, /* R81 */
123 0x0000, /* R82 */
124 0x0000, /* R83 */
125 0x0000, /* R84 */
126 0x0000, /* R85 */
127 0x0000, /* R86 */
128 0x0006, /* R87 */
129 0x0000, /* R88 */
130 0x0000, /* R89 */
131 0x0000, /* R90 - Analogue HP 0 */
132 0x0060, /* R91 */
133 0x0000, /* R92 */
134 0x0000, /* R93 */
135 0x0000, /* R94 - Analogue Lineout 0 */
136 0x0060, /* R95 */
137 0x0000, /* R96 */
138 0x0000, /* R97 */
139 0x0000, /* R98 - Charge Pump 0 */
140 0x1F25, /* R99 */
141 0x2B19, /* R100 */
142 0x01C0, /* R101 */
143 0x01EF, /* R102 */
144 0x2B00, /* R103 */
145 0x0000, /* R104 - Class W 0 */
146 0x01C0, /* R105 */
147 0x1C10, /* R106 */
148 0x0000, /* R107 */
149 0x0000, /* R108 - Write Sequencer 0 */
150 0x0000, /* R109 - Write Sequencer 1 */
151 0x0000, /* R110 - Write Sequencer 2 */
152 0x0000, /* R111 - Write Sequencer 3 */
153 0x0000, /* R112 - Write Sequencer 4 */
154 0x0000, /* R113 */
155 0x0000, /* R114 - Control Interface */
156 0x0000, /* R115 */
157 0x00A8, /* R116 - GPIO Control 1 */
158 0x00A8, /* R117 - GPIO Control 2 */
159 0x00A8, /* R118 - GPIO Control 3 */
160 0x0220, /* R119 - GPIO Control 4 */
161 0x01A0, /* R120 - GPIO Control 5 */
162 0x0000, /* R121 - Interrupt Status 1 */
163 0xFFFF, /* R122 - Interrupt Status 1 Mask */
164 0x0000, /* R123 - Interrupt Polarity 1 */
165 0x0000, /* R124 */
166 0x0003, /* R125 */
167 0x0000, /* R126 - Interrupt Control */
168 0x0000, /* R127 */
169 0x0005, /* R128 */
170 0x0000, /* R129 - Control Interface Test 1 */
171 0x0000, /* R130 */
172 0x0000, /* R131 */
173 0x0000, /* R132 */
174 0x0000, /* R133 */
175 0x0000, /* R134 */
176 0x03FF, /* R135 */
177 0x0007, /* R136 */
178 0x0040, /* R137 */
179 0x0000, /* R138 */
180 0x0000, /* R139 */
181 0x0000, /* R140 */
182 0x0000, /* R141 */
183 0x0000, /* R142 */
184 0x0000, /* R143 */
185 0x0000, /* R144 */
186 0x0000, /* R145 */
187 0x0000, /* R146 */
188 0x0000, /* R147 */
189 0x4000, /* R148 */
190 0x6810, /* R149 - Charge Pump Test 1 */
191 0x0004, /* R150 */
192 0x0000, /* R151 */
193 0x0000, /* R152 */
194 0x0000, /* R153 */
195 0x0000, /* R154 */
196 0x0000, /* R155 */
197 0x0000, /* R156 */
198 0x0000, /* R157 */
199 0x0000, /* R158 */
200 0x0000, /* R159 */
201 0x0000, /* R160 */
202 0x0000, /* R161 */
203 0x0000, /* R162 */
204 0x0000, /* R163 */
205 0x0028, /* R164 - Clock Rate Test 4 */
206 0x0004, /* R165 */
207 0x0000, /* R166 */
208 0x0060, /* R167 */
209 0x0000, /* R168 */
210 0x0000, /* R169 */
211 0x0000, /* R170 */
212 0x0000, /* R171 */
213 0x0000, /* R172 - Analogue Output Bias 0 */
214}; 114};
215 115
216struct wm8903_priv { 116struct wm8903_priv {
217 struct snd_soc_codec *codec; 117 struct snd_soc_codec *codec;
118 struct regmap *regmap;
218 119
219 int sysclk; 120 int sysclk;
220 int irq; 121 int irq;
@@ -239,7 +140,93 @@ struct wm8903_priv {
239#endif 140#endif
240}; 141};
241 142
242static int wm8903_volatile_register(struct snd_soc_codec *codec, unsigned int reg) 143static bool wm8903_readable_register(struct device *dev, unsigned int reg)
144{
145 switch (reg) {
146 case WM8903_SW_RESET_AND_ID:
147 case WM8903_REVISION_NUMBER:
148 case WM8903_BIAS_CONTROL_0:
149 case WM8903_VMID_CONTROL_0:
150 case WM8903_MIC_BIAS_CONTROL_0:
151 case WM8903_ANALOGUE_DAC_0:
152 case WM8903_ANALOGUE_ADC_0:
153 case WM8903_POWER_MANAGEMENT_0:
154 case WM8903_POWER_MANAGEMENT_1:
155 case WM8903_POWER_MANAGEMENT_2:
156 case WM8903_POWER_MANAGEMENT_3:
157 case WM8903_POWER_MANAGEMENT_4:
158 case WM8903_POWER_MANAGEMENT_5:
159 case WM8903_POWER_MANAGEMENT_6:
160 case WM8903_CLOCK_RATES_0:
161 case WM8903_CLOCK_RATES_1:
162 case WM8903_CLOCK_RATES_2:
163 case WM8903_AUDIO_INTERFACE_0:
164 case WM8903_AUDIO_INTERFACE_1:
165 case WM8903_AUDIO_INTERFACE_2:
166 case WM8903_AUDIO_INTERFACE_3:
167 case WM8903_DAC_DIGITAL_VOLUME_LEFT:
168 case WM8903_DAC_DIGITAL_VOLUME_RIGHT:
169 case WM8903_DAC_DIGITAL_0:
170 case WM8903_DAC_DIGITAL_1:
171 case WM8903_ADC_DIGITAL_VOLUME_LEFT:
172 case WM8903_ADC_DIGITAL_VOLUME_RIGHT:
173 case WM8903_ADC_DIGITAL_0:
174 case WM8903_DIGITAL_MICROPHONE_0:
175 case WM8903_DRC_0:
176 case WM8903_DRC_1:
177 case WM8903_DRC_2:
178 case WM8903_DRC_3:
179 case WM8903_ANALOGUE_LEFT_INPUT_0:
180 case WM8903_ANALOGUE_RIGHT_INPUT_0:
181 case WM8903_ANALOGUE_LEFT_INPUT_1:
182 case WM8903_ANALOGUE_RIGHT_INPUT_1:
183 case WM8903_ANALOGUE_LEFT_MIX_0:
184 case WM8903_ANALOGUE_RIGHT_MIX_0:
185 case WM8903_ANALOGUE_SPK_MIX_LEFT_0:
186 case WM8903_ANALOGUE_SPK_MIX_LEFT_1:
187 case WM8903_ANALOGUE_SPK_MIX_RIGHT_0:
188 case WM8903_ANALOGUE_SPK_MIX_RIGHT_1:
189 case WM8903_ANALOGUE_OUT1_LEFT:
190 case WM8903_ANALOGUE_OUT1_RIGHT:
191 case WM8903_ANALOGUE_OUT2_LEFT:
192 case WM8903_ANALOGUE_OUT2_RIGHT:
193 case WM8903_ANALOGUE_OUT3_LEFT:
194 case WM8903_ANALOGUE_OUT3_RIGHT:
195 case WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0:
196 case WM8903_DC_SERVO_0:
197 case WM8903_DC_SERVO_2:
198 case WM8903_DC_SERVO_READBACK_1:
199 case WM8903_DC_SERVO_READBACK_2:
200 case WM8903_DC_SERVO_READBACK_3:
201 case WM8903_DC_SERVO_READBACK_4:
202 case WM8903_ANALOGUE_HP_0:
203 case WM8903_ANALOGUE_LINEOUT_0:
204 case WM8903_CHARGE_PUMP_0:
205 case WM8903_CLASS_W_0:
206 case WM8903_WRITE_SEQUENCER_0:
207 case WM8903_WRITE_SEQUENCER_1:
208 case WM8903_WRITE_SEQUENCER_2:
209 case WM8903_WRITE_SEQUENCER_3:
210 case WM8903_WRITE_SEQUENCER_4:
211 case WM8903_CONTROL_INTERFACE:
212 case WM8903_GPIO_CONTROL_1:
213 case WM8903_GPIO_CONTROL_2:
214 case WM8903_GPIO_CONTROL_3:
215 case WM8903_GPIO_CONTROL_4:
216 case WM8903_GPIO_CONTROL_5:
217 case WM8903_INTERRUPT_STATUS_1:
218 case WM8903_INTERRUPT_STATUS_1_MASK:
219 case WM8903_INTERRUPT_POLARITY_1:
220 case WM8903_INTERRUPT_CONTROL:
221 case WM8903_CLOCK_RATE_TEST_4:
222 case WM8903_ANALOGUE_OUTPUT_BIAS_0:
223 return true;
224 default:
225 return false;
226 }
227}
228
229static bool wm8903_volatile_register(struct device *dev, unsigned int reg)
243{ 230{
244 switch (reg) { 231 switch (reg) {
245 case WM8903_SW_RESET_AND_ID: 232 case WM8903_SW_RESET_AND_ID:
@@ -1767,7 +1754,7 @@ static int wm8903_resume(struct snd_soc_codec *codec)
1767{ 1754{
1768 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 1755 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1769 1756
1770 snd_soc_cache_sync(codec); 1757 regcache_sync(wm8903->regmap);
1771 1758
1772 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1759 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1773 1760
@@ -1897,15 +1884,16 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1897 u16 val; 1884 u16 val;
1898 1885
1899 wm8903->codec = codec; 1886 wm8903->codec = codec;
1887 codec->control_data = wm8903->regmap;
1900 1888
1901 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1889 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
1902 if (ret != 0) { 1890 if (ret != 0) {
1903 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 1891 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1904 return ret; 1892 return ret;
1905 } 1893 }
1906 1894
1907 val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID); 1895 val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID);
1908 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) { 1896 if (val != 0x8903) {
1909 dev_err(codec->dev, 1897 dev_err(codec->dev,
1910 "Device with ID register %x is not a WM8903\n", val); 1898 "Device with ID register %x is not a WM8903\n", val);
1911 return -ENODEV; 1899 return -ENODEV;
@@ -2044,10 +2032,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8903 = {
2044 .suspend = wm8903_suspend, 2032 .suspend = wm8903_suspend,
2045 .resume = wm8903_resume, 2033 .resume = wm8903_resume,
2046 .set_bias_level = wm8903_set_bias_level, 2034 .set_bias_level = wm8903_set_bias_level,
2047 .reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults),
2048 .reg_word_size = sizeof(u16),
2049 .reg_cache_default = wm8903_reg_defaults,
2050 .volatile_register = wm8903_volatile_register,
2051 .seq_notifier = wm8903_seq_notifier, 2035 .seq_notifier = wm8903_seq_notifier,
2052 .controls = wm8903_snd_controls, 2036 .controls = wm8903_snd_controls,
2053 .num_controls = ARRAY_SIZE(wm8903_snd_controls), 2037 .num_controls = ARRAY_SIZE(wm8903_snd_controls),
@@ -2057,6 +2041,19 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8903 = {
2057 .num_dapm_routes = ARRAY_SIZE(wm8903_intercon), 2041 .num_dapm_routes = ARRAY_SIZE(wm8903_intercon),
2058}; 2042};
2059 2043
2044static const struct regmap_config wm8903_regmap = {
2045 .reg_bits = 8,
2046 .val_bits = 16,
2047
2048 .max_register = WM8903_MAX_REGISTER,
2049 .volatile_reg = wm8903_volatile_register,
2050 .readable_reg = wm8903_readable_register,
2051
2052 .cache_type = REGCACHE_RBTREE,
2053 .reg_defaults = wm8903_reg_defaults,
2054 .num_reg_defaults = ARRAY_SIZE(wm8903_reg_defaults),
2055};
2056
2060static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, 2057static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
2061 const struct i2c_device_id *id) 2058 const struct i2c_device_id *id)
2062{ 2059{
@@ -2068,18 +2065,35 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
2068 if (wm8903 == NULL) 2065 if (wm8903 == NULL)
2069 return -ENOMEM; 2066 return -ENOMEM;
2070 2067
2068 wm8903->regmap = regmap_init_i2c(i2c, &wm8903_regmap);
2069 if (IS_ERR(wm8903->regmap)) {
2070 ret = PTR_ERR(wm8903->regmap);
2071 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
2072 ret);
2073 return ret;
2074 }
2075
2071 i2c_set_clientdata(i2c, wm8903); 2076 i2c_set_clientdata(i2c, wm8903);
2072 wm8903->irq = i2c->irq; 2077 wm8903->irq = i2c->irq;
2073 2078
2074 ret = snd_soc_register_codec(&i2c->dev, 2079 ret = snd_soc_register_codec(&i2c->dev,
2075 &soc_codec_dev_wm8903, &wm8903_dai, 1); 2080 &soc_codec_dev_wm8903, &wm8903_dai, 1);
2081 if (ret != 0)
2082 goto err;
2076 2083
2084 return 0;
2085err:
2086 regmap_exit(wm8903->regmap);
2077 return ret; 2087 return ret;
2078} 2088}
2079 2089
2080static __devexit int wm8903_i2c_remove(struct i2c_client *client) 2090static __devexit int wm8903_i2c_remove(struct i2c_client *client)
2081{ 2091{
2092 struct wm8903_priv *wm8903 = i2c_get_clientdata(client);
2093
2094 regmap_exit(wm8903->regmap);
2082 snd_soc_unregister_codec(&client->dev); 2095 snd_soc_unregister_codec(&client->dev);
2096
2083 return 0; 2097 return 0;
2084} 2098}
2085 2099