Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only
2 : : /*
3 : : * Arizona core driver
4 : : *
5 : : * Copyright 2012 Wolfson Microelectronics plc
6 : : *
7 : : * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
8 : : */
9 : :
10 : : #include <linux/clk.h>
11 : : #include <linux/delay.h>
12 : : #include <linux/err.h>
13 : : #include <linux/gpio/consumer.h>
14 : : #include <linux/interrupt.h>
15 : : #include <linux/mfd/core.h>
16 : : #include <linux/module.h>
17 : : #include <linux/of.h>
18 : : #include <linux/of_device.h>
19 : : #include <linux/pm_runtime.h>
20 : : #include <linux/regmap.h>
21 : : #include <linux/regulator/consumer.h>
22 : : #include <linux/regulator/machine.h>
23 : : #include <linux/slab.h>
24 : : #include <linux/ktime.h>
25 : : #include <linux/platform_device.h>
26 : :
27 : : #include <linux/mfd/arizona/core.h>
28 : : #include <linux/mfd/arizona/registers.h>
29 : :
30 : : #include "arizona.h"
31 : :
32 : : static const char * const wm5102_core_supplies[] = {
33 : : "AVDD",
34 : : "DBVDD1",
35 : : };
36 : :
37 : 0 : int arizona_clk32k_enable(struct arizona *arizona)
38 : : {
39 : : int ret = 0;
40 : :
41 : 0 : mutex_lock(&arizona->clk_lock);
42 : :
43 : 0 : arizona->clk32k_ref++;
44 : :
45 [ # # ]: 0 : if (arizona->clk32k_ref == 1) {
46 [ # # # ]: 0 : switch (arizona->pdata.clk32k_src) {
47 : : case ARIZONA_32KZ_MCLK1:
48 : 0 : ret = pm_runtime_get_sync(arizona->dev);
49 [ # # ]: 0 : if (ret != 0)
50 : : goto err_ref;
51 : 0 : ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK1]);
52 [ # # ]: 0 : if (ret != 0) {
53 : 0 : pm_runtime_put_sync(arizona->dev);
54 : : goto err_ref;
55 : : }
56 : : break;
57 : : case ARIZONA_32KZ_MCLK2:
58 : 0 : ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK2]);
59 [ # # ]: 0 : if (ret != 0)
60 : : goto err_ref;
61 : : break;
62 : : }
63 : :
64 : 0 : ret = regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
65 : : ARIZONA_CLK_32K_ENA,
66 : : ARIZONA_CLK_32K_ENA);
67 : : }
68 : :
69 : : err_ref:
70 [ # # ]: 0 : if (ret != 0)
71 : 0 : arizona->clk32k_ref--;
72 : :
73 : 0 : mutex_unlock(&arizona->clk_lock);
74 : :
75 : 0 : return ret;
76 : : }
77 : : EXPORT_SYMBOL_GPL(arizona_clk32k_enable);
78 : :
79 : 0 : int arizona_clk32k_disable(struct arizona *arizona)
80 : : {
81 : 0 : mutex_lock(&arizona->clk_lock);
82 : :
83 [ # # ]: 0 : BUG_ON(arizona->clk32k_ref <= 0);
84 : :
85 : 0 : arizona->clk32k_ref--;
86 : :
87 [ # # ]: 0 : if (arizona->clk32k_ref == 0) {
88 : 0 : regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
89 : : ARIZONA_CLK_32K_ENA, 0);
90 : :
91 [ # # # ]: 0 : switch (arizona->pdata.clk32k_src) {
92 : : case ARIZONA_32KZ_MCLK1:
93 : 0 : pm_runtime_put_sync(arizona->dev);
94 : 0 : clk_disable_unprepare(arizona->mclk[ARIZONA_MCLK1]);
95 : : break;
96 : : case ARIZONA_32KZ_MCLK2:
97 : 0 : clk_disable_unprepare(arizona->mclk[ARIZONA_MCLK2]);
98 : : break;
99 : : }
100 : : }
101 : :
102 : 0 : mutex_unlock(&arizona->clk_lock);
103 : :
104 : 0 : return 0;
105 : : }
106 : : EXPORT_SYMBOL_GPL(arizona_clk32k_disable);
107 : :
108 : 0 : static irqreturn_t arizona_clkgen_err(int irq, void *data)
109 : : {
110 : : struct arizona *arizona = data;
111 : :
112 : 0 : dev_err(arizona->dev, "CLKGEN error\n");
113 : :
114 : 0 : return IRQ_HANDLED;
115 : : }
116 : :
117 : 0 : static irqreturn_t arizona_underclocked(int irq, void *data)
118 : : {
119 : : struct arizona *arizona = data;
120 : : unsigned int val;
121 : : int ret;
122 : :
123 : 0 : ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_8,
124 : : &val);
125 [ # # ]: 0 : if (ret != 0) {
126 : 0 : dev_err(arizona->dev, "Failed to read underclock status: %d\n",
127 : : ret);
128 : 0 : return IRQ_NONE;
129 : : }
130 : :
131 [ # # ]: 0 : if (val & ARIZONA_AIF3_UNDERCLOCKED_STS)
132 : 0 : dev_err(arizona->dev, "AIF3 underclocked\n");
133 [ # # ]: 0 : if (val & ARIZONA_AIF2_UNDERCLOCKED_STS)
134 : 0 : dev_err(arizona->dev, "AIF2 underclocked\n");
135 [ # # ]: 0 : if (val & ARIZONA_AIF1_UNDERCLOCKED_STS)
136 : 0 : dev_err(arizona->dev, "AIF1 underclocked\n");
137 [ # # ]: 0 : if (val & ARIZONA_ISRC3_UNDERCLOCKED_STS)
138 : 0 : dev_err(arizona->dev, "ISRC3 underclocked\n");
139 [ # # ]: 0 : if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS)
140 : 0 : dev_err(arizona->dev, "ISRC2 underclocked\n");
141 [ # # ]: 0 : if (val & ARIZONA_ISRC1_UNDERCLOCKED_STS)
142 : 0 : dev_err(arizona->dev, "ISRC1 underclocked\n");
143 [ # # ]: 0 : if (val & ARIZONA_FX_UNDERCLOCKED_STS)
144 : 0 : dev_err(arizona->dev, "FX underclocked\n");
145 [ # # ]: 0 : if (val & ARIZONA_ASRC_UNDERCLOCKED_STS)
146 : 0 : dev_err(arizona->dev, "ASRC underclocked\n");
147 [ # # ]: 0 : if (val & ARIZONA_DAC_UNDERCLOCKED_STS)
148 : 0 : dev_err(arizona->dev, "DAC underclocked\n");
149 [ # # ]: 0 : if (val & ARIZONA_ADC_UNDERCLOCKED_STS)
150 : 0 : dev_err(arizona->dev, "ADC underclocked\n");
151 [ # # ]: 0 : if (val & ARIZONA_MIXER_UNDERCLOCKED_STS)
152 : 0 : dev_err(arizona->dev, "Mixer dropped sample\n");
153 : :
154 : : return IRQ_HANDLED;
155 : : }
156 : :
157 : 0 : static irqreturn_t arizona_overclocked(int irq, void *data)
158 : : {
159 : : struct arizona *arizona = data;
160 : : unsigned int val[3];
161 : : int ret;
162 : :
163 : 0 : ret = regmap_bulk_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_6,
164 : : &val[0], 3);
165 [ # # ]: 0 : if (ret != 0) {
166 : 0 : dev_err(arizona->dev, "Failed to read overclock status: %d\n",
167 : : ret);
168 : 0 : return IRQ_NONE;
169 : : }
170 : :
171 [ # # ]: 0 : switch (arizona->type) {
172 : : case WM8998:
173 : : case WM1814:
174 : : /* Some bits are shifted on WM8998,
175 : : * rearrange to match the standard bit layout
176 : : */
177 : 0 : val[0] = ((val[0] & 0x60e0) >> 1) |
178 : 0 : ((val[0] & 0x1e00) >> 2) |
179 : 0 : (val[0] & 0x000f);
180 : 0 : break;
181 : : default:
182 : : break;
183 : : }
184 : :
185 [ # # ]: 0 : if (val[0] & ARIZONA_PWM_OVERCLOCKED_STS)
186 : 0 : dev_err(arizona->dev, "PWM overclocked\n");
187 [ # # ]: 0 : if (val[0] & ARIZONA_FX_CORE_OVERCLOCKED_STS)
188 : 0 : dev_err(arizona->dev, "FX core overclocked\n");
189 [ # # ]: 0 : if (val[0] & ARIZONA_DAC_SYS_OVERCLOCKED_STS)
190 : 0 : dev_err(arizona->dev, "DAC SYS overclocked\n");
191 [ # # ]: 0 : if (val[0] & ARIZONA_DAC_WARP_OVERCLOCKED_STS)
192 : 0 : dev_err(arizona->dev, "DAC WARP overclocked\n");
193 [ # # ]: 0 : if (val[0] & ARIZONA_ADC_OVERCLOCKED_STS)
194 : 0 : dev_err(arizona->dev, "ADC overclocked\n");
195 [ # # ]: 0 : if (val[0] & ARIZONA_MIXER_OVERCLOCKED_STS)
196 : 0 : dev_err(arizona->dev, "Mixer overclocked\n");
197 [ # # ]: 0 : if (val[0] & ARIZONA_AIF3_SYNC_OVERCLOCKED_STS)
198 : 0 : dev_err(arizona->dev, "AIF3 overclocked\n");
199 [ # # ]: 0 : if (val[0] & ARIZONA_AIF2_SYNC_OVERCLOCKED_STS)
200 : 0 : dev_err(arizona->dev, "AIF2 overclocked\n");
201 [ # # ]: 0 : if (val[0] & ARIZONA_AIF1_SYNC_OVERCLOCKED_STS)
202 : 0 : dev_err(arizona->dev, "AIF1 overclocked\n");
203 [ # # ]: 0 : if (val[0] & ARIZONA_PAD_CTRL_OVERCLOCKED_STS)
204 : 0 : dev_err(arizona->dev, "Pad control overclocked\n");
205 : :
206 [ # # ]: 0 : if (val[1] & ARIZONA_SLIMBUS_SUBSYS_OVERCLOCKED_STS)
207 : 0 : dev_err(arizona->dev, "Slimbus subsystem overclocked\n");
208 [ # # ]: 0 : if (val[1] & ARIZONA_SLIMBUS_ASYNC_OVERCLOCKED_STS)
209 : 0 : dev_err(arizona->dev, "Slimbus async overclocked\n");
210 [ # # ]: 0 : if (val[1] & ARIZONA_SLIMBUS_SYNC_OVERCLOCKED_STS)
211 : 0 : dev_err(arizona->dev, "Slimbus sync overclocked\n");
212 [ # # ]: 0 : if (val[1] & ARIZONA_ASRC_ASYNC_SYS_OVERCLOCKED_STS)
213 : 0 : dev_err(arizona->dev, "ASRC async system overclocked\n");
214 [ # # ]: 0 : if (val[1] & ARIZONA_ASRC_ASYNC_WARP_OVERCLOCKED_STS)
215 : 0 : dev_err(arizona->dev, "ASRC async WARP overclocked\n");
216 [ # # ]: 0 : if (val[1] & ARIZONA_ASRC_SYNC_SYS_OVERCLOCKED_STS)
217 : 0 : dev_err(arizona->dev, "ASRC sync system overclocked\n");
218 [ # # ]: 0 : if (val[1] & ARIZONA_ASRC_SYNC_WARP_OVERCLOCKED_STS)
219 : 0 : dev_err(arizona->dev, "ASRC sync WARP overclocked\n");
220 [ # # ]: 0 : if (val[1] & ARIZONA_ADSP2_1_OVERCLOCKED_STS)
221 : 0 : dev_err(arizona->dev, "DSP1 overclocked\n");
222 [ # # ]: 0 : if (val[1] & ARIZONA_ISRC3_OVERCLOCKED_STS)
223 : 0 : dev_err(arizona->dev, "ISRC3 overclocked\n");
224 [ # # ]: 0 : if (val[1] & ARIZONA_ISRC2_OVERCLOCKED_STS)
225 : 0 : dev_err(arizona->dev, "ISRC2 overclocked\n");
226 [ # # ]: 0 : if (val[1] & ARIZONA_ISRC1_OVERCLOCKED_STS)
227 : 0 : dev_err(arizona->dev, "ISRC1 overclocked\n");
228 : :
229 [ # # ]: 0 : if (val[2] & ARIZONA_SPDIF_OVERCLOCKED_STS)
230 : 0 : dev_err(arizona->dev, "SPDIF overclocked\n");
231 : :
232 : : return IRQ_HANDLED;
233 : : }
234 : :
235 : : #define ARIZONA_REG_POLL_DELAY_US 7500
236 : :
237 : 0 : static inline bool arizona_poll_reg_delay(ktime_t timeout)
238 : : {
239 [ # # ]: 0 : if (ktime_compare(ktime_get(), timeout) > 0)
240 : : return false;
241 : :
242 : 0 : usleep_range(ARIZONA_REG_POLL_DELAY_US / 2, ARIZONA_REG_POLL_DELAY_US);
243 : :
244 : 0 : return true;
245 : : }
246 : :
247 : 0 : static int arizona_poll_reg(struct arizona *arizona,
248 : : int timeout_ms, unsigned int reg,
249 : : unsigned int mask, unsigned int target)
250 : : {
251 : 0 : ktime_t timeout = ktime_add_us(ktime_get(), timeout_ms * USEC_PER_MSEC);
252 : 0 : unsigned int val = 0;
253 : : int ret;
254 : :
255 : : do {
256 : 0 : ret = regmap_read(arizona->regmap, reg, &val);
257 : :
258 [ # # ]: 0 : if ((val & mask) == target)
259 : : return 0;
260 [ # # ]: 0 : } while (arizona_poll_reg_delay(timeout));
261 : :
262 [ # # ]: 0 : if (ret) {
263 : 0 : dev_err(arizona->dev, "Failed polling reg 0x%x: %d\n",
264 : : reg, ret);
265 : 0 : return ret;
266 : : }
267 : :
268 : 0 : dev_err(arizona->dev, "Polling reg 0x%x timed out: %x\n", reg, val);
269 : 0 : return -ETIMEDOUT;
270 : : }
271 : :
272 : 0 : static int arizona_wait_for_boot(struct arizona *arizona)
273 : : {
274 : : int ret;
275 : :
276 : : /*
277 : : * We can't use an interrupt as we need to runtime resume to do so,
278 : : * we won't race with the interrupt handler as it'll be blocked on
279 : : * runtime resume.
280 : : */
281 : 0 : ret = arizona_poll_reg(arizona, 30, ARIZONA_INTERRUPT_RAW_STATUS_5,
282 : : ARIZONA_BOOT_DONE_STS, ARIZONA_BOOT_DONE_STS);
283 : :
284 [ # # ]: 0 : if (!ret)
285 : 0 : regmap_write(arizona->regmap, ARIZONA_INTERRUPT_STATUS_5,
286 : : ARIZONA_BOOT_DONE_STS);
287 : :
288 : 0 : pm_runtime_mark_last_busy(arizona->dev);
289 : :
290 : 0 : return ret;
291 : : }
292 : :
293 : : static inline void arizona_enable_reset(struct arizona *arizona)
294 : : {
295 [ # # # # : 0 : if (arizona->pdata.reset)
# # # # ]
296 : 0 : gpiod_set_raw_value_cansleep(arizona->pdata.reset, 0);
297 : : }
298 : :
299 : 0 : static void arizona_disable_reset(struct arizona *arizona)
300 : : {
301 [ # # ]: 0 : if (arizona->pdata.reset) {
302 [ # # ]: 0 : switch (arizona->type) {
303 : : case WM5110:
304 : : case WM8280:
305 : : /* Meet requirements for minimum reset duration */
306 : 0 : usleep_range(5000, 10000);
307 : 0 : break;
308 : : default:
309 : : break;
310 : : }
311 : :
312 : 0 : gpiod_set_raw_value_cansleep(arizona->pdata.reset, 1);
313 : 0 : usleep_range(1000, 5000);
314 : : }
315 : 0 : }
316 : :
317 : : struct arizona_sysclk_state {
318 : : unsigned int fll;
319 : : unsigned int sysclk;
320 : : };
321 : :
322 : 0 : static int arizona_enable_freerun_sysclk(struct arizona *arizona,
323 : : struct arizona_sysclk_state *state)
324 : : {
325 : : int ret, err;
326 : :
327 : : /* Cache existing FLL and SYSCLK settings */
328 : 0 : ret = regmap_read(arizona->regmap, ARIZONA_FLL1_CONTROL_1, &state->fll);
329 [ # # ]: 0 : if (ret) {
330 : 0 : dev_err(arizona->dev, "Failed to cache FLL settings: %d\n",
331 : : ret);
332 : 0 : return ret;
333 : : }
334 : 0 : ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1,
335 : : &state->sysclk);
336 [ # # ]: 0 : if (ret) {
337 : 0 : dev_err(arizona->dev, "Failed to cache SYSCLK settings: %d\n",
338 : : ret);
339 : 0 : return ret;
340 : : }
341 : :
342 : : /* Start up SYSCLK using the FLL in free running mode */
343 : 0 : ret = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1,
344 : : ARIZONA_FLL1_ENA | ARIZONA_FLL1_FREERUN);
345 [ # # ]: 0 : if (ret) {
346 : 0 : dev_err(arizona->dev,
347 : : "Failed to start FLL in freerunning mode: %d\n",
348 : : ret);
349 : 0 : return ret;
350 : : }
351 : 0 : ret = arizona_poll_reg(arizona, 180, ARIZONA_INTERRUPT_RAW_STATUS_5,
352 : : ARIZONA_FLL1_CLOCK_OK_STS,
353 : : ARIZONA_FLL1_CLOCK_OK_STS);
354 [ # # ]: 0 : if (ret)
355 : : goto err_fll;
356 : :
357 : 0 : ret = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, 0x0144);
358 [ # # ]: 0 : if (ret) {
359 : 0 : dev_err(arizona->dev, "Failed to start SYSCLK: %d\n", ret);
360 : 0 : goto err_fll;
361 : : }
362 : :
363 : : return 0;
364 : :
365 : : err_fll:
366 : 0 : err = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, state->fll);
367 [ # # ]: 0 : if (err)
368 : 0 : dev_err(arizona->dev,
369 : : "Failed to re-apply old FLL settings: %d\n", err);
370 : :
371 : 0 : return ret;
372 : : }
373 : :
374 : 0 : static int arizona_disable_freerun_sysclk(struct arizona *arizona,
375 : : struct arizona_sysclk_state *state)
376 : : {
377 : : int ret;
378 : :
379 : 0 : ret = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1,
380 : : state->sysclk);
381 [ # # ]: 0 : if (ret) {
382 : 0 : dev_err(arizona->dev,
383 : : "Failed to re-apply old SYSCLK settings: %d\n", ret);
384 : 0 : return ret;
385 : : }
386 : :
387 : 0 : ret = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, state->fll);
388 [ # # ]: 0 : if (ret) {
389 : 0 : dev_err(arizona->dev,
390 : : "Failed to re-apply old FLL settings: %d\n", ret);
391 : 0 : return ret;
392 : : }
393 : :
394 : : return 0;
395 : : }
396 : :
397 : 0 : static int wm5102_apply_hardware_patch(struct arizona *arizona)
398 : : {
399 : : struct arizona_sysclk_state state;
400 : : int err, ret;
401 : :
402 : 0 : ret = arizona_enable_freerun_sysclk(arizona, &state);
403 [ # # ]: 0 : if (ret)
404 : : return ret;
405 : :
406 : : /* Start the write sequencer and wait for it to finish */
407 : 0 : ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0,
408 : : ARIZONA_WSEQ_ENA | ARIZONA_WSEQ_START | 160);
409 [ # # ]: 0 : if (ret) {
410 : 0 : dev_err(arizona->dev, "Failed to start write sequencer: %d\n",
411 : : ret);
412 : 0 : goto err;
413 : : }
414 : :
415 : 0 : ret = arizona_poll_reg(arizona, 30, ARIZONA_WRITE_SEQUENCER_CTRL_1,
416 : : ARIZONA_WSEQ_BUSY, 0);
417 [ # # ]: 0 : if (ret)
418 : 0 : regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0,
419 : : ARIZONA_WSEQ_ABORT);
420 : :
421 : : err:
422 : 0 : err = arizona_disable_freerun_sysclk(arizona, &state);
423 : :
424 [ # # ]: 0 : return ret ?: err;
425 : : }
426 : :
427 : : /*
428 : : * Register patch to some of the CODECs internal write sequences
429 : : * to ensure a clean exit from the low power sleep state.
430 : : */
431 : : static const struct reg_sequence wm5110_sleep_patch[] = {
432 : : { 0x337A, 0xC100 },
433 : : { 0x337B, 0x0041 },
434 : : { 0x3300, 0xA210 },
435 : : { 0x3301, 0x050C },
436 : : };
437 : :
438 : 0 : static int wm5110_apply_sleep_patch(struct arizona *arizona)
439 : : {
440 : : struct arizona_sysclk_state state;
441 : : int err, ret;
442 : :
443 : 0 : ret = arizona_enable_freerun_sysclk(arizona, &state);
444 [ # # ]: 0 : if (ret)
445 : : return ret;
446 : :
447 : 0 : ret = regmap_multi_reg_write_bypassed(arizona->regmap,
448 : : wm5110_sleep_patch,
449 : : ARRAY_SIZE(wm5110_sleep_patch));
450 : :
451 : 0 : err = arizona_disable_freerun_sysclk(arizona, &state);
452 : :
453 [ # # ]: 0 : return ret ?: err;
454 : : }
455 : :
456 : 0 : static int wm5102_clear_write_sequencer(struct arizona *arizona)
457 : : {
458 : : int ret;
459 : :
460 : 0 : ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_3,
461 : : 0x0);
462 [ # # ]: 0 : if (ret) {
463 : 0 : dev_err(arizona->dev,
464 : : "Failed to clear write sequencer state: %d\n", ret);
465 : 0 : return ret;
466 : : }
467 : :
468 : : arizona_enable_reset(arizona);
469 : 0 : regulator_disable(arizona->dcvdd);
470 : :
471 : 0 : msleep(20);
472 : :
473 : 0 : ret = regulator_enable(arizona->dcvdd);
474 [ # # ]: 0 : if (ret) {
475 : 0 : dev_err(arizona->dev, "Failed to re-enable DCVDD: %d\n", ret);
476 : 0 : return ret;
477 : : }
478 : 0 : arizona_disable_reset(arizona);
479 : :
480 : 0 : return 0;
481 : : }
482 : :
483 : : #ifdef CONFIG_PM
484 : 0 : static int arizona_isolate_dcvdd(struct arizona *arizona)
485 : : {
486 : : int ret;
487 : :
488 : 0 : ret = regmap_update_bits(arizona->regmap,
489 : : ARIZONA_ISOLATION_CONTROL,
490 : : ARIZONA_ISOLATE_DCVDD1,
491 : : ARIZONA_ISOLATE_DCVDD1);
492 [ # # ]: 0 : if (ret != 0)
493 : 0 : dev_err(arizona->dev, "Failed to isolate DCVDD: %d\n", ret);
494 : :
495 : 0 : return ret;
496 : : }
497 : :
498 : 0 : static int arizona_connect_dcvdd(struct arizona *arizona)
499 : : {
500 : : int ret;
501 : :
502 : 0 : ret = regmap_update_bits(arizona->regmap,
503 : : ARIZONA_ISOLATION_CONTROL,
504 : : ARIZONA_ISOLATE_DCVDD1, 0);
505 [ # # ]: 0 : if (ret != 0)
506 : 0 : dev_err(arizona->dev, "Failed to connect DCVDD: %d\n", ret);
507 : :
508 : 0 : return ret;
509 : : }
510 : :
511 : 0 : static int arizona_is_jack_det_active(struct arizona *arizona)
512 : : {
513 : : unsigned int val;
514 : : int ret;
515 : :
516 : 0 : ret = regmap_read(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, &val);
517 [ # # ]: 0 : if (ret) {
518 : 0 : dev_err(arizona->dev,
519 : : "Failed to check jack det status: %d\n", ret);
520 : 0 : return ret;
521 [ # # ]: 0 : } else if (val & ARIZONA_JD1_ENA) {
522 : : return 1;
523 : : } else {
524 : 0 : return 0;
525 : : }
526 : : }
527 : :
528 : 0 : static int arizona_runtime_resume(struct device *dev)
529 : : {
530 : : struct arizona *arizona = dev_get_drvdata(dev);
531 : : int ret;
532 : :
533 : : dev_dbg(arizona->dev, "Leaving AoD mode\n");
534 : :
535 [ # # ]: 0 : if (arizona->has_fully_powered_off) {
536 : : dev_dbg(arizona->dev, "Re-enabling core supplies\n");
537 : :
538 : 0 : ret = regulator_bulk_enable(arizona->num_core_supplies,
539 : 0 : arizona->core_supplies);
540 [ # # ]: 0 : if (ret) {
541 : 0 : dev_err(dev, "Failed to enable core supplies: %d\n",
542 : : ret);
543 : 0 : return ret;
544 : : }
545 : : }
546 : :
547 : 0 : ret = regulator_enable(arizona->dcvdd);
548 [ # # ]: 0 : if (ret != 0) {
549 : 0 : dev_err(arizona->dev, "Failed to enable DCVDD: %d\n", ret);
550 [ # # ]: 0 : if (arizona->has_fully_powered_off)
551 : 0 : regulator_bulk_disable(arizona->num_core_supplies,
552 : 0 : arizona->core_supplies);
553 : 0 : return ret;
554 : : }
555 : :
556 [ # # ]: 0 : if (arizona->has_fully_powered_off) {
557 : 0 : arizona_disable_reset(arizona);
558 : 0 : enable_irq(arizona->irq);
559 : 0 : arizona->has_fully_powered_off = false;
560 : : }
561 : :
562 : 0 : regcache_cache_only(arizona->regmap, false);
563 : :
564 [ # # # # ]: 0 : switch (arizona->type) {
565 : : case WM5102:
566 [ # # ]: 0 : if (arizona->external_dcvdd) {
567 : 0 : ret = arizona_connect_dcvdd(arizona);
568 [ # # ]: 0 : if (ret != 0)
569 : : goto err;
570 : : }
571 : :
572 : 0 : ret = wm5102_patch(arizona);
573 [ # # ]: 0 : if (ret != 0) {
574 : 0 : dev_err(arizona->dev, "Failed to apply patch: %d\n",
575 : : ret);
576 : 0 : goto err;
577 : : }
578 : :
579 : 0 : ret = wm5102_apply_hardware_patch(arizona);
580 [ # # ]: 0 : if (ret) {
581 : 0 : dev_err(arizona->dev,
582 : : "Failed to apply hardware patch: %d\n",
583 : : ret);
584 : 0 : goto err;
585 : : }
586 : : break;
587 : : case WM5110:
588 : : case WM8280:
589 : 0 : ret = arizona_wait_for_boot(arizona);
590 [ # # ]: 0 : if (ret)
591 : : goto err;
592 : :
593 [ # # ]: 0 : if (arizona->external_dcvdd) {
594 : 0 : ret = arizona_connect_dcvdd(arizona);
595 [ # # ]: 0 : if (ret != 0)
596 : : goto err;
597 : : } else {
598 : : /*
599 : : * As this is only called for the internal regulator
600 : : * (where we know voltage ranges available) it is ok
601 : : * to request an exact range.
602 : : */
603 : 0 : ret = regulator_set_voltage(arizona->dcvdd,
604 : : 1200000, 1200000);
605 [ # # ]: 0 : if (ret < 0) {
606 : 0 : dev_err(arizona->dev,
607 : : "Failed to set resume voltage: %d\n",
608 : : ret);
609 : 0 : goto err;
610 : : }
611 : : }
612 : :
613 : 0 : ret = wm5110_apply_sleep_patch(arizona);
614 [ # # ]: 0 : if (ret) {
615 : 0 : dev_err(arizona->dev,
616 : : "Failed to re-apply sleep patch: %d\n",
617 : : ret);
618 : 0 : goto err;
619 : : }
620 : : break;
621 : : case WM1831:
622 : : case CS47L24:
623 : 0 : ret = arizona_wait_for_boot(arizona);
624 [ # # ]: 0 : if (ret != 0)
625 : : goto err;
626 : : break;
627 : : default:
628 : 0 : ret = arizona_wait_for_boot(arizona);
629 [ # # ]: 0 : if (ret != 0)
630 : : goto err;
631 : :
632 [ # # ]: 0 : if (arizona->external_dcvdd) {
633 : 0 : ret = arizona_connect_dcvdd(arizona);
634 [ # # ]: 0 : if (ret != 0)
635 : : goto err;
636 : : }
637 : : break;
638 : : }
639 : :
640 : 0 : ret = regcache_sync(arizona->regmap);
641 [ # # ]: 0 : if (ret != 0) {
642 : 0 : dev_err(arizona->dev, "Failed to restore register cache\n");
643 : 0 : goto err;
644 : : }
645 : :
646 : : return 0;
647 : :
648 : : err:
649 : 0 : regcache_cache_only(arizona->regmap, true);
650 : 0 : regulator_disable(arizona->dcvdd);
651 : 0 : return ret;
652 : : }
653 : :
654 : 0 : static int arizona_runtime_suspend(struct device *dev)
655 : : {
656 : : struct arizona *arizona = dev_get_drvdata(dev);
657 : : int jd_active = 0;
658 : : int ret;
659 : :
660 : : dev_dbg(arizona->dev, "Entering AoD mode\n");
661 : :
662 [ # # # # ]: 0 : switch (arizona->type) {
663 : : case WM5110:
664 : : case WM8280:
665 : 0 : jd_active = arizona_is_jack_det_active(arizona);
666 [ # # ]: 0 : if (jd_active < 0)
667 : : return jd_active;
668 : :
669 [ # # ]: 0 : if (arizona->external_dcvdd) {
670 : 0 : ret = arizona_isolate_dcvdd(arizona);
671 [ # # ]: 0 : if (ret != 0)
672 : : return ret;
673 : : } else {
674 : : /*
675 : : * As this is only called for the internal regulator
676 : : * (where we know voltage ranges available) it is ok
677 : : * to request an exact range.
678 : : */
679 : 0 : ret = regulator_set_voltage(arizona->dcvdd,
680 : : 1175000, 1175000);
681 [ # # ]: 0 : if (ret < 0) {
682 : 0 : dev_err(arizona->dev,
683 : : "Failed to set suspend voltage: %d\n",
684 : : ret);
685 : 0 : return ret;
686 : : }
687 : : }
688 : : break;
689 : : case WM5102:
690 : 0 : jd_active = arizona_is_jack_det_active(arizona);
691 [ # # ]: 0 : if (jd_active < 0)
692 : : return jd_active;
693 : :
694 [ # # ]: 0 : if (arizona->external_dcvdd) {
695 : 0 : ret = arizona_isolate_dcvdd(arizona);
696 [ # # ]: 0 : if (ret != 0)
697 : : return ret;
698 : : }
699 : :
700 [ # # ]: 0 : if (!jd_active) {
701 : 0 : ret = regmap_write(arizona->regmap,
702 : : ARIZONA_WRITE_SEQUENCER_CTRL_3, 0x0);
703 [ # # ]: 0 : if (ret) {
704 : 0 : dev_err(arizona->dev,
705 : : "Failed to clear write sequencer: %d\n",
706 : : ret);
707 : 0 : return ret;
708 : : }
709 : : }
710 : : break;
711 : : case WM1831:
712 : : case CS47L24:
713 : : break;
714 : : default:
715 : 0 : jd_active = arizona_is_jack_det_active(arizona);
716 [ # # ]: 0 : if (jd_active < 0)
717 : : return jd_active;
718 : :
719 [ # # ]: 0 : if (arizona->external_dcvdd) {
720 : 0 : ret = arizona_isolate_dcvdd(arizona);
721 [ # # ]: 0 : if (ret != 0)
722 : : return ret;
723 : : }
724 : : break;
725 : : }
726 : :
727 : 0 : regcache_cache_only(arizona->regmap, true);
728 : 0 : regcache_mark_dirty(arizona->regmap);
729 : 0 : regulator_disable(arizona->dcvdd);
730 : :
731 : : /* Allow us to completely power down if no jack detection */
732 [ # # ]: 0 : if (!jd_active) {
733 : : dev_dbg(arizona->dev, "Fully powering off\n");
734 : :
735 : 0 : arizona->has_fully_powered_off = true;
736 : :
737 : 0 : disable_irq_nosync(arizona->irq);
738 : : arizona_enable_reset(arizona);
739 : 0 : regulator_bulk_disable(arizona->num_core_supplies,
740 : 0 : arizona->core_supplies);
741 : : }
742 : :
743 : : return 0;
744 : : }
745 : : #endif
746 : :
747 : : #ifdef CONFIG_PM_SLEEP
748 : : static int arizona_suspend(struct device *dev)
749 : : {
750 : : struct arizona *arizona = dev_get_drvdata(dev);
751 : :
752 : : dev_dbg(arizona->dev, "Suspend, disabling IRQ\n");
753 : : disable_irq(arizona->irq);
754 : :
755 : : return 0;
756 : : }
757 : :
758 : : static int arizona_suspend_noirq(struct device *dev)
759 : : {
760 : : struct arizona *arizona = dev_get_drvdata(dev);
761 : :
762 : : dev_dbg(arizona->dev, "Late suspend, reenabling IRQ\n");
763 : : enable_irq(arizona->irq);
764 : :
765 : : return 0;
766 : : }
767 : :
768 : : static int arizona_resume_noirq(struct device *dev)
769 : : {
770 : : struct arizona *arizona = dev_get_drvdata(dev);
771 : :
772 : : dev_dbg(arizona->dev, "Early resume, disabling IRQ\n");
773 : : disable_irq(arizona->irq);
774 : :
775 : : return 0;
776 : : }
777 : :
778 : : static int arizona_resume(struct device *dev)
779 : : {
780 : : struct arizona *arizona = dev_get_drvdata(dev);
781 : :
782 : : dev_dbg(arizona->dev, "Resume, reenabling IRQ\n");
783 : : enable_irq(arizona->irq);
784 : :
785 : : return 0;
786 : : }
787 : : #endif
788 : :
789 : : const struct dev_pm_ops arizona_pm_ops = {
790 : : SET_RUNTIME_PM_OPS(arizona_runtime_suspend,
791 : : arizona_runtime_resume,
792 : : NULL)
793 : : SET_SYSTEM_SLEEP_PM_OPS(arizona_suspend, arizona_resume)
794 : : SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(arizona_suspend_noirq,
795 : : arizona_resume_noirq)
796 : : };
797 : : EXPORT_SYMBOL_GPL(arizona_pm_ops);
798 : :
799 : : #ifdef CONFIG_OF
800 : 0 : unsigned long arizona_of_get_type(struct device *dev)
801 : : {
802 : 0 : const struct of_device_id *id = of_match_device(arizona_of_match, dev);
803 : :
804 [ # # ]: 0 : if (id)
805 : 0 : return (unsigned long)id->data;
806 : : else
807 : : return 0;
808 : : }
809 : : EXPORT_SYMBOL_GPL(arizona_of_get_type);
810 : :
811 : 0 : static int arizona_of_get_core_pdata(struct arizona *arizona)
812 : : {
813 : : struct arizona_pdata *pdata = &arizona->pdata;
814 : : int ret, i;
815 : :
816 : : /* Handle old non-standard DT binding */
817 : 0 : pdata->reset = devm_gpiod_get_from_of_node(arizona->dev,
818 : 0 : arizona->dev->of_node,
819 : : "wlf,reset", 0,
820 : : GPIOD_OUT_LOW,
821 : : "arizona /RESET");
822 [ # # ]: 0 : if (IS_ERR(pdata->reset)) {
823 : : ret = PTR_ERR(pdata->reset);
824 : :
825 : : /*
826 : : * Reset missing will be caught when other binding is read
827 : : * but all other errors imply this binding is in use but has
828 : : * encountered a problem so should be handled.
829 : : */
830 [ # # ]: 0 : if (ret == -EPROBE_DEFER)
831 : : return ret;
832 [ # # ]: 0 : else if (ret != -ENOENT && ret != -ENOSYS)
833 : 0 : dev_err(arizona->dev, "Reset GPIO malformed: %d\n",
834 : : ret);
835 : :
836 : 0 : pdata->reset = NULL;
837 : : }
838 : :
839 : 0 : ret = of_property_read_u32_array(arizona->dev->of_node,
840 : : "wlf,gpio-defaults",
841 : 0 : pdata->gpio_defaults,
842 : : ARRAY_SIZE(pdata->gpio_defaults));
843 [ # # ]: 0 : if (ret >= 0) {
844 : : /*
845 : : * All values are literal except out of range values
846 : : * which are chip default, translate into platform
847 : : * data which uses 0 as chip default and out of range
848 : : * as zero.
849 : : */
850 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
851 [ # # ]: 0 : if (pdata->gpio_defaults[i] > 0xffff)
852 : 0 : pdata->gpio_defaults[i] = 0;
853 [ # # ]: 0 : else if (pdata->gpio_defaults[i] == 0)
854 : 0 : pdata->gpio_defaults[i] = 0x10000;
855 : : }
856 : : } else {
857 : 0 : dev_err(arizona->dev, "Failed to parse GPIO defaults: %d\n",
858 : : ret);
859 : : }
860 : :
861 : : return 0;
862 : : }
863 : :
864 : : const struct of_device_id arizona_of_match[] = {
865 : : { .compatible = "wlf,wm5102", .data = (void *)WM5102 },
866 : : { .compatible = "wlf,wm5110", .data = (void *)WM5110 },
867 : : { .compatible = "wlf,wm8280", .data = (void *)WM8280 },
868 : : { .compatible = "wlf,wm8997", .data = (void *)WM8997 },
869 : : { .compatible = "wlf,wm8998", .data = (void *)WM8998 },
870 : : { .compatible = "wlf,wm1814", .data = (void *)WM1814 },
871 : : { .compatible = "wlf,wm1831", .data = (void *)WM1831 },
872 : : { .compatible = "cirrus,cs47l24", .data = (void *)CS47L24 },
873 : : {},
874 : : };
875 : : EXPORT_SYMBOL_GPL(arizona_of_match);
876 : : #else
877 : : static inline int arizona_of_get_core_pdata(struct arizona *arizona)
878 : : {
879 : : return 0;
880 : : }
881 : : #endif
882 : :
883 : : static const struct mfd_cell early_devs[] = {
884 : : { .name = "arizona-ldo1" },
885 : : };
886 : :
887 : : static const char * const wm5102_supplies[] = {
888 : : "MICVDD",
889 : : "DBVDD2",
890 : : "DBVDD3",
891 : : "CPVDD",
892 : : "SPKVDDL",
893 : : "SPKVDDR",
894 : : };
895 : :
896 : : static const struct mfd_cell wm5102_devs[] = {
897 : : { .name = "arizona-micsupp" },
898 : : { .name = "arizona-gpio" },
899 : : {
900 : : .name = "arizona-extcon",
901 : : .parent_supplies = wm5102_supplies,
902 : : .num_parent_supplies = 1, /* We only need MICVDD */
903 : : },
904 : : { .name = "arizona-haptics" },
905 : : { .name = "arizona-pwm" },
906 : : {
907 : : .name = "wm5102-codec",
908 : : .parent_supplies = wm5102_supplies,
909 : : .num_parent_supplies = ARRAY_SIZE(wm5102_supplies),
910 : : },
911 : : };
912 : :
913 : : static const struct mfd_cell wm5110_devs[] = {
914 : : { .name = "arizona-micsupp" },
915 : : { .name = "arizona-gpio" },
916 : : {
917 : : .name = "arizona-extcon",
918 : : .parent_supplies = wm5102_supplies,
919 : : .num_parent_supplies = 1, /* We only need MICVDD */
920 : : },
921 : : { .name = "arizona-haptics" },
922 : : { .name = "arizona-pwm" },
923 : : {
924 : : .name = "wm5110-codec",
925 : : .parent_supplies = wm5102_supplies,
926 : : .num_parent_supplies = ARRAY_SIZE(wm5102_supplies),
927 : : },
928 : : };
929 : :
930 : : static const char * const cs47l24_supplies[] = {
931 : : "MICVDD",
932 : : "CPVDD",
933 : : "SPKVDD",
934 : : };
935 : :
936 : : static const struct mfd_cell cs47l24_devs[] = {
937 : : { .name = "arizona-gpio" },
938 : : { .name = "arizona-haptics" },
939 : : { .name = "arizona-pwm" },
940 : : {
941 : : .name = "cs47l24-codec",
942 : : .parent_supplies = cs47l24_supplies,
943 : : .num_parent_supplies = ARRAY_SIZE(cs47l24_supplies),
944 : : },
945 : : };
946 : :
947 : : static const char * const wm8997_supplies[] = {
948 : : "MICVDD",
949 : : "DBVDD2",
950 : : "CPVDD",
951 : : "SPKVDD",
952 : : };
953 : :
954 : : static const struct mfd_cell wm8997_devs[] = {
955 : : { .name = "arizona-micsupp" },
956 : : { .name = "arizona-gpio" },
957 : : {
958 : : .name = "arizona-extcon",
959 : : .parent_supplies = wm8997_supplies,
960 : : .num_parent_supplies = 1, /* We only need MICVDD */
961 : : },
962 : : { .name = "arizona-haptics" },
963 : : { .name = "arizona-pwm" },
964 : : {
965 : : .name = "wm8997-codec",
966 : : .parent_supplies = wm8997_supplies,
967 : : .num_parent_supplies = ARRAY_SIZE(wm8997_supplies),
968 : : },
969 : : };
970 : :
971 : : static const struct mfd_cell wm8998_devs[] = {
972 : : { .name = "arizona-micsupp" },
973 : : { .name = "arizona-gpio" },
974 : : {
975 : : .name = "arizona-extcon",
976 : : .parent_supplies = wm5102_supplies,
977 : : .num_parent_supplies = 1, /* We only need MICVDD */
978 : : },
979 : : { .name = "arizona-haptics" },
980 : : { .name = "arizona-pwm" },
981 : : {
982 : : .name = "wm8998-codec",
983 : : .parent_supplies = wm5102_supplies,
984 : : .num_parent_supplies = ARRAY_SIZE(wm5102_supplies),
985 : : },
986 : : };
987 : :
988 : 0 : int arizona_dev_init(struct arizona *arizona)
989 : : {
990 : : static const char * const mclk_name[] = { "mclk1", "mclk2" };
991 : 0 : struct device *dev = arizona->dev;
992 : : const char *type_name = NULL;
993 : : unsigned int reg, val;
994 : : int (*apply_patch)(struct arizona *) = NULL;
995 : : const struct mfd_cell *subdevs = NULL;
996 : : int n_subdevs = 0, ret, i;
997 : :
998 : : dev_set_drvdata(arizona->dev, arizona);
999 : 0 : mutex_init(&arizona->clk_lock);
1000 : :
1001 [ # # ]: 0 : if (dev_get_platdata(arizona->dev)) {
1002 : 0 : memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
1003 : : sizeof(arizona->pdata));
1004 : : } else {
1005 : 0 : ret = arizona_of_get_core_pdata(arizona);
1006 [ # # ]: 0 : if (ret < 0)
1007 : : return ret;
1008 : : }
1009 : :
1010 : : BUILD_BUG_ON(ARRAY_SIZE(arizona->mclk) != ARRAY_SIZE(mclk_name));
1011 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(arizona->mclk); i++) {
1012 : 0 : arizona->mclk[i] = devm_clk_get(arizona->dev, mclk_name[i]);
1013 [ # # ]: 0 : if (IS_ERR(arizona->mclk[i])) {
1014 : 0 : dev_info(arizona->dev, "Failed to get %s: %ld\n",
1015 : : mclk_name[i], PTR_ERR(arizona->mclk[i]));
1016 : 0 : arizona->mclk[i] = NULL;
1017 : : }
1018 : : }
1019 : :
1020 : 0 : regcache_cache_only(arizona->regmap, true);
1021 : :
1022 [ # # ]: 0 : switch (arizona->type) {
1023 : : case WM5102:
1024 : : case WM5110:
1025 : : case WM8280:
1026 : : case WM8997:
1027 : : case WM8998:
1028 : : case WM1814:
1029 : : case WM1831:
1030 : : case CS47L24:
1031 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++)
1032 : : arizona->core_supplies[i].supply
1033 : 0 : = wm5102_core_supplies[i];
1034 : 0 : arizona->num_core_supplies = ARRAY_SIZE(wm5102_core_supplies);
1035 : : break;
1036 : : default:
1037 : 0 : dev_err(arizona->dev, "Unknown device type %d\n",
1038 : : arizona->type);
1039 : 0 : return -ENODEV;
1040 : : }
1041 : :
1042 : : /* Mark DCVDD as external, LDO1 driver will clear if internal */
1043 : 0 : arizona->external_dcvdd = true;
1044 : :
1045 [ # # ]: 0 : switch (arizona->type) {
1046 : : case WM1831:
1047 : : case CS47L24:
1048 : : break; /* No LDO1 regulator */
1049 : : default:
1050 : 0 : ret = mfd_add_devices(arizona->dev, -1, early_devs,
1051 : : ARRAY_SIZE(early_devs), NULL, 0, NULL);
1052 [ # # ]: 0 : if (ret != 0) {
1053 : 0 : dev_err(dev, "Failed to add early children: %d\n", ret);
1054 : 0 : return ret;
1055 : : }
1056 : : break;
1057 : : }
1058 : :
1059 : 0 : ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies,
1060 : 0 : arizona->core_supplies);
1061 [ # # ]: 0 : if (ret != 0) {
1062 : 0 : dev_err(dev, "Failed to request core supplies: %d\n",
1063 : : ret);
1064 : 0 : goto err_early;
1065 : : }
1066 : :
1067 : : /**
1068 : : * Don't use devres here because the only device we have to get
1069 : : * against is the MFD device and DCVDD will likely be supplied by
1070 : : * one of its children. Meaning that the regulator will be
1071 : : * destroyed by the time devres calls regulator put.
1072 : : */
1073 : 0 : arizona->dcvdd = regulator_get(arizona->dev, "DCVDD");
1074 [ # # ]: 0 : if (IS_ERR(arizona->dcvdd)) {
1075 : : ret = PTR_ERR(arizona->dcvdd);
1076 : 0 : dev_err(dev, "Failed to request DCVDD: %d\n", ret);
1077 : 0 : goto err_early;
1078 : : }
1079 : :
1080 [ # # ]: 0 : if (!arizona->pdata.reset) {
1081 : : /* Start out with /RESET low to put the chip into reset */
1082 : 0 : arizona->pdata.reset = devm_gpiod_get(arizona->dev, "reset",
1083 : : GPIOD_OUT_LOW);
1084 [ # # ]: 0 : if (IS_ERR(arizona->pdata.reset)) {
1085 : : ret = PTR_ERR(arizona->pdata.reset);
1086 [ # # ]: 0 : if (ret == -EPROBE_DEFER)
1087 : : goto err_dcvdd;
1088 : :
1089 : 0 : dev_err(arizona->dev,
1090 : : "Reset GPIO missing/malformed: %d\n", ret);
1091 : :
1092 : 0 : arizona->pdata.reset = NULL;
1093 : : }
1094 : : }
1095 : :
1096 : 0 : ret = regulator_bulk_enable(arizona->num_core_supplies,
1097 : : arizona->core_supplies);
1098 [ # # ]: 0 : if (ret != 0) {
1099 : 0 : dev_err(dev, "Failed to enable core supplies: %d\n",
1100 : : ret);
1101 : 0 : goto err_dcvdd;
1102 : : }
1103 : :
1104 : 0 : ret = regulator_enable(arizona->dcvdd);
1105 [ # # ]: 0 : if (ret != 0) {
1106 : 0 : dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
1107 : 0 : goto err_enable;
1108 : : }
1109 : :
1110 : 0 : arizona_disable_reset(arizona);
1111 : :
1112 : 0 : regcache_cache_only(arizona->regmap, false);
1113 : :
1114 : : /* Verify that this is a chip we know about */
1115 : 0 : ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, ®);
1116 [ # # ]: 0 : if (ret != 0) {
1117 : 0 : dev_err(dev, "Failed to read ID register: %d\n", ret);
1118 : 0 : goto err_reset;
1119 : : }
1120 : :
1121 [ # # ]: 0 : switch (reg) {
1122 : : case 0x5102:
1123 : : case 0x5110:
1124 : : case 0x6349:
1125 : : case 0x6363:
1126 : : case 0x8997:
1127 : : break;
1128 : : default:
1129 : 0 : dev_err(arizona->dev, "Unknown device ID: %x\n", reg);
1130 : : ret = -ENODEV;
1131 : 0 : goto err_reset;
1132 : : }
1133 : :
1134 : : /* If we have a /RESET GPIO we'll already be reset */
1135 [ # # ]: 0 : if (!arizona->pdata.reset) {
1136 : 0 : ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0);
1137 [ # # ]: 0 : if (ret != 0) {
1138 : 0 : dev_err(dev, "Failed to reset device: %d\n", ret);
1139 : 0 : goto err_reset;
1140 : : }
1141 : :
1142 : 0 : usleep_range(1000, 5000);
1143 : : }
1144 : :
1145 : : /* Ensure device startup is complete */
1146 [ # # ]: 0 : switch (arizona->type) {
1147 : : case WM5102:
1148 : 0 : ret = regmap_read(arizona->regmap,
1149 : : ARIZONA_WRITE_SEQUENCER_CTRL_3, &val);
1150 [ # # ]: 0 : if (ret) {
1151 : 0 : dev_err(dev,
1152 : : "Failed to check write sequencer state: %d\n",
1153 : : ret);
1154 [ # # ]: 0 : } else if (val & 0x01) {
1155 : 0 : ret = wm5102_clear_write_sequencer(arizona);
1156 [ # # ]: 0 : if (ret)
1157 : : return ret;
1158 : : }
1159 : : break;
1160 : : default:
1161 : : break;
1162 : : }
1163 : :
1164 : 0 : ret = arizona_wait_for_boot(arizona);
1165 [ # # ]: 0 : if (ret) {
1166 : 0 : dev_err(arizona->dev, "Device failed initial boot: %d\n", ret);
1167 : 0 : goto err_reset;
1168 : : }
1169 : :
1170 : : /* Read the device ID information & do device specific stuff */
1171 : 0 : ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, ®);
1172 [ # # ]: 0 : if (ret != 0) {
1173 : 0 : dev_err(dev, "Failed to read ID register: %d\n", ret);
1174 : 0 : goto err_reset;
1175 : : }
1176 : :
1177 : 0 : ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
1178 : : &arizona->rev);
1179 [ # # ]: 0 : if (ret != 0) {
1180 : 0 : dev_err(dev, "Failed to read revision register: %d\n", ret);
1181 : 0 : goto err_reset;
1182 : : }
1183 : 0 : arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
1184 : :
1185 [ # # # ]: 0 : switch (reg) {
1186 : : case 0x5102:
1187 : : if (IS_ENABLED(CONFIG_MFD_WM5102)) {
1188 : : type_name = "WM5102";
1189 [ # # ]: 0 : if (arizona->type != WM5102) {
1190 : 0 : dev_warn(arizona->dev,
1191 : : "WM5102 registered as %d\n",
1192 : : arizona->type);
1193 : 0 : arizona->type = WM5102;
1194 : : }
1195 : :
1196 : : apply_patch = wm5102_patch;
1197 : 0 : arizona->rev &= 0x7;
1198 : : subdevs = wm5102_devs;
1199 : : n_subdevs = ARRAY_SIZE(wm5102_devs);
1200 : : }
1201 : 0 : break;
1202 : : case 0x5110:
1203 : : if (IS_ENABLED(CONFIG_MFD_WM5110)) {
1204 : : switch (arizona->type) {
1205 : : case WM5110:
1206 : : type_name = "WM5110";
1207 : : break;
1208 : : case WM8280:
1209 : : type_name = "WM8280";
1210 : : break;
1211 : : default:
1212 : : type_name = "WM5110";
1213 : : dev_warn(arizona->dev,
1214 : : "WM5110 registered as %d\n",
1215 : : arizona->type);
1216 : : arizona->type = WM5110;
1217 : : break;
1218 : : }
1219 : :
1220 : : apply_patch = wm5110_patch;
1221 : : subdevs = wm5110_devs;
1222 : : n_subdevs = ARRAY_SIZE(wm5110_devs);
1223 : : }
1224 : : break;
1225 : : case 0x6363:
1226 : : if (IS_ENABLED(CONFIG_MFD_CS47L24)) {
1227 : : switch (arizona->type) {
1228 : : case CS47L24:
1229 : : type_name = "CS47L24";
1230 : : break;
1231 : :
1232 : : case WM1831:
1233 : : type_name = "WM1831";
1234 : : break;
1235 : :
1236 : : default:
1237 : : dev_warn(arizona->dev,
1238 : : "CS47L24 registered as %d\n",
1239 : : arizona->type);
1240 : : arizona->type = CS47L24;
1241 : : break;
1242 : : }
1243 : :
1244 : : apply_patch = cs47l24_patch;
1245 : : subdevs = cs47l24_devs;
1246 : : n_subdevs = ARRAY_SIZE(cs47l24_devs);
1247 : : }
1248 : : break;
1249 : : case 0x8997:
1250 : : if (IS_ENABLED(CONFIG_MFD_WM8997)) {
1251 : : type_name = "WM8997";
1252 : : if (arizona->type != WM8997) {
1253 : : dev_warn(arizona->dev,
1254 : : "WM8997 registered as %d\n",
1255 : : arizona->type);
1256 : : arizona->type = WM8997;
1257 : : }
1258 : :
1259 : : apply_patch = wm8997_patch;
1260 : : subdevs = wm8997_devs;
1261 : : n_subdevs = ARRAY_SIZE(wm8997_devs);
1262 : : }
1263 : : break;
1264 : : case 0x6349:
1265 : : if (IS_ENABLED(CONFIG_MFD_WM8998)) {
1266 : : switch (arizona->type) {
1267 : : case WM8998:
1268 : : type_name = "WM8998";
1269 : : break;
1270 : :
1271 : : case WM1814:
1272 : : type_name = "WM1814";
1273 : : break;
1274 : :
1275 : : default:
1276 : : type_name = "WM8998";
1277 : : dev_warn(arizona->dev,
1278 : : "WM8998 registered as %d\n",
1279 : : arizona->type);
1280 : : arizona->type = WM8998;
1281 : : }
1282 : :
1283 : : apply_patch = wm8998_patch;
1284 : : subdevs = wm8998_devs;
1285 : : n_subdevs = ARRAY_SIZE(wm8998_devs);
1286 : : }
1287 : : break;
1288 : : default:
1289 : 0 : dev_err(arizona->dev, "Unknown device ID %x\n", reg);
1290 : : ret = -ENODEV;
1291 : 0 : goto err_reset;
1292 : : }
1293 : :
1294 [ # # ]: 0 : if (!subdevs) {
1295 : 0 : dev_err(arizona->dev,
1296 : : "No kernel support for device ID %x\n", reg);
1297 : : ret = -ENODEV;
1298 : 0 : goto err_reset;
1299 : : }
1300 : :
1301 : 0 : dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
1302 : :
1303 [ # # ]: 0 : if (apply_patch) {
1304 : 0 : ret = apply_patch(arizona);
1305 [ # # ]: 0 : if (ret != 0) {
1306 : 0 : dev_err(arizona->dev, "Failed to apply patch: %d\n",
1307 : : ret);
1308 : 0 : goto err_reset;
1309 : : }
1310 : :
1311 [ # # # ]: 0 : switch (arizona->type) {
1312 : : case WM5102:
1313 : 0 : ret = wm5102_apply_hardware_patch(arizona);
1314 [ # # ]: 0 : if (ret) {
1315 : 0 : dev_err(arizona->dev,
1316 : : "Failed to apply hardware patch: %d\n",
1317 : : ret);
1318 : 0 : goto err_reset;
1319 : : }
1320 : : break;
1321 : : case WM5110:
1322 : : case WM8280:
1323 : 0 : ret = wm5110_apply_sleep_patch(arizona);
1324 [ # # ]: 0 : if (ret) {
1325 : 0 : dev_err(arizona->dev,
1326 : : "Failed to apply sleep patch: %d\n",
1327 : : ret);
1328 : 0 : goto err_reset;
1329 : : }
1330 : : break;
1331 : : default:
1332 : : break;
1333 : : }
1334 : : }
1335 : :
1336 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
1337 [ # # ]: 0 : if (!arizona->pdata.gpio_defaults[i])
1338 : 0 : continue;
1339 : :
1340 : 0 : regmap_write(arizona->regmap, ARIZONA_GPIO1_CTRL + i,
1341 : : arizona->pdata.gpio_defaults[i]);
1342 : : }
1343 : :
1344 : : /* Chip default */
1345 [ # # ]: 0 : if (!arizona->pdata.clk32k_src)
1346 : 0 : arizona->pdata.clk32k_src = ARIZONA_32KZ_MCLK2;
1347 : :
1348 [ # # # ]: 0 : switch (arizona->pdata.clk32k_src) {
1349 : : case ARIZONA_32KZ_MCLK1:
1350 : : case ARIZONA_32KZ_MCLK2:
1351 : 0 : regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
1352 : : ARIZONA_CLK_32K_SRC_MASK,
1353 : : arizona->pdata.clk32k_src - 1);
1354 : 0 : arizona_clk32k_enable(arizona);
1355 : 0 : break;
1356 : : case ARIZONA_32KZ_NONE:
1357 : 0 : regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
1358 : : ARIZONA_CLK_32K_SRC_MASK, 2);
1359 : 0 : break;
1360 : : default:
1361 : 0 : dev_err(arizona->dev, "Invalid 32kHz clock source: %d\n",
1362 : : arizona->pdata.clk32k_src);
1363 : : ret = -EINVAL;
1364 : 0 : goto err_reset;
1365 : : }
1366 : :
1367 [ # # ]: 0 : for (i = 0; i < ARIZONA_MAX_MICBIAS; i++) {
1368 [ # # # # ]: 0 : if (!arizona->pdata.micbias[i].mV &&
1369 : 0 : !arizona->pdata.micbias[i].bypass)
1370 : 0 : continue;
1371 : :
1372 : : /* Apply default for bypass mode */
1373 [ # # ]: 0 : if (!arizona->pdata.micbias[i].mV)
1374 : 0 : arizona->pdata.micbias[i].mV = 2800;
1375 : :
1376 : 0 : val = (arizona->pdata.micbias[i].mV - 1500) / 100;
1377 : :
1378 : 0 : val <<= ARIZONA_MICB1_LVL_SHIFT;
1379 : :
1380 [ # # ]: 0 : if (arizona->pdata.micbias[i].ext_cap)
1381 : 0 : val |= ARIZONA_MICB1_EXT_CAP;
1382 : :
1383 [ # # ]: 0 : if (arizona->pdata.micbias[i].discharge)
1384 : 0 : val |= ARIZONA_MICB1_DISCH;
1385 : :
1386 [ # # ]: 0 : if (arizona->pdata.micbias[i].soft_start)
1387 : 0 : val |= ARIZONA_MICB1_RATE;
1388 : :
1389 [ # # ]: 0 : if (arizona->pdata.micbias[i].bypass)
1390 : 0 : val |= ARIZONA_MICB1_BYPASS;
1391 : :
1392 : 0 : regmap_update_bits(arizona->regmap,
1393 : : ARIZONA_MIC_BIAS_CTRL_1 + i,
1394 : : ARIZONA_MICB1_LVL_MASK |
1395 : : ARIZONA_MICB1_EXT_CAP |
1396 : : ARIZONA_MICB1_DISCH |
1397 : : ARIZONA_MICB1_BYPASS |
1398 : : ARIZONA_MICB1_RATE, val);
1399 : : }
1400 : :
1401 : 0 : pm_runtime_set_active(arizona->dev);
1402 : 0 : pm_runtime_enable(arizona->dev);
1403 : :
1404 : : /* Set up for interrupts */
1405 : 0 : ret = arizona_irq_init(arizona);
1406 [ # # ]: 0 : if (ret != 0)
1407 : : goto err_pm;
1408 : :
1409 : 0 : pm_runtime_set_autosuspend_delay(arizona->dev, 100);
1410 : 0 : pm_runtime_use_autosuspend(arizona->dev);
1411 : :
1412 : 0 : arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error",
1413 : : arizona_clkgen_err, arizona);
1414 : 0 : arizona_request_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, "Overclocked",
1415 : : arizona_overclocked, arizona);
1416 : 0 : arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked",
1417 : : arizona_underclocked, arizona);
1418 : :
1419 : 0 : ret = mfd_add_devices(arizona->dev, PLATFORM_DEVID_NONE,
1420 : : subdevs, n_subdevs, NULL, 0, NULL);
1421 : :
1422 [ # # ]: 0 : if (ret) {
1423 : 0 : dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret);
1424 : : goto err_irq;
1425 : : }
1426 : :
1427 : : return 0;
1428 : :
1429 : : err_irq:
1430 : 0 : arizona_irq_exit(arizona);
1431 : : err_pm:
1432 : 0 : pm_runtime_disable(arizona->dev);
1433 : :
1434 [ # # ]: 0 : switch (arizona->pdata.clk32k_src) {
1435 : : case ARIZONA_32KZ_MCLK1:
1436 : : case ARIZONA_32KZ_MCLK2:
1437 : 0 : arizona_clk32k_disable(arizona);
1438 : 0 : break;
1439 : : default:
1440 : : break;
1441 : : }
1442 : : err_reset:
1443 : : arizona_enable_reset(arizona);
1444 : 0 : regulator_disable(arizona->dcvdd);
1445 : : err_enable:
1446 : 0 : regulator_bulk_disable(arizona->num_core_supplies,
1447 : : arizona->core_supplies);
1448 : : err_dcvdd:
1449 : 0 : regulator_put(arizona->dcvdd);
1450 : : err_early:
1451 : 0 : mfd_remove_devices(dev);
1452 : 0 : return ret;
1453 : : }
1454 : : EXPORT_SYMBOL_GPL(arizona_dev_init);
1455 : :
1456 : 0 : int arizona_dev_exit(struct arizona *arizona)
1457 : : {
1458 : 0 : disable_irq(arizona->irq);
1459 : 0 : pm_runtime_disable(arizona->dev);
1460 : :
1461 : 0 : regulator_disable(arizona->dcvdd);
1462 : 0 : regulator_put(arizona->dcvdd);
1463 : :
1464 [ # # ]: 0 : switch (arizona->pdata.clk32k_src) {
1465 : : case ARIZONA_32KZ_MCLK1:
1466 : : case ARIZONA_32KZ_MCLK2:
1467 : 0 : arizona_clk32k_disable(arizona);
1468 : 0 : break;
1469 : : default:
1470 : : break;
1471 : : }
1472 : :
1473 : 0 : mfd_remove_devices(arizona->dev);
1474 : 0 : arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona);
1475 : 0 : arizona_free_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, arizona);
1476 : 0 : arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona);
1477 : 0 : arizona_irq_exit(arizona);
1478 : : arizona_enable_reset(arizona);
1479 : :
1480 : 0 : regulator_bulk_disable(arizona->num_core_supplies,
1481 : 0 : arizona->core_supplies);
1482 : 0 : return 0;
1483 : : }
1484 : : EXPORT_SYMBOL_GPL(arizona_dev_exit);
|