blob: 326a4afdd8326e6f7d648e7522e13138e99857ab [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) {
262 gpio_set_value_cansleep(arizona->pdata.reset, 1);
263 msleep(1);
264 }
265}
266
Charles Keepax0be068a2015-05-11 13:58:04 +0100267static int wm5102_apply_hardware_patch(struct arizona *arizona)
Charles Keepaxe80436b2013-03-26 18:46:15 +0000268{
269 unsigned int fll, sysclk;
270 int ret, err;
271
Charles Keepaxe80436b2013-03-26 18:46:15 +0000272 /* Cache existing FLL and SYSCLK settings */
273 ret = regmap_read(arizona->regmap, ARIZONA_FLL1_CONTROL_1, &fll);
Charles Keepax0be068a2015-05-11 13:58:04 +0100274 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000275 dev_err(arizona->dev, "Failed to cache FLL settings: %d\n",
276 ret);
277 return ret;
278 }
279 ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, &sysclk);
Charles Keepax0be068a2015-05-11 13:58:04 +0100280 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000281 dev_err(arizona->dev, "Failed to cache SYSCLK settings: %d\n",
282 ret);
283 return ret;
284 }
285
286 /* Start up SYSCLK using the FLL in free running mode */
287 ret = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1,
288 ARIZONA_FLL1_ENA | ARIZONA_FLL1_FREERUN);
Charles Keepax0be068a2015-05-11 13:58:04 +0100289 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000290 dev_err(arizona->dev,
291 "Failed to start FLL in freerunning mode: %d\n",
292 ret);
293 return ret;
294 }
295 ret = arizona_poll_reg(arizona, 25, ARIZONA_INTERRUPT_RAW_STATUS_5,
296 ARIZONA_FLL1_CLOCK_OK_STS,
297 ARIZONA_FLL1_CLOCK_OK_STS);
Charles Keepax0be068a2015-05-11 13:58:04 +0100298 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000299 ret = -ETIMEDOUT;
300 goto err_fll;
301 }
302
303 ret = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, 0x0144);
Charles Keepax0be068a2015-05-11 13:58:04 +0100304 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000305 dev_err(arizona->dev, "Failed to start SYSCLK: %d\n", ret);
306 goto err_fll;
307 }
308
309 /* Start the write sequencer and wait for it to finish */
310 ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0,
Charles Keepax0be068a2015-05-11 13:58:04 +0100311 ARIZONA_WSEQ_ENA | ARIZONA_WSEQ_START | 160);
312 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000313 dev_err(arizona->dev, "Failed to start write sequencer: %d\n",
314 ret);
315 goto err_sysclk;
316 }
317 ret = arizona_poll_reg(arizona, 5, ARIZONA_WRITE_SEQUENCER_CTRL_1,
318 ARIZONA_WSEQ_BUSY, 0);
Charles Keepax0be068a2015-05-11 13:58:04 +0100319 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000320 regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0,
Charles Keepax0be068a2015-05-11 13:58:04 +0100321 ARIZONA_WSEQ_ABORT);
Charles Keepaxe80436b2013-03-26 18:46:15 +0000322 ret = -ETIMEDOUT;
323 }
324
325err_sysclk:
326 err = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, sysclk);
Charles Keepax0be068a2015-05-11 13:58:04 +0100327 if (err) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000328 dev_err(arizona->dev,
329 "Failed to re-apply old SYSCLK settings: %d\n",
330 err);
331 }
332
333err_fll:
334 err = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, fll);
Charles Keepax0be068a2015-05-11 13:58:04 +0100335 if (err) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000336 dev_err(arizona->dev,
337 "Failed to re-apply old FLL settings: %d\n",
338 err);
339 }
340
Charles Keepax0be068a2015-05-11 13:58:04 +0100341 return ret ?: err;
Charles Keepaxe80436b2013-03-26 18:46:15 +0000342}
343
Charles Keepax1c1c6bb2015-05-11 13:58:03 +0100344static int wm5102_clear_write_sequencer(struct arizona *arizona)
345{
346 int ret;
347
348 ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_3,
349 0x0);
350 if (ret) {
351 dev_err(arizona->dev,
352 "Failed to clear write sequencer state: %d\n", ret);
353 return ret;
354 }
355
356 arizona_enable_reset(arizona);
357 regulator_disable(arizona->dcvdd);
358
359 msleep(20);
360
361 ret = regulator_enable(arizona->dcvdd);
362 if (ret) {
363 dev_err(arizona->dev, "Failed to re-enable DCVDD: %d\n", ret);
364 return ret;
365 }
366 arizona_disable_reset(arizona);
367
368 return 0;
369}
370
Rafael J. Wysocki48bb9fe2014-12-05 03:04:12 +0100371#ifdef CONFIG_PM
Mark Brown3cc72982012-06-19 16:31:53 +0100372static int arizona_runtime_resume(struct device *dev)
373{
374 struct arizona *arizona = dev_get_drvdata(dev);
375 int ret;
376
Mark Brown508c8292012-07-20 17:09:12 +0100377 dev_dbg(arizona->dev, "Leaving AoD mode\n");
378
Mark Brown59db9692012-07-09 00:31:36 +0200379 ret = regulator_enable(arizona->dcvdd);
380 if (ret != 0) {
381 dev_err(arizona->dev, "Failed to enable DCVDD: %d\n", ret);
382 return ret;
383 }
Mark Brown3cc72982012-06-19 16:31:53 +0100384
385 regcache_cache_only(arizona->regmap, false);
386
Charles Keepax4c9bb8b2013-03-26 18:01:49 +0000387 switch (arizona->type) {
388 case WM5102:
Mark Brown59274672013-04-23 19:44:16 +0100389 if (arizona->external_dcvdd) {
390 ret = regmap_update_bits(arizona->regmap,
391 ARIZONA_ISOLATION_CONTROL,
392 ARIZONA_ISOLATE_DCVDD1, 0);
393 if (ret != 0) {
394 dev_err(arizona->dev,
395 "Failed to connect DCVDD: %d\n", ret);
396 goto err;
397 }
398 }
399
Charles Keepax4c9bb8b2013-03-26 18:01:49 +0000400 ret = wm5102_patch(arizona);
401 if (ret != 0) {
402 dev_err(arizona->dev, "Failed to apply patch: %d\n",
403 ret);
404 goto err;
405 }
Charles Keepaxe80436b2013-03-26 18:46:15 +0000406
Charles Keepax0be068a2015-05-11 13:58:04 +0100407 ret = wm5102_apply_hardware_patch(arizona);
408 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000409 dev_err(arizona->dev,
410 "Failed to apply hardware patch: %d\n",
411 ret);
412 goto err;
413 }
414 break;
415 default:
Charles Keepax12bb68e2013-03-27 09:49:40 +0000416 ret = arizona_wait_for_boot(arizona);
417 if (ret != 0) {
418 goto err;
419 }
420
Mark Brown59274672013-04-23 19:44:16 +0100421 if (arizona->external_dcvdd) {
422 ret = regmap_update_bits(arizona->regmap,
423 ARIZONA_ISOLATION_CONTROL,
424 ARIZONA_ISOLATE_DCVDD1, 0);
425 if (ret != 0) {
426 dev_err(arizona->dev,
427 "Failed to connect DCVDD: %d\n", ret);
428 goto err;
429 }
430 }
Charles Keepaxe80436b2013-03-26 18:46:15 +0000431 break;
Charles Keepax4c9bb8b2013-03-26 18:01:49 +0000432 }
433
Mark Brown9270bdf2013-01-04 17:16:12 +0000434 ret = regcache_sync(arizona->regmap);
435 if (ret != 0) {
436 dev_err(arizona->dev, "Failed to restore register cache\n");
Mark Brown4816bd12013-01-14 15:50:38 +0900437 goto err;
Mark Brown9270bdf2013-01-04 17:16:12 +0000438 }
Mark Brown3cc72982012-06-19 16:31:53 +0100439
440 return 0;
Mark Brown4816bd12013-01-14 15:50:38 +0900441
442err:
443 regcache_cache_only(arizona->regmap, true);
444 regulator_disable(arizona->dcvdd);
445 return ret;
Mark Brown3cc72982012-06-19 16:31:53 +0100446}
447
448static int arizona_runtime_suspend(struct device *dev)
449{
450 struct arizona *arizona = dev_get_drvdata(dev);
Mark Brown59274672013-04-23 19:44:16 +0100451 int ret;
Mark Brown3cc72982012-06-19 16:31:53 +0100452
Mark Brown508c8292012-07-20 17:09:12 +0100453 dev_dbg(arizona->dev, "Entering AoD mode\n");
454
Mark Brown59274672013-04-23 19:44:16 +0100455 if (arizona->external_dcvdd) {
456 ret = regmap_update_bits(arizona->regmap,
457 ARIZONA_ISOLATION_CONTROL,
458 ARIZONA_ISOLATE_DCVDD1,
459 ARIZONA_ISOLATE_DCVDD1);
460 if (ret != 0) {
461 dev_err(arizona->dev, "Failed to isolate DCVDD: %d\n",
462 ret);
463 return ret;
464 }
465 }
466
Mark Brown59db9692012-07-09 00:31:36 +0200467 regcache_cache_only(arizona->regmap, true);
468 regcache_mark_dirty(arizona->regmap);
Charles Keepaxe293e84722013-08-06 17:18:35 +0100469 regulator_disable(arizona->dcvdd);
Mark Brown3cc72982012-06-19 16:31:53 +0100470
471 return 0;
472}
473#endif
474
Mark Browndc781d02013-01-27 12:07:32 +0800475#ifdef CONFIG_PM_SLEEP
Mark Brown67c99292013-04-10 12:40:26 +0100476static int arizona_suspend(struct device *dev)
477{
478 struct arizona *arizona = dev_get_drvdata(dev);
479
480 dev_dbg(arizona->dev, "Suspend, disabling IRQ\n");
481 disable_irq(arizona->irq);
482
483 return 0;
484}
485
486static int arizona_suspend_late(struct device *dev)
487{
488 struct arizona *arizona = dev_get_drvdata(dev);
489
490 dev_dbg(arizona->dev, "Late suspend, reenabling IRQ\n");
491 enable_irq(arizona->irq);
492
493 return 0;
494}
495
Mark Browndc781d02013-01-27 12:07:32 +0800496static int arizona_resume_noirq(struct device *dev)
497{
498 struct arizona *arizona = dev_get_drvdata(dev);
499
500 dev_dbg(arizona->dev, "Early resume, disabling IRQ\n");
501 disable_irq(arizona->irq);
502
503 return 0;
504}
505
506static int arizona_resume(struct device *dev)
507{
508 struct arizona *arizona = dev_get_drvdata(dev);
509
510 dev_dbg(arizona->dev, "Late resume, reenabling IRQ\n");
511 enable_irq(arizona->irq);
512
513 return 0;
514}
515#endif
516
Mark Brown3cc72982012-06-19 16:31:53 +0100517const struct dev_pm_ops arizona_pm_ops = {
518 SET_RUNTIME_PM_OPS(arizona_runtime_suspend,
519 arizona_runtime_resume,
520 NULL)
Mark Brown67c99292013-04-10 12:40:26 +0100521 SET_SYSTEM_SLEEP_PM_OPS(arizona_suspend, arizona_resume)
Mark Browndc781d02013-01-27 12:07:32 +0800522#ifdef CONFIG_PM_SLEEP
Mark Brown67c99292013-04-10 12:40:26 +0100523 .suspend_late = arizona_suspend_late,
Mark Browndc781d02013-01-27 12:07:32 +0800524 .resume_noirq = arizona_resume_noirq,
525#endif
Mark Brown3cc72982012-06-19 16:31:53 +0100526};
527EXPORT_SYMBOL_GPL(arizona_pm_ops);
528
Mark Brownd7810092013-03-25 00:11:27 +0000529#ifdef CONFIG_OF
Lee Jones942786e2014-07-02 14:28:46 +0100530unsigned long arizona_of_get_type(struct device *dev)
Mark Brownd7810092013-03-25 00:11:27 +0000531{
532 const struct of_device_id *id = of_match_device(arizona_of_match, dev);
533
534 if (id)
Lee Jones942786e2014-07-02 14:28:46 +0100535 return (unsigned long)id->data;
Mark Brownd7810092013-03-25 00:11:27 +0000536 else
537 return 0;
538}
539EXPORT_SYMBOL_GPL(arizona_of_get_type);
540
Charles Keepaxe4fcb1d2014-04-16 10:01:37 +0100541int arizona_of_get_named_gpio(struct arizona *arizona, const char *prop,
542 bool mandatory)
543{
544 int gpio;
545
546 gpio = of_get_named_gpio(arizona->dev->of_node, prop, 0);
547 if (gpio < 0) {
548 if (mandatory)
549 dev_err(arizona->dev,
550 "Mandatory DT gpio %s missing/malformed: %d\n",
551 prop, gpio);
552
553 gpio = 0;
554 }
555
556 return gpio;
557}
558EXPORT_SYMBOL_GPL(arizona_of_get_named_gpio);
559
Mark Brownd7810092013-03-25 00:11:27 +0000560static int arizona_of_get_core_pdata(struct arizona *arizona)
561{
Charles Keepaxe4fcb1d2014-04-16 10:01:37 +0100562 struct arizona_pdata *pdata = &arizona->pdata;
Inha Songcc47aed2014-08-30 11:27:18 +0900563 struct property *prop;
564 const __be32 *cur;
565 u32 val;
Mark Brownd7810092013-03-25 00:11:27 +0000566 int ret, i;
Inha Songcc47aed2014-08-30 11:27:18 +0900567 int count = 0;
Mark Brownd7810092013-03-25 00:11:27 +0000568
Charles Keepaxe4fcb1d2014-04-16 10:01:37 +0100569 pdata->reset = arizona_of_get_named_gpio(arizona, "wlf,reset", true);
Mark Brownd7810092013-03-25 00:11:27 +0000570
571 ret = of_property_read_u32_array(arizona->dev->of_node,
572 "wlf,gpio-defaults",
573 arizona->pdata.gpio_defaults,
574 ARRAY_SIZE(arizona->pdata.gpio_defaults));
575 if (ret >= 0) {
576 /*
577 * All values are literal except out of range values
578 * which are chip default, translate into platform
579 * data which uses 0 as chip default and out of range
580 * as zero.
581 */
582 for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
583 if (arizona->pdata.gpio_defaults[i] > 0xffff)
584 arizona->pdata.gpio_defaults[i] = 0;
Charles Keepax91c73932013-10-03 16:16:01 +0100585 else if (arizona->pdata.gpio_defaults[i] == 0)
Mark Brownd7810092013-03-25 00:11:27 +0000586 arizona->pdata.gpio_defaults[i] = 0x10000;
587 }
588 } else {
589 dev_err(arizona->dev, "Failed to parse GPIO defaults: %d\n",
590 ret);
591 }
592
Inha Songcc47aed2014-08-30 11:27:18 +0900593 of_property_for_each_u32(arizona->dev->of_node, "wlf,inmode", prop,
594 cur, val) {
595 if (count == ARRAY_SIZE(arizona->pdata.inmode))
596 break;
597
598 arizona->pdata.inmode[count] = val;
599 count++;
600 }
601
Charles Keepaxe7ad27c2015-03-03 15:04:53 +0000602 count = 0;
603 of_property_for_each_u32(arizona->dev->of_node, "wlf,dmic-ref", prop,
604 cur, val) {
605 if (count == ARRAY_SIZE(arizona->pdata.dmic_ref))
606 break;
607
608 arizona->pdata.dmic_ref[count] = val;
609 count++;
610 }
611
Mark Brownd7810092013-03-25 00:11:27 +0000612 return 0;
613}
614
615const struct of_device_id arizona_of_match[] = {
616 { .compatible = "wlf,wm5102", .data = (void *)WM5102 },
617 { .compatible = "wlf,wm5110", .data = (void *)WM5110 },
Richard Fitzgeralde5d4ef02015-01-17 15:21:22 +0000618 { .compatible = "wlf,wm8280", .data = (void *)WM8280 },
Charles Keepaxdc7d4862013-06-13 09:43:29 +0100619 { .compatible = "wlf,wm8997", .data = (void *)WM8997 },
Mark Brownd7810092013-03-25 00:11:27 +0000620 {},
621};
622EXPORT_SYMBOL_GPL(arizona_of_match);
623#else
624static inline int arizona_of_get_core_pdata(struct arizona *arizona)
625{
626 return 0;
627}
628#endif
629
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100630static const struct mfd_cell early_devs[] = {
Mark Brown3cc72982012-06-19 16:31:53 +0100631 { .name = "arizona-ldo1" },
632};
633
Charles Keepax32dadef2013-10-15 20:14:22 +0100634static const char *wm5102_supplies[] = {
Charles Keepax5fc6c392014-07-25 16:24:44 +0100635 "MICVDD",
Charles Keepax32dadef2013-10-15 20:14:22 +0100636 "DBVDD2",
637 "DBVDD3",
638 "CPVDD",
639 "SPKVDDL",
640 "SPKVDDR",
641};
642
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100643static const struct mfd_cell wm5102_devs[] = {
Mark Brownd77681112012-12-20 15:38:03 +0000644 { .name = "arizona-micsupp" },
Charles Keepax5fc6c392014-07-25 16:24:44 +0100645 {
646 .name = "arizona-extcon",
647 .parent_supplies = wm5102_supplies,
648 .num_parent_supplies = 1, /* We only need MICVDD */
649 },
Mark Brown3cc72982012-06-19 16:31:53 +0100650 { .name = "arizona-gpio" },
Mark Brown503b1ca2012-11-27 17:36:38 +0000651 { .name = "arizona-haptics" },
Mark Brown3cc72982012-06-19 16:31:53 +0100652 { .name = "arizona-pwm" },
Charles Keepax32dadef2013-10-15 20:14:22 +0100653 {
654 .name = "wm5102-codec",
655 .parent_supplies = wm5102_supplies,
656 .num_parent_supplies = ARRAY_SIZE(wm5102_supplies),
657 },
Mark Brown3cc72982012-06-19 16:31:53 +0100658};
659
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100660static const struct mfd_cell wm5110_devs[] = {
Mark Brownd77681112012-12-20 15:38:03 +0000661 { .name = "arizona-micsupp" },
Charles Keepax5fc6c392014-07-25 16:24:44 +0100662 {
663 .name = "arizona-extcon",
664 .parent_supplies = wm5102_supplies,
665 .num_parent_supplies = 1, /* We only need MICVDD */
666 },
Mark Browne102bef2012-07-10 12:37:58 +0100667 { .name = "arizona-gpio" },
Mark Brown503b1ca2012-11-27 17:36:38 +0000668 { .name = "arizona-haptics" },
Mark Browne102bef2012-07-10 12:37:58 +0100669 { .name = "arizona-pwm" },
Charles Keepax32dadef2013-10-15 20:14:22 +0100670 {
671 .name = "wm5110-codec",
672 .parent_supplies = wm5102_supplies,
673 .num_parent_supplies = ARRAY_SIZE(wm5102_supplies),
674 },
675};
676
677static const char *wm8997_supplies[] = {
Charles Keepax996c2d42014-07-25 16:24:43 +0100678 "MICVDD",
Charles Keepax32dadef2013-10-15 20:14:22 +0100679 "DBVDD2",
680 "CPVDD",
681 "SPKVDD",
Mark Browne102bef2012-07-10 12:37:58 +0100682};
683
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100684static const struct mfd_cell wm8997_devs[] = {
Charles Keepaxdc7d4862013-06-13 09:43:29 +0100685 { .name = "arizona-micsupp" },
Charles Keepax5fc6c392014-07-25 16:24:44 +0100686 {
687 .name = "arizona-extcon",
688 .parent_supplies = wm8997_supplies,
689 .num_parent_supplies = 1, /* We only need MICVDD */
690 },
Charles Keepaxdc7d4862013-06-13 09:43:29 +0100691 { .name = "arizona-gpio" },
692 { .name = "arizona-haptics" },
693 { .name = "arizona-pwm" },
Charles Keepax32dadef2013-10-15 20:14:22 +0100694 {
695 .name = "wm8997-codec",
696 .parent_supplies = wm8997_supplies,
697 .num_parent_supplies = ARRAY_SIZE(wm8997_supplies),
698 },
Charles Keepaxdc7d4862013-06-13 09:43:29 +0100699};
700
Bill Pembertonf791be42012-11-19 13:23:04 -0500701int arizona_dev_init(struct arizona *arizona)
Mark Brown3cc72982012-06-19 16:31:53 +0100702{
703 struct device *dev = arizona->dev;
704 const char *type_name;
705 unsigned int reg, val;
Mark Brown62d62b52012-12-02 11:41:46 +0900706 int (*apply_patch)(struct arizona *) = NULL;
Mark Brown3cc72982012-06-19 16:31:53 +0100707 int ret, i;
708
709 dev_set_drvdata(arizona->dev, arizona);
710 mutex_init(&arizona->clk_lock);
711
712 if (dev_get_platdata(arizona->dev))
713 memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
714 sizeof(arizona->pdata));
Lee Jones22d7dc82013-09-27 14:25:55 +0100715 else
716 arizona_of_get_core_pdata(arizona);
Mark Brown3cc72982012-06-19 16:31:53 +0100717
718 regcache_cache_only(arizona->regmap, true);
719
720 switch (arizona->type) {
721 case WM5102:
Mark Browne102bef2012-07-10 12:37:58 +0100722 case WM5110:
Richard Fitzgeralde5d4ef02015-01-17 15:21:22 +0000723 case WM8280:
Charles Keepaxdc7d4862013-06-13 09:43:29 +0100724 case WM8997:
Mark Brown3cc72982012-06-19 16:31:53 +0100725 for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++)
726 arizona->core_supplies[i].supply
727 = wm5102_core_supplies[i];
728 arizona->num_core_supplies = ARRAY_SIZE(wm5102_core_supplies);
729 break;
730 default:
731 dev_err(arizona->dev, "Unknown device type %d\n",
732 arizona->type);
733 return -EINVAL;
734 }
735
Charles Keepax4a8c4752014-04-16 10:01:38 +0100736 /* Mark DCVDD as external, LDO1 driver will clear if internal */
737 arizona->external_dcvdd = true;
738
Mark Brown3cc72982012-06-19 16:31:53 +0100739 ret = mfd_add_devices(arizona->dev, -1, early_devs,
Mark Brown0848c942012-09-11 15:16:36 +0800740 ARRAY_SIZE(early_devs), NULL, 0, NULL);
Mark Brown3cc72982012-06-19 16:31:53 +0100741 if (ret != 0) {
742 dev_err(dev, "Failed to add early children: %d\n", ret);
743 return ret;
744 }
745
746 ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies,
747 arizona->core_supplies);
748 if (ret != 0) {
749 dev_err(dev, "Failed to request core supplies: %d\n",
750 ret);
751 goto err_early;
752 }
753
Charles Keepax0c2d0ff2014-06-19 16:04:23 +0100754 /**
755 * Don't use devres here because the only device we have to get
756 * against is the MFD device and DCVDD will likely be supplied by
757 * one of its children. Meaning that the regulator will be
758 * destroyed by the time devres calls regulator put.
759 */
Charles Keepaxe6021512014-06-02 09:50:41 +0100760 arizona->dcvdd = regulator_get(arizona->dev, "DCVDD");
Mark Brown59db9692012-07-09 00:31:36 +0200761 if (IS_ERR(arizona->dcvdd)) {
762 ret = PTR_ERR(arizona->dcvdd);
763 dev_err(dev, "Failed to request DCVDD: %d\n", ret);
764 goto err_early;
765 }
766
Mark Brown87d3af42013-03-26 12:15:26 +0000767 if (arizona->pdata.reset) {
768 /* Start out with /RESET low to put the chip into reset */
Charles Keepax5f056bf2015-05-11 13:58:01 +0100769 ret = devm_gpio_request_one(arizona->dev, arizona->pdata.reset,
770 GPIOF_DIR_OUT | GPIOF_INIT_LOW,
771 "arizona /RESET");
Mark Brown87d3af42013-03-26 12:15:26 +0000772 if (ret != 0) {
773 dev_err(dev, "Failed to request /RESET: %d\n", ret);
Charles Keepaxe6021512014-06-02 09:50:41 +0100774 goto err_dcvdd;
Mark Brown87d3af42013-03-26 12:15:26 +0000775 }
776 }
777
Mark Brown3cc72982012-06-19 16:31:53 +0100778 ret = regulator_bulk_enable(arizona->num_core_supplies,
779 arizona->core_supplies);
780 if (ret != 0) {
781 dev_err(dev, "Failed to enable core supplies: %d\n",
782 ret);
Charles Keepaxe6021512014-06-02 09:50:41 +0100783 goto err_dcvdd;
Mark Brown3cc72982012-06-19 16:31:53 +0100784 }
785
Mark Brown59db9692012-07-09 00:31:36 +0200786 ret = regulator_enable(arizona->dcvdd);
787 if (ret != 0) {
788 dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
789 goto err_enable;
790 }
791
Charles Keepax22298752015-05-11 13:58:02 +0100792 arizona_disable_reset(arizona);
Mark Brown3cc72982012-06-19 16:31:53 +0100793
Mark Brown3cc72982012-06-19 16:31:53 +0100794 regcache_cache_only(arizona->regmap, false);
795
Mark Brownca76ceb2013-04-09 16:04:35 +0100796 /* Verify that this is a chip we know about */
797 ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
798 if (ret != 0) {
799 dev_err(dev, "Failed to read ID register: %d\n", ret);
800 goto err_reset;
801 }
802
803 switch (reg) {
804 case 0x5102:
805 case 0x5110:
Charles Keepaxdc7d4862013-06-13 09:43:29 +0100806 case 0x8997:
Mark Brownca76ceb2013-04-09 16:04:35 +0100807 break;
808 default:
809 dev_err(arizona->dev, "Unknown device ID: %x\n", reg);
810 goto err_reset;
811 }
812
813 /* If we have a /RESET GPIO we'll already be reset */
814 if (!arizona->pdata.reset) {
Mark Brownca76ceb2013-04-09 16:04:35 +0100815 ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0);
816 if (ret != 0) {
817 dev_err(dev, "Failed to reset device: %d\n", ret);
818 goto err_reset;
819 }
820
821 msleep(1);
Mark Brownca76ceb2013-04-09 16:04:35 +0100822 }
823
824 /* Ensure device startup is complete */
825 switch (arizona->type) {
826 case WM5102:
Mark Brown48018942014-08-13 11:42:46 +0100827 ret = regmap_read(arizona->regmap,
828 ARIZONA_WRITE_SEQUENCER_CTRL_3, &val);
Charles Keepax1c1c6bb2015-05-11 13:58:03 +0100829 if (ret) {
Mark Brownca76ceb2013-04-09 16:04:35 +0100830 dev_err(dev,
831 "Failed to check write sequencer state: %d\n",
832 ret);
Charles Keepax1c1c6bb2015-05-11 13:58:03 +0100833 } else if (val & 0x01) {
834 ret = wm5102_clear_write_sequencer(arizona);
835 if (ret)
836 return ret;
Mark Brownca76ceb2013-04-09 16:04:35 +0100837 }
838 break;
Charles Keepax1c1c6bb2015-05-11 13:58:03 +0100839 default:
840 break;
841 }
842
843 ret = arizona_wait_for_boot(arizona);
844 if (ret) {
845 dev_err(arizona->dev, "Device failed initial boot: %d\n", ret);
846 goto err_reset;
Mark Brownca76ceb2013-04-09 16:04:35 +0100847 }
848
849 /* Read the device ID information & do device specific stuff */
Mark Brown3cc72982012-06-19 16:31:53 +0100850 ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
851 if (ret != 0) {
852 dev_err(dev, "Failed to read ID register: %d\n", ret);
Mark Brown59db9692012-07-09 00:31:36 +0200853 goto err_reset;
Mark Brown3cc72982012-06-19 16:31:53 +0100854 }
855
856 ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
857 &arizona->rev);
858 if (ret != 0) {
859 dev_err(dev, "Failed to read revision register: %d\n", ret);
Mark Brown59db9692012-07-09 00:31:36 +0200860 goto err_reset;
Mark Brown3cc72982012-06-19 16:31:53 +0100861 }
862 arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
863
864 switch (reg) {
Mark Brown863df8d2012-07-05 20:35:31 +0100865#ifdef CONFIG_MFD_WM5102
Mark Brown3cc72982012-06-19 16:31:53 +0100866 case 0x5102:
867 type_name = "WM5102";
868 if (arizona->type != WM5102) {
869 dev_err(arizona->dev, "WM5102 registered as %d\n",
870 arizona->type);
871 arizona->type = WM5102;
872 }
Mark Brown62d62b52012-12-02 11:41:46 +0900873 apply_patch = wm5102_patch;
Mark Brownc6d6bfb2013-03-26 11:14:52 +0000874 arizona->rev &= 0x7;
Mark Brown3cc72982012-06-19 16:31:53 +0100875 break;
Mark Brown863df8d2012-07-05 20:35:31 +0100876#endif
Mark Browne102bef2012-07-10 12:37:58 +0100877#ifdef CONFIG_MFD_WM5110
878 case 0x5110:
Richard Fitzgeralde5d4ef02015-01-17 15:21:22 +0000879 switch (arizona->type) {
880 case WM5110:
881 type_name = "WM5110";
882 break;
883 case WM8280:
884 type_name = "WM8280";
885 break;
886 default:
887 type_name = "WM5110";
Mark Browne102bef2012-07-10 12:37:58 +0100888 dev_err(arizona->dev, "WM5110 registered as %d\n",
889 arizona->type);
890 arizona->type = WM5110;
Richard Fitzgeralde5d4ef02015-01-17 15:21:22 +0000891 break;
Mark Browne102bef2012-07-10 12:37:58 +0100892 }
Mark Brown62d62b52012-12-02 11:41:46 +0900893 apply_patch = wm5110_patch;
Mark Browne102bef2012-07-10 12:37:58 +0100894 break;
895#endif
Charles Keepaxdc7d4862013-06-13 09:43:29 +0100896#ifdef CONFIG_MFD_WM8997
897 case 0x8997:
898 type_name = "WM8997";
899 if (arizona->type != WM8997) {
900 dev_err(arizona->dev, "WM8997 registered as %d\n",
901 arizona->type);
902 arizona->type = WM8997;
903 }
904 apply_patch = wm8997_patch;
905 break;
906#endif
Mark Brown3cc72982012-06-19 16:31:53 +0100907 default:
908 dev_err(arizona->dev, "Unknown device ID %x\n", reg);
Mark Brown59db9692012-07-09 00:31:36 +0200909 goto err_reset;
Mark Brown3cc72982012-06-19 16:31:53 +0100910 }
911
912 dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
913
Mark Brown62d62b52012-12-02 11:41:46 +0900914 if (apply_patch) {
915 ret = apply_patch(arizona);
916 if (ret != 0) {
917 dev_err(arizona->dev, "Failed to apply patch: %d\n",
918 ret);
919 goto err_reset;
920 }
Charles Keepaxe80436b2013-03-26 18:46:15 +0000921
922 switch (arizona->type) {
923 case WM5102:
Charles Keepax0be068a2015-05-11 13:58:04 +0100924 ret = wm5102_apply_hardware_patch(arizona);
925 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000926 dev_err(arizona->dev,
927 "Failed to apply hardware patch: %d\n",
928 ret);
929 goto err_reset;
930 }
931 break;
932 default:
933 break;
934 }
Mark Brown62d62b52012-12-02 11:41:46 +0900935 }
936
Mark Brown3cc72982012-06-19 16:31:53 +0100937 for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
938 if (!arizona->pdata.gpio_defaults[i])
939 continue;
940
941 regmap_write(arizona->regmap, ARIZONA_GPIO1_CTRL + i,
942 arizona->pdata.gpio_defaults[i]);
943 }
944
945 pm_runtime_set_autosuspend_delay(arizona->dev, 100);
946 pm_runtime_use_autosuspend(arizona->dev);
947 pm_runtime_enable(arizona->dev);
948
949 /* Chip default */
950 if (!arizona->pdata.clk32k_src)
951 arizona->pdata.clk32k_src = ARIZONA_32KZ_MCLK2;
952
953 switch (arizona->pdata.clk32k_src) {
954 case ARIZONA_32KZ_MCLK1:
955 case ARIZONA_32KZ_MCLK2:
956 regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
957 ARIZONA_CLK_32K_SRC_MASK,
958 arizona->pdata.clk32k_src - 1);
Mark Brown767c6dc2013-03-19 19:04:46 +0100959 arizona_clk32k_enable(arizona);
Mark Brown3cc72982012-06-19 16:31:53 +0100960 break;
961 case ARIZONA_32KZ_NONE:
962 regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
963 ARIZONA_CLK_32K_SRC_MASK, 2);
964 break;
965 default:
966 dev_err(arizona->dev, "Invalid 32kHz clock source: %d\n",
967 arizona->pdata.clk32k_src);
968 ret = -EINVAL;
Mark Brown59db9692012-07-09 00:31:36 +0200969 goto err_reset;
Mark Brown3cc72982012-06-19 16:31:53 +0100970 }
971
Mark Brown3d91f822013-01-29 00:47:37 +0800972 for (i = 0; i < ARIZONA_MAX_MICBIAS; i++) {
Mark Brown544c7aa2013-01-29 18:44:41 +0800973 if (!arizona->pdata.micbias[i].mV &&
974 !arizona->pdata.micbias[i].bypass)
Mark Brown3d91f822013-01-29 00:47:37 +0800975 continue;
976
Mark Brown544c7aa2013-01-29 18:44:41 +0800977 /* Apply default for bypass mode */
978 if (!arizona->pdata.micbias[i].mV)
979 arizona->pdata.micbias[i].mV = 2800;
980
Mark Brown3d91f822013-01-29 00:47:37 +0800981 val = (arizona->pdata.micbias[i].mV - 1500) / 100;
Mark Brown544c7aa2013-01-29 18:44:41 +0800982
Mark Brown3d91f822013-01-29 00:47:37 +0800983 val <<= ARIZONA_MICB1_LVL_SHIFT;
984
985 if (arizona->pdata.micbias[i].ext_cap)
986 val |= ARIZONA_MICB1_EXT_CAP;
987
988 if (arizona->pdata.micbias[i].discharge)
989 val |= ARIZONA_MICB1_DISCH;
990
Charles Keepaxf773fc62013-05-21 14:56:58 +0100991 if (arizona->pdata.micbias[i].soft_start)
Mark Brown3d91f822013-01-29 00:47:37 +0800992 val |= ARIZONA_MICB1_RATE;
993
Mark Brown544c7aa2013-01-29 18:44:41 +0800994 if (arizona->pdata.micbias[i].bypass)
995 val |= ARIZONA_MICB1_BYPASS;
996
Mark Brown3d91f822013-01-29 00:47:37 +0800997 regmap_update_bits(arizona->regmap,
998 ARIZONA_MIC_BIAS_CTRL_1 + i,
999 ARIZONA_MICB1_LVL_MASK |
Charles Keepax71d134b2014-09-24 10:37:11 +01001000 ARIZONA_MICB1_EXT_CAP |
Mark Brown3d91f822013-01-29 00:47:37 +08001001 ARIZONA_MICB1_DISCH |
Mark Brown544c7aa2013-01-29 18:44:41 +08001002 ARIZONA_MICB1_BYPASS |
Mark Brown3d91f822013-01-29 00:47:37 +08001003 ARIZONA_MICB1_RATE, val);
1004 }
1005
Mark Brown3cc72982012-06-19 16:31:53 +01001006 for (i = 0; i < ARIZONA_MAX_INPUT; i++) {
1007 /* Default for both is 0 so noop with defaults */
1008 val = arizona->pdata.dmic_ref[i]
1009 << ARIZONA_IN1_DMIC_SUP_SHIFT;
1010 val |= arizona->pdata.inmode[i] << ARIZONA_IN1_MODE_SHIFT;
1011
1012 regmap_update_bits(arizona->regmap,
1013 ARIZONA_IN1L_CONTROL + (i * 8),
1014 ARIZONA_IN1_DMIC_SUP_MASK |
1015 ARIZONA_IN1_MODE_MASK, val);
1016 }
1017
1018 for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) {
1019 /* Default is 0 so noop with defaults */
1020 if (arizona->pdata.out_mono[i])
1021 val = ARIZONA_OUT1_MONO;
1022 else
1023 val = 0;
1024
1025 regmap_update_bits(arizona->regmap,
1026 ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8),
1027 ARIZONA_OUT1_MONO, val);
1028 }
1029
Mark Brown3cc72982012-06-19 16:31:53 +01001030 for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) {
1031 if (arizona->pdata.spk_mute[i])
1032 regmap_update_bits(arizona->regmap,
Mark Brown2a51da02012-07-09 19:33:14 +01001033 ARIZONA_PDM_SPK1_CTRL_1 + (i * 2),
Mark Brown3cc72982012-06-19 16:31:53 +01001034 ARIZONA_SPK1_MUTE_ENDIAN_MASK |
1035 ARIZONA_SPK1_MUTE_SEQ1_MASK,
1036 arizona->pdata.spk_mute[i]);
1037
1038 if (arizona->pdata.spk_fmt[i])
1039 regmap_update_bits(arizona->regmap,
Mark Brown2a51da02012-07-09 19:33:14 +01001040 ARIZONA_PDM_SPK1_CTRL_2 + (i * 2),
Mark Brown3cc72982012-06-19 16:31:53 +01001041 ARIZONA_SPK1_FMT_MASK,
1042 arizona->pdata.spk_fmt[i]);
1043 }
1044
1045 /* Set up for interrupts */
1046 ret = arizona_irq_init(arizona);
1047 if (ret != 0)
Mark Brown59db9692012-07-09 00:31:36 +02001048 goto err_reset;
Mark Brown3cc72982012-06-19 16:31:53 +01001049
1050 arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error",
1051 arizona_clkgen_err, arizona);
1052 arizona_request_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, "Overclocked",
1053 arizona_overclocked, arizona);
1054 arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked",
1055 arizona_underclocked, arizona);
1056
1057 switch (arizona->type) {
1058 case WM5102:
1059 ret = mfd_add_devices(arizona->dev, -1, wm5102_devs,
Mark Brown0848c942012-09-11 15:16:36 +08001060 ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);
Mark Brown3cc72982012-06-19 16:31:53 +01001061 break;
Mark Browne102bef2012-07-10 12:37:58 +01001062 case WM5110:
Richard Fitzgeralde5d4ef02015-01-17 15:21:22 +00001063 case WM8280:
Mark Browne102bef2012-07-10 12:37:58 +01001064 ret = mfd_add_devices(arizona->dev, -1, wm5110_devs,
Charles Keepax78566af2012-11-20 13:46:19 +09001065 ARRAY_SIZE(wm5110_devs), NULL, 0, NULL);
Mark Browne102bef2012-07-10 12:37:58 +01001066 break;
Charles Keepaxdc7d4862013-06-13 09:43:29 +01001067 case WM8997:
1068 ret = mfd_add_devices(arizona->dev, -1, wm8997_devs,
1069 ARRAY_SIZE(wm8997_devs), NULL, 0, NULL);
1070 break;
Mark Brown3cc72982012-06-19 16:31:53 +01001071 }
1072
1073 if (ret != 0) {
1074 dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret);
1075 goto err_irq;
1076 }
1077
Rafael J. Wysocki48bb9fe2014-12-05 03:04:12 +01001078#ifdef CONFIG_PM
Mark Brown59db9692012-07-09 00:31:36 +02001079 regulator_disable(arizona->dcvdd);
1080#endif
1081
Mark Brown3cc72982012-06-19 16:31:53 +01001082 return 0;
1083
1084err_irq:
1085 arizona_irq_exit(arizona);
Mark Brown3cc72982012-06-19 16:31:53 +01001086err_reset:
Charles Keepax22298752015-05-11 13:58:02 +01001087 arizona_enable_reset(arizona);
Mark Brown59db9692012-07-09 00:31:36 +02001088 regulator_disable(arizona->dcvdd);
Mark Brown3cc72982012-06-19 16:31:53 +01001089err_enable:
Mark Brown3a36a0db2012-07-09 00:45:53 +02001090 regulator_bulk_disable(arizona->num_core_supplies,
Mark Brown3cc72982012-06-19 16:31:53 +01001091 arizona->core_supplies);
Charles Keepaxe6021512014-06-02 09:50:41 +01001092err_dcvdd:
1093 regulator_put(arizona->dcvdd);
Mark Brown3cc72982012-06-19 16:31:53 +01001094err_early:
1095 mfd_remove_devices(dev);
1096 return ret;
1097}
1098EXPORT_SYMBOL_GPL(arizona_dev_init);
1099
Bill Pemberton4740f732012-11-19 13:26:01 -05001100int arizona_dev_exit(struct arizona *arizona)
Mark Brown3cc72982012-06-19 16:31:53 +01001101{
Charles Keepaxb8040202014-06-02 09:50:39 +01001102 pm_runtime_disable(arizona->dev);
1103
Charles Keepaxdf6b3352014-06-02 09:50:40 +01001104 regulator_disable(arizona->dcvdd);
Charles Keepaxe6021512014-06-02 09:50:41 +01001105 regulator_put(arizona->dcvdd);
Charles Keepaxdf6b3352014-06-02 09:50:40 +01001106
Mark Brown3cc72982012-06-19 16:31:53 +01001107 mfd_remove_devices(arizona->dev);
1108 arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona);
1109 arizona_free_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, arizona);
1110 arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona);
Mark Brown3cc72982012-06-19 16:31:53 +01001111 arizona_irq_exit(arizona);
Charles Keepax22298752015-05-11 13:58:02 +01001112 arizona_enable_reset(arizona);
Charles Keepaxdf6b3352014-06-02 09:50:40 +01001113
Charles Keepax44202862014-06-02 09:50:42 +01001114 regulator_bulk_disable(arizona->num_core_supplies,
Mark Brown1d017b62013-03-26 12:16:26 +00001115 arizona->core_supplies);
Mark Brown3cc72982012-06-19 16:31:53 +01001116 return 0;
1117}
1118EXPORT_SYMBOL_GPL(arizona_dev_exit);