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