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