blob: bebf58a06a6b2932d57798c0b5b81a31a12e9b7a [file] [log] [blame]
Mark Brown3cc72982012-06-19 16:31:53 +01001/*
2 * Arizona core driver
3 *
4 * Copyright 2012 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/delay.h>
Mark Brown59db9692012-07-09 00:31:36 +020014#include <linux/err.h>
Mark Brown3cc72982012-06-19 16:31:53 +010015#include <linux/gpio.h>
16#include <linux/interrupt.h>
17#include <linux/mfd/core.h>
18#include <linux/module.h>
Mark Brownd7810092013-03-25 00:11:27 +000019#include <linux/of.h>
20#include <linux/of_device.h>
21#include <linux/of_gpio.h>
Mark Brown3cc72982012-06-19 16:31:53 +010022#include <linux/pm_runtime.h>
23#include <linux/regmap.h>
24#include <linux/regulator/consumer.h>
Mark Brown59274672013-04-23 19:44:16 +010025#include <linux/regulator/machine.h>
Mark Brown3cc72982012-06-19 16:31:53 +010026#include <linux/slab.h>
27
28#include <linux/mfd/arizona/core.h>
29#include <linux/mfd/arizona/registers.h>
30
31#include "arizona.h"
32
33static const char *wm5102_core_supplies[] = {
34 "AVDD",
35 "DBVDD1",
Mark Brown3cc72982012-06-19 16:31:53 +010036};
37
38int arizona_clk32k_enable(struct arizona *arizona)
39{
40 int ret = 0;
41
42 mutex_lock(&arizona->clk_lock);
43
44 arizona->clk32k_ref++;
45
Mark Brown247fa192013-03-19 14:47:47 +010046 if (arizona->clk32k_ref == 1) {
47 switch (arizona->pdata.clk32k_src) {
48 case ARIZONA_32KZ_MCLK1:
49 ret = pm_runtime_get_sync(arizona->dev);
50 if (ret != 0)
51 goto out;
52 break;
53 }
54
Mark Brown3cc72982012-06-19 16:31:53 +010055 ret = regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
56 ARIZONA_CLK_32K_ENA,
57 ARIZONA_CLK_32K_ENA);
Mark Brown247fa192013-03-19 14:47:47 +010058 }
Mark Brown3cc72982012-06-19 16:31:53 +010059
Mark Brown247fa192013-03-19 14:47:47 +010060out:
Mark Brown3cc72982012-06-19 16:31:53 +010061 if (ret != 0)
62 arizona->clk32k_ref--;
63
64 mutex_unlock(&arizona->clk_lock);
65
66 return ret;
67}
68EXPORT_SYMBOL_GPL(arizona_clk32k_enable);
69
70int arizona_clk32k_disable(struct arizona *arizona)
71{
72 int ret = 0;
73
74 mutex_lock(&arizona->clk_lock);
75
76 BUG_ON(arizona->clk32k_ref <= 0);
77
78 arizona->clk32k_ref--;
79
Mark Brown247fa192013-03-19 14:47:47 +010080 if (arizona->clk32k_ref == 0) {
Mark Brown3cc72982012-06-19 16:31:53 +010081 regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
82 ARIZONA_CLK_32K_ENA, 0);
83
Mark Brown247fa192013-03-19 14:47:47 +010084 switch (arizona->pdata.clk32k_src) {
85 case ARIZONA_32KZ_MCLK1:
86 pm_runtime_put_sync(arizona->dev);
87 break;
88 }
89 }
90
Mark Brown3cc72982012-06-19 16:31:53 +010091 mutex_unlock(&arizona->clk_lock);
92
93 return ret;
94}
95EXPORT_SYMBOL_GPL(arizona_clk32k_disable);
96
97static irqreturn_t arizona_clkgen_err(int irq, void *data)
98{
99 struct arizona *arizona = data;
100
101 dev_err(arizona->dev, "CLKGEN error\n");
102
103 return IRQ_HANDLED;
104}
105
106static irqreturn_t arizona_underclocked(int irq, void *data)
107{
108 struct arizona *arizona = data;
109 unsigned int val;
110 int ret;
111
112 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_8,
113 &val);
114 if (ret != 0) {
115 dev_err(arizona->dev, "Failed to read underclock status: %d\n",
116 ret);
117 return IRQ_NONE;
118 }
119
120 if (val & ARIZONA_AIF3_UNDERCLOCKED_STS)
121 dev_err(arizona->dev, "AIF3 underclocked\n");
Mark Brown3cc72982012-06-19 16:31:53 +0100122 if (val & ARIZONA_AIF2_UNDERCLOCKED_STS)
Charles Keepax3ebef342012-11-20 13:46:20 +0900123 dev_err(arizona->dev, "AIF2 underclocked\n");
124 if (val & ARIZONA_AIF1_UNDERCLOCKED_STS)
Mark Brown3cc72982012-06-19 16:31:53 +0100125 dev_err(arizona->dev, "AIF1 underclocked\n");
Charles Keepax6e440d22014-07-15 11:21:49 +0100126 if (val & ARIZONA_ISRC3_UNDERCLOCKED_STS)
127 dev_err(arizona->dev, "ISRC3 underclocked\n");
Mark Brown3cc72982012-06-19 16:31:53 +0100128 if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS)
129 dev_err(arizona->dev, "ISRC2 underclocked\n");
130 if (val & ARIZONA_ISRC1_UNDERCLOCKED_STS)
131 dev_err(arizona->dev, "ISRC1 underclocked\n");
132 if (val & ARIZONA_FX_UNDERCLOCKED_STS)
133 dev_err(arizona->dev, "FX underclocked\n");
134 if (val & ARIZONA_ASRC_UNDERCLOCKED_STS)
135 dev_err(arizona->dev, "ASRC underclocked\n");
136 if (val & ARIZONA_DAC_UNDERCLOCKED_STS)
137 dev_err(arizona->dev, "DAC underclocked\n");
138 if (val & ARIZONA_ADC_UNDERCLOCKED_STS)
139 dev_err(arizona->dev, "ADC underclocked\n");
140 if (val & ARIZONA_MIXER_UNDERCLOCKED_STS)
Mark Brown648a9882013-01-28 00:32:53 +0800141 dev_err(arizona->dev, "Mixer dropped sample\n");
Mark Brown3cc72982012-06-19 16:31:53 +0100142
143 return IRQ_HANDLED;
144}
145
146static irqreturn_t arizona_overclocked(int irq, void *data)
147{
148 struct arizona *arizona = data;
149 unsigned int val[2];
150 int ret;
151
152 ret = regmap_bulk_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_6,
153 &val[0], 2);
154 if (ret != 0) {
155 dev_err(arizona->dev, "Failed to read overclock status: %d\n",
156 ret);
157 return IRQ_NONE;
158 }
159
160 if (val[0] & ARIZONA_PWM_OVERCLOCKED_STS)
161 dev_err(arizona->dev, "PWM overclocked\n");
162 if (val[0] & ARIZONA_FX_CORE_OVERCLOCKED_STS)
163 dev_err(arizona->dev, "FX core overclocked\n");
164 if (val[0] & ARIZONA_DAC_SYS_OVERCLOCKED_STS)
165 dev_err(arizona->dev, "DAC SYS overclocked\n");
166 if (val[0] & ARIZONA_DAC_WARP_OVERCLOCKED_STS)
167 dev_err(arizona->dev, "DAC WARP overclocked\n");
168 if (val[0] & ARIZONA_ADC_OVERCLOCKED_STS)
169 dev_err(arizona->dev, "ADC overclocked\n");
170 if (val[0] & ARIZONA_MIXER_OVERCLOCKED_STS)
171 dev_err(arizona->dev, "Mixer overclocked\n");
172 if (val[0] & ARIZONA_AIF3_SYNC_OVERCLOCKED_STS)
173 dev_err(arizona->dev, "AIF3 overclocked\n");
174 if (val[0] & ARIZONA_AIF2_SYNC_OVERCLOCKED_STS)
175 dev_err(arizona->dev, "AIF2 overclocked\n");
176 if (val[0] & ARIZONA_AIF1_SYNC_OVERCLOCKED_STS)
177 dev_err(arizona->dev, "AIF1 overclocked\n");
178 if (val[0] & ARIZONA_PAD_CTRL_OVERCLOCKED_STS)
179 dev_err(arizona->dev, "Pad control overclocked\n");
180
181 if (val[1] & ARIZONA_SLIMBUS_SUBSYS_OVERCLOCKED_STS)
182 dev_err(arizona->dev, "Slimbus subsystem overclocked\n");
183 if (val[1] & ARIZONA_SLIMBUS_ASYNC_OVERCLOCKED_STS)
184 dev_err(arizona->dev, "Slimbus async overclocked\n");
185 if (val[1] & ARIZONA_SLIMBUS_SYNC_OVERCLOCKED_STS)
186 dev_err(arizona->dev, "Slimbus sync overclocked\n");
187 if (val[1] & ARIZONA_ASRC_ASYNC_SYS_OVERCLOCKED_STS)
188 dev_err(arizona->dev, "ASRC async system overclocked\n");
189 if (val[1] & ARIZONA_ASRC_ASYNC_WARP_OVERCLOCKED_STS)
190 dev_err(arizona->dev, "ASRC async WARP overclocked\n");
191 if (val[1] & ARIZONA_ASRC_SYNC_SYS_OVERCLOCKED_STS)
192 dev_err(arizona->dev, "ASRC sync system overclocked\n");
193 if (val[1] & ARIZONA_ASRC_SYNC_WARP_OVERCLOCKED_STS)
194 dev_err(arizona->dev, "ASRC sync WARP overclocked\n");
195 if (val[1] & ARIZONA_ADSP2_1_OVERCLOCKED_STS)
196 dev_err(arizona->dev, "DSP1 overclocked\n");
Charles Keepax6e440d22014-07-15 11:21:49 +0100197 if (val[1] & ARIZONA_ISRC3_OVERCLOCKED_STS)
198 dev_err(arizona->dev, "ISRC3 overclocked\n");
Mark Brown3cc72982012-06-19 16:31:53 +0100199 if (val[1] & ARIZONA_ISRC2_OVERCLOCKED_STS)
200 dev_err(arizona->dev, "ISRC2 overclocked\n");
201 if (val[1] & ARIZONA_ISRC1_OVERCLOCKED_STS)
202 dev_err(arizona->dev, "ISRC1 overclocked\n");
203
204 return IRQ_HANDLED;
205}
206
Charles Keepax9d53dfd2013-03-26 17:38:45 +0000207static int arizona_poll_reg(struct arizona *arizona,
208 int timeout, unsigned int reg,
209 unsigned int mask, unsigned int target)
210{
211 unsigned int val = 0;
212 int ret, i;
213
214 for (i = 0; i < timeout; i++) {
215 ret = regmap_read(arizona->regmap, reg, &val);
216 if (ret != 0) {
217 dev_err(arizona->dev, "Failed to read reg %u: %d\n",
218 reg, ret);
219 continue;
220 }
221
222 if ((val & mask) == target)
223 return 0;
224
225 msleep(1);
226 }
227
228 dev_err(arizona->dev, "Polling reg %u timed out: %x\n", reg, val);
229 return -ETIMEDOUT;
230}
231
Mark Brown3cc72982012-06-19 16:31:53 +0100232static int arizona_wait_for_boot(struct arizona *arizona)
233{
Charles Keepax9d53dfd2013-03-26 17:38:45 +0000234 int ret;
Mark Brown3cc72982012-06-19 16:31:53 +0100235
236 /*
237 * We can't use an interrupt as we need to runtime resume to do so,
238 * we won't race with the interrupt handler as it'll be blocked on
239 * runtime resume.
240 */
Charles Keepax9d53dfd2013-03-26 17:38:45 +0000241 ret = arizona_poll_reg(arizona, 5, ARIZONA_INTERRUPT_RAW_STATUS_5,
242 ARIZONA_BOOT_DONE_STS, ARIZONA_BOOT_DONE_STS);
Mark Brown3cc72982012-06-19 16:31:53 +0100243
Charles Keepax9d53dfd2013-03-26 17:38:45 +0000244 if (!ret)
Mark Brown3cc72982012-06-19 16:31:53 +0100245 regmap_write(arizona->regmap, ARIZONA_INTERRUPT_STATUS_5,
246 ARIZONA_BOOT_DONE_STS);
Mark Brown3cc72982012-06-19 16:31:53 +0100247
248 pm_runtime_mark_last_busy(arizona->dev);
249
Charles Keepax9d53dfd2013-03-26 17:38:45 +0000250 return ret;
Mark Brown3cc72982012-06-19 16:31:53 +0100251}
252
Charles Keepax22298752015-05-11 13:58:02 +0100253static inline void arizona_enable_reset(struct arizona *arizona)
254{
255 if (arizona->pdata.reset)
256 gpio_set_value_cansleep(arizona->pdata.reset, 0);
257}
258
259static void arizona_disable_reset(struct arizona *arizona)
260{
261 if (arizona->pdata.reset) {
Charles Keepax121c0752015-05-11 13:58:10 +0100262 switch (arizona->type) {
263 case WM5110:
264 case WM8280:
265 /* Meet requirements for minimum reset duration */
266 msleep(5);
267 break;
268 default:
269 break;
270 }
271
Charles Keepax22298752015-05-11 13:58:02 +0100272 gpio_set_value_cansleep(arizona->pdata.reset, 1);
273 msleep(1);
274 }
275}
276
Charles Keepax3850e3e2015-05-11 13:58:05 +0100277struct arizona_sysclk_state {
278 unsigned int fll;
279 unsigned int sysclk;
280};
281
282static int arizona_enable_freerun_sysclk(struct arizona *arizona,
283 struct arizona_sysclk_state *state)
Charles Keepaxe80436b2013-03-26 18:46:15 +0000284{
Charles Keepaxe80436b2013-03-26 18:46:15 +0000285 int ret, err;
286
Charles Keepaxe80436b2013-03-26 18:46:15 +0000287 /* Cache existing FLL and SYSCLK settings */
Charles Keepax3850e3e2015-05-11 13:58:05 +0100288 ret = regmap_read(arizona->regmap, ARIZONA_FLL1_CONTROL_1, &state->fll);
Charles Keepax0be068a2015-05-11 13:58:04 +0100289 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000290 dev_err(arizona->dev, "Failed to cache FLL settings: %d\n",
291 ret);
292 return ret;
293 }
Charles Keepax3850e3e2015-05-11 13:58:05 +0100294 ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1,
295 &state->sysclk);
Charles Keepax0be068a2015-05-11 13:58:04 +0100296 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000297 dev_err(arizona->dev, "Failed to cache SYSCLK settings: %d\n",
298 ret);
299 return ret;
300 }
301
302 /* Start up SYSCLK using the FLL in free running mode */
303 ret = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1,
304 ARIZONA_FLL1_ENA | ARIZONA_FLL1_FREERUN);
Charles Keepax0be068a2015-05-11 13:58:04 +0100305 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000306 dev_err(arizona->dev,
307 "Failed to start FLL in freerunning mode: %d\n",
308 ret);
309 return ret;
310 }
311 ret = arizona_poll_reg(arizona, 25, ARIZONA_INTERRUPT_RAW_STATUS_5,
312 ARIZONA_FLL1_CLOCK_OK_STS,
313 ARIZONA_FLL1_CLOCK_OK_STS);
Charles Keepax0be068a2015-05-11 13:58:04 +0100314 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000315 ret = -ETIMEDOUT;
316 goto err_fll;
317 }
318
319 ret = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, 0x0144);
Charles Keepax0be068a2015-05-11 13:58:04 +0100320 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000321 dev_err(arizona->dev, "Failed to start SYSCLK: %d\n", ret);
322 goto err_fll;
323 }
324
Charles Keepax3850e3e2015-05-11 13:58:05 +0100325 return 0;
326
327err_fll:
328 err = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, state->fll);
329 if (err)
330 dev_err(arizona->dev,
331 "Failed to re-apply old FLL settings: %d\n", err);
332
333 return ret;
334}
335
336static int arizona_disable_freerun_sysclk(struct arizona *arizona,
337 struct arizona_sysclk_state *state)
338{
339 int ret;
340
341 ret = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1,
342 state->sysclk);
343 if (ret) {
344 dev_err(arizona->dev,
345 "Failed to re-apply old SYSCLK settings: %d\n", ret);
346 return ret;
347 }
348
349 ret = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, state->fll);
350 if (ret) {
351 dev_err(arizona->dev,
352 "Failed to re-apply old FLL settings: %d\n", ret);
353 return ret;
354 }
355
356 return 0;
357}
358
359static int wm5102_apply_hardware_patch(struct arizona *arizona)
360{
361 struct arizona_sysclk_state state;
362 int err, ret;
363
364 ret = arizona_enable_freerun_sysclk(arizona, &state);
365 if (ret)
366 return ret;
367
Charles Keepaxe80436b2013-03-26 18:46:15 +0000368 /* Start the write sequencer and wait for it to finish */
369 ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0,
Charles Keepax0be068a2015-05-11 13:58:04 +0100370 ARIZONA_WSEQ_ENA | ARIZONA_WSEQ_START | 160);
371 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000372 dev_err(arizona->dev, "Failed to start write sequencer: %d\n",
373 ret);
Charles Keepax3850e3e2015-05-11 13:58:05 +0100374 goto err;
Charles Keepaxe80436b2013-03-26 18:46:15 +0000375 }
Charles Keepax3850e3e2015-05-11 13:58:05 +0100376
Charles Keepaxe80436b2013-03-26 18:46:15 +0000377 ret = arizona_poll_reg(arizona, 5, ARIZONA_WRITE_SEQUENCER_CTRL_1,
378 ARIZONA_WSEQ_BUSY, 0);
Charles Keepax0be068a2015-05-11 13:58:04 +0100379 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000380 regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0,
Charles Keepax0be068a2015-05-11 13:58:04 +0100381 ARIZONA_WSEQ_ABORT);
Charles Keepaxe80436b2013-03-26 18:46:15 +0000382 ret = -ETIMEDOUT;
383 }
384
Charles Keepax3850e3e2015-05-11 13:58:05 +0100385err:
386 err = arizona_disable_freerun_sysclk(arizona, &state);
Charles Keepaxe80436b2013-03-26 18:46:15 +0000387
Charles Keepax0be068a2015-05-11 13:58:04 +0100388 return ret ?: err;
Charles Keepaxe80436b2013-03-26 18:46:15 +0000389}
390
Charles Keepax882bc462015-05-11 13:58:06 +0100391/*
392 * Register patch to some of the CODECs internal write sequences
393 * to ensure a clean exit from the low power sleep state.
394 */
395static const struct reg_default wm5110_sleep_patch[] = {
396 { 0x337A, 0xC100 },
397 { 0x337B, 0x0041 },
398 { 0x3300, 0xA210 },
399 { 0x3301, 0x050C },
400};
401
402static int wm5110_apply_sleep_patch(struct arizona *arizona)
403{
404 struct arizona_sysclk_state state;
405 int err, ret;
406
407 ret = arizona_enable_freerun_sysclk(arizona, &state);
408 if (ret)
409 return ret;
410
411 ret = regmap_multi_reg_write_bypassed(arizona->regmap,
412 wm5110_sleep_patch,
413 ARRAY_SIZE(wm5110_sleep_patch));
414
415 err = arizona_disable_freerun_sysclk(arizona, &state);
416
417 return ret ?: err;
418}
419
Charles Keepax1c1c6bb2015-05-11 13:58:03 +0100420static int wm5102_clear_write_sequencer(struct arizona *arizona)
421{
422 int ret;
423
424 ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_3,
425 0x0);
426 if (ret) {
427 dev_err(arizona->dev,
428 "Failed to clear write sequencer state: %d\n", ret);
429 return ret;
430 }
431
432 arizona_enable_reset(arizona);
433 regulator_disable(arizona->dcvdd);
434
435 msleep(20);
436
437 ret = regulator_enable(arizona->dcvdd);
438 if (ret) {
439 dev_err(arizona->dev, "Failed to re-enable DCVDD: %d\n", ret);
440 return ret;
441 }
442 arizona_disable_reset(arizona);
443
444 return 0;
445}
446
Rafael J. Wysocki48bb9fe2014-12-05 03:04:12 +0100447#ifdef CONFIG_PM
Mark Brown3cc72982012-06-19 16:31:53 +0100448static int arizona_runtime_resume(struct device *dev)
449{
450 struct arizona *arizona = dev_get_drvdata(dev);
451 int ret;
452
Mark Brown508c8292012-07-20 17:09:12 +0100453 dev_dbg(arizona->dev, "Leaving AoD mode\n");
454
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100455 if (arizona->has_fully_powered_off) {
456 dev_dbg(arizona->dev, "Re-enabling core supplies\n");
457
458 ret = regulator_bulk_enable(arizona->num_core_supplies,
459 arizona->core_supplies);
460 if (ret) {
461 dev_err(dev, "Failed to enable core supplies: %d\n",
462 ret);
463 return ret;
464 }
465 }
466
Mark Brown59db9692012-07-09 00:31:36 +0200467 ret = regulator_enable(arizona->dcvdd);
468 if (ret != 0) {
469 dev_err(arizona->dev, "Failed to enable DCVDD: %d\n", ret);
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100470 if (arizona->has_fully_powered_off)
471 regulator_bulk_disable(arizona->num_core_supplies,
472 arizona->core_supplies);
Mark Brown59db9692012-07-09 00:31:36 +0200473 return ret;
474 }
Mark Brown3cc72982012-06-19 16:31:53 +0100475
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100476 if (arizona->has_fully_powered_off) {
477 arizona_disable_reset(arizona);
478 enable_irq(arizona->irq);
479 arizona->has_fully_powered_off = false;
480 }
481
Mark Brown3cc72982012-06-19 16:31:53 +0100482 regcache_cache_only(arizona->regmap, false);
483
Charles Keepax4c9bb8b2013-03-26 18:01:49 +0000484 switch (arizona->type) {
485 case WM5102:
Mark Brown59274672013-04-23 19:44:16 +0100486 if (arizona->external_dcvdd) {
487 ret = regmap_update_bits(arizona->regmap,
488 ARIZONA_ISOLATION_CONTROL,
489 ARIZONA_ISOLATE_DCVDD1, 0);
490 if (ret != 0) {
491 dev_err(arizona->dev,
492 "Failed to connect DCVDD: %d\n", ret);
493 goto err;
494 }
495 }
496
Charles Keepax4c9bb8b2013-03-26 18:01:49 +0000497 ret = wm5102_patch(arizona);
498 if (ret != 0) {
499 dev_err(arizona->dev, "Failed to apply patch: %d\n",
500 ret);
501 goto err;
502 }
Charles Keepaxe80436b2013-03-26 18:46:15 +0000503
Charles Keepax0be068a2015-05-11 13:58:04 +0100504 ret = wm5102_apply_hardware_patch(arizona);
505 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000506 dev_err(arizona->dev,
507 "Failed to apply hardware patch: %d\n",
508 ret);
509 goto err;
510 }
511 break;
Charles Keepax96129a02015-05-11 13:58:08 +0100512 case WM5110:
513 case WM8280:
514 ret = arizona_wait_for_boot(arizona);
515 if (ret)
516 goto err;
517
518 if (arizona->external_dcvdd) {
519 ret = regmap_update_bits(arizona->regmap,
520 ARIZONA_ISOLATION_CONTROL,
521 ARIZONA_ISOLATE_DCVDD1, 0);
522 if (ret) {
523 dev_err(arizona->dev,
524 "Failed to connect DCVDD: %d\n", ret);
525 goto err;
526 }
527 } else {
528 /*
529 * As this is only called for the internal regulator
530 * (where we know voltage ranges available) it is ok
531 * to request an exact range.
532 */
533 ret = regulator_set_voltage(arizona->dcvdd,
534 1200000, 1200000);
535 if (ret < 0) {
536 dev_err(arizona->dev,
537 "Failed to set resume voltage: %d\n",
538 ret);
539 goto err;
540 }
541 }
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100542
543 ret = wm5110_apply_sleep_patch(arizona);
544 if (ret) {
545 dev_err(arizona->dev,
546 "Failed to re-apply sleep patch: %d\n",
547 ret);
548 goto err;
549 }
Charles Keepax96129a02015-05-11 13:58:08 +0100550 break;
Charles Keepaxe80436b2013-03-26 18:46:15 +0000551 default:
Charles Keepax12bb68e2013-03-27 09:49:40 +0000552 ret = arizona_wait_for_boot(arizona);
553 if (ret != 0) {
554 goto err;
555 }
556
Mark Brown59274672013-04-23 19:44:16 +0100557 if (arizona->external_dcvdd) {
558 ret = regmap_update_bits(arizona->regmap,
559 ARIZONA_ISOLATION_CONTROL,
560 ARIZONA_ISOLATE_DCVDD1, 0);
561 if (ret != 0) {
562 dev_err(arizona->dev,
563 "Failed to connect DCVDD: %d\n", ret);
564 goto err;
565 }
566 }
Charles Keepaxe80436b2013-03-26 18:46:15 +0000567 break;
Charles Keepax4c9bb8b2013-03-26 18:01:49 +0000568 }
569
Mark Brown9270bdf2013-01-04 17:16:12 +0000570 ret = regcache_sync(arizona->regmap);
571 if (ret != 0) {
572 dev_err(arizona->dev, "Failed to restore register cache\n");
Mark Brown4816bd12013-01-14 15:50:38 +0900573 goto err;
Mark Brown9270bdf2013-01-04 17:16:12 +0000574 }
Mark Brown3cc72982012-06-19 16:31:53 +0100575
576 return 0;
Mark Brown4816bd12013-01-14 15:50:38 +0900577
578err:
579 regcache_cache_only(arizona->regmap, true);
580 regulator_disable(arizona->dcvdd);
581 return ret;
Mark Brown3cc72982012-06-19 16:31:53 +0100582}
583
584static int arizona_runtime_suspend(struct device *dev)
585{
586 struct arizona *arizona = dev_get_drvdata(dev);
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100587 unsigned int val;
Mark Brown59274672013-04-23 19:44:16 +0100588 int ret;
Mark Brown3cc72982012-06-19 16:31:53 +0100589
Mark Brown508c8292012-07-20 17:09:12 +0100590 dev_dbg(arizona->dev, "Entering AoD mode\n");
591
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100592 ret = regmap_read(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, &val);
593 if (ret) {
594 dev_err(dev, "Failed to check jack det status: %d\n", ret);
595 return ret;
596 }
597
Mark Brown59274672013-04-23 19:44:16 +0100598 if (arizona->external_dcvdd) {
599 ret = regmap_update_bits(arizona->regmap,
600 ARIZONA_ISOLATION_CONTROL,
601 ARIZONA_ISOLATE_DCVDD1,
602 ARIZONA_ISOLATE_DCVDD1);
603 if (ret != 0) {
604 dev_err(arizona->dev, "Failed to isolate DCVDD: %d\n",
605 ret);
606 return ret;
607 }
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100608 }
609
610 switch (arizona->type) {
611 case WM5110:
612 case WM8280:
613 if (arizona->external_dcvdd)
614 break;
615
616 /*
617 * As this is only called for the internal regulator
618 * (where we know voltage ranges available) it is ok
619 * to request an exact range.
620 */
621 ret = regulator_set_voltage(arizona->dcvdd, 1175000, 1175000);
622 if (ret < 0) {
623 dev_err(arizona->dev,
624 "Failed to set suspend voltage: %d\n", ret);
625 return ret;
626 }
627 break;
628 case WM5102:
629 if (!(val & ARIZONA_JD1_ENA)) {
630 ret = regmap_write(arizona->regmap,
631 ARIZONA_WRITE_SEQUENCER_CTRL_3, 0x0);
632 if (ret) {
Charles Keepax96129a02015-05-11 13:58:08 +0100633 dev_err(arizona->dev,
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100634 "Failed to clear write sequencer: %d\n",
Charles Keepax96129a02015-05-11 13:58:08 +0100635 ret);
636 return ret;
637 }
Charles Keepax96129a02015-05-11 13:58:08 +0100638 }
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100639 break;
640 default:
641 break;
Mark Brown59274672013-04-23 19:44:16 +0100642 }
643
Mark Brown59db9692012-07-09 00:31:36 +0200644 regcache_cache_only(arizona->regmap, true);
645 regcache_mark_dirty(arizona->regmap);
Charles Keepaxe293e84722013-08-06 17:18:35 +0100646 regulator_disable(arizona->dcvdd);
Mark Brown3cc72982012-06-19 16:31:53 +0100647
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100648 /* Allow us to completely power down if no jack detection */
649 if (!(val & ARIZONA_JD1_ENA)) {
650 dev_dbg(arizona->dev, "Fully powering off\n");
651
652 arizona->has_fully_powered_off = true;
653
654 disable_irq(arizona->irq);
655 arizona_enable_reset(arizona);
656 regulator_bulk_disable(arizona->num_core_supplies,
657 arizona->core_supplies);
658 }
659
Mark Brown3cc72982012-06-19 16:31:53 +0100660 return 0;
661}
662#endif
663
Mark Browndc781d02013-01-27 12:07:32 +0800664#ifdef CONFIG_PM_SLEEP
Mark Brown67c99292013-04-10 12:40:26 +0100665static int arizona_suspend(struct device *dev)
666{
667 struct arizona *arizona = dev_get_drvdata(dev);
668
669 dev_dbg(arizona->dev, "Suspend, disabling IRQ\n");
670 disable_irq(arizona->irq);
671
672 return 0;
673}
674
675static int arizona_suspend_late(struct device *dev)
676{
677 struct arizona *arizona = dev_get_drvdata(dev);
678
679 dev_dbg(arizona->dev, "Late suspend, reenabling IRQ\n");
680 enable_irq(arizona->irq);
681
682 return 0;
683}
684
Mark Browndc781d02013-01-27 12:07:32 +0800685static int arizona_resume_noirq(struct device *dev)
686{
687 struct arizona *arizona = dev_get_drvdata(dev);
688
689 dev_dbg(arizona->dev, "Early resume, disabling IRQ\n");
690 disable_irq(arizona->irq);
691
692 return 0;
693}
694
695static int arizona_resume(struct device *dev)
696{
697 struct arizona *arizona = dev_get_drvdata(dev);
698
699 dev_dbg(arizona->dev, "Late resume, reenabling IRQ\n");
700 enable_irq(arizona->irq);
701
702 return 0;
703}
704#endif
705
Mark Brown3cc72982012-06-19 16:31:53 +0100706const struct dev_pm_ops arizona_pm_ops = {
707 SET_RUNTIME_PM_OPS(arizona_runtime_suspend,
708 arizona_runtime_resume,
709 NULL)
Mark Brown67c99292013-04-10 12:40:26 +0100710 SET_SYSTEM_SLEEP_PM_OPS(arizona_suspend, arizona_resume)
Mark Browndc781d02013-01-27 12:07:32 +0800711#ifdef CONFIG_PM_SLEEP
Mark Brown67c99292013-04-10 12:40:26 +0100712 .suspend_late = arizona_suspend_late,
Mark Browndc781d02013-01-27 12:07:32 +0800713 .resume_noirq = arizona_resume_noirq,
714#endif
Mark Brown3cc72982012-06-19 16:31:53 +0100715};
716EXPORT_SYMBOL_GPL(arizona_pm_ops);
717
Mark Brownd7810092013-03-25 00:11:27 +0000718#ifdef CONFIG_OF
Lee Jones942786e2014-07-02 14:28:46 +0100719unsigned long arizona_of_get_type(struct device *dev)
Mark Brownd7810092013-03-25 00:11:27 +0000720{
721 const struct of_device_id *id = of_match_device(arizona_of_match, dev);
722
723 if (id)
Lee Jones942786e2014-07-02 14:28:46 +0100724 return (unsigned long)id->data;
Mark Brownd7810092013-03-25 00:11:27 +0000725 else
726 return 0;
727}
728EXPORT_SYMBOL_GPL(arizona_of_get_type);
729
Charles Keepaxe4fcb1d2014-04-16 10:01:37 +0100730int arizona_of_get_named_gpio(struct arizona *arizona, const char *prop,
731 bool mandatory)
732{
733 int gpio;
734
735 gpio = of_get_named_gpio(arizona->dev->of_node, prop, 0);
736 if (gpio < 0) {
737 if (mandatory)
738 dev_err(arizona->dev,
739 "Mandatory DT gpio %s missing/malformed: %d\n",
740 prop, gpio);
741
742 gpio = 0;
743 }
744
745 return gpio;
746}
747EXPORT_SYMBOL_GPL(arizona_of_get_named_gpio);
748
Mark Brownd7810092013-03-25 00:11:27 +0000749static int arizona_of_get_core_pdata(struct arizona *arizona)
750{
Charles Keepaxe4fcb1d2014-04-16 10:01:37 +0100751 struct arizona_pdata *pdata = &arizona->pdata;
Inha Songcc47aed2014-08-30 11:27:18 +0900752 struct property *prop;
753 const __be32 *cur;
754 u32 val;
Mark Brownd7810092013-03-25 00:11:27 +0000755 int ret, i;
Inha Songcc47aed2014-08-30 11:27:18 +0900756 int count = 0;
Mark Brownd7810092013-03-25 00:11:27 +0000757
Charles Keepaxe4fcb1d2014-04-16 10:01:37 +0100758 pdata->reset = arizona_of_get_named_gpio(arizona, "wlf,reset", true);
Mark Brownd7810092013-03-25 00:11:27 +0000759
760 ret = of_property_read_u32_array(arizona->dev->of_node,
761 "wlf,gpio-defaults",
762 arizona->pdata.gpio_defaults,
763 ARRAY_SIZE(arizona->pdata.gpio_defaults));
764 if (ret >= 0) {
765 /*
766 * All values are literal except out of range values
767 * which are chip default, translate into platform
768 * data which uses 0 as chip default and out of range
769 * as zero.
770 */
771 for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
772 if (arizona->pdata.gpio_defaults[i] > 0xffff)
773 arizona->pdata.gpio_defaults[i] = 0;
Charles Keepax91c73932013-10-03 16:16:01 +0100774 else if (arizona->pdata.gpio_defaults[i] == 0)
Mark Brownd7810092013-03-25 00:11:27 +0000775 arizona->pdata.gpio_defaults[i] = 0x10000;
776 }
777 } else {
778 dev_err(arizona->dev, "Failed to parse GPIO defaults: %d\n",
779 ret);
780 }
781
Inha Songcc47aed2014-08-30 11:27:18 +0900782 of_property_for_each_u32(arizona->dev->of_node, "wlf,inmode", prop,
783 cur, val) {
784 if (count == ARRAY_SIZE(arizona->pdata.inmode))
785 break;
786
787 arizona->pdata.inmode[count] = val;
788 count++;
789 }
790
Charles Keepaxe7ad27c2015-03-03 15:04:53 +0000791 count = 0;
792 of_property_for_each_u32(arizona->dev->of_node, "wlf,dmic-ref", prop,
793 cur, val) {
794 if (count == ARRAY_SIZE(arizona->pdata.dmic_ref))
795 break;
796
797 arizona->pdata.dmic_ref[count] = val;
798 count++;
799 }
800
Mark Brownd7810092013-03-25 00:11:27 +0000801 return 0;
802}
803
804const struct of_device_id arizona_of_match[] = {
805 { .compatible = "wlf,wm5102", .data = (void *)WM5102 },
806 { .compatible = "wlf,wm5110", .data = (void *)WM5110 },
Richard Fitzgeralde5d4ef02015-01-17 15:21:22 +0000807 { .compatible = "wlf,wm8280", .data = (void *)WM8280 },
Charles Keepaxdc7d4862013-06-13 09:43:29 +0100808 { .compatible = "wlf,wm8997", .data = (void *)WM8997 },
Mark Brownd7810092013-03-25 00:11:27 +0000809 {},
810};
811EXPORT_SYMBOL_GPL(arizona_of_match);
812#else
813static inline int arizona_of_get_core_pdata(struct arizona *arizona)
814{
815 return 0;
816}
817#endif
818
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100819static const struct mfd_cell early_devs[] = {
Mark Brown3cc72982012-06-19 16:31:53 +0100820 { .name = "arizona-ldo1" },
821};
822
Charles Keepax32dadef2013-10-15 20:14:22 +0100823static const char *wm5102_supplies[] = {
Charles Keepax5fc6c392014-07-25 16:24:44 +0100824 "MICVDD",
Charles Keepax32dadef2013-10-15 20:14:22 +0100825 "DBVDD2",
826 "DBVDD3",
827 "CPVDD",
828 "SPKVDDL",
829 "SPKVDDR",
830};
831
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100832static const struct mfd_cell wm5102_devs[] = {
Mark Brownd77681112012-12-20 15:38:03 +0000833 { .name = "arizona-micsupp" },
Charles Keepax5fc6c392014-07-25 16:24:44 +0100834 {
835 .name = "arizona-extcon",
836 .parent_supplies = wm5102_supplies,
837 .num_parent_supplies = 1, /* We only need MICVDD */
838 },
Mark Brown3cc72982012-06-19 16:31:53 +0100839 { .name = "arizona-gpio" },
Mark Brown503b1ca2012-11-27 17:36:38 +0000840 { .name = "arizona-haptics" },
Mark Brown3cc72982012-06-19 16:31:53 +0100841 { .name = "arizona-pwm" },
Charles Keepax32dadef2013-10-15 20:14:22 +0100842 {
843 .name = "wm5102-codec",
844 .parent_supplies = wm5102_supplies,
845 .num_parent_supplies = ARRAY_SIZE(wm5102_supplies),
846 },
Mark Brown3cc72982012-06-19 16:31:53 +0100847};
848
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100849static const struct mfd_cell wm5110_devs[] = {
Mark Brownd77681112012-12-20 15:38:03 +0000850 { .name = "arizona-micsupp" },
Charles Keepax5fc6c392014-07-25 16:24:44 +0100851 {
852 .name = "arizona-extcon",
853 .parent_supplies = wm5102_supplies,
854 .num_parent_supplies = 1, /* We only need MICVDD */
855 },
Mark Browne102bef2012-07-10 12:37:58 +0100856 { .name = "arizona-gpio" },
Mark Brown503b1ca2012-11-27 17:36:38 +0000857 { .name = "arizona-haptics" },
Mark Browne102bef2012-07-10 12:37:58 +0100858 { .name = "arizona-pwm" },
Charles Keepax32dadef2013-10-15 20:14:22 +0100859 {
860 .name = "wm5110-codec",
861 .parent_supplies = wm5102_supplies,
862 .num_parent_supplies = ARRAY_SIZE(wm5102_supplies),
863 },
864};
865
866static const char *wm8997_supplies[] = {
Charles Keepax996c2d42014-07-25 16:24:43 +0100867 "MICVDD",
Charles Keepax32dadef2013-10-15 20:14:22 +0100868 "DBVDD2",
869 "CPVDD",
870 "SPKVDD",
Mark Browne102bef2012-07-10 12:37:58 +0100871};
872
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100873static const struct mfd_cell wm8997_devs[] = {
Charles Keepaxdc7d4862013-06-13 09:43:29 +0100874 { .name = "arizona-micsupp" },
Charles Keepax5fc6c392014-07-25 16:24:44 +0100875 {
876 .name = "arizona-extcon",
877 .parent_supplies = wm8997_supplies,
878 .num_parent_supplies = 1, /* We only need MICVDD */
879 },
Charles Keepaxdc7d4862013-06-13 09:43:29 +0100880 { .name = "arizona-gpio" },
881 { .name = "arizona-haptics" },
882 { .name = "arizona-pwm" },
Charles Keepax32dadef2013-10-15 20:14:22 +0100883 {
884 .name = "wm8997-codec",
885 .parent_supplies = wm8997_supplies,
886 .num_parent_supplies = ARRAY_SIZE(wm8997_supplies),
887 },
Charles Keepaxdc7d4862013-06-13 09:43:29 +0100888};
889
Bill Pembertonf791be42012-11-19 13:23:04 -0500890int arizona_dev_init(struct arizona *arizona)
Mark Brown3cc72982012-06-19 16:31:53 +0100891{
892 struct device *dev = arizona->dev;
893 const char *type_name;
894 unsigned int reg, val;
Mark Brown62d62b52012-12-02 11:41:46 +0900895 int (*apply_patch)(struct arizona *) = NULL;
Mark Brown3cc72982012-06-19 16:31:53 +0100896 int ret, i;
897
898 dev_set_drvdata(arizona->dev, arizona);
899 mutex_init(&arizona->clk_lock);
900
901 if (dev_get_platdata(arizona->dev))
902 memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
903 sizeof(arizona->pdata));
Lee Jones22d7dc82013-09-27 14:25:55 +0100904 else
905 arizona_of_get_core_pdata(arizona);
Mark Brown3cc72982012-06-19 16:31:53 +0100906
907 regcache_cache_only(arizona->regmap, true);
908
909 switch (arizona->type) {
910 case WM5102:
Mark Browne102bef2012-07-10 12:37:58 +0100911 case WM5110:
Richard Fitzgeralde5d4ef02015-01-17 15:21:22 +0000912 case WM8280:
Charles Keepaxdc7d4862013-06-13 09:43:29 +0100913 case WM8997:
Mark Brown3cc72982012-06-19 16:31:53 +0100914 for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++)
915 arizona->core_supplies[i].supply
916 = wm5102_core_supplies[i];
917 arizona->num_core_supplies = ARRAY_SIZE(wm5102_core_supplies);
918 break;
919 default:
920 dev_err(arizona->dev, "Unknown device type %d\n",
921 arizona->type);
922 return -EINVAL;
923 }
924
Charles Keepax4a8c4752014-04-16 10:01:38 +0100925 /* Mark DCVDD as external, LDO1 driver will clear if internal */
926 arizona->external_dcvdd = true;
927
Mark Brown3cc72982012-06-19 16:31:53 +0100928 ret = mfd_add_devices(arizona->dev, -1, early_devs,
Mark Brown0848c942012-09-11 15:16:36 +0800929 ARRAY_SIZE(early_devs), NULL, 0, NULL);
Mark Brown3cc72982012-06-19 16:31:53 +0100930 if (ret != 0) {
931 dev_err(dev, "Failed to add early children: %d\n", ret);
932 return ret;
933 }
934
935 ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies,
936 arizona->core_supplies);
937 if (ret != 0) {
938 dev_err(dev, "Failed to request core supplies: %d\n",
939 ret);
940 goto err_early;
941 }
942
Charles Keepax0c2d0ff2014-06-19 16:04:23 +0100943 /**
944 * Don't use devres here because the only device we have to get
945 * against is the MFD device and DCVDD will likely be supplied by
946 * one of its children. Meaning that the regulator will be
947 * destroyed by the time devres calls regulator put.
948 */
Charles Keepaxe6021512014-06-02 09:50:41 +0100949 arizona->dcvdd = regulator_get(arizona->dev, "DCVDD");
Mark Brown59db9692012-07-09 00:31:36 +0200950 if (IS_ERR(arizona->dcvdd)) {
951 ret = PTR_ERR(arizona->dcvdd);
952 dev_err(dev, "Failed to request DCVDD: %d\n", ret);
953 goto err_early;
954 }
955
Mark Brown87d3af42013-03-26 12:15:26 +0000956 if (arizona->pdata.reset) {
957 /* Start out with /RESET low to put the chip into reset */
Charles Keepax5f056bf2015-05-11 13:58:01 +0100958 ret = devm_gpio_request_one(arizona->dev, arizona->pdata.reset,
959 GPIOF_DIR_OUT | GPIOF_INIT_LOW,
960 "arizona /RESET");
Mark Brown87d3af42013-03-26 12:15:26 +0000961 if (ret != 0) {
962 dev_err(dev, "Failed to request /RESET: %d\n", ret);
Charles Keepaxe6021512014-06-02 09:50:41 +0100963 goto err_dcvdd;
Mark Brown87d3af42013-03-26 12:15:26 +0000964 }
965 }
966
Mark Brown3cc72982012-06-19 16:31:53 +0100967 ret = regulator_bulk_enable(arizona->num_core_supplies,
968 arizona->core_supplies);
969 if (ret != 0) {
970 dev_err(dev, "Failed to enable core supplies: %d\n",
971 ret);
Charles Keepaxe6021512014-06-02 09:50:41 +0100972 goto err_dcvdd;
Mark Brown3cc72982012-06-19 16:31:53 +0100973 }
974
Mark Brown59db9692012-07-09 00:31:36 +0200975 ret = regulator_enable(arizona->dcvdd);
976 if (ret != 0) {
977 dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
978 goto err_enable;
979 }
980
Charles Keepax22298752015-05-11 13:58:02 +0100981 arizona_disable_reset(arizona);
Mark Brown3cc72982012-06-19 16:31:53 +0100982
Mark Brown3cc72982012-06-19 16:31:53 +0100983 regcache_cache_only(arizona->regmap, false);
984
Mark Brownca76ceb2013-04-09 16:04:35 +0100985 /* Verify that this is a chip we know about */
986 ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
987 if (ret != 0) {
988 dev_err(dev, "Failed to read ID register: %d\n", ret);
989 goto err_reset;
990 }
991
992 switch (reg) {
993 case 0x5102:
994 case 0x5110:
Charles Keepaxdc7d4862013-06-13 09:43:29 +0100995 case 0x8997:
Mark Brownca76ceb2013-04-09 16:04:35 +0100996 break;
997 default:
998 dev_err(arizona->dev, "Unknown device ID: %x\n", reg);
999 goto err_reset;
1000 }
1001
1002 /* If we have a /RESET GPIO we'll already be reset */
1003 if (!arizona->pdata.reset) {
Mark Brownca76ceb2013-04-09 16:04:35 +01001004 ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0);
1005 if (ret != 0) {
1006 dev_err(dev, "Failed to reset device: %d\n", ret);
1007 goto err_reset;
1008 }
1009
1010 msleep(1);
Mark Brownca76ceb2013-04-09 16:04:35 +01001011 }
1012
1013 /* Ensure device startup is complete */
1014 switch (arizona->type) {
1015 case WM5102:
Mark Brown48018942014-08-13 11:42:46 +01001016 ret = regmap_read(arizona->regmap,
1017 ARIZONA_WRITE_SEQUENCER_CTRL_3, &val);
Charles Keepax1c1c6bb2015-05-11 13:58:03 +01001018 if (ret) {
Mark Brownca76ceb2013-04-09 16:04:35 +01001019 dev_err(dev,
1020 "Failed to check write sequencer state: %d\n",
1021 ret);
Charles Keepax1c1c6bb2015-05-11 13:58:03 +01001022 } else if (val & 0x01) {
1023 ret = wm5102_clear_write_sequencer(arizona);
1024 if (ret)
1025 return ret;
Mark Brownca76ceb2013-04-09 16:04:35 +01001026 }
1027 break;
Charles Keepax1c1c6bb2015-05-11 13:58:03 +01001028 default:
1029 break;
1030 }
1031
1032 ret = arizona_wait_for_boot(arizona);
1033 if (ret) {
1034 dev_err(arizona->dev, "Device failed initial boot: %d\n", ret);
1035 goto err_reset;
Mark Brownca76ceb2013-04-09 16:04:35 +01001036 }
1037
1038 /* Read the device ID information & do device specific stuff */
Mark Brown3cc72982012-06-19 16:31:53 +01001039 ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
1040 if (ret != 0) {
1041 dev_err(dev, "Failed to read ID register: %d\n", ret);
Mark Brown59db9692012-07-09 00:31:36 +02001042 goto err_reset;
Mark Brown3cc72982012-06-19 16:31:53 +01001043 }
1044
1045 ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
1046 &arizona->rev);
1047 if (ret != 0) {
1048 dev_err(dev, "Failed to read revision register: %d\n", ret);
Mark Brown59db9692012-07-09 00:31:36 +02001049 goto err_reset;
Mark Brown3cc72982012-06-19 16:31:53 +01001050 }
1051 arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
1052
1053 switch (reg) {
Mark Brown863df8d2012-07-05 20:35:31 +01001054#ifdef CONFIG_MFD_WM5102
Mark Brown3cc72982012-06-19 16:31:53 +01001055 case 0x5102:
1056 type_name = "WM5102";
1057 if (arizona->type != WM5102) {
1058 dev_err(arizona->dev, "WM5102 registered as %d\n",
1059 arizona->type);
1060 arizona->type = WM5102;
1061 }
Mark Brown62d62b52012-12-02 11:41:46 +09001062 apply_patch = wm5102_patch;
Mark Brownc6d6bfb2013-03-26 11:14:52 +00001063 arizona->rev &= 0x7;
Mark Brown3cc72982012-06-19 16:31:53 +01001064 break;
Mark Brown863df8d2012-07-05 20:35:31 +01001065#endif
Mark Browne102bef2012-07-10 12:37:58 +01001066#ifdef CONFIG_MFD_WM5110
1067 case 0x5110:
Richard Fitzgeralde5d4ef02015-01-17 15:21:22 +00001068 switch (arizona->type) {
1069 case WM5110:
1070 type_name = "WM5110";
1071 break;
1072 case WM8280:
1073 type_name = "WM8280";
1074 break;
1075 default:
1076 type_name = "WM5110";
Mark Browne102bef2012-07-10 12:37:58 +01001077 dev_err(arizona->dev, "WM5110 registered as %d\n",
1078 arizona->type);
1079 arizona->type = WM5110;
Richard Fitzgeralde5d4ef02015-01-17 15:21:22 +00001080 break;
Mark Browne102bef2012-07-10 12:37:58 +01001081 }
Mark Brown62d62b52012-12-02 11:41:46 +09001082 apply_patch = wm5110_patch;
Mark Browne102bef2012-07-10 12:37:58 +01001083 break;
1084#endif
Charles Keepaxdc7d4862013-06-13 09:43:29 +01001085#ifdef CONFIG_MFD_WM8997
1086 case 0x8997:
1087 type_name = "WM8997";
1088 if (arizona->type != WM8997) {
1089 dev_err(arizona->dev, "WM8997 registered as %d\n",
1090 arizona->type);
1091 arizona->type = WM8997;
1092 }
1093 apply_patch = wm8997_patch;
1094 break;
1095#endif
Mark Brown3cc72982012-06-19 16:31:53 +01001096 default:
1097 dev_err(arizona->dev, "Unknown device ID %x\n", reg);
Mark Brown59db9692012-07-09 00:31:36 +02001098 goto err_reset;
Mark Brown3cc72982012-06-19 16:31:53 +01001099 }
1100
1101 dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
1102
Mark Brown62d62b52012-12-02 11:41:46 +09001103 if (apply_patch) {
1104 ret = apply_patch(arizona);
1105 if (ret != 0) {
1106 dev_err(arizona->dev, "Failed to apply patch: %d\n",
1107 ret);
1108 goto err_reset;
1109 }
Charles Keepaxe80436b2013-03-26 18:46:15 +00001110
1111 switch (arizona->type) {
1112 case WM5102:
Charles Keepax0be068a2015-05-11 13:58:04 +01001113 ret = wm5102_apply_hardware_patch(arizona);
1114 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +00001115 dev_err(arizona->dev,
1116 "Failed to apply hardware patch: %d\n",
1117 ret);
1118 goto err_reset;
1119 }
1120 break;
Charles Keepax882bc462015-05-11 13:58:06 +01001121 case WM5110:
1122 case WM8280:
1123 ret = wm5110_apply_sleep_patch(arizona);
1124 if (ret) {
1125 dev_err(arizona->dev,
1126 "Failed to apply sleep patch: %d\n",
1127 ret);
1128 goto err_reset;
1129 }
1130 break;
Charles Keepaxe80436b2013-03-26 18:46:15 +00001131 default:
1132 break;
1133 }
Mark Brown62d62b52012-12-02 11:41:46 +09001134 }
1135
Mark Brown3cc72982012-06-19 16:31:53 +01001136 for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
1137 if (!arizona->pdata.gpio_defaults[i])
1138 continue;
1139
1140 regmap_write(arizona->regmap, ARIZONA_GPIO1_CTRL + i,
1141 arizona->pdata.gpio_defaults[i]);
1142 }
1143
1144 pm_runtime_set_autosuspend_delay(arizona->dev, 100);
1145 pm_runtime_use_autosuspend(arizona->dev);
1146 pm_runtime_enable(arizona->dev);
1147
1148 /* Chip default */
1149 if (!arizona->pdata.clk32k_src)
1150 arizona->pdata.clk32k_src = ARIZONA_32KZ_MCLK2;
1151
1152 switch (arizona->pdata.clk32k_src) {
1153 case ARIZONA_32KZ_MCLK1:
1154 case ARIZONA_32KZ_MCLK2:
1155 regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
1156 ARIZONA_CLK_32K_SRC_MASK,
1157 arizona->pdata.clk32k_src - 1);
Mark Brown767c6dc2013-03-19 19:04:46 +01001158 arizona_clk32k_enable(arizona);
Mark Brown3cc72982012-06-19 16:31:53 +01001159 break;
1160 case ARIZONA_32KZ_NONE:
1161 regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
1162 ARIZONA_CLK_32K_SRC_MASK, 2);
1163 break;
1164 default:
1165 dev_err(arizona->dev, "Invalid 32kHz clock source: %d\n",
1166 arizona->pdata.clk32k_src);
1167 ret = -EINVAL;
Mark Brown59db9692012-07-09 00:31:36 +02001168 goto err_reset;
Mark Brown3cc72982012-06-19 16:31:53 +01001169 }
1170
Mark Brown3d91f822013-01-29 00:47:37 +08001171 for (i = 0; i < ARIZONA_MAX_MICBIAS; i++) {
Mark Brown544c7aa2013-01-29 18:44:41 +08001172 if (!arizona->pdata.micbias[i].mV &&
1173 !arizona->pdata.micbias[i].bypass)
Mark Brown3d91f822013-01-29 00:47:37 +08001174 continue;
1175
Mark Brown544c7aa2013-01-29 18:44:41 +08001176 /* Apply default for bypass mode */
1177 if (!arizona->pdata.micbias[i].mV)
1178 arizona->pdata.micbias[i].mV = 2800;
1179
Mark Brown3d91f822013-01-29 00:47:37 +08001180 val = (arizona->pdata.micbias[i].mV - 1500) / 100;
Mark Brown544c7aa2013-01-29 18:44:41 +08001181
Mark Brown3d91f822013-01-29 00:47:37 +08001182 val <<= ARIZONA_MICB1_LVL_SHIFT;
1183
1184 if (arizona->pdata.micbias[i].ext_cap)
1185 val |= ARIZONA_MICB1_EXT_CAP;
1186
1187 if (arizona->pdata.micbias[i].discharge)
1188 val |= ARIZONA_MICB1_DISCH;
1189
Charles Keepaxf773fc62013-05-21 14:56:58 +01001190 if (arizona->pdata.micbias[i].soft_start)
Mark Brown3d91f822013-01-29 00:47:37 +08001191 val |= ARIZONA_MICB1_RATE;
1192
Mark Brown544c7aa2013-01-29 18:44:41 +08001193 if (arizona->pdata.micbias[i].bypass)
1194 val |= ARIZONA_MICB1_BYPASS;
1195
Mark Brown3d91f822013-01-29 00:47:37 +08001196 regmap_update_bits(arizona->regmap,
1197 ARIZONA_MIC_BIAS_CTRL_1 + i,
1198 ARIZONA_MICB1_LVL_MASK |
Charles Keepax71d134b2014-09-24 10:37:11 +01001199 ARIZONA_MICB1_EXT_CAP |
Mark Brown3d91f822013-01-29 00:47:37 +08001200 ARIZONA_MICB1_DISCH |
Mark Brown544c7aa2013-01-29 18:44:41 +08001201 ARIZONA_MICB1_BYPASS |
Mark Brown3d91f822013-01-29 00:47:37 +08001202 ARIZONA_MICB1_RATE, val);
1203 }
1204
Mark Brown3cc72982012-06-19 16:31:53 +01001205 for (i = 0; i < ARIZONA_MAX_INPUT; i++) {
1206 /* Default for both is 0 so noop with defaults */
1207 val = arizona->pdata.dmic_ref[i]
1208 << ARIZONA_IN1_DMIC_SUP_SHIFT;
Richard Fitzgeraldfc027d12015-05-01 16:15:12 +01001209 if (arizona->pdata.inmode[i] & ARIZONA_INMODE_DMIC)
1210 val |= 1 << ARIZONA_IN1_MODE_SHIFT;
1211 if (arizona->pdata.inmode[i] & ARIZONA_INMODE_SE)
1212 val |= 1 << ARIZONA_IN1_SINGLE_ENDED_SHIFT;
Mark Brown3cc72982012-06-19 16:31:53 +01001213
1214 regmap_update_bits(arizona->regmap,
1215 ARIZONA_IN1L_CONTROL + (i * 8),
1216 ARIZONA_IN1_DMIC_SUP_MASK |
Richard Fitzgeraldfc027d12015-05-01 16:15:12 +01001217 ARIZONA_IN1_MODE_MASK |
1218 ARIZONA_IN1_SINGLE_ENDED_MASK, val);
Mark Brown3cc72982012-06-19 16:31:53 +01001219 }
1220
1221 for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) {
1222 /* Default is 0 so noop with defaults */
1223 if (arizona->pdata.out_mono[i])
1224 val = ARIZONA_OUT1_MONO;
1225 else
1226 val = 0;
1227
1228 regmap_update_bits(arizona->regmap,
1229 ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8),
1230 ARIZONA_OUT1_MONO, val);
1231 }
1232
Mark Brown3cc72982012-06-19 16:31:53 +01001233 for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) {
1234 if (arizona->pdata.spk_mute[i])
1235 regmap_update_bits(arizona->regmap,
Mark Brown2a51da02012-07-09 19:33:14 +01001236 ARIZONA_PDM_SPK1_CTRL_1 + (i * 2),
Mark Brown3cc72982012-06-19 16:31:53 +01001237 ARIZONA_SPK1_MUTE_ENDIAN_MASK |
1238 ARIZONA_SPK1_MUTE_SEQ1_MASK,
1239 arizona->pdata.spk_mute[i]);
1240
1241 if (arizona->pdata.spk_fmt[i])
1242 regmap_update_bits(arizona->regmap,
Mark Brown2a51da02012-07-09 19:33:14 +01001243 ARIZONA_PDM_SPK1_CTRL_2 + (i * 2),
Mark Brown3cc72982012-06-19 16:31:53 +01001244 ARIZONA_SPK1_FMT_MASK,
1245 arizona->pdata.spk_fmt[i]);
1246 }
1247
1248 /* Set up for interrupts */
1249 ret = arizona_irq_init(arizona);
1250 if (ret != 0)
Mark Brown59db9692012-07-09 00:31:36 +02001251 goto err_reset;
Mark Brown3cc72982012-06-19 16:31:53 +01001252
1253 arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error",
1254 arizona_clkgen_err, arizona);
1255 arizona_request_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, "Overclocked",
1256 arizona_overclocked, arizona);
1257 arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked",
1258 arizona_underclocked, arizona);
1259
1260 switch (arizona->type) {
1261 case WM5102:
1262 ret = mfd_add_devices(arizona->dev, -1, wm5102_devs,
Mark Brown0848c942012-09-11 15:16:36 +08001263 ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);
Mark Brown3cc72982012-06-19 16:31:53 +01001264 break;
Mark Browne102bef2012-07-10 12:37:58 +01001265 case WM5110:
Richard Fitzgeralde5d4ef02015-01-17 15:21:22 +00001266 case WM8280:
Mark Browne102bef2012-07-10 12:37:58 +01001267 ret = mfd_add_devices(arizona->dev, -1, wm5110_devs,
Charles Keepax78566af2012-11-20 13:46:19 +09001268 ARRAY_SIZE(wm5110_devs), NULL, 0, NULL);
Mark Browne102bef2012-07-10 12:37:58 +01001269 break;
Charles Keepaxdc7d4862013-06-13 09:43:29 +01001270 case WM8997:
1271 ret = mfd_add_devices(arizona->dev, -1, wm8997_devs,
1272 ARRAY_SIZE(wm8997_devs), NULL, 0, NULL);
1273 break;
Mark Brown3cc72982012-06-19 16:31:53 +01001274 }
1275
1276 if (ret != 0) {
1277 dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret);
1278 goto err_irq;
1279 }
1280
Rafael J. Wysocki48bb9fe2014-12-05 03:04:12 +01001281#ifdef CONFIG_PM
Mark Brown59db9692012-07-09 00:31:36 +02001282 regulator_disable(arizona->dcvdd);
1283#endif
1284
Mark Brown3cc72982012-06-19 16:31:53 +01001285 return 0;
1286
1287err_irq:
1288 arizona_irq_exit(arizona);
Mark Brown3cc72982012-06-19 16:31:53 +01001289err_reset:
Charles Keepax22298752015-05-11 13:58:02 +01001290 arizona_enable_reset(arizona);
Mark Brown59db9692012-07-09 00:31:36 +02001291 regulator_disable(arizona->dcvdd);
Mark Brown3cc72982012-06-19 16:31:53 +01001292err_enable:
Mark Brown3a36a0db2012-07-09 00:45:53 +02001293 regulator_bulk_disable(arizona->num_core_supplies,
Mark Brown3cc72982012-06-19 16:31:53 +01001294 arizona->core_supplies);
Charles Keepaxe6021512014-06-02 09:50:41 +01001295err_dcvdd:
1296 regulator_put(arizona->dcvdd);
Mark Brown3cc72982012-06-19 16:31:53 +01001297err_early:
1298 mfd_remove_devices(dev);
1299 return ret;
1300}
1301EXPORT_SYMBOL_GPL(arizona_dev_init);
1302
Bill Pemberton4740f732012-11-19 13:26:01 -05001303int arizona_dev_exit(struct arizona *arizona)
Mark Brown3cc72982012-06-19 16:31:53 +01001304{
Charles Keepaxb8040202014-06-02 09:50:39 +01001305 pm_runtime_disable(arizona->dev);
1306
Charles Keepaxdf6b3352014-06-02 09:50:40 +01001307 regulator_disable(arizona->dcvdd);
Charles Keepaxe6021512014-06-02 09:50:41 +01001308 regulator_put(arizona->dcvdd);
Charles Keepaxdf6b3352014-06-02 09:50:40 +01001309
Mark Brown3cc72982012-06-19 16:31:53 +01001310 mfd_remove_devices(arizona->dev);
1311 arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona);
1312 arizona_free_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, arizona);
1313 arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona);
Mark Brown3cc72982012-06-19 16:31:53 +01001314 arizona_irq_exit(arizona);
Charles Keepax22298752015-05-11 13:58:02 +01001315 arizona_enable_reset(arizona);
Charles Keepaxdf6b3352014-06-02 09:50:40 +01001316
Charles Keepax44202862014-06-02 09:50:42 +01001317 regulator_bulk_disable(arizona->num_core_supplies,
Mark Brown1d017b62013-03-26 12:16:26 +00001318 arizona->core_supplies);
Mark Brown3cc72982012-06-19 16:31:53 +01001319 return 0;
1320}
1321EXPORT_SYMBOL_GPL(arizona_dev_exit);