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