]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/mfd/wm831x-core.c
Merge branch 'x86/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
[mirror_ubuntu-bionic-kernel.git] / drivers / mfd / wm831x-core.c
CommitLineData
d2bedfe7
MB
1/*
2 * wm831x-core.c -- Device access for Wolfson WM831x PMICs
3 *
4 * Copyright 2009 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/module.h>
7e9f9fd4
MB
17#include <linux/bcd.h>
18#include <linux/delay.h>
d2bedfe7 19#include <linux/mfd/core.h>
5a0e3ad6 20#include <linux/slab.h>
1df5981b 21#include <linux/err.h>
f6dd8449
CK
22#include <linux/of.h>
23#include <linux/of_device.h>
d2bedfe7
MB
24
25#include <linux/mfd/wm831x/core.h>
26#include <linux/mfd/wm831x/pdata.h>
7d4d0a3e 27#include <linux/mfd/wm831x/irq.h>
7e9f9fd4 28#include <linux/mfd/wm831x/auxadc.h>
6704e517 29#include <linux/mfd/wm831x/otp.h>
523d9cfb 30#include <linux/mfd/wm831x/pmu.h>
698659d5
MB
31#include <linux/mfd/wm831x/regulator.h>
32
33/* Current settings - values are 2*2^(reg_val/4) microamps. These are
34 * exported since they are used by multiple drivers.
35 */
7716977b 36int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = {
698659d5
MB
37 2,
38 2,
39 3,
40 3,
41 4,
42 5,
43 6,
44 7,
45 8,
46 10,
47 11,
48 13,
49 16,
50 19,
51 23,
52 27,
53 32,
54 38,
55 45,
56 54,
57 64,
58 76,
59 91,
60 108,
61 128,
62 152,
63 181,
64 215,
65 256,
66 304,
67 362,
68 431,
69 512,
70 609,
71 724,
72 861,
73 1024,
74 1218,
75 1448,
76 1722,
77 2048,
78 2435,
79 2896,
80 3444,
81 4096,
82 4871,
83 5793,
84 6889,
85 8192,
86 9742,
87 11585,
88 13777,
89 16384,
90 19484,
91 23170,
92 27554,
93};
94EXPORT_SYMBOL_GPL(wm831x_isinkv_values);
d2bedfe7 95
d2bedfe7
MB
96static int wm831x_reg_locked(struct wm831x *wm831x, unsigned short reg)
97{
98 if (!wm831x->locked)
99 return 0;
100
101 switch (reg) {
102 case WM831X_WATCHDOG:
103 case WM831X_DC4_CONTROL:
104 case WM831X_ON_PIN_CONTROL:
105 case WM831X_BACKUP_CHARGER_CONTROL:
106 case WM831X_CHARGER_CONTROL_1:
107 case WM831X_CHARGER_CONTROL_2:
108 return 1;
109
110 default:
111 return 0;
112 }
113}
114
115/**
116 * wm831x_reg_unlock: Unlock user keyed registers
117 *
118 * The WM831x has a user key preventing writes to particularly
119 * critical registers. This function locks those registers,
120 * allowing writes to them.
121 */
122void wm831x_reg_lock(struct wm831x *wm831x)
123{
124 int ret;
125
126 ret = wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0);
127 if (ret == 0) {
128 dev_vdbg(wm831x->dev, "Registers locked\n");
129
130 mutex_lock(&wm831x->io_lock);
131 WARN_ON(wm831x->locked);
132 wm831x->locked = 1;
133 mutex_unlock(&wm831x->io_lock);
134 } else {
135 dev_err(wm831x->dev, "Failed to lock registers: %d\n", ret);
136 }
137
138}
139EXPORT_SYMBOL_GPL(wm831x_reg_lock);
140
141/**
142 * wm831x_reg_unlock: Unlock user keyed registers
143 *
144 * The WM831x has a user key preventing writes to particularly
145 * critical registers. This function locks those registers,
146 * preventing spurious writes.
147 */
148int wm831x_reg_unlock(struct wm831x *wm831x)
149{
150 int ret;
151
152 /* 0x9716 is the value required to unlock the registers */
153 ret = wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0x9716);
154 if (ret == 0) {
155 dev_vdbg(wm831x->dev, "Registers unlocked\n");
156
157 mutex_lock(&wm831x->io_lock);
158 WARN_ON(!wm831x->locked);
159 wm831x->locked = 0;
160 mutex_unlock(&wm831x->io_lock);
161 }
162
163 return ret;
164}
165EXPORT_SYMBOL_GPL(wm831x_reg_unlock);
166
2e47fff1
MB
167static bool wm831x_reg_readable(struct device *dev, unsigned int reg)
168{
169 switch (reg) {
170 case WM831X_RESET_ID:
171 case WM831X_REVISION:
172 case WM831X_PARENT_ID:
173 case WM831X_SYSVDD_CONTROL:
174 case WM831X_THERMAL_MONITORING:
175 case WM831X_POWER_STATE:
176 case WM831X_WATCHDOG:
177 case WM831X_ON_PIN_CONTROL:
178 case WM831X_RESET_CONTROL:
179 case WM831X_CONTROL_INTERFACE:
180 case WM831X_SECURITY_KEY:
181 case WM831X_SOFTWARE_SCRATCH:
182 case WM831X_OTP_CONTROL:
183 case WM831X_GPIO_LEVEL:
184 case WM831X_SYSTEM_STATUS:
185 case WM831X_ON_SOURCE:
186 case WM831X_OFF_SOURCE:
187 case WM831X_SYSTEM_INTERRUPTS:
188 case WM831X_INTERRUPT_STATUS_1:
189 case WM831X_INTERRUPT_STATUS_2:
190 case WM831X_INTERRUPT_STATUS_3:
191 case WM831X_INTERRUPT_STATUS_4:
192 case WM831X_INTERRUPT_STATUS_5:
193 case WM831X_IRQ_CONFIG:
194 case WM831X_SYSTEM_INTERRUPTS_MASK:
195 case WM831X_INTERRUPT_STATUS_1_MASK:
196 case WM831X_INTERRUPT_STATUS_2_MASK:
197 case WM831X_INTERRUPT_STATUS_3_MASK:
198 case WM831X_INTERRUPT_STATUS_4_MASK:
199 case WM831X_INTERRUPT_STATUS_5_MASK:
200 case WM831X_RTC_WRITE_COUNTER:
201 case WM831X_RTC_TIME_1:
202 case WM831X_RTC_TIME_2:
203 case WM831X_RTC_ALARM_1:
204 case WM831X_RTC_ALARM_2:
205 case WM831X_RTC_CONTROL:
206 case WM831X_RTC_TRIM:
207 case WM831X_TOUCH_CONTROL_1:
208 case WM831X_TOUCH_CONTROL_2:
209 case WM831X_TOUCH_DATA_X:
210 case WM831X_TOUCH_DATA_Y:
211 case WM831X_TOUCH_DATA_Z:
212 case WM831X_AUXADC_DATA:
213 case WM831X_AUXADC_CONTROL:
214 case WM831X_AUXADC_SOURCE:
215 case WM831X_COMPARATOR_CONTROL:
216 case WM831X_COMPARATOR_1:
217 case WM831X_COMPARATOR_2:
218 case WM831X_COMPARATOR_3:
219 case WM831X_COMPARATOR_4:
220 case WM831X_GPIO1_CONTROL:
221 case WM831X_GPIO2_CONTROL:
222 case WM831X_GPIO3_CONTROL:
223 case WM831X_GPIO4_CONTROL:
224 case WM831X_GPIO5_CONTROL:
225 case WM831X_GPIO6_CONTROL:
226 case WM831X_GPIO7_CONTROL:
227 case WM831X_GPIO8_CONTROL:
228 case WM831X_GPIO9_CONTROL:
229 case WM831X_GPIO10_CONTROL:
230 case WM831X_GPIO11_CONTROL:
231 case WM831X_GPIO12_CONTROL:
232 case WM831X_GPIO13_CONTROL:
233 case WM831X_GPIO14_CONTROL:
234 case WM831X_GPIO15_CONTROL:
235 case WM831X_GPIO16_CONTROL:
236 case WM831X_CHARGER_CONTROL_1:
237 case WM831X_CHARGER_CONTROL_2:
238 case WM831X_CHARGER_STATUS:
239 case WM831X_BACKUP_CHARGER_CONTROL:
240 case WM831X_STATUS_LED_1:
241 case WM831X_STATUS_LED_2:
242 case WM831X_CURRENT_SINK_1:
243 case WM831X_CURRENT_SINK_2:
244 case WM831X_DCDC_ENABLE:
245 case WM831X_LDO_ENABLE:
246 case WM831X_DCDC_STATUS:
247 case WM831X_LDO_STATUS:
248 case WM831X_DCDC_UV_STATUS:
249 case WM831X_LDO_UV_STATUS:
250 case WM831X_DC1_CONTROL_1:
251 case WM831X_DC1_CONTROL_2:
252 case WM831X_DC1_ON_CONFIG:
253 case WM831X_DC1_SLEEP_CONTROL:
254 case WM831X_DC1_DVS_CONTROL:
255 case WM831X_DC2_CONTROL_1:
256 case WM831X_DC2_CONTROL_2:
257 case WM831X_DC2_ON_CONFIG:
258 case WM831X_DC2_SLEEP_CONTROL:
259 case WM831X_DC2_DVS_CONTROL:
260 case WM831X_DC3_CONTROL_1:
261 case WM831X_DC3_CONTROL_2:
262 case WM831X_DC3_ON_CONFIG:
263 case WM831X_DC3_SLEEP_CONTROL:
264 case WM831X_DC4_CONTROL:
265 case WM831X_DC4_SLEEP_CONTROL:
266 case WM831X_EPE1_CONTROL:
267 case WM831X_EPE2_CONTROL:
268 case WM831X_LDO1_CONTROL:
269 case WM831X_LDO1_ON_CONTROL:
270 case WM831X_LDO1_SLEEP_CONTROL:
271 case WM831X_LDO2_CONTROL:
272 case WM831X_LDO2_ON_CONTROL:
273 case WM831X_LDO2_SLEEP_CONTROL:
274 case WM831X_LDO3_CONTROL:
275 case WM831X_LDO3_ON_CONTROL:
276 case WM831X_LDO3_SLEEP_CONTROL:
277 case WM831X_LDO4_CONTROL:
278 case WM831X_LDO4_ON_CONTROL:
279 case WM831X_LDO4_SLEEP_CONTROL:
280 case WM831X_LDO5_CONTROL:
281 case WM831X_LDO5_ON_CONTROL:
282 case WM831X_LDO5_SLEEP_CONTROL:
283 case WM831X_LDO6_CONTROL:
284 case WM831X_LDO6_ON_CONTROL:
285 case WM831X_LDO6_SLEEP_CONTROL:
286 case WM831X_LDO7_CONTROL:
287 case WM831X_LDO7_ON_CONTROL:
288 case WM831X_LDO7_SLEEP_CONTROL:
289 case WM831X_LDO8_CONTROL:
290 case WM831X_LDO8_ON_CONTROL:
291 case WM831X_LDO8_SLEEP_CONTROL:
292 case WM831X_LDO9_CONTROL:
293 case WM831X_LDO9_ON_CONTROL:
294 case WM831X_LDO9_SLEEP_CONTROL:
295 case WM831X_LDO10_CONTROL:
296 case WM831X_LDO10_ON_CONTROL:
297 case WM831X_LDO10_SLEEP_CONTROL:
298 case WM831X_LDO11_ON_CONTROL:
299 case WM831X_LDO11_SLEEP_CONTROL:
300 case WM831X_POWER_GOOD_SOURCE_1:
301 case WM831X_POWER_GOOD_SOURCE_2:
302 case WM831X_CLOCK_CONTROL_1:
303 case WM831X_CLOCK_CONTROL_2:
304 case WM831X_FLL_CONTROL_1:
305 case WM831X_FLL_CONTROL_2:
306 case WM831X_FLL_CONTROL_3:
307 case WM831X_FLL_CONTROL_4:
308 case WM831X_FLL_CONTROL_5:
309 case WM831X_UNIQUE_ID_1:
310 case WM831X_UNIQUE_ID_2:
311 case WM831X_UNIQUE_ID_3:
312 case WM831X_UNIQUE_ID_4:
313 case WM831X_UNIQUE_ID_5:
314 case WM831X_UNIQUE_ID_6:
315 case WM831X_UNIQUE_ID_7:
316 case WM831X_UNIQUE_ID_8:
317 case WM831X_FACTORY_OTP_ID:
318 case WM831X_FACTORY_OTP_1:
319 case WM831X_FACTORY_OTP_2:
320 case WM831X_FACTORY_OTP_3:
321 case WM831X_FACTORY_OTP_4:
322 case WM831X_FACTORY_OTP_5:
323 case WM831X_CUSTOMER_OTP_ID:
324 case WM831X_DC1_OTP_CONTROL:
325 case WM831X_DC2_OTP_CONTROL:
326 case WM831X_DC3_OTP_CONTROL:
327 case WM831X_LDO1_2_OTP_CONTROL:
328 case WM831X_LDO3_4_OTP_CONTROL:
329 case WM831X_LDO5_6_OTP_CONTROL:
330 case WM831X_LDO7_8_OTP_CONTROL:
331 case WM831X_LDO9_10_OTP_CONTROL:
332 case WM831X_LDO11_EPE_CONTROL:
333 case WM831X_GPIO1_OTP_CONTROL:
334 case WM831X_GPIO2_OTP_CONTROL:
335 case WM831X_GPIO3_OTP_CONTROL:
336 case WM831X_GPIO4_OTP_CONTROL:
337 case WM831X_GPIO5_OTP_CONTROL:
338 case WM831X_GPIO6_OTP_CONTROL:
339 case WM831X_DBE_CHECK_DATA:
340 return true;
341 default:
342 return false;
343 }
344}
345
346static bool wm831x_reg_writeable(struct device *dev, unsigned int reg)
347{
348 struct wm831x *wm831x = dev_get_drvdata(dev);
349
350 if (wm831x_reg_locked(wm831x, reg))
351 return false;
352
353 switch (reg) {
354 case WM831X_SYSVDD_CONTROL:
355 case WM831X_THERMAL_MONITORING:
356 case WM831X_POWER_STATE:
357 case WM831X_WATCHDOG:
358 case WM831X_ON_PIN_CONTROL:
359 case WM831X_RESET_CONTROL:
360 case WM831X_CONTROL_INTERFACE:
361 case WM831X_SECURITY_KEY:
362 case WM831X_SOFTWARE_SCRATCH:
363 case WM831X_OTP_CONTROL:
364 case WM831X_GPIO_LEVEL:
365 case WM831X_INTERRUPT_STATUS_1:
366 case WM831X_INTERRUPT_STATUS_2:
367 case WM831X_INTERRUPT_STATUS_3:
368 case WM831X_INTERRUPT_STATUS_4:
369 case WM831X_INTERRUPT_STATUS_5:
370 case WM831X_IRQ_CONFIG:
371 case WM831X_SYSTEM_INTERRUPTS_MASK:
372 case WM831X_INTERRUPT_STATUS_1_MASK:
373 case WM831X_INTERRUPT_STATUS_2_MASK:
374 case WM831X_INTERRUPT_STATUS_3_MASK:
375 case WM831X_INTERRUPT_STATUS_4_MASK:
376 case WM831X_INTERRUPT_STATUS_5_MASK:
377 case WM831X_RTC_TIME_1:
378 case WM831X_RTC_TIME_2:
379 case WM831X_RTC_ALARM_1:
380 case WM831X_RTC_ALARM_2:
381 case WM831X_RTC_CONTROL:
382 case WM831X_RTC_TRIM:
383 case WM831X_TOUCH_CONTROL_1:
384 case WM831X_TOUCH_CONTROL_2:
385 case WM831X_AUXADC_CONTROL:
386 case WM831X_AUXADC_SOURCE:
387 case WM831X_COMPARATOR_CONTROL:
388 case WM831X_COMPARATOR_1:
389 case WM831X_COMPARATOR_2:
390 case WM831X_COMPARATOR_3:
391 case WM831X_COMPARATOR_4:
392 case WM831X_GPIO1_CONTROL:
393 case WM831X_GPIO2_CONTROL:
394 case WM831X_GPIO3_CONTROL:
395 case WM831X_GPIO4_CONTROL:
396 case WM831X_GPIO5_CONTROL:
397 case WM831X_GPIO6_CONTROL:
398 case WM831X_GPIO7_CONTROL:
399 case WM831X_GPIO8_CONTROL:
400 case WM831X_GPIO9_CONTROL:
401 case WM831X_GPIO10_CONTROL:
402 case WM831X_GPIO11_CONTROL:
403 case WM831X_GPIO12_CONTROL:
404 case WM831X_GPIO13_CONTROL:
405 case WM831X_GPIO14_CONTROL:
406 case WM831X_GPIO15_CONTROL:
407 case WM831X_GPIO16_CONTROL:
408 case WM831X_CHARGER_CONTROL_1:
409 case WM831X_CHARGER_CONTROL_2:
410 case WM831X_CHARGER_STATUS:
411 case WM831X_BACKUP_CHARGER_CONTROL:
412 case WM831X_STATUS_LED_1:
413 case WM831X_STATUS_LED_2:
414 case WM831X_CURRENT_SINK_1:
415 case WM831X_CURRENT_SINK_2:
416 case WM831X_DCDC_ENABLE:
417 case WM831X_LDO_ENABLE:
418 case WM831X_DC1_CONTROL_1:
419 case WM831X_DC1_CONTROL_2:
420 case WM831X_DC1_ON_CONFIG:
421 case WM831X_DC1_SLEEP_CONTROL:
422 case WM831X_DC1_DVS_CONTROL:
423 case WM831X_DC2_CONTROL_1:
424 case WM831X_DC2_CONTROL_2:
425 case WM831X_DC2_ON_CONFIG:
426 case WM831X_DC2_SLEEP_CONTROL:
427 case WM831X_DC2_DVS_CONTROL:
428 case WM831X_DC3_CONTROL_1:
429 case WM831X_DC3_CONTROL_2:
430 case WM831X_DC3_ON_CONFIG:
431 case WM831X_DC3_SLEEP_CONTROL:
432 case WM831X_DC4_CONTROL:
433 case WM831X_DC4_SLEEP_CONTROL:
434 case WM831X_EPE1_CONTROL:
435 case WM831X_EPE2_CONTROL:
436 case WM831X_LDO1_CONTROL:
437 case WM831X_LDO1_ON_CONTROL:
438 case WM831X_LDO1_SLEEP_CONTROL:
439 case WM831X_LDO2_CONTROL:
440 case WM831X_LDO2_ON_CONTROL:
441 case WM831X_LDO2_SLEEP_CONTROL:
442 case WM831X_LDO3_CONTROL:
443 case WM831X_LDO3_ON_CONTROL:
444 case WM831X_LDO3_SLEEP_CONTROL:
445 case WM831X_LDO4_CONTROL:
446 case WM831X_LDO4_ON_CONTROL:
447 case WM831X_LDO4_SLEEP_CONTROL:
448 case WM831X_LDO5_CONTROL:
449 case WM831X_LDO5_ON_CONTROL:
450 case WM831X_LDO5_SLEEP_CONTROL:
451 case WM831X_LDO6_CONTROL:
452 case WM831X_LDO6_ON_CONTROL:
453 case WM831X_LDO6_SLEEP_CONTROL:
454 case WM831X_LDO7_CONTROL:
455 case WM831X_LDO7_ON_CONTROL:
456 case WM831X_LDO7_SLEEP_CONTROL:
457 case WM831X_LDO8_CONTROL:
458 case WM831X_LDO8_ON_CONTROL:
459 case WM831X_LDO8_SLEEP_CONTROL:
460 case WM831X_LDO9_CONTROL:
461 case WM831X_LDO9_ON_CONTROL:
462 case WM831X_LDO9_SLEEP_CONTROL:
463 case WM831X_LDO10_CONTROL:
464 case WM831X_LDO10_ON_CONTROL:
465 case WM831X_LDO10_SLEEP_CONTROL:
466 case WM831X_LDO11_ON_CONTROL:
467 case WM831X_LDO11_SLEEP_CONTROL:
468 case WM831X_POWER_GOOD_SOURCE_1:
469 case WM831X_POWER_GOOD_SOURCE_2:
470 case WM831X_CLOCK_CONTROL_1:
471 case WM831X_CLOCK_CONTROL_2:
472 case WM831X_FLL_CONTROL_1:
473 case WM831X_FLL_CONTROL_2:
474 case WM831X_FLL_CONTROL_3:
475 case WM831X_FLL_CONTROL_4:
476 case WM831X_FLL_CONTROL_5:
477 return true;
478 default:
479 return false;
480 }
481}
482
483static bool wm831x_reg_volatile(struct device *dev, unsigned int reg)
484{
485 switch (reg) {
486 case WM831X_SYSTEM_STATUS:
487 case WM831X_ON_SOURCE:
488 case WM831X_OFF_SOURCE:
489 case WM831X_GPIO_LEVEL:
490 case WM831X_SYSTEM_INTERRUPTS:
491 case WM831X_INTERRUPT_STATUS_1:
492 case WM831X_INTERRUPT_STATUS_2:
493 case WM831X_INTERRUPT_STATUS_3:
494 case WM831X_INTERRUPT_STATUS_4:
495 case WM831X_INTERRUPT_STATUS_5:
496 case WM831X_RTC_TIME_1:
497 case WM831X_RTC_TIME_2:
498 case WM831X_TOUCH_DATA_X:
499 case WM831X_TOUCH_DATA_Y:
500 case WM831X_TOUCH_DATA_Z:
501 case WM831X_AUXADC_DATA:
502 case WM831X_CHARGER_STATUS:
503 case WM831X_DCDC_STATUS:
504 case WM831X_LDO_STATUS:
505 case WM831X_DCDC_UV_STATUS:
506 case WM831X_LDO_UV_STATUS:
507 return true;
508 default:
509 return false;
510 }
511}
512
d2bedfe7
MB
513/**
514 * wm831x_reg_read: Read a single WM831x register.
515 *
516 * @wm831x: Device to read from.
517 * @reg: Register to read.
518 */
519int wm831x_reg_read(struct wm831x *wm831x, unsigned short reg)
520{
1df5981b 521 unsigned int val;
d2bedfe7
MB
522 int ret;
523
1df5981b 524 ret = regmap_read(wm831x->regmap, reg, &val);
d2bedfe7
MB
525
526 if (ret < 0)
527 return ret;
528 else
529 return val;
530}
531EXPORT_SYMBOL_GPL(wm831x_reg_read);
532
533/**
534 * wm831x_bulk_read: Read multiple WM831x registers
535 *
536 * @wm831x: Device to read from
537 * @reg: First register
538 * @count: Number of registers
539 * @buf: Buffer to fill.
540 */
541int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg,
542 int count, u16 *buf)
543{
1df5981b 544 return regmap_bulk_read(wm831x->regmap, reg, buf, count);
d2bedfe7
MB
545}
546EXPORT_SYMBOL_GPL(wm831x_bulk_read);
547
548static int wm831x_write(struct wm831x *wm831x, unsigned short reg,
549 int bytes, void *src)
550{
551 u16 *buf = src;
1df5981b 552 int i, ret;
d2bedfe7
MB
553
554 BUG_ON(bytes % 2);
555 BUG_ON(bytes <= 0);
556
557 for (i = 0; i < bytes / 2; i++) {
558 if (wm831x_reg_locked(wm831x, reg))
559 return -EPERM;
560
561 dev_vdbg(wm831x->dev, "Write %04x to R%d(0x%x)\n",
562 buf[i], reg + i, reg + i);
1df5981b 563 ret = regmap_write(wm831x->regmap, reg + i, buf[i]);
5391b5c6
MB
564 if (ret != 0)
565 return ret;
d2bedfe7
MB
566 }
567
1df5981b 568 return 0;
d2bedfe7
MB
569}
570
571/**
572 * wm831x_reg_write: Write a single WM831x register.
573 *
574 * @wm831x: Device to write to.
575 * @reg: Register to write to.
576 * @val: Value to write.
577 */
578int wm831x_reg_write(struct wm831x *wm831x, unsigned short reg,
579 unsigned short val)
580{
581 int ret;
582
583 mutex_lock(&wm831x->io_lock);
584
585 ret = wm831x_write(wm831x, reg, 2, &val);
586
587 mutex_unlock(&wm831x->io_lock);
588
589 return ret;
590}
591EXPORT_SYMBOL_GPL(wm831x_reg_write);
592
593/**
594 * wm831x_set_bits: Set the value of a bitfield in a WM831x register
595 *
596 * @wm831x: Device to write to.
597 * @reg: Register to write to.
598 * @mask: Mask of bits to set.
599 * @val: Value to set (unshifted)
600 */
601int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg,
602 unsigned short mask, unsigned short val)
603{
604 int ret;
d2bedfe7
MB
605
606 mutex_lock(&wm831x->io_lock);
607
1df5981b
MB
608 if (!wm831x_reg_locked(wm831x, reg))
609 ret = regmap_update_bits(wm831x->regmap, reg, mask, val);
610 else
611 ret = -EPERM;
d2bedfe7 612
d2bedfe7
MB
613 mutex_unlock(&wm831x->io_lock);
614
615 return ret;
616}
617EXPORT_SYMBOL_GPL(wm831x_set_bits);
618
619static struct resource wm831x_dcdc1_resources[] = {
620 {
621 .start = WM831X_DC1_CONTROL_1,
622 .end = WM831X_DC1_DVS_CONTROL,
5656098e 623 .flags = IORESOURCE_REG,
d2bedfe7
MB
624 },
625 {
626 .name = "UV",
627 .start = WM831X_IRQ_UV_DC1,
628 .end = WM831X_IRQ_UV_DC1,
629 .flags = IORESOURCE_IRQ,
630 },
631 {
632 .name = "HC",
633 .start = WM831X_IRQ_HC_DC1,
634 .end = WM831X_IRQ_HC_DC1,
635 .flags = IORESOURCE_IRQ,
636 },
637};
638
639
640static struct resource wm831x_dcdc2_resources[] = {
641 {
642 .start = WM831X_DC2_CONTROL_1,
643 .end = WM831X_DC2_DVS_CONTROL,
5656098e 644 .flags = IORESOURCE_REG,
d2bedfe7
MB
645 },
646 {
647 .name = "UV",
648 .start = WM831X_IRQ_UV_DC2,
649 .end = WM831X_IRQ_UV_DC2,
650 .flags = IORESOURCE_IRQ,
651 },
652 {
653 .name = "HC",
654 .start = WM831X_IRQ_HC_DC2,
655 .end = WM831X_IRQ_HC_DC2,
656 .flags = IORESOURCE_IRQ,
657 },
658};
659
660static struct resource wm831x_dcdc3_resources[] = {
661 {
662 .start = WM831X_DC3_CONTROL_1,
663 .end = WM831X_DC3_SLEEP_CONTROL,
5656098e 664 .flags = IORESOURCE_REG,
d2bedfe7
MB
665 },
666 {
667 .name = "UV",
668 .start = WM831X_IRQ_UV_DC3,
669 .end = WM831X_IRQ_UV_DC3,
670 .flags = IORESOURCE_IRQ,
671 },
672};
673
674static struct resource wm831x_dcdc4_resources[] = {
675 {
676 .start = WM831X_DC4_CONTROL,
677 .end = WM831X_DC4_SLEEP_CONTROL,
5656098e 678 .flags = IORESOURCE_REG,
d2bedfe7
MB
679 },
680 {
681 .name = "UV",
682 .start = WM831X_IRQ_UV_DC4,
683 .end = WM831X_IRQ_UV_DC4,
684 .flags = IORESOURCE_IRQ,
685 },
686};
687
d4e0a89e
MB
688static struct resource wm8320_dcdc4_buck_resources[] = {
689 {
690 .start = WM831X_DC4_CONTROL,
691 .end = WM832X_DC4_SLEEP_CONTROL,
5656098e 692 .flags = IORESOURCE_REG,
d4e0a89e
MB
693 },
694 {
695 .name = "UV",
696 .start = WM831X_IRQ_UV_DC4,
697 .end = WM831X_IRQ_UV_DC4,
698 .flags = IORESOURCE_IRQ,
699 },
700};
701
d2bedfe7
MB
702static struct resource wm831x_gpio_resources[] = {
703 {
704 .start = WM831X_IRQ_GPIO_1,
705 .end = WM831X_IRQ_GPIO_16,
706 .flags = IORESOURCE_IRQ,
707 },
708};
709
710static struct resource wm831x_isink1_resources[] = {
711 {
712 .start = WM831X_CURRENT_SINK_1,
713 .end = WM831X_CURRENT_SINK_1,
5656098e 714 .flags = IORESOURCE_REG,
d2bedfe7
MB
715 },
716 {
717 .start = WM831X_IRQ_CS1,
718 .end = WM831X_IRQ_CS1,
719 .flags = IORESOURCE_IRQ,
720 },
721};
722
723static struct resource wm831x_isink2_resources[] = {
724 {
725 .start = WM831X_CURRENT_SINK_2,
726 .end = WM831X_CURRENT_SINK_2,
5656098e 727 .flags = IORESOURCE_REG,
d2bedfe7
MB
728 },
729 {
730 .start = WM831X_IRQ_CS2,
731 .end = WM831X_IRQ_CS2,
732 .flags = IORESOURCE_IRQ,
733 },
734};
735
736static struct resource wm831x_ldo1_resources[] = {
737 {
738 .start = WM831X_LDO1_CONTROL,
739 .end = WM831X_LDO1_SLEEP_CONTROL,
5656098e 740 .flags = IORESOURCE_REG,
d2bedfe7
MB
741 },
742 {
743 .name = "UV",
744 .start = WM831X_IRQ_UV_LDO1,
745 .end = WM831X_IRQ_UV_LDO1,
746 .flags = IORESOURCE_IRQ,
747 },
748};
749
750static struct resource wm831x_ldo2_resources[] = {
751 {
752 .start = WM831X_LDO2_CONTROL,
753 .end = WM831X_LDO2_SLEEP_CONTROL,
5656098e 754 .flags = IORESOURCE_REG,
d2bedfe7
MB
755 },
756 {
757 .name = "UV",
758 .start = WM831X_IRQ_UV_LDO2,
759 .end = WM831X_IRQ_UV_LDO2,
760 .flags = IORESOURCE_IRQ,
761 },
762};
763
764static struct resource wm831x_ldo3_resources[] = {
765 {
766 .start = WM831X_LDO3_CONTROL,
767 .end = WM831X_LDO3_SLEEP_CONTROL,
5656098e 768 .flags = IORESOURCE_REG,
d2bedfe7
MB
769 },
770 {
771 .name = "UV",
772 .start = WM831X_IRQ_UV_LDO3,
773 .end = WM831X_IRQ_UV_LDO3,
774 .flags = IORESOURCE_IRQ,
775 },
776};
777
778static struct resource wm831x_ldo4_resources[] = {
779 {
780 .start = WM831X_LDO4_CONTROL,
781 .end = WM831X_LDO4_SLEEP_CONTROL,
5656098e 782 .flags = IORESOURCE_REG,
d2bedfe7
MB
783 },
784 {
785 .name = "UV",
786 .start = WM831X_IRQ_UV_LDO4,
787 .end = WM831X_IRQ_UV_LDO4,
788 .flags = IORESOURCE_IRQ,
789 },
790};
791
792static struct resource wm831x_ldo5_resources[] = {
793 {
794 .start = WM831X_LDO5_CONTROL,
795 .end = WM831X_LDO5_SLEEP_CONTROL,
5656098e 796 .flags = IORESOURCE_REG,
d2bedfe7
MB
797 },
798 {
799 .name = "UV",
800 .start = WM831X_IRQ_UV_LDO5,
801 .end = WM831X_IRQ_UV_LDO5,
802 .flags = IORESOURCE_IRQ,
803 },
804};
805
806static struct resource wm831x_ldo6_resources[] = {
807 {
808 .start = WM831X_LDO6_CONTROL,
809 .end = WM831X_LDO6_SLEEP_CONTROL,
5656098e 810 .flags = IORESOURCE_REG,
d2bedfe7
MB
811 },
812 {
813 .name = "UV",
814 .start = WM831X_IRQ_UV_LDO6,
815 .end = WM831X_IRQ_UV_LDO6,
816 .flags = IORESOURCE_IRQ,
817 },
818};
819
820static struct resource wm831x_ldo7_resources[] = {
821 {
822 .start = WM831X_LDO7_CONTROL,
823 .end = WM831X_LDO7_SLEEP_CONTROL,
5656098e 824 .flags = IORESOURCE_REG,
d2bedfe7
MB
825 },
826 {
827 .name = "UV",
828 .start = WM831X_IRQ_UV_LDO7,
829 .end = WM831X_IRQ_UV_LDO7,
830 .flags = IORESOURCE_IRQ,
831 },
832};
833
834static struct resource wm831x_ldo8_resources[] = {
835 {
836 .start = WM831X_LDO8_CONTROL,
837 .end = WM831X_LDO8_SLEEP_CONTROL,
5656098e 838 .flags = IORESOURCE_REG,
d2bedfe7
MB
839 },
840 {
841 .name = "UV",
842 .start = WM831X_IRQ_UV_LDO8,
843 .end = WM831X_IRQ_UV_LDO8,
844 .flags = IORESOURCE_IRQ,
845 },
846};
847
848static struct resource wm831x_ldo9_resources[] = {
849 {
850 .start = WM831X_LDO9_CONTROL,
851 .end = WM831X_LDO9_SLEEP_CONTROL,
5656098e 852 .flags = IORESOURCE_REG,
d2bedfe7
MB
853 },
854 {
855 .name = "UV",
856 .start = WM831X_IRQ_UV_LDO9,
857 .end = WM831X_IRQ_UV_LDO9,
858 .flags = IORESOURCE_IRQ,
859 },
860};
861
862static struct resource wm831x_ldo10_resources[] = {
863 {
864 .start = WM831X_LDO10_CONTROL,
865 .end = WM831X_LDO10_SLEEP_CONTROL,
5656098e 866 .flags = IORESOURCE_REG,
d2bedfe7
MB
867 },
868 {
869 .name = "UV",
870 .start = WM831X_IRQ_UV_LDO10,
871 .end = WM831X_IRQ_UV_LDO10,
872 .flags = IORESOURCE_IRQ,
873 },
874};
875
876static struct resource wm831x_ldo11_resources[] = {
877 {
878 .start = WM831X_LDO11_ON_CONTROL,
879 .end = WM831X_LDO11_SLEEP_CONTROL,
5656098e 880 .flags = IORESOURCE_REG,
d2bedfe7
MB
881 },
882};
883
884static struct resource wm831x_on_resources[] = {
885 {
886 .start = WM831X_IRQ_ON,
887 .end = WM831X_IRQ_ON,
888 .flags = IORESOURCE_IRQ,
889 },
890};
891
892
893static struct resource wm831x_power_resources[] = {
894 {
895 .name = "SYSLO",
896 .start = WM831X_IRQ_PPM_SYSLO,
897 .end = WM831X_IRQ_PPM_SYSLO,
898 .flags = IORESOURCE_IRQ,
899 },
900 {
901 .name = "PWR SRC",
902 .start = WM831X_IRQ_PPM_PWR_SRC,
903 .end = WM831X_IRQ_PPM_PWR_SRC,
904 .flags = IORESOURCE_IRQ,
905 },
906 {
907 .name = "USB CURR",
908 .start = WM831X_IRQ_PPM_USB_CURR,
909 .end = WM831X_IRQ_PPM_USB_CURR,
910 .flags = IORESOURCE_IRQ,
911 },
912 {
913 .name = "BATT HOT",
914 .start = WM831X_IRQ_CHG_BATT_HOT,
915 .end = WM831X_IRQ_CHG_BATT_HOT,
916 .flags = IORESOURCE_IRQ,
917 },
918 {
919 .name = "BATT COLD",
920 .start = WM831X_IRQ_CHG_BATT_COLD,
921 .end = WM831X_IRQ_CHG_BATT_COLD,
922 .flags = IORESOURCE_IRQ,
923 },
924 {
925 .name = "BATT FAIL",
926 .start = WM831X_IRQ_CHG_BATT_FAIL,
927 .end = WM831X_IRQ_CHG_BATT_FAIL,
928 .flags = IORESOURCE_IRQ,
929 },
930 {
931 .name = "OV",
932 .start = WM831X_IRQ_CHG_OV,
933 .end = WM831X_IRQ_CHG_OV,
934 .flags = IORESOURCE_IRQ,
935 },
936 {
937 .name = "END",
938 .start = WM831X_IRQ_CHG_END,
939 .end = WM831X_IRQ_CHG_END,
940 .flags = IORESOURCE_IRQ,
941 },
942 {
943 .name = "TO",
944 .start = WM831X_IRQ_CHG_TO,
945 .end = WM831X_IRQ_CHG_TO,
946 .flags = IORESOURCE_IRQ,
947 },
948 {
949 .name = "MODE",
950 .start = WM831X_IRQ_CHG_MODE,
951 .end = WM831X_IRQ_CHG_MODE,
952 .flags = IORESOURCE_IRQ,
953 },
954 {
955 .name = "START",
956 .start = WM831X_IRQ_CHG_START,
957 .end = WM831X_IRQ_CHG_START,
958 .flags = IORESOURCE_IRQ,
959 },
960};
961
962static struct resource wm831x_rtc_resources[] = {
963 {
964 .name = "PER",
965 .start = WM831X_IRQ_RTC_PER,
966 .end = WM831X_IRQ_RTC_PER,
967 .flags = IORESOURCE_IRQ,
968 },
969 {
970 .name = "ALM",
971 .start = WM831X_IRQ_RTC_ALM,
972 .end = WM831X_IRQ_RTC_ALM,
973 .flags = IORESOURCE_IRQ,
974 },
975};
976
977static struct resource wm831x_status1_resources[] = {
978 {
979 .start = WM831X_STATUS_LED_1,
980 .end = WM831X_STATUS_LED_1,
5656098e 981 .flags = IORESOURCE_REG,
d2bedfe7
MB
982 },
983};
984
985static struct resource wm831x_status2_resources[] = {
986 {
987 .start = WM831X_STATUS_LED_2,
988 .end = WM831X_STATUS_LED_2,
5656098e 989 .flags = IORESOURCE_REG,
d2bedfe7
MB
990 },
991};
992
993static struct resource wm831x_touch_resources[] = {
994 {
995 .name = "TCHPD",
996 .start = WM831X_IRQ_TCHPD,
997 .end = WM831X_IRQ_TCHPD,
998 .flags = IORESOURCE_IRQ,
999 },
1000 {
1001 .name = "TCHDATA",
1002 .start = WM831X_IRQ_TCHDATA,
1003 .end = WM831X_IRQ_TCHDATA,
1004 .flags = IORESOURCE_IRQ,
1005 },
1006};
1007
1008static struct resource wm831x_wdt_resources[] = {
1009 {
1010 .start = WM831X_IRQ_WDOG_TO,
1011 .end = WM831X_IRQ_WDOG_TO,
1012 .flags = IORESOURCE_IRQ,
1013 },
1014};
1015
ad59de48 1016static const struct mfd_cell wm8310_devs[] = {
c26964ea
MB
1017 {
1018 .name = "wm831x-backup",
1019 },
d2bedfe7
MB
1020 {
1021 .name = "wm831x-buckv",
1022 .id = 1,
1023 .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
1024 .resources = wm831x_dcdc1_resources,
1025 },
1026 {
1027 .name = "wm831x-buckv",
1028 .id = 2,
1029 .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
1030 .resources = wm831x_dcdc2_resources,
1031 },
1032 {
1033 .name = "wm831x-buckp",
1034 .id = 3,
1035 .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
1036 .resources = wm831x_dcdc3_resources,
1037 },
1038 {
1039 .name = "wm831x-boostp",
1040 .id = 4,
1041 .num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
1042 .resources = wm831x_dcdc4_resources,
1043 },
a5e06781
MB
1044 {
1045 .name = "wm831x-clk",
1046 },
d2bedfe7
MB
1047 {
1048 .name = "wm831x-epe",
1049 .id = 1,
1050 },
1051 {
1052 .name = "wm831x-epe",
1053 .id = 2,
1054 },
1055 {
1056 .name = "wm831x-gpio",
1057 .num_resources = ARRAY_SIZE(wm831x_gpio_resources),
1058 .resources = wm831x_gpio_resources,
1059 },
1060 {
1061 .name = "wm831x-hwmon",
1062 },
1063 {
1064 .name = "wm831x-isink",
1065 .id = 1,
1066 .num_resources = ARRAY_SIZE(wm831x_isink1_resources),
1067 .resources = wm831x_isink1_resources,
1068 },
1069 {
1070 .name = "wm831x-isink",
1071 .id = 2,
1072 .num_resources = ARRAY_SIZE(wm831x_isink2_resources),
1073 .resources = wm831x_isink2_resources,
1074 },
1075 {
1076 .name = "wm831x-ldo",
1077 .id = 1,
1078 .num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
1079 .resources = wm831x_ldo1_resources,
1080 },
1081 {
1082 .name = "wm831x-ldo",
1083 .id = 2,
1084 .num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
1085 .resources = wm831x_ldo2_resources,
1086 },
1087 {
1088 .name = "wm831x-ldo",
1089 .id = 3,
1090 .num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
1091 .resources = wm831x_ldo3_resources,
1092 },
1093 {
1094 .name = "wm831x-ldo",
1095 .id = 4,
1096 .num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
1097 .resources = wm831x_ldo4_resources,
1098 },
1099 {
1100 .name = "wm831x-ldo",
1101 .id = 5,
1102 .num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
1103 .resources = wm831x_ldo5_resources,
1104 },
1105 {
1106 .name = "wm831x-ldo",
1107 .id = 6,
1108 .num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
1109 .resources = wm831x_ldo6_resources,
1110 },
1111 {
1112 .name = "wm831x-aldo",
1113 .id = 7,
1114 .num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
1115 .resources = wm831x_ldo7_resources,
1116 },
1117 {
1118 .name = "wm831x-aldo",
1119 .id = 8,
1120 .num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
1121 .resources = wm831x_ldo8_resources,
1122 },
1123 {
1124 .name = "wm831x-aldo",
1125 .id = 9,
1126 .num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
1127 .resources = wm831x_ldo9_resources,
1128 },
1129 {
1130 .name = "wm831x-aldo",
1131 .id = 10,
1132 .num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
1133 .resources = wm831x_ldo10_resources,
1134 },
1135 {
1136 .name = "wm831x-alive-ldo",
1137 .id = 11,
1138 .num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
1139 .resources = wm831x_ldo11_resources,
1140 },
1141 {
1142 .name = "wm831x-on",
1143 .num_resources = ARRAY_SIZE(wm831x_on_resources),
1144 .resources = wm831x_on_resources,
1145 },
1146 {
1147 .name = "wm831x-power",
1148 .num_resources = ARRAY_SIZE(wm831x_power_resources),
1149 .resources = wm831x_power_resources,
1150 },
d2bedfe7
MB
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-watchdog",
1165 .num_resources = ARRAY_SIZE(wm831x_wdt_resources),
1166 .resources = wm831x_wdt_resources,
1167 },
1168};
1169
ad59de48 1170static const struct mfd_cell wm8311_devs[] = {
c26964ea
MB
1171 {
1172 .name = "wm831x-backup",
1173 },
d2bedfe7
MB
1174 {
1175 .name = "wm831x-buckv",
1176 .id = 1,
1177 .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
1178 .resources = wm831x_dcdc1_resources,
1179 },
1180 {
1181 .name = "wm831x-buckv",
1182 .id = 2,
1183 .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
1184 .resources = wm831x_dcdc2_resources,
1185 },
1186 {
1187 .name = "wm831x-buckp",
1188 .id = 3,
1189 .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
1190 .resources = wm831x_dcdc3_resources,
1191 },
1192 {
1193 .name = "wm831x-boostp",
1194 .id = 4,
1195 .num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
1196 .resources = wm831x_dcdc4_resources,
1197 },
a5e06781
MB
1198 {
1199 .name = "wm831x-clk",
1200 },
d2bedfe7
MB
1201 {
1202 .name = "wm831x-epe",
1203 .id = 1,
1204 },
1205 {
1206 .name = "wm831x-epe",
1207 .id = 2,
1208 },
1209 {
1210 .name = "wm831x-gpio",
1211 .num_resources = ARRAY_SIZE(wm831x_gpio_resources),
1212 .resources = wm831x_gpio_resources,
1213 },
1214 {
1215 .name = "wm831x-hwmon",
1216 },
1217 {
1218 .name = "wm831x-isink",
1219 .id = 1,
1220 .num_resources = ARRAY_SIZE(wm831x_isink1_resources),
1221 .resources = wm831x_isink1_resources,
1222 },
1223 {
1224 .name = "wm831x-isink",
1225 .id = 2,
1226 .num_resources = ARRAY_SIZE(wm831x_isink2_resources),
1227 .resources = wm831x_isink2_resources,
1228 },
1229 {
1230 .name = "wm831x-ldo",
1231 .id = 1,
1232 .num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
1233 .resources = wm831x_ldo1_resources,
1234 },
1235 {
1236 .name = "wm831x-ldo",
1237 .id = 2,
1238 .num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
1239 .resources = wm831x_ldo2_resources,
1240 },
1241 {
1242 .name = "wm831x-ldo",
1243 .id = 3,
1244 .num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
1245 .resources = wm831x_ldo3_resources,
1246 },
1247 {
1248 .name = "wm831x-ldo",
1249 .id = 4,
1250 .num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
1251 .resources = wm831x_ldo4_resources,
1252 },
1253 {
1254 .name = "wm831x-ldo",
1255 .id = 5,
1256 .num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
1257 .resources = wm831x_ldo5_resources,
1258 },
1259 {
1260 .name = "wm831x-aldo",
1261 .id = 7,
1262 .num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
1263 .resources = wm831x_ldo7_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 },
d2bedfe7
MB
1281 {
1282 .name = "wm831x-status",
1283 .id = 1,
1284 .num_resources = ARRAY_SIZE(wm831x_status1_resources),
1285 .resources = wm831x_status1_resources,
1286 },
1287 {
1288 .name = "wm831x-status",
1289 .id = 2,
1290 .num_resources = ARRAY_SIZE(wm831x_status2_resources),
1291 .resources = wm831x_status2_resources,
1292 },
d2bedfe7
MB
1293 {
1294 .name = "wm831x-watchdog",
1295 .num_resources = ARRAY_SIZE(wm831x_wdt_resources),
1296 .resources = wm831x_wdt_resources,
1297 },
1298};
1299
ad59de48 1300static const struct mfd_cell wm8312_devs[] = {
c26964ea
MB
1301 {
1302 .name = "wm831x-backup",
1303 },
d2bedfe7
MB
1304 {
1305 .name = "wm831x-buckv",
1306 .id = 1,
1307 .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
1308 .resources = wm831x_dcdc1_resources,
1309 },
1310 {
1311 .name = "wm831x-buckv",
1312 .id = 2,
1313 .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
1314 .resources = wm831x_dcdc2_resources,
1315 },
1316 {
1317 .name = "wm831x-buckp",
1318 .id = 3,
1319 .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
1320 .resources = wm831x_dcdc3_resources,
1321 },
1322 {
1323 .name = "wm831x-boostp",
1324 .id = 4,
1325 .num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
1326 .resources = wm831x_dcdc4_resources,
1327 },
a5e06781
MB
1328 {
1329 .name = "wm831x-clk",
1330 },
d2bedfe7
MB
1331 {
1332 .name = "wm831x-epe",
1333 .id = 1,
1334 },
1335 {
1336 .name = "wm831x-epe",
1337 .id = 2,
1338 },
1339 {
1340 .name = "wm831x-gpio",
1341 .num_resources = ARRAY_SIZE(wm831x_gpio_resources),
1342 .resources = wm831x_gpio_resources,
1343 },
1344 {
1345 .name = "wm831x-hwmon",
1346 },
1347 {
1348 .name = "wm831x-isink",
1349 .id = 1,
1350 .num_resources = ARRAY_SIZE(wm831x_isink1_resources),
1351 .resources = wm831x_isink1_resources,
1352 },
1353 {
1354 .name = "wm831x-isink",
1355 .id = 2,
1356 .num_resources = ARRAY_SIZE(wm831x_isink2_resources),
1357 .resources = wm831x_isink2_resources,
1358 },
1359 {
1360 .name = "wm831x-ldo",
1361 .id = 1,
1362 .num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
1363 .resources = wm831x_ldo1_resources,
1364 },
1365 {
1366 .name = "wm831x-ldo",
1367 .id = 2,
1368 .num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
1369 .resources = wm831x_ldo2_resources,
1370 },
1371 {
1372 .name = "wm831x-ldo",
1373 .id = 3,
1374 .num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
1375 .resources = wm831x_ldo3_resources,
1376 },
1377 {
1378 .name = "wm831x-ldo",
1379 .id = 4,
1380 .num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
1381 .resources = wm831x_ldo4_resources,
1382 },
1383 {
1384 .name = "wm831x-ldo",
1385 .id = 5,
1386 .num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
1387 .resources = wm831x_ldo5_resources,
1388 },
1389 {
1390 .name = "wm831x-ldo",
1391 .id = 6,
1392 .num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
1393 .resources = wm831x_ldo6_resources,
1394 },
1395 {
1396 .name = "wm831x-aldo",
1397 .id = 7,
1398 .num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
1399 .resources = wm831x_ldo7_resources,
1400 },
1401 {
1402 .name = "wm831x-aldo",
1403 .id = 8,
1404 .num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
1405 .resources = wm831x_ldo8_resources,
1406 },
1407 {
1408 .name = "wm831x-aldo",
1409 .id = 9,
1410 .num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
1411 .resources = wm831x_ldo9_resources,
1412 },
1413 {
1414 .name = "wm831x-aldo",
1415 .id = 10,
1416 .num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
1417 .resources = wm831x_ldo10_resources,
1418 },
1419 {
1420 .name = "wm831x-alive-ldo",
1421 .id = 11,
1422 .num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
1423 .resources = wm831x_ldo11_resources,
1424 },
1425 {
1426 .name = "wm831x-on",
1427 .num_resources = ARRAY_SIZE(wm831x_on_resources),
1428 .resources = wm831x_on_resources,
1429 },
1430 {
1431 .name = "wm831x-power",
1432 .num_resources = ARRAY_SIZE(wm831x_power_resources),
1433 .resources = wm831x_power_resources,
1434 },
d2bedfe7
MB
1435 {
1436 .name = "wm831x-status",
1437 .id = 1,
1438 .num_resources = ARRAY_SIZE(wm831x_status1_resources),
1439 .resources = wm831x_status1_resources,
1440 },
1441 {
1442 .name = "wm831x-status",
1443 .id = 2,
1444 .num_resources = ARRAY_SIZE(wm831x_status2_resources),
1445 .resources = wm831x_status2_resources,
1446 },
d2bedfe7
MB
1447 {
1448 .name = "wm831x-watchdog",
1449 .num_resources = ARRAY_SIZE(wm831x_wdt_resources),
1450 .resources = wm831x_wdt_resources,
1451 },
1452};
1453
ad59de48 1454static const struct mfd_cell wm8320_devs[] = {
d4e0a89e
MB
1455 {
1456 .name = "wm831x-backup",
1457 },
1458 {
1459 .name = "wm831x-buckv",
1460 .id = 1,
1461 .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
1462 .resources = wm831x_dcdc1_resources,
1463 },
1464 {
1465 .name = "wm831x-buckv",
1466 .id = 2,
1467 .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
1468 .resources = wm831x_dcdc2_resources,
1469 },
1470 {
1471 .name = "wm831x-buckp",
1472 .id = 3,
1473 .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
1474 .resources = wm831x_dcdc3_resources,
1475 },
1476 {
1477 .name = "wm831x-buckp",
1478 .id = 4,
1479 .num_resources = ARRAY_SIZE(wm8320_dcdc4_buck_resources),
1480 .resources = wm8320_dcdc4_buck_resources,
1481 },
a5e06781
MB
1482 {
1483 .name = "wm831x-clk",
1484 },
d4e0a89e
MB
1485 {
1486 .name = "wm831x-gpio",
1487 .num_resources = ARRAY_SIZE(wm831x_gpio_resources),
1488 .resources = wm831x_gpio_resources,
1489 },
1490 {
1491 .name = "wm831x-hwmon",
1492 },
1493 {
1494 .name = "wm831x-ldo",
1495 .id = 1,
1496 .num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
1497 .resources = wm831x_ldo1_resources,
1498 },
1499 {
1500 .name = "wm831x-ldo",
1501 .id = 2,
1502 .num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
1503 .resources = wm831x_ldo2_resources,
1504 },
1505 {
1506 .name = "wm831x-ldo",
1507 .id = 3,
1508 .num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
1509 .resources = wm831x_ldo3_resources,
1510 },
1511 {
1512 .name = "wm831x-ldo",
1513 .id = 4,
1514 .num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
1515 .resources = wm831x_ldo4_resources,
1516 },
1517 {
1518 .name = "wm831x-ldo",
1519 .id = 5,
1520 .num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
1521 .resources = wm831x_ldo5_resources,
1522 },
1523 {
1524 .name = "wm831x-ldo",
1525 .id = 6,
1526 .num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
1527 .resources = wm831x_ldo6_resources,
1528 },
1529 {
1530 .name = "wm831x-aldo",
1531 .id = 7,
1532 .num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
1533 .resources = wm831x_ldo7_resources,
1534 },
1535 {
1536 .name = "wm831x-aldo",
1537 .id = 8,
1538 .num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
1539 .resources = wm831x_ldo8_resources,
1540 },
1541 {
1542 .name = "wm831x-aldo",
1543 .id = 9,
1544 .num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
1545 .resources = wm831x_ldo9_resources,
1546 },
1547 {
1548 .name = "wm831x-aldo",
1549 .id = 10,
1550 .num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
1551 .resources = wm831x_ldo10_resources,
1552 },
1553 {
1554 .name = "wm831x-alive-ldo",
1555 .id = 11,
1556 .num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
1557 .resources = wm831x_ldo11_resources,
1558 },
1559 {
1560 .name = "wm831x-on",
1561 .num_resources = ARRAY_SIZE(wm831x_on_resources),
1562 .resources = wm831x_on_resources,
1563 },
d4e0a89e
MB
1564 {
1565 .name = "wm831x-status",
1566 .id = 1,
1567 .num_resources = ARRAY_SIZE(wm831x_status1_resources),
1568 .resources = wm831x_status1_resources,
1569 },
1570 {
1571 .name = "wm831x-status",
1572 .id = 2,
1573 .num_resources = ARRAY_SIZE(wm831x_status2_resources),
1574 .resources = wm831x_status2_resources,
1575 },
1576 {
1577 .name = "wm831x-watchdog",
1578 .num_resources = ARRAY_SIZE(wm831x_wdt_resources),
1579 .resources = wm831x_wdt_resources,
1580 },
1581};
1582
ad59de48 1583static const struct mfd_cell touch_devs[] = {
266a5e02
MB
1584 {
1585 .name = "wm831x-touch",
1586 .num_resources = ARRAY_SIZE(wm831x_touch_resources),
1587 .resources = wm831x_touch_resources,
1588 },
1589};
1590
ad59de48 1591static const struct mfd_cell rtc_devs[] = {
b9d03d99
MB
1592 {
1593 .name = "wm831x-rtc",
1594 .num_resources = ARRAY_SIZE(wm831x_rtc_resources),
1595 .resources = wm831x_rtc_resources,
1596 },
1597};
266a5e02 1598
ad59de48 1599static const struct mfd_cell backlight_devs[] = {
63aed85e
MB
1600 {
1601 .name = "wm831x-backlight",
1602 },
1603};
1604
1df5981b
MB
1605struct regmap_config wm831x_regmap_config = {
1606 .reg_bits = 16,
1607 .val_bits = 16,
2e47fff1 1608
7cccbdc8
MB
1609 .cache_type = REGCACHE_RBTREE,
1610
2e47fff1
MB
1611 .max_register = WM831X_DBE_CHECK_DATA,
1612 .readable_reg = wm831x_reg_readable,
1613 .writeable_reg = wm831x_reg_writeable,
1614 .volatile_reg = wm831x_reg_volatile,
1df5981b
MB
1615};
1616EXPORT_SYMBOL_GPL(wm831x_regmap_config);
1617
f6dd8449
CK
1618const struct of_device_id wm831x_of_match[] = {
1619 { .compatible = "wlf,wm8310", .data = (void *)WM8310 },
1620 { .compatible = "wlf,wm8311", .data = (void *)WM8311 },
1621 { .compatible = "wlf,wm8312", .data = (void *)WM8312 },
1622 { .compatible = "wlf,wm8320", .data = (void *)WM8320 },
1623 { .compatible = "wlf,wm8321", .data = (void *)WM8321 },
1624 { .compatible = "wlf,wm8325", .data = (void *)WM8325 },
1625 { .compatible = "wlf,wm8326", .data = (void *)WM8326 },
1626 { },
1627};
1628EXPORT_SYMBOL_GPL(wm831x_of_match);
1629
d2bedfe7
MB
1630/*
1631 * Instantiate the generic non-control parts of the device.
1632 */
f6dd8449 1633int wm831x_device_init(struct wm831x *wm831x, int irq)
d2bedfe7 1634{
f6dd8449 1635 struct wm831x_pdata *pdata = &wm831x->pdata;
eb503dc1 1636 int rev, wm831x_num;
d2bedfe7 1637 enum wm831x_parent parent;
0b14c22e 1638 int ret, i;
d2bedfe7
MB
1639
1640 mutex_init(&wm831x->io_lock);
1641 mutex_init(&wm831x->key_lock);
1642 dev_set_drvdata(wm831x->dev, wm831x);
16dfd103 1643
f6dd8449 1644 wm831x->soft_shutdown = pdata->soft_shutdown;
d2bedfe7
MB
1645
1646 ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
1647 if (ret < 0) {
1648 dev_err(wm831x->dev, "Failed to read parent ID: %d\n", ret);
130a7032 1649 goto err;
d2bedfe7 1650 }
b93cef55
MB
1651 switch (ret) {
1652 case 0x6204:
1653 case 0x6246:
1654 break;
1655 default:
d2bedfe7
MB
1656 dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret);
1657 ret = -EINVAL;
130a7032 1658 goto err;
d2bedfe7
MB
1659 }
1660
1661 ret = wm831x_reg_read(wm831x, WM831X_REVISION);
1662 if (ret < 0) {
1663 dev_err(wm831x->dev, "Failed to read revision: %d\n", ret);
130a7032 1664 goto err;
d2bedfe7
MB
1665 }
1666 rev = (ret & WM831X_PARENT_REV_MASK) >> WM831X_PARENT_REV_SHIFT;
1667
1668 ret = wm831x_reg_read(wm831x, WM831X_RESET_ID);
1669 if (ret < 0) {
1670 dev_err(wm831x->dev, "Failed to read device ID: %d\n", ret);
130a7032 1671 goto err;
d2bedfe7
MB
1672 }
1673
894362f5
MB
1674 /* Some engineering samples do not have the ID set, rely on
1675 * the device being registered correctly.
1676 */
1677 if (ret == 0) {
1678 dev_info(wm831x->dev, "Device is an engineering sample\n");
f6dd8449 1679 ret = wm831x->type;
894362f5
MB
1680 }
1681
d2bedfe7 1682 switch (ret) {
894362f5 1683 case WM8310:
d2bedfe7 1684 parent = WM8310;
6f2ecaae 1685 wm831x->num_gpio = 16;
b03b4d7c 1686 wm831x->charger_irq_wake = 1;
f92e8f81
MB
1687 if (rev > 0) {
1688 wm831x->has_gpio_ena = 1;
1689 wm831x->has_cs_sts = 1;
1690 }
1691
894362f5 1692 dev_info(wm831x->dev, "WM8310 revision %c\n", 'A' + rev);
d2bedfe7
MB
1693 break;
1694
894362f5 1695 case WM8311:
d2bedfe7 1696 parent = WM8311;
6f2ecaae 1697 wm831x->num_gpio = 16;
b03b4d7c 1698 wm831x->charger_irq_wake = 1;
f92e8f81
MB
1699 if (rev > 0) {
1700 wm831x->has_gpio_ena = 1;
1701 wm831x->has_cs_sts = 1;
1702 }
1703
894362f5 1704 dev_info(wm831x->dev, "WM8311 revision %c\n", 'A' + rev);
d2bedfe7
MB
1705 break;
1706
894362f5 1707 case WM8312:
d2bedfe7 1708 parent = WM8312;
6f2ecaae 1709 wm831x->num_gpio = 16;
b03b4d7c 1710 wm831x->charger_irq_wake = 1;
f92e8f81
MB
1711 if (rev > 0) {
1712 wm831x->has_gpio_ena = 1;
1713 wm831x->has_cs_sts = 1;
1714 }
1715
894362f5 1716 dev_info(wm831x->dev, "WM8312 revision %c\n", 'A' + rev);
d2bedfe7
MB
1717 break;
1718
d4e0a89e
MB
1719 case WM8320:
1720 parent = WM8320;
1721 wm831x->num_gpio = 12;
1722 dev_info(wm831x->dev, "WM8320 revision %c\n", 'A' + rev);
1723 break;
1724
88913521
MB
1725 case WM8321:
1726 parent = WM8321;
1727 wm831x->num_gpio = 12;
1728 dev_info(wm831x->dev, "WM8321 revision %c\n", 'A' + rev);
1729 break;
1730
0b315884
MB
1731 case WM8325:
1732 parent = WM8325;
1733 wm831x->num_gpio = 12;
1734 dev_info(wm831x->dev, "WM8325 revision %c\n", 'A' + rev);
1735 break;
1736
412dc11d
MB
1737 case WM8326:
1738 parent = WM8326;
1739 wm831x->num_gpio = 12;
1740 dev_info(wm831x->dev, "WM8326 revision %c\n", 'A' + rev);
1741 break;
1742
d2bedfe7
MB
1743 default:
1744 dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret);
1745 ret = -EINVAL;
130a7032 1746 goto err;
d2bedfe7
MB
1747 }
1748
1749 /* This will need revisiting in future but is OK for all
1750 * current parts.
1751 */
f6dd8449
CK
1752 if (parent != wm831x->type)
1753 dev_warn(wm831x->dev, "Device was registered as a WM%x\n",
1754 wm831x->type);
d2bedfe7
MB
1755
1756 /* Bootstrap the user key */
1757 ret = wm831x_reg_read(wm831x, WM831X_SECURITY_KEY);
1758 if (ret < 0) {
1759 dev_err(wm831x->dev, "Failed to read security key: %d\n", ret);
130a7032 1760 goto err;
d2bedfe7
MB
1761 }
1762 if (ret != 0) {
1763 dev_warn(wm831x->dev, "Security key had non-zero value %x\n",
1764 ret);
1765 wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0);
1766 }
1767 wm831x->locked = 1;
1768
dcb0574b 1769 if (pdata->pre_init) {
d2bedfe7
MB
1770 ret = pdata->pre_init(wm831x);
1771 if (ret != 0) {
1772 dev_err(wm831x->dev, "pre_init() failed: %d\n", ret);
130a7032 1773 goto err;
d2bedfe7
MB
1774 }
1775 }
1776
dcb0574b
CK
1777 for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
1778 if (!pdata->gpio_defaults[i])
1779 continue;
0b14c22e 1780
dcb0574b
CK
1781 wm831x_reg_write(wm831x,
1782 WM831X_GPIO1_CONTROL + i,
1783 pdata->gpio_defaults[i] & 0xffff);
0b14c22e
MB
1784 }
1785
eb503dc1 1786 /* Multiply by 10 as we have many subdevices of the same type */
dcb0574b 1787 if (pdata->wm831x_num)
eb503dc1
MB
1788 wm831x_num = pdata->wm831x_num * 10;
1789 else
1790 wm831x_num = -1;
1791
7d4d0a3e
MB
1792 ret = wm831x_irq_init(wm831x, irq);
1793 if (ret != 0)
130a7032 1794 goto err;
7d4d0a3e 1795
e69b6de1 1796 wm831x_auxadc_init(wm831x);
473fe736 1797
d2bedfe7
MB
1798 /* The core device is up, instantiate the subdevices. */
1799 switch (parent) {
1800 case WM8310:
eb503dc1 1801 ret = mfd_add_devices(wm831x->dev, wm831x_num,
d2bedfe7 1802 wm8310_devs, ARRAY_SIZE(wm8310_devs),
55692af5 1803 NULL, 0, NULL);
d2bedfe7
MB
1804 break;
1805
1806 case WM8311:
eb503dc1 1807 ret = mfd_add_devices(wm831x->dev, wm831x_num,
d2bedfe7 1808 wm8311_devs, ARRAY_SIZE(wm8311_devs),
55692af5 1809 NULL, 0, NULL);
dcb0574b 1810 if (!pdata->disable_touch)
266a5e02
MB
1811 mfd_add_devices(wm831x->dev, wm831x_num,
1812 touch_devs, ARRAY_SIZE(touch_devs),
55692af5 1813 NULL, 0, NULL);
d2bedfe7
MB
1814 break;
1815
1816 case WM8312:
eb503dc1 1817 ret = mfd_add_devices(wm831x->dev, wm831x_num,
d2bedfe7 1818 wm8312_devs, ARRAY_SIZE(wm8312_devs),
55692af5 1819 NULL, 0, NULL);
dcb0574b 1820 if (!pdata->disable_touch)
266a5e02
MB
1821 mfd_add_devices(wm831x->dev, wm831x_num,
1822 touch_devs, ARRAY_SIZE(touch_devs),
55692af5 1823 NULL, 0, NULL);
d2bedfe7
MB
1824 break;
1825
d4e0a89e 1826 case WM8320:
88913521 1827 case WM8321:
0b315884 1828 case WM8325:
412dc11d 1829 case WM8326:
eb503dc1 1830 ret = mfd_add_devices(wm831x->dev, wm831x_num,
0b315884 1831 wm8320_devs, ARRAY_SIZE(wm8320_devs),
55692af5 1832 NULL, 0, NULL);
0b315884
MB
1833 break;
1834
d2bedfe7
MB
1835 default:
1836 /* If this happens the bus probe function is buggy */
1837 BUG();
1838 }
1839
1840 if (ret != 0) {
1841 dev_err(wm831x->dev, "Failed to add children\n");
7d4d0a3e 1842 goto err_irq;
d2bedfe7
MB
1843 }
1844
b9d03d99
MB
1845 /* The RTC can only be used if the 32.768kHz crystal is
1846 * enabled; this can't be controlled by software at runtime.
1847 */
1848 ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_2);
1849 if (ret < 0) {
1850 dev_err(wm831x->dev, "Failed to read clock status: %d\n", ret);
1851 goto err_irq;
1852 }
1853
1854 if (ret & WM831X_XTAL_ENA) {
1855 ret = mfd_add_devices(wm831x->dev, wm831x_num,
1856 rtc_devs, ARRAY_SIZE(rtc_devs),
55692af5 1857 NULL, 0, NULL);
b9d03d99
MB
1858 if (ret != 0) {
1859 dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret);
1860 goto err_irq;
1861 }
1862 } else {
1863 dev_info(wm831x->dev, "32.768kHz clock disabled, no RTC\n");
1864 }
1865
dcb0574b 1866 if (pdata->backlight) {
63aed85e 1867 /* Treat errors as non-critical */
eb503dc1 1868 ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs,
5fb4d38b 1869 ARRAY_SIZE(backlight_devs), NULL,
55692af5 1870 0, NULL);
63aed85e
MB
1871 if (ret < 0)
1872 dev_err(wm831x->dev, "Failed to add backlight: %d\n",
1873 ret);
1874 }
1875
6704e517
MB
1876 wm831x_otp_init(wm831x);
1877
dcb0574b 1878 if (pdata->post_init) {
d2bedfe7
MB
1879 ret = pdata->post_init(wm831x);
1880 if (ret != 0) {
1881 dev_err(wm831x->dev, "post_init() failed: %d\n", ret);
7d4d0a3e 1882 goto err_irq;
d2bedfe7
MB
1883 }
1884 }
1885
1886 return 0;
1887
7d4d0a3e
MB
1888err_irq:
1889 wm831x_irq_exit(wm831x);
130a7032 1890err:
d2bedfe7 1891 mfd_remove_devices(wm831x->dev);
d2bedfe7
MB
1892 return ret;
1893}
1894
e5b48684 1895void wm831x_device_exit(struct wm831x *wm831x)
d2bedfe7 1896{
6704e517 1897 wm831x_otp_exit(wm831x);
d2bedfe7 1898 mfd_remove_devices(wm831x->dev);
cd99758b 1899 free_irq(wm831x_irq(wm831x, WM831X_IRQ_AUXADC_DATA), wm831x);
7d4d0a3e 1900 wm831x_irq_exit(wm831x);
d2bedfe7
MB
1901}
1902
e5b48684 1903int wm831x_device_suspend(struct wm831x *wm831x)
b03b4d7c
MB
1904{
1905 int reg, mask;
1906
1907 /* If the charger IRQs are a wake source then make sure we ack
1908 * them even if they're not actively being used (eg, no power
1909 * driver or no IRQ line wired up) then acknowledge the
1910 * interrupts otherwise suspend won't last very long.
1911 */
1912 if (wm831x->charger_irq_wake) {
1913 reg = wm831x_reg_read(wm831x, WM831X_INTERRUPT_STATUS_2_MASK);
1914
1915 mask = WM831X_CHG_BATT_HOT_EINT |
1916 WM831X_CHG_BATT_COLD_EINT |
1917 WM831X_CHG_BATT_FAIL_EINT |
1918 WM831X_CHG_OV_EINT | WM831X_CHG_END_EINT |
1919 WM831X_CHG_TO_EINT | WM831X_CHG_MODE_EINT |
1920 WM831X_CHG_START_EINT;
1921
1922 /* If any of the interrupts are masked read the statuses */
1923 if (reg & mask)
1924 reg = wm831x_reg_read(wm831x,
1925 WM831X_INTERRUPT_STATUS_2);
1926
1927 if (reg & mask) {
1928 dev_info(wm831x->dev,
1929 "Acknowledging masked charger IRQs: %x\n",
1930 reg & mask);
1931 wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_2,
1932 reg & mask);
1933 }
1934 }
1935
1936 return 0;
1937}
1938
523d9cfb
MB
1939void wm831x_device_shutdown(struct wm831x *wm831x)
1940{
1941 if (wm831x->soft_shutdown) {
1942 dev_info(wm831x->dev, "Initiating shutdown...\n");
1943 wm831x_set_bits(wm831x, WM831X_POWER_STATE, WM831X_CHIP_ON, 0);
1944 }
1945}
1946EXPORT_SYMBOL_GPL(wm831x_device_shutdown);
1947
e5b48684 1948MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC");
d2bedfe7
MB
1949MODULE_LICENSE("GPL");
1950MODULE_AUTHOR("Mark Brown");