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