xref: /openbmc/linux/drivers/mfd/wm831x-core.c (revision f977284a)
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>
18f6dd8449SCharles Keepax #include <linux/of.h>
19f6dd8449SCharles Keepax #include <linux/of_device.h>
20d2bedfe7SMark Brown 
21d2bedfe7SMark Brown #include <linux/mfd/wm831x/core.h>
22d2bedfe7SMark Brown #include <linux/mfd/wm831x/pdata.h>
237d4d0a3eSMark Brown #include <linux/mfd/wm831x/irq.h>
247e9f9fd4SMark Brown #include <linux/mfd/wm831x/auxadc.h>
256704e517SMark Brown #include <linux/mfd/wm831x/otp.h>
26523d9cfbSMark Brown #include <linux/mfd/wm831x/pmu.h>
27698659d5SMark Brown #include <linux/mfd/wm831x/regulator.h>
28698659d5SMark Brown 
29698659d5SMark Brown /* Current settings - values are 2*2^(reg_val/4) microamps.  These are
30698659d5SMark Brown  * exported since they are used by multiple drivers.
31698659d5SMark Brown  */
32d48acfd0SAxel Lin const unsigned int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = {
33698659d5SMark Brown 	2,
34698659d5SMark Brown 	2,
35698659d5SMark Brown 	3,
36698659d5SMark Brown 	3,
37698659d5SMark Brown 	4,
38698659d5SMark Brown 	5,
39698659d5SMark Brown 	6,
40698659d5SMark Brown 	7,
41698659d5SMark Brown 	8,
42698659d5SMark Brown 	10,
43698659d5SMark Brown 	11,
44698659d5SMark Brown 	13,
45698659d5SMark Brown 	16,
46698659d5SMark Brown 	19,
47698659d5SMark Brown 	23,
48698659d5SMark Brown 	27,
49698659d5SMark Brown 	32,
50698659d5SMark Brown 	38,
51698659d5SMark Brown 	45,
52698659d5SMark Brown 	54,
53698659d5SMark Brown 	64,
54698659d5SMark Brown 	76,
55698659d5SMark Brown 	91,
56698659d5SMark Brown 	108,
57698659d5SMark Brown 	128,
58698659d5SMark Brown 	152,
59698659d5SMark Brown 	181,
60698659d5SMark Brown 	215,
61698659d5SMark Brown 	256,
62698659d5SMark Brown 	304,
63698659d5SMark Brown 	362,
64698659d5SMark Brown 	431,
65698659d5SMark Brown 	512,
66698659d5SMark Brown 	609,
67698659d5SMark Brown 	724,
68698659d5SMark Brown 	861,
69698659d5SMark Brown 	1024,
70698659d5SMark Brown 	1218,
71698659d5SMark Brown 	1448,
72698659d5SMark Brown 	1722,
73698659d5SMark Brown 	2048,
74698659d5SMark Brown 	2435,
75698659d5SMark Brown 	2896,
76698659d5SMark Brown 	3444,
77698659d5SMark Brown 	4096,
78698659d5SMark Brown 	4871,
79698659d5SMark Brown 	5793,
80698659d5SMark Brown 	6889,
81698659d5SMark Brown 	8192,
82698659d5SMark Brown 	9742,
83698659d5SMark Brown 	11585,
84698659d5SMark Brown 	13777,
85698659d5SMark Brown 	16384,
86698659d5SMark Brown 	19484,
87698659d5SMark Brown 	23170,
88698659d5SMark Brown 	27554,
89698659d5SMark Brown };
90698659d5SMark Brown EXPORT_SYMBOL_GPL(wm831x_isinkv_values);
91d2bedfe7SMark Brown 
92d2bedfe7SMark Brown static int wm831x_reg_locked(struct wm831x *wm831x, unsigned short reg)
93d2bedfe7SMark Brown {
94d2bedfe7SMark Brown 	if (!wm831x->locked)
95d2bedfe7SMark Brown 		return 0;
96d2bedfe7SMark Brown 
97d2bedfe7SMark Brown 	switch (reg) {
98d2bedfe7SMark Brown 	case WM831X_WATCHDOG:
99d2bedfe7SMark Brown 	case WM831X_DC4_CONTROL:
100d2bedfe7SMark Brown 	case WM831X_ON_PIN_CONTROL:
101d2bedfe7SMark Brown 	case WM831X_BACKUP_CHARGER_CONTROL:
102d2bedfe7SMark Brown 	case WM831X_CHARGER_CONTROL_1:
103d2bedfe7SMark Brown 	case WM831X_CHARGER_CONTROL_2:
104d2bedfe7SMark Brown 		return 1;
105d2bedfe7SMark Brown 
106d2bedfe7SMark Brown 	default:
107d2bedfe7SMark Brown 		return 0;
108d2bedfe7SMark Brown 	}
109d2bedfe7SMark Brown }
110d2bedfe7SMark Brown 
111d2bedfe7SMark Brown /**
112d2bedfe7SMark Brown  * wm831x_reg_unlock: Unlock user keyed registers
113d2bedfe7SMark Brown  *
114d2bedfe7SMark Brown  * The WM831x has a user key preventing writes to particularly
115d2bedfe7SMark Brown  * critical registers.  This function locks those registers,
116d2bedfe7SMark Brown  * allowing writes to them.
11738ea9f47SLee Jones  *
11838ea9f47SLee Jones  * @wm831x: pointer to local driver data structure
119d2bedfe7SMark Brown  */
120d2bedfe7SMark Brown void wm831x_reg_lock(struct wm831x *wm831x)
121d2bedfe7SMark Brown {
122d2bedfe7SMark Brown 	int ret;
123d2bedfe7SMark Brown 
124d2bedfe7SMark Brown 	ret = wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0);
125d2bedfe7SMark Brown 	if (ret == 0) {
126d2bedfe7SMark Brown 		dev_vdbg(wm831x->dev, "Registers locked\n");
127d2bedfe7SMark Brown 
128d2bedfe7SMark Brown 		mutex_lock(&wm831x->io_lock);
129d2bedfe7SMark Brown 		WARN_ON(wm831x->locked);
130d2bedfe7SMark Brown 		wm831x->locked = 1;
131d2bedfe7SMark Brown 		mutex_unlock(&wm831x->io_lock);
132d2bedfe7SMark Brown 	} else {
133d2bedfe7SMark Brown 		dev_err(wm831x->dev, "Failed to lock registers: %d\n", ret);
134d2bedfe7SMark Brown 	}
135d2bedfe7SMark Brown 
136d2bedfe7SMark Brown }
137d2bedfe7SMark Brown EXPORT_SYMBOL_GPL(wm831x_reg_lock);
138d2bedfe7SMark Brown 
139d2bedfe7SMark Brown /**
140d2bedfe7SMark Brown  * wm831x_reg_unlock: Unlock user keyed registers
141d2bedfe7SMark Brown  *
142d2bedfe7SMark Brown  * The WM831x has a user key preventing writes to particularly
143d2bedfe7SMark Brown  * critical registers.  This function locks those registers,
144d2bedfe7SMark Brown  * preventing spurious writes.
14538ea9f47SLee Jones  *
14638ea9f47SLee Jones  * @wm831x: pointer to local driver data structure
147d2bedfe7SMark Brown  */
148d2bedfe7SMark Brown int wm831x_reg_unlock(struct wm831x *wm831x)
149d2bedfe7SMark Brown {
150d2bedfe7SMark Brown 	int ret;
151d2bedfe7SMark Brown 
152d2bedfe7SMark Brown 	/* 0x9716 is the value required to unlock the registers */
153d2bedfe7SMark Brown 	ret = wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0x9716);
154d2bedfe7SMark Brown 	if (ret == 0) {
155d2bedfe7SMark Brown 		dev_vdbg(wm831x->dev, "Registers unlocked\n");
156d2bedfe7SMark Brown 
157d2bedfe7SMark Brown 		mutex_lock(&wm831x->io_lock);
158d2bedfe7SMark Brown 		WARN_ON(!wm831x->locked);
159d2bedfe7SMark Brown 		wm831x->locked = 0;
160d2bedfe7SMark Brown 		mutex_unlock(&wm831x->io_lock);
161d2bedfe7SMark Brown 	}
162d2bedfe7SMark Brown 
163d2bedfe7SMark Brown 	return ret;
164d2bedfe7SMark Brown }
165d2bedfe7SMark Brown EXPORT_SYMBOL_GPL(wm831x_reg_unlock);
166d2bedfe7SMark Brown 
1672e47fff1SMark Brown static bool wm831x_reg_readable(struct device *dev, unsigned int reg)
1682e47fff1SMark Brown {
1692e47fff1SMark Brown 	switch (reg) {
1702e47fff1SMark Brown 	case WM831X_RESET_ID:
1712e47fff1SMark Brown 	case WM831X_REVISION:
1722e47fff1SMark Brown 	case WM831X_PARENT_ID:
1732e47fff1SMark Brown 	case WM831X_SYSVDD_CONTROL:
1742e47fff1SMark Brown 	case WM831X_THERMAL_MONITORING:
1752e47fff1SMark Brown 	case WM831X_POWER_STATE:
1762e47fff1SMark Brown 	case WM831X_WATCHDOG:
1772e47fff1SMark Brown 	case WM831X_ON_PIN_CONTROL:
1782e47fff1SMark Brown 	case WM831X_RESET_CONTROL:
1792e47fff1SMark Brown 	case WM831X_CONTROL_INTERFACE:
1802e47fff1SMark Brown 	case WM831X_SECURITY_KEY:
1812e47fff1SMark Brown 	case WM831X_SOFTWARE_SCRATCH:
1822e47fff1SMark Brown 	case WM831X_OTP_CONTROL:
1832e47fff1SMark Brown 	case WM831X_GPIO_LEVEL:
1842e47fff1SMark Brown 	case WM831X_SYSTEM_STATUS:
1852e47fff1SMark Brown 	case WM831X_ON_SOURCE:
1862e47fff1SMark Brown 	case WM831X_OFF_SOURCE:
1872e47fff1SMark Brown 	case WM831X_SYSTEM_INTERRUPTS:
1882e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_1:
1892e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_2:
1902e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_3:
1912e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_4:
1922e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_5:
1932e47fff1SMark Brown 	case WM831X_IRQ_CONFIG:
1942e47fff1SMark Brown 	case WM831X_SYSTEM_INTERRUPTS_MASK:
1952e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_1_MASK:
1962e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_2_MASK:
1972e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_3_MASK:
1982e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_4_MASK:
1992e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_5_MASK:
2002e47fff1SMark Brown 	case WM831X_RTC_WRITE_COUNTER:
2012e47fff1SMark Brown 	case WM831X_RTC_TIME_1:
2022e47fff1SMark Brown 	case WM831X_RTC_TIME_2:
2032e47fff1SMark Brown 	case WM831X_RTC_ALARM_1:
2042e47fff1SMark Brown 	case WM831X_RTC_ALARM_2:
2052e47fff1SMark Brown 	case WM831X_RTC_CONTROL:
2062e47fff1SMark Brown 	case WM831X_RTC_TRIM:
2072e47fff1SMark Brown 	case WM831X_TOUCH_CONTROL_1:
2082e47fff1SMark Brown 	case WM831X_TOUCH_CONTROL_2:
2092e47fff1SMark Brown 	case WM831X_TOUCH_DATA_X:
2102e47fff1SMark Brown 	case WM831X_TOUCH_DATA_Y:
2112e47fff1SMark Brown 	case WM831X_TOUCH_DATA_Z:
2122e47fff1SMark Brown 	case WM831X_AUXADC_DATA:
2132e47fff1SMark Brown 	case WM831X_AUXADC_CONTROL:
2142e47fff1SMark Brown 	case WM831X_AUXADC_SOURCE:
2152e47fff1SMark Brown 	case WM831X_COMPARATOR_CONTROL:
2162e47fff1SMark Brown 	case WM831X_COMPARATOR_1:
2172e47fff1SMark Brown 	case WM831X_COMPARATOR_2:
2182e47fff1SMark Brown 	case WM831X_COMPARATOR_3:
2192e47fff1SMark Brown 	case WM831X_COMPARATOR_4:
2202e47fff1SMark Brown 	case WM831X_GPIO1_CONTROL:
2212e47fff1SMark Brown 	case WM831X_GPIO2_CONTROL:
2222e47fff1SMark Brown 	case WM831X_GPIO3_CONTROL:
2232e47fff1SMark Brown 	case WM831X_GPIO4_CONTROL:
2242e47fff1SMark Brown 	case WM831X_GPIO5_CONTROL:
2252e47fff1SMark Brown 	case WM831X_GPIO6_CONTROL:
2262e47fff1SMark Brown 	case WM831X_GPIO7_CONTROL:
2272e47fff1SMark Brown 	case WM831X_GPIO8_CONTROL:
2282e47fff1SMark Brown 	case WM831X_GPIO9_CONTROL:
2292e47fff1SMark Brown 	case WM831X_GPIO10_CONTROL:
2302e47fff1SMark Brown 	case WM831X_GPIO11_CONTROL:
2312e47fff1SMark Brown 	case WM831X_GPIO12_CONTROL:
2322e47fff1SMark Brown 	case WM831X_GPIO13_CONTROL:
2332e47fff1SMark Brown 	case WM831X_GPIO14_CONTROL:
2342e47fff1SMark Brown 	case WM831X_GPIO15_CONTROL:
2352e47fff1SMark Brown 	case WM831X_GPIO16_CONTROL:
2362e47fff1SMark Brown 	case WM831X_CHARGER_CONTROL_1:
2372e47fff1SMark Brown 	case WM831X_CHARGER_CONTROL_2:
2382e47fff1SMark Brown 	case WM831X_CHARGER_STATUS:
2392e47fff1SMark Brown 	case WM831X_BACKUP_CHARGER_CONTROL:
2402e47fff1SMark Brown 	case WM831X_STATUS_LED_1:
2412e47fff1SMark Brown 	case WM831X_STATUS_LED_2:
2422e47fff1SMark Brown 	case WM831X_CURRENT_SINK_1:
2432e47fff1SMark Brown 	case WM831X_CURRENT_SINK_2:
2442e47fff1SMark Brown 	case WM831X_DCDC_ENABLE:
2452e47fff1SMark Brown 	case WM831X_LDO_ENABLE:
2462e47fff1SMark Brown 	case WM831X_DCDC_STATUS:
2472e47fff1SMark Brown 	case WM831X_LDO_STATUS:
2482e47fff1SMark Brown 	case WM831X_DCDC_UV_STATUS:
2492e47fff1SMark Brown 	case WM831X_LDO_UV_STATUS:
2502e47fff1SMark Brown 	case WM831X_DC1_CONTROL_1:
2512e47fff1SMark Brown 	case WM831X_DC1_CONTROL_2:
2522e47fff1SMark Brown 	case WM831X_DC1_ON_CONFIG:
2532e47fff1SMark Brown 	case WM831X_DC1_SLEEP_CONTROL:
2542e47fff1SMark Brown 	case WM831X_DC1_DVS_CONTROL:
2552e47fff1SMark Brown 	case WM831X_DC2_CONTROL_1:
2562e47fff1SMark Brown 	case WM831X_DC2_CONTROL_2:
2572e47fff1SMark Brown 	case WM831X_DC2_ON_CONFIG:
2582e47fff1SMark Brown 	case WM831X_DC2_SLEEP_CONTROL:
2592e47fff1SMark Brown 	case WM831X_DC2_DVS_CONTROL:
2602e47fff1SMark Brown 	case WM831X_DC3_CONTROL_1:
2612e47fff1SMark Brown 	case WM831X_DC3_CONTROL_2:
2622e47fff1SMark Brown 	case WM831X_DC3_ON_CONFIG:
2632e47fff1SMark Brown 	case WM831X_DC3_SLEEP_CONTROL:
2642e47fff1SMark Brown 	case WM831X_DC4_CONTROL:
2652e47fff1SMark Brown 	case WM831X_DC4_SLEEP_CONTROL:
2662e47fff1SMark Brown 	case WM831X_EPE1_CONTROL:
2672e47fff1SMark Brown 	case WM831X_EPE2_CONTROL:
2682e47fff1SMark Brown 	case WM831X_LDO1_CONTROL:
2692e47fff1SMark Brown 	case WM831X_LDO1_ON_CONTROL:
2702e47fff1SMark Brown 	case WM831X_LDO1_SLEEP_CONTROL:
2712e47fff1SMark Brown 	case WM831X_LDO2_CONTROL:
2722e47fff1SMark Brown 	case WM831X_LDO2_ON_CONTROL:
2732e47fff1SMark Brown 	case WM831X_LDO2_SLEEP_CONTROL:
2742e47fff1SMark Brown 	case WM831X_LDO3_CONTROL:
2752e47fff1SMark Brown 	case WM831X_LDO3_ON_CONTROL:
2762e47fff1SMark Brown 	case WM831X_LDO3_SLEEP_CONTROL:
2772e47fff1SMark Brown 	case WM831X_LDO4_CONTROL:
2782e47fff1SMark Brown 	case WM831X_LDO4_ON_CONTROL:
2792e47fff1SMark Brown 	case WM831X_LDO4_SLEEP_CONTROL:
2802e47fff1SMark Brown 	case WM831X_LDO5_CONTROL:
2812e47fff1SMark Brown 	case WM831X_LDO5_ON_CONTROL:
2822e47fff1SMark Brown 	case WM831X_LDO5_SLEEP_CONTROL:
2832e47fff1SMark Brown 	case WM831X_LDO6_CONTROL:
2842e47fff1SMark Brown 	case WM831X_LDO6_ON_CONTROL:
2852e47fff1SMark Brown 	case WM831X_LDO6_SLEEP_CONTROL:
2862e47fff1SMark Brown 	case WM831X_LDO7_CONTROL:
2872e47fff1SMark Brown 	case WM831X_LDO7_ON_CONTROL:
2882e47fff1SMark Brown 	case WM831X_LDO7_SLEEP_CONTROL:
2892e47fff1SMark Brown 	case WM831X_LDO8_CONTROL:
2902e47fff1SMark Brown 	case WM831X_LDO8_ON_CONTROL:
2912e47fff1SMark Brown 	case WM831X_LDO8_SLEEP_CONTROL:
2922e47fff1SMark Brown 	case WM831X_LDO9_CONTROL:
2932e47fff1SMark Brown 	case WM831X_LDO9_ON_CONTROL:
2942e47fff1SMark Brown 	case WM831X_LDO9_SLEEP_CONTROL:
2952e47fff1SMark Brown 	case WM831X_LDO10_CONTROL:
2962e47fff1SMark Brown 	case WM831X_LDO10_ON_CONTROL:
2972e47fff1SMark Brown 	case WM831X_LDO10_SLEEP_CONTROL:
2982e47fff1SMark Brown 	case WM831X_LDO11_ON_CONTROL:
2992e47fff1SMark Brown 	case WM831X_LDO11_SLEEP_CONTROL:
3002e47fff1SMark Brown 	case WM831X_POWER_GOOD_SOURCE_1:
3012e47fff1SMark Brown 	case WM831X_POWER_GOOD_SOURCE_2:
3022e47fff1SMark Brown 	case WM831X_CLOCK_CONTROL_1:
3032e47fff1SMark Brown 	case WM831X_CLOCK_CONTROL_2:
3042e47fff1SMark Brown 	case WM831X_FLL_CONTROL_1:
3052e47fff1SMark Brown 	case WM831X_FLL_CONTROL_2:
3062e47fff1SMark Brown 	case WM831X_FLL_CONTROL_3:
3072e47fff1SMark Brown 	case WM831X_FLL_CONTROL_4:
3082e47fff1SMark Brown 	case WM831X_FLL_CONTROL_5:
3092e47fff1SMark Brown 	case WM831X_UNIQUE_ID_1:
3102e47fff1SMark Brown 	case WM831X_UNIQUE_ID_2:
3112e47fff1SMark Brown 	case WM831X_UNIQUE_ID_3:
3122e47fff1SMark Brown 	case WM831X_UNIQUE_ID_4:
3132e47fff1SMark Brown 	case WM831X_UNIQUE_ID_5:
3142e47fff1SMark Brown 	case WM831X_UNIQUE_ID_6:
3152e47fff1SMark Brown 	case WM831X_UNIQUE_ID_7:
3162e47fff1SMark Brown 	case WM831X_UNIQUE_ID_8:
3172e47fff1SMark Brown 	case WM831X_FACTORY_OTP_ID:
3182e47fff1SMark Brown 	case WM831X_FACTORY_OTP_1:
3192e47fff1SMark Brown 	case WM831X_FACTORY_OTP_2:
3202e47fff1SMark Brown 	case WM831X_FACTORY_OTP_3:
3212e47fff1SMark Brown 	case WM831X_FACTORY_OTP_4:
3222e47fff1SMark Brown 	case WM831X_FACTORY_OTP_5:
3232e47fff1SMark Brown 	case WM831X_CUSTOMER_OTP_ID:
3242e47fff1SMark Brown 	case WM831X_DC1_OTP_CONTROL:
3252e47fff1SMark Brown 	case WM831X_DC2_OTP_CONTROL:
3262e47fff1SMark Brown 	case WM831X_DC3_OTP_CONTROL:
3272e47fff1SMark Brown 	case WM831X_LDO1_2_OTP_CONTROL:
3282e47fff1SMark Brown 	case WM831X_LDO3_4_OTP_CONTROL:
3292e47fff1SMark Brown 	case WM831X_LDO5_6_OTP_CONTROL:
3302e47fff1SMark Brown 	case WM831X_LDO7_8_OTP_CONTROL:
3312e47fff1SMark Brown 	case WM831X_LDO9_10_OTP_CONTROL:
3322e47fff1SMark Brown 	case WM831X_LDO11_EPE_CONTROL:
3332e47fff1SMark Brown 	case WM831X_GPIO1_OTP_CONTROL:
3342e47fff1SMark Brown 	case WM831X_GPIO2_OTP_CONTROL:
3352e47fff1SMark Brown 	case WM831X_GPIO3_OTP_CONTROL:
3362e47fff1SMark Brown 	case WM831X_GPIO4_OTP_CONTROL:
3372e47fff1SMark Brown 	case WM831X_GPIO5_OTP_CONTROL:
3382e47fff1SMark Brown 	case WM831X_GPIO6_OTP_CONTROL:
3392e47fff1SMark Brown 	case WM831X_DBE_CHECK_DATA:
3402e47fff1SMark Brown 		return true;
3412e47fff1SMark Brown 	default:
3422e47fff1SMark Brown 		return false;
3432e47fff1SMark Brown 	}
3442e47fff1SMark Brown }
3452e47fff1SMark Brown 
3462e47fff1SMark Brown static bool wm831x_reg_writeable(struct device *dev, unsigned int reg)
3472e47fff1SMark Brown {
3482e47fff1SMark Brown 	struct wm831x *wm831x = dev_get_drvdata(dev);
3492e47fff1SMark Brown 
3502e47fff1SMark Brown 	if (wm831x_reg_locked(wm831x, reg))
3512e47fff1SMark Brown 		return false;
3522e47fff1SMark Brown 
3532e47fff1SMark Brown 	switch (reg) {
3542e47fff1SMark Brown 	case WM831X_SYSVDD_CONTROL:
3552e47fff1SMark Brown 	case WM831X_THERMAL_MONITORING:
3562e47fff1SMark Brown 	case WM831X_POWER_STATE:
3572e47fff1SMark Brown 	case WM831X_WATCHDOG:
3582e47fff1SMark Brown 	case WM831X_ON_PIN_CONTROL:
3592e47fff1SMark Brown 	case WM831X_RESET_CONTROL:
3602e47fff1SMark Brown 	case WM831X_CONTROL_INTERFACE:
3612e47fff1SMark Brown 	case WM831X_SECURITY_KEY:
3622e47fff1SMark Brown 	case WM831X_SOFTWARE_SCRATCH:
3632e47fff1SMark Brown 	case WM831X_OTP_CONTROL:
3642e47fff1SMark Brown 	case WM831X_GPIO_LEVEL:
3652e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_1:
3662e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_2:
3672e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_3:
3682e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_4:
3692e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_5:
3702e47fff1SMark Brown 	case WM831X_IRQ_CONFIG:
3712e47fff1SMark Brown 	case WM831X_SYSTEM_INTERRUPTS_MASK:
3722e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_1_MASK:
3732e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_2_MASK:
3742e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_3_MASK:
3752e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_4_MASK:
3762e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_5_MASK:
3772e47fff1SMark Brown 	case WM831X_RTC_TIME_1:
3782e47fff1SMark Brown 	case WM831X_RTC_TIME_2:
3792e47fff1SMark Brown 	case WM831X_RTC_ALARM_1:
3802e47fff1SMark Brown 	case WM831X_RTC_ALARM_2:
3812e47fff1SMark Brown 	case WM831X_RTC_CONTROL:
3822e47fff1SMark Brown 	case WM831X_RTC_TRIM:
3832e47fff1SMark Brown 	case WM831X_TOUCH_CONTROL_1:
3842e47fff1SMark Brown 	case WM831X_TOUCH_CONTROL_2:
3852e47fff1SMark Brown 	case WM831X_AUXADC_CONTROL:
3862e47fff1SMark Brown 	case WM831X_AUXADC_SOURCE:
3872e47fff1SMark Brown 	case WM831X_COMPARATOR_CONTROL:
3882e47fff1SMark Brown 	case WM831X_COMPARATOR_1:
3892e47fff1SMark Brown 	case WM831X_COMPARATOR_2:
3902e47fff1SMark Brown 	case WM831X_COMPARATOR_3:
3912e47fff1SMark Brown 	case WM831X_COMPARATOR_4:
3922e47fff1SMark Brown 	case WM831X_GPIO1_CONTROL:
3932e47fff1SMark Brown 	case WM831X_GPIO2_CONTROL:
3942e47fff1SMark Brown 	case WM831X_GPIO3_CONTROL:
3952e47fff1SMark Brown 	case WM831X_GPIO4_CONTROL:
3962e47fff1SMark Brown 	case WM831X_GPIO5_CONTROL:
3972e47fff1SMark Brown 	case WM831X_GPIO6_CONTROL:
3982e47fff1SMark Brown 	case WM831X_GPIO7_CONTROL:
3992e47fff1SMark Brown 	case WM831X_GPIO8_CONTROL:
4002e47fff1SMark Brown 	case WM831X_GPIO9_CONTROL:
4012e47fff1SMark Brown 	case WM831X_GPIO10_CONTROL:
4022e47fff1SMark Brown 	case WM831X_GPIO11_CONTROL:
4032e47fff1SMark Brown 	case WM831X_GPIO12_CONTROL:
4042e47fff1SMark Brown 	case WM831X_GPIO13_CONTROL:
4052e47fff1SMark Brown 	case WM831X_GPIO14_CONTROL:
4062e47fff1SMark Brown 	case WM831X_GPIO15_CONTROL:
4072e47fff1SMark Brown 	case WM831X_GPIO16_CONTROL:
4082e47fff1SMark Brown 	case WM831X_CHARGER_CONTROL_1:
4092e47fff1SMark Brown 	case WM831X_CHARGER_CONTROL_2:
4102e47fff1SMark Brown 	case WM831X_CHARGER_STATUS:
4112e47fff1SMark Brown 	case WM831X_BACKUP_CHARGER_CONTROL:
4122e47fff1SMark Brown 	case WM831X_STATUS_LED_1:
4132e47fff1SMark Brown 	case WM831X_STATUS_LED_2:
4142e47fff1SMark Brown 	case WM831X_CURRENT_SINK_1:
4152e47fff1SMark Brown 	case WM831X_CURRENT_SINK_2:
4162e47fff1SMark Brown 	case WM831X_DCDC_ENABLE:
4172e47fff1SMark Brown 	case WM831X_LDO_ENABLE:
4182e47fff1SMark Brown 	case WM831X_DC1_CONTROL_1:
4192e47fff1SMark Brown 	case WM831X_DC1_CONTROL_2:
4202e47fff1SMark Brown 	case WM831X_DC1_ON_CONFIG:
4212e47fff1SMark Brown 	case WM831X_DC1_SLEEP_CONTROL:
4222e47fff1SMark Brown 	case WM831X_DC1_DVS_CONTROL:
4232e47fff1SMark Brown 	case WM831X_DC2_CONTROL_1:
4242e47fff1SMark Brown 	case WM831X_DC2_CONTROL_2:
4252e47fff1SMark Brown 	case WM831X_DC2_ON_CONFIG:
4262e47fff1SMark Brown 	case WM831X_DC2_SLEEP_CONTROL:
4272e47fff1SMark Brown 	case WM831X_DC2_DVS_CONTROL:
4282e47fff1SMark Brown 	case WM831X_DC3_CONTROL_1:
4292e47fff1SMark Brown 	case WM831X_DC3_CONTROL_2:
4302e47fff1SMark Brown 	case WM831X_DC3_ON_CONFIG:
4312e47fff1SMark Brown 	case WM831X_DC3_SLEEP_CONTROL:
4322e47fff1SMark Brown 	case WM831X_DC4_CONTROL:
4332e47fff1SMark Brown 	case WM831X_DC4_SLEEP_CONTROL:
4342e47fff1SMark Brown 	case WM831X_EPE1_CONTROL:
4352e47fff1SMark Brown 	case WM831X_EPE2_CONTROL:
4362e47fff1SMark Brown 	case WM831X_LDO1_CONTROL:
4372e47fff1SMark Brown 	case WM831X_LDO1_ON_CONTROL:
4382e47fff1SMark Brown 	case WM831X_LDO1_SLEEP_CONTROL:
4392e47fff1SMark Brown 	case WM831X_LDO2_CONTROL:
4402e47fff1SMark Brown 	case WM831X_LDO2_ON_CONTROL:
4412e47fff1SMark Brown 	case WM831X_LDO2_SLEEP_CONTROL:
4422e47fff1SMark Brown 	case WM831X_LDO3_CONTROL:
4432e47fff1SMark Brown 	case WM831X_LDO3_ON_CONTROL:
4442e47fff1SMark Brown 	case WM831X_LDO3_SLEEP_CONTROL:
4452e47fff1SMark Brown 	case WM831X_LDO4_CONTROL:
4462e47fff1SMark Brown 	case WM831X_LDO4_ON_CONTROL:
4472e47fff1SMark Brown 	case WM831X_LDO4_SLEEP_CONTROL:
4482e47fff1SMark Brown 	case WM831X_LDO5_CONTROL:
4492e47fff1SMark Brown 	case WM831X_LDO5_ON_CONTROL:
4502e47fff1SMark Brown 	case WM831X_LDO5_SLEEP_CONTROL:
4512e47fff1SMark Brown 	case WM831X_LDO6_CONTROL:
4522e47fff1SMark Brown 	case WM831X_LDO6_ON_CONTROL:
4532e47fff1SMark Brown 	case WM831X_LDO6_SLEEP_CONTROL:
4542e47fff1SMark Brown 	case WM831X_LDO7_CONTROL:
4552e47fff1SMark Brown 	case WM831X_LDO7_ON_CONTROL:
4562e47fff1SMark Brown 	case WM831X_LDO7_SLEEP_CONTROL:
4572e47fff1SMark Brown 	case WM831X_LDO8_CONTROL:
4582e47fff1SMark Brown 	case WM831X_LDO8_ON_CONTROL:
4592e47fff1SMark Brown 	case WM831X_LDO8_SLEEP_CONTROL:
4602e47fff1SMark Brown 	case WM831X_LDO9_CONTROL:
4612e47fff1SMark Brown 	case WM831X_LDO9_ON_CONTROL:
4622e47fff1SMark Brown 	case WM831X_LDO9_SLEEP_CONTROL:
4632e47fff1SMark Brown 	case WM831X_LDO10_CONTROL:
4642e47fff1SMark Brown 	case WM831X_LDO10_ON_CONTROL:
4652e47fff1SMark Brown 	case WM831X_LDO10_SLEEP_CONTROL:
4662e47fff1SMark Brown 	case WM831X_LDO11_ON_CONTROL:
4672e47fff1SMark Brown 	case WM831X_LDO11_SLEEP_CONTROL:
4682e47fff1SMark Brown 	case WM831X_POWER_GOOD_SOURCE_1:
4692e47fff1SMark Brown 	case WM831X_POWER_GOOD_SOURCE_2:
4702e47fff1SMark Brown 	case WM831X_CLOCK_CONTROL_1:
4712e47fff1SMark Brown 	case WM831X_CLOCK_CONTROL_2:
4722e47fff1SMark Brown 	case WM831X_FLL_CONTROL_1:
4732e47fff1SMark Brown 	case WM831X_FLL_CONTROL_2:
4742e47fff1SMark Brown 	case WM831X_FLL_CONTROL_3:
4752e47fff1SMark Brown 	case WM831X_FLL_CONTROL_4:
4762e47fff1SMark Brown 	case WM831X_FLL_CONTROL_5:
4772e47fff1SMark Brown 		return true;
4782e47fff1SMark Brown 	default:
4792e47fff1SMark Brown 		return false;
4802e47fff1SMark Brown 	}
4812e47fff1SMark Brown }
4822e47fff1SMark Brown 
4832e47fff1SMark Brown static bool wm831x_reg_volatile(struct device *dev, unsigned int reg)
4842e47fff1SMark Brown {
4852e47fff1SMark Brown 	switch (reg) {
4862e47fff1SMark Brown 	case WM831X_SYSTEM_STATUS:
4872e47fff1SMark Brown 	case WM831X_ON_SOURCE:
4882e47fff1SMark Brown 	case WM831X_OFF_SOURCE:
4892e47fff1SMark Brown 	case WM831X_GPIO_LEVEL:
4902e47fff1SMark Brown 	case WM831X_SYSTEM_INTERRUPTS:
4912e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_1:
4922e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_2:
4932e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_3:
4942e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_4:
4952e47fff1SMark Brown 	case WM831X_INTERRUPT_STATUS_5:
4962e47fff1SMark Brown 	case WM831X_RTC_TIME_1:
4972e47fff1SMark Brown 	case WM831X_RTC_TIME_2:
4982e47fff1SMark Brown 	case WM831X_TOUCH_DATA_X:
4992e47fff1SMark Brown 	case WM831X_TOUCH_DATA_Y:
5002e47fff1SMark Brown 	case WM831X_TOUCH_DATA_Z:
5012e47fff1SMark Brown 	case WM831X_AUXADC_DATA:
5022e47fff1SMark Brown 	case WM831X_CHARGER_STATUS:
5032e47fff1SMark Brown 	case WM831X_DCDC_STATUS:
5042e47fff1SMark Brown 	case WM831X_LDO_STATUS:
5052e47fff1SMark Brown 	case WM831X_DCDC_UV_STATUS:
5062e47fff1SMark Brown 	case WM831X_LDO_UV_STATUS:
5072e47fff1SMark Brown 		return true;
5082e47fff1SMark Brown 	default:
5092e47fff1SMark Brown 		return false;
5102e47fff1SMark Brown 	}
5112e47fff1SMark Brown }
5122e47fff1SMark Brown 
513d2bedfe7SMark Brown /**
514d2bedfe7SMark Brown  * wm831x_reg_read: Read a single WM831x register.
515d2bedfe7SMark Brown  *
516d2bedfe7SMark Brown  * @wm831x: Device to read from.
517d2bedfe7SMark Brown  * @reg: Register to read.
518d2bedfe7SMark Brown  */
519d2bedfe7SMark Brown int wm831x_reg_read(struct wm831x *wm831x, unsigned short reg)
520d2bedfe7SMark Brown {
5211df5981bSMark Brown 	unsigned int val;
522d2bedfe7SMark Brown 	int ret;
523d2bedfe7SMark Brown 
5241df5981bSMark Brown 	ret = regmap_read(wm831x->regmap, reg, &val);
525d2bedfe7SMark Brown 
526d2bedfe7SMark Brown 	if (ret < 0)
527d2bedfe7SMark Brown 		return ret;
528d2bedfe7SMark Brown 	else
529d2bedfe7SMark Brown 		return val;
530d2bedfe7SMark Brown }
531d2bedfe7SMark Brown EXPORT_SYMBOL_GPL(wm831x_reg_read);
532d2bedfe7SMark Brown 
533d2bedfe7SMark Brown /**
534d2bedfe7SMark Brown  * wm831x_bulk_read: Read multiple WM831x registers
535d2bedfe7SMark Brown  *
536d2bedfe7SMark Brown  * @wm831x: Device to read from
537d2bedfe7SMark Brown  * @reg: First register
538d2bedfe7SMark Brown  * @count: Number of registers
539d2bedfe7SMark Brown  * @buf: Buffer to fill.
540d2bedfe7SMark Brown  */
541d2bedfe7SMark Brown int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg,
542d2bedfe7SMark Brown 		     int count, u16 *buf)
543d2bedfe7SMark Brown {
5441df5981bSMark Brown 	return regmap_bulk_read(wm831x->regmap, reg, buf, count);
545d2bedfe7SMark Brown }
546d2bedfe7SMark Brown EXPORT_SYMBOL_GPL(wm831x_bulk_read);
547d2bedfe7SMark Brown 
548d2bedfe7SMark Brown static int wm831x_write(struct wm831x *wm831x, unsigned short reg,
549d2bedfe7SMark Brown 			int bytes, void *src)
550d2bedfe7SMark Brown {
551d2bedfe7SMark Brown 	u16 *buf = src;
5521df5981bSMark Brown 	int i, ret;
553d2bedfe7SMark Brown 
554d2bedfe7SMark Brown 	BUG_ON(bytes % 2);
555d2bedfe7SMark Brown 	BUG_ON(bytes <= 0);
556d2bedfe7SMark Brown 
557d2bedfe7SMark Brown 	for (i = 0; i < bytes / 2; i++) {
558d2bedfe7SMark Brown 		if (wm831x_reg_locked(wm831x, reg))
559d2bedfe7SMark Brown 			return -EPERM;
560d2bedfe7SMark Brown 
561d2bedfe7SMark Brown 		dev_vdbg(wm831x->dev, "Write %04x to R%d(0x%x)\n",
562d2bedfe7SMark Brown 			 buf[i], reg + i, reg + i);
5631df5981bSMark Brown 		ret = regmap_write(wm831x->regmap, reg + i, buf[i]);
5645391b5c6SMark Brown 		if (ret != 0)
5655391b5c6SMark Brown 			return ret;
566d2bedfe7SMark Brown 	}
567d2bedfe7SMark Brown 
5681df5981bSMark Brown 	return 0;
569d2bedfe7SMark Brown }
570d2bedfe7SMark Brown 
571d2bedfe7SMark Brown /**
572d2bedfe7SMark Brown  * wm831x_reg_write: Write a single WM831x register.
573d2bedfe7SMark Brown  *
574d2bedfe7SMark Brown  * @wm831x: Device to write to.
575d2bedfe7SMark Brown  * @reg: Register to write to.
576d2bedfe7SMark Brown  * @val: Value to write.
577d2bedfe7SMark Brown  */
578d2bedfe7SMark Brown int wm831x_reg_write(struct wm831x *wm831x, unsigned short reg,
579d2bedfe7SMark Brown 		     unsigned short val)
580d2bedfe7SMark Brown {
581d2bedfe7SMark Brown 	int ret;
582d2bedfe7SMark Brown 
583d2bedfe7SMark Brown 	mutex_lock(&wm831x->io_lock);
584d2bedfe7SMark Brown 
585d2bedfe7SMark Brown 	ret = wm831x_write(wm831x, reg, 2, &val);
586d2bedfe7SMark Brown 
587d2bedfe7SMark Brown 	mutex_unlock(&wm831x->io_lock);
588d2bedfe7SMark Brown 
589d2bedfe7SMark Brown 	return ret;
590d2bedfe7SMark Brown }
591d2bedfe7SMark Brown EXPORT_SYMBOL_GPL(wm831x_reg_write);
592d2bedfe7SMark Brown 
593d2bedfe7SMark Brown /**
594d2bedfe7SMark Brown  * wm831x_set_bits: Set the value of a bitfield in a WM831x register
595d2bedfe7SMark Brown  *
596d2bedfe7SMark Brown  * @wm831x: Device to write to.
597d2bedfe7SMark Brown  * @reg: Register to write to.
598d2bedfe7SMark Brown  * @mask: Mask of bits to set.
599d2bedfe7SMark Brown  * @val: Value to set (unshifted)
600d2bedfe7SMark Brown  */
601d2bedfe7SMark Brown int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg,
602d2bedfe7SMark Brown 		    unsigned short mask, unsigned short val)
603d2bedfe7SMark Brown {
604d2bedfe7SMark Brown 	int ret;
605d2bedfe7SMark Brown 
606d2bedfe7SMark Brown 	mutex_lock(&wm831x->io_lock);
607d2bedfe7SMark Brown 
6081df5981bSMark Brown 	if (!wm831x_reg_locked(wm831x, reg))
6091df5981bSMark Brown 		ret = regmap_update_bits(wm831x->regmap, reg, mask, val);
6101df5981bSMark Brown 	else
6111df5981bSMark Brown 		ret = -EPERM;
612d2bedfe7SMark Brown 
613d2bedfe7SMark Brown 	mutex_unlock(&wm831x->io_lock);
614d2bedfe7SMark Brown 
615d2bedfe7SMark Brown 	return ret;
616d2bedfe7SMark Brown }
617d2bedfe7SMark Brown EXPORT_SYMBOL_GPL(wm831x_set_bits);
618d2bedfe7SMark Brown 
619*f977284aSRikard Falkeborn static const struct resource wm831x_dcdc1_resources[] = {
620d2bedfe7SMark Brown 	{
621d2bedfe7SMark Brown 		.start = WM831X_DC1_CONTROL_1,
622d2bedfe7SMark Brown 		.end   = WM831X_DC1_DVS_CONTROL,
6235656098eSMark Brown 		.flags = IORESOURCE_REG,
624d2bedfe7SMark Brown 	},
625d2bedfe7SMark Brown 	{
626d2bedfe7SMark Brown 		.name  = "UV",
627d2bedfe7SMark Brown 		.start = WM831X_IRQ_UV_DC1,
628d2bedfe7SMark Brown 		.end   = WM831X_IRQ_UV_DC1,
629d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
630d2bedfe7SMark Brown 	},
631d2bedfe7SMark Brown 	{
632d2bedfe7SMark Brown 		.name  = "HC",
633d2bedfe7SMark Brown 		.start = WM831X_IRQ_HC_DC1,
634d2bedfe7SMark Brown 		.end   = WM831X_IRQ_HC_DC1,
635d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
636d2bedfe7SMark Brown 	},
637d2bedfe7SMark Brown };
638d2bedfe7SMark Brown 
639d2bedfe7SMark Brown 
640*f977284aSRikard Falkeborn static const struct resource wm831x_dcdc2_resources[] = {
641d2bedfe7SMark Brown 	{
642d2bedfe7SMark Brown 		.start = WM831X_DC2_CONTROL_1,
643d2bedfe7SMark Brown 		.end   = WM831X_DC2_DVS_CONTROL,
6445656098eSMark Brown 		.flags = IORESOURCE_REG,
645d2bedfe7SMark Brown 	},
646d2bedfe7SMark Brown 	{
647d2bedfe7SMark Brown 		.name  = "UV",
648d2bedfe7SMark Brown 		.start = WM831X_IRQ_UV_DC2,
649d2bedfe7SMark Brown 		.end   = WM831X_IRQ_UV_DC2,
650d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
651d2bedfe7SMark Brown 	},
652d2bedfe7SMark Brown 	{
653d2bedfe7SMark Brown 		.name  = "HC",
654d2bedfe7SMark Brown 		.start = WM831X_IRQ_HC_DC2,
655d2bedfe7SMark Brown 		.end   = WM831X_IRQ_HC_DC2,
656d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
657d2bedfe7SMark Brown 	},
658d2bedfe7SMark Brown };
659d2bedfe7SMark Brown 
660*f977284aSRikard Falkeborn static const struct resource wm831x_dcdc3_resources[] = {
661d2bedfe7SMark Brown 	{
662d2bedfe7SMark Brown 		.start = WM831X_DC3_CONTROL_1,
663d2bedfe7SMark Brown 		.end   = WM831X_DC3_SLEEP_CONTROL,
6645656098eSMark Brown 		.flags = IORESOURCE_REG,
665d2bedfe7SMark Brown 	},
666d2bedfe7SMark Brown 	{
667d2bedfe7SMark Brown 		.name  = "UV",
668d2bedfe7SMark Brown 		.start = WM831X_IRQ_UV_DC3,
669d2bedfe7SMark Brown 		.end   = WM831X_IRQ_UV_DC3,
670d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
671d2bedfe7SMark Brown 	},
672d2bedfe7SMark Brown };
673d2bedfe7SMark Brown 
674*f977284aSRikard Falkeborn static const struct resource wm831x_dcdc4_resources[] = {
675d2bedfe7SMark Brown 	{
676d2bedfe7SMark Brown 		.start = WM831X_DC4_CONTROL,
677d2bedfe7SMark Brown 		.end   = WM831X_DC4_SLEEP_CONTROL,
6785656098eSMark Brown 		.flags = IORESOURCE_REG,
679d2bedfe7SMark Brown 	},
680d2bedfe7SMark Brown 	{
681d2bedfe7SMark Brown 		.name  = "UV",
682d2bedfe7SMark Brown 		.start = WM831X_IRQ_UV_DC4,
683d2bedfe7SMark Brown 		.end   = WM831X_IRQ_UV_DC4,
684d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
685d2bedfe7SMark Brown 	},
686d2bedfe7SMark Brown };
687d2bedfe7SMark Brown 
688*f977284aSRikard Falkeborn static const struct resource wm8320_dcdc4_buck_resources[] = {
689d4e0a89eSMark Brown 	{
690d4e0a89eSMark Brown 		.start = WM831X_DC4_CONTROL,
691d4e0a89eSMark Brown 		.end   = WM832X_DC4_SLEEP_CONTROL,
6925656098eSMark Brown 		.flags = IORESOURCE_REG,
693d4e0a89eSMark Brown 	},
694d4e0a89eSMark Brown 	{
695d4e0a89eSMark Brown 		.name  = "UV",
696d4e0a89eSMark Brown 		.start = WM831X_IRQ_UV_DC4,
697d4e0a89eSMark Brown 		.end   = WM831X_IRQ_UV_DC4,
698d4e0a89eSMark Brown 		.flags = IORESOURCE_IRQ,
699d4e0a89eSMark Brown 	},
700d4e0a89eSMark Brown };
701d4e0a89eSMark Brown 
702*f977284aSRikard Falkeborn static const struct resource wm831x_gpio_resources[] = {
703d2bedfe7SMark Brown 	{
704d2bedfe7SMark Brown 		.start = WM831X_IRQ_GPIO_1,
705d2bedfe7SMark Brown 		.end   = WM831X_IRQ_GPIO_16,
706d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
707d2bedfe7SMark Brown 	},
708d2bedfe7SMark Brown };
709d2bedfe7SMark Brown 
710*f977284aSRikard Falkeborn static const struct resource wm831x_isink1_resources[] = {
711d2bedfe7SMark Brown 	{
712d2bedfe7SMark Brown 		.start = WM831X_CURRENT_SINK_1,
713d2bedfe7SMark Brown 		.end   = WM831X_CURRENT_SINK_1,
7145656098eSMark Brown 		.flags = IORESOURCE_REG,
715d2bedfe7SMark Brown 	},
716d2bedfe7SMark Brown 	{
717d2bedfe7SMark Brown 		.start = WM831X_IRQ_CS1,
718d2bedfe7SMark Brown 		.end   = WM831X_IRQ_CS1,
719d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
720d2bedfe7SMark Brown 	},
721d2bedfe7SMark Brown };
722d2bedfe7SMark Brown 
723*f977284aSRikard Falkeborn static const struct resource wm831x_isink2_resources[] = {
724d2bedfe7SMark Brown 	{
725d2bedfe7SMark Brown 		.start = WM831X_CURRENT_SINK_2,
726d2bedfe7SMark Brown 		.end   = WM831X_CURRENT_SINK_2,
7275656098eSMark Brown 		.flags = IORESOURCE_REG,
728d2bedfe7SMark Brown 	},
729d2bedfe7SMark Brown 	{
730d2bedfe7SMark Brown 		.start = WM831X_IRQ_CS2,
731d2bedfe7SMark Brown 		.end   = WM831X_IRQ_CS2,
732d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
733d2bedfe7SMark Brown 	},
734d2bedfe7SMark Brown };
735d2bedfe7SMark Brown 
736*f977284aSRikard Falkeborn static const struct resource wm831x_ldo1_resources[] = {
737d2bedfe7SMark Brown 	{
738d2bedfe7SMark Brown 		.start = WM831X_LDO1_CONTROL,
739d2bedfe7SMark Brown 		.end   = WM831X_LDO1_SLEEP_CONTROL,
7405656098eSMark Brown 		.flags = IORESOURCE_REG,
741d2bedfe7SMark Brown 	},
742d2bedfe7SMark Brown 	{
743d2bedfe7SMark Brown 		.name  = "UV",
744d2bedfe7SMark Brown 		.start = WM831X_IRQ_UV_LDO1,
745d2bedfe7SMark Brown 		.end   = WM831X_IRQ_UV_LDO1,
746d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
747d2bedfe7SMark Brown 	},
748d2bedfe7SMark Brown };
749d2bedfe7SMark Brown 
750*f977284aSRikard Falkeborn static const struct resource wm831x_ldo2_resources[] = {
751d2bedfe7SMark Brown 	{
752d2bedfe7SMark Brown 		.start = WM831X_LDO2_CONTROL,
753d2bedfe7SMark Brown 		.end   = WM831X_LDO2_SLEEP_CONTROL,
7545656098eSMark Brown 		.flags = IORESOURCE_REG,
755d2bedfe7SMark Brown 	},
756d2bedfe7SMark Brown 	{
757d2bedfe7SMark Brown 		.name  = "UV",
758d2bedfe7SMark Brown 		.start = WM831X_IRQ_UV_LDO2,
759d2bedfe7SMark Brown 		.end   = WM831X_IRQ_UV_LDO2,
760d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
761d2bedfe7SMark Brown 	},
762d2bedfe7SMark Brown };
763d2bedfe7SMark Brown 
764*f977284aSRikard Falkeborn static const struct resource wm831x_ldo3_resources[] = {
765d2bedfe7SMark Brown 	{
766d2bedfe7SMark Brown 		.start = WM831X_LDO3_CONTROL,
767d2bedfe7SMark Brown 		.end   = WM831X_LDO3_SLEEP_CONTROL,
7685656098eSMark Brown 		.flags = IORESOURCE_REG,
769d2bedfe7SMark Brown 	},
770d2bedfe7SMark Brown 	{
771d2bedfe7SMark Brown 		.name  = "UV",
772d2bedfe7SMark Brown 		.start = WM831X_IRQ_UV_LDO3,
773d2bedfe7SMark Brown 		.end   = WM831X_IRQ_UV_LDO3,
774d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
775d2bedfe7SMark Brown 	},
776d2bedfe7SMark Brown };
777d2bedfe7SMark Brown 
778*f977284aSRikard Falkeborn static const struct resource wm831x_ldo4_resources[] = {
779d2bedfe7SMark Brown 	{
780d2bedfe7SMark Brown 		.start = WM831X_LDO4_CONTROL,
781d2bedfe7SMark Brown 		.end   = WM831X_LDO4_SLEEP_CONTROL,
7825656098eSMark Brown 		.flags = IORESOURCE_REG,
783d2bedfe7SMark Brown 	},
784d2bedfe7SMark Brown 	{
785d2bedfe7SMark Brown 		.name  = "UV",
786d2bedfe7SMark Brown 		.start = WM831X_IRQ_UV_LDO4,
787d2bedfe7SMark Brown 		.end   = WM831X_IRQ_UV_LDO4,
788d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
789d2bedfe7SMark Brown 	},
790d2bedfe7SMark Brown };
791d2bedfe7SMark Brown 
792*f977284aSRikard Falkeborn static const struct resource wm831x_ldo5_resources[] = {
793d2bedfe7SMark Brown 	{
794d2bedfe7SMark Brown 		.start = WM831X_LDO5_CONTROL,
795d2bedfe7SMark Brown 		.end   = WM831X_LDO5_SLEEP_CONTROL,
7965656098eSMark Brown 		.flags = IORESOURCE_REG,
797d2bedfe7SMark Brown 	},
798d2bedfe7SMark Brown 	{
799d2bedfe7SMark Brown 		.name  = "UV",
800d2bedfe7SMark Brown 		.start = WM831X_IRQ_UV_LDO5,
801d2bedfe7SMark Brown 		.end   = WM831X_IRQ_UV_LDO5,
802d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
803d2bedfe7SMark Brown 	},
804d2bedfe7SMark Brown };
805d2bedfe7SMark Brown 
806*f977284aSRikard Falkeborn static const struct resource wm831x_ldo6_resources[] = {
807d2bedfe7SMark Brown 	{
808d2bedfe7SMark Brown 		.start = WM831X_LDO6_CONTROL,
809d2bedfe7SMark Brown 		.end   = WM831X_LDO6_SLEEP_CONTROL,
8105656098eSMark Brown 		.flags = IORESOURCE_REG,
811d2bedfe7SMark Brown 	},
812d2bedfe7SMark Brown 	{
813d2bedfe7SMark Brown 		.name  = "UV",
814d2bedfe7SMark Brown 		.start = WM831X_IRQ_UV_LDO6,
815d2bedfe7SMark Brown 		.end   = WM831X_IRQ_UV_LDO6,
816d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
817d2bedfe7SMark Brown 	},
818d2bedfe7SMark Brown };
819d2bedfe7SMark Brown 
820*f977284aSRikard Falkeborn static const struct resource wm831x_ldo7_resources[] = {
821d2bedfe7SMark Brown 	{
822d2bedfe7SMark Brown 		.start = WM831X_LDO7_CONTROL,
823d2bedfe7SMark Brown 		.end   = WM831X_LDO7_SLEEP_CONTROL,
8245656098eSMark Brown 		.flags = IORESOURCE_REG,
825d2bedfe7SMark Brown 	},
826d2bedfe7SMark Brown 	{
827d2bedfe7SMark Brown 		.name  = "UV",
828d2bedfe7SMark Brown 		.start = WM831X_IRQ_UV_LDO7,
829d2bedfe7SMark Brown 		.end   = WM831X_IRQ_UV_LDO7,
830d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
831d2bedfe7SMark Brown 	},
832d2bedfe7SMark Brown };
833d2bedfe7SMark Brown 
834*f977284aSRikard Falkeborn static const struct resource wm831x_ldo8_resources[] = {
835d2bedfe7SMark Brown 	{
836d2bedfe7SMark Brown 		.start = WM831X_LDO8_CONTROL,
837d2bedfe7SMark Brown 		.end   = WM831X_LDO8_SLEEP_CONTROL,
8385656098eSMark Brown 		.flags = IORESOURCE_REG,
839d2bedfe7SMark Brown 	},
840d2bedfe7SMark Brown 	{
841d2bedfe7SMark Brown 		.name  = "UV",
842d2bedfe7SMark Brown 		.start = WM831X_IRQ_UV_LDO8,
843d2bedfe7SMark Brown 		.end   = WM831X_IRQ_UV_LDO8,
844d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
845d2bedfe7SMark Brown 	},
846d2bedfe7SMark Brown };
847d2bedfe7SMark Brown 
848*f977284aSRikard Falkeborn static const struct resource wm831x_ldo9_resources[] = {
849d2bedfe7SMark Brown 	{
850d2bedfe7SMark Brown 		.start = WM831X_LDO9_CONTROL,
851d2bedfe7SMark Brown 		.end   = WM831X_LDO9_SLEEP_CONTROL,
8525656098eSMark Brown 		.flags = IORESOURCE_REG,
853d2bedfe7SMark Brown 	},
854d2bedfe7SMark Brown 	{
855d2bedfe7SMark Brown 		.name  = "UV",
856d2bedfe7SMark Brown 		.start = WM831X_IRQ_UV_LDO9,
857d2bedfe7SMark Brown 		.end   = WM831X_IRQ_UV_LDO9,
858d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
859d2bedfe7SMark Brown 	},
860d2bedfe7SMark Brown };
861d2bedfe7SMark Brown 
862*f977284aSRikard Falkeborn static const struct resource wm831x_ldo10_resources[] = {
863d2bedfe7SMark Brown 	{
864d2bedfe7SMark Brown 		.start = WM831X_LDO10_CONTROL,
865d2bedfe7SMark Brown 		.end   = WM831X_LDO10_SLEEP_CONTROL,
8665656098eSMark Brown 		.flags = IORESOURCE_REG,
867d2bedfe7SMark Brown 	},
868d2bedfe7SMark Brown 	{
869d2bedfe7SMark Brown 		.name  = "UV",
870d2bedfe7SMark Brown 		.start = WM831X_IRQ_UV_LDO10,
871d2bedfe7SMark Brown 		.end   = WM831X_IRQ_UV_LDO10,
872d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
873d2bedfe7SMark Brown 	},
874d2bedfe7SMark Brown };
875d2bedfe7SMark Brown 
876*f977284aSRikard Falkeborn static const struct resource wm831x_ldo11_resources[] = {
877d2bedfe7SMark Brown 	{
878d2bedfe7SMark Brown 		.start = WM831X_LDO11_ON_CONTROL,
879d2bedfe7SMark Brown 		.end   = WM831X_LDO11_SLEEP_CONTROL,
8805656098eSMark Brown 		.flags = IORESOURCE_REG,
881d2bedfe7SMark Brown 	},
882d2bedfe7SMark Brown };
883d2bedfe7SMark Brown 
884*f977284aSRikard Falkeborn static const struct resource wm831x_on_resources[] = {
885d2bedfe7SMark Brown 	{
886d2bedfe7SMark Brown 		.start = WM831X_IRQ_ON,
887d2bedfe7SMark Brown 		.end   = WM831X_IRQ_ON,
888d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
889d2bedfe7SMark Brown 	},
890d2bedfe7SMark Brown };
891d2bedfe7SMark Brown 
892d2bedfe7SMark Brown 
893*f977284aSRikard Falkeborn static const struct resource wm831x_power_resources[] = {
894d2bedfe7SMark Brown 	{
895d2bedfe7SMark Brown 		.name = "SYSLO",
896d2bedfe7SMark Brown 		.start = WM831X_IRQ_PPM_SYSLO,
897d2bedfe7SMark Brown 		.end   = WM831X_IRQ_PPM_SYSLO,
898d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
899d2bedfe7SMark Brown 	},
900d2bedfe7SMark Brown 	{
901d2bedfe7SMark Brown 		.name = "PWR SRC",
902d2bedfe7SMark Brown 		.start = WM831X_IRQ_PPM_PWR_SRC,
903d2bedfe7SMark Brown 		.end   = WM831X_IRQ_PPM_PWR_SRC,
904d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
905d2bedfe7SMark Brown 	},
906d2bedfe7SMark Brown 	{
907d2bedfe7SMark Brown 		.name = "USB CURR",
908d2bedfe7SMark Brown 		.start = WM831X_IRQ_PPM_USB_CURR,
909d2bedfe7SMark Brown 		.end   = WM831X_IRQ_PPM_USB_CURR,
910d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
911d2bedfe7SMark Brown 	},
912d2bedfe7SMark Brown 	{
913d2bedfe7SMark Brown 		.name = "BATT HOT",
914d2bedfe7SMark Brown 		.start = WM831X_IRQ_CHG_BATT_HOT,
915d2bedfe7SMark Brown 		.end   = WM831X_IRQ_CHG_BATT_HOT,
916d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
917d2bedfe7SMark Brown 	},
918d2bedfe7SMark Brown 	{
919d2bedfe7SMark Brown 		.name = "BATT COLD",
920d2bedfe7SMark Brown 		.start = WM831X_IRQ_CHG_BATT_COLD,
921d2bedfe7SMark Brown 		.end   = WM831X_IRQ_CHG_BATT_COLD,
922d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
923d2bedfe7SMark Brown 	},
924d2bedfe7SMark Brown 	{
925d2bedfe7SMark Brown 		.name = "BATT FAIL",
926d2bedfe7SMark Brown 		.start = WM831X_IRQ_CHG_BATT_FAIL,
927d2bedfe7SMark Brown 		.end   = WM831X_IRQ_CHG_BATT_FAIL,
928d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
929d2bedfe7SMark Brown 	},
930d2bedfe7SMark Brown 	{
931d2bedfe7SMark Brown 		.name = "OV",
932d2bedfe7SMark Brown 		.start = WM831X_IRQ_CHG_OV,
933d2bedfe7SMark Brown 		.end   = WM831X_IRQ_CHG_OV,
934d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
935d2bedfe7SMark Brown 	},
936d2bedfe7SMark Brown 	{
937d2bedfe7SMark Brown 		.name = "END",
938d2bedfe7SMark Brown 		.start = WM831X_IRQ_CHG_END,
939d2bedfe7SMark Brown 		.end   = WM831X_IRQ_CHG_END,
940d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
941d2bedfe7SMark Brown 	},
942d2bedfe7SMark Brown 	{
943d2bedfe7SMark Brown 		.name = "TO",
944d2bedfe7SMark Brown 		.start = WM831X_IRQ_CHG_TO,
945d2bedfe7SMark Brown 		.end   = WM831X_IRQ_CHG_TO,
946d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
947d2bedfe7SMark Brown 	},
948d2bedfe7SMark Brown 	{
949d2bedfe7SMark Brown 		.name = "MODE",
950d2bedfe7SMark Brown 		.start = WM831X_IRQ_CHG_MODE,
951d2bedfe7SMark Brown 		.end   = WM831X_IRQ_CHG_MODE,
952d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
953d2bedfe7SMark Brown 	},
954d2bedfe7SMark Brown 	{
955d2bedfe7SMark Brown 		.name = "START",
956d2bedfe7SMark Brown 		.start = WM831X_IRQ_CHG_START,
957d2bedfe7SMark Brown 		.end   = WM831X_IRQ_CHG_START,
958d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
959d2bedfe7SMark Brown 	},
960d2bedfe7SMark Brown };
961d2bedfe7SMark Brown 
962*f977284aSRikard Falkeborn static const struct resource wm831x_rtc_resources[] = {
963d2bedfe7SMark Brown 	{
964d2bedfe7SMark Brown 		.name = "PER",
965d2bedfe7SMark Brown 		.start = WM831X_IRQ_RTC_PER,
966d2bedfe7SMark Brown 		.end   = WM831X_IRQ_RTC_PER,
967d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
968d2bedfe7SMark Brown 	},
969d2bedfe7SMark Brown 	{
970d2bedfe7SMark Brown 		.name = "ALM",
971d2bedfe7SMark Brown 		.start = WM831X_IRQ_RTC_ALM,
972d2bedfe7SMark Brown 		.end   = WM831X_IRQ_RTC_ALM,
973d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
974d2bedfe7SMark Brown 	},
975d2bedfe7SMark Brown };
976d2bedfe7SMark Brown 
977*f977284aSRikard Falkeborn static const struct resource wm831x_status1_resources[] = {
978d2bedfe7SMark Brown 	{
979d2bedfe7SMark Brown 		.start = WM831X_STATUS_LED_1,
980d2bedfe7SMark Brown 		.end   = WM831X_STATUS_LED_1,
9815656098eSMark Brown 		.flags = IORESOURCE_REG,
982d2bedfe7SMark Brown 	},
983d2bedfe7SMark Brown };
984d2bedfe7SMark Brown 
985*f977284aSRikard Falkeborn static const struct resource wm831x_status2_resources[] = {
986d2bedfe7SMark Brown 	{
987d2bedfe7SMark Brown 		.start = WM831X_STATUS_LED_2,
988d2bedfe7SMark Brown 		.end   = WM831X_STATUS_LED_2,
9895656098eSMark Brown 		.flags = IORESOURCE_REG,
990d2bedfe7SMark Brown 	},
991d2bedfe7SMark Brown };
992d2bedfe7SMark Brown 
993*f977284aSRikard Falkeborn static const struct resource wm831x_touch_resources[] = {
994d2bedfe7SMark Brown 	{
995d2bedfe7SMark Brown 		.name = "TCHPD",
996d2bedfe7SMark Brown 		.start = WM831X_IRQ_TCHPD,
997d2bedfe7SMark Brown 		.end   = WM831X_IRQ_TCHPD,
998d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
999d2bedfe7SMark Brown 	},
1000d2bedfe7SMark Brown 	{
1001d2bedfe7SMark Brown 		.name = "TCHDATA",
1002d2bedfe7SMark Brown 		.start = WM831X_IRQ_TCHDATA,
1003d2bedfe7SMark Brown 		.end   = WM831X_IRQ_TCHDATA,
1004d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
1005d2bedfe7SMark Brown 	},
1006d2bedfe7SMark Brown };
1007d2bedfe7SMark Brown 
1008*f977284aSRikard Falkeborn static const struct resource wm831x_wdt_resources[] = {
1009d2bedfe7SMark Brown 	{
1010d2bedfe7SMark Brown 		.start = WM831X_IRQ_WDOG_TO,
1011d2bedfe7SMark Brown 		.end   = WM831X_IRQ_WDOG_TO,
1012d2bedfe7SMark Brown 		.flags = IORESOURCE_IRQ,
1013d2bedfe7SMark Brown 	},
1014d2bedfe7SMark Brown };
1015d2bedfe7SMark Brown 
1016ad59de48SGeert Uytterhoeven static const struct mfd_cell wm8310_devs[] = {
1017d2bedfe7SMark Brown 	{
1018c26964eaSMark Brown 		.name = "wm831x-backup",
1019c26964eaSMark Brown 	},
1020c26964eaSMark Brown 	{
1021d2bedfe7SMark Brown 		.name = "wm831x-buckv",
1022d2bedfe7SMark Brown 		.id = 1,
1023d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
1024d2bedfe7SMark Brown 		.resources = wm831x_dcdc1_resources,
1025d2bedfe7SMark Brown 	},
1026d2bedfe7SMark Brown 	{
1027d2bedfe7SMark Brown 		.name = "wm831x-buckv",
1028d2bedfe7SMark Brown 		.id = 2,
1029d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
1030d2bedfe7SMark Brown 		.resources = wm831x_dcdc2_resources,
1031d2bedfe7SMark Brown 	},
1032d2bedfe7SMark Brown 	{
1033d2bedfe7SMark Brown 		.name = "wm831x-buckp",
1034d2bedfe7SMark Brown 		.id = 3,
1035d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
1036d2bedfe7SMark Brown 		.resources = wm831x_dcdc3_resources,
1037d2bedfe7SMark Brown 	},
1038d2bedfe7SMark Brown 	{
1039d2bedfe7SMark Brown 		.name = "wm831x-boostp",
1040d2bedfe7SMark Brown 		.id = 4,
1041d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
1042d2bedfe7SMark Brown 		.resources = wm831x_dcdc4_resources,
1043d2bedfe7SMark Brown 	},
1044d2bedfe7SMark Brown 	{
1045a5e06781SMark Brown 		.name = "wm831x-clk",
1046a5e06781SMark Brown 	},
1047a5e06781SMark Brown 	{
1048d2bedfe7SMark Brown 		.name = "wm831x-epe",
1049d2bedfe7SMark Brown 		.id = 1,
1050d2bedfe7SMark Brown 	},
1051d2bedfe7SMark Brown 	{
1052d2bedfe7SMark Brown 		.name = "wm831x-epe",
1053d2bedfe7SMark Brown 		.id = 2,
1054d2bedfe7SMark Brown 	},
1055d2bedfe7SMark Brown 	{
1056d2bedfe7SMark Brown 		.name = "wm831x-gpio",
1057d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_gpio_resources),
1058d2bedfe7SMark Brown 		.resources = wm831x_gpio_resources,
1059d2bedfe7SMark Brown 	},
1060d2bedfe7SMark Brown 	{
1061d2bedfe7SMark Brown 		.name = "wm831x-hwmon",
1062d2bedfe7SMark Brown 	},
1063d2bedfe7SMark Brown 	{
1064d2bedfe7SMark Brown 		.name = "wm831x-isink",
1065d2bedfe7SMark Brown 		.id = 1,
1066d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_isink1_resources),
1067d2bedfe7SMark Brown 		.resources = wm831x_isink1_resources,
1068d2bedfe7SMark Brown 	},
1069d2bedfe7SMark Brown 	{
1070d2bedfe7SMark Brown 		.name = "wm831x-isink",
1071d2bedfe7SMark Brown 		.id = 2,
1072d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_isink2_resources),
1073d2bedfe7SMark Brown 		.resources = wm831x_isink2_resources,
1074d2bedfe7SMark Brown 	},
1075d2bedfe7SMark Brown 	{
1076d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1077d2bedfe7SMark Brown 		.id = 1,
1078d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
1079d2bedfe7SMark Brown 		.resources = wm831x_ldo1_resources,
1080d2bedfe7SMark Brown 	},
1081d2bedfe7SMark Brown 	{
1082d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1083d2bedfe7SMark Brown 		.id = 2,
1084d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
1085d2bedfe7SMark Brown 		.resources = wm831x_ldo2_resources,
1086d2bedfe7SMark Brown 	},
1087d2bedfe7SMark Brown 	{
1088d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1089d2bedfe7SMark Brown 		.id = 3,
1090d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
1091d2bedfe7SMark Brown 		.resources = wm831x_ldo3_resources,
1092d2bedfe7SMark Brown 	},
1093d2bedfe7SMark Brown 	{
1094d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1095d2bedfe7SMark Brown 		.id = 4,
1096d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
1097d2bedfe7SMark Brown 		.resources = wm831x_ldo4_resources,
1098d2bedfe7SMark Brown 	},
1099d2bedfe7SMark Brown 	{
1100d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1101d2bedfe7SMark Brown 		.id = 5,
1102d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
1103d2bedfe7SMark Brown 		.resources = wm831x_ldo5_resources,
1104d2bedfe7SMark Brown 	},
1105d2bedfe7SMark Brown 	{
1106d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1107d2bedfe7SMark Brown 		.id = 6,
1108d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
1109d2bedfe7SMark Brown 		.resources = wm831x_ldo6_resources,
1110d2bedfe7SMark Brown 	},
1111d2bedfe7SMark Brown 	{
1112d2bedfe7SMark Brown 		.name = "wm831x-aldo",
1113d2bedfe7SMark Brown 		.id = 7,
1114d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
1115d2bedfe7SMark Brown 		.resources = wm831x_ldo7_resources,
1116d2bedfe7SMark Brown 	},
1117d2bedfe7SMark Brown 	{
1118d2bedfe7SMark Brown 		.name = "wm831x-aldo",
1119d2bedfe7SMark Brown 		.id = 8,
1120d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
1121d2bedfe7SMark Brown 		.resources = wm831x_ldo8_resources,
1122d2bedfe7SMark Brown 	},
1123d2bedfe7SMark Brown 	{
1124d2bedfe7SMark Brown 		.name = "wm831x-aldo",
1125d2bedfe7SMark Brown 		.id = 9,
1126d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
1127d2bedfe7SMark Brown 		.resources = wm831x_ldo9_resources,
1128d2bedfe7SMark Brown 	},
1129d2bedfe7SMark Brown 	{
1130d2bedfe7SMark Brown 		.name = "wm831x-aldo",
1131d2bedfe7SMark Brown 		.id = 10,
1132d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
1133d2bedfe7SMark Brown 		.resources = wm831x_ldo10_resources,
1134d2bedfe7SMark Brown 	},
1135d2bedfe7SMark Brown 	{
1136d2bedfe7SMark Brown 		.name = "wm831x-alive-ldo",
1137d2bedfe7SMark Brown 		.id = 11,
1138d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
1139d2bedfe7SMark Brown 		.resources = wm831x_ldo11_resources,
1140d2bedfe7SMark Brown 	},
1141d2bedfe7SMark Brown 	{
1142d2bedfe7SMark Brown 		.name = "wm831x-on",
1143d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_on_resources),
1144d2bedfe7SMark Brown 		.resources = wm831x_on_resources,
1145d2bedfe7SMark Brown 	},
1146d2bedfe7SMark Brown 	{
1147d2bedfe7SMark Brown 		.name = "wm831x-power",
1148d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_power_resources),
1149d2bedfe7SMark Brown 		.resources = wm831x_power_resources,
1150d2bedfe7SMark Brown 	},
1151d2bedfe7SMark Brown 	{
1152d2bedfe7SMark Brown 		.name = "wm831x-status",
1153d2bedfe7SMark Brown 		.id = 1,
1154d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_status1_resources),
1155d2bedfe7SMark Brown 		.resources = wm831x_status1_resources,
1156d2bedfe7SMark Brown 	},
1157d2bedfe7SMark Brown 	{
1158d2bedfe7SMark Brown 		.name = "wm831x-status",
1159d2bedfe7SMark Brown 		.id = 2,
1160d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_status2_resources),
1161d2bedfe7SMark Brown 		.resources = wm831x_status2_resources,
1162d2bedfe7SMark Brown 	},
1163d2bedfe7SMark Brown 	{
1164d2bedfe7SMark Brown 		.name = "wm831x-watchdog",
1165d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_wdt_resources),
1166d2bedfe7SMark Brown 		.resources = wm831x_wdt_resources,
1167d2bedfe7SMark Brown 	},
1168d2bedfe7SMark Brown };
1169d2bedfe7SMark Brown 
1170ad59de48SGeert Uytterhoeven static const struct mfd_cell wm8311_devs[] = {
1171d2bedfe7SMark Brown 	{
1172c26964eaSMark Brown 		.name = "wm831x-backup",
1173c26964eaSMark Brown 	},
1174c26964eaSMark Brown 	{
1175d2bedfe7SMark Brown 		.name = "wm831x-buckv",
1176d2bedfe7SMark Brown 		.id = 1,
1177d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
1178d2bedfe7SMark Brown 		.resources = wm831x_dcdc1_resources,
1179d2bedfe7SMark Brown 	},
1180d2bedfe7SMark Brown 	{
1181d2bedfe7SMark Brown 		.name = "wm831x-buckv",
1182d2bedfe7SMark Brown 		.id = 2,
1183d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
1184d2bedfe7SMark Brown 		.resources = wm831x_dcdc2_resources,
1185d2bedfe7SMark Brown 	},
1186d2bedfe7SMark Brown 	{
1187d2bedfe7SMark Brown 		.name = "wm831x-buckp",
1188d2bedfe7SMark Brown 		.id = 3,
1189d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
1190d2bedfe7SMark Brown 		.resources = wm831x_dcdc3_resources,
1191d2bedfe7SMark Brown 	},
1192d2bedfe7SMark Brown 	{
1193d2bedfe7SMark Brown 		.name = "wm831x-boostp",
1194d2bedfe7SMark Brown 		.id = 4,
1195d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
1196d2bedfe7SMark Brown 		.resources = wm831x_dcdc4_resources,
1197d2bedfe7SMark Brown 	},
1198d2bedfe7SMark Brown 	{
1199a5e06781SMark Brown 		.name = "wm831x-clk",
1200a5e06781SMark Brown 	},
1201a5e06781SMark Brown 	{
1202d2bedfe7SMark Brown 		.name = "wm831x-epe",
1203d2bedfe7SMark Brown 		.id = 1,
1204d2bedfe7SMark Brown 	},
1205d2bedfe7SMark Brown 	{
1206d2bedfe7SMark Brown 		.name = "wm831x-epe",
1207d2bedfe7SMark Brown 		.id = 2,
1208d2bedfe7SMark Brown 	},
1209d2bedfe7SMark Brown 	{
1210d2bedfe7SMark Brown 		.name = "wm831x-gpio",
1211d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_gpio_resources),
1212d2bedfe7SMark Brown 		.resources = wm831x_gpio_resources,
1213d2bedfe7SMark Brown 	},
1214d2bedfe7SMark Brown 	{
1215d2bedfe7SMark Brown 		.name = "wm831x-hwmon",
1216d2bedfe7SMark Brown 	},
1217d2bedfe7SMark Brown 	{
1218d2bedfe7SMark Brown 		.name = "wm831x-isink",
1219d2bedfe7SMark Brown 		.id = 1,
1220d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_isink1_resources),
1221d2bedfe7SMark Brown 		.resources = wm831x_isink1_resources,
1222d2bedfe7SMark Brown 	},
1223d2bedfe7SMark Brown 	{
1224d2bedfe7SMark Brown 		.name = "wm831x-isink",
1225d2bedfe7SMark Brown 		.id = 2,
1226d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_isink2_resources),
1227d2bedfe7SMark Brown 		.resources = wm831x_isink2_resources,
1228d2bedfe7SMark Brown 	},
1229d2bedfe7SMark Brown 	{
1230d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1231d2bedfe7SMark Brown 		.id = 1,
1232d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
1233d2bedfe7SMark Brown 		.resources = wm831x_ldo1_resources,
1234d2bedfe7SMark Brown 	},
1235d2bedfe7SMark Brown 	{
1236d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1237d2bedfe7SMark Brown 		.id = 2,
1238d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
1239d2bedfe7SMark Brown 		.resources = wm831x_ldo2_resources,
1240d2bedfe7SMark Brown 	},
1241d2bedfe7SMark Brown 	{
1242d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1243d2bedfe7SMark Brown 		.id = 3,
1244d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
1245d2bedfe7SMark Brown 		.resources = wm831x_ldo3_resources,
1246d2bedfe7SMark Brown 	},
1247d2bedfe7SMark Brown 	{
1248d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1249d2bedfe7SMark Brown 		.id = 4,
1250d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
1251d2bedfe7SMark Brown 		.resources = wm831x_ldo4_resources,
1252d2bedfe7SMark Brown 	},
1253d2bedfe7SMark Brown 	{
1254d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1255d2bedfe7SMark Brown 		.id = 5,
1256d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
1257d2bedfe7SMark Brown 		.resources = wm831x_ldo5_resources,
1258d2bedfe7SMark Brown 	},
1259d2bedfe7SMark Brown 	{
1260d2bedfe7SMark Brown 		.name = "wm831x-aldo",
1261d2bedfe7SMark Brown 		.id = 7,
1262d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
1263d2bedfe7SMark Brown 		.resources = wm831x_ldo7_resources,
1264d2bedfe7SMark Brown 	},
1265d2bedfe7SMark Brown 	{
1266d2bedfe7SMark Brown 		.name = "wm831x-alive-ldo",
1267d2bedfe7SMark Brown 		.id = 11,
1268d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
1269d2bedfe7SMark Brown 		.resources = wm831x_ldo11_resources,
1270d2bedfe7SMark Brown 	},
1271d2bedfe7SMark Brown 	{
1272d2bedfe7SMark Brown 		.name = "wm831x-on",
1273d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_on_resources),
1274d2bedfe7SMark Brown 		.resources = wm831x_on_resources,
1275d2bedfe7SMark Brown 	},
1276d2bedfe7SMark Brown 	{
1277d2bedfe7SMark Brown 		.name = "wm831x-power",
1278d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_power_resources),
1279d2bedfe7SMark Brown 		.resources = wm831x_power_resources,
1280d2bedfe7SMark Brown 	},
1281d2bedfe7SMark Brown 	{
1282d2bedfe7SMark Brown 		.name = "wm831x-status",
1283d2bedfe7SMark Brown 		.id = 1,
1284d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_status1_resources),
1285d2bedfe7SMark Brown 		.resources = wm831x_status1_resources,
1286d2bedfe7SMark Brown 	},
1287d2bedfe7SMark Brown 	{
1288d2bedfe7SMark Brown 		.name = "wm831x-status",
1289d2bedfe7SMark Brown 		.id = 2,
1290d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_status2_resources),
1291d2bedfe7SMark Brown 		.resources = wm831x_status2_resources,
1292d2bedfe7SMark Brown 	},
1293d2bedfe7SMark Brown 	{
1294d2bedfe7SMark Brown 		.name = "wm831x-watchdog",
1295d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_wdt_resources),
1296d2bedfe7SMark Brown 		.resources = wm831x_wdt_resources,
1297d2bedfe7SMark Brown 	},
1298d2bedfe7SMark Brown };
1299d2bedfe7SMark Brown 
1300ad59de48SGeert Uytterhoeven static const struct mfd_cell wm8312_devs[] = {
1301d2bedfe7SMark Brown 	{
1302c26964eaSMark Brown 		.name = "wm831x-backup",
1303c26964eaSMark Brown 	},
1304c26964eaSMark Brown 	{
1305d2bedfe7SMark Brown 		.name = "wm831x-buckv",
1306d2bedfe7SMark Brown 		.id = 1,
1307d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
1308d2bedfe7SMark Brown 		.resources = wm831x_dcdc1_resources,
1309d2bedfe7SMark Brown 	},
1310d2bedfe7SMark Brown 	{
1311d2bedfe7SMark Brown 		.name = "wm831x-buckv",
1312d2bedfe7SMark Brown 		.id = 2,
1313d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
1314d2bedfe7SMark Brown 		.resources = wm831x_dcdc2_resources,
1315d2bedfe7SMark Brown 	},
1316d2bedfe7SMark Brown 	{
1317d2bedfe7SMark Brown 		.name = "wm831x-buckp",
1318d2bedfe7SMark Brown 		.id = 3,
1319d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
1320d2bedfe7SMark Brown 		.resources = wm831x_dcdc3_resources,
1321d2bedfe7SMark Brown 	},
1322d2bedfe7SMark Brown 	{
1323d2bedfe7SMark Brown 		.name = "wm831x-boostp",
1324d2bedfe7SMark Brown 		.id = 4,
1325d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
1326d2bedfe7SMark Brown 		.resources = wm831x_dcdc4_resources,
1327d2bedfe7SMark Brown 	},
1328d2bedfe7SMark Brown 	{
1329a5e06781SMark Brown 		.name = "wm831x-clk",
1330a5e06781SMark Brown 	},
1331a5e06781SMark Brown 	{
1332d2bedfe7SMark Brown 		.name = "wm831x-epe",
1333d2bedfe7SMark Brown 		.id = 1,
1334d2bedfe7SMark Brown 	},
1335d2bedfe7SMark Brown 	{
1336d2bedfe7SMark Brown 		.name = "wm831x-epe",
1337d2bedfe7SMark Brown 		.id = 2,
1338d2bedfe7SMark Brown 	},
1339d2bedfe7SMark Brown 	{
1340d2bedfe7SMark Brown 		.name = "wm831x-gpio",
1341d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_gpio_resources),
1342d2bedfe7SMark Brown 		.resources = wm831x_gpio_resources,
1343d2bedfe7SMark Brown 	},
1344d2bedfe7SMark Brown 	{
1345d2bedfe7SMark Brown 		.name = "wm831x-hwmon",
1346d2bedfe7SMark Brown 	},
1347d2bedfe7SMark Brown 	{
1348d2bedfe7SMark Brown 		.name = "wm831x-isink",
1349d2bedfe7SMark Brown 		.id = 1,
1350d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_isink1_resources),
1351d2bedfe7SMark Brown 		.resources = wm831x_isink1_resources,
1352d2bedfe7SMark Brown 	},
1353d2bedfe7SMark Brown 	{
1354d2bedfe7SMark Brown 		.name = "wm831x-isink",
1355d2bedfe7SMark Brown 		.id = 2,
1356d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_isink2_resources),
1357d2bedfe7SMark Brown 		.resources = wm831x_isink2_resources,
1358d2bedfe7SMark Brown 	},
1359d2bedfe7SMark Brown 	{
1360d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1361d2bedfe7SMark Brown 		.id = 1,
1362d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
1363d2bedfe7SMark Brown 		.resources = wm831x_ldo1_resources,
1364d2bedfe7SMark Brown 	},
1365d2bedfe7SMark Brown 	{
1366d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1367d2bedfe7SMark Brown 		.id = 2,
1368d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
1369d2bedfe7SMark Brown 		.resources = wm831x_ldo2_resources,
1370d2bedfe7SMark Brown 	},
1371d2bedfe7SMark Brown 	{
1372d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1373d2bedfe7SMark Brown 		.id = 3,
1374d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
1375d2bedfe7SMark Brown 		.resources = wm831x_ldo3_resources,
1376d2bedfe7SMark Brown 	},
1377d2bedfe7SMark Brown 	{
1378d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1379d2bedfe7SMark Brown 		.id = 4,
1380d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
1381d2bedfe7SMark Brown 		.resources = wm831x_ldo4_resources,
1382d2bedfe7SMark Brown 	},
1383d2bedfe7SMark Brown 	{
1384d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1385d2bedfe7SMark Brown 		.id = 5,
1386d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
1387d2bedfe7SMark Brown 		.resources = wm831x_ldo5_resources,
1388d2bedfe7SMark Brown 	},
1389d2bedfe7SMark Brown 	{
1390d2bedfe7SMark Brown 		.name = "wm831x-ldo",
1391d2bedfe7SMark Brown 		.id = 6,
1392d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
1393d2bedfe7SMark Brown 		.resources = wm831x_ldo6_resources,
1394d2bedfe7SMark Brown 	},
1395d2bedfe7SMark Brown 	{
1396d2bedfe7SMark Brown 		.name = "wm831x-aldo",
1397d2bedfe7SMark Brown 		.id = 7,
1398d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
1399d2bedfe7SMark Brown 		.resources = wm831x_ldo7_resources,
1400d2bedfe7SMark Brown 	},
1401d2bedfe7SMark Brown 	{
1402d2bedfe7SMark Brown 		.name = "wm831x-aldo",
1403d2bedfe7SMark Brown 		.id = 8,
1404d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
1405d2bedfe7SMark Brown 		.resources = wm831x_ldo8_resources,
1406d2bedfe7SMark Brown 	},
1407d2bedfe7SMark Brown 	{
1408d2bedfe7SMark Brown 		.name = "wm831x-aldo",
1409d2bedfe7SMark Brown 		.id = 9,
1410d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
1411d2bedfe7SMark Brown 		.resources = wm831x_ldo9_resources,
1412d2bedfe7SMark Brown 	},
1413d2bedfe7SMark Brown 	{
1414d2bedfe7SMark Brown 		.name = "wm831x-aldo",
1415d2bedfe7SMark Brown 		.id = 10,
1416d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
1417d2bedfe7SMark Brown 		.resources = wm831x_ldo10_resources,
1418d2bedfe7SMark Brown 	},
1419d2bedfe7SMark Brown 	{
1420d2bedfe7SMark Brown 		.name = "wm831x-alive-ldo",
1421d2bedfe7SMark Brown 		.id = 11,
1422d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
1423d2bedfe7SMark Brown 		.resources = wm831x_ldo11_resources,
1424d2bedfe7SMark Brown 	},
1425d2bedfe7SMark Brown 	{
1426d2bedfe7SMark Brown 		.name = "wm831x-on",
1427d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_on_resources),
1428d2bedfe7SMark Brown 		.resources = wm831x_on_resources,
1429d2bedfe7SMark Brown 	},
1430d2bedfe7SMark Brown 	{
1431d2bedfe7SMark Brown 		.name = "wm831x-power",
1432d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_power_resources),
1433d2bedfe7SMark Brown 		.resources = wm831x_power_resources,
1434d2bedfe7SMark Brown 	},
1435d2bedfe7SMark Brown 	{
1436d2bedfe7SMark Brown 		.name = "wm831x-status",
1437d2bedfe7SMark Brown 		.id = 1,
1438d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_status1_resources),
1439d2bedfe7SMark Brown 		.resources = wm831x_status1_resources,
1440d2bedfe7SMark Brown 	},
1441d2bedfe7SMark Brown 	{
1442d2bedfe7SMark Brown 		.name = "wm831x-status",
1443d2bedfe7SMark Brown 		.id = 2,
1444d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_status2_resources),
1445d2bedfe7SMark Brown 		.resources = wm831x_status2_resources,
1446d2bedfe7SMark Brown 	},
1447d2bedfe7SMark Brown 	{
1448d2bedfe7SMark Brown 		.name = "wm831x-watchdog",
1449d2bedfe7SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_wdt_resources),
1450d2bedfe7SMark Brown 		.resources = wm831x_wdt_resources,
1451d2bedfe7SMark Brown 	},
1452d2bedfe7SMark Brown };
1453d2bedfe7SMark Brown 
1454ad59de48SGeert Uytterhoeven static const struct mfd_cell wm8320_devs[] = {
1455d4e0a89eSMark Brown 	{
1456d4e0a89eSMark Brown 		.name = "wm831x-backup",
1457d4e0a89eSMark Brown 	},
1458d4e0a89eSMark Brown 	{
1459d4e0a89eSMark Brown 		.name = "wm831x-buckv",
1460d4e0a89eSMark Brown 		.id = 1,
1461d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
1462d4e0a89eSMark Brown 		.resources = wm831x_dcdc1_resources,
1463d4e0a89eSMark Brown 	},
1464d4e0a89eSMark Brown 	{
1465d4e0a89eSMark Brown 		.name = "wm831x-buckv",
1466d4e0a89eSMark Brown 		.id = 2,
1467d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
1468d4e0a89eSMark Brown 		.resources = wm831x_dcdc2_resources,
1469d4e0a89eSMark Brown 	},
1470d4e0a89eSMark Brown 	{
1471d4e0a89eSMark Brown 		.name = "wm831x-buckp",
1472d4e0a89eSMark Brown 		.id = 3,
1473d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
1474d4e0a89eSMark Brown 		.resources = wm831x_dcdc3_resources,
1475d4e0a89eSMark Brown 	},
1476d4e0a89eSMark Brown 	{
1477d4e0a89eSMark Brown 		.name = "wm831x-buckp",
1478d4e0a89eSMark Brown 		.id = 4,
1479d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm8320_dcdc4_buck_resources),
1480d4e0a89eSMark Brown 		.resources = wm8320_dcdc4_buck_resources,
1481d4e0a89eSMark Brown 	},
1482d4e0a89eSMark Brown 	{
1483a5e06781SMark Brown 		.name = "wm831x-clk",
1484a5e06781SMark Brown 	},
1485a5e06781SMark Brown 	{
1486d4e0a89eSMark Brown 		.name = "wm831x-gpio",
1487d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_gpio_resources),
1488d4e0a89eSMark Brown 		.resources = wm831x_gpio_resources,
1489d4e0a89eSMark Brown 	},
1490d4e0a89eSMark Brown 	{
1491d4e0a89eSMark Brown 		.name = "wm831x-hwmon",
1492d4e0a89eSMark Brown 	},
1493d4e0a89eSMark Brown 	{
1494d4e0a89eSMark Brown 		.name = "wm831x-ldo",
1495d4e0a89eSMark Brown 		.id = 1,
1496d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
1497d4e0a89eSMark Brown 		.resources = wm831x_ldo1_resources,
1498d4e0a89eSMark Brown 	},
1499d4e0a89eSMark Brown 	{
1500d4e0a89eSMark Brown 		.name = "wm831x-ldo",
1501d4e0a89eSMark Brown 		.id = 2,
1502d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
1503d4e0a89eSMark Brown 		.resources = wm831x_ldo2_resources,
1504d4e0a89eSMark Brown 	},
1505d4e0a89eSMark Brown 	{
1506d4e0a89eSMark Brown 		.name = "wm831x-ldo",
1507d4e0a89eSMark Brown 		.id = 3,
1508d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
1509d4e0a89eSMark Brown 		.resources = wm831x_ldo3_resources,
1510d4e0a89eSMark Brown 	},
1511d4e0a89eSMark Brown 	{
1512d4e0a89eSMark Brown 		.name = "wm831x-ldo",
1513d4e0a89eSMark Brown 		.id = 4,
1514d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
1515d4e0a89eSMark Brown 		.resources = wm831x_ldo4_resources,
1516d4e0a89eSMark Brown 	},
1517d4e0a89eSMark Brown 	{
1518d4e0a89eSMark Brown 		.name = "wm831x-ldo",
1519d4e0a89eSMark Brown 		.id = 5,
1520d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
1521d4e0a89eSMark Brown 		.resources = wm831x_ldo5_resources,
1522d4e0a89eSMark Brown 	},
1523d4e0a89eSMark Brown 	{
1524d4e0a89eSMark Brown 		.name = "wm831x-ldo",
1525d4e0a89eSMark Brown 		.id = 6,
1526d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
1527d4e0a89eSMark Brown 		.resources = wm831x_ldo6_resources,
1528d4e0a89eSMark Brown 	},
1529d4e0a89eSMark Brown 	{
1530d4e0a89eSMark Brown 		.name = "wm831x-aldo",
1531d4e0a89eSMark Brown 		.id = 7,
1532d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
1533d4e0a89eSMark Brown 		.resources = wm831x_ldo7_resources,
1534d4e0a89eSMark Brown 	},
1535d4e0a89eSMark Brown 	{
1536d4e0a89eSMark Brown 		.name = "wm831x-aldo",
1537d4e0a89eSMark Brown 		.id = 8,
1538d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
1539d4e0a89eSMark Brown 		.resources = wm831x_ldo8_resources,
1540d4e0a89eSMark Brown 	},
1541d4e0a89eSMark Brown 	{
1542d4e0a89eSMark Brown 		.name = "wm831x-aldo",
1543d4e0a89eSMark Brown 		.id = 9,
1544d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
1545d4e0a89eSMark Brown 		.resources = wm831x_ldo9_resources,
1546d4e0a89eSMark Brown 	},
1547d4e0a89eSMark Brown 	{
1548d4e0a89eSMark Brown 		.name = "wm831x-aldo",
1549d4e0a89eSMark Brown 		.id = 10,
1550d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
1551d4e0a89eSMark Brown 		.resources = wm831x_ldo10_resources,
1552d4e0a89eSMark Brown 	},
1553d4e0a89eSMark Brown 	{
1554d4e0a89eSMark Brown 		.name = "wm831x-alive-ldo",
1555d4e0a89eSMark Brown 		.id = 11,
1556d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
1557d4e0a89eSMark Brown 		.resources = wm831x_ldo11_resources,
1558d4e0a89eSMark Brown 	},
1559d4e0a89eSMark Brown 	{
1560d4e0a89eSMark Brown 		.name = "wm831x-on",
1561d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_on_resources),
1562d4e0a89eSMark Brown 		.resources = wm831x_on_resources,
1563d4e0a89eSMark Brown 	},
1564d4e0a89eSMark Brown 	{
1565d4e0a89eSMark Brown 		.name = "wm831x-status",
1566d4e0a89eSMark Brown 		.id = 1,
1567d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_status1_resources),
1568d4e0a89eSMark Brown 		.resources = wm831x_status1_resources,
1569d4e0a89eSMark Brown 	},
1570d4e0a89eSMark Brown 	{
1571d4e0a89eSMark Brown 		.name = "wm831x-status",
1572d4e0a89eSMark Brown 		.id = 2,
1573d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_status2_resources),
1574d4e0a89eSMark Brown 		.resources = wm831x_status2_resources,
1575d4e0a89eSMark Brown 	},
1576d4e0a89eSMark Brown 	{
1577d4e0a89eSMark Brown 		.name = "wm831x-watchdog",
1578d4e0a89eSMark Brown 		.num_resources = ARRAY_SIZE(wm831x_wdt_resources),
1579d4e0a89eSMark Brown 		.resources = wm831x_wdt_resources,
1580d4e0a89eSMark Brown 	},
1581d4e0a89eSMark Brown };
1582d4e0a89eSMark Brown 
1583ad59de48SGeert Uytterhoeven static const struct mfd_cell touch_devs[] = {
1584266a5e02SMark Brown 	{
1585266a5e02SMark Brown 		.name = "wm831x-touch",
1586266a5e02SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_touch_resources),
1587266a5e02SMark Brown 		.resources = wm831x_touch_resources,
1588266a5e02SMark Brown 	},
1589266a5e02SMark Brown };
1590266a5e02SMark Brown 
1591ad59de48SGeert Uytterhoeven static const struct mfd_cell rtc_devs[] = {
1592b9d03d99SMark Brown 	{
1593b9d03d99SMark Brown 		.name = "wm831x-rtc",
1594b9d03d99SMark Brown 		.num_resources = ARRAY_SIZE(wm831x_rtc_resources),
1595b9d03d99SMark Brown 		.resources = wm831x_rtc_resources,
1596b9d03d99SMark Brown 	},
1597b9d03d99SMark Brown };
1598266a5e02SMark Brown 
1599ad59de48SGeert Uytterhoeven static const struct mfd_cell backlight_devs[] = {
160063aed85eSMark Brown 	{
160163aed85eSMark Brown 		.name = "wm831x-backlight",
160263aed85eSMark Brown 	},
160363aed85eSMark Brown };
160463aed85eSMark Brown 
16051df5981bSMark Brown struct regmap_config wm831x_regmap_config = {
16061df5981bSMark Brown 	.reg_bits = 16,
16071df5981bSMark Brown 	.val_bits = 16,
16082e47fff1SMark Brown 
16097cccbdc8SMark Brown 	.cache_type = REGCACHE_RBTREE,
16107cccbdc8SMark Brown 
16112e47fff1SMark Brown 	.max_register = WM831X_DBE_CHECK_DATA,
16122e47fff1SMark Brown 	.readable_reg = wm831x_reg_readable,
16132e47fff1SMark Brown 	.writeable_reg = wm831x_reg_writeable,
16142e47fff1SMark Brown 	.volatile_reg = wm831x_reg_volatile,
16151df5981bSMark Brown };
16161df5981bSMark Brown EXPORT_SYMBOL_GPL(wm831x_regmap_config);
16171df5981bSMark Brown 
1618f6dd8449SCharles Keepax const struct of_device_id wm831x_of_match[] = {
1619f6dd8449SCharles Keepax 	{ .compatible = "wlf,wm8310", .data = (void *)WM8310 },
1620f6dd8449SCharles Keepax 	{ .compatible = "wlf,wm8311", .data = (void *)WM8311 },
1621f6dd8449SCharles Keepax 	{ .compatible = "wlf,wm8312", .data = (void *)WM8312 },
1622f6dd8449SCharles Keepax 	{ .compatible = "wlf,wm8320", .data = (void *)WM8320 },
1623f6dd8449SCharles Keepax 	{ .compatible = "wlf,wm8321", .data = (void *)WM8321 },
1624f6dd8449SCharles Keepax 	{ .compatible = "wlf,wm8325", .data = (void *)WM8325 },
1625f6dd8449SCharles Keepax 	{ .compatible = "wlf,wm8326", .data = (void *)WM8326 },
1626f6dd8449SCharles Keepax 	{ },
1627f6dd8449SCharles Keepax };
1628f6dd8449SCharles Keepax EXPORT_SYMBOL_GPL(wm831x_of_match);
1629f6dd8449SCharles Keepax 
1630d2bedfe7SMark Brown /*
1631d2bedfe7SMark Brown  * Instantiate the generic non-control parts of the device.
1632d2bedfe7SMark Brown  */
1633f6dd8449SCharles Keepax int wm831x_device_init(struct wm831x *wm831x, int irq)
1634d2bedfe7SMark Brown {
1635f6dd8449SCharles Keepax 	struct wm831x_pdata *pdata = &wm831x->pdata;
1636eb503dc1SMark Brown 	int rev, wm831x_num;
1637d2bedfe7SMark Brown 	enum wm831x_parent parent;
16380b14c22eSMark Brown 	int ret, i;
1639d2bedfe7SMark Brown 
1640d2bedfe7SMark Brown 	mutex_init(&wm831x->io_lock);
1641d2bedfe7SMark Brown 	mutex_init(&wm831x->key_lock);
1642d2bedfe7SMark Brown 	dev_set_drvdata(wm831x->dev, wm831x);
164316dfd103SJavier Martinez Canillas 
1644523d9cfbSMark Brown 	wm831x->soft_shutdown = pdata->soft_shutdown;
1645d2bedfe7SMark Brown 
1646d2bedfe7SMark Brown 	ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
1647d2bedfe7SMark Brown 	if (ret < 0) {
1648d2bedfe7SMark Brown 		dev_err(wm831x->dev, "Failed to read parent ID: %d\n", ret);
1649130a7032SMark Brown 		goto err;
1650d2bedfe7SMark Brown 	}
1651b93cef55SMark Brown 	switch (ret) {
1652b93cef55SMark Brown 	case 0x6204:
1653b93cef55SMark Brown 	case 0x6246:
1654b93cef55SMark Brown 		break;
1655b93cef55SMark Brown 	default:
1656d2bedfe7SMark Brown 		dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret);
1657d2bedfe7SMark Brown 		ret = -EINVAL;
1658130a7032SMark Brown 		goto err;
1659d2bedfe7SMark Brown 	}
1660d2bedfe7SMark Brown 
1661d2bedfe7SMark Brown 	ret = wm831x_reg_read(wm831x, WM831X_REVISION);
1662d2bedfe7SMark Brown 	if (ret < 0) {
1663d2bedfe7SMark Brown 		dev_err(wm831x->dev, "Failed to read revision: %d\n", ret);
1664130a7032SMark Brown 		goto err;
1665d2bedfe7SMark Brown 	}
1666d2bedfe7SMark Brown 	rev = (ret & WM831X_PARENT_REV_MASK) >> WM831X_PARENT_REV_SHIFT;
1667d2bedfe7SMark Brown 
1668d2bedfe7SMark Brown 	ret = wm831x_reg_read(wm831x, WM831X_RESET_ID);
1669d2bedfe7SMark Brown 	if (ret < 0) {
1670d2bedfe7SMark Brown 		dev_err(wm831x->dev, "Failed to read device ID: %d\n", ret);
1671130a7032SMark Brown 		goto err;
1672d2bedfe7SMark Brown 	}
1673d2bedfe7SMark Brown 
1674894362f5SMark Brown 	/* Some engineering samples do not have the ID set, rely on
1675894362f5SMark Brown 	 * the device being registered correctly.
1676d2bedfe7SMark Brown 	 */
1677894362f5SMark Brown 	if (ret == 0) {
1678894362f5SMark Brown 		dev_info(wm831x->dev, "Device is an engineering sample\n");
1679f6dd8449SCharles Keepax 		ret = wm831x->type;
1680d2bedfe7SMark Brown 	}
1681894362f5SMark Brown 
1682894362f5SMark Brown 	switch (ret) {
1683894362f5SMark Brown 	case WM8310:
1684894362f5SMark Brown 		parent = WM8310;
16856f2ecaaeSMark Brown 		wm831x->num_gpio = 16;
1686b03b4d7cSMark Brown 		wm831x->charger_irq_wake = 1;
1687f92e8f81SMark Brown 		if (rev > 0) {
1688f92e8f81SMark Brown 			wm831x->has_gpio_ena = 1;
1689f92e8f81SMark Brown 			wm831x->has_cs_sts = 1;
1690f92e8f81SMark Brown 		}
1691f92e8f81SMark Brown 
1692894362f5SMark Brown 		dev_info(wm831x->dev, "WM8310 revision %c\n", 'A' + rev);
1693894362f5SMark Brown 		break;
1694894362f5SMark Brown 
1695894362f5SMark Brown 	case WM8311:
1696894362f5SMark Brown 		parent = WM8311;
16976f2ecaaeSMark Brown 		wm831x->num_gpio = 16;
1698b03b4d7cSMark Brown 		wm831x->charger_irq_wake = 1;
1699f92e8f81SMark Brown 		if (rev > 0) {
1700f92e8f81SMark Brown 			wm831x->has_gpio_ena = 1;
1701f92e8f81SMark Brown 			wm831x->has_cs_sts = 1;
1702f92e8f81SMark Brown 		}
1703f92e8f81SMark Brown 
1704894362f5SMark Brown 		dev_info(wm831x->dev, "WM8311 revision %c\n", 'A' + rev);
1705894362f5SMark Brown 		break;
1706894362f5SMark Brown 
1707894362f5SMark Brown 	case WM8312:
1708894362f5SMark Brown 		parent = WM8312;
17096f2ecaaeSMark Brown 		wm831x->num_gpio = 16;
1710b03b4d7cSMark Brown 		wm831x->charger_irq_wake = 1;
1711f92e8f81SMark Brown 		if (rev > 0) {
1712f92e8f81SMark Brown 			wm831x->has_gpio_ena = 1;
1713f92e8f81SMark Brown 			wm831x->has_cs_sts = 1;
1714f92e8f81SMark Brown 		}
1715f92e8f81SMark Brown 
1716894362f5SMark Brown 		dev_info(wm831x->dev, "WM8312 revision %c\n", 'A' + rev);
1717d2bedfe7SMark Brown 		break;
1718d2bedfe7SMark Brown 
1719d4e0a89eSMark Brown 	case WM8320:
1720d4e0a89eSMark Brown 		parent = WM8320;
1721d4e0a89eSMark Brown 		wm831x->num_gpio = 12;
1722d4e0a89eSMark Brown 		dev_info(wm831x->dev, "WM8320 revision %c\n", 'A' + rev);
1723d4e0a89eSMark Brown 		break;
1724d4e0a89eSMark Brown 
172588913521SMark Brown 	case WM8321:
172688913521SMark Brown 		parent = WM8321;
172788913521SMark Brown 		wm831x->num_gpio = 12;
172888913521SMark Brown 		dev_info(wm831x->dev, "WM8321 revision %c\n", 'A' + rev);
172988913521SMark Brown 		break;
173088913521SMark Brown 
17310b315884SMark Brown 	case WM8325:
17320b315884SMark Brown 		parent = WM8325;
17330b315884SMark Brown 		wm831x->num_gpio = 12;
17340b315884SMark Brown 		dev_info(wm831x->dev, "WM8325 revision %c\n", 'A' + rev);
17350b315884SMark Brown 		break;
17360b315884SMark Brown 
1737412dc11dSMark Brown 	case WM8326:
1738412dc11dSMark Brown 		parent = WM8326;
1739412dc11dSMark Brown 		wm831x->num_gpio = 12;
1740412dc11dSMark Brown 		dev_info(wm831x->dev, "WM8326 revision %c\n", 'A' + rev);
1741412dc11dSMark Brown 		break;
1742412dc11dSMark Brown 
1743d2bedfe7SMark Brown 	default:
1744d2bedfe7SMark Brown 		dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret);
1745d2bedfe7SMark Brown 		ret = -EINVAL;
1746130a7032SMark Brown 		goto err;
1747d2bedfe7SMark Brown 	}
1748d2bedfe7SMark Brown 
1749d2bedfe7SMark Brown 	/* This will need revisiting in future but is OK for all
1750d2bedfe7SMark Brown 	 * current parts.
1751d2bedfe7SMark Brown 	 */
1752f6dd8449SCharles Keepax 	if (parent != wm831x->type)
1753f6dd8449SCharles Keepax 		dev_warn(wm831x->dev, "Device was registered as a WM%x\n",
1754f6dd8449SCharles Keepax 			 wm831x->type);
1755d2bedfe7SMark Brown 
1756d2bedfe7SMark Brown 	/* Bootstrap the user key */
1757d2bedfe7SMark Brown 	ret = wm831x_reg_read(wm831x, WM831X_SECURITY_KEY);
1758d2bedfe7SMark Brown 	if (ret < 0) {
1759d2bedfe7SMark Brown 		dev_err(wm831x->dev, "Failed to read security key: %d\n", ret);
1760130a7032SMark Brown 		goto err;
1761d2bedfe7SMark Brown 	}
1762d2bedfe7SMark Brown 	if (ret != 0) {
1763d2bedfe7SMark Brown 		dev_warn(wm831x->dev, "Security key had non-zero value %x\n",
1764d2bedfe7SMark Brown 			 ret);
1765d2bedfe7SMark Brown 		wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0);
1766d2bedfe7SMark Brown 	}
1767d2bedfe7SMark Brown 	wm831x->locked = 1;
1768d2bedfe7SMark Brown 
1769dcb0574bSCharles Keepax 	if (pdata->pre_init) {
1770d2bedfe7SMark Brown 		ret = pdata->pre_init(wm831x);
1771d2bedfe7SMark Brown 		if (ret != 0) {
1772d2bedfe7SMark Brown 			dev_err(wm831x->dev, "pre_init() failed: %d\n", ret);
1773130a7032SMark Brown 			goto err;
1774d2bedfe7SMark Brown 		}
1775d2bedfe7SMark Brown 	}
1776d2bedfe7SMark Brown 
17770b14c22eSMark Brown 	for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
17780b14c22eSMark Brown 		if (!pdata->gpio_defaults[i])
17790b14c22eSMark Brown 			continue;
17800b14c22eSMark Brown 
17810b14c22eSMark Brown 		wm831x_reg_write(wm831x,
17820b14c22eSMark Brown 				 WM831X_GPIO1_CONTROL + i,
17830b14c22eSMark Brown 				 pdata->gpio_defaults[i] & 0xffff);
17840b14c22eSMark Brown 	}
17850b14c22eSMark Brown 
1786eb503dc1SMark Brown 	/* Multiply by 10 as we have many subdevices of the same type */
1787dcb0574bSCharles Keepax 	if (pdata->wm831x_num)
1788eb503dc1SMark Brown 		wm831x_num = pdata->wm831x_num * 10;
1789eb503dc1SMark Brown 	else
1790eb503dc1SMark Brown 		wm831x_num = -1;
1791eb503dc1SMark Brown 
17927d4d0a3eSMark Brown 	ret = wm831x_irq_init(wm831x, irq);
17937d4d0a3eSMark Brown 	if (ret != 0)
1794130a7032SMark Brown 		goto err;
17957d4d0a3eSMark Brown 
1796e69b6de1SMark Brown 	wm831x_auxadc_init(wm831x);
1797473fe736SMark Brown 
1798d2bedfe7SMark Brown 	/* The core device is up, instantiate the subdevices. */
1799d2bedfe7SMark Brown 	switch (parent) {
1800d2bedfe7SMark Brown 	case WM8310:
1801eb503dc1SMark Brown 		ret = mfd_add_devices(wm831x->dev, wm831x_num,
1802d2bedfe7SMark Brown 				      wm8310_devs, ARRAY_SIZE(wm8310_devs),
180355692af5SMark Brown 				      NULL, 0, NULL);
1804d2bedfe7SMark Brown 		break;
1805d2bedfe7SMark Brown 
1806d2bedfe7SMark Brown 	case WM8311:
1807eb503dc1SMark Brown 		ret = mfd_add_devices(wm831x->dev, wm831x_num,
1808d2bedfe7SMark Brown 				      wm8311_devs, ARRAY_SIZE(wm8311_devs),
180955692af5SMark Brown 				      NULL, 0, NULL);
1810dcb0574bSCharles Keepax 		if (!pdata->disable_touch)
1811266a5e02SMark Brown 			mfd_add_devices(wm831x->dev, wm831x_num,
1812266a5e02SMark Brown 					touch_devs, ARRAY_SIZE(touch_devs),
181355692af5SMark Brown 					NULL, 0, NULL);
1814d2bedfe7SMark Brown 		break;
1815d2bedfe7SMark Brown 
1816d2bedfe7SMark Brown 	case WM8312:
1817eb503dc1SMark Brown 		ret = mfd_add_devices(wm831x->dev, wm831x_num,
1818d2bedfe7SMark Brown 				      wm8312_devs, ARRAY_SIZE(wm8312_devs),
181955692af5SMark Brown 				      NULL, 0, NULL);
1820dcb0574bSCharles Keepax 		if (!pdata->disable_touch)
1821266a5e02SMark Brown 			mfd_add_devices(wm831x->dev, wm831x_num,
1822266a5e02SMark Brown 					touch_devs, ARRAY_SIZE(touch_devs),
182355692af5SMark Brown 					NULL, 0, NULL);
1824d2bedfe7SMark Brown 		break;
1825d2bedfe7SMark Brown 
1826d4e0a89eSMark Brown 	case WM8320:
182788913521SMark Brown 	case WM8321:
18280b315884SMark Brown 	case WM8325:
1829412dc11dSMark Brown 	case WM8326:
1830eb503dc1SMark Brown 		ret = mfd_add_devices(wm831x->dev, wm831x_num,
18310b315884SMark Brown 				      wm8320_devs, ARRAY_SIZE(wm8320_devs),
183255692af5SMark Brown 				      NULL, 0, NULL);
18330b315884SMark Brown 		break;
18340b315884SMark Brown 
1835d2bedfe7SMark Brown 	default:
1836d2bedfe7SMark Brown 		/* If this happens the bus probe function is buggy */
1837d2bedfe7SMark Brown 		BUG();
1838d2bedfe7SMark Brown 	}
1839d2bedfe7SMark Brown 
1840d2bedfe7SMark Brown 	if (ret != 0) {
1841d2bedfe7SMark Brown 		dev_err(wm831x->dev, "Failed to add children\n");
18427d4d0a3eSMark Brown 		goto err_irq;
1843d2bedfe7SMark Brown 	}
1844d2bedfe7SMark Brown 
1845b9d03d99SMark Brown 	/* The RTC can only be used if the 32.768kHz crystal is
1846b9d03d99SMark Brown 	 * enabled; this can't be controlled by software at runtime.
1847b9d03d99SMark Brown 	 */
1848b9d03d99SMark Brown 	ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_2);
1849b9d03d99SMark Brown 	if (ret < 0) {
1850b9d03d99SMark Brown 		dev_err(wm831x->dev, "Failed to read clock status: %d\n", ret);
1851b9d03d99SMark Brown 		goto err_irq;
1852b9d03d99SMark Brown 	}
1853b9d03d99SMark Brown 
1854b9d03d99SMark Brown 	if (ret & WM831X_XTAL_ENA) {
1855b9d03d99SMark Brown 		ret = mfd_add_devices(wm831x->dev, wm831x_num,
1856b9d03d99SMark Brown 				      rtc_devs, ARRAY_SIZE(rtc_devs),
185755692af5SMark Brown 				      NULL, 0, NULL);
1858b9d03d99SMark Brown 		if (ret != 0) {
1859b9d03d99SMark Brown 			dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret);
1860b9d03d99SMark Brown 			goto err_irq;
1861b9d03d99SMark Brown 		}
1862b9d03d99SMark Brown 	} else {
1863b9d03d99SMark Brown 		dev_info(wm831x->dev, "32.768kHz clock disabled, no RTC\n");
1864b9d03d99SMark Brown 	}
1865b9d03d99SMark Brown 
1866dcb0574bSCharles Keepax 	if (pdata->backlight) {
186763aed85eSMark Brown 		/* Treat errors as non-critical */
1868eb503dc1SMark Brown 		ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs,
18695fb4d38bSMark Brown 				      ARRAY_SIZE(backlight_devs), NULL,
187055692af5SMark Brown 				      0, NULL);
187163aed85eSMark Brown 		if (ret < 0)
187263aed85eSMark Brown 			dev_err(wm831x->dev, "Failed to add backlight: %d\n",
187363aed85eSMark Brown 				ret);
187463aed85eSMark Brown 	}
187563aed85eSMark Brown 
18766704e517SMark Brown 	wm831x_otp_init(wm831x);
18776704e517SMark Brown 
1878dcb0574bSCharles Keepax 	if (pdata->post_init) {
1879d2bedfe7SMark Brown 		ret = pdata->post_init(wm831x);
1880d2bedfe7SMark Brown 		if (ret != 0) {
1881d2bedfe7SMark Brown 			dev_err(wm831x->dev, "post_init() failed: %d\n", ret);
18827d4d0a3eSMark Brown 			goto err_irq;
1883d2bedfe7SMark Brown 		}
1884d2bedfe7SMark Brown 	}
1885d2bedfe7SMark Brown 
1886d2bedfe7SMark Brown 	return 0;
1887d2bedfe7SMark Brown 
18887d4d0a3eSMark Brown err_irq:
18897d4d0a3eSMark Brown 	wm831x_irq_exit(wm831x);
1890130a7032SMark Brown err:
1891d2bedfe7SMark Brown 	mfd_remove_devices(wm831x->dev);
1892d2bedfe7SMark Brown 	return ret;
1893d2bedfe7SMark Brown }
1894d2bedfe7SMark Brown 
1895e5b48684SMark Brown int wm831x_device_suspend(struct wm831x *wm831x)
1896b03b4d7cSMark Brown {
1897b03b4d7cSMark Brown 	int reg, mask;
1898b03b4d7cSMark Brown 
1899b03b4d7cSMark Brown 	/* If the charger IRQs are a wake source then make sure we ack
1900b03b4d7cSMark Brown 	 * them even if they're not actively being used (eg, no power
1901b03b4d7cSMark Brown 	 * driver or no IRQ line wired up) then acknowledge the
1902b03b4d7cSMark Brown 	 * interrupts otherwise suspend won't last very long.
1903b03b4d7cSMark Brown 	 */
1904b03b4d7cSMark Brown 	if (wm831x->charger_irq_wake) {
1905b03b4d7cSMark Brown 		reg = wm831x_reg_read(wm831x, WM831X_INTERRUPT_STATUS_2_MASK);
1906b03b4d7cSMark Brown 
1907b03b4d7cSMark Brown 		mask = WM831X_CHG_BATT_HOT_EINT |
1908b03b4d7cSMark Brown 			WM831X_CHG_BATT_COLD_EINT |
1909b03b4d7cSMark Brown 			WM831X_CHG_BATT_FAIL_EINT |
1910b03b4d7cSMark Brown 			WM831X_CHG_OV_EINT | WM831X_CHG_END_EINT |
1911b03b4d7cSMark Brown 			WM831X_CHG_TO_EINT | WM831X_CHG_MODE_EINT |
1912b03b4d7cSMark Brown 			WM831X_CHG_START_EINT;
1913b03b4d7cSMark Brown 
1914b03b4d7cSMark Brown 		/* If any of the interrupts are masked read the statuses */
1915b03b4d7cSMark Brown 		if (reg & mask)
1916b03b4d7cSMark Brown 			reg = wm831x_reg_read(wm831x,
1917b03b4d7cSMark Brown 					      WM831X_INTERRUPT_STATUS_2);
1918b03b4d7cSMark Brown 
1919b03b4d7cSMark Brown 		if (reg & mask) {
1920b03b4d7cSMark Brown 			dev_info(wm831x->dev,
1921b03b4d7cSMark Brown 				 "Acknowledging masked charger IRQs: %x\n",
1922b03b4d7cSMark Brown 				 reg & mask);
1923b03b4d7cSMark Brown 			wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_2,
1924b03b4d7cSMark Brown 					 reg & mask);
1925b03b4d7cSMark Brown 		}
1926b03b4d7cSMark Brown 	}
1927b03b4d7cSMark Brown 
1928b03b4d7cSMark Brown 	return 0;
1929b03b4d7cSMark Brown }
1930b03b4d7cSMark Brown 
1931523d9cfbSMark Brown void wm831x_device_shutdown(struct wm831x *wm831x)
1932523d9cfbSMark Brown {
1933523d9cfbSMark Brown 	if (wm831x->soft_shutdown) {
1934523d9cfbSMark Brown 		dev_info(wm831x->dev, "Initiating shutdown...\n");
1935523d9cfbSMark Brown 		wm831x_set_bits(wm831x, WM831X_POWER_STATE, WM831X_CHIP_ON, 0);
1936523d9cfbSMark Brown 	}
1937523d9cfbSMark Brown }
1938523d9cfbSMark Brown EXPORT_SYMBOL_GPL(wm831x_device_shutdown);
1939