xref: /openbmc/linux/drivers/mfd/wm831x-core.c (revision dc0c386e)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2d2bedfe7SMark Brown /*
3d2bedfe7SMark Brown  * wm831x-core.c  --  Device access for Wolfson WM831x PMICs
4d2bedfe7SMark Brown  *
5d2bedfe7SMark Brown  * Copyright 2009 Wolfson Microelectronics PLC.
6d2bedfe7SMark Brown  *
7d2bedfe7SMark Brown  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
8d2bedfe7SMark Brown  */
9d2bedfe7SMark Brown 
10d2bedfe7SMark Brown #include <linux/kernel.h>
11efb5a790SPaul Gortmaker #include <linux/init.h>
12efb5a790SPaul Gortmaker #include <linux/export.h>
137e9f9fd4SMark Brown #include <linux/bcd.h>
147e9f9fd4SMark Brown #include <linux/delay.h>
15d2bedfe7SMark Brown #include <linux/mfd/core.h>
165a0e3ad6STejun Heo #include <linux/slab.h>
171df5981bSMark Brown #include <linux/err.h>
18*dc0c386eSRob Herring #include <linux/mod_devicetable.h>
19d2bedfe7SMark Brown 
20d2bedfe7SMark Brown #include <linux/mfd/wm831x/core.h>
21d2bedfe7SMark Brown #include <linux/mfd/wm831x/pdata.h>
227d4d0a3eSMark Brown #include <linux/mfd/wm831x/irq.h>
237e9f9fd4SMark Brown #include <linux/mfd/wm831x/auxadc.h>
246704e517SMark Brown #include <linux/mfd/wm831x/otp.h>
25523d9cfbSMark Brown #include <linux/mfd/wm831x/pmu.h>
26698659d5SMark Brown #include <linux/mfd/wm831x/regulator.h>
27698659d5SMark Brown 
28698659d5SMark Brown /* Current settings - values are 2*2^(reg_val/4) microamps.  These are
29698659d5SMark Brown  * exported since they are used by multiple drivers.
30698659d5SMark Brown  */
31d48acfd0SAxel Lin const unsigned int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = {
32698659d5SMark Brown 	2,
33698659d5SMark Brown 	2,
34698659d5SMark Brown 	3,
35698659d5SMark Brown 	3,
36698659d5SMark Brown 	4,
37698659d5SMark Brown 	5,
38698659d5SMark Brown 	6,
39698659d5SMark Brown 	7,
40698659d5SMark Brown 	8,
41698659d5SMark Brown 	10,
42698659d5SMark Brown 	11,
43698659d5SMark Brown 	13,
44698659d5SMark Brown 	16,
45698659d5SMark Brown 	19,
46698659d5SMark Brown 	23,
47698659d5SMark Brown 	27,
48698659d5SMark Brown 	32,
49698659d5SMark Brown 	38,
50698659d5SMark Brown 	45,
51698659d5SMark Brown 	54,
52698659d5SMark Brown 	64,
53698659d5SMark Brown 	76,
54698659d5SMark Brown 	91,
55698659d5SMark Brown 	108,
56698659d5SMark Brown 	128,
57698659d5SMark Brown 	152,
58698659d5SMark Brown 	181,
59698659d5SMark Brown 	215,
60698659d5SMark Brown 	256,
61698659d5SMark Brown 	304,
62698659d5SMark Brown 	362,
63698659d5SMark Brown 	431,
64698659d5SMark Brown 	512,
65698659d5SMark Brown 	609,
66698659d5SMark Brown 	724,
67698659d5SMark Brown 	861,
68698659d5SMark Brown 	1024,
69698659d5SMark Brown 	1218,
70698659d5SMark Brown 	1448,
71698659d5SMark Brown 	1722,
72698659d5SMark Brown 	2048,
73698659d5SMark Brown 	2435,
74698659d5SMark Brown 	2896,
75698659d5SMark Brown 	3444,
76698659d5SMark Brown 	4096,
77698659d5SMark Brown 	4871,
78698659d5SMark Brown 	5793,
79698659d5SMark Brown 	6889,
80698659d5SMark Brown 	8192,
81698659d5SMark Brown 	9742,
82698659d5SMark Brown 	11585,
83698659d5SMark Brown 	13777,
84698659d5SMark Brown 	16384,
85698659d5SMark Brown 	19484,
86698659d5SMark Brown 	23170,
87698659d5SMark Brown 	27554,
88698659d5SMark Brown };
89698659d5SMark Brown EXPORT_SYMBOL_GPL(wm831x_isinkv_values);
90d2bedfe7SMark Brown 
wm831x_reg_locked(struct wm831x * wm831x,unsigned short reg)91d2bedfe7SMark Brown static int wm831x_reg_locked(struct wm831x *wm831x, unsigned short reg)
92d2bedfe7SMark Brown {
93d2bedfe7SMark Brown 	if (!wm831x->locked)
94d2bedfe7SMark Brown 		return 0;
95d2bedfe7SMark Brown 
96d2bedfe7SMark Brown 	switch (reg) {
97d2bedfe7SMark Brown 	case WM831X_WATCHDOG:
98d2bedfe7SMark Brown 	case WM831X_DC4_CONTROL:
99d2bedfe7SMark Brown 	case WM831X_ON_PIN_CONTROL:
100d2bedfe7SMark Brown 	case WM831X_BACKUP_CHARGER_CONTROL:
101d2bedfe7SMark Brown 	case WM831X_CHARGER_CONTROL_1:
102d2bedfe7SMark Brown 	case WM831X_CHARGER_CONTROL_2:
103d2bedfe7SMark Brown 		return 1;
104d2bedfe7SMark Brown 
105d2bedfe7SMark Brown 	default:
106d2bedfe7SMark Brown 		return 0;
107d2bedfe7SMark Brown 	}
108d2bedfe7SMark Brown }
109d2bedfe7SMark Brown 
110d2bedfe7SMark Brown /**
111926337b2SLee Jones  * wm831x_reg_lock: Unlock user keyed registers
112d2bedfe7SMark Brown  *
113d2bedfe7SMark Brown  * The WM831x has a user key preventing writes to particularly
114d2bedfe7SMark Brown  * critical registers.  This function locks those registers,
115d2bedfe7SMark Brown  * allowing writes to them.
11638ea9f47SLee Jones  *
11738ea9f47SLee Jones  * @wm831x: pointer to local driver data structure
118d2bedfe7SMark Brown  */
wm831x_reg_lock(struct wm831x * wm831x)119d2bedfe7SMark Brown void wm831x_reg_lock(struct wm831x *wm831x)
120d2bedfe7SMark Brown {
121d2bedfe7SMark Brown 	int ret;
122d2bedfe7SMark Brown 
123d2bedfe7SMark Brown 	ret = wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0);
124d2bedfe7SMark Brown 	if (ret == 0) {
125d2bedfe7SMark Brown 		dev_vdbg(wm831x->dev, "Registers locked\n");
126d2bedfe7SMark Brown 
127d2bedfe7SMark Brown 		mutex_lock(&wm831x->io_lock);
128d2bedfe7SMark Brown 		WARN_ON(wm831x->locked);
129d2bedfe7SMark Brown 		wm831x->locked = 1;
130d2bedfe7SMark Brown 		mutex_unlock(&wm831x->io_lock);
131d2bedfe7SMark Brown 	} else {
132d2bedfe7SMark Brown 		dev_err(wm831x->dev, "Failed to lock registers: %d\n", ret);
133d2bedfe7SMark Brown 	}
134d2bedfe7SMark Brown 
135d2bedfe7SMark Brown }
136d2bedfe7SMark Brown EXPORT_SYMBOL_GPL(wm831x_reg_lock);
137d2bedfe7SMark Brown 
138d2bedfe7SMark Brown /**
139d2bedfe7SMark Brown  * wm831x_reg_unlock: Unlock user keyed registers
140d2bedfe7SMark Brown  *
141d2bedfe7SMark Brown  * The WM831x has a user key preventing writes to particularly
142d2bedfe7SMark Brown  * critical registers.  This function locks those registers,
143d2bedfe7SMark Brown  * preventing spurious writes.
14438ea9f47SLee Jones  *
14538ea9f47SLee Jones  * @wm831x: pointer to local driver data structure
146d2bedfe7SMark Brown  */
wm831x_reg_unlock(struct wm831x * wm831x)147d2bedfe7SMark Brown int wm831x_reg_unlock(struct wm831x *wm831x)
148d2bedfe7SMark Brown {
149d2bedfe7SMark Brown 	int ret;
150d2bedfe7SMark Brown 
151d2bedfe7SMark Brown 	/* 0x9716 is the value required to unlock the registers */
152d2bedfe7SMark Brown 	ret = wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0x9716);
153d2bedfe7SMark Brown 	if (ret == 0) {
154d2bedfe7SMark Brown 		dev_vdbg(wm831x->dev, "Registers unlocked\n");
155d2bedfe7SMark Brown 
156d2bedfe7SMark Brown 		mutex_lock(&wm831x->io_lock);
157d2bedfe7SMark Brown 		WARN_ON(!wm831x->locked);
158d2bedfe7SMark Brown 		wm831x->locked = 0;
159d2bedfe7SMark Brown 		mutex_unlock(&wm831x->io_lock);
160d2bedfe7SMark Brown 	}
161d2bedfe7SMark Brown 
162d2bedfe7SMark Brown 	return ret;
163d2bedfe7SMark Brown }
164d2bedfe7SMark Brown EXPORT_SYMBOL_GPL(wm831x_reg_unlock);
165d2bedfe7SMark Brown 
wm831x_reg_readable(struct device * dev,unsigned int reg)1662e47fff1SMark Brown static bool wm831x_reg_readable(struct device *dev, unsigned int reg)
1672e47fff1SMark Brown {
1682e47fff1SMark Brown 	switch (reg) {
1692e47fff1SMark Brown 	case WM831X_RESET_ID:
1702e47fff1SMark Brown 	case WM831X_REVISION:
1712e47fff1SMark Brown 	case WM831X_PARENT_ID:
1722e47fff1SMark Brown 	case WM831X_SYSVDD_CONTROL:
1732e47fff1SMark Brown 	case WM831X_THERMAL_MONITORING:
1742e47fff1SMark Brown 	case WM831X_POWER_STATE:
1752e47fff1SMark Brown 	case WM831X_WATCHDOG:
1762e47fff1SMark Brown 	case WM831X_ON_PIN_CONTROL:
1772e47fff1SMark Brown 	case WM831X_RESET_CONTROL:
1782e47fff1SMark Brown 	case WM831X_CONTROL_INTERFACE:
1792e47fff1SMark Brown 	case WM831X_SECURITY_KEY:
1802e47fff1SMark Brown 	case WM831X_SOFTWARE_SCRATCH:
1812e47fff1SMark Brown 	case WM831X_OTP_CONTROL:
1822e47fff1SMark Brown 	case WM831X_GPIO_LEVEL:
1832e47fff1SMark Brown 	case WM831X_SYSTEM_STATUS:
1842e47fff1SMark Brown 	case WM831X_ON_SOURCE:
1852e47fff1SMark Brown 	case WM831X_OFF_SOURCE:
1862e47fff1SMark Brown 	case WM831X_SYSTEM_INTERRUPTS:
1872e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_1:
1882e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_2:
1892e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_3:
1902e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_4:
1912e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_5:
1922e47fff1SMark Brown 	case WM831X_IRQ_CONFIG:
1932e47fff1SMark Brown 	case WM831X_SYSTEM_INTERRUPTS_MASK:
1942e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_1_MASK:
1952e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_2_MASK:
1962e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_3_MASK:
1972e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_4_MASK:
1982e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_5_MASK:
1992e47fff1SMark Brown 	case WM831X_RTC_WRITE_COUNTER:
2002e47fff1SMark Brown 	case WM831X_RTC_TIME_1:
2012e47fff1SMark Brown 	case WM831X_RTC_TIME_2:
2022e47fff1SMark Brown 	case WM831X_RTC_ALARM_1:
2032e47fff1SMark Brown 	case WM831X_RTC_ALARM_2:
2042e47fff1SMark Brown 	case WM831X_RTC_CONTROL:
2052e47fff1SMark Brown 	case WM831X_RTC_TRIM:
2062e47fff1SMark Brown 	case WM831X_TOUCH_CONTROL_1:
2072e47fff1SMark Brown 	case WM831X_TOUCH_CONTROL_2:
2082e47fff1SMark Brown 	case WM831X_TOUCH_DATA_X:
2092e47fff1SMark Brown 	case WM831X_TOUCH_DATA_Y:
2102e47fff1SMark Brown 	case WM831X_TOUCH_DATA_Z:
2112e47fff1SMark Brown 	case WM831X_AUXADC_DATA:
2122e47fff1SMark Brown 	case WM831X_AUXADC_CONTROL:
2132e47fff1SMark Brown 	case WM831X_AUXADC_SOURCE:
2142e47fff1SMark Brown 	case WM831X_COMPARATOR_CONTROL:
2152e47fff1SMark Brown 	case WM831X_COMPARATOR_1:
2162e47fff1SMark Brown 	case WM831X_COMPARATOR_2:
2172e47fff1SMark Brown 	case WM831X_COMPARATOR_3:
2182e47fff1SMark Brown 	case WM831X_COMPARATOR_4:
2192e47fff1SMark Brown 	case WM831X_GPIO1_CONTROL:
2202e47fff1SMark Brown 	case WM831X_GPIO2_CONTROL:
2212e47fff1SMark Brown 	case WM831X_GPIO3_CONTROL:
2222e47fff1SMark Brown 	case WM831X_GPIO4_CONTROL:
2232e47fff1SMark Brown 	case WM831X_GPIO5_CONTROL:
2242e47fff1SMark Brown 	case WM831X_GPIO6_CONTROL:
2252e47fff1SMark Brown 	case WM831X_GPIO7_CONTROL:
2262e47fff1SMark Brown 	case WM831X_GPIO8_CONTROL:
2272e47fff1SMark Brown 	case WM831X_GPIO9_CONTROL:
2282e47fff1SMark Brown 	case WM831X_GPIO10_CONTROL:
2292e47fff1SMark Brown 	case WM831X_GPIO11_CONTROL:
2302e47fff1SMark Brown 	case WM831X_GPIO12_CONTROL:
2312e47fff1SMark Brown 	case WM831X_GPIO13_CONTROL:
2322e47fff1SMark Brown 	case WM831X_GPIO14_CONTROL:
2332e47fff1SMark Brown 	case WM831X_GPIO15_CONTROL:
2342e47fff1SMark Brown 	case WM831X_GPIO16_CONTROL:
2352e47fff1SMark Brown 	case WM831X_CHARGER_CONTROL_1:
2362e47fff1SMark Brown 	case WM831X_CHARGER_CONTROL_2:
2372e47fff1SMark Brown 	case WM831X_CHARGER_STATUS:
2382e47fff1SMark Brown 	case WM831X_BACKUP_CHARGER_CONTROL:
2392e47fff1SMark Brown 	case WM831X_STATUS_LED_1:
2402e47fff1SMark Brown 	case WM831X_STATUS_LED_2:
2412e47fff1SMark Brown 	case WM831X_CURRENT_SINK_1:
2422e47fff1SMark Brown 	case WM831X_CURRENT_SINK_2:
2432e47fff1SMark Brown 	case WM831X_DCDC_ENABLE:
2442e47fff1SMark Brown 	case WM831X_LDO_ENABLE:
2452e47fff1SMark Brown 	case WM831X_DCDC_STATUS:
2462e47fff1SMark Brown 	case WM831X_LDO_STATUS:
2472e47fff1SMark Brown 	case WM831X_DCDC_UV_STATUS:
2482e47fff1SMark Brown 	case WM831X_LDO_UV_STATUS:
2492e47fff1SMark Brown 	case WM831X_DC1_CONTROL_1:
2502e47fff1SMark Brown 	case WM831X_DC1_CONTROL_2:
2512e47fff1SMark Brown 	case WM831X_DC1_ON_CONFIG:
2522e47fff1SMark Brown 	case WM831X_DC1_SLEEP_CONTROL:
2532e47fff1SMark Brown 	case WM831X_DC1_DVS_CONTROL:
2542e47fff1SMark Brown 	case WM831X_DC2_CONTROL_1:
2552e47fff1SMark Brown 	case WM831X_DC2_CONTROL_2:
2562e47fff1SMark Brown 	case WM831X_DC2_ON_CONFIG:
2572e47fff1SMark Brown 	case WM831X_DC2_SLEEP_CONTROL:
2582e47fff1SMark Brown 	case WM831X_DC2_DVS_CONTROL:
2592e47fff1SMark Brown 	case WM831X_DC3_CONTROL_1:
2602e47fff1SMark Brown 	case WM831X_DC3_CONTROL_2:
2612e47fff1SMark Brown 	case WM831X_DC3_ON_CONFIG:
2622e47fff1SMark Brown 	case WM831X_DC3_SLEEP_CONTROL:
2632e47fff1SMark Brown 	case WM831X_DC4_CONTROL:
2642e47fff1SMark Brown 	case WM831X_DC4_SLEEP_CONTROL:
2652e47fff1SMark Brown 	case WM831X_EPE1_CONTROL:
2662e47fff1SMark Brown 	case WM831X_EPE2_CONTROL:
2672e47fff1SMark Brown 	case WM831X_LDO1_CONTROL:
2682e47fff1SMark Brown 	case WM831X_LDO1_ON_CONTROL:
2692e47fff1SMark Brown 	case WM831X_LDO1_SLEEP_CONTROL:
2702e47fff1SMark Brown 	case WM831X_LDO2_CONTROL:
2712e47fff1SMark Brown 	case WM831X_LDO2_ON_CONTROL:
2722e47fff1SMark Brown 	case WM831X_LDO2_SLEEP_CONTROL:
2732e47fff1SMark Brown 	case WM831X_LDO3_CONTROL:
2742e47fff1SMark Brown 	case WM831X_LDO3_ON_CONTROL:
2752e47fff1SMark Brown 	case WM831X_LDO3_SLEEP_CONTROL:
2762e47fff1SMark Brown 	case WM831X_LDO4_CONTROL:
2772e47fff1SMark Brown 	case WM831X_LDO4_ON_CONTROL:
2782e47fff1SMark Brown 	case WM831X_LDO4_SLEEP_CONTROL:
2792e47fff1SMark Brown 	case WM831X_LDO5_CONTROL:
2802e47fff1SMark Brown 	case WM831X_LDO5_ON_CONTROL:
2812e47fff1SMark Brown 	case WM831X_LDO5_SLEEP_CONTROL:
2822e47fff1SMark Brown 	case WM831X_LDO6_CONTROL:
2832e47fff1SMark Brown 	case WM831X_LDO6_ON_CONTROL:
2842e47fff1SMark Brown 	case WM831X_LDO6_SLEEP_CONTROL:
2852e47fff1SMark Brown 	case WM831X_LDO7_CONTROL:
2862e47fff1SMark Brown 	case WM831X_LDO7_ON_CONTROL:
2872e47fff1SMark Brown 	case WM831X_LDO7_SLEEP_CONTROL:
2882e47fff1SMark Brown 	case WM831X_LDO8_CONTROL:
2892e47fff1SMark Brown 	case WM831X_LDO8_ON_CONTROL:
2902e47fff1SMark Brown 	case WM831X_LDO8_SLEEP_CONTROL:
2912e47fff1SMark Brown 	case WM831X_LDO9_CONTROL:
2922e47fff1SMark Brown 	case WM831X_LDO9_ON_CONTROL:
2932e47fff1SMark Brown 	case WM831X_LDO9_SLEEP_CONTROL:
2942e47fff1SMark Brown 	case WM831X_LDO10_CONTROL:
2952e47fff1SMark Brown 	case WM831X_LDO10_ON_CONTROL:
2962e47fff1SMark Brown 	case WM831X_LDO10_SLEEP_CONTROL:
2972e47fff1SMark Brown 	case WM831X_LDO11_ON_CONTROL:
2982e47fff1SMark Brown 	case WM831X_LDO11_SLEEP_CONTROL:
2992e47fff1SMark Brown 	case WM831X_POWER_GOOD_SOURCE_1:
3002e47fff1SMark Brown 	case WM831X_POWER_GOOD_SOURCE_2:
3012e47fff1SMark Brown 	case WM831X_CLOCK_CONTROL_1:
3022e47fff1SMark Brown 	case WM831X_CLOCK_CONTROL_2:
3032e47fff1SMark Brown 	case WM831X_FLL_CONTROL_1:
3042e47fff1SMark Brown 	case WM831X_FLL_CONTROL_2:
3052e47fff1SMark Brown 	case WM831X_FLL_CONTROL_3:
3062e47fff1SMark Brown 	case WM831X_FLL_CONTROL_4:
3072e47fff1SMark Brown 	case WM831X_FLL_CONTROL_5:
3082e47fff1SMark Brown 	case WM831X_UNIQUE_ID_1:
3092e47fff1SMark Brown 	case WM831X_UNIQUE_ID_2:
3102e47fff1SMark Brown 	case WM831X_UNIQUE_ID_3:
3112e47fff1SMark Brown 	case WM831X_UNIQUE_ID_4:
3122e47fff1SMark Brown 	case WM831X_UNIQUE_ID_5:
3132e47fff1SMark Brown 	case WM831X_UNIQUE_ID_6:
3142e47fff1SMark Brown 	case WM831X_UNIQUE_ID_7:
3152e47fff1SMark Brown 	case WM831X_UNIQUE_ID_8:
3162e47fff1SMark Brown 	case WM831X_FACTORY_OTP_ID:
3172e47fff1SMark Brown 	case WM831X_FACTORY_OTP_1:
3182e47fff1SMark Brown 	case WM831X_FACTORY_OTP_2:
3192e47fff1SMark Brown 	case WM831X_FACTORY_OTP_3:
3202e47fff1SMark Brown 	case WM831X_FACTORY_OTP_4:
3212e47fff1SMark Brown 	case WM831X_FACTORY_OTP_5:
3222e47fff1SMark Brown 	case WM831X_CUSTOMER_OTP_ID:
3232e47fff1SMark Brown 	case WM831X_DC1_OTP_CONTROL:
3242e47fff1SMark Brown 	case WM831X_DC2_OTP_CONTROL:
3252e47fff1SMark Brown 	case WM831X_DC3_OTP_CONTROL:
3262e47fff1SMark Brown 	case WM831X_LDO1_2_OTP_CONTROL:
3272e47fff1SMark Brown 	case WM831X_LDO3_4_OTP_CONTROL:
3282e47fff1SMark Brown 	case WM831X_LDO5_6_OTP_CONTROL:
3292e47fff1SMark Brown 	case WM831X_LDO7_8_OTP_CONTROL:
3302e47fff1SMark Brown 	case WM831X_LDO9_10_OTP_CONTROL:
3312e47fff1SMark Brown 	case WM831X_LDO11_EPE_CONTROL:
3322e47fff1SMark Brown 	case WM831X_GPIO1_OTP_CONTROL:
3332e47fff1SMark Brown 	case WM831X_GPIO2_OTP_CONTROL:
3342e47fff1SMark Brown 	case WM831X_GPIO3_OTP_CONTROL:
3352e47fff1SMark Brown 	case WM831X_GPIO4_OTP_CONTROL:
3362e47fff1SMark Brown 	case WM831X_GPIO5_OTP_CONTROL:
3372e47fff1SMark Brown 	case WM831X_GPIO6_OTP_CONTROL:
3382e47fff1SMark Brown 	case WM831X_DBE_CHECK_DATA:
3392e47fff1SMark Brown 		return true;
3402e47fff1SMark Brown 	default:
3412e47fff1SMark Brown 		return false;
3422e47fff1SMark Brown 	}
3432e47fff1SMark Brown }
3442e47fff1SMark Brown 
wm831x_reg_writeable(struct device * dev,unsigned int reg)3452e47fff1SMark Brown static bool wm831x_reg_writeable(struct device *dev, unsigned int reg)
3462e47fff1SMark Brown {
3472e47fff1SMark Brown 	struct wm831x *wm831x = dev_get_drvdata(dev);
3482e47fff1SMark Brown 
3492e47fff1SMark Brown 	if (wm831x_reg_locked(wm831x, reg))
3502e47fff1SMark Brown 		return false;
3512e47fff1SMark Brown 
3522e47fff1SMark Brown 	switch (reg) {
3532e47fff1SMark Brown 	case WM831X_SYSVDD_CONTROL:
3542e47fff1SMark Brown 	case WM831X_THERMAL_MONITORING:
3552e47fff1SMark Brown 	case WM831X_POWER_STATE:
3562e47fff1SMark Brown 	case WM831X_WATCHDOG:
3572e47fff1SMark Brown 	case WM831X_ON_PIN_CONTROL:
3582e47fff1SMark Brown 	case WM831X_RESET_CONTROL:
3592e47fff1SMark Brown 	case WM831X_CONTROL_INTERFACE:
3602e47fff1SMark Brown 	case WM831X_SECURITY_KEY:
3612e47fff1SMark Brown 	case WM831X_SOFTWARE_SCRATCH:
3622e47fff1SMark Brown 	case WM831X_OTP_CONTROL:
3632e47fff1SMark Brown 	case WM831X_GPIO_LEVEL:
3642e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_1:
3652e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_2:
3662e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_3:
3672e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_4:
3682e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_5:
3692e47fff1SMark Brown 	case WM831X_IRQ_CONFIG:
3702e47fff1SMark Brown 	case WM831X_SYSTEM_INTERRUPTS_MASK:
3712e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_1_MASK:
3722e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_2_MASK:
3732e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_3_MASK:
3742e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_4_MASK:
3752e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_5_MASK:
3762e47fff1SMark Brown 	case WM831X_RTC_TIME_1:
3772e47fff1SMark Brown 	case WM831X_RTC_TIME_2:
3782e47fff1SMark Brown 	case WM831X_RTC_ALARM_1:
3792e47fff1SMark Brown 	case WM831X_RTC_ALARM_2:
3802e47fff1SMark Brown 	case WM831X_RTC_CONTROL:
3812e47fff1SMark Brown 	case WM831X_RTC_TRIM:
3822e47fff1SMark Brown 	case WM831X_TOUCH_CONTROL_1:
3832e47fff1SMark Brown 	case WM831X_TOUCH_CONTROL_2:
3842e47fff1SMark Brown 	case WM831X_AUXADC_CONTROL:
3852e47fff1SMark Brown 	case WM831X_AUXADC_SOURCE:
3862e47fff1SMark Brown 	case WM831X_COMPARATOR_CONTROL:
3872e47fff1SMark Brown 	case WM831X_COMPARATOR_1:
3882e47fff1SMark Brown 	case WM831X_COMPARATOR_2:
3892e47fff1SMark Brown 	case WM831X_COMPARATOR_3:
3902e47fff1SMark Brown 	case WM831X_COMPARATOR_4:
3912e47fff1SMark Brown 	case WM831X_GPIO1_CONTROL:
3922e47fff1SMark Brown 	case WM831X_GPIO2_CONTROL:
3932e47fff1SMark Brown 	case WM831X_GPIO3_CONTROL:
3942e47fff1SMark Brown 	case WM831X_GPIO4_CONTROL:
3952e47fff1SMark Brown 	case WM831X_GPIO5_CONTROL:
3962e47fff1SMark Brown 	case WM831X_GPIO6_CONTROL:
3972e47fff1SMark Brown 	case WM831X_GPIO7_CONTROL:
3982e47fff1SMark Brown 	case WM831X_GPIO8_CONTROL:
3992e47fff1SMark Brown 	case WM831X_GPIO9_CONTROL:
4002e47fff1SMark Brown 	case WM831X_GPIO10_CONTROL:
4012e47fff1SMark Brown 	case WM831X_GPIO11_CONTROL:
4022e47fff1SMark Brown 	case WM831X_GPIO12_CONTROL:
4032e47fff1SMark Brown 	case WM831X_GPIO13_CONTROL:
4042e47fff1SMark Brown 	case WM831X_GPIO14_CONTROL:
4052e47fff1SMark Brown 	case WM831X_GPIO15_CONTROL:
4062e47fff1SMark Brown 	case WM831X_GPIO16_CONTROL:
4072e47fff1SMark Brown 	case WM831X_CHARGER_CONTROL_1:
4082e47fff1SMark Brown 	case WM831X_CHARGER_CONTROL_2:
4092e47fff1SMark Brown 	case WM831X_CHARGER_STATUS:
4102e47fff1SMark Brown 	case WM831X_BACKUP_CHARGER_CONTROL:
4112e47fff1SMark Brown 	case WM831X_STATUS_LED_1:
4122e47fff1SMark Brown 	case WM831X_STATUS_LED_2:
4132e47fff1SMark Brown 	case WM831X_CURRENT_SINK_1:
4142e47fff1SMark Brown 	case WM831X_CURRENT_SINK_2:
4152e47fff1SMark Brown 	case WM831X_DCDC_ENABLE:
4162e47fff1SMark Brown 	case WM831X_LDO_ENABLE:
4172e47fff1SMark Brown 	case WM831X_DC1_CONTROL_1:
4182e47fff1SMark Brown 	case WM831X_DC1_CONTROL_2:
4192e47fff1SMark Brown 	case WM831X_DC1_ON_CONFIG:
4202e47fff1SMark Brown 	case WM831X_DC1_SLEEP_CONTROL:
4212e47fff1SMark Brown 	case WM831X_DC1_DVS_CONTROL:
4222e47fff1SMark Brown 	case WM831X_DC2_CONTROL_1:
4232e47fff1SMark Brown 	case WM831X_DC2_CONTROL_2:
4242e47fff1SMark Brown 	case WM831X_DC2_ON_CONFIG:
4252e47fff1SMark Brown 	case WM831X_DC2_SLEEP_CONTROL:
4262e47fff1SMark Brown 	case WM831X_DC2_DVS_CONTROL:
4272e47fff1SMark Brown 	case WM831X_DC3_CONTROL_1:
4282e47fff1SMark Brown 	case WM831X_DC3_CONTROL_2:
4292e47fff1SMark Brown 	case WM831X_DC3_ON_CONFIG:
4302e47fff1SMark Brown 	case WM831X_DC3_SLEEP_CONTROL:
4312e47fff1SMark Brown 	case WM831X_DC4_CONTROL:
4322e47fff1SMark Brown 	case WM831X_DC4_SLEEP_CONTROL:
4332e47fff1SMark Brown 	case WM831X_EPE1_CONTROL:
4342e47fff1SMark Brown 	case WM831X_EPE2_CONTROL:
4352e47fff1SMark Brown 	case WM831X_LDO1_CONTROL:
4362e47fff1SMark Brown 	case WM831X_LDO1_ON_CONTROL:
4372e47fff1SMark Brown 	case WM831X_LDO1_SLEEP_CONTROL:
4382e47fff1SMark Brown 	case WM831X_LDO2_CONTROL:
4392e47fff1SMark Brown 	case WM831X_LDO2_ON_CONTROL:
4402e47fff1SMark Brown 	case WM831X_LDO2_SLEEP_CONTROL:
4412e47fff1SMark Brown 	case WM831X_LDO3_CONTROL:
4422e47fff1SMark Brown 	case WM831X_LDO3_ON_CONTROL:
4432e47fff1SMark Brown 	case WM831X_LDO3_SLEEP_CONTROL:
4442e47fff1SMark Brown 	case WM831X_LDO4_CONTROL:
4452e47fff1SMark Brown 	case WM831X_LDO4_ON_CONTROL:
4462e47fff1SMark Brown 	case WM831X_LDO4_SLEEP_CONTROL:
4472e47fff1SMark Brown 	case WM831X_LDO5_CONTROL:
4482e47fff1SMark Brown 	case WM831X_LDO5_ON_CONTROL:
4492e47fff1SMark Brown 	case WM831X_LDO5_SLEEP_CONTROL:
4502e47fff1SMark Brown 	case WM831X_LDO6_CONTROL:
4512e47fff1SMark Brown 	case WM831X_LDO6_ON_CONTROL:
4522e47fff1SMark Brown 	case WM831X_LDO6_SLEEP_CONTROL:
4532e47fff1SMark Brown 	case WM831X_LDO7_CONTROL:
4542e47fff1SMark Brown 	case WM831X_LDO7_ON_CONTROL:
4552e47fff1SMark Brown 	case WM831X_LDO7_SLEEP_CONTROL:
4562e47fff1SMark Brown 	case WM831X_LDO8_CONTROL:
4572e47fff1SMark Brown 	case WM831X_LDO8_ON_CONTROL:
4582e47fff1SMark Brown 	case WM831X_LDO8_SLEEP_CONTROL:
4592e47fff1SMark Brown 	case WM831X_LDO9_CONTROL:
4602e47fff1SMark Brown 	case WM831X_LDO9_ON_CONTROL:
4612e47fff1SMark Brown 	case WM831X_LDO9_SLEEP_CONTROL:
4622e47fff1SMark Brown 	case WM831X_LDO10_CONTROL:
4632e47fff1SMark Brown 	case WM831X_LDO10_ON_CONTROL:
4642e47fff1SMark Brown 	case WM831X_LDO10_SLEEP_CONTROL:
4652e47fff1SMark Brown 	case WM831X_LDO11_ON_CONTROL:
4662e47fff1SMark Brown 	case WM831X_LDO11_SLEEP_CONTROL:
4672e47fff1SMark Brown 	case WM831X_POWER_GOOD_SOURCE_1:
4682e47fff1SMark Brown 	case WM831X_POWER_GOOD_SOURCE_2:
4692e47fff1SMark Brown 	case WM831X_CLOCK_CONTROL_1:
4702e47fff1SMark Brown 	case WM831X_CLOCK_CONTROL_2:
4712e47fff1SMark Brown 	case WM831X_FLL_CONTROL_1:
4722e47fff1SMark Brown 	case WM831X_FLL_CONTROL_2:
4732e47fff1SMark Brown 	case WM831X_FLL_CONTROL_3:
4742e47fff1SMark Brown 	case WM831X_FLL_CONTROL_4:
4752e47fff1SMark Brown 	case WM831X_FLL_CONTROL_5:
4762e47fff1SMark Brown 		return true;
4772e47fff1SMark Brown 	default:
4782e47fff1SMark Brown 		return false;
4792e47fff1SMark Brown 	}
4802e47fff1SMark Brown }
4812e47fff1SMark Brown 
wm831x_reg_volatile(struct device * dev,unsigned int reg)4822e47fff1SMark Brown static bool wm831x_reg_volatile(struct device *dev, unsigned int reg)
4832e47fff1SMark Brown {
4842e47fff1SMark Brown 	switch (reg) {
4852e47fff1SMark Brown 	case WM831X_SYSTEM_STATUS:
4862e47fff1SMark Brown 	case WM831X_ON_SOURCE:
4872e47fff1SMark Brown 	case WM831X_OFF_SOURCE:
4882e47fff1SMark Brown 	case WM831X_GPIO_LEVEL:
4892e47fff1SMark Brown 	case WM831X_SYSTEM_INTERRUPTS:
4902e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_1:
4912e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_2:
4922e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_3:
4932e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_4:
4942e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_5:
4952e47fff1SMark Brown 	case WM831X_RTC_TIME_1:
4962e47fff1SMark Brown 	case WM831X_RTC_TIME_2:
4972e47fff1SMark Brown 	case WM831X_TOUCH_DATA_X:
4982e47fff1SMark Brown 	case WM831X_TOUCH_DATA_Y:
4992e47fff1SMark Brown 	case WM831X_TOUCH_DATA_Z:
5002e47fff1SMark Brown 	case WM831X_AUXADC_DATA:
5012e47fff1SMark Brown 	case WM831X_CHARGER_STATUS:
5022e47fff1SMark Brown 	case WM831X_DCDC_STATUS:
5032e47fff1SMark Brown 	case WM831X_LDO_STATUS:
5042e47fff1SMark Brown 	case WM831X_DCDC_UV_STATUS:
5052e47fff1SMark Brown 	case WM831X_LDO_UV_STATUS:
5062e47fff1SMark Brown 		return true;
5072e47fff1SMark Brown 	default:
5082e47fff1SMark Brown 		return false;
5092e47fff1SMark Brown 	}
5102e47fff1SMark Brown }
5112e47fff1SMark Brown 
512d2bedfe7SMark Brown /**
513d2bedfe7SMark Brown  * wm831x_reg_read: Read a single WM831x register.
514d2bedfe7SMark Brown  *
515d2bedfe7SMark Brown  * @wm831x: Device to read from.
516d2bedfe7SMark Brown  * @reg: Register to read.
517d2bedfe7SMark Brown  */
wm831x_reg_read(struct wm831x * wm831x,unsigned short reg)518d2bedfe7SMark Brown int wm831x_reg_read(struct wm831x *wm831x, unsigned short reg)
519d2bedfe7SMark Brown {
5201df5981bSMark Brown 	unsigned int val;
521d2bedfe7SMark Brown 	int ret;
522d2bedfe7SMark Brown 
5231df5981bSMark Brown 	ret = regmap_read(wm831x->regmap, reg, &val);
524d2bedfe7SMark Brown 
525d2bedfe7SMark Brown 	if (ret < 0)
526d2bedfe7SMark Brown 		return ret;
527d2bedfe7SMark Brown 	else
528d2bedfe7SMark Brown 		return val;
529d2bedfe7SMark Brown }
530d2bedfe7SMark Brown EXPORT_SYMBOL_GPL(wm831x_reg_read);
531d2bedfe7SMark Brown 
532d2bedfe7SMark Brown /**
533d2bedfe7SMark Brown  * wm831x_bulk_read: Read multiple WM831x registers
534d2bedfe7SMark Brown  *
535d2bedfe7SMark Brown  * @wm831x: Device to read from
536d2bedfe7SMark Brown  * @reg: First register
537d2bedfe7SMark Brown  * @count: Number of registers
538d2bedfe7SMark Brown  * @buf: Buffer to fill.
539d2bedfe7SMark Brown  */
wm831x_bulk_read(struct wm831x * wm831x,unsigned short reg,int count,u16 * buf)540d2bedfe7SMark Brown int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg,
541d2bedfe7SMark Brown 		     int count, u16 *buf)
542d2bedfe7SMark Brown {
5431df5981bSMark Brown 	return regmap_bulk_read(wm831x->regmap, reg, buf, count);
544d2bedfe7SMark Brown }
545d2bedfe7SMark Brown EXPORT_SYMBOL_GPL(wm831x_bulk_read);
546d2bedfe7SMark Brown 
wm831x_write(struct wm831x * wm831x,unsigned short reg,int bytes,void * src)547d2bedfe7SMark Brown static int wm831x_write(struct wm831x *wm831x, unsigned short reg,
548d2bedfe7SMark Brown 			int bytes, void *src)
549d2bedfe7SMark Brown {
550d2bedfe7SMark Brown 	u16 *buf = src;
5511df5981bSMark Brown 	int i, ret;
552d2bedfe7SMark Brown 
553d2bedfe7SMark Brown 	BUG_ON(bytes % 2);
554d2bedfe7SMark Brown 	BUG_ON(bytes <= 0);
555d2bedfe7SMark Brown 
556d2bedfe7SMark Brown 	for (i = 0; i < bytes / 2; i++) {
557d2bedfe7SMark Brown 		if (wm831x_reg_locked(wm831x, reg))
558d2bedfe7SMark Brown 			return -EPERM;
559d2bedfe7SMark Brown 
560d2bedfe7SMark Brown 		dev_vdbg(wm831x->dev, "Write %04x to R%d(0x%x)\n",
561d2bedfe7SMark Brown 			 buf[i], reg + i, reg + i);
5621df5981bSMark Brown 		ret = regmap_write(wm831x->regmap, reg + i, buf[i]);
5635391b5c6SMark Brown 		if (ret != 0)
5645391b5c6SMark Brown 			return ret;
565d2bedfe7SMark Brown 	}
566d2bedfe7SMark Brown 
5671df5981bSMark Brown 	return 0;
568d2bedfe7SMark Brown }
569d2bedfe7SMark Brown 
570d2bedfe7SMark Brown /**
571d2bedfe7SMark Brown  * wm831x_reg_write: Write a single WM831x register.
572d2bedfe7SMark Brown  *
573d2bedfe7SMark Brown  * @wm831x: Device to write to.
574d2bedfe7SMark Brown  * @reg: Register to write to.
575d2bedfe7SMark Brown  * @val: Value to write.
576d2bedfe7SMark Brown  */
wm831x_reg_write(struct wm831x * wm831x,unsigned short reg,unsigned short val)577d2bedfe7SMark Brown int wm831x_reg_write(struct wm831x *wm831x, unsigned short reg,
578d2bedfe7SMark Brown 		     unsigned short val)
579d2bedfe7SMark Brown {
580d2bedfe7SMark Brown 	int ret;
581d2bedfe7SMark Brown 
582d2bedfe7SMark Brown 	mutex_lock(&wm831x->io_lock);
583d2bedfe7SMark Brown 
584d2bedfe7SMark Brown 	ret = wm831x_write(wm831x, reg, 2, &val);
585d2bedfe7SMark Brown 
586d2bedfe7SMark Brown 	mutex_unlock(&wm831x->io_lock);
587d2bedfe7SMark Brown 
588d2bedfe7SMark Brown 	return ret;
589d2bedfe7SMark Brown }
590d2bedfe7SMark Brown EXPORT_SYMBOL_GPL(wm831x_reg_write);
591d2bedfe7SMark Brown 
592d2bedfe7SMark Brown /**
593d2bedfe7SMark Brown  * wm831x_set_bits: Set the value of a bitfield in a WM831x register
594d2bedfe7SMark Brown  *
595d2bedfe7SMark Brown  * @wm831x: Device to write to.
596d2bedfe7SMark Brown  * @reg: Register to write to.
597d2bedfe7SMark Brown  * @mask: Mask of bits to set.
598d2bedfe7SMark Brown  * @val: Value to set (unshifted)
599d2bedfe7SMark Brown  */
wm831x_set_bits(struct wm831x * wm831x,unsigned short reg,unsigned short mask,unsigned short val)600d2bedfe7SMark Brown int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg,
601d2bedfe7SMark Brown 		    unsigned short mask, unsigned short val)
602d2bedfe7SMark Brown {
603d2bedfe7SMark Brown 	int ret;
604d2bedfe7SMark Brown 
605d2bedfe7SMark Brown 	mutex_lock(&wm831x->io_lock);
606d2bedfe7SMark Brown 
6071df5981bSMark Brown 	if (!wm831x_reg_locked(wm831x, reg))
6081df5981bSMark Brown 		ret = regmap_update_bits(wm831x->regmap, reg, mask, val);
6091df5981bSMark Brown 	else
6101df5981bSMark Brown 		ret = -EPERM;
611d2bedfe7SMark Brown 
612d2bedfe7SMark Brown 	mutex_unlock(&wm831x->io_lock);
613d2bedfe7SMark Brown 
614d2bedfe7SMark Brown 	return ret;
615d2bedfe7SMark Brown }
616d2bedfe7SMark Brown EXPORT_SYMBOL_GPL(wm831x_set_bits);
617d2bedfe7SMark Brown 
618f977284aSRikard Falkeborn static const struct resource wm831x_dcdc1_resources[] = {
619d2bedfe7SMark Brown 	{
620d2bedfe7SMark Brown 		.start = WM831X_DC1_CONTROL_1,
621d2bedfe7SMark Brown 		.end   = WM831X_DC1_DVS_CONTROL,
6225656098eSMark Brown 		.flags = IORESOURCE_REG,
623d2bedfe7SMark Brown 	},
6243da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_DC1, "UV"),
6253da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_HC_DC1, "HC"),
626d2bedfe7SMark Brown };
627d2bedfe7SMark Brown 
628d2bedfe7SMark Brown 
629f977284aSRikard Falkeborn static const struct resource wm831x_dcdc2_resources[] = {
630d2bedfe7SMark Brown 	{
631d2bedfe7SMark Brown 		.start = WM831X_DC2_CONTROL_1,
632d2bedfe7SMark Brown 		.end   = WM831X_DC2_DVS_CONTROL,
6335656098eSMark Brown 		.flags = IORESOURCE_REG,
634d2bedfe7SMark Brown 	},
6353da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_DC2, "UV"),
6363da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_HC_DC2, "HC"),
637d2bedfe7SMark Brown };
638d2bedfe7SMark Brown 
639f977284aSRikard Falkeborn static const struct resource wm831x_dcdc3_resources[] = {
640d2bedfe7SMark Brown 	{
641d2bedfe7SMark Brown 		.start = WM831X_DC3_CONTROL_1,
642d2bedfe7SMark Brown 		.end   = WM831X_DC3_SLEEP_CONTROL,
6435656098eSMark Brown 		.flags = IORESOURCE_REG,
644d2bedfe7SMark Brown 	},
6453da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_DC3, "UV"),
646d2bedfe7SMark Brown };
647d2bedfe7SMark Brown 
648f977284aSRikard Falkeborn static const struct resource wm831x_dcdc4_resources[] = {
649d2bedfe7SMark Brown 	{
650d2bedfe7SMark Brown 		.start = WM831X_DC4_CONTROL,
651d2bedfe7SMark Brown 		.end   = WM831X_DC4_SLEEP_CONTROL,
6525656098eSMark Brown 		.flags = IORESOURCE_REG,
653d2bedfe7SMark Brown 	},
6543da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_DC4, "UV"),
655d2bedfe7SMark Brown };
656d2bedfe7SMark Brown 
657f977284aSRikard Falkeborn static const struct resource wm8320_dcdc4_buck_resources[] = {
658d4e0a89eSMark Brown 	{
659d4e0a89eSMark Brown 		.start = WM831X_DC4_CONTROL,
660d4e0a89eSMark Brown 		.end   = WM832X_DC4_SLEEP_CONTROL,
6615656098eSMark Brown 		.flags = IORESOURCE_REG,
662d4e0a89eSMark Brown 	},
6633da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_DC4, "UV"),
664d4e0a89eSMark Brown };
665d4e0a89eSMark Brown 
666f977284aSRikard Falkeborn static const struct resource wm831x_gpio_resources[] = {
667d2bedfe7SMark Brown 	{
668d2bedfe7SMark Brown 		.start = WM831X_IRQ_GPIO_1,
669d2bedfe7SMark Brown 		.end   = WM831X_IRQ_GPIO_16,
670d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
671d2bedfe7SMark Brown 	},
672d2bedfe7SMark Brown };
673d2bedfe7SMark Brown 
674f977284aSRikard Falkeborn static const struct resource wm831x_isink1_resources[] = {
675d2bedfe7SMark Brown 	{
676d2bedfe7SMark Brown 		.start = WM831X_CURRENT_SINK_1,
677d2bedfe7SMark Brown 		.end   = WM831X_CURRENT_SINK_1,
6785656098eSMark Brown 		.flags = IORESOURCE_REG,
679d2bedfe7SMark Brown 	},
6803da286aaSZhen Lei 	DEFINE_RES_IRQ(WM831X_IRQ_CS1),
681d2bedfe7SMark Brown };
682d2bedfe7SMark Brown 
683f977284aSRikard Falkeborn static const struct resource wm831x_isink2_resources[] = {
684d2bedfe7SMark Brown 	{
685d2bedfe7SMark Brown 		.start = WM831X_CURRENT_SINK_2,
686d2bedfe7SMark Brown 		.end   = WM831X_CURRENT_SINK_2,
6875656098eSMark Brown 		.flags = IORESOURCE_REG,
688d2bedfe7SMark Brown 	},
6893da286aaSZhen Lei 	DEFINE_RES_IRQ(WM831X_IRQ_CS2),
690d2bedfe7SMark Brown };
691d2bedfe7SMark Brown 
692f977284aSRikard Falkeborn static const struct resource wm831x_ldo1_resources[] = {
693d2bedfe7SMark Brown 	{
694d2bedfe7SMark Brown 		.start = WM831X_LDO1_CONTROL,
695d2bedfe7SMark Brown 		.end   = WM831X_LDO1_SLEEP_CONTROL,
6965656098eSMark Brown 		.flags = IORESOURCE_REG,
697d2bedfe7SMark Brown 	},
6983da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO1, "UV"),
699d2bedfe7SMark Brown };
700d2bedfe7SMark Brown 
701f977284aSRikard Falkeborn static const struct resource wm831x_ldo2_resources[] = {
702d2bedfe7SMark Brown 	{
703d2bedfe7SMark Brown 		.start = WM831X_LDO2_CONTROL,
704d2bedfe7SMark Brown 		.end   = WM831X_LDO2_SLEEP_CONTROL,
7055656098eSMark Brown 		.flags = IORESOURCE_REG,
706d2bedfe7SMark Brown 	},
7073da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO2, "UV"),
708d2bedfe7SMark Brown };
709d2bedfe7SMark Brown 
710f977284aSRikard Falkeborn static const struct resource wm831x_ldo3_resources[] = {
711d2bedfe7SMark Brown 	{
712d2bedfe7SMark Brown 		.start = WM831X_LDO3_CONTROL,
713d2bedfe7SMark Brown 		.end   = WM831X_LDO3_SLEEP_CONTROL,
7145656098eSMark Brown 		.flags = IORESOURCE_REG,
715d2bedfe7SMark Brown 	},
7163da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO3, "UV"),
717d2bedfe7SMark Brown };
718d2bedfe7SMark Brown 
719f977284aSRikard Falkeborn static const struct resource wm831x_ldo4_resources[] = {
720d2bedfe7SMark Brown 	{
721d2bedfe7SMark Brown 		.start = WM831X_LDO4_CONTROL,
722d2bedfe7SMark Brown 		.end   = WM831X_LDO4_SLEEP_CONTROL,
7235656098eSMark Brown 		.flags = IORESOURCE_REG,
724d2bedfe7SMark Brown 	},
7253da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO4, "UV"),
726d2bedfe7SMark Brown };
727d2bedfe7SMark Brown 
728f977284aSRikard Falkeborn static const struct resource wm831x_ldo5_resources[] = {
729d2bedfe7SMark Brown 	{
730d2bedfe7SMark Brown 		.start = WM831X_LDO5_CONTROL,
731d2bedfe7SMark Brown 		.end   = WM831X_LDO5_SLEEP_CONTROL,
7325656098eSMark Brown 		.flags = IORESOURCE_REG,
733d2bedfe7SMark Brown 	},
7343da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO5, "UV"),
735d2bedfe7SMark Brown };
736d2bedfe7SMark Brown 
737f977284aSRikard Falkeborn static const struct resource wm831x_ldo6_resources[] = {
738d2bedfe7SMark Brown 	{
739d2bedfe7SMark Brown 		.start = WM831X_LDO6_CONTROL,
740d2bedfe7SMark Brown 		.end   = WM831X_LDO6_SLEEP_CONTROL,
7415656098eSMark Brown 		.flags = IORESOURCE_REG,
742d2bedfe7SMark Brown 	},
7433da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO6, "UV"),
744d2bedfe7SMark Brown };
745d2bedfe7SMark Brown 
746f977284aSRikard Falkeborn static const struct resource wm831x_ldo7_resources[] = {
747d2bedfe7SMark Brown 	{
748d2bedfe7SMark Brown 		.start = WM831X_LDO7_CONTROL,
749d2bedfe7SMark Brown 		.end   = WM831X_LDO7_SLEEP_CONTROL,
7505656098eSMark Brown 		.flags = IORESOURCE_REG,
751d2bedfe7SMark Brown 	},
7523da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO7, "UV"),
753d2bedfe7SMark Brown };
754d2bedfe7SMark Brown 
755f977284aSRikard Falkeborn static const struct resource wm831x_ldo8_resources[] = {
756d2bedfe7SMark Brown 	{
757d2bedfe7SMark Brown 		.start = WM831X_LDO8_CONTROL,
758d2bedfe7SMark Brown 		.end   = WM831X_LDO8_SLEEP_CONTROL,
7595656098eSMark Brown 		.flags = IORESOURCE_REG,
760d2bedfe7SMark Brown 	},
7613da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO8, "UV"),
762d2bedfe7SMark Brown };
763d2bedfe7SMark Brown 
764f977284aSRikard Falkeborn static const struct resource wm831x_ldo9_resources[] = {
765d2bedfe7SMark Brown 	{
766d2bedfe7SMark Brown 		.start = WM831X_LDO9_CONTROL,
767d2bedfe7SMark Brown 		.end   = WM831X_LDO9_SLEEP_CONTROL,
7685656098eSMark Brown 		.flags = IORESOURCE_REG,
769d2bedfe7SMark Brown 	},
7703da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO9, "UV"),
771d2bedfe7SMark Brown };
772d2bedfe7SMark Brown 
773f977284aSRikard Falkeborn static const struct resource wm831x_ldo10_resources[] = {
774d2bedfe7SMark Brown 	{
775d2bedfe7SMark Brown 		.start = WM831X_LDO10_CONTROL,
776d2bedfe7SMark Brown 		.end   = WM831X_LDO10_SLEEP_CONTROL,
7775656098eSMark Brown 		.flags = IORESOURCE_REG,
778d2bedfe7SMark Brown 	},
7793da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO10, "UV"),
780d2bedfe7SMark Brown };
781d2bedfe7SMark Brown 
782f977284aSRikard Falkeborn static const struct resource wm831x_ldo11_resources[] = {
783d2bedfe7SMark Brown 	{
784d2bedfe7SMark Brown 		.start = WM831X_LDO11_ON_CONTROL,
785d2bedfe7SMark Brown 		.end   = WM831X_LDO11_SLEEP_CONTROL,
7865656098eSMark Brown 		.flags = IORESOURCE_REG,
787d2bedfe7SMark Brown 	},
788d2bedfe7SMark Brown };
789d2bedfe7SMark Brown 
790f977284aSRikard Falkeborn static const struct resource wm831x_on_resources[] = {
7913da286aaSZhen Lei 	DEFINE_RES_IRQ(WM831X_IRQ_ON),
792d2bedfe7SMark Brown };
793d2bedfe7SMark Brown 
794d2bedfe7SMark Brown 
795f977284aSRikard Falkeborn static const struct resource wm831x_power_resources[] = {
7963da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_PPM_SYSLO, "SYSLO"),
7973da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_PPM_PWR_SRC, "PWR SRC"),
7983da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_PPM_USB_CURR, "USB CURR"),
7993da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_CHG_BATT_HOT, "BATT HOT"),
8003da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_CHG_BATT_COLD, "BATT COLD"),
8013da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_CHG_BATT_FAIL, "BATT FAIL"),
8023da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_CHG_OV, "OV"),
8033da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_CHG_END, "END"),
8043da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_CHG_TO, "TO"),
8053da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_CHG_MODE, "MODE"),
8063da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_CHG_START, "START"),
807d2bedfe7SMark Brown };
808d2bedfe7SMark Brown 
809f977284aSRikard Falkeborn static const struct resource wm831x_rtc_resources[] = {
8103da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_RTC_PER, "PER"),
8113da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_RTC_ALM, "ALM"),
812d2bedfe7SMark Brown };
813d2bedfe7SMark Brown 
814f977284aSRikard Falkeborn static const struct resource wm831x_status1_resources[] = {
815d2bedfe7SMark Brown 	{
816d2bedfe7SMark Brown 		.start = WM831X_STATUS_LED_1,
817d2bedfe7SMark Brown 		.end   = WM831X_STATUS_LED_1,
8185656098eSMark Brown 		.flags = IORESOURCE_REG,
819d2bedfe7SMark Brown 	},
820d2bedfe7SMark Brown };
821d2bedfe7SMark Brown 
822f977284aSRikard Falkeborn static const struct resource wm831x_status2_resources[] = {
823d2bedfe7SMark Brown 	{
824d2bedfe7SMark Brown 		.start = WM831X_STATUS_LED_2,
825d2bedfe7SMark Brown 		.end   = WM831X_STATUS_LED_2,
8265656098eSMark Brown 		.flags = IORESOURCE_REG,
827d2bedfe7SMark Brown 	},
828d2bedfe7SMark Brown };
829d2bedfe7SMark Brown 
830f977284aSRikard Falkeborn static const struct resource wm831x_touch_resources[] = {
8313da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_TCHPD, "TCHPD"),
8323da286aaSZhen Lei 	DEFINE_RES_IRQ_NAMED(WM831X_IRQ_TCHDATA, "TCHDATA"),
833d2bedfe7SMark Brown };
834d2bedfe7SMark Brown 
835f977284aSRikard Falkeborn static const struct resource wm831x_wdt_resources[] = {
8363da286aaSZhen Lei 	DEFINE_RES_IRQ(WM831X_IRQ_WDOG_TO),
837d2bedfe7SMark Brown };
838d2bedfe7SMark Brown 
839ad59de48SGeert Uytterhoeven static const struct mfd_cell wm8310_devs[] = {
840d2bedfe7SMark Brown 	{
841c26964eaSMark Brown 		.name = "wm831x-backup",
842c26964eaSMark Brown 	},
843c26964eaSMark Brown 	{
844d2bedfe7SMark Brown 		.name = "wm831x-buckv",
845d2bedfe7SMark Brown 		.id = 1,
846d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
847d2bedfe7SMark Brown 		.resources = wm831x_dcdc1_resources,
848d2bedfe7SMark Brown 	},
849d2bedfe7SMark Brown 	{
850d2bedfe7SMark Brown 		.name = "wm831x-buckv",
851d2bedfe7SMark Brown 		.id = 2,
852d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
853d2bedfe7SMark Brown 		.resources = wm831x_dcdc2_resources,
854d2bedfe7SMark Brown 	},
855d2bedfe7SMark Brown 	{
856d2bedfe7SMark Brown 		.name = "wm831x-buckp",
857d2bedfe7SMark Brown 		.id = 3,
858d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
859d2bedfe7SMark Brown 		.resources = wm831x_dcdc3_resources,
860d2bedfe7SMark Brown 	},
861d2bedfe7SMark Brown 	{
862d2bedfe7SMark Brown 		.name = "wm831x-boostp",
863d2bedfe7SMark Brown 		.id = 4,
864d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
865d2bedfe7SMark Brown 		.resources = wm831x_dcdc4_resources,
866d2bedfe7SMark Brown 	},
867d2bedfe7SMark Brown 	{
868a5e06781SMark Brown 		.name = "wm831x-clk",
869a5e06781SMark Brown 	},
870a5e06781SMark Brown 	{
871d2bedfe7SMark Brown 		.name = "wm831x-epe",
872d2bedfe7SMark Brown 		.id = 1,
873d2bedfe7SMark Brown 	},
874d2bedfe7SMark Brown 	{
875d2bedfe7SMark Brown 		.name = "wm831x-epe",
876d2bedfe7SMark Brown 		.id = 2,
877d2bedfe7SMark Brown 	},
878d2bedfe7SMark Brown 	{
879d2bedfe7SMark Brown 		.name = "wm831x-gpio",
880d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_gpio_resources),
881d2bedfe7SMark Brown 		.resources = wm831x_gpio_resources,
882d2bedfe7SMark Brown 	},
883d2bedfe7SMark Brown 	{
884d2bedfe7SMark Brown 		.name = "wm831x-hwmon",
885d2bedfe7SMark Brown 	},
886d2bedfe7SMark Brown 	{
887d2bedfe7SMark Brown 		.name = "wm831x-isink",
888d2bedfe7SMark Brown 		.id = 1,
889d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_isink1_resources),
890d2bedfe7SMark Brown 		.resources = wm831x_isink1_resources,
891d2bedfe7SMark Brown 	},
892d2bedfe7SMark Brown 	{
893d2bedfe7SMark Brown 		.name = "wm831x-isink",
894d2bedfe7SMark Brown 		.id = 2,
895d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_isink2_resources),
896d2bedfe7SMark Brown 		.resources = wm831x_isink2_resources,
897d2bedfe7SMark Brown 	},
898d2bedfe7SMark Brown 	{
899d2bedfe7SMark Brown 		.name = "wm831x-ldo",
900d2bedfe7SMark Brown 		.id = 1,
901d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
902d2bedfe7SMark Brown 		.resources = wm831x_ldo1_resources,
903d2bedfe7SMark Brown 	},
904d2bedfe7SMark Brown 	{
905d2bedfe7SMark Brown 		.name = "wm831x-ldo",
906d2bedfe7SMark Brown 		.id = 2,
907d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
908d2bedfe7SMark Brown 		.resources = wm831x_ldo2_resources,
909d2bedfe7SMark Brown 	},
910d2bedfe7SMark Brown 	{
911d2bedfe7SMark Brown 		.name = "wm831x-ldo",
912d2bedfe7SMark Brown 		.id = 3,
913d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
914d2bedfe7SMark Brown 		.resources = wm831x_ldo3_resources,
915d2bedfe7SMark Brown 	},
916d2bedfe7SMark Brown 	{
917d2bedfe7SMark Brown 		.name = "wm831x-ldo",
918d2bedfe7SMark Brown 		.id = 4,
919d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
920d2bedfe7SMark Brown 		.resources = wm831x_ldo4_resources,
921d2bedfe7SMark Brown 	},
922d2bedfe7SMark Brown 	{
923d2bedfe7SMark Brown 		.name = "wm831x-ldo",
924d2bedfe7SMark Brown 		.id = 5,
925d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
926d2bedfe7SMark Brown 		.resources = wm831x_ldo5_resources,
927d2bedfe7SMark Brown 	},
928d2bedfe7SMark Brown 	{
929d2bedfe7SMark Brown 		.name = "wm831x-ldo",
930d2bedfe7SMark Brown 		.id = 6,
931d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
932d2bedfe7SMark Brown 		.resources = wm831x_ldo6_resources,
933d2bedfe7SMark Brown 	},
934d2bedfe7SMark Brown 	{
935d2bedfe7SMark Brown 		.name = "wm831x-aldo",
936d2bedfe7SMark Brown 		.id = 7,
937d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
938d2bedfe7SMark Brown 		.resources = wm831x_ldo7_resources,
939d2bedfe7SMark Brown 	},
940d2bedfe7SMark Brown 	{
941d2bedfe7SMark Brown 		.name = "wm831x-aldo",
942d2bedfe7SMark Brown 		.id = 8,
943d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
944d2bedfe7SMark Brown 		.resources = wm831x_ldo8_resources,
945d2bedfe7SMark Brown 	},
946d2bedfe7SMark Brown 	{
947d2bedfe7SMark Brown 		.name = "wm831x-aldo",
948d2bedfe7SMark Brown 		.id = 9,
949d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
950d2bedfe7SMark Brown 		.resources = wm831x_ldo9_resources,
951d2bedfe7SMark Brown 	},
952d2bedfe7SMark Brown 	{
953d2bedfe7SMark Brown 		.name = "wm831x-aldo",
954d2bedfe7SMark Brown 		.id = 10,
955d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
956d2bedfe7SMark Brown 		.resources = wm831x_ldo10_resources,
957d2bedfe7SMark Brown 	},
958d2bedfe7SMark Brown 	{
959d2bedfe7SMark Brown 		.name = "wm831x-alive-ldo",
960d2bedfe7SMark Brown 		.id = 11,
961d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
962d2bedfe7SMark Brown 		.resources = wm831x_ldo11_resources,
963d2bedfe7SMark Brown 	},
964d2bedfe7SMark Brown 	{
965d2bedfe7SMark Brown 		.name = "wm831x-on",
966d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_on_resources),
967d2bedfe7SMark Brown 		.resources = wm831x_on_resources,
968d2bedfe7SMark Brown 	},
969d2bedfe7SMark Brown 	{
970d2bedfe7SMark Brown 		.name = "wm831x-power",
971d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_power_resources),
972d2bedfe7SMark Brown 		.resources = wm831x_power_resources,
973d2bedfe7SMark Brown 	},
974d2bedfe7SMark Brown 	{
975d2bedfe7SMark Brown 		.name = "wm831x-status",
976d2bedfe7SMark Brown 		.id = 1,
977d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_status1_resources),
978d2bedfe7SMark Brown 		.resources = wm831x_status1_resources,
979d2bedfe7SMark Brown 	},
980d2bedfe7SMark Brown 	{
981d2bedfe7SMark Brown 		.name = "wm831x-status",
982d2bedfe7SMark Brown 		.id = 2,
983d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_status2_resources),
984d2bedfe7SMark Brown 		.resources = wm831x_status2_resources,
985d2bedfe7SMark Brown 	},
986d2bedfe7SMark Brown 	{
987d2bedfe7SMark Brown 		.name = "wm831x-watchdog",
988d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_wdt_resources),
989d2bedfe7SMark Brown 		.resources = wm831x_wdt_resources,
990d2bedfe7SMark Brown 	},
991d2bedfe7SMark Brown };
992d2bedfe7SMark Brown 
993ad59de48SGeert Uytterhoeven static const struct mfd_cell wm8311_devs[] = {
994d2bedfe7SMark Brown 	{
995c26964eaSMark Brown 		.name = "wm831x-backup",
996c26964eaSMark Brown 	},
997c26964eaSMark Brown 	{
998d2bedfe7SMark Brown 		.name = "wm831x-buckv",
999d2bedfe7SMark Brown 		.id = 1,
1000d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
1001d2bedfe7SMark Brown 		.resources = wm831x_dcdc1_resources,
1002d2bedfe7SMark Brown 	},
1003d2bedfe7SMark Brown 	{
1004d2bedfe7SMark Brown 		.name = "wm831x-buckv",
1005d2bedfe7SMark Brown 		.id = 2,
1006d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
1007d2bedfe7SMark Brown 		.resources = wm831x_dcdc2_resources,
1008d2bedfe7SMark Brown 	},
1009d2bedfe7SMark Brown 	{
1010d2bedfe7SMark Brown 		.name = "wm831x-buckp",
1011d2bedfe7SMark Brown 		.id = 3,
1012d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
1013d2bedfe7SMark Brown 		.resources = wm831x_dcdc3_resources,
1014d2bedfe7SMark Brown 	},
1015d2bedfe7SMark Brown 	{
1016d2bedfe7SMark Brown 		.name = "wm831x-boostp",
1017d2bedfe7SMark Brown 		.id = 4,
1018d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
1019d2bedfe7SMark Brown 		.resources = wm831x_dcdc4_resources,
1020d2bedfe7SMark Brown 	},
1021d2bedfe7SMark Brown 	{
1022a5e06781SMark Brown 		.name = "wm831x-clk",
1023a5e06781SMark Brown 	},
1024a5e06781SMark Brown 	{
1025d2bedfe7SMark Brown 		.name = "wm831x-epe",
1026d2bedfe7SMark Brown 		.id = 1,
1027d2bedfe7SMark Brown 	},
1028d2bedfe7SMark Brown 	{
1029d2bedfe7SMark Brown 		.name = "wm831x-epe",
1030d2bedfe7SMark Brown 		.id = 2,
1031d2bedfe7SMark Brown 	},
1032d2bedfe7SMark Brown 	{
1033d2bedfe7SMark Brown 		.name = "wm831x-gpio",
1034d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_gpio_resources),
1035d2bedfe7SMark Brown 		.resources = wm831x_gpio_resources,
1036d2bedfe7SMark Brown 	},
1037d2bedfe7SMark Brown 	{
1038d2bedfe7SMark Brown 		.name = "wm831x-hwmon",
1039d2bedfe7SMark Brown 	},
1040d2bedfe7SMark Brown 	{
1041d2bedfe7SMark Brown 		.name = "wm831x-isink",
1042d2bedfe7SMark Brown 		.id = 1,
1043d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_isink1_resources),
1044d2bedfe7SMark Brown 		.resources = wm831x_isink1_resources,
1045d2bedfe7SMark Brown 	},
1046d2bedfe7SMark Brown 	{
1047d2bedfe7SMark Brown 		.name = "wm831x-isink",
1048d2bedfe7SMark Brown 		.id = 2,
1049d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_isink2_resources),
1050d2bedfe7SMark Brown 		.resources = wm831x_isink2_resources,
1051d2bedfe7SMark Brown 	},
1052d2bedfe7SMark Brown 	{
1053d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1054d2bedfe7SMark Brown 		.id = 1,
1055d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
1056d2bedfe7SMark Brown 		.resources = wm831x_ldo1_resources,
1057d2bedfe7SMark Brown 	},
1058d2bedfe7SMark Brown 	{
1059d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1060d2bedfe7SMark Brown 		.id = 2,
1061d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
1062d2bedfe7SMark Brown 		.resources = wm831x_ldo2_resources,
1063d2bedfe7SMark Brown 	},
1064d2bedfe7SMark Brown 	{
1065d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1066d2bedfe7SMark Brown 		.id = 3,
1067d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
1068d2bedfe7SMark Brown 		.resources = wm831x_ldo3_resources,
1069d2bedfe7SMark Brown 	},
1070d2bedfe7SMark Brown 	{
1071d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1072d2bedfe7SMark Brown 		.id = 4,
1073d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
1074d2bedfe7SMark Brown 		.resources = wm831x_ldo4_resources,
1075d2bedfe7SMark Brown 	},
1076d2bedfe7SMark Brown 	{
1077d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1078d2bedfe7SMark Brown 		.id = 5,
1079d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
1080d2bedfe7SMark Brown 		.resources = wm831x_ldo5_resources,
1081d2bedfe7SMark Brown 	},
1082d2bedfe7SMark Brown 	{
1083d2bedfe7SMark Brown 		.name = "wm831x-aldo",
1084d2bedfe7SMark Brown 		.id = 7,
1085d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
1086d2bedfe7SMark Brown 		.resources = wm831x_ldo7_resources,
1087d2bedfe7SMark Brown 	},
1088d2bedfe7SMark Brown 	{
1089d2bedfe7SMark Brown 		.name = "wm831x-alive-ldo",
1090d2bedfe7SMark Brown 		.id = 11,
1091d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
1092d2bedfe7SMark Brown 		.resources = wm831x_ldo11_resources,
1093d2bedfe7SMark Brown 	},
1094d2bedfe7SMark Brown 	{
1095d2bedfe7SMark Brown 		.name = "wm831x-on",
1096d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_on_resources),
1097d2bedfe7SMark Brown 		.resources = wm831x_on_resources,
1098d2bedfe7SMark Brown 	},
1099d2bedfe7SMark Brown 	{
1100d2bedfe7SMark Brown 		.name = "wm831x-power",
1101d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_power_resources),
1102d2bedfe7SMark Brown 		.resources = wm831x_power_resources,
1103d2bedfe7SMark Brown 	},
1104d2bedfe7SMark Brown 	{
1105d2bedfe7SMark Brown 		.name = "wm831x-status",
1106d2bedfe7SMark Brown 		.id = 1,
1107d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_status1_resources),
1108d2bedfe7SMark Brown 		.resources = wm831x_status1_resources,
1109d2bedfe7SMark Brown 	},
1110d2bedfe7SMark Brown 	{
1111d2bedfe7SMark Brown 		.name = "wm831x-status",
1112d2bedfe7SMark Brown 		.id = 2,
1113d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_status2_resources),
1114d2bedfe7SMark Brown 		.resources = wm831x_status2_resources,
1115d2bedfe7SMark Brown 	},
1116d2bedfe7SMark Brown 	{
1117d2bedfe7SMark Brown 		.name = "wm831x-watchdog",
1118d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_wdt_resources),
1119d2bedfe7SMark Brown 		.resources = wm831x_wdt_resources,
1120d2bedfe7SMark Brown 	},
1121d2bedfe7SMark Brown };
1122d2bedfe7SMark Brown 
1123ad59de48SGeert Uytterhoeven static const struct mfd_cell wm8312_devs[] = {
1124d2bedfe7SMark Brown 	{
1125c26964eaSMark Brown 		.name = "wm831x-backup",
1126c26964eaSMark Brown 	},
1127c26964eaSMark Brown 	{
1128d2bedfe7SMark Brown 		.name = "wm831x-buckv",
1129d2bedfe7SMark Brown 		.id = 1,
1130d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
1131d2bedfe7SMark Brown 		.resources = wm831x_dcdc1_resources,
1132d2bedfe7SMark Brown 	},
1133d2bedfe7SMark Brown 	{
1134d2bedfe7SMark Brown 		.name = "wm831x-buckv",
1135d2bedfe7SMark Brown 		.id = 2,
1136d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
1137d2bedfe7SMark Brown 		.resources = wm831x_dcdc2_resources,
1138d2bedfe7SMark Brown 	},
1139d2bedfe7SMark Brown 	{
1140d2bedfe7SMark Brown 		.name = "wm831x-buckp",
1141d2bedfe7SMark Brown 		.id = 3,
1142d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
1143d2bedfe7SMark Brown 		.resources = wm831x_dcdc3_resources,
1144d2bedfe7SMark Brown 	},
1145d2bedfe7SMark Brown 	{
1146d2bedfe7SMark Brown 		.name = "wm831x-boostp",
1147d2bedfe7SMark Brown 		.id = 4,
1148d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
1149d2bedfe7SMark Brown 		.resources = wm831x_dcdc4_resources,
1150d2bedfe7SMark Brown 	},
1151d2bedfe7SMark Brown 	{
1152a5e06781SMark Brown 		.name = "wm831x-clk",
1153a5e06781SMark Brown 	},
1154a5e06781SMark Brown 	{
1155d2bedfe7SMark Brown 		.name = "wm831x-epe",
1156d2bedfe7SMark Brown 		.id = 1,
1157d2bedfe7SMark Brown 	},
1158d2bedfe7SMark Brown 	{
1159d2bedfe7SMark Brown 		.name = "wm831x-epe",
1160d2bedfe7SMark Brown 		.id = 2,
1161d2bedfe7SMark Brown 	},
1162d2bedfe7SMark Brown 	{
1163d2bedfe7SMark Brown 		.name = "wm831x-gpio",
1164d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_gpio_resources),
1165d2bedfe7SMark Brown 		.resources = wm831x_gpio_resources,
1166d2bedfe7SMark Brown 	},
1167d2bedfe7SMark Brown 	{
1168d2bedfe7SMark Brown 		.name = "wm831x-hwmon",
1169d2bedfe7SMark Brown 	},
1170d2bedfe7SMark Brown 	{
1171d2bedfe7SMark Brown 		.name = "wm831x-isink",
1172d2bedfe7SMark Brown 		.id = 1,
1173d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_isink1_resources),
1174d2bedfe7SMark Brown 		.resources = wm831x_isink1_resources,
1175d2bedfe7SMark Brown 	},
1176d2bedfe7SMark Brown 	{
1177d2bedfe7SMark Brown 		.name = "wm831x-isink",
1178d2bedfe7SMark Brown 		.id = 2,
1179d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_isink2_resources),
1180d2bedfe7SMark Brown 		.resources = wm831x_isink2_resources,
1181d2bedfe7SMark Brown 	},
1182d2bedfe7SMark Brown 	{
1183d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1184d2bedfe7SMark Brown 		.id = 1,
1185d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
1186d2bedfe7SMark Brown 		.resources = wm831x_ldo1_resources,
1187d2bedfe7SMark Brown 	},
1188d2bedfe7SMark Brown 	{
1189d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1190d2bedfe7SMark Brown 		.id = 2,
1191d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
1192d2bedfe7SMark Brown 		.resources = wm831x_ldo2_resources,
1193d2bedfe7SMark Brown 	},
1194d2bedfe7SMark Brown 	{
1195d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1196d2bedfe7SMark Brown 		.id = 3,
1197d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
1198d2bedfe7SMark Brown 		.resources = wm831x_ldo3_resources,
1199d2bedfe7SMark Brown 	},
1200d2bedfe7SMark Brown 	{
1201d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1202d2bedfe7SMark Brown 		.id = 4,
1203d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
1204d2bedfe7SMark Brown 		.resources = wm831x_ldo4_resources,
1205d2bedfe7SMark Brown 	},
1206d2bedfe7SMark Brown 	{
1207d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1208d2bedfe7SMark Brown 		.id = 5,
1209d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
1210d2bedfe7SMark Brown 		.resources = wm831x_ldo5_resources,
1211d2bedfe7SMark Brown 	},
1212d2bedfe7SMark Brown 	{
1213d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1214d2bedfe7SMark Brown 		.id = 6,
1215d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
1216d2bedfe7SMark Brown 		.resources = wm831x_ldo6_resources,
1217d2bedfe7SMark Brown 	},
1218d2bedfe7SMark Brown 	{
1219d2bedfe7SMark Brown 		.name = "wm831x-aldo",
1220d2bedfe7SMark Brown 		.id = 7,
1221d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
1222d2bedfe7SMark Brown 		.resources = wm831x_ldo7_resources,
1223d2bedfe7SMark Brown 	},
1224d2bedfe7SMark Brown 	{
1225d2bedfe7SMark Brown 		.name = "wm831x-aldo",
1226d2bedfe7SMark Brown 		.id = 8,
1227d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
1228d2bedfe7SMark Brown 		.resources = wm831x_ldo8_resources,
1229d2bedfe7SMark Brown 	},
1230d2bedfe7SMark Brown 	{
1231d2bedfe7SMark Brown 		.name = "wm831x-aldo",
1232d2bedfe7SMark Brown 		.id = 9,
1233d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
1234d2bedfe7SMark Brown 		.resources = wm831x_ldo9_resources,
1235d2bedfe7SMark Brown 	},
1236d2bedfe7SMark Brown 	{
1237d2bedfe7SMark Brown 		.name = "wm831x-aldo",
1238d2bedfe7SMark Brown 		.id = 10,
1239d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
1240d2bedfe7SMark Brown 		.resources = wm831x_ldo10_resources,
1241d2bedfe7SMark Brown 	},
1242d2bedfe7SMark Brown 	{
1243d2bedfe7SMark Brown 		.name = "wm831x-alive-ldo",
1244d2bedfe7SMark Brown 		.id = 11,
1245d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
1246d2bedfe7SMark Brown 		.resources = wm831x_ldo11_resources,
1247d2bedfe7SMark Brown 	},
1248d2bedfe7SMark Brown 	{
1249d2bedfe7SMark Brown 		.name = "wm831x-on",
1250d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_on_resources),
1251d2bedfe7SMark Brown 		.resources = wm831x_on_resources,
1252d2bedfe7SMark Brown 	},
1253d2bedfe7SMark Brown 	{
1254d2bedfe7SMark Brown 		.name = "wm831x-power",
1255d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_power_resources),
1256d2bedfe7SMark Brown 		.resources = wm831x_power_resources,
1257d2bedfe7SMark Brown 	},
1258d2bedfe7SMark Brown 	{
1259d2bedfe7SMark Brown 		.name = "wm831x-status",
1260d2bedfe7SMark Brown 		.id = 1,
1261d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_status1_resources),
1262d2bedfe7SMark Brown 		.resources = wm831x_status1_resources,
1263d2bedfe7SMark Brown 	},
1264d2bedfe7SMark Brown 	{
1265d2bedfe7SMark Brown 		.name = "wm831x-status",
1266d2bedfe7SMark Brown 		.id = 2,
1267d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_status2_resources),
1268d2bedfe7SMark Brown 		.resources = wm831x_status2_resources,
1269d2bedfe7SMark Brown 	},
1270d2bedfe7SMark Brown 	{
1271d2bedfe7SMark Brown 		.name = "wm831x-watchdog",
1272d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_wdt_resources),
1273d2bedfe7SMark Brown 		.resources = wm831x_wdt_resources,
1274d2bedfe7SMark Brown 	},
1275d2bedfe7SMark Brown };
1276d2bedfe7SMark Brown 
1277ad59de48SGeert Uytterhoeven static const struct mfd_cell wm8320_devs[] = {
1278d4e0a89eSMark Brown 	{
1279d4e0a89eSMark Brown 		.name = "wm831x-backup",
1280d4e0a89eSMark Brown 	},
1281d4e0a89eSMark Brown 	{
1282d4e0a89eSMark Brown 		.name = "wm831x-buckv",
1283d4e0a89eSMark Brown 		.id = 1,
1284d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
1285d4e0a89eSMark Brown 		.resources = wm831x_dcdc1_resources,
1286d4e0a89eSMark Brown 	},
1287d4e0a89eSMark Brown 	{
1288d4e0a89eSMark Brown 		.name = "wm831x-buckv",
1289d4e0a89eSMark Brown 		.id = 2,
1290d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
1291d4e0a89eSMark Brown 		.resources = wm831x_dcdc2_resources,
1292d4e0a89eSMark Brown 	},
1293d4e0a89eSMark Brown 	{
1294d4e0a89eSMark Brown 		.name = "wm831x-buckp",
1295d4e0a89eSMark Brown 		.id = 3,
1296d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
1297d4e0a89eSMark Brown 		.resources = wm831x_dcdc3_resources,
1298d4e0a89eSMark Brown 	},
1299d4e0a89eSMark Brown 	{
1300d4e0a89eSMark Brown 		.name = "wm831x-buckp",
1301d4e0a89eSMark Brown 		.id = 4,
1302d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm8320_dcdc4_buck_resources),
1303d4e0a89eSMark Brown 		.resources = wm8320_dcdc4_buck_resources,
1304d4e0a89eSMark Brown 	},
1305d4e0a89eSMark Brown 	{
1306a5e06781SMark Brown 		.name = "wm831x-clk",
1307a5e06781SMark Brown 	},
1308a5e06781SMark Brown 	{
1309d4e0a89eSMark Brown 		.name = "wm831x-gpio",
1310d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_gpio_resources),
1311d4e0a89eSMark Brown 		.resources = wm831x_gpio_resources,
1312d4e0a89eSMark Brown 	},
1313d4e0a89eSMark Brown 	{
1314d4e0a89eSMark Brown 		.name = "wm831x-hwmon",
1315d4e0a89eSMark Brown 	},
1316d4e0a89eSMark Brown 	{
1317d4e0a89eSMark Brown 		.name = "wm831x-ldo",
1318d4e0a89eSMark Brown 		.id = 1,
1319d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
1320d4e0a89eSMark Brown 		.resources = wm831x_ldo1_resources,
1321d4e0a89eSMark Brown 	},
1322d4e0a89eSMark Brown 	{
1323d4e0a89eSMark Brown 		.name = "wm831x-ldo",
1324d4e0a89eSMark Brown 		.id = 2,
1325d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
1326d4e0a89eSMark Brown 		.resources = wm831x_ldo2_resources,
1327d4e0a89eSMark Brown 	},
1328d4e0a89eSMark Brown 	{
1329d4e0a89eSMark Brown 		.name = "wm831x-ldo",
1330d4e0a89eSMark Brown 		.id = 3,
1331d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
1332d4e0a89eSMark Brown 		.resources = wm831x_ldo3_resources,
1333d4e0a89eSMark Brown 	},
1334d4e0a89eSMark Brown 	{
1335d4e0a89eSMark Brown 		.name = "wm831x-ldo",
1336d4e0a89eSMark Brown 		.id = 4,
1337d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
1338d4e0a89eSMark Brown 		.resources = wm831x_ldo4_resources,
1339d4e0a89eSMark Brown 	},
1340d4e0a89eSMark Brown 	{
1341d4e0a89eSMark Brown 		.name = "wm831x-ldo",
1342d4e0a89eSMark Brown 		.id = 5,
1343d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
1344d4e0a89eSMark Brown 		.resources = wm831x_ldo5_resources,
1345d4e0a89eSMark Brown 	},
1346d4e0a89eSMark Brown 	{
1347d4e0a89eSMark Brown 		.name = "wm831x-ldo",
1348d4e0a89eSMark Brown 		.id = 6,
1349d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
1350d4e0a89eSMark Brown 		.resources = wm831x_ldo6_resources,
1351d4e0a89eSMark Brown 	},
1352d4e0a89eSMark Brown 	{
1353d4e0a89eSMark Brown 		.name = "wm831x-aldo",
1354d4e0a89eSMark Brown 		.id = 7,
1355d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
1356d4e0a89eSMark Brown 		.resources = wm831x_ldo7_resources,
1357d4e0a89eSMark Brown 	},
1358d4e0a89eSMark Brown 	{
1359d4e0a89eSMark Brown 		.name = "wm831x-aldo",
1360d4e0a89eSMark Brown 		.id = 8,
1361d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
1362d4e0a89eSMark Brown 		.resources = wm831x_ldo8_resources,
1363d4e0a89eSMark Brown 	},
1364d4e0a89eSMark Brown 	{
1365d4e0a89eSMark Brown 		.name = "wm831x-aldo",
1366d4e0a89eSMark Brown 		.id = 9,
1367d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
1368d4e0a89eSMark Brown 		.resources = wm831x_ldo9_resources,
1369d4e0a89eSMark Brown 	},
1370d4e0a89eSMark Brown 	{
1371d4e0a89eSMark Brown 		.name = "wm831x-aldo",
1372d4e0a89eSMark Brown 		.id = 10,
1373d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
1374d4e0a89eSMark Brown 		.resources = wm831x_ldo10_resources,
1375d4e0a89eSMark Brown 	},
1376d4e0a89eSMark Brown 	{
1377d4e0a89eSMark Brown 		.name = "wm831x-alive-ldo",
1378d4e0a89eSMark Brown 		.id = 11,
1379d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
1380d4e0a89eSMark Brown 		.resources = wm831x_ldo11_resources,
1381d4e0a89eSMark Brown 	},
1382d4e0a89eSMark Brown 	{
1383d4e0a89eSMark Brown 		.name = "wm831x-on",
1384d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_on_resources),
1385d4e0a89eSMark Brown 		.resources = wm831x_on_resources,
1386d4e0a89eSMark Brown 	},
1387d4e0a89eSMark Brown 	{
1388d4e0a89eSMark Brown 		.name = "wm831x-status",
1389d4e0a89eSMark Brown 		.id = 1,
1390d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_status1_resources),
1391d4e0a89eSMark Brown 		.resources = wm831x_status1_resources,
1392d4e0a89eSMark Brown 	},
1393d4e0a89eSMark Brown 	{
1394d4e0a89eSMark Brown 		.name = "wm831x-status",
1395d4e0a89eSMark Brown 		.id = 2,
1396d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_status2_resources),
1397d4e0a89eSMark Brown 		.resources = wm831x_status2_resources,
1398d4e0a89eSMark Brown 	},
1399d4e0a89eSMark Brown 	{
1400d4e0a89eSMark Brown 		.name = "wm831x-watchdog",
1401d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_wdt_resources),
1402d4e0a89eSMark Brown 		.resources = wm831x_wdt_resources,
1403d4e0a89eSMark Brown 	},
1404d4e0a89eSMark Brown };
1405d4e0a89eSMark Brown 
1406ad59de48SGeert Uytterhoeven static const struct mfd_cell touch_devs[] = {
1407266a5e02SMark Brown 	{
1408266a5e02SMark Brown 		.name = "wm831x-touch",
1409266a5e02SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_touch_resources),
1410266a5e02SMark Brown 		.resources = wm831x_touch_resources,
1411266a5e02SMark Brown 	},
1412266a5e02SMark Brown };
1413266a5e02SMark Brown 
1414ad59de48SGeert Uytterhoeven static const struct mfd_cell rtc_devs[] = {
1415b9d03d99SMark Brown 	{
1416b9d03d99SMark Brown 		.name = "wm831x-rtc",
1417b9d03d99SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_rtc_resources),
1418b9d03d99SMark Brown 		.resources = wm831x_rtc_resources,
1419b9d03d99SMark Brown 	},
1420b9d03d99SMark Brown };
1421266a5e02SMark Brown 
1422ad59de48SGeert Uytterhoeven static const struct mfd_cell backlight_devs[] = {
142363aed85eSMark Brown 	{
142463aed85eSMark Brown 		.name = "wm831x-backlight",
142563aed85eSMark Brown 	},
142663aed85eSMark Brown };
142763aed85eSMark Brown 
14281df5981bSMark Brown struct regmap_config wm831x_regmap_config = {
14291df5981bSMark Brown 	.reg_bits = 16,
14301df5981bSMark Brown 	.val_bits = 16,
14312e47fff1SMark Brown 
14327ef47a12SMark Brown 	.cache_type = REGCACHE_MAPLE,
14337cccbdc8SMark Brown 
14342e47fff1SMark Brown 	.max_register = WM831X_DBE_CHECK_DATA,
14352e47fff1SMark Brown 	.readable_reg = wm831x_reg_readable,
14362e47fff1SMark Brown 	.writeable_reg = wm831x_reg_writeable,
14372e47fff1SMark Brown 	.volatile_reg = wm831x_reg_volatile,
14381df5981bSMark Brown };
14391df5981bSMark Brown EXPORT_SYMBOL_GPL(wm831x_regmap_config);
14401df5981bSMark Brown 
1441f6dd8449SCharles Keepax const struct of_device_id wm831x_of_match[] = {
1442f6dd8449SCharles Keepax 	{ .compatible = "wlf,wm8310", .data = (void *)WM8310 },
1443f6dd8449SCharles Keepax 	{ .compatible = "wlf,wm8311", .data = (void *)WM8311 },
1444f6dd8449SCharles Keepax 	{ .compatible = "wlf,wm8312", .data = (void *)WM8312 },
1445f6dd8449SCharles Keepax 	{ .compatible = "wlf,wm8320", .data = (void *)WM8320 },
1446f6dd8449SCharles Keepax 	{ .compatible = "wlf,wm8321", .data = (void *)WM8321 },
1447f6dd8449SCharles Keepax 	{ .compatible = "wlf,wm8325", .data = (void *)WM8325 },
1448f6dd8449SCharles Keepax 	{ .compatible = "wlf,wm8326", .data = (void *)WM8326 },
1449f6dd8449SCharles Keepax 	{ },
1450f6dd8449SCharles Keepax };
1451f6dd8449SCharles Keepax EXPORT_SYMBOL_GPL(wm831x_of_match);
1452f6dd8449SCharles Keepax 
1453d2bedfe7SMark Brown /*
1454d2bedfe7SMark Brown  * Instantiate the generic non-control parts of the device.
1455d2bedfe7SMark Brown  */
wm831x_device_init(struct wm831x * wm831x,int irq)1456f6dd8449SCharles Keepax int wm831x_device_init(struct wm831x *wm831x, int irq)
1457d2bedfe7SMark Brown {
1458f6dd8449SCharles Keepax 	struct wm831x_pdata *pdata = &wm831x->pdata;
1459eb503dc1SMark Brown 	int rev, wm831x_num;
1460d2bedfe7SMark Brown 	enum wm831x_parent parent;
14610b14c22eSMark Brown 	int ret, i;
1462d2bedfe7SMark Brown 
1463d2bedfe7SMark Brown 	mutex_init(&wm831x->io_lock);
1464d2bedfe7SMark Brown 	mutex_init(&wm831x->key_lock);
1465d2bedfe7SMark Brown 	dev_set_drvdata(wm831x->dev, wm831x);
146616dfd103SJavier Martinez Canillas 
1467523d9cfbSMark Brown 	wm831x->soft_shutdown = pdata->soft_shutdown;
1468d2bedfe7SMark Brown 
1469d2bedfe7SMark Brown 	ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
1470d2bedfe7SMark Brown 	if (ret < 0) {
1471d2bedfe7SMark Brown 		dev_err(wm831x->dev, "Failed to read parent ID: %d\n", ret);
1472130a7032SMark Brown 		goto err;
1473d2bedfe7SMark Brown 	}
1474b93cef55SMark Brown 	switch (ret) {
1475b93cef55SMark Brown 	case 0x6204:
1476b93cef55SMark Brown 	case 0x6246:
1477b93cef55SMark Brown 		break;
1478b93cef55SMark Brown 	default:
1479d2bedfe7SMark Brown 		dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret);
1480d2bedfe7SMark Brown 		ret = -EINVAL;
1481130a7032SMark Brown 		goto err;
1482d2bedfe7SMark Brown 	}
1483d2bedfe7SMark Brown 
1484d2bedfe7SMark Brown 	ret = wm831x_reg_read(wm831x, WM831X_REVISION);
1485d2bedfe7SMark Brown 	if (ret < 0) {
1486d2bedfe7SMark Brown 		dev_err(wm831x->dev, "Failed to read revision: %d\n", ret);
1487130a7032SMark Brown 		goto err;
1488d2bedfe7SMark Brown 	}
1489d2bedfe7SMark Brown 	rev = (ret & WM831X_PARENT_REV_MASK) >> WM831X_PARENT_REV_SHIFT;
1490d2bedfe7SMark Brown 
1491d2bedfe7SMark Brown 	ret = wm831x_reg_read(wm831x, WM831X_RESET_ID);
1492d2bedfe7SMark Brown 	if (ret < 0) {
1493d2bedfe7SMark Brown 		dev_err(wm831x->dev, "Failed to read device ID: %d\n", ret);
1494130a7032SMark Brown 		goto err;
1495d2bedfe7SMark Brown 	}
1496d2bedfe7SMark Brown 
1497894362f5SMark Brown 	/* Some engineering samples do not have the ID set, rely on
1498894362f5SMark Brown 	 * the device being registered correctly.
1499d2bedfe7SMark Brown 	 */
1500894362f5SMark Brown 	if (ret == 0) {
1501894362f5SMark Brown 		dev_info(wm831x->dev, "Device is an engineering sample\n");
1502f6dd8449SCharles Keepax 		ret = wm831x->type;
1503d2bedfe7SMark Brown 	}
1504894362f5SMark Brown 
1505894362f5SMark Brown 	switch (ret) {
1506894362f5SMark Brown 	case WM8310:
1507894362f5SMark Brown 		parent = WM8310;
15086f2ecaaeSMark Brown 		wm831x->num_gpio = 16;
1509b03b4d7cSMark Brown 		wm831x->charger_irq_wake = 1;
1510f92e8f81SMark Brown 		if (rev > 0) {
1511f92e8f81SMark Brown 			wm831x->has_gpio_ena = 1;
1512f92e8f81SMark Brown 			wm831x->has_cs_sts = 1;
1513f92e8f81SMark Brown 		}
1514f92e8f81SMark Brown 
1515894362f5SMark Brown 		dev_info(wm831x->dev, "WM8310 revision %c\n", 'A' + rev);
1516894362f5SMark Brown 		break;
1517894362f5SMark Brown 
1518894362f5SMark Brown 	case WM8311:
1519894362f5SMark Brown 		parent = WM8311;
15206f2ecaaeSMark Brown 		wm831x->num_gpio = 16;
1521b03b4d7cSMark Brown 		wm831x->charger_irq_wake = 1;
1522f92e8f81SMark Brown 		if (rev > 0) {
1523f92e8f81SMark Brown 			wm831x->has_gpio_ena = 1;
1524f92e8f81SMark Brown 			wm831x->has_cs_sts = 1;
1525f92e8f81SMark Brown 		}
1526f92e8f81SMark Brown 
1527894362f5SMark Brown 		dev_info(wm831x->dev, "WM8311 revision %c\n", 'A' + rev);
1528894362f5SMark Brown 		break;
1529894362f5SMark Brown 
1530894362f5SMark Brown 	case WM8312:
1531894362f5SMark Brown 		parent = WM8312;
15326f2ecaaeSMark Brown 		wm831x->num_gpio = 16;
1533b03b4d7cSMark Brown 		wm831x->charger_irq_wake = 1;
1534f92e8f81SMark Brown 		if (rev > 0) {
1535f92e8f81SMark Brown 			wm831x->has_gpio_ena = 1;
1536f92e8f81SMark Brown 			wm831x->has_cs_sts = 1;
1537f92e8f81SMark Brown 		}
1538f92e8f81SMark Brown 
1539894362f5SMark Brown 		dev_info(wm831x->dev, "WM8312 revision %c\n", 'A' + rev);
1540d2bedfe7SMark Brown 		break;
1541d2bedfe7SMark Brown 
1542d4e0a89eSMark Brown 	case WM8320:
1543d4e0a89eSMark Brown 		parent = WM8320;
1544d4e0a89eSMark Brown 		wm831x->num_gpio = 12;
1545d4e0a89eSMark Brown 		dev_info(wm831x->dev, "WM8320 revision %c\n", 'A' + rev);
1546d4e0a89eSMark Brown 		break;
1547d4e0a89eSMark Brown 
154888913521SMark Brown 	case WM8321:
154988913521SMark Brown 		parent = WM8321;
155088913521SMark Brown 		wm831x->num_gpio = 12;
155188913521SMark Brown 		dev_info(wm831x->dev, "WM8321 revision %c\n", 'A' + rev);
155288913521SMark Brown 		break;
155388913521SMark Brown 
15540b315884SMark Brown 	case WM8325:
15550b315884SMark Brown 		parent = WM8325;
15560b315884SMark Brown 		wm831x->num_gpio = 12;
15570b315884SMark Brown 		dev_info(wm831x->dev, "WM8325 revision %c\n", 'A' + rev);
15580b315884SMark Brown 		break;
15590b315884SMark Brown 
1560412dc11dSMark Brown 	case WM8326:
1561412dc11dSMark Brown 		parent = WM8326;
1562412dc11dSMark Brown 		wm831x->num_gpio = 12;
1563412dc11dSMark Brown 		dev_info(wm831x->dev, "WM8326 revision %c\n", 'A' + rev);
1564412dc11dSMark Brown 		break;
1565412dc11dSMark Brown 
1566d2bedfe7SMark Brown 	default:
1567d2bedfe7SMark Brown 		dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret);
1568d2bedfe7SMark Brown 		ret = -EINVAL;
1569130a7032SMark Brown 		goto err;
1570d2bedfe7SMark Brown 	}
1571d2bedfe7SMark Brown 
1572d2bedfe7SMark Brown 	/* This will need revisiting in future but is OK for all
1573d2bedfe7SMark Brown 	 * current parts.
1574d2bedfe7SMark Brown 	 */
1575f6dd8449SCharles Keepax 	if (parent != wm831x->type)
1576f6dd8449SCharles Keepax 		dev_warn(wm831x->dev, "Device was registered as a WM%x\n",
1577f6dd8449SCharles Keepax 			 wm831x->type);
1578d2bedfe7SMark Brown 
1579d2bedfe7SMark Brown 	/* Bootstrap the user key */
1580d2bedfe7SMark Brown 	ret = wm831x_reg_read(wm831x, WM831X_SECURITY_KEY);
1581d2bedfe7SMark Brown 	if (ret < 0) {
1582d2bedfe7SMark Brown 		dev_err(wm831x->dev, "Failed to read security key: %d\n", ret);
1583130a7032SMark Brown 		goto err;
1584d2bedfe7SMark Brown 	}
1585d2bedfe7SMark Brown 	if (ret != 0) {
1586d2bedfe7SMark Brown 		dev_warn(wm831x->dev, "Security key had non-zero value %x\n",
1587d2bedfe7SMark Brown 			 ret);
1588d2bedfe7SMark Brown 		wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0);
1589d2bedfe7SMark Brown 	}
1590d2bedfe7SMark Brown 	wm831x->locked = 1;
1591d2bedfe7SMark Brown 
1592dcb0574bSCharles Keepax 	if (pdata->pre_init) {
1593d2bedfe7SMark Brown 		ret = pdata->pre_init(wm831x);
1594d2bedfe7SMark Brown 		if (ret != 0) {
1595d2bedfe7SMark Brown 			dev_err(wm831x->dev, "pre_init() failed: %d\n", ret);
1596130a7032SMark Brown 			goto err;
1597d2bedfe7SMark Brown 		}
1598d2bedfe7SMark Brown 	}
1599d2bedfe7SMark Brown 
16000b14c22eSMark Brown 	for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
16010b14c22eSMark Brown 		if (!pdata->gpio_defaults[i])
16020b14c22eSMark Brown 			continue;
16030b14c22eSMark Brown 
16040b14c22eSMark Brown 		wm831x_reg_write(wm831x,
16050b14c22eSMark Brown 				 WM831X_GPIO1_CONTROL + i,
16060b14c22eSMark Brown 				 pdata->gpio_defaults[i] & 0xffff);
16070b14c22eSMark Brown 	}
16080b14c22eSMark Brown 
1609eb503dc1SMark Brown 	/* Multiply by 10 as we have many subdevices of the same type */
1610dcb0574bSCharles Keepax 	if (pdata->wm831x_num)
1611eb503dc1SMark Brown 		wm831x_num = pdata->wm831x_num * 10;
1612eb503dc1SMark Brown 	else
1613eb503dc1SMark Brown 		wm831x_num = -1;
1614eb503dc1SMark Brown 
16157d4d0a3eSMark Brown 	ret = wm831x_irq_init(wm831x, irq);
16167d4d0a3eSMark Brown 	if (ret != 0)
1617130a7032SMark Brown 		goto err;
16187d4d0a3eSMark Brown 
1619e69b6de1SMark Brown 	wm831x_auxadc_init(wm831x);
1620473fe736SMark Brown 
1621d2bedfe7SMark Brown 	/* The core device is up, instantiate the subdevices. */
1622d2bedfe7SMark Brown 	switch (parent) {
1623d2bedfe7SMark Brown 	case WM8310:
1624eb503dc1SMark Brown 		ret = mfd_add_devices(wm831x->dev, wm831x_num,
1625d2bedfe7SMark Brown 				      wm8310_devs, ARRAY_SIZE(wm8310_devs),
162655692af5SMark Brown 				      NULL, 0, NULL);
1627d2bedfe7SMark Brown 		break;
1628d2bedfe7SMark Brown 
1629d2bedfe7SMark Brown 	case WM8311:
1630eb503dc1SMark Brown 		ret = mfd_add_devices(wm831x->dev, wm831x_num,
1631d2bedfe7SMark Brown 				      wm8311_devs, ARRAY_SIZE(wm8311_devs),
163255692af5SMark Brown 				      NULL, 0, NULL);
1633dcb0574bSCharles Keepax 		if (!pdata->disable_touch)
1634266a5e02SMark Brown 			mfd_add_devices(wm831x->dev, wm831x_num,
1635266a5e02SMark Brown 					touch_devs, ARRAY_SIZE(touch_devs),
163655692af5SMark Brown 					NULL, 0, NULL);
1637d2bedfe7SMark Brown 		break;
1638d2bedfe7SMark Brown 
1639d2bedfe7SMark Brown 	case WM8312:
1640eb503dc1SMark Brown 		ret = mfd_add_devices(wm831x->dev, wm831x_num,
1641d2bedfe7SMark Brown 				      wm8312_devs, ARRAY_SIZE(wm8312_devs),
164255692af5SMark Brown 				      NULL, 0, NULL);
1643dcb0574bSCharles Keepax 		if (!pdata->disable_touch)
1644266a5e02SMark Brown 			mfd_add_devices(wm831x->dev, wm831x_num,
1645266a5e02SMark Brown 					touch_devs, ARRAY_SIZE(touch_devs),
164655692af5SMark Brown 					NULL, 0, NULL);
1647d2bedfe7SMark Brown 		break;
1648d2bedfe7SMark Brown 
1649d4e0a89eSMark Brown 	case WM8320:
165088913521SMark Brown 	case WM8321:
16510b315884SMark Brown 	case WM8325:
1652412dc11dSMark Brown 	case WM8326:
1653eb503dc1SMark Brown 		ret = mfd_add_devices(wm831x->dev, wm831x_num,
16540b315884SMark Brown 				      wm8320_devs, ARRAY_SIZE(wm8320_devs),
165555692af5SMark Brown 				      NULL, 0, NULL);
16560b315884SMark Brown 		break;
16570b315884SMark Brown 
1658d2bedfe7SMark Brown 	default:
1659d2bedfe7SMark Brown 		/* If this happens the bus probe function is buggy */
1660d2bedfe7SMark Brown 		BUG();
1661d2bedfe7SMark Brown 	}
1662d2bedfe7SMark Brown 
1663d2bedfe7SMark Brown 	if (ret != 0) {
1664d2bedfe7SMark Brown 		dev_err(wm831x->dev, "Failed to add children\n");
16657d4d0a3eSMark Brown 		goto err_irq;
1666d2bedfe7SMark Brown 	}
1667d2bedfe7SMark Brown 
1668b9d03d99SMark Brown 	/* The RTC can only be used if the 32.768kHz crystal is
1669b9d03d99SMark Brown 	 * enabled; this can't be controlled by software at runtime.
1670b9d03d99SMark Brown 	 */
1671b9d03d99SMark Brown 	ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_2);
1672b9d03d99SMark Brown 	if (ret < 0) {
1673b9d03d99SMark Brown 		dev_err(wm831x->dev, "Failed to read clock status: %d\n", ret);
1674b9d03d99SMark Brown 		goto err_irq;
1675b9d03d99SMark Brown 	}
1676b9d03d99SMark Brown 
1677b9d03d99SMark Brown 	if (ret & WM831X_XTAL_ENA) {
1678b9d03d99SMark Brown 		ret = mfd_add_devices(wm831x->dev, wm831x_num,
1679b9d03d99SMark Brown 				      rtc_devs, ARRAY_SIZE(rtc_devs),
168055692af5SMark Brown 				      NULL, 0, NULL);
1681b9d03d99SMark Brown 		if (ret != 0) {
1682b9d03d99SMark Brown 			dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret);
1683b9d03d99SMark Brown 			goto err_irq;
1684b9d03d99SMark Brown 		}
1685b9d03d99SMark Brown 	} else {
1686b9d03d99SMark Brown 		dev_info(wm831x->dev, "32.768kHz clock disabled, no RTC\n");
1687b9d03d99SMark Brown 	}
1688b9d03d99SMark Brown 
1689dcb0574bSCharles Keepax 	if (pdata->backlight) {
169063aed85eSMark Brown 		/* Treat errors as non-critical */
1691eb503dc1SMark Brown 		ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs,
16925fb4d38bSMark Brown 				      ARRAY_SIZE(backlight_devs), NULL,
169355692af5SMark Brown 				      0, NULL);
169463aed85eSMark Brown 		if (ret < 0)
169563aed85eSMark Brown 			dev_err(wm831x->dev, "Failed to add backlight: %d\n",
169663aed85eSMark Brown 				ret);
169763aed85eSMark Brown 	}
169863aed85eSMark Brown 
16996704e517SMark Brown 	wm831x_otp_init(wm831x);
17006704e517SMark Brown 
1701dcb0574bSCharles Keepax 	if (pdata->post_init) {
1702d2bedfe7SMark Brown 		ret = pdata->post_init(wm831x);
1703d2bedfe7SMark Brown 		if (ret != 0) {
1704d2bedfe7SMark Brown 			dev_err(wm831x->dev, "post_init() failed: %d\n", ret);
17057d4d0a3eSMark Brown 			goto err_irq;
1706d2bedfe7SMark Brown 		}
1707d2bedfe7SMark Brown 	}
1708d2bedfe7SMark Brown 
1709d2bedfe7SMark Brown 	return 0;
1710d2bedfe7SMark Brown 
17117d4d0a3eSMark Brown err_irq:
17127d4d0a3eSMark Brown 	wm831x_irq_exit(wm831x);
1713130a7032SMark Brown err:
1714d2bedfe7SMark Brown 	mfd_remove_devices(wm831x->dev);
1715d2bedfe7SMark Brown 	return ret;
1716d2bedfe7SMark Brown }
1717d2bedfe7SMark Brown 
wm831x_device_suspend(struct wm831x * wm831x)1718e5b48684SMark Brown int wm831x_device_suspend(struct wm831x *wm831x)
1719b03b4d7cSMark Brown {
1720b03b4d7cSMark Brown 	int reg, mask;
1721b03b4d7cSMark Brown 
1722b03b4d7cSMark Brown 	/* If the charger IRQs are a wake source then make sure we ack
1723b03b4d7cSMark Brown 	 * them even if they're not actively being used (eg, no power
1724b03b4d7cSMark Brown 	 * driver or no IRQ line wired up) then acknowledge the
1725b03b4d7cSMark Brown 	 * interrupts otherwise suspend won't last very long.
1726b03b4d7cSMark Brown 	 */
1727b03b4d7cSMark Brown 	if (wm831x->charger_irq_wake) {
1728b03b4d7cSMark Brown 		reg = wm831x_reg_read(wm831x, WM831X_INTERRUPT_STATUS_2_MASK);
1729b03b4d7cSMark Brown 
1730b03b4d7cSMark Brown 		mask = WM831X_CHG_BATT_HOT_EINT |
1731b03b4d7cSMark Brown 			WM831X_CHG_BATT_COLD_EINT |
1732b03b4d7cSMark Brown 			WM831X_CHG_BATT_FAIL_EINT |
1733b03b4d7cSMark Brown 			WM831X_CHG_OV_EINT | WM831X_CHG_END_EINT |
1734b03b4d7cSMark Brown 			WM831X_CHG_TO_EINT | WM831X_CHG_MODE_EINT |
1735b03b4d7cSMark Brown 			WM831X_CHG_START_EINT;
1736b03b4d7cSMark Brown 
1737b03b4d7cSMark Brown 		/* If any of the interrupts are masked read the statuses */
1738b03b4d7cSMark Brown 		if (reg & mask)
1739b03b4d7cSMark Brown 			reg = wm831x_reg_read(wm831x,
1740b03b4d7cSMark Brown 					      WM831X_INTERRUPT_STATUS_2);
1741b03b4d7cSMark Brown 
1742b03b4d7cSMark Brown 		if (reg & mask) {
1743b03b4d7cSMark Brown 			dev_info(wm831x->dev,
1744b03b4d7cSMark Brown 				 "Acknowledging masked charger IRQs: %x\n",
1745b03b4d7cSMark Brown 				 reg & mask);
1746b03b4d7cSMark Brown 			wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_2,
1747b03b4d7cSMark Brown 					 reg & mask);
1748b03b4d7cSMark Brown 		}
1749b03b4d7cSMark Brown 	}
1750b03b4d7cSMark Brown 
1751b03b4d7cSMark Brown 	return 0;
1752b03b4d7cSMark Brown }
1753b03b4d7cSMark Brown 
wm831x_device_shutdown(struct wm831x * wm831x)1754523d9cfbSMark Brown void wm831x_device_shutdown(struct wm831x *wm831x)
1755523d9cfbSMark Brown {
1756523d9cfbSMark Brown 	if (wm831x->soft_shutdown) {
1757523d9cfbSMark Brown 		dev_info(wm831x->dev, "Initiating shutdown...\n");
1758523d9cfbSMark Brown 		wm831x_set_bits(wm831x, WM831X_POWER_STATE, WM831X_CHIP_ON, 0);
1759523d9cfbSMark Brown 	}
1760523d9cfbSMark Brown }
1761523d9cfbSMark Brown EXPORT_SYMBOL_GPL(wm831x_device_shutdown);
1762