]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/mfd/wm831x-core.c
mfd: Convert WM831x to use regmap API
[mirror_ubuntu-artful-kernel.git] / drivers / mfd / wm831x-core.c
CommitLineData
d2bedfe7
MB
1/*
2 * wm831x-core.c -- Device access for Wolfson WM831x PMICs
3 *
4 * Copyright 2009 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 it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/module.h>
7e9f9fd4
MB
17#include <linux/bcd.h>
18#include <linux/delay.h>
d2bedfe7 19#include <linux/mfd/core.h>
5a0e3ad6 20#include <linux/slab.h>
1df5981b 21#include <linux/err.h>
d2bedfe7
MB
22
23#include <linux/mfd/wm831x/core.h>
24#include <linux/mfd/wm831x/pdata.h>
7d4d0a3e 25#include <linux/mfd/wm831x/irq.h>
7e9f9fd4 26#include <linux/mfd/wm831x/auxadc.h>
6704e517 27#include <linux/mfd/wm831x/otp.h>
698659d5
MB
28#include <linux/mfd/wm831x/regulator.h>
29
30/* Current settings - values are 2*2^(reg_val/4) microamps. These are
31 * exported since they are used by multiple drivers.
32 */
7716977b 33int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = {
698659d5
MB
34 2,
35 2,
36 3,
37 3,
38 4,
39 5,
40 6,
41 7,
42 8,
43 10,
44 11,
45 13,
46 16,
47 19,
48 23,
49 27,
50 32,
51 38,
52 45,
53 54,
54 64,
55 76,
56 91,
57 108,
58 128,
59 152,
60 181,
61 215,
62 256,
63 304,
64 362,
65 431,
66 512,
67 609,
68 724,
69 861,
70 1024,
71 1218,
72 1448,
73 1722,
74 2048,
75 2435,
76 2896,
77 3444,
78 4096,
79 4871,
80 5793,
81 6889,
82 8192,
83 9742,
84 11585,
85 13777,
86 16384,
87 19484,
88 23170,
89 27554,
90};
91EXPORT_SYMBOL_GPL(wm831x_isinkv_values);
d2bedfe7 92
d2bedfe7
MB
93static int wm831x_reg_locked(struct wm831x *wm831x, unsigned short reg)
94{
95 if (!wm831x->locked)
96 return 0;
97
98 switch (reg) {
99 case WM831X_WATCHDOG:
100 case WM831X_DC4_CONTROL:
101 case WM831X_ON_PIN_CONTROL:
102 case WM831X_BACKUP_CHARGER_CONTROL:
103 case WM831X_CHARGER_CONTROL_1:
104 case WM831X_CHARGER_CONTROL_2:
105 return 1;
106
107 default:
108 return 0;
109 }
110}
111
112/**
113 * wm831x_reg_unlock: Unlock user keyed registers
114 *
115 * The WM831x has a user key preventing writes to particularly
116 * critical registers. This function locks those registers,
117 * allowing writes to them.
118 */
119void wm831x_reg_lock(struct wm831x *wm831x)
120{
121 int ret;
122
123 ret = wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0);
124 if (ret == 0) {
125 dev_vdbg(wm831x->dev, "Registers locked\n");
126
127 mutex_lock(&wm831x->io_lock);
128 WARN_ON(wm831x->locked);
129 wm831x->locked = 1;
130 mutex_unlock(&wm831x->io_lock);
131 } else {
132 dev_err(wm831x->dev, "Failed to lock registers: %d\n", ret);
133 }
134
135}
136EXPORT_SYMBOL_GPL(wm831x_reg_lock);
137
138/**
139 * wm831x_reg_unlock: Unlock user keyed registers
140 *
141 * The WM831x has a user key preventing writes to particularly
142 * critical registers. This function locks those registers,
143 * preventing spurious writes.
144 */
145int wm831x_reg_unlock(struct wm831x *wm831x)
146{
147 int ret;
148
149 /* 0x9716 is the value required to unlock the registers */
150 ret = wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0x9716);
151 if (ret == 0) {
152 dev_vdbg(wm831x->dev, "Registers unlocked\n");
153
154 mutex_lock(&wm831x->io_lock);
155 WARN_ON(!wm831x->locked);
156 wm831x->locked = 0;
157 mutex_unlock(&wm831x->io_lock);
158 }
159
160 return ret;
161}
162EXPORT_SYMBOL_GPL(wm831x_reg_unlock);
163
d2bedfe7
MB
164/**
165 * wm831x_reg_read: Read a single WM831x register.
166 *
167 * @wm831x: Device to read from.
168 * @reg: Register to read.
169 */
170int wm831x_reg_read(struct wm831x *wm831x, unsigned short reg)
171{
1df5981b 172 unsigned int val;
d2bedfe7
MB
173 int ret;
174
1df5981b 175 ret = regmap_read(wm831x->regmap, reg, &val);
d2bedfe7
MB
176
177 if (ret < 0)
178 return ret;
179 else
180 return val;
181}
182EXPORT_SYMBOL_GPL(wm831x_reg_read);
183
184/**
185 * wm831x_bulk_read: Read multiple WM831x registers
186 *
187 * @wm831x: Device to read from
188 * @reg: First register
189 * @count: Number of registers
190 * @buf: Buffer to fill.
191 */
192int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg,
193 int count, u16 *buf)
194{
1df5981b 195 return regmap_bulk_read(wm831x->regmap, reg, buf, count);
d2bedfe7
MB
196}
197EXPORT_SYMBOL_GPL(wm831x_bulk_read);
198
199static int wm831x_write(struct wm831x *wm831x, unsigned short reg,
200 int bytes, void *src)
201{
202 u16 *buf = src;
1df5981b 203 int i, ret;
d2bedfe7
MB
204
205 BUG_ON(bytes % 2);
206 BUG_ON(bytes <= 0);
207
208 for (i = 0; i < bytes / 2; i++) {
209 if (wm831x_reg_locked(wm831x, reg))
210 return -EPERM;
211
212 dev_vdbg(wm831x->dev, "Write %04x to R%d(0x%x)\n",
213 buf[i], reg + i, reg + i);
1df5981b 214 ret = regmap_write(wm831x->regmap, reg + i, buf[i]);
d2bedfe7
MB
215 }
216
1df5981b 217 return 0;
d2bedfe7
MB
218}
219
220/**
221 * wm831x_reg_write: Write a single WM831x register.
222 *
223 * @wm831x: Device to write to.
224 * @reg: Register to write to.
225 * @val: Value to write.
226 */
227int wm831x_reg_write(struct wm831x *wm831x, unsigned short reg,
228 unsigned short val)
229{
230 int ret;
231
232 mutex_lock(&wm831x->io_lock);
233
234 ret = wm831x_write(wm831x, reg, 2, &val);
235
236 mutex_unlock(&wm831x->io_lock);
237
238 return ret;
239}
240EXPORT_SYMBOL_GPL(wm831x_reg_write);
241
242/**
243 * wm831x_set_bits: Set the value of a bitfield in a WM831x register
244 *
245 * @wm831x: Device to write to.
246 * @reg: Register to write to.
247 * @mask: Mask of bits to set.
248 * @val: Value to set (unshifted)
249 */
250int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg,
251 unsigned short mask, unsigned short val)
252{
253 int ret;
d2bedfe7
MB
254
255 mutex_lock(&wm831x->io_lock);
256
1df5981b
MB
257 if (!wm831x_reg_locked(wm831x, reg))
258 ret = regmap_update_bits(wm831x->regmap, reg, mask, val);
259 else
260 ret = -EPERM;
d2bedfe7 261
d2bedfe7
MB
262 mutex_unlock(&wm831x->io_lock);
263
264 return ret;
265}
266EXPORT_SYMBOL_GPL(wm831x_set_bits);
267
268static struct resource wm831x_dcdc1_resources[] = {
269 {
270 .start = WM831X_DC1_CONTROL_1,
271 .end = WM831X_DC1_DVS_CONTROL,
272 .flags = IORESOURCE_IO,
273 },
274 {
275 .name = "UV",
276 .start = WM831X_IRQ_UV_DC1,
277 .end = WM831X_IRQ_UV_DC1,
278 .flags = IORESOURCE_IRQ,
279 },
280 {
281 .name = "HC",
282 .start = WM831X_IRQ_HC_DC1,
283 .end = WM831X_IRQ_HC_DC1,
284 .flags = IORESOURCE_IRQ,
285 },
286};
287
288
289static struct resource wm831x_dcdc2_resources[] = {
290 {
291 .start = WM831X_DC2_CONTROL_1,
292 .end = WM831X_DC2_DVS_CONTROL,
293 .flags = IORESOURCE_IO,
294 },
295 {
296 .name = "UV",
297 .start = WM831X_IRQ_UV_DC2,
298 .end = WM831X_IRQ_UV_DC2,
299 .flags = IORESOURCE_IRQ,
300 },
301 {
302 .name = "HC",
303 .start = WM831X_IRQ_HC_DC2,
304 .end = WM831X_IRQ_HC_DC2,
305 .flags = IORESOURCE_IRQ,
306 },
307};
308
309static struct resource wm831x_dcdc3_resources[] = {
310 {
311 .start = WM831X_DC3_CONTROL_1,
312 .end = WM831X_DC3_SLEEP_CONTROL,
313 .flags = IORESOURCE_IO,
314 },
315 {
316 .name = "UV",
317 .start = WM831X_IRQ_UV_DC3,
318 .end = WM831X_IRQ_UV_DC3,
319 .flags = IORESOURCE_IRQ,
320 },
321};
322
323static struct resource wm831x_dcdc4_resources[] = {
324 {
325 .start = WM831X_DC4_CONTROL,
326 .end = WM831X_DC4_SLEEP_CONTROL,
327 .flags = IORESOURCE_IO,
328 },
329 {
330 .name = "UV",
331 .start = WM831X_IRQ_UV_DC4,
332 .end = WM831X_IRQ_UV_DC4,
333 .flags = IORESOURCE_IRQ,
334 },
335};
336
d4e0a89e
MB
337static struct resource wm8320_dcdc4_buck_resources[] = {
338 {
339 .start = WM831X_DC4_CONTROL,
340 .end = WM832X_DC4_SLEEP_CONTROL,
341 .flags = IORESOURCE_IO,
342 },
343 {
344 .name = "UV",
345 .start = WM831X_IRQ_UV_DC4,
346 .end = WM831X_IRQ_UV_DC4,
347 .flags = IORESOURCE_IRQ,
348 },
349};
350
d2bedfe7
MB
351static struct resource wm831x_gpio_resources[] = {
352 {
353 .start = WM831X_IRQ_GPIO_1,
354 .end = WM831X_IRQ_GPIO_16,
355 .flags = IORESOURCE_IRQ,
356 },
357};
358
359static struct resource wm831x_isink1_resources[] = {
360 {
361 .start = WM831X_CURRENT_SINK_1,
362 .end = WM831X_CURRENT_SINK_1,
363 .flags = IORESOURCE_IO,
364 },
365 {
366 .start = WM831X_IRQ_CS1,
367 .end = WM831X_IRQ_CS1,
368 .flags = IORESOURCE_IRQ,
369 },
370};
371
372static struct resource wm831x_isink2_resources[] = {
373 {
374 .start = WM831X_CURRENT_SINK_2,
375 .end = WM831X_CURRENT_SINK_2,
376 .flags = IORESOURCE_IO,
377 },
378 {
379 .start = WM831X_IRQ_CS2,
380 .end = WM831X_IRQ_CS2,
381 .flags = IORESOURCE_IRQ,
382 },
383};
384
385static struct resource wm831x_ldo1_resources[] = {
386 {
387 .start = WM831X_LDO1_CONTROL,
388 .end = WM831X_LDO1_SLEEP_CONTROL,
389 .flags = IORESOURCE_IO,
390 },
391 {
392 .name = "UV",
393 .start = WM831X_IRQ_UV_LDO1,
394 .end = WM831X_IRQ_UV_LDO1,
395 .flags = IORESOURCE_IRQ,
396 },
397};
398
399static struct resource wm831x_ldo2_resources[] = {
400 {
401 .start = WM831X_LDO2_CONTROL,
402 .end = WM831X_LDO2_SLEEP_CONTROL,
403 .flags = IORESOURCE_IO,
404 },
405 {
406 .name = "UV",
407 .start = WM831X_IRQ_UV_LDO2,
408 .end = WM831X_IRQ_UV_LDO2,
409 .flags = IORESOURCE_IRQ,
410 },
411};
412
413static struct resource wm831x_ldo3_resources[] = {
414 {
415 .start = WM831X_LDO3_CONTROL,
416 .end = WM831X_LDO3_SLEEP_CONTROL,
417 .flags = IORESOURCE_IO,
418 },
419 {
420 .name = "UV",
421 .start = WM831X_IRQ_UV_LDO3,
422 .end = WM831X_IRQ_UV_LDO3,
423 .flags = IORESOURCE_IRQ,
424 },
425};
426
427static struct resource wm831x_ldo4_resources[] = {
428 {
429 .start = WM831X_LDO4_CONTROL,
430 .end = WM831X_LDO4_SLEEP_CONTROL,
431 .flags = IORESOURCE_IO,
432 },
433 {
434 .name = "UV",
435 .start = WM831X_IRQ_UV_LDO4,
436 .end = WM831X_IRQ_UV_LDO4,
437 .flags = IORESOURCE_IRQ,
438 },
439};
440
441static struct resource wm831x_ldo5_resources[] = {
442 {
443 .start = WM831X_LDO5_CONTROL,
444 .end = WM831X_LDO5_SLEEP_CONTROL,
445 .flags = IORESOURCE_IO,
446 },
447 {
448 .name = "UV",
449 .start = WM831X_IRQ_UV_LDO5,
450 .end = WM831X_IRQ_UV_LDO5,
451 .flags = IORESOURCE_IRQ,
452 },
453};
454
455static struct resource wm831x_ldo6_resources[] = {
456 {
457 .start = WM831X_LDO6_CONTROL,
458 .end = WM831X_LDO6_SLEEP_CONTROL,
459 .flags = IORESOURCE_IO,
460 },
461 {
462 .name = "UV",
463 .start = WM831X_IRQ_UV_LDO6,
464 .end = WM831X_IRQ_UV_LDO6,
465 .flags = IORESOURCE_IRQ,
466 },
467};
468
469static struct resource wm831x_ldo7_resources[] = {
470 {
471 .start = WM831X_LDO7_CONTROL,
472 .end = WM831X_LDO7_SLEEP_CONTROL,
473 .flags = IORESOURCE_IO,
474 },
475 {
476 .name = "UV",
477 .start = WM831X_IRQ_UV_LDO7,
478 .end = WM831X_IRQ_UV_LDO7,
479 .flags = IORESOURCE_IRQ,
480 },
481};
482
483static struct resource wm831x_ldo8_resources[] = {
484 {
485 .start = WM831X_LDO8_CONTROL,
486 .end = WM831X_LDO8_SLEEP_CONTROL,
487 .flags = IORESOURCE_IO,
488 },
489 {
490 .name = "UV",
491 .start = WM831X_IRQ_UV_LDO8,
492 .end = WM831X_IRQ_UV_LDO8,
493 .flags = IORESOURCE_IRQ,
494 },
495};
496
497static struct resource wm831x_ldo9_resources[] = {
498 {
499 .start = WM831X_LDO9_CONTROL,
500 .end = WM831X_LDO9_SLEEP_CONTROL,
501 .flags = IORESOURCE_IO,
502 },
503 {
504 .name = "UV",
505 .start = WM831X_IRQ_UV_LDO9,
506 .end = WM831X_IRQ_UV_LDO9,
507 .flags = IORESOURCE_IRQ,
508 },
509};
510
511static struct resource wm831x_ldo10_resources[] = {
512 {
513 .start = WM831X_LDO10_CONTROL,
514 .end = WM831X_LDO10_SLEEP_CONTROL,
515 .flags = IORESOURCE_IO,
516 },
517 {
518 .name = "UV",
519 .start = WM831X_IRQ_UV_LDO10,
520 .end = WM831X_IRQ_UV_LDO10,
521 .flags = IORESOURCE_IRQ,
522 },
523};
524
525static struct resource wm831x_ldo11_resources[] = {
526 {
527 .start = WM831X_LDO11_ON_CONTROL,
528 .end = WM831X_LDO11_SLEEP_CONTROL,
529 .flags = IORESOURCE_IO,
530 },
531};
532
533static struct resource wm831x_on_resources[] = {
534 {
535 .start = WM831X_IRQ_ON,
536 .end = WM831X_IRQ_ON,
537 .flags = IORESOURCE_IRQ,
538 },
539};
540
541
542static struct resource wm831x_power_resources[] = {
543 {
544 .name = "SYSLO",
545 .start = WM831X_IRQ_PPM_SYSLO,
546 .end = WM831X_IRQ_PPM_SYSLO,
547 .flags = IORESOURCE_IRQ,
548 },
549 {
550 .name = "PWR SRC",
551 .start = WM831X_IRQ_PPM_PWR_SRC,
552 .end = WM831X_IRQ_PPM_PWR_SRC,
553 .flags = IORESOURCE_IRQ,
554 },
555 {
556 .name = "USB CURR",
557 .start = WM831X_IRQ_PPM_USB_CURR,
558 .end = WM831X_IRQ_PPM_USB_CURR,
559 .flags = IORESOURCE_IRQ,
560 },
561 {
562 .name = "BATT HOT",
563 .start = WM831X_IRQ_CHG_BATT_HOT,
564 .end = WM831X_IRQ_CHG_BATT_HOT,
565 .flags = IORESOURCE_IRQ,
566 },
567 {
568 .name = "BATT COLD",
569 .start = WM831X_IRQ_CHG_BATT_COLD,
570 .end = WM831X_IRQ_CHG_BATT_COLD,
571 .flags = IORESOURCE_IRQ,
572 },
573 {
574 .name = "BATT FAIL",
575 .start = WM831X_IRQ_CHG_BATT_FAIL,
576 .end = WM831X_IRQ_CHG_BATT_FAIL,
577 .flags = IORESOURCE_IRQ,
578 },
579 {
580 .name = "OV",
581 .start = WM831X_IRQ_CHG_OV,
582 .end = WM831X_IRQ_CHG_OV,
583 .flags = IORESOURCE_IRQ,
584 },
585 {
586 .name = "END",
587 .start = WM831X_IRQ_CHG_END,
588 .end = WM831X_IRQ_CHG_END,
589 .flags = IORESOURCE_IRQ,
590 },
591 {
592 .name = "TO",
593 .start = WM831X_IRQ_CHG_TO,
594 .end = WM831X_IRQ_CHG_TO,
595 .flags = IORESOURCE_IRQ,
596 },
597 {
598 .name = "MODE",
599 .start = WM831X_IRQ_CHG_MODE,
600 .end = WM831X_IRQ_CHG_MODE,
601 .flags = IORESOURCE_IRQ,
602 },
603 {
604 .name = "START",
605 .start = WM831X_IRQ_CHG_START,
606 .end = WM831X_IRQ_CHG_START,
607 .flags = IORESOURCE_IRQ,
608 },
609};
610
611static struct resource wm831x_rtc_resources[] = {
612 {
613 .name = "PER",
614 .start = WM831X_IRQ_RTC_PER,
615 .end = WM831X_IRQ_RTC_PER,
616 .flags = IORESOURCE_IRQ,
617 },
618 {
619 .name = "ALM",
620 .start = WM831X_IRQ_RTC_ALM,
621 .end = WM831X_IRQ_RTC_ALM,
622 .flags = IORESOURCE_IRQ,
623 },
624};
625
626static struct resource wm831x_status1_resources[] = {
627 {
628 .start = WM831X_STATUS_LED_1,
629 .end = WM831X_STATUS_LED_1,
630 .flags = IORESOURCE_IO,
631 },
632};
633
634static struct resource wm831x_status2_resources[] = {
635 {
636 .start = WM831X_STATUS_LED_2,
637 .end = WM831X_STATUS_LED_2,
638 .flags = IORESOURCE_IO,
639 },
640};
641
642static struct resource wm831x_touch_resources[] = {
643 {
644 .name = "TCHPD",
645 .start = WM831X_IRQ_TCHPD,
646 .end = WM831X_IRQ_TCHPD,
647 .flags = IORESOURCE_IRQ,
648 },
649 {
650 .name = "TCHDATA",
651 .start = WM831X_IRQ_TCHDATA,
652 .end = WM831X_IRQ_TCHDATA,
653 .flags = IORESOURCE_IRQ,
654 },
655};
656
657static struct resource wm831x_wdt_resources[] = {
658 {
659 .start = WM831X_IRQ_WDOG_TO,
660 .end = WM831X_IRQ_WDOG_TO,
661 .flags = IORESOURCE_IRQ,
662 },
663};
664
665static struct mfd_cell wm8310_devs[] = {
c26964ea
MB
666 {
667 .name = "wm831x-backup",
668 },
d2bedfe7
MB
669 {
670 .name = "wm831x-buckv",
671 .id = 1,
672 .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
673 .resources = wm831x_dcdc1_resources,
674 },
675 {
676 .name = "wm831x-buckv",
677 .id = 2,
678 .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
679 .resources = wm831x_dcdc2_resources,
680 },
681 {
682 .name = "wm831x-buckp",
683 .id = 3,
684 .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
685 .resources = wm831x_dcdc3_resources,
686 },
687 {
688 .name = "wm831x-boostp",
689 .id = 4,
690 .num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
691 .resources = wm831x_dcdc4_resources,
692 },
a5e06781
MB
693 {
694 .name = "wm831x-clk",
695 },
d2bedfe7
MB
696 {
697 .name = "wm831x-epe",
698 .id = 1,
699 },
700 {
701 .name = "wm831x-epe",
702 .id = 2,
703 },
704 {
705 .name = "wm831x-gpio",
706 .num_resources = ARRAY_SIZE(wm831x_gpio_resources),
707 .resources = wm831x_gpio_resources,
708 },
709 {
710 .name = "wm831x-hwmon",
711 },
712 {
713 .name = "wm831x-isink",
714 .id = 1,
715 .num_resources = ARRAY_SIZE(wm831x_isink1_resources),
716 .resources = wm831x_isink1_resources,
717 },
718 {
719 .name = "wm831x-isink",
720 .id = 2,
721 .num_resources = ARRAY_SIZE(wm831x_isink2_resources),
722 .resources = wm831x_isink2_resources,
723 },
724 {
725 .name = "wm831x-ldo",
726 .id = 1,
727 .num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
728 .resources = wm831x_ldo1_resources,
729 },
730 {
731 .name = "wm831x-ldo",
732 .id = 2,
733 .num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
734 .resources = wm831x_ldo2_resources,
735 },
736 {
737 .name = "wm831x-ldo",
738 .id = 3,
739 .num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
740 .resources = wm831x_ldo3_resources,
741 },
742 {
743 .name = "wm831x-ldo",
744 .id = 4,
745 .num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
746 .resources = wm831x_ldo4_resources,
747 },
748 {
749 .name = "wm831x-ldo",
750 .id = 5,
751 .num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
752 .resources = wm831x_ldo5_resources,
753 },
754 {
755 .name = "wm831x-ldo",
756 .id = 6,
757 .num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
758 .resources = wm831x_ldo6_resources,
759 },
760 {
761 .name = "wm831x-aldo",
762 .id = 7,
763 .num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
764 .resources = wm831x_ldo7_resources,
765 },
766 {
767 .name = "wm831x-aldo",
768 .id = 8,
769 .num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
770 .resources = wm831x_ldo8_resources,
771 },
772 {
773 .name = "wm831x-aldo",
774 .id = 9,
775 .num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
776 .resources = wm831x_ldo9_resources,
777 },
778 {
779 .name = "wm831x-aldo",
780 .id = 10,
781 .num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
782 .resources = wm831x_ldo10_resources,
783 },
784 {
785 .name = "wm831x-alive-ldo",
786 .id = 11,
787 .num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
788 .resources = wm831x_ldo11_resources,
789 },
790 {
791 .name = "wm831x-on",
792 .num_resources = ARRAY_SIZE(wm831x_on_resources),
793 .resources = wm831x_on_resources,
794 },
795 {
796 .name = "wm831x-power",
797 .num_resources = ARRAY_SIZE(wm831x_power_resources),
798 .resources = wm831x_power_resources,
799 },
d2bedfe7
MB
800 {
801 .name = "wm831x-status",
802 .id = 1,
803 .num_resources = ARRAY_SIZE(wm831x_status1_resources),
804 .resources = wm831x_status1_resources,
805 },
806 {
807 .name = "wm831x-status",
808 .id = 2,
809 .num_resources = ARRAY_SIZE(wm831x_status2_resources),
810 .resources = wm831x_status2_resources,
811 },
812 {
813 .name = "wm831x-watchdog",
814 .num_resources = ARRAY_SIZE(wm831x_wdt_resources),
815 .resources = wm831x_wdt_resources,
816 },
817};
818
819static struct mfd_cell wm8311_devs[] = {
c26964ea
MB
820 {
821 .name = "wm831x-backup",
822 },
d2bedfe7
MB
823 {
824 .name = "wm831x-buckv",
825 .id = 1,
826 .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
827 .resources = wm831x_dcdc1_resources,
828 },
829 {
830 .name = "wm831x-buckv",
831 .id = 2,
832 .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
833 .resources = wm831x_dcdc2_resources,
834 },
835 {
836 .name = "wm831x-buckp",
837 .id = 3,
838 .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
839 .resources = wm831x_dcdc3_resources,
840 },
841 {
842 .name = "wm831x-boostp",
843 .id = 4,
844 .num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
845 .resources = wm831x_dcdc4_resources,
846 },
a5e06781
MB
847 {
848 .name = "wm831x-clk",
849 },
d2bedfe7
MB
850 {
851 .name = "wm831x-epe",
852 .id = 1,
853 },
854 {
855 .name = "wm831x-epe",
856 .id = 2,
857 },
858 {
859 .name = "wm831x-gpio",
860 .num_resources = ARRAY_SIZE(wm831x_gpio_resources),
861 .resources = wm831x_gpio_resources,
862 },
863 {
864 .name = "wm831x-hwmon",
865 },
866 {
867 .name = "wm831x-isink",
868 .id = 1,
869 .num_resources = ARRAY_SIZE(wm831x_isink1_resources),
870 .resources = wm831x_isink1_resources,
871 },
872 {
873 .name = "wm831x-isink",
874 .id = 2,
875 .num_resources = ARRAY_SIZE(wm831x_isink2_resources),
876 .resources = wm831x_isink2_resources,
877 },
878 {
879 .name = "wm831x-ldo",
880 .id = 1,
881 .num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
882 .resources = wm831x_ldo1_resources,
883 },
884 {
885 .name = "wm831x-ldo",
886 .id = 2,
887 .num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
888 .resources = wm831x_ldo2_resources,
889 },
890 {
891 .name = "wm831x-ldo",
892 .id = 3,
893 .num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
894 .resources = wm831x_ldo3_resources,
895 },
896 {
897 .name = "wm831x-ldo",
898 .id = 4,
899 .num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
900 .resources = wm831x_ldo4_resources,
901 },
902 {
903 .name = "wm831x-ldo",
904 .id = 5,
905 .num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
906 .resources = wm831x_ldo5_resources,
907 },
908 {
909 .name = "wm831x-aldo",
910 .id = 7,
911 .num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
912 .resources = wm831x_ldo7_resources,
913 },
914 {
915 .name = "wm831x-alive-ldo",
916 .id = 11,
917 .num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
918 .resources = wm831x_ldo11_resources,
919 },
920 {
921 .name = "wm831x-on",
922 .num_resources = ARRAY_SIZE(wm831x_on_resources),
923 .resources = wm831x_on_resources,
924 },
925 {
926 .name = "wm831x-power",
927 .num_resources = ARRAY_SIZE(wm831x_power_resources),
928 .resources = wm831x_power_resources,
929 },
d2bedfe7
MB
930 {
931 .name = "wm831x-status",
932 .id = 1,
933 .num_resources = ARRAY_SIZE(wm831x_status1_resources),
934 .resources = wm831x_status1_resources,
935 },
936 {
937 .name = "wm831x-status",
938 .id = 2,
939 .num_resources = ARRAY_SIZE(wm831x_status2_resources),
940 .resources = wm831x_status2_resources,
941 },
d2bedfe7
MB
942 {
943 .name = "wm831x-watchdog",
944 .num_resources = ARRAY_SIZE(wm831x_wdt_resources),
945 .resources = wm831x_wdt_resources,
946 },
947};
948
949static struct mfd_cell wm8312_devs[] = {
c26964ea
MB
950 {
951 .name = "wm831x-backup",
952 },
d2bedfe7
MB
953 {
954 .name = "wm831x-buckv",
955 .id = 1,
956 .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
957 .resources = wm831x_dcdc1_resources,
958 },
959 {
960 .name = "wm831x-buckv",
961 .id = 2,
962 .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
963 .resources = wm831x_dcdc2_resources,
964 },
965 {
966 .name = "wm831x-buckp",
967 .id = 3,
968 .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
969 .resources = wm831x_dcdc3_resources,
970 },
971 {
972 .name = "wm831x-boostp",
973 .id = 4,
974 .num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
975 .resources = wm831x_dcdc4_resources,
976 },
a5e06781
MB
977 {
978 .name = "wm831x-clk",
979 },
d2bedfe7
MB
980 {
981 .name = "wm831x-epe",
982 .id = 1,
983 },
984 {
985 .name = "wm831x-epe",
986 .id = 2,
987 },
988 {
989 .name = "wm831x-gpio",
990 .num_resources = ARRAY_SIZE(wm831x_gpio_resources),
991 .resources = wm831x_gpio_resources,
992 },
993 {
994 .name = "wm831x-hwmon",
995 },
996 {
997 .name = "wm831x-isink",
998 .id = 1,
999 .num_resources = ARRAY_SIZE(wm831x_isink1_resources),
1000 .resources = wm831x_isink1_resources,
1001 },
1002 {
1003 .name = "wm831x-isink",
1004 .id = 2,
1005 .num_resources = ARRAY_SIZE(wm831x_isink2_resources),
1006 .resources = wm831x_isink2_resources,
1007 },
1008 {
1009 .name = "wm831x-ldo",
1010 .id = 1,
1011 .num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
1012 .resources = wm831x_ldo1_resources,
1013 },
1014 {
1015 .name = "wm831x-ldo",
1016 .id = 2,
1017 .num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
1018 .resources = wm831x_ldo2_resources,
1019 },
1020 {
1021 .name = "wm831x-ldo",
1022 .id = 3,
1023 .num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
1024 .resources = wm831x_ldo3_resources,
1025 },
1026 {
1027 .name = "wm831x-ldo",
1028 .id = 4,
1029 .num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
1030 .resources = wm831x_ldo4_resources,
1031 },
1032 {
1033 .name = "wm831x-ldo",
1034 .id = 5,
1035 .num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
1036 .resources = wm831x_ldo5_resources,
1037 },
1038 {
1039 .name = "wm831x-ldo",
1040 .id = 6,
1041 .num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
1042 .resources = wm831x_ldo6_resources,
1043 },
1044 {
1045 .name = "wm831x-aldo",
1046 .id = 7,
1047 .num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
1048 .resources = wm831x_ldo7_resources,
1049 },
1050 {
1051 .name = "wm831x-aldo",
1052 .id = 8,
1053 .num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
1054 .resources = wm831x_ldo8_resources,
1055 },
1056 {
1057 .name = "wm831x-aldo",
1058 .id = 9,
1059 .num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
1060 .resources = wm831x_ldo9_resources,
1061 },
1062 {
1063 .name = "wm831x-aldo",
1064 .id = 10,
1065 .num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
1066 .resources = wm831x_ldo10_resources,
1067 },
1068 {
1069 .name = "wm831x-alive-ldo",
1070 .id = 11,
1071 .num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
1072 .resources = wm831x_ldo11_resources,
1073 },
1074 {
1075 .name = "wm831x-on",
1076 .num_resources = ARRAY_SIZE(wm831x_on_resources),
1077 .resources = wm831x_on_resources,
1078 },
1079 {
1080 .name = "wm831x-power",
1081 .num_resources = ARRAY_SIZE(wm831x_power_resources),
1082 .resources = wm831x_power_resources,
1083 },
d2bedfe7
MB
1084 {
1085 .name = "wm831x-status",
1086 .id = 1,
1087 .num_resources = ARRAY_SIZE(wm831x_status1_resources),
1088 .resources = wm831x_status1_resources,
1089 },
1090 {
1091 .name = "wm831x-status",
1092 .id = 2,
1093 .num_resources = ARRAY_SIZE(wm831x_status2_resources),
1094 .resources = wm831x_status2_resources,
1095 },
d2bedfe7
MB
1096 {
1097 .name = "wm831x-watchdog",
1098 .num_resources = ARRAY_SIZE(wm831x_wdt_resources),
1099 .resources = wm831x_wdt_resources,
1100 },
1101};
1102
d4e0a89e
MB
1103static struct mfd_cell wm8320_devs[] = {
1104 {
1105 .name = "wm831x-backup",
1106 },
1107 {
1108 .name = "wm831x-buckv",
1109 .id = 1,
1110 .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
1111 .resources = wm831x_dcdc1_resources,
1112 },
1113 {
1114 .name = "wm831x-buckv",
1115 .id = 2,
1116 .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
1117 .resources = wm831x_dcdc2_resources,
1118 },
1119 {
1120 .name = "wm831x-buckp",
1121 .id = 3,
1122 .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
1123 .resources = wm831x_dcdc3_resources,
1124 },
1125 {
1126 .name = "wm831x-buckp",
1127 .id = 4,
1128 .num_resources = ARRAY_SIZE(wm8320_dcdc4_buck_resources),
1129 .resources = wm8320_dcdc4_buck_resources,
1130 },
a5e06781
MB
1131 {
1132 .name = "wm831x-clk",
1133 },
d4e0a89e
MB
1134 {
1135 .name = "wm831x-gpio",
1136 .num_resources = ARRAY_SIZE(wm831x_gpio_resources),
1137 .resources = wm831x_gpio_resources,
1138 },
1139 {
1140 .name = "wm831x-hwmon",
1141 },
1142 {
1143 .name = "wm831x-ldo",
1144 .id = 1,
1145 .num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
1146 .resources = wm831x_ldo1_resources,
1147 },
1148 {
1149 .name = "wm831x-ldo",
1150 .id = 2,
1151 .num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
1152 .resources = wm831x_ldo2_resources,
1153 },
1154 {
1155 .name = "wm831x-ldo",
1156 .id = 3,
1157 .num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
1158 .resources = wm831x_ldo3_resources,
1159 },
1160 {
1161 .name = "wm831x-ldo",
1162 .id = 4,
1163 .num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
1164 .resources = wm831x_ldo4_resources,
1165 },
1166 {
1167 .name = "wm831x-ldo",
1168 .id = 5,
1169 .num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
1170 .resources = wm831x_ldo5_resources,
1171 },
1172 {
1173 .name = "wm831x-ldo",
1174 .id = 6,
1175 .num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
1176 .resources = wm831x_ldo6_resources,
1177 },
1178 {
1179 .name = "wm831x-aldo",
1180 .id = 7,
1181 .num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
1182 .resources = wm831x_ldo7_resources,
1183 },
1184 {
1185 .name = "wm831x-aldo",
1186 .id = 8,
1187 .num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
1188 .resources = wm831x_ldo8_resources,
1189 },
1190 {
1191 .name = "wm831x-aldo",
1192 .id = 9,
1193 .num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
1194 .resources = wm831x_ldo9_resources,
1195 },
1196 {
1197 .name = "wm831x-aldo",
1198 .id = 10,
1199 .num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
1200 .resources = wm831x_ldo10_resources,
1201 },
1202 {
1203 .name = "wm831x-alive-ldo",
1204 .id = 11,
1205 .num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
1206 .resources = wm831x_ldo11_resources,
1207 },
1208 {
1209 .name = "wm831x-on",
1210 .num_resources = ARRAY_SIZE(wm831x_on_resources),
1211 .resources = wm831x_on_resources,
1212 },
d4e0a89e
MB
1213 {
1214 .name = "wm831x-status",
1215 .id = 1,
1216 .num_resources = ARRAY_SIZE(wm831x_status1_resources),
1217 .resources = wm831x_status1_resources,
1218 },
1219 {
1220 .name = "wm831x-status",
1221 .id = 2,
1222 .num_resources = ARRAY_SIZE(wm831x_status2_resources),
1223 .resources = wm831x_status2_resources,
1224 },
1225 {
1226 .name = "wm831x-watchdog",
1227 .num_resources = ARRAY_SIZE(wm831x_wdt_resources),
1228 .resources = wm831x_wdt_resources,
1229 },
1230};
1231
266a5e02
MB
1232static struct mfd_cell touch_devs[] = {
1233 {
1234 .name = "wm831x-touch",
1235 .num_resources = ARRAY_SIZE(wm831x_touch_resources),
1236 .resources = wm831x_touch_resources,
1237 },
1238};
1239
b9d03d99
MB
1240static struct mfd_cell rtc_devs[] = {
1241 {
1242 .name = "wm831x-rtc",
1243 .num_resources = ARRAY_SIZE(wm831x_rtc_resources),
1244 .resources = wm831x_rtc_resources,
1245 },
1246};
266a5e02 1247
63aed85e
MB
1248static struct mfd_cell backlight_devs[] = {
1249 {
1250 .name = "wm831x-backlight",
1251 },
1252};
1253
1df5981b
MB
1254struct regmap_config wm831x_regmap_config = {
1255 .reg_bits = 16,
1256 .val_bits = 16,
1257};
1258EXPORT_SYMBOL_GPL(wm831x_regmap_config);
1259
d2bedfe7
MB
1260/*
1261 * Instantiate the generic non-control parts of the device.
1262 */
e5b48684 1263int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
d2bedfe7
MB
1264{
1265 struct wm831x_pdata *pdata = wm831x->dev->platform_data;
eb503dc1 1266 int rev, wm831x_num;
d2bedfe7 1267 enum wm831x_parent parent;
0b14c22e 1268 int ret, i;
d2bedfe7
MB
1269
1270 mutex_init(&wm831x->io_lock);
1271 mutex_init(&wm831x->key_lock);
1272 dev_set_drvdata(wm831x->dev, wm831x);
1273
1274 ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
1275 if (ret < 0) {
1276 dev_err(wm831x->dev, "Failed to read parent ID: %d\n", ret);
1df5981b 1277 goto err_regmap;
d2bedfe7 1278 }
b93cef55
MB
1279 switch (ret) {
1280 case 0x6204:
1281 case 0x6246:
1282 break;
1283 default:
d2bedfe7
MB
1284 dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret);
1285 ret = -EINVAL;
1df5981b 1286 goto err_regmap;
d2bedfe7
MB
1287 }
1288
1289 ret = wm831x_reg_read(wm831x, WM831X_REVISION);
1290 if (ret < 0) {
1291 dev_err(wm831x->dev, "Failed to read revision: %d\n", ret);
1df5981b 1292 goto err_regmap;
d2bedfe7
MB
1293 }
1294 rev = (ret & WM831X_PARENT_REV_MASK) >> WM831X_PARENT_REV_SHIFT;
1295
1296 ret = wm831x_reg_read(wm831x, WM831X_RESET_ID);
1297 if (ret < 0) {
1298 dev_err(wm831x->dev, "Failed to read device ID: %d\n", ret);
1df5981b 1299 goto err_regmap;
d2bedfe7
MB
1300 }
1301
894362f5
MB
1302 /* Some engineering samples do not have the ID set, rely on
1303 * the device being registered correctly.
1304 */
1305 if (ret == 0) {
1306 dev_info(wm831x->dev, "Device is an engineering sample\n");
1307 ret = id;
1308 }
1309
d2bedfe7 1310 switch (ret) {
894362f5 1311 case WM8310:
d2bedfe7 1312 parent = WM8310;
6f2ecaae 1313 wm831x->num_gpio = 16;
b03b4d7c 1314 wm831x->charger_irq_wake = 1;
f92e8f81
MB
1315 if (rev > 0) {
1316 wm831x->has_gpio_ena = 1;
1317 wm831x->has_cs_sts = 1;
1318 }
1319
894362f5 1320 dev_info(wm831x->dev, "WM8310 revision %c\n", 'A' + rev);
d2bedfe7
MB
1321 break;
1322
894362f5 1323 case WM8311:
d2bedfe7 1324 parent = WM8311;
6f2ecaae 1325 wm831x->num_gpio = 16;
b03b4d7c 1326 wm831x->charger_irq_wake = 1;
f92e8f81
MB
1327 if (rev > 0) {
1328 wm831x->has_gpio_ena = 1;
1329 wm831x->has_cs_sts = 1;
1330 }
1331
894362f5 1332 dev_info(wm831x->dev, "WM8311 revision %c\n", 'A' + rev);
d2bedfe7
MB
1333 break;
1334
894362f5 1335 case WM8312:
d2bedfe7 1336 parent = WM8312;
6f2ecaae 1337 wm831x->num_gpio = 16;
b03b4d7c 1338 wm831x->charger_irq_wake = 1;
f92e8f81
MB
1339 if (rev > 0) {
1340 wm831x->has_gpio_ena = 1;
1341 wm831x->has_cs_sts = 1;
1342 }
1343
894362f5 1344 dev_info(wm831x->dev, "WM8312 revision %c\n", 'A' + rev);
d2bedfe7
MB
1345 break;
1346
d4e0a89e
MB
1347 case WM8320:
1348 parent = WM8320;
1349 wm831x->num_gpio = 12;
1350 dev_info(wm831x->dev, "WM8320 revision %c\n", 'A' + rev);
1351 break;
1352
88913521
MB
1353 case WM8321:
1354 parent = WM8321;
1355 wm831x->num_gpio = 12;
1356 dev_info(wm831x->dev, "WM8321 revision %c\n", 'A' + rev);
1357 break;
1358
0b315884
MB
1359 case WM8325:
1360 parent = WM8325;
1361 wm831x->num_gpio = 12;
1362 dev_info(wm831x->dev, "WM8325 revision %c\n", 'A' + rev);
1363 break;
1364
412dc11d
MB
1365 case WM8326:
1366 parent = WM8326;
1367 wm831x->num_gpio = 12;
1368 dev_info(wm831x->dev, "WM8326 revision %c\n", 'A' + rev);
1369 break;
1370
d2bedfe7
MB
1371 default:
1372 dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret);
1373 ret = -EINVAL;
1df5981b 1374 goto err_regmap;
d2bedfe7
MB
1375 }
1376
1377 /* This will need revisiting in future but is OK for all
1378 * current parts.
1379 */
1380 if (parent != id)
894362f5 1381 dev_warn(wm831x->dev, "Device was registered as a WM%lx\n",
d2bedfe7
MB
1382 id);
1383
1384 /* Bootstrap the user key */
1385 ret = wm831x_reg_read(wm831x, WM831X_SECURITY_KEY);
1386 if (ret < 0) {
1387 dev_err(wm831x->dev, "Failed to read security key: %d\n", ret);
1df5981b 1388 goto err_regmap;
d2bedfe7
MB
1389 }
1390 if (ret != 0) {
1391 dev_warn(wm831x->dev, "Security key had non-zero value %x\n",
1392 ret);
1393 wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0);
1394 }
1395 wm831x->locked = 1;
1396
1397 if (pdata && pdata->pre_init) {
1398 ret = pdata->pre_init(wm831x);
1399 if (ret != 0) {
1400 dev_err(wm831x->dev, "pre_init() failed: %d\n", ret);
1df5981b 1401 goto err_regmap;
d2bedfe7
MB
1402 }
1403 }
1404
0b14c22e
MB
1405 if (pdata) {
1406 for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
1407 if (!pdata->gpio_defaults[i])
1408 continue;
1409
1410 wm831x_reg_write(wm831x,
1411 WM831X_GPIO1_CONTROL + i,
1412 pdata->gpio_defaults[i] & 0xffff);
1413 }
1414 }
1415
eb503dc1
MB
1416 /* Multiply by 10 as we have many subdevices of the same type */
1417 if (pdata && pdata->wm831x_num)
1418 wm831x_num = pdata->wm831x_num * 10;
1419 else
1420 wm831x_num = -1;
1421
7d4d0a3e
MB
1422 ret = wm831x_irq_init(wm831x, irq);
1423 if (ret != 0)
1df5981b 1424 goto err_regmap;
7d4d0a3e 1425
e69b6de1 1426 wm831x_auxadc_init(wm831x);
473fe736 1427
d2bedfe7
MB
1428 /* The core device is up, instantiate the subdevices. */
1429 switch (parent) {
1430 case WM8310:
eb503dc1 1431 ret = mfd_add_devices(wm831x->dev, wm831x_num,
d2bedfe7 1432 wm8310_devs, ARRAY_SIZE(wm8310_devs),
5fb4d38b 1433 NULL, wm831x->irq_base);
d2bedfe7
MB
1434 break;
1435
1436 case WM8311:
eb503dc1 1437 ret = mfd_add_devices(wm831x->dev, wm831x_num,
d2bedfe7 1438 wm8311_devs, ARRAY_SIZE(wm8311_devs),
5fb4d38b 1439 NULL, wm831x->irq_base);
266a5e02
MB
1440 if (!pdata || !pdata->disable_touch)
1441 mfd_add_devices(wm831x->dev, wm831x_num,
1442 touch_devs, ARRAY_SIZE(touch_devs),
1443 NULL, wm831x->irq_base);
d2bedfe7
MB
1444 break;
1445
1446 case WM8312:
eb503dc1 1447 ret = mfd_add_devices(wm831x->dev, wm831x_num,
d2bedfe7 1448 wm8312_devs, ARRAY_SIZE(wm8312_devs),
5fb4d38b 1449 NULL, wm831x->irq_base);
266a5e02
MB
1450 if (!pdata || !pdata->disable_touch)
1451 mfd_add_devices(wm831x->dev, wm831x_num,
1452 touch_devs, ARRAY_SIZE(touch_devs),
1453 NULL, wm831x->irq_base);
d2bedfe7
MB
1454 break;
1455
d4e0a89e 1456 case WM8320:
88913521 1457 case WM8321:
0b315884 1458 case WM8325:
412dc11d 1459 case WM8326:
eb503dc1 1460 ret = mfd_add_devices(wm831x->dev, wm831x_num,
0b315884 1461 wm8320_devs, ARRAY_SIZE(wm8320_devs),
bd7c72ed 1462 NULL, wm831x->irq_base);
0b315884
MB
1463 break;
1464
d2bedfe7
MB
1465 default:
1466 /* If this happens the bus probe function is buggy */
1467 BUG();
1468 }
1469
1470 if (ret != 0) {
1471 dev_err(wm831x->dev, "Failed to add children\n");
7d4d0a3e 1472 goto err_irq;
d2bedfe7
MB
1473 }
1474
b9d03d99
MB
1475 /* The RTC can only be used if the 32.768kHz crystal is
1476 * enabled; this can't be controlled by software at runtime.
1477 */
1478 ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_2);
1479 if (ret < 0) {
1480 dev_err(wm831x->dev, "Failed to read clock status: %d\n", ret);
1481 goto err_irq;
1482 }
1483
1484 if (ret & WM831X_XTAL_ENA) {
1485 ret = mfd_add_devices(wm831x->dev, wm831x_num,
1486 rtc_devs, ARRAY_SIZE(rtc_devs),
1487 NULL, wm831x->irq_base);
1488 if (ret != 0) {
1489 dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret);
1490 goto err_irq;
1491 }
1492 } else {
1493 dev_info(wm831x->dev, "32.768kHz clock disabled, no RTC\n");
1494 }
1495
63aed85e
MB
1496 if (pdata && pdata->backlight) {
1497 /* Treat errors as non-critical */
eb503dc1 1498 ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs,
5fb4d38b
MB
1499 ARRAY_SIZE(backlight_devs), NULL,
1500 wm831x->irq_base);
63aed85e
MB
1501 if (ret < 0)
1502 dev_err(wm831x->dev, "Failed to add backlight: %d\n",
1503 ret);
1504 }
1505
6704e517
MB
1506 wm831x_otp_init(wm831x);
1507
d2bedfe7
MB
1508 if (pdata && pdata->post_init) {
1509 ret = pdata->post_init(wm831x);
1510 if (ret != 0) {
1511 dev_err(wm831x->dev, "post_init() failed: %d\n", ret);
7d4d0a3e 1512 goto err_irq;
d2bedfe7
MB
1513 }
1514 }
1515
1516 return 0;
1517
7d4d0a3e
MB
1518err_irq:
1519 wm831x_irq_exit(wm831x);
1df5981b 1520err_regmap:
d2bedfe7 1521 mfd_remove_devices(wm831x->dev);
1df5981b 1522 regmap_exit(wm831x->regmap);
d2bedfe7
MB
1523 kfree(wm831x);
1524 return ret;
1525}
1526
e5b48684 1527void wm831x_device_exit(struct wm831x *wm831x)
d2bedfe7 1528{
6704e517 1529 wm831x_otp_exit(wm831x);
d2bedfe7 1530 mfd_remove_devices(wm831x->dev);
473fe736
MB
1531 if (wm831x->irq_base)
1532 free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x);
7d4d0a3e 1533 wm831x_irq_exit(wm831x);
1df5981b 1534 regmap_exit(wm831x->regmap);
d2bedfe7
MB
1535 kfree(wm831x);
1536}
1537
e5b48684 1538int wm831x_device_suspend(struct wm831x *wm831x)
b03b4d7c
MB
1539{
1540 int reg, mask;
1541
1542 /* If the charger IRQs are a wake source then make sure we ack
1543 * them even if they're not actively being used (eg, no power
1544 * driver or no IRQ line wired up) then acknowledge the
1545 * interrupts otherwise suspend won't last very long.
1546 */
1547 if (wm831x->charger_irq_wake) {
1548 reg = wm831x_reg_read(wm831x, WM831X_INTERRUPT_STATUS_2_MASK);
1549
1550 mask = WM831X_CHG_BATT_HOT_EINT |
1551 WM831X_CHG_BATT_COLD_EINT |
1552 WM831X_CHG_BATT_FAIL_EINT |
1553 WM831X_CHG_OV_EINT | WM831X_CHG_END_EINT |
1554 WM831X_CHG_TO_EINT | WM831X_CHG_MODE_EINT |
1555 WM831X_CHG_START_EINT;
1556
1557 /* If any of the interrupts are masked read the statuses */
1558 if (reg & mask)
1559 reg = wm831x_reg_read(wm831x,
1560 WM831X_INTERRUPT_STATUS_2);
1561
1562 if (reg & mask) {
1563 dev_info(wm831x->dev,
1564 "Acknowledging masked charger IRQs: %x\n",
1565 reg & mask);
1566 wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_2,
1567 reg & mask);
1568 }
1569 }
1570
1571 return 0;
1572}
1573
e5b48684 1574MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC");
d2bedfe7
MB
1575MODULE_LICENSE("GPL");
1576MODULE_AUTHOR("Mark Brown");