]> Pileus Git - ~andy/linux/blob - drivers/mfd/arizona-core.c
b71bf7ba4cfa8917bf5e828e6545bd2abf9d467b
[~andy/linux] / drivers / mfd / arizona-core.c
1 /*
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>
14 #include <linux/err.h>
15 #include <linux/gpio.h>
16 #include <linux/interrupt.h>
17 #include <linux/mfd/core.h>
18 #include <linux/module.h>
19 #include <linux/pm_runtime.h>
20 #include <linux/regmap.h>
21 #include <linux/regulator/consumer.h>
22 #include <linux/slab.h>
23
24 #include <linux/mfd/arizona/core.h>
25 #include <linux/mfd/arizona/registers.h>
26
27 #include "arizona.h"
28
29 static const char *wm5102_core_supplies[] = {
30         "AVDD",
31         "DBVDD1",
32 };
33
34 int arizona_clk32k_enable(struct arizona *arizona)
35 {
36         int ret = 0;
37
38         mutex_lock(&arizona->clk_lock);
39
40         arizona->clk32k_ref++;
41
42         if (arizona->clk32k_ref == 1) {
43                 switch (arizona->pdata.clk32k_src) {
44                 case ARIZONA_32KZ_MCLK1:
45                         ret = pm_runtime_get_sync(arizona->dev);
46                         if (ret != 0)
47                                 goto out;
48                         break;
49                 }
50
51                 ret = regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
52                                          ARIZONA_CLK_32K_ENA,
53                                          ARIZONA_CLK_32K_ENA);
54         }
55
56 out:
57         if (ret != 0)
58                 arizona->clk32k_ref--;
59
60         mutex_unlock(&arizona->clk_lock);
61
62         return ret;
63 }
64 EXPORT_SYMBOL_GPL(arizona_clk32k_enable);
65
66 int arizona_clk32k_disable(struct arizona *arizona)
67 {
68         int ret = 0;
69
70         mutex_lock(&arizona->clk_lock);
71
72         BUG_ON(arizona->clk32k_ref <= 0);
73
74         arizona->clk32k_ref--;
75
76         if (arizona->clk32k_ref == 0) {
77                 regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
78                                    ARIZONA_CLK_32K_ENA, 0);
79
80                 switch (arizona->pdata.clk32k_src) {
81                 case ARIZONA_32KZ_MCLK1:
82                         pm_runtime_put_sync(arizona->dev);
83                         break;
84                 }
85         }
86
87         mutex_unlock(&arizona->clk_lock);
88
89         return ret;
90 }
91 EXPORT_SYMBOL_GPL(arizona_clk32k_disable);
92
93 static irqreturn_t arizona_clkgen_err(int irq, void *data)
94 {
95         struct arizona *arizona = data;
96
97         dev_err(arizona->dev, "CLKGEN error\n");
98
99         return IRQ_HANDLED;
100 }
101
102 static irqreturn_t arizona_underclocked(int irq, void *data)
103 {
104         struct arizona *arizona = data;
105         unsigned int val;
106         int ret;
107
108         ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_8,
109                           &val);
110         if (ret != 0) {
111                 dev_err(arizona->dev, "Failed to read underclock status: %d\n",
112                         ret);
113                 return IRQ_NONE;
114         }
115
116         if (val & ARIZONA_AIF3_UNDERCLOCKED_STS)
117                 dev_err(arizona->dev, "AIF3 underclocked\n");
118         if (val & ARIZONA_AIF2_UNDERCLOCKED_STS)
119                 dev_err(arizona->dev, "AIF2 underclocked\n");
120         if (val & ARIZONA_AIF1_UNDERCLOCKED_STS)
121                 dev_err(arizona->dev, "AIF1 underclocked\n");
122         if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS)
123                 dev_err(arizona->dev, "ISRC2 underclocked\n");
124         if (val & ARIZONA_ISRC1_UNDERCLOCKED_STS)
125                 dev_err(arizona->dev, "ISRC1 underclocked\n");
126         if (val & ARIZONA_FX_UNDERCLOCKED_STS)
127                 dev_err(arizona->dev, "FX underclocked\n");
128         if (val & ARIZONA_ASRC_UNDERCLOCKED_STS)
129                 dev_err(arizona->dev, "ASRC underclocked\n");
130         if (val & ARIZONA_DAC_UNDERCLOCKED_STS)
131                 dev_err(arizona->dev, "DAC underclocked\n");
132         if (val & ARIZONA_ADC_UNDERCLOCKED_STS)
133                 dev_err(arizona->dev, "ADC underclocked\n");
134         if (val & ARIZONA_MIXER_UNDERCLOCKED_STS)
135                 dev_err(arizona->dev, "Mixer dropped sample\n");
136
137         return IRQ_HANDLED;
138 }
139
140 static irqreturn_t arizona_overclocked(int irq, void *data)
141 {
142         struct arizona *arizona = data;
143         unsigned int val[2];
144         int ret;
145         
146         ret = regmap_bulk_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_6,
147                                &val[0], 2);
148         if (ret != 0) {
149                 dev_err(arizona->dev, "Failed to read overclock status: %d\n",
150                         ret);
151                 return IRQ_NONE;
152         }
153
154         if (val[0] & ARIZONA_PWM_OVERCLOCKED_STS)
155                 dev_err(arizona->dev, "PWM overclocked\n");
156         if (val[0] & ARIZONA_FX_CORE_OVERCLOCKED_STS)
157                 dev_err(arizona->dev, "FX core overclocked\n");
158         if (val[0] & ARIZONA_DAC_SYS_OVERCLOCKED_STS)
159                 dev_err(arizona->dev, "DAC SYS overclocked\n");
160         if (val[0] & ARIZONA_DAC_WARP_OVERCLOCKED_STS)
161                 dev_err(arizona->dev, "DAC WARP overclocked\n");
162         if (val[0] & ARIZONA_ADC_OVERCLOCKED_STS)
163                 dev_err(arizona->dev, "ADC overclocked\n");
164         if (val[0] & ARIZONA_MIXER_OVERCLOCKED_STS)
165                 dev_err(arizona->dev, "Mixer overclocked\n");
166         if (val[0] & ARIZONA_AIF3_SYNC_OVERCLOCKED_STS)
167                 dev_err(arizona->dev, "AIF3 overclocked\n");
168         if (val[0] & ARIZONA_AIF2_SYNC_OVERCLOCKED_STS)
169                 dev_err(arizona->dev, "AIF2 overclocked\n");
170         if (val[0] & ARIZONA_AIF1_SYNC_OVERCLOCKED_STS)
171                 dev_err(arizona->dev, "AIF1 overclocked\n");
172         if (val[0] & ARIZONA_PAD_CTRL_OVERCLOCKED_STS)
173                 dev_err(arizona->dev, "Pad control overclocked\n");
174
175         if (val[1] & ARIZONA_SLIMBUS_SUBSYS_OVERCLOCKED_STS)
176                 dev_err(arizona->dev, "Slimbus subsystem overclocked\n");
177         if (val[1] & ARIZONA_SLIMBUS_ASYNC_OVERCLOCKED_STS)
178                 dev_err(arizona->dev, "Slimbus async overclocked\n");
179         if (val[1] & ARIZONA_SLIMBUS_SYNC_OVERCLOCKED_STS)
180                 dev_err(arizona->dev, "Slimbus sync overclocked\n");
181         if (val[1] & ARIZONA_ASRC_ASYNC_SYS_OVERCLOCKED_STS)
182                 dev_err(arizona->dev, "ASRC async system overclocked\n");
183         if (val[1] & ARIZONA_ASRC_ASYNC_WARP_OVERCLOCKED_STS)
184                 dev_err(arizona->dev, "ASRC async WARP overclocked\n");
185         if (val[1] & ARIZONA_ASRC_SYNC_SYS_OVERCLOCKED_STS)
186                 dev_err(arizona->dev, "ASRC sync system overclocked\n");
187         if (val[1] & ARIZONA_ASRC_SYNC_WARP_OVERCLOCKED_STS)
188                 dev_err(arizona->dev, "ASRC sync WARP overclocked\n");
189         if (val[1] & ARIZONA_ADSP2_1_OVERCLOCKED_STS)
190                 dev_err(arizona->dev, "DSP1 overclocked\n");
191         if (val[1] & ARIZONA_ISRC2_OVERCLOCKED_STS)
192                 dev_err(arizona->dev, "ISRC2 overclocked\n");
193         if (val[1] & ARIZONA_ISRC1_OVERCLOCKED_STS)
194                 dev_err(arizona->dev, "ISRC1 overclocked\n");
195
196         return IRQ_HANDLED;
197 }
198
199 static int arizona_wait_for_boot(struct arizona *arizona)
200 {
201         unsigned int reg;
202         int ret, i;
203
204         /*
205          * We can't use an interrupt as we need to runtime resume to do so,
206          * we won't race with the interrupt handler as it'll be blocked on
207          * runtime resume.
208          */
209         for (i = 0; i < 5; i++) {
210                 msleep(1);
211
212                 ret = regmap_read(arizona->regmap,
213                                   ARIZONA_INTERRUPT_RAW_STATUS_5, &reg);
214                 if (ret != 0) {
215                         dev_err(arizona->dev, "Failed to read boot state: %d\n",
216                                 ret);
217                         continue;
218                 }
219
220                 if (reg & ARIZONA_BOOT_DONE_STS)
221                         break;
222         }
223
224         if (reg & ARIZONA_BOOT_DONE_STS) {
225                 regmap_write(arizona->regmap, ARIZONA_INTERRUPT_STATUS_5,
226                              ARIZONA_BOOT_DONE_STS);
227         } else {
228                 dev_err(arizona->dev, "Device boot timed out: %x\n", reg);
229                 return -ETIMEDOUT;
230         }
231
232         pm_runtime_mark_last_busy(arizona->dev);
233
234         return 0;
235 }
236
237 #ifdef CONFIG_PM_RUNTIME
238 static int arizona_runtime_resume(struct device *dev)
239 {
240         struct arizona *arizona = dev_get_drvdata(dev);
241         int ret;
242
243         dev_dbg(arizona->dev, "Leaving AoD mode\n");
244
245         ret = regulator_enable(arizona->dcvdd);
246         if (ret != 0) {
247                 dev_err(arizona->dev, "Failed to enable DCVDD: %d\n", ret);
248                 return ret;
249         }
250
251         regcache_cache_only(arizona->regmap, false);
252
253         ret = arizona_wait_for_boot(arizona);
254         if (ret != 0) {
255                 goto err;
256         }
257
258         switch (arizona->type) {
259         case WM5102:
260                 ret = wm5102_patch(arizona);
261                 if (ret != 0) {
262                         dev_err(arizona->dev, "Failed to apply patch: %d\n",
263                                 ret);
264                         goto err;
265                 }
266         }
267
268         ret = regcache_sync(arizona->regmap);
269         if (ret != 0) {
270                 dev_err(arizona->dev, "Failed to restore register cache\n");
271                 goto err;
272         }
273
274         return 0;
275
276 err:
277         regcache_cache_only(arizona->regmap, true);
278         regulator_disable(arizona->dcvdd);
279         return ret;
280 }
281
282 static int arizona_runtime_suspend(struct device *dev)
283 {
284         struct arizona *arizona = dev_get_drvdata(dev);
285
286         dev_dbg(arizona->dev, "Entering AoD mode\n");
287
288         regulator_disable(arizona->dcvdd);
289         regcache_cache_only(arizona->regmap, true);
290         regcache_mark_dirty(arizona->regmap);
291
292         return 0;
293 }
294 #endif
295
296 #ifdef CONFIG_PM_SLEEP
297 static int arizona_resume_noirq(struct device *dev)
298 {
299         struct arizona *arizona = dev_get_drvdata(dev);
300
301         dev_dbg(arizona->dev, "Early resume, disabling IRQ\n");
302         disable_irq(arizona->irq);
303
304         return 0;
305 }
306
307 static int arizona_resume(struct device *dev)
308 {
309         struct arizona *arizona = dev_get_drvdata(dev);
310
311         dev_dbg(arizona->dev, "Late resume, reenabling IRQ\n");
312         enable_irq(arizona->irq);
313
314         return 0;
315 }
316 #endif
317
318 const struct dev_pm_ops arizona_pm_ops = {
319         SET_RUNTIME_PM_OPS(arizona_runtime_suspend,
320                            arizona_runtime_resume,
321                            NULL)
322         SET_SYSTEM_SLEEP_PM_OPS(NULL, arizona_resume)
323 #ifdef CONFIG_PM_SLEEP
324         .resume_noirq = arizona_resume_noirq,
325 #endif
326 };
327 EXPORT_SYMBOL_GPL(arizona_pm_ops);
328
329 static struct mfd_cell early_devs[] = {
330         { .name = "arizona-ldo1" },
331 };
332
333 static struct mfd_cell wm5102_devs[] = {
334         { .name = "arizona-micsupp" },
335         { .name = "arizona-extcon" },
336         { .name = "arizona-gpio" },
337         { .name = "arizona-haptics" },
338         { .name = "arizona-pwm" },
339         { .name = "wm5102-codec" },
340 };
341
342 static struct mfd_cell wm5110_devs[] = {
343         { .name = "arizona-micsupp" },
344         { .name = "arizona-extcon" },
345         { .name = "arizona-gpio" },
346         { .name = "arizona-haptics" },
347         { .name = "arizona-pwm" },
348         { .name = "wm5110-codec" },
349 };
350
351 int arizona_dev_init(struct arizona *arizona)
352 {
353         struct device *dev = arizona->dev;
354         const char *type_name;
355         unsigned int reg, val;
356         int (*apply_patch)(struct arizona *) = NULL;
357         int ret, i;
358
359         dev_set_drvdata(arizona->dev, arizona);
360         mutex_init(&arizona->clk_lock);
361
362         if (dev_get_platdata(arizona->dev))
363                 memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
364                        sizeof(arizona->pdata));
365
366         regcache_cache_only(arizona->regmap, true);
367
368         switch (arizona->type) {
369         case WM5102:
370         case WM5110:
371                 for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++)
372                         arizona->core_supplies[i].supply
373                                 = wm5102_core_supplies[i];
374                 arizona->num_core_supplies = ARRAY_SIZE(wm5102_core_supplies);
375                 break;
376         default:
377                 dev_err(arizona->dev, "Unknown device type %d\n",
378                         arizona->type);
379                 return -EINVAL;
380         }
381
382         ret = mfd_add_devices(arizona->dev, -1, early_devs,
383                               ARRAY_SIZE(early_devs), NULL, 0, NULL);
384         if (ret != 0) {
385                 dev_err(dev, "Failed to add early children: %d\n", ret);
386                 return ret;
387         }
388
389         ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies,
390                                       arizona->core_supplies);
391         if (ret != 0) {
392                 dev_err(dev, "Failed to request core supplies: %d\n",
393                         ret);
394                 goto err_early;
395         }
396
397         arizona->dcvdd = devm_regulator_get(arizona->dev, "DCVDD");
398         if (IS_ERR(arizona->dcvdd)) {
399                 ret = PTR_ERR(arizona->dcvdd);
400                 dev_err(dev, "Failed to request DCVDD: %d\n", ret);
401                 goto err_early;
402         }
403
404         ret = regulator_bulk_enable(arizona->num_core_supplies,
405                                     arizona->core_supplies);
406         if (ret != 0) {
407                 dev_err(dev, "Failed to enable core supplies: %d\n",
408                         ret);
409                 goto err_early;
410         }
411
412         ret = regulator_enable(arizona->dcvdd);
413         if (ret != 0) {
414                 dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
415                 goto err_enable;
416         }
417
418         if (arizona->pdata.reset) {
419                 /* Start out with /RESET low to put the chip into reset */
420                 ret = gpio_request_one(arizona->pdata.reset,
421                                        GPIOF_DIR_OUT | GPIOF_INIT_LOW,
422                                        "arizona /RESET");
423                 if (ret != 0) {
424                         dev_err(dev, "Failed to request /RESET: %d\n", ret);
425                         goto err_dcvdd;
426                 }
427
428                 gpio_set_value_cansleep(arizona->pdata.reset, 1);
429         }
430
431         regcache_cache_only(arizona->regmap, false);
432
433         ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
434         if (ret != 0) {
435                 dev_err(dev, "Failed to read ID register: %d\n", ret);
436                 goto err_reset;
437         }
438
439         ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
440                           &arizona->rev);
441         if (ret != 0) {
442                 dev_err(dev, "Failed to read revision register: %d\n", ret);
443                 goto err_reset;
444         }
445         arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
446
447         switch (reg) {
448 #ifdef CONFIG_MFD_WM5102
449         case 0x5102:
450                 type_name = "WM5102";
451                 if (arizona->type != WM5102) {
452                         dev_err(arizona->dev, "WM5102 registered as %d\n",
453                                 arizona->type);
454                         arizona->type = WM5102;
455                 }
456                 apply_patch = wm5102_patch;
457                 arizona->rev &= 0x7;
458                 break;
459 #endif
460 #ifdef CONFIG_MFD_WM5110
461         case 0x5110:
462                 type_name = "WM5110";
463                 if (arizona->type != WM5110) {
464                         dev_err(arizona->dev, "WM5110 registered as %d\n",
465                                 arizona->type);
466                         arizona->type = WM5110;
467                 }
468                 apply_patch = wm5110_patch;
469                 break;
470 #endif
471         default:
472                 dev_err(arizona->dev, "Unknown device ID %x\n", reg);
473                 goto err_reset;
474         }
475
476         dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
477
478         /* If we have a /RESET GPIO we'll already be reset */
479         if (!arizona->pdata.reset) {
480                 regcache_mark_dirty(arizona->regmap);
481
482                 ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0);
483                 if (ret != 0) {
484                         dev_err(dev, "Failed to reset device: %d\n", ret);
485                         goto err_reset;
486                 }
487
488                 ret = regcache_sync(arizona->regmap);
489                 if (ret != 0) {
490                         dev_err(dev, "Failed to sync device: %d\n", ret);
491                         goto err_reset;
492                 }
493         }
494
495         ret = arizona_wait_for_boot(arizona);
496         if (ret != 0) {
497                 dev_err(arizona->dev, "Device failed initial boot: %d\n", ret);
498                 goto err_reset;
499         }
500
501         if (apply_patch) {
502                 ret = apply_patch(arizona);
503                 if (ret != 0) {
504                         dev_err(arizona->dev, "Failed to apply patch: %d\n",
505                                 ret);
506                         goto err_reset;
507                 }
508         }
509
510         for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
511                 if (!arizona->pdata.gpio_defaults[i])
512                         continue;
513
514                 regmap_write(arizona->regmap, ARIZONA_GPIO1_CTRL + i,
515                              arizona->pdata.gpio_defaults[i]);
516         }
517
518         pm_runtime_set_autosuspend_delay(arizona->dev, 100);
519         pm_runtime_use_autosuspend(arizona->dev);
520         pm_runtime_enable(arizona->dev);
521
522         /* Chip default */
523         if (!arizona->pdata.clk32k_src)
524                 arizona->pdata.clk32k_src = ARIZONA_32KZ_MCLK2;
525
526         switch (arizona->pdata.clk32k_src) {
527         case ARIZONA_32KZ_MCLK1:
528         case ARIZONA_32KZ_MCLK2:
529                 regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
530                                    ARIZONA_CLK_32K_SRC_MASK,
531                                    arizona->pdata.clk32k_src - 1);
532                 arizona_clk32k_enable(arizona);
533                 break;
534         case ARIZONA_32KZ_NONE:
535                 regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
536                                    ARIZONA_CLK_32K_SRC_MASK, 2);
537                 break;
538         default:
539                 dev_err(arizona->dev, "Invalid 32kHz clock source: %d\n",
540                         arizona->pdata.clk32k_src);
541                 ret = -EINVAL;
542                 goto err_reset;
543         }
544
545         for (i = 0; i < ARIZONA_MAX_MICBIAS; i++) {
546                 if (!arizona->pdata.micbias[i].mV &&
547                     !arizona->pdata.micbias[i].bypass)
548                         continue;
549
550                 /* Apply default for bypass mode */
551                 if (!arizona->pdata.micbias[i].mV)
552                         arizona->pdata.micbias[i].mV = 2800;
553
554                 val = (arizona->pdata.micbias[i].mV - 1500) / 100;
555
556                 val <<= ARIZONA_MICB1_LVL_SHIFT;
557
558                 if (arizona->pdata.micbias[i].ext_cap)
559                         val |= ARIZONA_MICB1_EXT_CAP;
560
561                 if (arizona->pdata.micbias[i].discharge)
562                         val |= ARIZONA_MICB1_DISCH;
563
564                 if (arizona->pdata.micbias[i].fast_start)
565                         val |= ARIZONA_MICB1_RATE;
566
567                 if (arizona->pdata.micbias[i].bypass)
568                         val |= ARIZONA_MICB1_BYPASS;
569
570                 regmap_update_bits(arizona->regmap,
571                                    ARIZONA_MIC_BIAS_CTRL_1 + i,
572                                    ARIZONA_MICB1_LVL_MASK |
573                                    ARIZONA_MICB1_DISCH |
574                                    ARIZONA_MICB1_BYPASS |
575                                    ARIZONA_MICB1_RATE, val);
576         }
577
578         for (i = 0; i < ARIZONA_MAX_INPUT; i++) {
579                 /* Default for both is 0 so noop with defaults */
580                 val = arizona->pdata.dmic_ref[i]
581                         << ARIZONA_IN1_DMIC_SUP_SHIFT;
582                 val |= arizona->pdata.inmode[i] << ARIZONA_IN1_MODE_SHIFT;
583
584                 regmap_update_bits(arizona->regmap,
585                                    ARIZONA_IN1L_CONTROL + (i * 8),
586                                    ARIZONA_IN1_DMIC_SUP_MASK |
587                                    ARIZONA_IN1_MODE_MASK, val);
588         }
589
590         for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) {
591                 /* Default is 0 so noop with defaults */
592                 if (arizona->pdata.out_mono[i])
593                         val = ARIZONA_OUT1_MONO;
594                 else
595                         val = 0;
596
597                 regmap_update_bits(arizona->regmap,
598                                    ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8),
599                                    ARIZONA_OUT1_MONO, val);
600         }
601
602         for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) {
603                 if (arizona->pdata.spk_mute[i])
604                         regmap_update_bits(arizona->regmap,
605                                            ARIZONA_PDM_SPK1_CTRL_1 + (i * 2),
606                                            ARIZONA_SPK1_MUTE_ENDIAN_MASK |
607                                            ARIZONA_SPK1_MUTE_SEQ1_MASK,
608                                            arizona->pdata.spk_mute[i]);
609
610                 if (arizona->pdata.spk_fmt[i])
611                         regmap_update_bits(arizona->regmap,
612                                            ARIZONA_PDM_SPK1_CTRL_2 + (i * 2),
613                                            ARIZONA_SPK1_FMT_MASK,
614                                            arizona->pdata.spk_fmt[i]);
615         }
616
617         /* Set up for interrupts */
618         ret = arizona_irq_init(arizona);
619         if (ret != 0)
620                 goto err_reset;
621
622         arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error",
623                             arizona_clkgen_err, arizona);
624         arizona_request_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, "Overclocked",
625                             arizona_overclocked, arizona);
626         arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked",
627                             arizona_underclocked, arizona);
628
629         switch (arizona->type) {
630         case WM5102:
631                 ret = mfd_add_devices(arizona->dev, -1, wm5102_devs,
632                                       ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);
633                 break;
634         case WM5110:
635                 ret = mfd_add_devices(arizona->dev, -1, wm5110_devs,
636                                       ARRAY_SIZE(wm5110_devs), NULL, 0, NULL);
637                 break;
638         }
639
640         if (ret != 0) {
641                 dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret);
642                 goto err_irq;
643         }
644
645 #ifdef CONFIG_PM_RUNTIME
646         regulator_disable(arizona->dcvdd);
647 #endif
648
649         return 0;
650
651 err_irq:
652         arizona_irq_exit(arizona);
653 err_reset:
654         if (arizona->pdata.reset) {
655                 gpio_set_value_cansleep(arizona->pdata.reset, 1);
656                 gpio_free(arizona->pdata.reset);
657         }
658 err_dcvdd:
659         regulator_disable(arizona->dcvdd);
660 err_enable:
661         regulator_bulk_disable(arizona->num_core_supplies,
662                                arizona->core_supplies);
663 err_early:
664         mfd_remove_devices(dev);
665         return ret;
666 }
667 EXPORT_SYMBOL_GPL(arizona_dev_init);
668
669 int arizona_dev_exit(struct arizona *arizona)
670 {
671         mfd_remove_devices(arizona->dev);
672         arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona);
673         arizona_free_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, arizona);
674         arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona);
675         pm_runtime_disable(arizona->dev);
676         arizona_irq_exit(arizona);
677         return 0;
678 }
679 EXPORT_SYMBOL_GPL(arizona_dev_exit);