brintos

brintos / linux-shallow public Read only

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