blob: 83f1c5a516d99a974bd399c6fad01a3bcb7a59df [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
Sylwester Nawrockicdd8da82016-09-02 16:52:46 +010013#include <linux/clk.h>
Mark Brown3cc72982012-06-19 16:31:53 +010014#include <linux/delay.h>
Mark Brown59db9692012-07-09 00:31:36 +020015#include <linux/err.h>
Charles Keepaxc1860462018-03-12 15:52:00 +000016#include <linux/gpio/consumer.h>
Mark Brown3cc72982012-06-19 16:31:53 +010017#include <linux/interrupt.h>
18#include <linux/mfd/core.h>
19#include <linux/module.h>
Mark Brownd7810092013-03-25 00:11:27 +000020#include <linux/of.h>
21#include <linux/of_device.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>
Richard Fitzgeraldae05ea362015-10-02 13:29:13 +010027#include <linux/platform_device.h>
Mark Brown3cc72982012-06-19 16:31:53 +010028
29#include <linux/mfd/arizona/core.h>
30#include <linux/mfd/arizona/registers.h>
31
32#include "arizona.h"
33
Charles Keepax3762aed2015-08-11 09:34:31 +010034static const char * const wm5102_core_supplies[] = {
Mark Brown3cc72982012-06-19 16:31:53 +010035 "AVDD",
36 "DBVDD1",
Mark Brown3cc72982012-06-19 16:31:53 +010037};
38
39int arizona_clk32k_enable(struct arizona *arizona)
40{
41 int ret = 0;
42
43 mutex_lock(&arizona->clk_lock);
44
45 arizona->clk32k_ref++;
46
Mark Brown247fa192013-03-19 14:47:47 +010047 if (arizona->clk32k_ref == 1) {
48 switch (arizona->pdata.clk32k_src) {
49 case ARIZONA_32KZ_MCLK1:
50 ret = pm_runtime_get_sync(arizona->dev);
51 if (ret != 0)
Sylwester Nawrockicdd8da82016-09-02 16:52:46 +010052 goto err_ref;
53 ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK1]);
54 if (ret != 0)
55 goto err_pm;
56 break;
57 case ARIZONA_32KZ_MCLK2:
58 ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK2]);
59 if (ret != 0)
60 goto err_ref;
Mark Brown247fa192013-03-19 14:47:47 +010061 break;
62 }
63
Mark Brown3cc72982012-06-19 16:31:53 +010064 ret = regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
65 ARIZONA_CLK_32K_ENA,
66 ARIZONA_CLK_32K_ENA);
Mark Brown247fa192013-03-19 14:47:47 +010067 }
Mark Brown3cc72982012-06-19 16:31:53 +010068
Sylwester Nawrockicdd8da82016-09-02 16:52:46 +010069err_pm:
70 pm_runtime_put_sync(arizona->dev);
71err_ref:
Mark Brown3cc72982012-06-19 16:31:53 +010072 if (ret != 0)
73 arizona->clk32k_ref--;
74
75 mutex_unlock(&arizona->clk_lock);
76
77 return ret;
78}
79EXPORT_SYMBOL_GPL(arizona_clk32k_enable);
80
81int arizona_clk32k_disable(struct arizona *arizona)
82{
Mark Brown3cc72982012-06-19 16:31:53 +010083 mutex_lock(&arizona->clk_lock);
84
85 BUG_ON(arizona->clk32k_ref <= 0);
86
87 arizona->clk32k_ref--;
88
Mark Brown247fa192013-03-19 14:47:47 +010089 if (arizona->clk32k_ref == 0) {
Mark Brown3cc72982012-06-19 16:31:53 +010090 regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
91 ARIZONA_CLK_32K_ENA, 0);
92
Mark Brown247fa192013-03-19 14:47:47 +010093 switch (arizona->pdata.clk32k_src) {
94 case ARIZONA_32KZ_MCLK1:
95 pm_runtime_put_sync(arizona->dev);
Sylwester Nawrockicdd8da82016-09-02 16:52:46 +010096 clk_disable_unprepare(arizona->mclk[ARIZONA_MCLK1]);
97 break;
98 case ARIZONA_32KZ_MCLK2:
99 clk_disable_unprepare(arizona->mclk[ARIZONA_MCLK2]);
Mark Brown247fa192013-03-19 14:47:47 +0100100 break;
101 }
102 }
103
Mark Brown3cc72982012-06-19 16:31:53 +0100104 mutex_unlock(&arizona->clk_lock);
105
Javier Martinez Canillasa260fba2015-09-29 13:26:02 +0200106 return 0;
Mark Brown3cc72982012-06-19 16:31:53 +0100107}
108EXPORT_SYMBOL_GPL(arizona_clk32k_disable);
109
110static irqreturn_t arizona_clkgen_err(int irq, void *data)
111{
112 struct arizona *arizona = data;
113
114 dev_err(arizona->dev, "CLKGEN error\n");
115
116 return IRQ_HANDLED;
117}
118
119static irqreturn_t arizona_underclocked(int irq, void *data)
120{
121 struct arizona *arizona = data;
122 unsigned int val;
123 int ret;
124
125 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_8,
126 &val);
127 if (ret != 0) {
128 dev_err(arizona->dev, "Failed to read underclock status: %d\n",
129 ret);
130 return IRQ_NONE;
131 }
132
133 if (val & ARIZONA_AIF3_UNDERCLOCKED_STS)
134 dev_err(arizona->dev, "AIF3 underclocked\n");
Mark Brown3cc72982012-06-19 16:31:53 +0100135 if (val & ARIZONA_AIF2_UNDERCLOCKED_STS)
Charles Keepax3ebef342012-11-20 13:46:20 +0900136 dev_err(arizona->dev, "AIF2 underclocked\n");
137 if (val & ARIZONA_AIF1_UNDERCLOCKED_STS)
Mark Brown3cc72982012-06-19 16:31:53 +0100138 dev_err(arizona->dev, "AIF1 underclocked\n");
Charles Keepax6e440d22014-07-15 11:21:49 +0100139 if (val & ARIZONA_ISRC3_UNDERCLOCKED_STS)
140 dev_err(arizona->dev, "ISRC3 underclocked\n");
Mark Brown3cc72982012-06-19 16:31:53 +0100141 if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS)
142 dev_err(arizona->dev, "ISRC2 underclocked\n");
143 if (val & ARIZONA_ISRC1_UNDERCLOCKED_STS)
144 dev_err(arizona->dev, "ISRC1 underclocked\n");
145 if (val & ARIZONA_FX_UNDERCLOCKED_STS)
146 dev_err(arizona->dev, "FX underclocked\n");
147 if (val & ARIZONA_ASRC_UNDERCLOCKED_STS)
148 dev_err(arizona->dev, "ASRC underclocked\n");
149 if (val & ARIZONA_DAC_UNDERCLOCKED_STS)
150 dev_err(arizona->dev, "DAC underclocked\n");
151 if (val & ARIZONA_ADC_UNDERCLOCKED_STS)
152 dev_err(arizona->dev, "ADC underclocked\n");
153 if (val & ARIZONA_MIXER_UNDERCLOCKED_STS)
Mark Brown648a9882013-01-28 00:32:53 +0800154 dev_err(arizona->dev, "Mixer dropped sample\n");
Mark Brown3cc72982012-06-19 16:31:53 +0100155
156 return IRQ_HANDLED;
157}
158
159static irqreturn_t arizona_overclocked(int irq, void *data)
160{
161 struct arizona *arizona = data;
Richard Fitzgerald6887b042015-07-03 16:16:35 +0100162 unsigned int val[3];
Mark Brown3cc72982012-06-19 16:31:53 +0100163 int ret;
Charles Keepax3762aed2015-08-11 09:34:31 +0100164
Mark Brown3cc72982012-06-19 16:31:53 +0100165 ret = regmap_bulk_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_6,
Richard Fitzgerald6887b042015-07-03 16:16:35 +0100166 &val[0], 3);
Mark Brown3cc72982012-06-19 16:31:53 +0100167 if (ret != 0) {
168 dev_err(arizona->dev, "Failed to read overclock status: %d\n",
169 ret);
170 return IRQ_NONE;
171 }
172
Richard Fitzgerald6887b042015-07-03 16:16:35 +0100173 switch (arizona->type) {
174 case WM8998:
175 case WM1814:
176 /* Some bits are shifted on WM8998,
177 * rearrange to match the standard bit layout
178 */
179 val[0] = ((val[0] & 0x60e0) >> 1) |
180 ((val[0] & 0x1e00) >> 2) |
181 (val[0] & 0x000f);
182 break;
183 default:
184 break;
185 }
186
Mark Brown3cc72982012-06-19 16:31:53 +0100187 if (val[0] & ARIZONA_PWM_OVERCLOCKED_STS)
188 dev_err(arizona->dev, "PWM overclocked\n");
189 if (val[0] & ARIZONA_FX_CORE_OVERCLOCKED_STS)
190 dev_err(arizona->dev, "FX core overclocked\n");
191 if (val[0] & ARIZONA_DAC_SYS_OVERCLOCKED_STS)
192 dev_err(arizona->dev, "DAC SYS overclocked\n");
193 if (val[0] & ARIZONA_DAC_WARP_OVERCLOCKED_STS)
194 dev_err(arizona->dev, "DAC WARP overclocked\n");
195 if (val[0] & ARIZONA_ADC_OVERCLOCKED_STS)
196 dev_err(arizona->dev, "ADC overclocked\n");
197 if (val[0] & ARIZONA_MIXER_OVERCLOCKED_STS)
198 dev_err(arizona->dev, "Mixer overclocked\n");
199 if (val[0] & ARIZONA_AIF3_SYNC_OVERCLOCKED_STS)
200 dev_err(arizona->dev, "AIF3 overclocked\n");
201 if (val[0] & ARIZONA_AIF2_SYNC_OVERCLOCKED_STS)
202 dev_err(arizona->dev, "AIF2 overclocked\n");
203 if (val[0] & ARIZONA_AIF1_SYNC_OVERCLOCKED_STS)
204 dev_err(arizona->dev, "AIF1 overclocked\n");
205 if (val[0] & ARIZONA_PAD_CTRL_OVERCLOCKED_STS)
206 dev_err(arizona->dev, "Pad control overclocked\n");
207
208 if (val[1] & ARIZONA_SLIMBUS_SUBSYS_OVERCLOCKED_STS)
209 dev_err(arizona->dev, "Slimbus subsystem overclocked\n");
210 if (val[1] & ARIZONA_SLIMBUS_ASYNC_OVERCLOCKED_STS)
211 dev_err(arizona->dev, "Slimbus async overclocked\n");
212 if (val[1] & ARIZONA_SLIMBUS_SYNC_OVERCLOCKED_STS)
213 dev_err(arizona->dev, "Slimbus sync overclocked\n");
214 if (val[1] & ARIZONA_ASRC_ASYNC_SYS_OVERCLOCKED_STS)
215 dev_err(arizona->dev, "ASRC async system overclocked\n");
216 if (val[1] & ARIZONA_ASRC_ASYNC_WARP_OVERCLOCKED_STS)
217 dev_err(arizona->dev, "ASRC async WARP overclocked\n");
218 if (val[1] & ARIZONA_ASRC_SYNC_SYS_OVERCLOCKED_STS)
219 dev_err(arizona->dev, "ASRC sync system overclocked\n");
220 if (val[1] & ARIZONA_ASRC_SYNC_WARP_OVERCLOCKED_STS)
221 dev_err(arizona->dev, "ASRC sync WARP overclocked\n");
222 if (val[1] & ARIZONA_ADSP2_1_OVERCLOCKED_STS)
223 dev_err(arizona->dev, "DSP1 overclocked\n");
Charles Keepax6e440d22014-07-15 11:21:49 +0100224 if (val[1] & ARIZONA_ISRC3_OVERCLOCKED_STS)
225 dev_err(arizona->dev, "ISRC3 overclocked\n");
Mark Brown3cc72982012-06-19 16:31:53 +0100226 if (val[1] & ARIZONA_ISRC2_OVERCLOCKED_STS)
227 dev_err(arizona->dev, "ISRC2 overclocked\n");
228 if (val[1] & ARIZONA_ISRC1_OVERCLOCKED_STS)
229 dev_err(arizona->dev, "ISRC1 overclocked\n");
230
Richard Fitzgerald6887b042015-07-03 16:16:35 +0100231 if (val[2] & ARIZONA_SPDIF_OVERCLOCKED_STS)
232 dev_err(arizona->dev, "SPDIF overclocked\n");
233
Mark Brown3cc72982012-06-19 16:31:53 +0100234 return IRQ_HANDLED;
235}
236
Charles Keepaxef84f882017-03-15 14:58:38 +0000237#define ARIZONA_REG_POLL_DELAY_US 7500
238
Charles Keepax9d53dfd2013-03-26 17:38:45 +0000239static int arizona_poll_reg(struct arizona *arizona,
Charles Keepaxef84f882017-03-15 14:58:38 +0000240 int timeout_ms, unsigned int reg,
Charles Keepax9d53dfd2013-03-26 17:38:45 +0000241 unsigned int mask, unsigned int target)
242{
243 unsigned int val = 0;
Charles Keepaxef84f882017-03-15 14:58:38 +0000244 int ret;
Charles Keepax9d53dfd2013-03-26 17:38:45 +0000245
Charles Keepaxef84f882017-03-15 14:58:38 +0000246 ret = regmap_read_poll_timeout(arizona->regmap,
Charles Keepax27fef9f2017-06-06 09:46:33 +0100247 reg, val, ((val & mask) == target),
Charles Keepaxef84f882017-03-15 14:58:38 +0000248 ARIZONA_REG_POLL_DELAY_US,
249 timeout_ms * 1000);
250 if (ret)
251 dev_err(arizona->dev, "Polling reg 0x%x timed out: %x\n",
252 reg, val);
Charles Keepax9d53dfd2013-03-26 17:38:45 +0000253
Charles Keepaxef84f882017-03-15 14:58:38 +0000254 return ret;
Charles Keepax9d53dfd2013-03-26 17:38:45 +0000255}
256
Mark Brown3cc72982012-06-19 16:31:53 +0100257static int arizona_wait_for_boot(struct arizona *arizona)
258{
Charles Keepax9d53dfd2013-03-26 17:38:45 +0000259 int ret;
Mark Brown3cc72982012-06-19 16:31:53 +0100260
261 /*
262 * We can't use an interrupt as we need to runtime resume to do so,
263 * we won't race with the interrupt handler as it'll be blocked on
264 * runtime resume.
265 */
Charles Keepaxef84f882017-03-15 14:58:38 +0000266 ret = arizona_poll_reg(arizona, 30, ARIZONA_INTERRUPT_RAW_STATUS_5,
Charles Keepax9d53dfd2013-03-26 17:38:45 +0000267 ARIZONA_BOOT_DONE_STS, ARIZONA_BOOT_DONE_STS);
Mark Brown3cc72982012-06-19 16:31:53 +0100268
Charles Keepax9d53dfd2013-03-26 17:38:45 +0000269 if (!ret)
Mark Brown3cc72982012-06-19 16:31:53 +0100270 regmap_write(arizona->regmap, ARIZONA_INTERRUPT_STATUS_5,
271 ARIZONA_BOOT_DONE_STS);
Mark Brown3cc72982012-06-19 16:31:53 +0100272
273 pm_runtime_mark_last_busy(arizona->dev);
274
Charles Keepax9d53dfd2013-03-26 17:38:45 +0000275 return ret;
Mark Brown3cc72982012-06-19 16:31:53 +0100276}
277
Charles Keepax22298752015-05-11 13:58:02 +0100278static inline void arizona_enable_reset(struct arizona *arizona)
279{
280 if (arizona->pdata.reset)
Charles Keepaxc1860462018-03-12 15:52:00 +0000281 gpiod_set_raw_value_cansleep(arizona->pdata.reset, 0);
Charles Keepax22298752015-05-11 13:58:02 +0100282}
283
284static void arizona_disable_reset(struct arizona *arizona)
285{
286 if (arizona->pdata.reset) {
Charles Keepax121c0752015-05-11 13:58:10 +0100287 switch (arizona->type) {
288 case WM5110:
289 case WM8280:
290 /* Meet requirements for minimum reset duration */
Lee Jonesb79a9802015-10-28 12:42:30 +0000291 usleep_range(5000, 10000);
Charles Keepax121c0752015-05-11 13:58:10 +0100292 break;
293 default:
294 break;
295 }
296
Charles Keepaxc1860462018-03-12 15:52:00 +0000297 gpiod_set_raw_value_cansleep(arizona->pdata.reset, 1);
Lee Jonesb79a9802015-10-28 12:42:30 +0000298 usleep_range(1000, 5000);
Charles Keepax22298752015-05-11 13:58:02 +0100299 }
300}
301
Charles Keepax3850e3e2015-05-11 13:58:05 +0100302struct arizona_sysclk_state {
303 unsigned int fll;
304 unsigned int sysclk;
305};
306
307static int arizona_enable_freerun_sysclk(struct arizona *arizona,
308 struct arizona_sysclk_state *state)
Charles Keepaxe80436b2013-03-26 18:46:15 +0000309{
Charles Keepaxe80436b2013-03-26 18:46:15 +0000310 int ret, err;
311
Charles Keepaxe80436b2013-03-26 18:46:15 +0000312 /* Cache existing FLL and SYSCLK settings */
Charles Keepax3850e3e2015-05-11 13:58:05 +0100313 ret = regmap_read(arizona->regmap, ARIZONA_FLL1_CONTROL_1, &state->fll);
Charles Keepax0be068a2015-05-11 13:58:04 +0100314 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000315 dev_err(arizona->dev, "Failed to cache FLL settings: %d\n",
316 ret);
317 return ret;
318 }
Charles Keepax3850e3e2015-05-11 13:58:05 +0100319 ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1,
320 &state->sysclk);
Charles Keepax0be068a2015-05-11 13:58:04 +0100321 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000322 dev_err(arizona->dev, "Failed to cache SYSCLK settings: %d\n",
323 ret);
324 return ret;
325 }
326
327 /* Start up SYSCLK using the FLL in free running mode */
328 ret = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1,
329 ARIZONA_FLL1_ENA | ARIZONA_FLL1_FREERUN);
Charles Keepax0be068a2015-05-11 13:58:04 +0100330 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000331 dev_err(arizona->dev,
332 "Failed to start FLL in freerunning mode: %d\n",
333 ret);
334 return ret;
335 }
Charles Keepaxef84f882017-03-15 14:58:38 +0000336 ret = arizona_poll_reg(arizona, 180, ARIZONA_INTERRUPT_RAW_STATUS_5,
Charles Keepaxe80436b2013-03-26 18:46:15 +0000337 ARIZONA_FLL1_CLOCK_OK_STS,
338 ARIZONA_FLL1_CLOCK_OK_STS);
Charles Keepaxde4ea102017-03-15 14:58:36 +0000339 if (ret)
Charles Keepaxe80436b2013-03-26 18:46:15 +0000340 goto err_fll;
Charles Keepaxe80436b2013-03-26 18:46:15 +0000341
342 ret = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, 0x0144);
Charles Keepax0be068a2015-05-11 13:58:04 +0100343 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000344 dev_err(arizona->dev, "Failed to start SYSCLK: %d\n", ret);
345 goto err_fll;
346 }
347
Charles Keepax3850e3e2015-05-11 13:58:05 +0100348 return 0;
349
350err_fll:
351 err = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, state->fll);
352 if (err)
353 dev_err(arizona->dev,
354 "Failed to re-apply old FLL settings: %d\n", err);
355
356 return ret;
357}
358
359static int arizona_disable_freerun_sysclk(struct arizona *arizona,
360 struct arizona_sysclk_state *state)
361{
362 int ret;
363
364 ret = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1,
365 state->sysclk);
366 if (ret) {
367 dev_err(arizona->dev,
368 "Failed to re-apply old SYSCLK settings: %d\n", ret);
369 return ret;
370 }
371
372 ret = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, state->fll);
373 if (ret) {
374 dev_err(arizona->dev,
375 "Failed to re-apply old FLL settings: %d\n", ret);
376 return ret;
377 }
378
379 return 0;
380}
381
382static int wm5102_apply_hardware_patch(struct arizona *arizona)
383{
384 struct arizona_sysclk_state state;
385 int err, ret;
386
387 ret = arizona_enable_freerun_sysclk(arizona, &state);
388 if (ret)
389 return ret;
390
Charles Keepaxe80436b2013-03-26 18:46:15 +0000391 /* Start the write sequencer and wait for it to finish */
392 ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0,
Charles Keepax0be068a2015-05-11 13:58:04 +0100393 ARIZONA_WSEQ_ENA | ARIZONA_WSEQ_START | 160);
394 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000395 dev_err(arizona->dev, "Failed to start write sequencer: %d\n",
396 ret);
Charles Keepax3850e3e2015-05-11 13:58:05 +0100397 goto err;
Charles Keepaxe80436b2013-03-26 18:46:15 +0000398 }
Charles Keepax3850e3e2015-05-11 13:58:05 +0100399
Charles Keepaxef84f882017-03-15 14:58:38 +0000400 ret = arizona_poll_reg(arizona, 30, ARIZONA_WRITE_SEQUENCER_CTRL_1,
Charles Keepaxe80436b2013-03-26 18:46:15 +0000401 ARIZONA_WSEQ_BUSY, 0);
Charles Keepaxde4ea102017-03-15 14:58:36 +0000402 if (ret)
Charles Keepaxe80436b2013-03-26 18:46:15 +0000403 regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0,
Charles Keepax0be068a2015-05-11 13:58:04 +0100404 ARIZONA_WSEQ_ABORT);
Charles Keepaxe80436b2013-03-26 18:46:15 +0000405
Charles Keepax3850e3e2015-05-11 13:58:05 +0100406err:
407 err = arizona_disable_freerun_sysclk(arizona, &state);
Charles Keepaxe80436b2013-03-26 18:46:15 +0000408
Charles Keepax0be068a2015-05-11 13:58:04 +0100409 return ret ?: err;
Charles Keepaxe80436b2013-03-26 18:46:15 +0000410}
411
Charles Keepax882bc462015-05-11 13:58:06 +0100412/*
413 * Register patch to some of the CODECs internal write sequences
414 * to ensure a clean exit from the low power sleep state.
415 */
Nariman Poushin8019ff62015-07-16 16:36:21 +0100416static const struct reg_sequence wm5110_sleep_patch[] = {
Charles Keepax882bc462015-05-11 13:58:06 +0100417 { 0x337A, 0xC100 },
418 { 0x337B, 0x0041 },
419 { 0x3300, 0xA210 },
420 { 0x3301, 0x050C },
421};
422
423static int wm5110_apply_sleep_patch(struct arizona *arizona)
424{
425 struct arizona_sysclk_state state;
426 int err, ret;
427
428 ret = arizona_enable_freerun_sysclk(arizona, &state);
429 if (ret)
430 return ret;
431
432 ret = regmap_multi_reg_write_bypassed(arizona->regmap,
433 wm5110_sleep_patch,
434 ARRAY_SIZE(wm5110_sleep_patch));
435
436 err = arizona_disable_freerun_sysclk(arizona, &state);
437
438 return ret ?: err;
439}
440
Charles Keepax1c1c6bb2015-05-11 13:58:03 +0100441static int wm5102_clear_write_sequencer(struct arizona *arizona)
442{
443 int ret;
444
445 ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_3,
446 0x0);
447 if (ret) {
448 dev_err(arizona->dev,
449 "Failed to clear write sequencer state: %d\n", ret);
450 return ret;
451 }
452
453 arizona_enable_reset(arizona);
454 regulator_disable(arizona->dcvdd);
455
456 msleep(20);
457
458 ret = regulator_enable(arizona->dcvdd);
459 if (ret) {
460 dev_err(arizona->dev, "Failed to re-enable DCVDD: %d\n", ret);
461 return ret;
462 }
463 arizona_disable_reset(arizona);
464
465 return 0;
466}
467
Rafael J. Wysocki48bb9fe2014-12-05 03:04:12 +0100468#ifdef CONFIG_PM
Richard Fitzgeralde7811142015-10-02 13:29:10 +0100469static int arizona_isolate_dcvdd(struct arizona *arizona)
470{
471 int ret;
472
473 ret = regmap_update_bits(arizona->regmap,
474 ARIZONA_ISOLATION_CONTROL,
475 ARIZONA_ISOLATE_DCVDD1,
476 ARIZONA_ISOLATE_DCVDD1);
477 if (ret != 0)
478 dev_err(arizona->dev, "Failed to isolate DCVDD: %d\n", ret);
479
480 return ret;
481}
482
483static int arizona_connect_dcvdd(struct arizona *arizona)
484{
485 int ret;
486
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, "Failed to connect DCVDD: %d\n", ret);
492
493 return ret;
494}
495
Richard Fitzgeralde3424272015-10-02 13:29:11 +0100496static int arizona_is_jack_det_active(struct arizona *arizona)
497{
498 unsigned int val;
499 int ret;
500
501 ret = regmap_read(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, &val);
502 if (ret) {
503 dev_err(arizona->dev,
504 "Failed to check jack det status: %d\n", ret);
505 return ret;
506 } else if (val & ARIZONA_JD1_ENA) {
507 return 1;
508 } else {
509 return 0;
510 }
511}
512
Mark Brown3cc72982012-06-19 16:31:53 +0100513static int arizona_runtime_resume(struct device *dev)
514{
515 struct arizona *arizona = dev_get_drvdata(dev);
516 int ret;
517
Mark Brown508c8292012-07-20 17:09:12 +0100518 dev_dbg(arizona->dev, "Leaving AoD mode\n");
519
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100520 if (arizona->has_fully_powered_off) {
521 dev_dbg(arizona->dev, "Re-enabling core supplies\n");
522
523 ret = regulator_bulk_enable(arizona->num_core_supplies,
524 arizona->core_supplies);
525 if (ret) {
526 dev_err(dev, "Failed to enable core supplies: %d\n",
527 ret);
528 return ret;
529 }
530 }
531
Mark Brown59db9692012-07-09 00:31:36 +0200532 ret = regulator_enable(arizona->dcvdd);
533 if (ret != 0) {
534 dev_err(arizona->dev, "Failed to enable DCVDD: %d\n", ret);
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100535 if (arizona->has_fully_powered_off)
536 regulator_bulk_disable(arizona->num_core_supplies,
537 arizona->core_supplies);
Mark Brown59db9692012-07-09 00:31:36 +0200538 return ret;
539 }
Mark Brown3cc72982012-06-19 16:31:53 +0100540
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100541 if (arizona->has_fully_powered_off) {
542 arizona_disable_reset(arizona);
543 enable_irq(arizona->irq);
544 arizona->has_fully_powered_off = false;
545 }
546
Mark Brown3cc72982012-06-19 16:31:53 +0100547 regcache_cache_only(arizona->regmap, false);
548
Charles Keepax4c9bb8b2013-03-26 18:01:49 +0000549 switch (arizona->type) {
550 case WM5102:
Mark Brown59274672013-04-23 19:44:16 +0100551 if (arizona->external_dcvdd) {
Richard Fitzgeralde7811142015-10-02 13:29:10 +0100552 ret = arizona_connect_dcvdd(arizona);
553 if (ret != 0)
Mark Brown59274672013-04-23 19:44:16 +0100554 goto err;
Mark Brown59274672013-04-23 19:44:16 +0100555 }
556
Charles Keepax4c9bb8b2013-03-26 18:01:49 +0000557 ret = wm5102_patch(arizona);
558 if (ret != 0) {
559 dev_err(arizona->dev, "Failed to apply patch: %d\n",
560 ret);
561 goto err;
562 }
Charles Keepaxe80436b2013-03-26 18:46:15 +0000563
Charles Keepax0be068a2015-05-11 13:58:04 +0100564 ret = wm5102_apply_hardware_patch(arizona);
565 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +0000566 dev_err(arizona->dev,
567 "Failed to apply hardware patch: %d\n",
568 ret);
569 goto err;
570 }
571 break;
Charles Keepax96129a02015-05-11 13:58:08 +0100572 case WM5110:
573 case WM8280:
574 ret = arizona_wait_for_boot(arizona);
575 if (ret)
576 goto err;
577
578 if (arizona->external_dcvdd) {
Richard Fitzgeralde7811142015-10-02 13:29:10 +0100579 ret = arizona_connect_dcvdd(arizona);
580 if (ret != 0)
Charles Keepax96129a02015-05-11 13:58:08 +0100581 goto err;
Charles Keepax96129a02015-05-11 13:58:08 +0100582 } else {
583 /*
584 * As this is only called for the internal regulator
585 * (where we know voltage ranges available) it is ok
586 * to request an exact range.
587 */
588 ret = regulator_set_voltage(arizona->dcvdd,
589 1200000, 1200000);
590 if (ret < 0) {
591 dev_err(arizona->dev,
592 "Failed to set resume voltage: %d\n",
593 ret);
594 goto err;
595 }
596 }
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100597
598 ret = wm5110_apply_sleep_patch(arizona);
599 if (ret) {
600 dev_err(arizona->dev,
601 "Failed to re-apply sleep patch: %d\n",
602 ret);
603 goto err;
604 }
Charles Keepax96129a02015-05-11 13:58:08 +0100605 break;
Richard Fitzgeraldea1f3332015-11-03 15:08:32 +0000606 case WM1831:
607 case CS47L24:
608 ret = arizona_wait_for_boot(arizona);
609 if (ret != 0)
610 goto err;
611 break;
Charles Keepaxe80436b2013-03-26 18:46:15 +0000612 default:
Charles Keepax12bb68e2013-03-27 09:49:40 +0000613 ret = arizona_wait_for_boot(arizona);
Charles Keepax3762aed2015-08-11 09:34:31 +0100614 if (ret != 0)
Charles Keepax12bb68e2013-03-27 09:49:40 +0000615 goto err;
Charles Keepax12bb68e2013-03-27 09:49:40 +0000616
Mark Brown59274672013-04-23 19:44:16 +0100617 if (arizona->external_dcvdd) {
Richard Fitzgeralde7811142015-10-02 13:29:10 +0100618 ret = arizona_connect_dcvdd(arizona);
619 if (ret != 0)
Mark Brown59274672013-04-23 19:44:16 +0100620 goto err;
Mark Brown59274672013-04-23 19:44:16 +0100621 }
Charles Keepaxe80436b2013-03-26 18:46:15 +0000622 break;
Charles Keepax4c9bb8b2013-03-26 18:01:49 +0000623 }
624
Mark Brown9270bdf2013-01-04 17:16:12 +0000625 ret = regcache_sync(arizona->regmap);
626 if (ret != 0) {
627 dev_err(arizona->dev, "Failed to restore register cache\n");
Mark Brown4816bd12013-01-14 15:50:38 +0900628 goto err;
Mark Brown9270bdf2013-01-04 17:16:12 +0000629 }
Mark Brown3cc72982012-06-19 16:31:53 +0100630
631 return 0;
Mark Brown4816bd12013-01-14 15:50:38 +0900632
633err:
634 regcache_cache_only(arizona->regmap, true);
635 regulator_disable(arizona->dcvdd);
636 return ret;
Mark Brown3cc72982012-06-19 16:31:53 +0100637}
638
639static int arizona_runtime_suspend(struct device *dev)
640{
641 struct arizona *arizona = dev_get_drvdata(dev);
Dan Carpentera05950a2015-10-19 13:18:05 +0300642 int jd_active = 0;
Mark Brown59274672013-04-23 19:44:16 +0100643 int ret;
Mark Brown3cc72982012-06-19 16:31:53 +0100644
Mark Brown508c8292012-07-20 17:09:12 +0100645 dev_dbg(arizona->dev, "Entering AoD mode\n");
646
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100647 switch (arizona->type) {
648 case WM5110:
649 case WM8280:
Richard Fitzgeralde3424272015-10-02 13:29:11 +0100650 jd_active = arizona_is_jack_det_active(arizona);
651 if (jd_active < 0)
652 return jd_active;
653
Richard Fitzgeralde7811142015-10-02 13:29:10 +0100654 if (arizona->external_dcvdd) {
655 ret = arizona_isolate_dcvdd(arizona);
656 if (ret != 0)
657 return ret;
658 } else {
659 /*
660 * As this is only called for the internal regulator
661 * (where we know voltage ranges available) it is ok
662 * to request an exact range.
663 */
664 ret = regulator_set_voltage(arizona->dcvdd,
665 1175000, 1175000);
666 if (ret < 0) {
667 dev_err(arizona->dev,
668 "Failed to set suspend voltage: %d\n",
669 ret);
670 return ret;
671 }
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100672 }
673 break;
674 case WM5102:
Richard Fitzgeralde3424272015-10-02 13:29:11 +0100675 jd_active = arizona_is_jack_det_active(arizona);
676 if (jd_active < 0)
677 return jd_active;
678
Richard Fitzgeralde7811142015-10-02 13:29:10 +0100679 if (arizona->external_dcvdd) {
680 ret = arizona_isolate_dcvdd(arizona);
681 if (ret != 0)
682 return ret;
683 }
684
Richard Fitzgeralde3424272015-10-02 13:29:11 +0100685 if (!jd_active) {
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100686 ret = regmap_write(arizona->regmap,
687 ARIZONA_WRITE_SEQUENCER_CTRL_3, 0x0);
688 if (ret) {
Charles Keepax96129a02015-05-11 13:58:08 +0100689 dev_err(arizona->dev,
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100690 "Failed to clear write sequencer: %d\n",
Charles Keepax96129a02015-05-11 13:58:08 +0100691 ret);
692 return ret;
693 }
Charles Keepax96129a02015-05-11 13:58:08 +0100694 }
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100695 break;
Richard Fitzgeraldea1f3332015-11-03 15:08:32 +0000696 case WM1831:
697 case CS47L24:
698 break;
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100699 default:
Richard Fitzgeralde3424272015-10-02 13:29:11 +0100700 jd_active = arizona_is_jack_det_active(arizona);
701 if (jd_active < 0)
702 return jd_active;
703
Richard Fitzgeralde7811142015-10-02 13:29:10 +0100704 if (arizona->external_dcvdd) {
705 ret = arizona_isolate_dcvdd(arizona);
706 if (ret != 0)
707 return ret;
708 }
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100709 break;
Mark Brown59274672013-04-23 19:44:16 +0100710 }
711
Mark Brown59db9692012-07-09 00:31:36 +0200712 regcache_cache_only(arizona->regmap, true);
713 regcache_mark_dirty(arizona->regmap);
Charles Keepaxe293e84722013-08-06 17:18:35 +0100714 regulator_disable(arizona->dcvdd);
Mark Brown3cc72982012-06-19 16:31:53 +0100715
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100716 /* Allow us to completely power down if no jack detection */
Richard Fitzgeralde3424272015-10-02 13:29:11 +0100717 if (!jd_active) {
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100718 dev_dbg(arizona->dev, "Fully powering off\n");
719
720 arizona->has_fully_powered_off = true;
721
Charles Keepax11150922015-06-14 15:41:49 +0100722 disable_irq_nosync(arizona->irq);
Charles Keepaxe6cb7342015-05-11 13:58:09 +0100723 arizona_enable_reset(arizona);
724 regulator_bulk_disable(arizona->num_core_supplies,
725 arizona->core_supplies);
726 }
727
Mark Brown3cc72982012-06-19 16:31:53 +0100728 return 0;
729}
730#endif
731
Mark Browndc781d02013-01-27 12:07:32 +0800732#ifdef CONFIG_PM_SLEEP
Mark Brown67c99292013-04-10 12:40:26 +0100733static int arizona_suspend(struct device *dev)
734{
735 struct arizona *arizona = dev_get_drvdata(dev);
736
737 dev_dbg(arizona->dev, "Suspend, disabling IRQ\n");
738 disable_irq(arizona->irq);
739
740 return 0;
741}
742
Charles Keepax3612b272016-08-30 10:33:10 +0100743static int arizona_suspend_noirq(struct device *dev)
Mark Brown67c99292013-04-10 12:40:26 +0100744{
745 struct arizona *arizona = dev_get_drvdata(dev);
746
747 dev_dbg(arizona->dev, "Late suspend, reenabling IRQ\n");
748 enable_irq(arizona->irq);
749
750 return 0;
751}
752
Mark Browndc781d02013-01-27 12:07:32 +0800753static int arizona_resume_noirq(struct device *dev)
754{
755 struct arizona *arizona = dev_get_drvdata(dev);
756
757 dev_dbg(arizona->dev, "Early resume, disabling IRQ\n");
758 disable_irq(arizona->irq);
759
760 return 0;
761}
762
763static int arizona_resume(struct device *dev)
764{
765 struct arizona *arizona = dev_get_drvdata(dev);
766
Charles Keepax3612b272016-08-30 10:33:10 +0100767 dev_dbg(arizona->dev, "Resume, reenabling IRQ\n");
Mark Browndc781d02013-01-27 12:07:32 +0800768 enable_irq(arizona->irq);
769
770 return 0;
771}
772#endif
773
Mark Brown3cc72982012-06-19 16:31:53 +0100774const struct dev_pm_ops arizona_pm_ops = {
775 SET_RUNTIME_PM_OPS(arizona_runtime_suspend,
776 arizona_runtime_resume,
777 NULL)
Mark Brown67c99292013-04-10 12:40:26 +0100778 SET_SYSTEM_SLEEP_PM_OPS(arizona_suspend, arizona_resume)
Charles Keepax3612b272016-08-30 10:33:10 +0100779 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(arizona_suspend_noirq,
780 arizona_resume_noirq)
Mark Brown3cc72982012-06-19 16:31:53 +0100781};
782EXPORT_SYMBOL_GPL(arizona_pm_ops);
783
Mark Brownd7810092013-03-25 00:11:27 +0000784#ifdef CONFIG_OF
Lee Jones942786e2014-07-02 14:28:46 +0100785unsigned long arizona_of_get_type(struct device *dev)
Mark Brownd7810092013-03-25 00:11:27 +0000786{
787 const struct of_device_id *id = of_match_device(arizona_of_match, dev);
788
789 if (id)
Lee Jones942786e2014-07-02 14:28:46 +0100790 return (unsigned long)id->data;
Mark Brownd7810092013-03-25 00:11:27 +0000791 else
792 return 0;
793}
794EXPORT_SYMBOL_GPL(arizona_of_get_type);
795
796static int arizona_of_get_core_pdata(struct arizona *arizona)
797{
Charles Keepaxe4fcb1d2014-04-16 10:01:37 +0100798 struct arizona_pdata *pdata = &arizona->pdata;
Mark Brownd7810092013-03-25 00:11:27 +0000799 int ret, i;
800
Charles Keepaxc1860462018-03-12 15:52:00 +0000801 /* Handle old non-standard DT binding */
802 pdata->reset = devm_gpiod_get_from_of_node(arizona->dev,
803 arizona->dev->of_node,
804 "wlf,reset", 0,
805 GPIOD_OUT_LOW,
806 "arizona /RESET");
807 if (IS_ERR(pdata->reset)) {
808 ret = PTR_ERR(pdata->reset);
Charles Keepax1961531d2016-09-20 16:30:13 +0100809
Charles Keepaxc1860462018-03-12 15:52:00 +0000810 /*
811 * Reset missing will be caught when other binding is read
812 * but all other errors imply this binding is in use but has
813 * encountered a problem so should be handled.
814 */
815 if (ret == -EPROBE_DEFER)
816 return ret;
817 else if (ret != -ENOENT && ret != -ENOSYS)
818 dev_err(arizona->dev, "Reset GPIO malformed: %d\n",
819 ret);
820
821 pdata->reset = NULL;
Charles Keepax1961531d2016-09-20 16:30:13 +0100822 }
Mark Brownd7810092013-03-25 00:11:27 +0000823
824 ret = of_property_read_u32_array(arizona->dev->of_node,
825 "wlf,gpio-defaults",
Charles Keepax3762aed2015-08-11 09:34:31 +0100826 pdata->gpio_defaults,
827 ARRAY_SIZE(pdata->gpio_defaults));
Mark Brownd7810092013-03-25 00:11:27 +0000828 if (ret >= 0) {
829 /*
830 * All values are literal except out of range values
831 * which are chip default, translate into platform
832 * data which uses 0 as chip default and out of range
833 * as zero.
834 */
Charles Keepax3762aed2015-08-11 09:34:31 +0100835 for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
836 if (pdata->gpio_defaults[i] > 0xffff)
837 pdata->gpio_defaults[i] = 0;
838 else if (pdata->gpio_defaults[i] == 0)
839 pdata->gpio_defaults[i] = 0x10000;
Mark Brownd7810092013-03-25 00:11:27 +0000840 }
841 } else {
842 dev_err(arizona->dev, "Failed to parse GPIO defaults: %d\n",
843 ret);
844 }
845
846 return 0;
847}
848
849const struct of_device_id arizona_of_match[] = {
850 { .compatible = "wlf,wm5102", .data = (void *)WM5102 },
851 { .compatible = "wlf,wm5110", .data = (void *)WM5110 },
Richard Fitzgeralde5d4ef02015-01-17 15:21:22 +0000852 { .compatible = "wlf,wm8280", .data = (void *)WM8280 },
Charles Keepaxdc7d4862013-06-13 09:43:29 +0100853 { .compatible = "wlf,wm8997", .data = (void *)WM8997 },
Richard Fitzgerald6887b042015-07-03 16:16:35 +0100854 { .compatible = "wlf,wm8998", .data = (void *)WM8998 },
855 { .compatible = "wlf,wm1814", .data = (void *)WM1814 },
Richard Fitzgeraldea1f3332015-11-03 15:08:32 +0000856 { .compatible = "wlf,wm1831", .data = (void *)WM1831 },
857 { .compatible = "cirrus,cs47l24", .data = (void *)CS47L24 },
Mark Brownd7810092013-03-25 00:11:27 +0000858 {},
859};
860EXPORT_SYMBOL_GPL(arizona_of_match);
861#else
862static inline int arizona_of_get_core_pdata(struct arizona *arizona)
863{
864 return 0;
865}
866#endif
867
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100868static const struct mfd_cell early_devs[] = {
Mark Brown3cc72982012-06-19 16:31:53 +0100869 { .name = "arizona-ldo1" },
870};
871
Charles Keepax3762aed2015-08-11 09:34:31 +0100872static const char * const wm5102_supplies[] = {
Charles Keepax5fc6c392014-07-25 16:24:44 +0100873 "MICVDD",
Charles Keepax32dadef2013-10-15 20:14:22 +0100874 "DBVDD2",
875 "DBVDD3",
876 "CPVDD",
877 "SPKVDDL",
878 "SPKVDDR",
879};
880
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100881static const struct mfd_cell wm5102_devs[] = {
Mark Brownd7768112012-12-20 15:38:03 +0000882 { .name = "arizona-micsupp" },
Charles Keepaxf83c2182016-04-15 13:18:47 +0100883 { .name = "arizona-gpio" },
Charles Keepax5fc6c392014-07-25 16:24:44 +0100884 {
885 .name = "arizona-extcon",
886 .parent_supplies = wm5102_supplies,
887 .num_parent_supplies = 1, /* We only need MICVDD */
888 },
Mark Brown503b1ca2012-11-27 17:36:38 +0000889 { .name = "arizona-haptics" },
Mark Brown3cc72982012-06-19 16:31:53 +0100890 { .name = "arizona-pwm" },
Charles Keepax32dadef2013-10-15 20:14:22 +0100891 {
892 .name = "wm5102-codec",
893 .parent_supplies = wm5102_supplies,
894 .num_parent_supplies = ARRAY_SIZE(wm5102_supplies),
895 },
Mark Brown3cc72982012-06-19 16:31:53 +0100896};
897
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100898static const struct mfd_cell wm5110_devs[] = {
Mark Brownd7768112012-12-20 15:38:03 +0000899 { .name = "arizona-micsupp" },
Charles Keepaxf83c2182016-04-15 13:18:47 +0100900 { .name = "arizona-gpio" },
Charles Keepax5fc6c392014-07-25 16:24:44 +0100901 {
902 .name = "arizona-extcon",
903 .parent_supplies = wm5102_supplies,
904 .num_parent_supplies = 1, /* We only need MICVDD */
905 },
Mark Brown503b1ca2012-11-27 17:36:38 +0000906 { .name = "arizona-haptics" },
Mark Browne102bef2012-07-10 12:37:58 +0100907 { .name = "arizona-pwm" },
Charles Keepax32dadef2013-10-15 20:14:22 +0100908 {
909 .name = "wm5110-codec",
910 .parent_supplies = wm5102_supplies,
911 .num_parent_supplies = ARRAY_SIZE(wm5102_supplies),
912 },
913};
914
Richard Fitzgeraldea1f3332015-11-03 15:08:32 +0000915static const char * const cs47l24_supplies[] = {
916 "MICVDD",
917 "CPVDD",
918 "SPKVDD",
919};
920
921static const struct mfd_cell cs47l24_devs[] = {
922 { .name = "arizona-gpio" },
923 { .name = "arizona-haptics" },
924 { .name = "arizona-pwm" },
925 {
926 .name = "cs47l24-codec",
927 .parent_supplies = cs47l24_supplies,
928 .num_parent_supplies = ARRAY_SIZE(cs47l24_supplies),
929 },
930};
931
Charles Keepax3762aed2015-08-11 09:34:31 +0100932static const char * const wm8997_supplies[] = {
Charles Keepax996c2d42014-07-25 16:24:43 +0100933 "MICVDD",
Charles Keepax32dadef2013-10-15 20:14:22 +0100934 "DBVDD2",
935 "CPVDD",
936 "SPKVDD",
Mark Browne102bef2012-07-10 12:37:58 +0100937};
938
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100939static const struct mfd_cell wm8997_devs[] = {
Charles Keepaxdc7d4862013-06-13 09:43:29 +0100940 { .name = "arizona-micsupp" },
Charles Keepaxf83c2182016-04-15 13:18:47 +0100941 { .name = "arizona-gpio" },
Charles Keepax5fc6c392014-07-25 16:24:44 +0100942 {
943 .name = "arizona-extcon",
944 .parent_supplies = wm8997_supplies,
945 .num_parent_supplies = 1, /* We only need MICVDD */
946 },
Charles Keepaxdc7d4862013-06-13 09:43:29 +0100947 { .name = "arizona-haptics" },
948 { .name = "arizona-pwm" },
Charles Keepax32dadef2013-10-15 20:14:22 +0100949 {
950 .name = "wm8997-codec",
951 .parent_supplies = wm8997_supplies,
952 .num_parent_supplies = ARRAY_SIZE(wm8997_supplies),
953 },
Charles Keepaxdc7d4862013-06-13 09:43:29 +0100954};
955
Richard Fitzgerald6887b042015-07-03 16:16:35 +0100956static const struct mfd_cell wm8998_devs[] = {
Charles Keepaxf83c2182016-04-15 13:18:47 +0100957 { .name = "arizona-micsupp" },
958 { .name = "arizona-gpio" },
Richard Fitzgerald6887b042015-07-03 16:16:35 +0100959 {
960 .name = "arizona-extcon",
961 .parent_supplies = wm5102_supplies,
962 .num_parent_supplies = 1, /* We only need MICVDD */
963 },
Richard Fitzgerald6887b042015-07-03 16:16:35 +0100964 { .name = "arizona-haptics" },
965 { .name = "arizona-pwm" },
966 {
967 .name = "wm8998-codec",
968 .parent_supplies = wm5102_supplies,
969 .num_parent_supplies = ARRAY_SIZE(wm5102_supplies),
970 },
Richard Fitzgerald6887b042015-07-03 16:16:35 +0100971};
972
Bill Pembertonf791be42012-11-19 13:23:04 -0500973int arizona_dev_init(struct arizona *arizona)
Mark Brown3cc72982012-06-19 16:31:53 +0100974{
Sylwester Nawrockicdd8da82016-09-02 16:52:46 +0100975 const char * const mclk_name[] = { "mclk1", "mclk2" };
Mark Brown3cc72982012-06-19 16:31:53 +0100976 struct device *dev = arizona->dev;
Richard Fitzgeraldea1f3332015-11-03 15:08:32 +0000977 const char *type_name = NULL;
Charles Keepax6000c992017-09-04 16:41:51 +0100978 unsigned int reg, val;
Mark Brown62d62b52012-12-02 11:41:46 +0900979 int (*apply_patch)(struct arizona *) = NULL;
Richard Fitzgeraldae05ea362015-10-02 13:29:13 +0100980 const struct mfd_cell *subdevs = NULL;
981 int n_subdevs, ret, i;
Mark Brown3cc72982012-06-19 16:31:53 +0100982
983 dev_set_drvdata(arizona->dev, arizona);
984 mutex_init(&arizona->clk_lock);
985
Charles Keepaxb8d336e2016-09-20 16:30:14 +0100986 if (dev_get_platdata(arizona->dev)) {
Mark Brown3cc72982012-06-19 16:31:53 +0100987 memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
988 sizeof(arizona->pdata));
Charles Keepaxb8d336e2016-09-20 16:30:14 +0100989 } else {
990 ret = arizona_of_get_core_pdata(arizona);
991 if (ret < 0)
992 return ret;
993 }
Mark Brown3cc72982012-06-19 16:31:53 +0100994
Sylwester Nawrockicdd8da82016-09-02 16:52:46 +0100995 BUILD_BUG_ON(ARRAY_SIZE(arizona->mclk) != ARRAY_SIZE(mclk_name));
996 for (i = 0; i < ARRAY_SIZE(arizona->mclk); i++) {
997 arizona->mclk[i] = devm_clk_get(arizona->dev, mclk_name[i]);
998 if (IS_ERR(arizona->mclk[i])) {
999 dev_info(arizona->dev, "Failed to get %s: %ld\n",
1000 mclk_name[i], PTR_ERR(arizona->mclk[i]));
1001 arizona->mclk[i] = NULL;
1002 }
1003 }
1004
Mark Brown3cc72982012-06-19 16:31:53 +01001005 regcache_cache_only(arizona->regmap, true);
1006
1007 switch (arizona->type) {
1008 case WM5102:
Mark Browne102bef2012-07-10 12:37:58 +01001009 case WM5110:
Richard Fitzgeralde5d4ef02015-01-17 15:21:22 +00001010 case WM8280:
Charles Keepaxdc7d4862013-06-13 09:43:29 +01001011 case WM8997:
Richard Fitzgerald6887b042015-07-03 16:16:35 +01001012 case WM8998:
1013 case WM1814:
Richard Fitzgeraldea1f3332015-11-03 15:08:32 +00001014 case WM1831:
1015 case CS47L24:
Mark Brown3cc72982012-06-19 16:31:53 +01001016 for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++)
1017 arizona->core_supplies[i].supply
1018 = wm5102_core_supplies[i];
1019 arizona->num_core_supplies = ARRAY_SIZE(wm5102_core_supplies);
1020 break;
1021 default:
1022 dev_err(arizona->dev, "Unknown device type %d\n",
1023 arizona->type);
Charles Keepax75d8a2b2016-08-31 10:41:30 +01001024 return -ENODEV;
Mark Brown3cc72982012-06-19 16:31:53 +01001025 }
1026
Charles Keepax4a8c4752014-04-16 10:01:38 +01001027 /* Mark DCVDD as external, LDO1 driver will clear if internal */
1028 arizona->external_dcvdd = true;
1029
Richard Fitzgeraldea1f3332015-11-03 15:08:32 +00001030 switch (arizona->type) {
1031 case WM1831:
1032 case CS47L24:
1033 break; /* No LDO1 regulator */
1034 default:
1035 ret = mfd_add_devices(arizona->dev, -1, early_devs,
1036 ARRAY_SIZE(early_devs), NULL, 0, NULL);
1037 if (ret != 0) {
1038 dev_err(dev, "Failed to add early children: %d\n", ret);
1039 return ret;
1040 }
1041 break;
Mark Brown3cc72982012-06-19 16:31:53 +01001042 }
1043
1044 ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies,
1045 arizona->core_supplies);
1046 if (ret != 0) {
1047 dev_err(dev, "Failed to request core supplies: %d\n",
1048 ret);
1049 goto err_early;
1050 }
1051
Charles Keepax0c2d0ff2014-06-19 16:04:23 +01001052 /**
1053 * Don't use devres here because the only device we have to get
1054 * against is the MFD device and DCVDD will likely be supplied by
1055 * one of its children. Meaning that the regulator will be
1056 * destroyed by the time devres calls regulator put.
1057 */
Charles Keepaxe6021512014-06-02 09:50:41 +01001058 arizona->dcvdd = regulator_get(arizona->dev, "DCVDD");
Mark Brown59db9692012-07-09 00:31:36 +02001059 if (IS_ERR(arizona->dcvdd)) {
1060 ret = PTR_ERR(arizona->dcvdd);
1061 dev_err(dev, "Failed to request DCVDD: %d\n", ret);
1062 goto err_early;
1063 }
1064
Charles Keepaxc1860462018-03-12 15:52:00 +00001065 if (!arizona->pdata.reset) {
Mark Brown87d3af42013-03-26 12:15:26 +00001066 /* Start out with /RESET low to put the chip into reset */
Charles Keepaxc1860462018-03-12 15:52:00 +00001067 arizona->pdata.reset = devm_gpiod_get(arizona->dev, "reset",
1068 GPIOD_OUT_LOW);
1069 if (IS_ERR(arizona->pdata.reset)) {
1070 ret = PTR_ERR(arizona->pdata.reset);
1071 if (ret == -EPROBE_DEFER)
1072 goto err_dcvdd;
1073
1074 dev_err(arizona->dev,
1075 "Reset GPIO missing/malformed: %d\n", ret);
1076
1077 arizona->pdata.reset = NULL;
Mark Brown87d3af42013-03-26 12:15:26 +00001078 }
1079 }
1080
Mark Brown3cc72982012-06-19 16:31:53 +01001081 ret = regulator_bulk_enable(arizona->num_core_supplies,
1082 arizona->core_supplies);
1083 if (ret != 0) {
1084 dev_err(dev, "Failed to enable core supplies: %d\n",
1085 ret);
Charles Keepaxe6021512014-06-02 09:50:41 +01001086 goto err_dcvdd;
Mark Brown3cc72982012-06-19 16:31:53 +01001087 }
1088
Mark Brown59db9692012-07-09 00:31:36 +02001089 ret = regulator_enable(arizona->dcvdd);
1090 if (ret != 0) {
1091 dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
1092 goto err_enable;
1093 }
1094
Charles Keepax22298752015-05-11 13:58:02 +01001095 arizona_disable_reset(arizona);
Mark Brown3cc72982012-06-19 16:31:53 +01001096
Mark Brown3cc72982012-06-19 16:31:53 +01001097 regcache_cache_only(arizona->regmap, false);
1098
Mark Brownca76ceb2013-04-09 16:04:35 +01001099 /* Verify that this is a chip we know about */
1100 ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
1101 if (ret != 0) {
1102 dev_err(dev, "Failed to read ID register: %d\n", ret);
1103 goto err_reset;
1104 }
1105
1106 switch (reg) {
1107 case 0x5102:
1108 case 0x5110:
Richard Fitzgerald6887b042015-07-03 16:16:35 +01001109 case 0x6349:
Richard Fitzgeraldea1f3332015-11-03 15:08:32 +00001110 case 0x6363:
Charles Keepaxdc7d4862013-06-13 09:43:29 +01001111 case 0x8997:
Mark Brownca76ceb2013-04-09 16:04:35 +01001112 break;
1113 default:
1114 dev_err(arizona->dev, "Unknown device ID: %x\n", reg);
Charles Keepax75d8a2b2016-08-31 10:41:30 +01001115 ret = -ENODEV;
Mark Brownca76ceb2013-04-09 16:04:35 +01001116 goto err_reset;
1117 }
1118
1119 /* If we have a /RESET GPIO we'll already be reset */
1120 if (!arizona->pdata.reset) {
Mark Brownca76ceb2013-04-09 16:04:35 +01001121 ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0);
1122 if (ret != 0) {
1123 dev_err(dev, "Failed to reset device: %d\n", ret);
1124 goto err_reset;
1125 }
1126
Lee Jonesb79a9802015-10-28 12:42:30 +00001127 usleep_range(1000, 5000);
Mark Brownca76ceb2013-04-09 16:04:35 +01001128 }
1129
1130 /* Ensure device startup is complete */
1131 switch (arizona->type) {
1132 case WM5102:
Mark Brown48018942014-08-13 11:42:46 +01001133 ret = regmap_read(arizona->regmap,
1134 ARIZONA_WRITE_SEQUENCER_CTRL_3, &val);
Charles Keepax1c1c6bb2015-05-11 13:58:03 +01001135 if (ret) {
Mark Brownca76ceb2013-04-09 16:04:35 +01001136 dev_err(dev,
1137 "Failed to check write sequencer state: %d\n",
1138 ret);
Charles Keepax1c1c6bb2015-05-11 13:58:03 +01001139 } else if (val & 0x01) {
1140 ret = wm5102_clear_write_sequencer(arizona);
1141 if (ret)
1142 return ret;
Mark Brownca76ceb2013-04-09 16:04:35 +01001143 }
1144 break;
Charles Keepax1c1c6bb2015-05-11 13:58:03 +01001145 default:
1146 break;
1147 }
1148
1149 ret = arizona_wait_for_boot(arizona);
1150 if (ret) {
1151 dev_err(arizona->dev, "Device failed initial boot: %d\n", ret);
1152 goto err_reset;
Mark Brownca76ceb2013-04-09 16:04:35 +01001153 }
1154
1155 /* Read the device ID information & do device specific stuff */
Mark Brown3cc72982012-06-19 16:31:53 +01001156 ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
1157 if (ret != 0) {
1158 dev_err(dev, "Failed to read ID register: %d\n", ret);
Mark Brown59db9692012-07-09 00:31:36 +02001159 goto err_reset;
Mark Brown3cc72982012-06-19 16:31:53 +01001160 }
1161
1162 ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
1163 &arizona->rev);
1164 if (ret != 0) {
1165 dev_err(dev, "Failed to read revision register: %d\n", ret);
Mark Brown59db9692012-07-09 00:31:36 +02001166 goto err_reset;
Mark Brown3cc72982012-06-19 16:31:53 +01001167 }
1168 arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
1169
1170 switch (reg) {
1171 case 0x5102:
Richard Fitzgeraldb61c1ec2015-10-02 13:29:14 +01001172 if (IS_ENABLED(CONFIG_MFD_WM5102)) {
1173 type_name = "WM5102";
1174 if (arizona->type != WM5102) {
1175 dev_warn(arizona->dev,
1176 "WM5102 registered as %d\n",
1177 arizona->type);
1178 arizona->type = WM5102;
1179 }
1180
1181 apply_patch = wm5102_patch;
1182 arizona->rev &= 0x7;
1183 subdevs = wm5102_devs;
1184 n_subdevs = ARRAY_SIZE(wm5102_devs);
Mark Brown3cc72982012-06-19 16:31:53 +01001185 }
Mark Brown3cc72982012-06-19 16:31:53 +01001186 break;
Mark Browne102bef2012-07-10 12:37:58 +01001187 case 0x5110:
Richard Fitzgeraldb61c1ec2015-10-02 13:29:14 +01001188 if (IS_ENABLED(CONFIG_MFD_WM5110)) {
1189 switch (arizona->type) {
1190 case WM5110:
1191 type_name = "WM5110";
1192 break;
1193 case WM8280:
1194 type_name = "WM8280";
1195 break;
1196 default:
1197 type_name = "WM5110";
1198 dev_warn(arizona->dev,
1199 "WM5110 registered as %d\n",
1200 arizona->type);
1201 arizona->type = WM5110;
1202 break;
1203 }
1204
1205 apply_patch = wm5110_patch;
1206 subdevs = wm5110_devs;
1207 n_subdevs = ARRAY_SIZE(wm5110_devs);
Mark Browne102bef2012-07-10 12:37:58 +01001208 }
Mark Browne102bef2012-07-10 12:37:58 +01001209 break;
Richard Fitzgeraldea1f3332015-11-03 15:08:32 +00001210 case 0x6363:
1211 if (IS_ENABLED(CONFIG_MFD_CS47L24)) {
1212 switch (arizona->type) {
1213 case CS47L24:
1214 type_name = "CS47L24";
1215 break;
1216
1217 case WM1831:
1218 type_name = "WM1831";
1219 break;
1220
1221 default:
1222 dev_warn(arizona->dev,
1223 "CS47L24 registered as %d\n",
1224 arizona->type);
1225 arizona->type = CS47L24;
1226 break;
1227 }
1228
1229 apply_patch = cs47l24_patch;
1230 subdevs = cs47l24_devs;
1231 n_subdevs = ARRAY_SIZE(cs47l24_devs);
1232 }
1233 break;
Charles Keepaxdc7d4862013-06-13 09:43:29 +01001234 case 0x8997:
Richard Fitzgeraldb61c1ec2015-10-02 13:29:14 +01001235 if (IS_ENABLED(CONFIG_MFD_WM8997)) {
1236 type_name = "WM8997";
1237 if (arizona->type != WM8997) {
1238 dev_warn(arizona->dev,
1239 "WM8997 registered as %d\n",
1240 arizona->type);
1241 arizona->type = WM8997;
1242 }
1243
1244 apply_patch = wm8997_patch;
1245 subdevs = wm8997_devs;
1246 n_subdevs = ARRAY_SIZE(wm8997_devs);
Charles Keepaxdc7d4862013-06-13 09:43:29 +01001247 }
Charles Keepaxdc7d4862013-06-13 09:43:29 +01001248 break;
Richard Fitzgerald6887b042015-07-03 16:16:35 +01001249 case 0x6349:
Richard Fitzgeraldb61c1ec2015-10-02 13:29:14 +01001250 if (IS_ENABLED(CONFIG_MFD_WM8998)) {
1251 switch (arizona->type) {
1252 case WM8998:
1253 type_name = "WM8998";
1254 break;
Richard Fitzgerald6887b042015-07-03 16:16:35 +01001255
Richard Fitzgeraldb61c1ec2015-10-02 13:29:14 +01001256 case WM1814:
1257 type_name = "WM1814";
1258 break;
Richard Fitzgerald6887b042015-07-03 16:16:35 +01001259
Richard Fitzgeraldb61c1ec2015-10-02 13:29:14 +01001260 default:
1261 type_name = "WM8998";
1262 dev_warn(arizona->dev,
1263 "WM8998 registered as %d\n",
1264 arizona->type);
1265 arizona->type = WM8998;
1266 }
1267
1268 apply_patch = wm8998_patch;
1269 subdevs = wm8998_devs;
1270 n_subdevs = ARRAY_SIZE(wm8998_devs);
Richard Fitzgerald6887b042015-07-03 16:16:35 +01001271 }
Richard Fitzgerald6887b042015-07-03 16:16:35 +01001272 break;
Mark Brown3cc72982012-06-19 16:31:53 +01001273 default:
1274 dev_err(arizona->dev, "Unknown device ID %x\n", reg);
Charles Keepax75d8a2b2016-08-31 10:41:30 +01001275 ret = -ENODEV;
Mark Brown59db9692012-07-09 00:31:36 +02001276 goto err_reset;
Mark Brown3cc72982012-06-19 16:31:53 +01001277 }
1278
Richard Fitzgeraldb61c1ec2015-10-02 13:29:14 +01001279 if (!subdevs) {
1280 dev_err(arizona->dev,
1281 "No kernel support for device ID %x\n", reg);
Charles Keepax75d8a2b2016-08-31 10:41:30 +01001282 ret = -ENODEV;
Richard Fitzgeraldb61c1ec2015-10-02 13:29:14 +01001283 goto err_reset;
1284 }
1285
Mark Brown3cc72982012-06-19 16:31:53 +01001286 dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
1287
Mark Brown62d62b52012-12-02 11:41:46 +09001288 if (apply_patch) {
1289 ret = apply_patch(arizona);
1290 if (ret != 0) {
1291 dev_err(arizona->dev, "Failed to apply patch: %d\n",
1292 ret);
1293 goto err_reset;
1294 }
Charles Keepaxe80436b2013-03-26 18:46:15 +00001295
1296 switch (arizona->type) {
1297 case WM5102:
Charles Keepax0be068a2015-05-11 13:58:04 +01001298 ret = wm5102_apply_hardware_patch(arizona);
1299 if (ret) {
Charles Keepaxe80436b2013-03-26 18:46:15 +00001300 dev_err(arizona->dev,
1301 "Failed to apply hardware patch: %d\n",
1302 ret);
1303 goto err_reset;
1304 }
1305 break;
Charles Keepax882bc462015-05-11 13:58:06 +01001306 case WM5110:
1307 case WM8280:
1308 ret = wm5110_apply_sleep_patch(arizona);
1309 if (ret) {
1310 dev_err(arizona->dev,
1311 "Failed to apply sleep patch: %d\n",
1312 ret);
1313 goto err_reset;
1314 }
1315 break;
Charles Keepaxe80436b2013-03-26 18:46:15 +00001316 default:
1317 break;
1318 }
Mark Brown62d62b52012-12-02 11:41:46 +09001319 }
1320
Mark Brown3cc72982012-06-19 16:31:53 +01001321 for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
1322 if (!arizona->pdata.gpio_defaults[i])
1323 continue;
1324
1325 regmap_write(arizona->regmap, ARIZONA_GPIO1_CTRL + i,
1326 arizona->pdata.gpio_defaults[i]);
1327 }
1328
Mark Brown3cc72982012-06-19 16:31:53 +01001329 /* Chip default */
1330 if (!arizona->pdata.clk32k_src)
1331 arizona->pdata.clk32k_src = ARIZONA_32KZ_MCLK2;
1332
1333 switch (arizona->pdata.clk32k_src) {
1334 case ARIZONA_32KZ_MCLK1:
1335 case ARIZONA_32KZ_MCLK2:
1336 regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
1337 ARIZONA_CLK_32K_SRC_MASK,
1338 arizona->pdata.clk32k_src - 1);
Mark Brown767c6dc2013-03-19 19:04:46 +01001339 arizona_clk32k_enable(arizona);
Mark Brown3cc72982012-06-19 16:31:53 +01001340 break;
1341 case ARIZONA_32KZ_NONE:
1342 regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
1343 ARIZONA_CLK_32K_SRC_MASK, 2);
1344 break;
1345 default:
1346 dev_err(arizona->dev, "Invalid 32kHz clock source: %d\n",
1347 arizona->pdata.clk32k_src);
1348 ret = -EINVAL;
Mark Brown59db9692012-07-09 00:31:36 +02001349 goto err_reset;
Mark Brown3cc72982012-06-19 16:31:53 +01001350 }
1351
Mark Brown3d91f822013-01-29 00:47:37 +08001352 for (i = 0; i < ARIZONA_MAX_MICBIAS; i++) {
Mark Brown544c7aa2013-01-29 18:44:41 +08001353 if (!arizona->pdata.micbias[i].mV &&
1354 !arizona->pdata.micbias[i].bypass)
Mark Brown3d91f822013-01-29 00:47:37 +08001355 continue;
1356
Mark Brown544c7aa2013-01-29 18:44:41 +08001357 /* Apply default for bypass mode */
1358 if (!arizona->pdata.micbias[i].mV)
1359 arizona->pdata.micbias[i].mV = 2800;
1360
Mark Brown3d91f822013-01-29 00:47:37 +08001361 val = (arizona->pdata.micbias[i].mV - 1500) / 100;
Mark Brown544c7aa2013-01-29 18:44:41 +08001362
Mark Brown3d91f822013-01-29 00:47:37 +08001363 val <<= ARIZONA_MICB1_LVL_SHIFT;
1364
1365 if (arizona->pdata.micbias[i].ext_cap)
1366 val |= ARIZONA_MICB1_EXT_CAP;
1367
1368 if (arizona->pdata.micbias[i].discharge)
1369 val |= ARIZONA_MICB1_DISCH;
1370
Charles Keepaxf773fc62013-05-21 14:56:58 +01001371 if (arizona->pdata.micbias[i].soft_start)
Mark Brown3d91f822013-01-29 00:47:37 +08001372 val |= ARIZONA_MICB1_RATE;
1373
Mark Brown544c7aa2013-01-29 18:44:41 +08001374 if (arizona->pdata.micbias[i].bypass)
1375 val |= ARIZONA_MICB1_BYPASS;
1376
Mark Brown3d91f822013-01-29 00:47:37 +08001377 regmap_update_bits(arizona->regmap,
1378 ARIZONA_MIC_BIAS_CTRL_1 + i,
1379 ARIZONA_MICB1_LVL_MASK |
Charles Keepax71d134b2014-09-24 10:37:11 +01001380 ARIZONA_MICB1_EXT_CAP |
Mark Brown3d91f822013-01-29 00:47:37 +08001381 ARIZONA_MICB1_DISCH |
Mark Brown544c7aa2013-01-29 18:44:41 +08001382 ARIZONA_MICB1_BYPASS |
Mark Brown3d91f822013-01-29 00:47:37 +08001383 ARIZONA_MICB1_RATE, val);
1384 }
1385
Charles Keepax72e43162015-06-14 15:41:50 +01001386 pm_runtime_set_active(arizona->dev);
1387 pm_runtime_enable(arizona->dev);
1388
Mark Brown3cc72982012-06-19 16:31:53 +01001389 /* Set up for interrupts */
1390 ret = arizona_irq_init(arizona);
1391 if (ret != 0)
Charles Keepaxd3477922016-06-27 15:19:11 +01001392 goto err_pm;
Mark Brown3cc72982012-06-19 16:31:53 +01001393
Charles Keepax72e43162015-06-14 15:41:50 +01001394 pm_runtime_set_autosuspend_delay(arizona->dev, 100);
1395 pm_runtime_use_autosuspend(arizona->dev);
1396
Mark Brown3cc72982012-06-19 16:31:53 +01001397 arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error",
1398 arizona_clkgen_err, arizona);
1399 arizona_request_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, "Overclocked",
1400 arizona_overclocked, arizona);
1401 arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked",
1402 arizona_underclocked, arizona);
1403
Richard Fitzgeraldae05ea362015-10-02 13:29:13 +01001404 ret = mfd_add_devices(arizona->dev, PLATFORM_DEVID_NONE,
1405 subdevs, n_subdevs, NULL, 0, NULL);
Mark Brown3cc72982012-06-19 16:31:53 +01001406
Richard Fitzgeraldae05ea362015-10-02 13:29:13 +01001407 if (ret) {
Mark Brown3cc72982012-06-19 16:31:53 +01001408 dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret);
1409 goto err_irq;
1410 }
1411
1412 return 0;
1413
1414err_irq:
1415 arizona_irq_exit(arizona);
Charles Keepaxd3477922016-06-27 15:19:11 +01001416err_pm:
1417 pm_runtime_disable(arizona->dev);
Mark Brown3cc72982012-06-19 16:31:53 +01001418err_reset:
Charles Keepax22298752015-05-11 13:58:02 +01001419 arizona_enable_reset(arizona);
Mark Brown59db9692012-07-09 00:31:36 +02001420 regulator_disable(arizona->dcvdd);
Mark Brown3cc72982012-06-19 16:31:53 +01001421err_enable:
Mark Brown3a36a0db2012-07-09 00:45:53 +02001422 regulator_bulk_disable(arizona->num_core_supplies,
Mark Brown3cc72982012-06-19 16:31:53 +01001423 arizona->core_supplies);
Charles Keepaxe6021512014-06-02 09:50:41 +01001424err_dcvdd:
1425 regulator_put(arizona->dcvdd);
Mark Brown3cc72982012-06-19 16:31:53 +01001426err_early:
1427 mfd_remove_devices(dev);
1428 return ret;
1429}
1430EXPORT_SYMBOL_GPL(arizona_dev_init);
1431
Bill Pemberton4740f732012-11-19 13:26:01 -05001432int arizona_dev_exit(struct arizona *arizona)
Mark Brown3cc72982012-06-19 16:31:53 +01001433{
Charles Keepaxfb36f772016-11-14 17:15:56 +00001434 disable_irq(arizona->irq);
Charles Keepaxb8040202014-06-02 09:50:39 +01001435 pm_runtime_disable(arizona->dev);
1436
Charles Keepaxdf6b3352014-06-02 09:50:40 +01001437 regulator_disable(arizona->dcvdd);
Charles Keepaxe6021512014-06-02 09:50:41 +01001438 regulator_put(arizona->dcvdd);
Charles Keepaxdf6b3352014-06-02 09:50:40 +01001439
Mark Brown3cc72982012-06-19 16:31:53 +01001440 mfd_remove_devices(arizona->dev);
1441 arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona);
1442 arizona_free_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, arizona);
1443 arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona);
Mark Brown3cc72982012-06-19 16:31:53 +01001444 arizona_irq_exit(arizona);
Charles Keepax22298752015-05-11 13:58:02 +01001445 arizona_enable_reset(arizona);
Charles Keepaxdf6b3352014-06-02 09:50:40 +01001446
Charles Keepax44202862014-06-02 09:50:42 +01001447 regulator_bulk_disable(arizona->num_core_supplies,
Mark Brown1d017b62013-03-26 12:16:26 +00001448 arizona->core_supplies);
Mark Brown3cc72982012-06-19 16:31:53 +01001449 return 0;
1450}
1451EXPORT_SYMBOL_GPL(arizona_dev_exit);