diff options
Diffstat (limited to 'sound/soc/codecs/wm8993.c')
-rw-r--r-- | sound/soc/codecs/wm8993.c | 649 |
1 files changed, 427 insertions, 222 deletions
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 7c7fd925db8d..d256a9340644 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <linux/regmap.h> | ||
19 | #include <linux/regulator/consumer.h> | 20 | #include <linux/regulator/consumer.h> |
20 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
@@ -40,134 +41,113 @@ static const char *wm8993_supply_names[WM8993_NUM_SUPPLIES] = { | |||
40 | "SPKVDD", | 41 | "SPKVDD", |
41 | }; | 42 | }; |
42 | 43 | ||
43 | static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = { | 44 | static struct reg_default wm8993_reg_defaults[] = { |
44 | 0x8993, /* R0 - Software Reset */ | 45 | { 1, 0x0000 }, /* R1 - Power Management (1) */ |
45 | 0x0000, /* R1 - Power Management (1) */ | 46 | { 2, 0x6000 }, /* R2 - Power Management (2) */ |
46 | 0x6000, /* R2 - Power Management (2) */ | 47 | { 3, 0x0000 }, /* R3 - Power Management (3) */ |
47 | 0x0000, /* R3 - Power Management (3) */ | 48 | { 4, 0x4050 }, /* R4 - Audio Interface (1) */ |
48 | 0x4050, /* R4 - Audio Interface (1) */ | 49 | { 5, 0x4000 }, /* R5 - Audio Interface (2) */ |
49 | 0x4000, /* R5 - Audio Interface (2) */ | 50 | { 6, 0x01C8 }, /* R6 - Clocking 1 */ |
50 | 0x01C8, /* R6 - Clocking 1 */ | 51 | { 7, 0x0000 }, /* R7 - Clocking 2 */ |
51 | 0x0000, /* R7 - Clocking 2 */ | 52 | { 8, 0x0000 }, /* R8 - Audio Interface (3) */ |
52 | 0x0000, /* R8 - Audio Interface (3) */ | 53 | { 9, 0x0040 }, /* R9 - Audio Interface (4) */ |
53 | 0x0040, /* R9 - Audio Interface (4) */ | 54 | { 10, 0x0004 }, /* R10 - DAC CTRL */ |
54 | 0x0004, /* R10 - DAC CTRL */ | 55 | { 11, 0x00C0 }, /* R11 - Left DAC Digital Volume */ |
55 | 0x00C0, /* R11 - Left DAC Digital Volume */ | 56 | { 12, 0x00C0 }, /* R12 - Right DAC Digital Volume */ |
56 | 0x00C0, /* R12 - Right DAC Digital Volume */ | 57 | { 13, 0x0000 }, /* R13 - Digital Side Tone */ |
57 | 0x0000, /* R13 - Digital Side Tone */ | 58 | { 14, 0x0300 }, /* R14 - ADC CTRL */ |
58 | 0x0300, /* R14 - ADC CTRL */ | 59 | { 15, 0x00C0 }, /* R15 - Left ADC Digital Volume */ |
59 | 0x00C0, /* R15 - Left ADC Digital Volume */ | 60 | { 16, 0x00C0 }, /* R16 - Right ADC Digital Volume */ |
60 | 0x00C0, /* R16 - Right ADC Digital Volume */ | 61 | { 18, 0x0000 }, /* R18 - GPIO CTRL 1 */ |
61 | 0x0000, /* R17 */ | 62 | { 19, 0x0010 }, /* R19 - GPIO1 */ |
62 | 0x0000, /* R18 - GPIO CTRL 1 */ | 63 | { 20, 0x0000 }, /* R20 - IRQ_DEBOUNCE */ |
63 | 0x0010, /* R19 - GPIO1 */ | 64 | { 21, 0x0000 }, /* R21 - Inputs Clamp */ |
64 | 0x0000, /* R20 - IRQ_DEBOUNCE */ | 65 | { 22, 0x8000 }, /* R22 - GPIOCTRL 2 */ |
65 | 0x0000, /* R21 */ | 66 | { 23, 0x0800 }, /* R23 - GPIO_POL */ |
66 | 0x8000, /* R22 - GPIOCTRL 2 */ | 67 | { 24, 0x008B }, /* R24 - Left Line Input 1&2 Volume */ |
67 | 0x0800, /* R23 - GPIO_POL */ | 68 | { 25, 0x008B }, /* R25 - Left Line Input 3&4 Volume */ |
68 | 0x008B, /* R24 - Left Line Input 1&2 Volume */ | 69 | { 26, 0x008B }, /* R26 - Right Line Input 1&2 Volume */ |
69 | 0x008B, /* R25 - Left Line Input 3&4 Volume */ | 70 | { 27, 0x008B }, /* R27 - Right Line Input 3&4 Volume */ |
70 | 0x008B, /* R26 - Right Line Input 1&2 Volume */ | 71 | { 28, 0x006D }, /* R28 - Left Output Volume */ |
71 | 0x008B, /* R27 - Right Line Input 3&4 Volume */ | 72 | { 29, 0x006D }, /* R29 - Right Output Volume */ |
72 | 0x006D, /* R28 - Left Output Volume */ | 73 | { 30, 0x0066 }, /* R30 - Line Outputs Volume */ |
73 | 0x006D, /* R29 - Right Output Volume */ | 74 | { 31, 0x0020 }, /* R31 - HPOUT2 Volume */ |
74 | 0x0066, /* R30 - Line Outputs Volume */ | 75 | { 32, 0x0079 }, /* R32 - Left OPGA Volume */ |
75 | 0x0020, /* R31 - HPOUT2 Volume */ | 76 | { 33, 0x0079 }, /* R33 - Right OPGA Volume */ |
76 | 0x0079, /* R32 - Left OPGA Volume */ | 77 | { 34, 0x0003 }, /* R34 - SPKMIXL Attenuation */ |
77 | 0x0079, /* R33 - Right OPGA Volume */ | 78 | { 35, 0x0003 }, /* R35 - SPKMIXR Attenuation */ |
78 | 0x0003, /* R34 - SPKMIXL Attenuation */ | 79 | { 36, 0x0011 }, /* R36 - SPKOUT Mixers */ |
79 | 0x0003, /* R35 - SPKMIXR Attenuation */ | 80 | { 37, 0x0100 }, /* R37 - SPKOUT Boost */ |
80 | 0x0011, /* R36 - SPKOUT Mixers */ | 81 | { 38, 0x0079 }, /* R38 - Speaker Volume Left */ |
81 | 0x0100, /* R37 - SPKOUT Boost */ | 82 | { 39, 0x0079 }, /* R39 - Speaker Volume Right */ |
82 | 0x0079, /* R38 - Speaker Volume Left */ | 83 | { 40, 0x0000 }, /* R40 - Input Mixer2 */ |
83 | 0x0079, /* R39 - Speaker Volume Right */ | 84 | { 41, 0x0000 }, /* R41 - Input Mixer3 */ |
84 | 0x0000, /* R40 - Input Mixer2 */ | 85 | { 42, 0x0000 }, /* R42 - Input Mixer4 */ |
85 | 0x0000, /* R41 - Input Mixer3 */ | 86 | { 43, 0x0000 }, /* R43 - Input Mixer5 */ |
86 | 0x0000, /* R42 - Input Mixer4 */ | 87 | { 44, 0x0000 }, /* R44 - Input Mixer6 */ |
87 | 0x0000, /* R43 - Input Mixer5 */ | 88 | { 45, 0x0000 }, /* R45 - Output Mixer1 */ |
88 | 0x0000, /* R44 - Input Mixer6 */ | 89 | { 46, 0x0000 }, /* R46 - Output Mixer2 */ |
89 | 0x0000, /* R45 - Output Mixer1 */ | 90 | { 47, 0x0000 }, /* R47 - Output Mixer3 */ |
90 | 0x0000, /* R46 - Output Mixer2 */ | 91 | { 48, 0x0000 }, /* R48 - Output Mixer4 */ |
91 | 0x0000, /* R47 - Output Mixer3 */ | 92 | { 49, 0x0000 }, /* R49 - Output Mixer5 */ |
92 | 0x0000, /* R48 - Output Mixer4 */ | 93 | { 50, 0x0000 }, /* R50 - Output Mixer6 */ |
93 | 0x0000, /* R49 - Output Mixer5 */ | 94 | { 51, 0x0000 }, /* R51 - HPOUT2 Mixer */ |
94 | 0x0000, /* R50 - Output Mixer6 */ | 95 | { 52, 0x0000 }, /* R52 - Line Mixer1 */ |
95 | 0x0000, /* R51 - HPOUT2 Mixer */ | 96 | { 53, 0x0000 }, /* R53 - Line Mixer2 */ |
96 | 0x0000, /* R52 - Line Mixer1 */ | 97 | { 54, 0x0000 }, /* R54 - Speaker Mixer */ |
97 | 0x0000, /* R53 - Line Mixer2 */ | 98 | { 55, 0x0000 }, /* R55 - Additional Control */ |
98 | 0x0000, /* R54 - Speaker Mixer */ | 99 | { 56, 0x0000 }, /* R56 - AntiPOP1 */ |
99 | 0x0000, /* R55 - Additional Control */ | 100 | { 57, 0x0000 }, /* R57 - AntiPOP2 */ |
100 | 0x0000, /* R56 - AntiPOP1 */ | 101 | { 58, 0x0000 }, /* R58 - MICBIAS */ |
101 | 0x0000, /* R57 - AntiPOP2 */ | 102 | { 60, 0x0000 }, /* R60 - FLL Control 1 */ |
102 | 0x0000, /* R58 - MICBIAS */ | 103 | { 61, 0x0000 }, /* R61 - FLL Control 2 */ |
103 | 0x0000, /* R59 */ | 104 | { 62, 0x0000 }, /* R62 - FLL Control 3 */ |
104 | 0x0000, /* R60 - FLL Control 1 */ | 105 | { 63, 0x2EE0 }, /* R63 - FLL Control 4 */ |
105 | 0x0000, /* R61 - FLL Control 2 */ | 106 | { 64, 0x0002 }, /* R64 - FLL Control 5 */ |
106 | 0x0000, /* R62 - FLL Control 3 */ | 107 | { 65, 0x2287 }, /* R65 - Clocking 3 */ |
107 | 0x2EE0, /* R63 - FLL Control 4 */ | 108 | { 66, 0x025F }, /* R66 - Clocking 4 */ |
108 | 0x0002, /* R64 - FLL Control 5 */ | 109 | { 67, 0x0000 }, /* R67 - MW Slave Control */ |
109 | 0x2287, /* R65 - Clocking 3 */ | 110 | { 69, 0x0002 }, /* R69 - Bus Control 1 */ |
110 | 0x025F, /* R66 - Clocking 4 */ | 111 | { 70, 0x0000 }, /* R70 - Write Sequencer 0 */ |
111 | 0x0000, /* R67 - MW Slave Control */ | 112 | { 71, 0x0000 }, /* R71 - Write Sequencer 1 */ |
112 | 0x0000, /* R68 */ | 113 | { 72, 0x0000 }, /* R72 - Write Sequencer 2 */ |
113 | 0x0002, /* R69 - Bus Control 1 */ | 114 | { 73, 0x0000 }, /* R73 - Write Sequencer 3 */ |
114 | 0x0000, /* R70 - Write Sequencer 0 */ | 115 | { 74, 0x0000 }, /* R74 - Write Sequencer 4 */ |
115 | 0x0000, /* R71 - Write Sequencer 1 */ | 116 | { 75, 0x0000 }, /* R75 - Write Sequencer 5 */ |
116 | 0x0000, /* R72 - Write Sequencer 2 */ | 117 | { 76, 0x1F25 }, /* R76 - Charge Pump 1 */ |
117 | 0x0000, /* R73 - Write Sequencer 3 */ | 118 | { 81, 0x0000 }, /* R81 - Class W 0 */ |
118 | 0x0000, /* R74 - Write Sequencer 4 */ | 119 | { 85, 0x054A }, /* R85 - DC Servo 1 */ |
119 | 0x0000, /* R75 - Write Sequencer 5 */ | 120 | { 87, 0x0000 }, /* R87 - DC Servo 3 */ |
120 | 0x1F25, /* R76 - Charge Pump 1 */ | 121 | { 96, 0x0100 }, /* R96 - Analogue HP 0 */ |
121 | 0x0000, /* R77 */ | 122 | { 98, 0x0000 }, /* R98 - EQ1 */ |
122 | 0x0000, /* R78 */ | 123 | { 99, 0x000C }, /* R99 - EQ2 */ |
123 | 0x0000, /* R79 */ | 124 | { 100, 0x000C }, /* R100 - EQ3 */ |
124 | 0x0000, /* R80 */ | 125 | { 101, 0x000C }, /* R101 - EQ4 */ |
125 | 0x0000, /* R81 - Class W 0 */ | 126 | { 102, 0x000C }, /* R102 - EQ5 */ |
126 | 0x0000, /* R82 */ | 127 | { 103, 0x000C }, /* R103 - EQ6 */ |
127 | 0x0000, /* R83 */ | 128 | { 104, 0x0FCA }, /* R104 - EQ7 */ |
128 | 0x0000, /* R84 - DC Servo 0 */ | 129 | { 105, 0x0400 }, /* R105 - EQ8 */ |
129 | 0x054A, /* R85 - DC Servo 1 */ | 130 | { 106, 0x00D8 }, /* R106 - EQ9 */ |
130 | 0x0000, /* R86 */ | 131 | { 107, 0x1EB5 }, /* R107 - EQ10 */ |
131 | 0x0000, /* R87 - DC Servo 3 */ | 132 | { 108, 0xF145 }, /* R108 - EQ11 */ |
132 | 0x0000, /* R88 - DC Servo Readback 0 */ | 133 | { 109, 0x0B75 }, /* R109 - EQ12 */ |
133 | 0x0000, /* R89 - DC Servo Readback 1 */ | 134 | { 110, 0x01C5 }, /* R110 - EQ13 */ |
134 | 0x0000, /* R90 - DC Servo Readback 2 */ | 135 | { 111, 0x1C58 }, /* R111 - EQ14 */ |
135 | 0x0000, /* R91 */ | 136 | { 112, 0xF373 }, /* R112 - EQ15 */ |
136 | 0x0000, /* R92 */ | 137 | { 113, 0x0A54 }, /* R113 - EQ16 */ |
137 | 0x0000, /* R93 */ | 138 | { 114, 0x0558 }, /* R114 - EQ17 */ |
138 | 0x0000, /* R94 */ | 139 | { 115, 0x168E }, /* R115 - EQ18 */ |
139 | 0x0000, /* R95 */ | 140 | { 116, 0xF829 }, /* R116 - EQ19 */ |
140 | 0x0100, /* R96 - Analogue HP 0 */ | 141 | { 117, 0x07AD }, /* R117 - EQ20 */ |
141 | 0x0000, /* R97 */ | 142 | { 118, 0x1103 }, /* R118 - EQ21 */ |
142 | 0x0000, /* R98 - EQ1 */ | 143 | { 119, 0x0564 }, /* R119 - EQ22 */ |
143 | 0x000C, /* R99 - EQ2 */ | 144 | { 120, 0x0559 }, /* R120 - EQ23 */ |
144 | 0x000C, /* R100 - EQ3 */ | 145 | { 121, 0x4000 }, /* R121 - EQ24 */ |
145 | 0x000C, /* R101 - EQ4 */ | 146 | { 122, 0x0000 }, /* R122 - Digital Pulls */ |
146 | 0x000C, /* R102 - EQ5 */ | 147 | { 123, 0x0F08 }, /* R123 - DRC Control 1 */ |
147 | 0x000C, /* R103 - EQ6 */ | 148 | { 124, 0x0000 }, /* R124 - DRC Control 2 */ |
148 | 0x0FCA, /* R104 - EQ7 */ | 149 | { 125, 0x0080 }, /* R125 - DRC Control 3 */ |
149 | 0x0400, /* R105 - EQ8 */ | 150 | { 126, 0x0000 }, /* R126 - DRC Control 4 */ |
150 | 0x00D8, /* R106 - EQ9 */ | ||
151 | 0x1EB5, /* R107 - EQ10 */ | ||
152 | 0xF145, /* R108 - EQ11 */ | ||
153 | 0x0B75, /* R109 - EQ12 */ | ||
154 | 0x01C5, /* R110 - EQ13 */ | ||
155 | 0x1C58, /* R111 - EQ14 */ | ||
156 | 0xF373, /* R112 - EQ15 */ | ||
157 | 0x0A54, /* R113 - EQ16 */ | ||
158 | 0x0558, /* R114 - EQ17 */ | ||
159 | 0x168E, /* R115 - EQ18 */ | ||
160 | 0xF829, /* R116 - EQ19 */ | ||
161 | 0x07AD, /* R117 - EQ20 */ | ||
162 | 0x1103, /* R118 - EQ21 */ | ||
163 | 0x0564, /* R119 - EQ22 */ | ||
164 | 0x0559, /* R120 - EQ23 */ | ||
165 | 0x4000, /* R121 - EQ24 */ | ||
166 | 0x0000, /* R122 - Digital Pulls */ | ||
167 | 0x0F08, /* R123 - DRC Control 1 */ | ||
168 | 0x0000, /* R124 - DRC Control 2 */ | ||
169 | 0x0080, /* R125 - DRC Control 3 */ | ||
170 | 0x0000, /* R126 - DRC Control 4 */ | ||
171 | }; | 151 | }; |
172 | 152 | ||
173 | static struct { | 153 | static struct { |
@@ -225,9 +205,11 @@ static struct { | |||
225 | 205 | ||
226 | struct wm8993_priv { | 206 | struct wm8993_priv { |
227 | struct wm_hubs_data hubs_data; | 207 | struct wm_hubs_data hubs_data; |
208 | struct device *dev; | ||
209 | struct regmap *regmap; | ||
228 | struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES]; | 210 | struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES]; |
229 | struct wm8993_platform_data pdata; | 211 | struct wm8993_platform_data pdata; |
230 | enum snd_soc_control_type control_type; | 212 | struct completion fll_lock; |
231 | int master; | 213 | int master; |
232 | int sysclk_source; | 214 | int sysclk_source; |
233 | int tdm_slots; | 215 | int tdm_slots; |
@@ -242,17 +224,137 @@ struct wm8993_priv { | |||
242 | int fll_src; | 224 | int fll_src; |
243 | }; | 225 | }; |
244 | 226 | ||
245 | static int wm8993_volatile(struct snd_soc_codec *codec, unsigned int reg) | 227 | static bool wm8993_volatile(struct device *dev, unsigned int reg) |
246 | { | 228 | { |
247 | switch (reg) { | 229 | switch (reg) { |
248 | case WM8993_SOFTWARE_RESET: | 230 | case WM8993_SOFTWARE_RESET: |
231 | case WM8993_GPIO_CTRL_1: | ||
249 | case WM8993_DC_SERVO_0: | 232 | case WM8993_DC_SERVO_0: |
250 | case WM8993_DC_SERVO_READBACK_0: | 233 | case WM8993_DC_SERVO_READBACK_0: |
251 | case WM8993_DC_SERVO_READBACK_1: | 234 | case WM8993_DC_SERVO_READBACK_1: |
252 | case WM8993_DC_SERVO_READBACK_2: | 235 | case WM8993_DC_SERVO_READBACK_2: |
253 | return 1; | 236 | return true; |
254 | default: | 237 | default: |
255 | return 0; | 238 | return false; |
239 | } | ||
240 | } | ||
241 | |||
242 | static bool wm8993_readable(struct device *dev, unsigned int reg) | ||
243 | { | ||
244 | switch (reg) { | ||
245 | case WM8993_SOFTWARE_RESET: | ||
246 | case WM8993_POWER_MANAGEMENT_1: | ||
247 | case WM8993_POWER_MANAGEMENT_2: | ||
248 | case WM8993_POWER_MANAGEMENT_3: | ||
249 | case WM8993_AUDIO_INTERFACE_1: | ||
250 | case WM8993_AUDIO_INTERFACE_2: | ||
251 | case WM8993_CLOCKING_1: | ||
252 | case WM8993_CLOCKING_2: | ||
253 | case WM8993_AUDIO_INTERFACE_3: | ||
254 | case WM8993_AUDIO_INTERFACE_4: | ||
255 | case WM8993_DAC_CTRL: | ||
256 | case WM8993_LEFT_DAC_DIGITAL_VOLUME: | ||
257 | case WM8993_RIGHT_DAC_DIGITAL_VOLUME: | ||
258 | case WM8993_DIGITAL_SIDE_TONE: | ||
259 | case WM8993_ADC_CTRL: | ||
260 | case WM8993_LEFT_ADC_DIGITAL_VOLUME: | ||
261 | case WM8993_RIGHT_ADC_DIGITAL_VOLUME: | ||
262 | case WM8993_GPIO_CTRL_1: | ||
263 | case WM8993_GPIO1: | ||
264 | case WM8993_IRQ_DEBOUNCE: | ||
265 | case WM8993_GPIOCTRL_2: | ||
266 | case WM8993_GPIO_POL: | ||
267 | case WM8993_LEFT_LINE_INPUT_1_2_VOLUME: | ||
268 | case WM8993_LEFT_LINE_INPUT_3_4_VOLUME: | ||
269 | case WM8993_RIGHT_LINE_INPUT_1_2_VOLUME: | ||
270 | case WM8993_RIGHT_LINE_INPUT_3_4_VOLUME: | ||
271 | case WM8993_LEFT_OUTPUT_VOLUME: | ||
272 | case WM8993_RIGHT_OUTPUT_VOLUME: | ||
273 | case WM8993_LINE_OUTPUTS_VOLUME: | ||
274 | case WM8993_HPOUT2_VOLUME: | ||
275 | case WM8993_LEFT_OPGA_VOLUME: | ||
276 | case WM8993_RIGHT_OPGA_VOLUME: | ||
277 | case WM8993_SPKMIXL_ATTENUATION: | ||
278 | case WM8993_SPKMIXR_ATTENUATION: | ||
279 | case WM8993_SPKOUT_MIXERS: | ||
280 | case WM8993_SPKOUT_BOOST: | ||
281 | case WM8993_SPEAKER_VOLUME_LEFT: | ||
282 | case WM8993_SPEAKER_VOLUME_RIGHT: | ||
283 | case WM8993_INPUT_MIXER2: | ||
284 | case WM8993_INPUT_MIXER3: | ||
285 | case WM8993_INPUT_MIXER4: | ||
286 | case WM8993_INPUT_MIXER5: | ||
287 | case WM8993_INPUT_MIXER6: | ||
288 | case WM8993_OUTPUT_MIXER1: | ||
289 | case WM8993_OUTPUT_MIXER2: | ||
290 | case WM8993_OUTPUT_MIXER3: | ||
291 | case WM8993_OUTPUT_MIXER4: | ||
292 | case WM8993_OUTPUT_MIXER5: | ||
293 | case WM8993_OUTPUT_MIXER6: | ||
294 | case WM8993_HPOUT2_MIXER: | ||
295 | case WM8993_LINE_MIXER1: | ||
296 | case WM8993_LINE_MIXER2: | ||
297 | case WM8993_SPEAKER_MIXER: | ||
298 | case WM8993_ADDITIONAL_CONTROL: | ||
299 | case WM8993_ANTIPOP1: | ||
300 | case WM8993_ANTIPOP2: | ||
301 | case WM8993_MICBIAS: | ||
302 | case WM8993_FLL_CONTROL_1: | ||
303 | case WM8993_FLL_CONTROL_2: | ||
304 | case WM8993_FLL_CONTROL_3: | ||
305 | case WM8993_FLL_CONTROL_4: | ||
306 | case WM8993_FLL_CONTROL_5: | ||
307 | case WM8993_CLOCKING_3: | ||
308 | case WM8993_CLOCKING_4: | ||
309 | case WM8993_MW_SLAVE_CONTROL: | ||
310 | case WM8993_BUS_CONTROL_1: | ||
311 | case WM8993_WRITE_SEQUENCER_0: | ||
312 | case WM8993_WRITE_SEQUENCER_1: | ||
313 | case WM8993_WRITE_SEQUENCER_2: | ||
314 | case WM8993_WRITE_SEQUENCER_3: | ||
315 | case WM8993_WRITE_SEQUENCER_4: | ||
316 | case WM8993_WRITE_SEQUENCER_5: | ||
317 | case WM8993_CHARGE_PUMP_1: | ||
318 | case WM8993_CLASS_W_0: | ||
319 | case WM8993_DC_SERVO_0: | ||
320 | case WM8993_DC_SERVO_1: | ||
321 | case WM8993_DC_SERVO_3: | ||
322 | case WM8993_DC_SERVO_READBACK_0: | ||
323 | case WM8993_DC_SERVO_READBACK_1: | ||
324 | case WM8993_DC_SERVO_READBACK_2: | ||
325 | case WM8993_ANALOGUE_HP_0: | ||
326 | case WM8993_EQ1: | ||
327 | case WM8993_EQ2: | ||
328 | case WM8993_EQ3: | ||
329 | case WM8993_EQ4: | ||
330 | case WM8993_EQ5: | ||
331 | case WM8993_EQ6: | ||
332 | case WM8993_EQ7: | ||
333 | case WM8993_EQ8: | ||
334 | case WM8993_EQ9: | ||
335 | case WM8993_EQ10: | ||
336 | case WM8993_EQ11: | ||
337 | case WM8993_EQ12: | ||
338 | case WM8993_EQ13: | ||
339 | case WM8993_EQ14: | ||
340 | case WM8993_EQ15: | ||
341 | case WM8993_EQ16: | ||
342 | case WM8993_EQ17: | ||
343 | case WM8993_EQ18: | ||
344 | case WM8993_EQ19: | ||
345 | case WM8993_EQ20: | ||
346 | case WM8993_EQ21: | ||
347 | case WM8993_EQ22: | ||
348 | case WM8993_EQ23: | ||
349 | case WM8993_EQ24: | ||
350 | case WM8993_DIGITAL_PULLS: | ||
351 | case WM8993_DRC_CONTROL_1: | ||
352 | case WM8993_DRC_CONTROL_2: | ||
353 | case WM8993_DRC_CONTROL_3: | ||
354 | case WM8993_DRC_CONTROL_4: | ||
355 | return true; | ||
356 | default: | ||
357 | return false; | ||
256 | } | 358 | } |
257 | } | 359 | } |
258 | 360 | ||
@@ -369,8 +471,10 @@ static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
369 | unsigned int Fref, unsigned int Fout) | 471 | unsigned int Fref, unsigned int Fout) |
370 | { | 472 | { |
371 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); | 473 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
474 | struct i2c_client *i2c = to_i2c_client(codec->dev); | ||
372 | u16 reg1, reg4, reg5; | 475 | u16 reg1, reg4, reg5; |
373 | struct _fll_div fll_div; | 476 | struct _fll_div fll_div; |
477 | unsigned int timeout; | ||
374 | int ret; | 478 | int ret; |
375 | 479 | ||
376 | /* Any change? */ | 480 | /* Any change? */ |
@@ -441,14 +545,22 @@ static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
441 | reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT; | 545 | reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT; |
442 | snd_soc_write(codec, WM8993_FLL_CONTROL_5, reg5); | 546 | snd_soc_write(codec, WM8993_FLL_CONTROL_5, reg5); |
443 | 547 | ||
548 | /* If we've got an interrupt wired up make sure we get it */ | ||
549 | if (i2c->irq) | ||
550 | timeout = msecs_to_jiffies(20); | ||
551 | else if (Fref < 1000000) | ||
552 | timeout = msecs_to_jiffies(3); | ||
553 | else | ||
554 | timeout = msecs_to_jiffies(1); | ||
555 | |||
556 | try_wait_for_completion(&wm8993->fll_lock); | ||
557 | |||
444 | /* Enable the FLL */ | 558 | /* Enable the FLL */ |
445 | snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA); | 559 | snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA); |
446 | 560 | ||
447 | /* Both overestimates */ | 561 | timeout = wait_for_completion_timeout(&wm8993->fll_lock, timeout); |
448 | if (Fref < 1000000) | 562 | if (i2c->irq && !timeout) |
449 | msleep(3); | 563 | dev_warn(codec->dev, "Timed out waiting for FLL\n"); |
450 | else | ||
451 | msleep(1); | ||
452 | 564 | ||
453 | dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); | 565 | dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); |
454 | 566 | ||
@@ -946,6 +1058,8 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, | |||
946 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); | 1058 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
947 | int ret; | 1059 | int ret; |
948 | 1060 | ||
1061 | wm_hubs_set_bias_level(codec, level); | ||
1062 | |||
949 | switch (level) { | 1063 | switch (level) { |
950 | case SND_SOC_BIAS_ON: | 1064 | case SND_SOC_BIAS_ON: |
951 | case SND_SOC_BIAS_PREPARE: | 1065 | case SND_SOC_BIAS_PREPARE: |
@@ -963,12 +1077,10 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, | |||
963 | if (ret != 0) | 1077 | if (ret != 0) |
964 | return ret; | 1078 | return ret; |
965 | 1079 | ||
966 | snd_soc_cache_sync(codec); | 1080 | regcache_cache_only(wm8993->regmap, false); |
1081 | regcache_sync(wm8993->regmap); | ||
967 | 1082 | ||
968 | /* Tune DC servo configuration */ | 1083 | wm_hubs_vmid_ena(codec); |
969 | snd_soc_write(codec, 0x44, 3); | ||
970 | snd_soc_write(codec, 0x56, 3); | ||
971 | snd_soc_write(codec, 0x44, 0); | ||
972 | 1084 | ||
973 | /* Bring up VMID with fast soft start */ | 1085 | /* Bring up VMID with fast soft start */ |
974 | snd_soc_update_bits(codec, WM8993_ANTIPOP2, | 1086 | snd_soc_update_bits(codec, WM8993_ANTIPOP2, |
@@ -1024,14 +1136,8 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, | |||
1024 | WM8993_VMID_RAMP_MASK | | 1136 | WM8993_VMID_RAMP_MASK | |
1025 | WM8993_BIAS_SRC, 0); | 1137 | WM8993_BIAS_SRC, 0); |
1026 | 1138 | ||
1027 | #ifdef CONFIG_REGULATOR | 1139 | regcache_cache_only(wm8993->regmap, true); |
1028 | /* Post 2.6.34 we will be able to get a callback when | 1140 | regcache_mark_dirty(wm8993->regmap); |
1029 | * the regulators are disabled which we can use but | ||
1030 | * for now just assume that the power will be cut if | ||
1031 | * the regulator API is in use. | ||
1032 | */ | ||
1033 | codec->cache_sync = 1; | ||
1034 | #endif | ||
1035 | 1141 | ||
1036 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), | 1142 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), |
1037 | wm8993->supplies); | 1143 | wm8993->supplies); |
@@ -1378,6 +1484,45 @@ out: | |||
1378 | return 0; | 1484 | return 0; |
1379 | } | 1485 | } |
1380 | 1486 | ||
1487 | static irqreturn_t wm8993_irq(int irq, void *data) | ||
1488 | { | ||
1489 | struct wm8993_priv *wm8993 = data; | ||
1490 | int mask, val, ret; | ||
1491 | |||
1492 | ret = regmap_read(wm8993->regmap, WM8993_GPIO_CTRL_1, &val); | ||
1493 | if (ret != 0) { | ||
1494 | dev_err(wm8993->dev, "Failed to read interrupt status: %d\n", | ||
1495 | ret); | ||
1496 | return IRQ_NONE; | ||
1497 | } | ||
1498 | |||
1499 | ret = regmap_read(wm8993->regmap, WM8993_GPIOCTRL_2, &mask); | ||
1500 | if (ret != 0) { | ||
1501 | dev_err(wm8993->dev, "Failed to read interrupt mask: %d\n", | ||
1502 | ret); | ||
1503 | return IRQ_NONE; | ||
1504 | } | ||
1505 | |||
1506 | /* The IRQ pin status is visible in the register too */ | ||
1507 | val &= ~(mask | WM8993_IRQ); | ||
1508 | if (!val) | ||
1509 | return IRQ_NONE; | ||
1510 | |||
1511 | if (val & WM8993_TEMPOK_EINT) | ||
1512 | dev_crit(wm8993->dev, "Thermal warning\n"); | ||
1513 | |||
1514 | if (val & WM8993_FLL_LOCK_EINT) { | ||
1515 | dev_dbg(wm8993->dev, "FLL locked\n"); | ||
1516 | complete(&wm8993->fll_lock); | ||
1517 | } | ||
1518 | |||
1519 | ret = regmap_write(wm8993->regmap, WM8993_GPIO_CTRL_1, val); | ||
1520 | if (ret != 0) | ||
1521 | dev_err(wm8993->dev, "Failed to ack interrupt: %d\n", ret); | ||
1522 | |||
1523 | return IRQ_HANDLED; | ||
1524 | } | ||
1525 | |||
1381 | static const struct snd_soc_dai_ops wm8993_ops = { | 1526 | static const struct snd_soc_dai_ops wm8993_ops = { |
1382 | .set_sysclk = wm8993_set_sysclk, | 1527 | .set_sysclk = wm8993_set_sysclk, |
1383 | .set_fmt = wm8993_set_dai_fmt, | 1528 | .set_fmt = wm8993_set_dai_fmt, |
@@ -1402,6 +1547,7 @@ static struct snd_soc_dai_driver wm8993_dai = { | |||
1402 | .channels_max = 2, | 1547 | .channels_max = 2, |
1403 | .rates = WM8993_RATES, | 1548 | .rates = WM8993_RATES, |
1404 | .formats = WM8993_FORMATS, | 1549 | .formats = WM8993_FORMATS, |
1550 | .sig_bits = 24, | ||
1405 | }, | 1551 | }, |
1406 | .capture = { | 1552 | .capture = { |
1407 | .stream_name = "Capture", | 1553 | .stream_name = "Capture", |
@@ -1409,6 +1555,7 @@ static struct snd_soc_dai_driver wm8993_dai = { | |||
1409 | .channels_max = 2, | 1555 | .channels_max = 2, |
1410 | .rates = WM8993_RATES, | 1556 | .rates = WM8993_RATES, |
1411 | .formats = WM8993_FORMATS, | 1557 | .formats = WM8993_FORMATS, |
1558 | .sig_bits = 24, | ||
1412 | }, | 1559 | }, |
1413 | .ops = &wm8993_ops, | 1560 | .ops = &wm8993_ops, |
1414 | .symmetric_rates = 1, | 1561 | .symmetric_rates = 1, |
@@ -1418,49 +1565,20 @@ static int wm8993_probe(struct snd_soc_codec *codec) | |||
1418 | { | 1565 | { |
1419 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); | 1566 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
1420 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 1567 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
1421 | int ret, i, val; | 1568 | int ret; |
1422 | 1569 | ||
1423 | wm8993->hubs_data.hp_startup_mode = 1; | 1570 | wm8993->hubs_data.hp_startup_mode = 1; |
1424 | wm8993->hubs_data.dcs_codes_l = -2; | 1571 | wm8993->hubs_data.dcs_codes_l = -2; |
1425 | wm8993->hubs_data.dcs_codes_r = -2; | 1572 | wm8993->hubs_data.dcs_codes_r = -2; |
1426 | wm8993->hubs_data.series_startup = 1; | 1573 | wm8993->hubs_data.series_startup = 1; |
1427 | 1574 | ||
1428 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); | 1575 | codec->control_data = wm8993->regmap; |
1576 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
1429 | if (ret != 0) { | 1577 | if (ret != 0) { |
1430 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 1578 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
1431 | return ret; | 1579 | return ret; |
1432 | } | 1580 | } |
1433 | 1581 | ||
1434 | for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++) | ||
1435 | wm8993->supplies[i].supply = wm8993_supply_names[i]; | ||
1436 | |||
1437 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies), | ||
1438 | wm8993->supplies); | ||
1439 | if (ret != 0) { | ||
1440 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | ||
1441 | return ret; | ||
1442 | } | ||
1443 | |||
1444 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), | ||
1445 | wm8993->supplies); | ||
1446 | if (ret != 0) { | ||
1447 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | ||
1448 | goto err_get; | ||
1449 | } | ||
1450 | |||
1451 | val = snd_soc_read(codec, WM8993_SOFTWARE_RESET); | ||
1452 | if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) { | ||
1453 | dev_err(codec->dev, "Invalid ID register value %x\n", val); | ||
1454 | ret = -EINVAL; | ||
1455 | goto err_enable; | ||
1456 | } | ||
1457 | |||
1458 | ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff); | ||
1459 | if (ret != 0) | ||
1460 | goto err_enable; | ||
1461 | |||
1462 | codec->cache_only = 1; | ||
1463 | |||
1464 | /* By default we're using the output mixers */ | 1582 | /* By default we're using the output mixers */ |
1465 | wm8993->class_w_users = 2; | 1583 | wm8993->class_w_users = 2; |
1466 | 1584 | ||
@@ -1489,15 +1607,15 @@ static int wm8993_probe(struct snd_soc_codec *codec) | |||
1489 | 1607 | ||
1490 | ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1608 | ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1491 | if (ret != 0) | 1609 | if (ret != 0) |
1492 | goto err_enable; | 1610 | return ret; |
1493 | 1611 | ||
1494 | snd_soc_add_controls(codec, wm8993_snd_controls, | 1612 | snd_soc_add_codec_controls(codec, wm8993_snd_controls, |
1495 | ARRAY_SIZE(wm8993_snd_controls)); | 1613 | ARRAY_SIZE(wm8993_snd_controls)); |
1496 | if (wm8993->pdata.num_retune_configs != 0) { | 1614 | if (wm8993->pdata.num_retune_configs != 0) { |
1497 | dev_dbg(codec->dev, "Using ReTune Mobile\n"); | 1615 | dev_dbg(codec->dev, "Using ReTune Mobile\n"); |
1498 | } else { | 1616 | } else { |
1499 | dev_dbg(codec->dev, "No ReTune Mobile, using normal EQ\n"); | 1617 | dev_dbg(codec->dev, "No ReTune Mobile, using normal EQ\n"); |
1500 | snd_soc_add_controls(codec, wm8993_eq_controls, | 1618 | snd_soc_add_codec_controls(codec, wm8993_eq_controls, |
1501 | ARRAY_SIZE(wm8993_eq_controls)); | 1619 | ARRAY_SIZE(wm8993_eq_controls)); |
1502 | } | 1620 | } |
1503 | 1621 | ||
@@ -1509,13 +1627,14 @@ static int wm8993_probe(struct snd_soc_codec *codec) | |||
1509 | wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff, | 1627 | wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff, |
1510 | wm8993->pdata.lineout2_diff); | 1628 | wm8993->pdata.lineout2_diff); |
1511 | 1629 | ||
1630 | /* If the line outputs are differential then we aren't presenting | ||
1631 | * VMID as an output and can disable it. | ||
1632 | */ | ||
1633 | if (wm8993->pdata.lineout1_diff && wm8993->pdata.lineout2_diff) | ||
1634 | codec->dapm.idle_bias_off = 1; | ||
1635 | |||
1512 | return 0; | 1636 | return 0; |
1513 | 1637 | ||
1514 | err_enable: | ||
1515 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1516 | err_get: | ||
1517 | regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1518 | return ret; | ||
1519 | } | 1638 | } |
1520 | 1639 | ||
1521 | static int wm8993_remove(struct snd_soc_codec *codec) | 1640 | static int wm8993_remove(struct snd_soc_codec *codec) |
@@ -1578,41 +1697,149 @@ static int wm8993_resume(struct snd_soc_codec *codec) | |||
1578 | #define wm8993_resume NULL | 1697 | #define wm8993_resume NULL |
1579 | #endif | 1698 | #endif |
1580 | 1699 | ||
1700 | /* Tune DC servo configuration */ | ||
1701 | static struct reg_default wm8993_regmap_patch[] = { | ||
1702 | { 0x44, 3 }, | ||
1703 | { 0x56, 3 }, | ||
1704 | { 0x44, 0 }, | ||
1705 | }; | ||
1706 | |||
1707 | static const struct regmap_config wm8993_regmap = { | ||
1708 | .reg_bits = 8, | ||
1709 | .val_bits = 16, | ||
1710 | |||
1711 | .max_register = WM8993_MAX_REGISTER, | ||
1712 | .volatile_reg = wm8993_volatile, | ||
1713 | .readable_reg = wm8993_readable, | ||
1714 | |||
1715 | .cache_type = REGCACHE_RBTREE, | ||
1716 | .reg_defaults = wm8993_reg_defaults, | ||
1717 | .num_reg_defaults = ARRAY_SIZE(wm8993_reg_defaults), | ||
1718 | }; | ||
1719 | |||
1581 | static struct snd_soc_codec_driver soc_codec_dev_wm8993 = { | 1720 | static struct snd_soc_codec_driver soc_codec_dev_wm8993 = { |
1582 | .probe = wm8993_probe, | 1721 | .probe = wm8993_probe, |
1583 | .remove = wm8993_remove, | 1722 | .remove = wm8993_remove, |
1584 | .suspend = wm8993_suspend, | 1723 | .suspend = wm8993_suspend, |
1585 | .resume = wm8993_resume, | 1724 | .resume = wm8993_resume, |
1586 | .set_bias_level = wm8993_set_bias_level, | 1725 | .set_bias_level = wm8993_set_bias_level, |
1587 | .reg_cache_size = ARRAY_SIZE(wm8993_reg_defaults), | ||
1588 | .reg_word_size = sizeof(u16), | ||
1589 | .reg_cache_default = wm8993_reg_defaults, | ||
1590 | .volatile_register = wm8993_volatile, | ||
1591 | }; | 1726 | }; |
1592 | 1727 | ||
1593 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1594 | static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, | 1728 | static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, |
1595 | const struct i2c_device_id *id) | 1729 | const struct i2c_device_id *id) |
1596 | { | 1730 | { |
1597 | struct wm8993_priv *wm8993; | 1731 | struct wm8993_priv *wm8993; |
1598 | int ret; | 1732 | unsigned int reg; |
1733 | int ret, i; | ||
1599 | 1734 | ||
1600 | wm8993 = devm_kzalloc(&i2c->dev, sizeof(struct wm8993_priv), | 1735 | wm8993 = devm_kzalloc(&i2c->dev, sizeof(struct wm8993_priv), |
1601 | GFP_KERNEL); | 1736 | GFP_KERNEL); |
1602 | if (wm8993 == NULL) | 1737 | if (wm8993 == NULL) |
1603 | return -ENOMEM; | 1738 | return -ENOMEM; |
1604 | 1739 | ||
1740 | wm8993->dev = &i2c->dev; | ||
1741 | init_completion(&wm8993->fll_lock); | ||
1742 | |||
1743 | wm8993->regmap = regmap_init_i2c(i2c, &wm8993_regmap); | ||
1744 | if (IS_ERR(wm8993->regmap)) { | ||
1745 | ret = PTR_ERR(wm8993->regmap); | ||
1746 | dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); | ||
1747 | return ret; | ||
1748 | } | ||
1749 | |||
1605 | i2c_set_clientdata(i2c, wm8993); | 1750 | i2c_set_clientdata(i2c, wm8993); |
1606 | 1751 | ||
1752 | for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++) | ||
1753 | wm8993->supplies[i].supply = wm8993_supply_names[i]; | ||
1754 | |||
1755 | ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8993->supplies), | ||
1756 | wm8993->supplies); | ||
1757 | if (ret != 0) { | ||
1758 | dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); | ||
1759 | goto err; | ||
1760 | } | ||
1761 | |||
1762 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), | ||
1763 | wm8993->supplies); | ||
1764 | if (ret != 0) { | ||
1765 | dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); | ||
1766 | goto err_get; | ||
1767 | } | ||
1768 | |||
1769 | ret = regmap_read(wm8993->regmap, WM8993_SOFTWARE_RESET, ®); | ||
1770 | if (ret != 0) { | ||
1771 | dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); | ||
1772 | goto err_enable; | ||
1773 | } | ||
1774 | |||
1775 | if (reg != 0x8993) { | ||
1776 | dev_err(&i2c->dev, "Invalid ID register value %x\n", reg); | ||
1777 | ret = -EINVAL; | ||
1778 | goto err_enable; | ||
1779 | } | ||
1780 | |||
1781 | ret = regmap_write(wm8993->regmap, WM8993_SOFTWARE_RESET, 0xffff); | ||
1782 | if (ret != 0) | ||
1783 | goto err_enable; | ||
1784 | |||
1785 | ret = regmap_register_patch(wm8993->regmap, wm8993_regmap_patch, | ||
1786 | ARRAY_SIZE(wm8993_regmap_patch)); | ||
1787 | if (ret != 0) | ||
1788 | dev_warn(wm8993->dev, "Failed to apply regmap patch: %d\n", | ||
1789 | ret); | ||
1790 | |||
1791 | if (i2c->irq) { | ||
1792 | /* Put GPIO1 into interrupt mode (only GPIO1 can output IRQ) */ | ||
1793 | ret = regmap_update_bits(wm8993->regmap, WM8993_GPIO1, | ||
1794 | WM8993_GPIO1_PD | | ||
1795 | WM8993_GPIO1_SEL_MASK, 7); | ||
1796 | if (ret != 0) | ||
1797 | goto err_enable; | ||
1798 | |||
1799 | ret = request_threaded_irq(i2c->irq, NULL, wm8993_irq, | ||
1800 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, | ||
1801 | "wm8993", wm8993); | ||
1802 | if (ret != 0) | ||
1803 | goto err_enable; | ||
1804 | |||
1805 | } | ||
1806 | |||
1807 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1808 | |||
1809 | regcache_cache_only(wm8993->regmap, true); | ||
1810 | |||
1607 | ret = snd_soc_register_codec(&i2c->dev, | 1811 | ret = snd_soc_register_codec(&i2c->dev, |
1608 | &soc_codec_dev_wm8993, &wm8993_dai, 1); | 1812 | &soc_codec_dev_wm8993, &wm8993_dai, 1); |
1813 | if (ret != 0) { | ||
1814 | dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); | ||
1815 | goto err_irq; | ||
1816 | } | ||
1817 | |||
1818 | return 0; | ||
1819 | |||
1820 | err_irq: | ||
1821 | if (i2c->irq) | ||
1822 | free_irq(i2c->irq, wm8993); | ||
1823 | err_enable: | ||
1824 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1825 | err_get: | ||
1826 | regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1827 | err: | ||
1828 | regmap_exit(wm8993->regmap); | ||
1609 | return ret; | 1829 | return ret; |
1610 | } | 1830 | } |
1611 | 1831 | ||
1612 | static __devexit int wm8993_i2c_remove(struct i2c_client *client) | 1832 | static __devexit int wm8993_i2c_remove(struct i2c_client *i2c) |
1613 | { | 1833 | { |
1614 | snd_soc_unregister_codec(&client->dev); | 1834 | struct wm8993_priv *wm8993 = i2c_get_clientdata(i2c); |
1615 | kfree(i2c_get_clientdata(client)); | 1835 | |
1836 | snd_soc_unregister_codec(&i2c->dev); | ||
1837 | if (i2c->irq) | ||
1838 | free_irq(i2c->irq, wm8993); | ||
1839 | regmap_exit(wm8993->regmap); | ||
1840 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1841 | regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1842 | |||
1616 | return 0; | 1843 | return 0; |
1617 | } | 1844 | } |
1618 | 1845 | ||
@@ -1631,30 +1858,8 @@ static struct i2c_driver wm8993_i2c_driver = { | |||
1631 | .remove = __devexit_p(wm8993_i2c_remove), | 1858 | .remove = __devexit_p(wm8993_i2c_remove), |
1632 | .id_table = wm8993_i2c_id, | 1859 | .id_table = wm8993_i2c_id, |
1633 | }; | 1860 | }; |
1634 | #endif | ||
1635 | |||
1636 | static int __init wm8993_modinit(void) | ||
1637 | { | ||
1638 | int ret = 0; | ||
1639 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1640 | ret = i2c_add_driver(&wm8993_i2c_driver); | ||
1641 | if (ret != 0) { | ||
1642 | pr_err("WM8993: Unable to register I2C driver: %d\n", | ||
1643 | ret); | ||
1644 | } | ||
1645 | #endif | ||
1646 | return ret; | ||
1647 | } | ||
1648 | module_init(wm8993_modinit); | ||
1649 | |||
1650 | static void __exit wm8993_exit(void) | ||
1651 | { | ||
1652 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1653 | i2c_del_driver(&wm8993_i2c_driver); | ||
1654 | #endif | ||
1655 | } | ||
1656 | module_exit(wm8993_exit); | ||
1657 | 1861 | ||
1862 | module_i2c_driver(wm8993_i2c_driver); | ||
1658 | 1863 | ||
1659 | MODULE_DESCRIPTION("ASoC WM8993 driver"); | 1864 | MODULE_DESCRIPTION("ASoC WM8993 driver"); |
1660 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 1865 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |