brintos

brintos / linux-shallow public Read only

0
0
Text · 32.7 KiB · 9939a5d Raw
1331 lines · c
1// SPDX-License-Identifier: GPL-2.0+2//3// wm8350.c  --  Voltage and current regulation for the Wolfson WM8350 PMIC4//5// Copyright 2007, 2008 Wolfson Microelectronics PLC.6//7// Author: Liam Girdwood8//         linux@wolfsonmicro.com9 10#include <linux/module.h>11#include <linux/moduleparam.h>12#include <linux/init.h>13#include <linux/bitops.h>14#include <linux/err.h>15#include <linux/i2c.h>16#include <linux/mfd/wm8350/core.h>17#include <linux/mfd/wm8350/pmic.h>18#include <linux/platform_device.h>19#include <linux/regulator/driver.h>20#include <linux/regulator/machine.h>21 22/* Maximum value possible for VSEL */23#define WM8350_DCDC_MAX_VSEL 0x6624 25/* Microamps */26static const unsigned int isink_cur[] = {27	4,28	5,29	6,30	7,31	8,32	10,33	11,34	14,35	16,36	19,37	23,38	27,39	32,40	39,41	46,42	54,43	65,44	77,45	92,46	109,47	130,48	154,49	183,50	218,51	259,52	308,53	367,54	436,55	518,56	616,57	733,58	872,59	1037,60	1233,61	1466,62	1744,63	2073,64	2466,65	2933,66	3487,67	4147,68	4932,69	5865,70	6975,71	8294,72	9864,73	11730,74	13949,75	16589,76	19728,77	23460,78	27899,79	33178,80	39455,81	46920,82	55798,83	66355,84	78910,85	93840,86	111596,87	132710,88	157820,89	187681,90	22319191};92 93/* turn on ISINK followed by DCDC */94static int wm8350_isink_enable(struct regulator_dev *rdev)95{96	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);97	int isink = rdev_get_id(rdev);98 99	switch (isink) {100	case WM8350_ISINK_A:101		switch (wm8350->pmic.isink_A_dcdc) {102		case WM8350_DCDC_2:103		case WM8350_DCDC_5:104			wm8350_set_bits(wm8350, WM8350_POWER_MGMT_7,105					WM8350_CS1_ENA);106			wm8350_set_bits(wm8350, WM8350_CSA_FLASH_CONTROL,107					WM8350_CS1_DRIVE);108			wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,109					1 << (wm8350->pmic.isink_A_dcdc -110					      WM8350_DCDC_1));111			break;112		default:113			return -EINVAL;114		}115		break;116	case WM8350_ISINK_B:117		switch (wm8350->pmic.isink_B_dcdc) {118		case WM8350_DCDC_2:119		case WM8350_DCDC_5:120			wm8350_set_bits(wm8350, WM8350_POWER_MGMT_7,121					WM8350_CS2_ENA);122			wm8350_set_bits(wm8350, WM8350_CSB_FLASH_CONTROL,123					WM8350_CS2_DRIVE);124			wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,125					1 << (wm8350->pmic.isink_B_dcdc -126					      WM8350_DCDC_1));127			break;128		default:129			return -EINVAL;130		}131		break;132	default:133		return -EINVAL;134	}135	return 0;136}137 138static int wm8350_isink_disable(struct regulator_dev *rdev)139{140	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);141	int isink = rdev_get_id(rdev);142 143	switch (isink) {144	case WM8350_ISINK_A:145		switch (wm8350->pmic.isink_A_dcdc) {146		case WM8350_DCDC_2:147		case WM8350_DCDC_5:148			wm8350_clear_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,149					  1 << (wm8350->pmic.isink_A_dcdc -150						WM8350_DCDC_1));151			wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_7,152					  WM8350_CS1_ENA);153			break;154		default:155			return -EINVAL;156		}157		break;158	case WM8350_ISINK_B:159		switch (wm8350->pmic.isink_B_dcdc) {160		case WM8350_DCDC_2:161		case WM8350_DCDC_5:162			wm8350_clear_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,163					  1 << (wm8350->pmic.isink_B_dcdc -164						WM8350_DCDC_1));165			wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_7,166					  WM8350_CS2_ENA);167			break;168		default:169			return -EINVAL;170		}171		break;172	default:173		return -EINVAL;174	}175	return 0;176}177 178static int wm8350_isink_is_enabled(struct regulator_dev *rdev)179{180	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);181	int isink = rdev_get_id(rdev);182 183	switch (isink) {184	case WM8350_ISINK_A:185		return wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_A) &186		    0x8000;187	case WM8350_ISINK_B:188		return wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_B) &189		    0x8000;190	}191	return -EINVAL;192}193 194static int wm8350_isink_enable_time(struct regulator_dev *rdev)195{196	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);197	int isink = rdev_get_id(rdev);198	int reg;199 200	switch (isink) {201	case WM8350_ISINK_A:202		reg = wm8350_reg_read(wm8350, WM8350_CSA_FLASH_CONTROL);203		break;204	case WM8350_ISINK_B:205		reg = wm8350_reg_read(wm8350, WM8350_CSB_FLASH_CONTROL);206		break;207	default:208		return -EINVAL;209	}210 211	if (reg & WM8350_CS1_FLASH_MODE) {212		switch (reg & WM8350_CS1_ON_RAMP_MASK) {213		case 0:214			return 0;215		case 1:216			return 1950;217		case 2:218			return 3910;219		case 3:220			return 7800;221		}222	} else {223		switch (reg & WM8350_CS1_ON_RAMP_MASK) {224		case 0:225			return 0;226		case 1:227			return 250000;228		case 2:229			return 500000;230		case 3:231			return 1000000;232		}233	}234 235	return -EINVAL;236}237 238 239int wm8350_isink_set_flash(struct wm8350 *wm8350, int isink, u16 mode,240			   u16 trigger, u16 duration, u16 on_ramp, u16 off_ramp,241			   u16 drive)242{243	switch (isink) {244	case WM8350_ISINK_A:245		wm8350_reg_write(wm8350, WM8350_CSA_FLASH_CONTROL,246				 (mode ? WM8350_CS1_FLASH_MODE : 0) |247				 (trigger ? WM8350_CS1_TRIGSRC : 0) |248				 duration | on_ramp | off_ramp | drive);249		break;250	case WM8350_ISINK_B:251		wm8350_reg_write(wm8350, WM8350_CSB_FLASH_CONTROL,252				 (mode ? WM8350_CS2_FLASH_MODE : 0) |253				 (trigger ? WM8350_CS2_TRIGSRC : 0) |254				 duration | on_ramp | off_ramp | drive);255		break;256	default:257		return -EINVAL;258	}259	return 0;260}261EXPORT_SYMBOL_GPL(wm8350_isink_set_flash);262 263static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV)264{265	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);266	int sel, volt_reg, dcdc = rdev_get_id(rdev);267	u16 val;268 269	dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, dcdc, uV / 1000);270 271	switch (dcdc) {272	case WM8350_DCDC_1:273		volt_reg = WM8350_DCDC1_LOW_POWER;274		break;275	case WM8350_DCDC_3:276		volt_reg = WM8350_DCDC3_LOW_POWER;277		break;278	case WM8350_DCDC_4:279		volt_reg = WM8350_DCDC4_LOW_POWER;280		break;281	case WM8350_DCDC_6:282		volt_reg = WM8350_DCDC6_LOW_POWER;283		break;284	case WM8350_DCDC_2:285	case WM8350_DCDC_5:286	default:287		return -EINVAL;288	}289 290	sel = regulator_map_voltage_linear(rdev, uV, uV);291	if (sel < 0)292		return sel;293 294	/* all DCDCs have same mV bits */295	val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_DC1_VSEL_MASK;296	wm8350_reg_write(wm8350, volt_reg, val | sel);297	return 0;298}299 300static int wm8350_dcdc_set_suspend_enable(struct regulator_dev *rdev)301{302	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);303	int dcdc = rdev_get_id(rdev);304	u16 val;305 306	switch (dcdc) {307	case WM8350_DCDC_1:308		val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER)309			& ~WM8350_DCDC_HIB_MODE_MASK;310		wm8350_reg_write(wm8350, WM8350_DCDC1_LOW_POWER,311			val | wm8350->pmic.dcdc1_hib_mode);312		break;313	case WM8350_DCDC_3:314		val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER)315			& ~WM8350_DCDC_HIB_MODE_MASK;316		wm8350_reg_write(wm8350, WM8350_DCDC3_LOW_POWER,317			val | wm8350->pmic.dcdc3_hib_mode);318		break;319	case WM8350_DCDC_4:320		val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER)321			& ~WM8350_DCDC_HIB_MODE_MASK;322		wm8350_reg_write(wm8350, WM8350_DCDC4_LOW_POWER,323			val | wm8350->pmic.dcdc4_hib_mode);324		break;325	case WM8350_DCDC_6:326		val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER)327			& ~WM8350_DCDC_HIB_MODE_MASK;328		wm8350_reg_write(wm8350, WM8350_DCDC6_LOW_POWER,329			val | wm8350->pmic.dcdc6_hib_mode);330		break;331	case WM8350_DCDC_2:332	case WM8350_DCDC_5:333	default:334		return -EINVAL;335	}336 337	return 0;338}339 340static int wm8350_dcdc_set_suspend_disable(struct regulator_dev *rdev)341{342	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);343	int dcdc = rdev_get_id(rdev);344	u16 val;345 346	switch (dcdc) {347	case WM8350_DCDC_1:348		val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER);349		wm8350->pmic.dcdc1_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;350		wm8350_reg_write(wm8350, WM8350_DCDC1_LOW_POWER,351				 val | WM8350_DCDC_HIB_MODE_DIS);352		break;353	case WM8350_DCDC_3:354		val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER);355		wm8350->pmic.dcdc3_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;356		wm8350_reg_write(wm8350, WM8350_DCDC3_LOW_POWER,357				 val | WM8350_DCDC_HIB_MODE_DIS);358		break;359	case WM8350_DCDC_4:360		val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER);361		wm8350->pmic.dcdc4_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;362		wm8350_reg_write(wm8350, WM8350_DCDC4_LOW_POWER,363				 val | WM8350_DCDC_HIB_MODE_DIS);364		break;365	case WM8350_DCDC_6:366		val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER);367		wm8350->pmic.dcdc6_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;368		wm8350_reg_write(wm8350, WM8350_DCDC6_LOW_POWER,369				 val | WM8350_DCDC_HIB_MODE_DIS);370		break;371	case WM8350_DCDC_2:372	case WM8350_DCDC_5:373	default:374		return -EINVAL;375	}376 377	return 0;378}379 380static int wm8350_dcdc25_set_suspend_enable(struct regulator_dev *rdev)381{382	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);383	int dcdc = rdev_get_id(rdev);384	u16 val;385 386	switch (dcdc) {387	case WM8350_DCDC_2:388		val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL)389		    & ~WM8350_DC2_HIB_MODE_MASK;390		wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val |391		    (WM8350_DC2_HIB_MODE_ACTIVE << WM8350_DC2_HIB_MODE_SHIFT));392		break;393	case WM8350_DCDC_5:394		val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL)395		    & ~WM8350_DC5_HIB_MODE_MASK;396		wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val |397		    (WM8350_DC5_HIB_MODE_ACTIVE << WM8350_DC5_HIB_MODE_SHIFT));398		break;399	default:400		return -EINVAL;401	}402	return 0;403}404 405static int wm8350_dcdc25_set_suspend_disable(struct regulator_dev *rdev)406{407	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);408	int dcdc = rdev_get_id(rdev);409	u16 val;410 411	switch (dcdc) {412	case WM8350_DCDC_2:413		val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL)414		    & ~WM8350_DC2_HIB_MODE_MASK;415		wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val |416		    (WM8350_DC2_HIB_MODE_DISABLE << WM8350_DC2_HIB_MODE_SHIFT));417		break;418	case WM8350_DCDC_5:419		val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL)420		    & ~WM8350_DC5_HIB_MODE_MASK;421		wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val |422		    (WM8350_DC5_HIB_MODE_DISABLE << WM8350_DC5_HIB_MODE_SHIFT));423		break;424	default:425		return -EINVAL;426	}427	return 0;428}429 430static int wm8350_dcdc_set_suspend_mode(struct regulator_dev *rdev,431	unsigned int mode)432{433	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);434	int dcdc = rdev_get_id(rdev);435	u16 *hib_mode;436 437	switch (dcdc) {438	case WM8350_DCDC_1:439		hib_mode = &wm8350->pmic.dcdc1_hib_mode;440		break;441	case WM8350_DCDC_3:442		hib_mode = &wm8350->pmic.dcdc3_hib_mode;443		break;444	case WM8350_DCDC_4:445		hib_mode = &wm8350->pmic.dcdc4_hib_mode;446		break;447	case WM8350_DCDC_6:448		hib_mode = &wm8350->pmic.dcdc6_hib_mode;449		break;450	case WM8350_DCDC_2:451	case WM8350_DCDC_5:452	default:453		return -EINVAL;454	}455 456	switch (mode) {457	case REGULATOR_MODE_NORMAL:458		*hib_mode = WM8350_DCDC_HIB_MODE_IMAGE;459		break;460	case REGULATOR_MODE_IDLE:461		*hib_mode = WM8350_DCDC_HIB_MODE_STANDBY;462		break;463	case REGULATOR_MODE_STANDBY:464		*hib_mode = WM8350_DCDC_HIB_MODE_LDO_IM;465		break;466	default:467		return -EINVAL;468	}469 470	return 0;471}472 473static const struct linear_range wm8350_ldo_ranges[] = {474	REGULATOR_LINEAR_RANGE(900000, 0, 15, 50000),475	REGULATOR_LINEAR_RANGE(1800000, 16, 31, 100000),476};477 478static int wm8350_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV)479{480	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);481	int sel, volt_reg, ldo = rdev_get_id(rdev);482	u16 val;483 484	dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, ldo, uV / 1000);485 486	switch (ldo) {487	case WM8350_LDO_1:488		volt_reg = WM8350_LDO1_LOW_POWER;489		break;490	case WM8350_LDO_2:491		volt_reg = WM8350_LDO2_LOW_POWER;492		break;493	case WM8350_LDO_3:494		volt_reg = WM8350_LDO3_LOW_POWER;495		break;496	case WM8350_LDO_4:497		volt_reg = WM8350_LDO4_LOW_POWER;498		break;499	default:500		return -EINVAL;501	}502 503	sel = regulator_map_voltage_linear_range(rdev, uV, uV);504	if (sel < 0)505		return sel;506 507	/* all LDOs have same mV bits */508	val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_VSEL_MASK;509	wm8350_reg_write(wm8350, volt_reg, val | sel);510	return 0;511}512 513static int wm8350_ldo_set_suspend_enable(struct regulator_dev *rdev)514{515	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);516	int volt_reg, ldo = rdev_get_id(rdev);517	u16 val;518 519	switch (ldo) {520	case WM8350_LDO_1:521		volt_reg = WM8350_LDO1_LOW_POWER;522		break;523	case WM8350_LDO_2:524		volt_reg = WM8350_LDO2_LOW_POWER;525		break;526	case WM8350_LDO_3:527		volt_reg = WM8350_LDO3_LOW_POWER;528		break;529	case WM8350_LDO_4:530		volt_reg = WM8350_LDO4_LOW_POWER;531		break;532	default:533		return -EINVAL;534	}535 536	/* all LDOs have same mV bits */537	val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_HIB_MODE_MASK;538	wm8350_reg_write(wm8350, volt_reg, val);539	return 0;540}541 542static int wm8350_ldo_set_suspend_disable(struct regulator_dev *rdev)543{544	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);545	int volt_reg, ldo = rdev_get_id(rdev);546	u16 val;547 548	switch (ldo) {549	case WM8350_LDO_1:550		volt_reg = WM8350_LDO1_LOW_POWER;551		break;552	case WM8350_LDO_2:553		volt_reg = WM8350_LDO2_LOW_POWER;554		break;555	case WM8350_LDO_3:556		volt_reg = WM8350_LDO3_LOW_POWER;557		break;558	case WM8350_LDO_4:559		volt_reg = WM8350_LDO4_LOW_POWER;560		break;561	default:562		return -EINVAL;563	}564 565	/* all LDOs have same mV bits */566	val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_HIB_MODE_MASK;567	wm8350_reg_write(wm8350, volt_reg, val | WM8350_LDO1_HIB_MODE_DIS);568	return 0;569}570 571int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start,572			 u16 stop, u16 fault)573{574	int slot_reg;575	u16 val;576 577	dev_dbg(wm8350->dev, "%s %d start %d stop %d\n",578		__func__, dcdc, start, stop);579 580	/* slot valid ? */581	if (start > 15 || stop > 15)582		return -EINVAL;583 584	switch (dcdc) {585	case WM8350_DCDC_1:586		slot_reg = WM8350_DCDC1_TIMEOUTS;587		break;588	case WM8350_DCDC_2:589		slot_reg = WM8350_DCDC2_TIMEOUTS;590		break;591	case WM8350_DCDC_3:592		slot_reg = WM8350_DCDC3_TIMEOUTS;593		break;594	case WM8350_DCDC_4:595		slot_reg = WM8350_DCDC4_TIMEOUTS;596		break;597	case WM8350_DCDC_5:598		slot_reg = WM8350_DCDC5_TIMEOUTS;599		break;600	case WM8350_DCDC_6:601		slot_reg = WM8350_DCDC6_TIMEOUTS;602		break;603	default:604		return -EINVAL;605	}606 607	val = wm8350_reg_read(wm8350, slot_reg) &608	    ~(WM8350_DC1_ENSLOT_MASK | WM8350_DC1_SDSLOT_MASK |609	      WM8350_DC1_ERRACT_MASK);610	wm8350_reg_write(wm8350, slot_reg,611			 val | (start << WM8350_DC1_ENSLOT_SHIFT) |612			 (stop << WM8350_DC1_SDSLOT_SHIFT) |613			 (fault << WM8350_DC1_ERRACT_SHIFT));614 615	return 0;616}617EXPORT_SYMBOL_GPL(wm8350_dcdc_set_slot);618 619int wm8350_ldo_set_slot(struct wm8350 *wm8350, int ldo, u16 start, u16 stop)620{621	int slot_reg;622	u16 val;623 624	dev_dbg(wm8350->dev, "%s %d start %d stop %d\n",625		__func__, ldo, start, stop);626 627	/* slot valid ? */628	if (start > 15 || stop > 15)629		return -EINVAL;630 631	switch (ldo) {632	case WM8350_LDO_1:633		slot_reg = WM8350_LDO1_TIMEOUTS;634		break;635	case WM8350_LDO_2:636		slot_reg = WM8350_LDO2_TIMEOUTS;637		break;638	case WM8350_LDO_3:639		slot_reg = WM8350_LDO3_TIMEOUTS;640		break;641	case WM8350_LDO_4:642		slot_reg = WM8350_LDO4_TIMEOUTS;643		break;644	default:645		return -EINVAL;646	}647 648	val = wm8350_reg_read(wm8350, slot_reg) & ~WM8350_LDO1_SDSLOT_MASK;649	wm8350_reg_write(wm8350, slot_reg, val | ((start << 10) | (stop << 6)));650	return 0;651}652EXPORT_SYMBOL_GPL(wm8350_ldo_set_slot);653 654int wm8350_dcdc25_set_mode(struct wm8350 *wm8350, int dcdc, u16 mode,655			   u16 ilim, u16 ramp, u16 feedback)656{657	u16 val;658 659	dev_dbg(wm8350->dev, "%s %d mode: %s %s\n", __func__, dcdc,660		mode ? "normal" : "boost", ilim ? "low" : "normal");661 662	switch (dcdc) {663	case WM8350_DCDC_2:664		val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL)665		    & ~(WM8350_DC2_MODE_MASK | WM8350_DC2_ILIM_MASK |666			WM8350_DC2_RMP_MASK | WM8350_DC2_FBSRC_MASK);667		wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val |668				 (mode << WM8350_DC2_MODE_SHIFT) |669				 (ilim << WM8350_DC2_ILIM_SHIFT) |670				 (ramp << WM8350_DC2_RMP_SHIFT) |671				 (feedback << WM8350_DC2_FBSRC_SHIFT));672		break;673	case WM8350_DCDC_5:674		val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL)675		    & ~(WM8350_DC5_MODE_MASK | WM8350_DC5_ILIM_MASK |676			WM8350_DC5_RMP_MASK | WM8350_DC5_FBSRC_MASK);677		wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val |678				 (mode << WM8350_DC5_MODE_SHIFT) |679				 (ilim << WM8350_DC5_ILIM_SHIFT) |680				 (ramp << WM8350_DC5_RMP_SHIFT) |681				 (feedback << WM8350_DC5_FBSRC_SHIFT));682		break;683	default:684		return -EINVAL;685	}686 687	return 0;688}689EXPORT_SYMBOL_GPL(wm8350_dcdc25_set_mode);690 691static int force_continuous_enable(struct wm8350 *wm8350, int dcdc, int enable)692{693	int reg = 0, ret;694 695	switch (dcdc) {696	case WM8350_DCDC_1:697		reg = WM8350_DCDC1_FORCE_PWM;698		break;699	case WM8350_DCDC_3:700		reg = WM8350_DCDC3_FORCE_PWM;701		break;702	case WM8350_DCDC_4:703		reg = WM8350_DCDC4_FORCE_PWM;704		break;705	case WM8350_DCDC_6:706		reg = WM8350_DCDC6_FORCE_PWM;707		break;708	default:709		return -EINVAL;710	}711 712	if (enable)713		ret = wm8350_set_bits(wm8350, reg,714			WM8350_DCDC1_FORCE_PWM_ENA);715	else716		ret = wm8350_clear_bits(wm8350, reg,717			WM8350_DCDC1_FORCE_PWM_ENA);718	return ret;719}720 721static int wm8350_dcdc_set_mode(struct regulator_dev *rdev, unsigned int mode)722{723	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);724	int dcdc = rdev_get_id(rdev);725	u16 val;726 727	if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6)728		return -EINVAL;729 730	if (dcdc == WM8350_DCDC_2 || dcdc == WM8350_DCDC_5)731		return -EINVAL;732 733	val = 1 << (dcdc - WM8350_DCDC_1);734 735	switch (mode) {736	case REGULATOR_MODE_FAST:737		/* force continuous mode */738		wm8350_set_bits(wm8350, WM8350_DCDC_ACTIVE_OPTIONS, val);739		wm8350_clear_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val);740		force_continuous_enable(wm8350, dcdc, 1);741		break;742	case REGULATOR_MODE_NORMAL:743		/* active / pulse skipping */744		wm8350_set_bits(wm8350, WM8350_DCDC_ACTIVE_OPTIONS, val);745		wm8350_clear_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val);746		force_continuous_enable(wm8350, dcdc, 0);747		break;748	case REGULATOR_MODE_IDLE:749		/* standby mode */750		force_continuous_enable(wm8350, dcdc, 0);751		wm8350_clear_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val);752		wm8350_clear_bits(wm8350, WM8350_DCDC_ACTIVE_OPTIONS, val);753		break;754	case REGULATOR_MODE_STANDBY:755		/* LDO mode */756		force_continuous_enable(wm8350, dcdc, 0);757		wm8350_set_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val);758		break;759	}760 761	return 0;762}763 764static unsigned int wm8350_dcdc_get_mode(struct regulator_dev *rdev)765{766	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);767	int dcdc = rdev_get_id(rdev);768	u16 mask, sleep, active, force;769	int mode = REGULATOR_MODE_NORMAL;770	int reg;771 772	switch (dcdc) {773	case WM8350_DCDC_1:774		reg = WM8350_DCDC1_FORCE_PWM;775		break;776	case WM8350_DCDC_3:777		reg = WM8350_DCDC3_FORCE_PWM;778		break;779	case WM8350_DCDC_4:780		reg = WM8350_DCDC4_FORCE_PWM;781		break;782	case WM8350_DCDC_6:783		reg = WM8350_DCDC6_FORCE_PWM;784		break;785	default:786		return -EINVAL;787	}788 789	mask = 1 << (dcdc - WM8350_DCDC_1);790	active = wm8350_reg_read(wm8350, WM8350_DCDC_ACTIVE_OPTIONS) & mask;791	force = wm8350_reg_read(wm8350, reg) & WM8350_DCDC1_FORCE_PWM_ENA;792	sleep = wm8350_reg_read(wm8350, WM8350_DCDC_SLEEP_OPTIONS) & mask;793 794	dev_dbg(wm8350->dev, "mask %x active %x sleep %x force %x",795		mask, active, sleep, force);796 797	if (active && !sleep) {798		if (force)799			mode = REGULATOR_MODE_FAST;800		else801			mode = REGULATOR_MODE_NORMAL;802	} else if (!active && !sleep)803		mode = REGULATOR_MODE_IDLE;804	else if (sleep)805		mode = REGULATOR_MODE_STANDBY;806 807	return mode;808}809 810static unsigned int wm8350_ldo_get_mode(struct regulator_dev *rdev)811{812	return REGULATOR_MODE_NORMAL;813}814 815struct wm8350_dcdc_efficiency {816	int uA_load_min;817	int uA_load_max;818	unsigned int mode;819};820 821static const struct wm8350_dcdc_efficiency dcdc1_6_efficiency[] = {822	{0, 10000, REGULATOR_MODE_STANDBY},       /* 0 - 10mA - LDO */823	{10000, 100000, REGULATOR_MODE_IDLE},     /* 10mA - 100mA - Standby */824	{100000, 1000000, REGULATOR_MODE_NORMAL}, /* > 100mA - Active */825	{-1, -1, REGULATOR_MODE_NORMAL},826};827 828static const struct wm8350_dcdc_efficiency dcdc3_4_efficiency[] = {829	{0, 10000, REGULATOR_MODE_STANDBY},      /* 0 - 10mA - LDO */830	{10000, 100000, REGULATOR_MODE_IDLE},    /* 10mA - 100mA - Standby */831	{100000, 800000, REGULATOR_MODE_NORMAL}, /* > 100mA - Active */832	{-1, -1, REGULATOR_MODE_NORMAL},833};834 835static unsigned int get_mode(int uA, const struct wm8350_dcdc_efficiency *eff)836{837	int i = 0;838 839	while (eff[i].uA_load_min != -1) {840		if (uA >= eff[i].uA_load_min && uA <= eff[i].uA_load_max)841			return eff[i].mode;842		i++;843	}844	return REGULATOR_MODE_NORMAL;845}846 847/* Query the regulator for it's most efficient mode @ uV,uA848 * WM8350 regulator efficiency is pretty similar over849 * different input and output uV.850 */851static unsigned int wm8350_dcdc_get_optimum_mode(struct regulator_dev *rdev,852						 int input_uV, int output_uV,853						 int output_uA)854{855	int dcdc = rdev_get_id(rdev), mode;856 857	switch (dcdc) {858	case WM8350_DCDC_1:859	case WM8350_DCDC_6:860		mode = get_mode(output_uA, dcdc1_6_efficiency);861		break;862	case WM8350_DCDC_3:863	case WM8350_DCDC_4:864		mode = get_mode(output_uA, dcdc3_4_efficiency);865		break;866	default:867		mode = REGULATOR_MODE_NORMAL;868		break;869	}870	return mode;871}872 873static const struct regulator_ops wm8350_dcdc_ops = {874	.set_voltage_sel = regulator_set_voltage_sel_regmap,875	.get_voltage_sel = regulator_get_voltage_sel_regmap,876	.list_voltage = regulator_list_voltage_linear,877	.map_voltage = regulator_map_voltage_linear,878	.enable = regulator_enable_regmap,879	.disable = regulator_disable_regmap,880	.is_enabled = regulator_is_enabled_regmap,881	.get_mode = wm8350_dcdc_get_mode,882	.set_mode = wm8350_dcdc_set_mode,883	.get_optimum_mode = wm8350_dcdc_get_optimum_mode,884	.set_suspend_voltage = wm8350_dcdc_set_suspend_voltage,885	.set_suspend_enable = wm8350_dcdc_set_suspend_enable,886	.set_suspend_disable = wm8350_dcdc_set_suspend_disable,887	.set_suspend_mode = wm8350_dcdc_set_suspend_mode,888};889 890static const struct regulator_ops wm8350_dcdc2_5_ops = {891	.enable = regulator_enable_regmap,892	.disable = regulator_disable_regmap,893	.is_enabled = regulator_is_enabled_regmap,894	.set_suspend_enable = wm8350_dcdc25_set_suspend_enable,895	.set_suspend_disable = wm8350_dcdc25_set_suspend_disable,896};897 898static const struct regulator_ops wm8350_ldo_ops = {899	.map_voltage = regulator_map_voltage_linear_range,900	.set_voltage_sel = regulator_set_voltage_sel_regmap,901	.get_voltage_sel = regulator_get_voltage_sel_regmap,902	.list_voltage = regulator_list_voltage_linear_range,903	.enable = regulator_enable_regmap,904	.disable = regulator_disable_regmap,905	.is_enabled = regulator_is_enabled_regmap,906	.get_mode = wm8350_ldo_get_mode,907	.set_suspend_voltage = wm8350_ldo_set_suspend_voltage,908	.set_suspend_enable = wm8350_ldo_set_suspend_enable,909	.set_suspend_disable = wm8350_ldo_set_suspend_disable,910};911 912static const struct regulator_ops wm8350_isink_ops = {913	.set_current_limit = regulator_set_current_limit_regmap,914	.get_current_limit = regulator_get_current_limit_regmap,915	.enable = wm8350_isink_enable,916	.disable = wm8350_isink_disable,917	.is_enabled = wm8350_isink_is_enabled,918	.enable_time = wm8350_isink_enable_time,919};920 921static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {922	{923		.name = "DCDC1",924		.id = WM8350_DCDC_1,925		.ops = &wm8350_dcdc_ops,926		.irq = WM8350_IRQ_UV_DC1,927		.type = REGULATOR_VOLTAGE,928		.n_voltages = WM8350_DCDC_MAX_VSEL + 1,929		.min_uV = 850000,930		.uV_step = 25000,931		.vsel_reg = WM8350_DCDC1_CONTROL,932		.vsel_mask = WM8350_DC1_VSEL_MASK,933		.enable_reg = WM8350_DCDC_LDO_REQUESTED,934		.enable_mask = WM8350_DC1_ENA,935		.owner = THIS_MODULE,936	},937	{938		.name = "DCDC2",939		.id = WM8350_DCDC_2,940		.ops = &wm8350_dcdc2_5_ops,941		.irq = WM8350_IRQ_UV_DC2,942		.type = REGULATOR_VOLTAGE,943		.enable_reg = WM8350_DCDC_LDO_REQUESTED,944		.enable_mask = WM8350_DC2_ENA,945		.owner = THIS_MODULE,946	},947	{948		.name = "DCDC3",949		.id = WM8350_DCDC_3,950		.ops = &wm8350_dcdc_ops,951		.irq = WM8350_IRQ_UV_DC3,952		.type = REGULATOR_VOLTAGE,953		.n_voltages = WM8350_DCDC_MAX_VSEL + 1,954		.min_uV = 850000,955		.uV_step = 25000,956		.vsel_reg = WM8350_DCDC3_CONTROL,957		.vsel_mask = WM8350_DC3_VSEL_MASK,958		.enable_reg = WM8350_DCDC_LDO_REQUESTED,959		.enable_mask = WM8350_DC3_ENA,960		.owner = THIS_MODULE,961	},962	{963		.name = "DCDC4",964		.id = WM8350_DCDC_4,965		.ops = &wm8350_dcdc_ops,966		.irq = WM8350_IRQ_UV_DC4,967		.type = REGULATOR_VOLTAGE,968		.n_voltages = WM8350_DCDC_MAX_VSEL + 1,969		.min_uV = 850000,970		.uV_step = 25000,971		.vsel_reg = WM8350_DCDC4_CONTROL,972		.vsel_mask = WM8350_DC4_VSEL_MASK,973		.enable_reg = WM8350_DCDC_LDO_REQUESTED,974		.enable_mask = WM8350_DC4_ENA,975		.owner = THIS_MODULE,976	},977	{978		.name = "DCDC5",979		.id = WM8350_DCDC_5,980		.ops = &wm8350_dcdc2_5_ops,981		.irq = WM8350_IRQ_UV_DC5,982		.type = REGULATOR_VOLTAGE,983		.enable_reg = WM8350_DCDC_LDO_REQUESTED,984		.enable_mask = WM8350_DC5_ENA,985		.owner = THIS_MODULE,986	 },987	{988		.name = "DCDC6",989		.id = WM8350_DCDC_6,990		.ops = &wm8350_dcdc_ops,991		.irq = WM8350_IRQ_UV_DC6,992		.type = REGULATOR_VOLTAGE,993		.n_voltages = WM8350_DCDC_MAX_VSEL + 1,994		.min_uV = 850000,995		.uV_step = 25000,996		.vsel_reg = WM8350_DCDC6_CONTROL,997		.vsel_mask = WM8350_DC6_VSEL_MASK,998		.enable_reg = WM8350_DCDC_LDO_REQUESTED,999		.enable_mask = WM8350_DC6_ENA,1000		.owner = THIS_MODULE,1001	},1002	{1003		.name = "LDO1",1004		.id = WM8350_LDO_1,1005		.ops = &wm8350_ldo_ops,1006		.irq = WM8350_IRQ_UV_LDO1,1007		.type = REGULATOR_VOLTAGE,1008		.n_voltages = WM8350_LDO1_VSEL_MASK + 1,1009		.linear_ranges = wm8350_ldo_ranges,1010		.n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),1011		.vsel_reg = WM8350_LDO1_CONTROL,1012		.vsel_mask = WM8350_LDO1_VSEL_MASK,1013		.enable_reg = WM8350_DCDC_LDO_REQUESTED,1014		.enable_mask = WM8350_LDO1_ENA,1015		.owner = THIS_MODULE,1016	},1017	{1018		.name = "LDO2",1019		.id = WM8350_LDO_2,1020		.ops = &wm8350_ldo_ops,1021		.irq = WM8350_IRQ_UV_LDO2,1022		.type = REGULATOR_VOLTAGE,1023		.n_voltages = WM8350_LDO2_VSEL_MASK + 1,1024		.linear_ranges = wm8350_ldo_ranges,1025		.n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),1026		.vsel_reg = WM8350_LDO2_CONTROL,1027		.vsel_mask = WM8350_LDO2_VSEL_MASK,1028		.enable_reg = WM8350_DCDC_LDO_REQUESTED,1029		.enable_mask = WM8350_LDO2_ENA,1030		.owner = THIS_MODULE,1031	},1032	{1033		.name = "LDO3",1034		.id = WM8350_LDO_3,1035		.ops = &wm8350_ldo_ops,1036		.irq = WM8350_IRQ_UV_LDO3,1037		.type = REGULATOR_VOLTAGE,1038		.n_voltages = WM8350_LDO3_VSEL_MASK + 1,1039		.linear_ranges = wm8350_ldo_ranges,1040		.n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),1041		.vsel_reg = WM8350_LDO3_CONTROL,1042		.vsel_mask = WM8350_LDO3_VSEL_MASK,1043		.enable_reg = WM8350_DCDC_LDO_REQUESTED,1044		.enable_mask = WM8350_LDO3_ENA,1045		.owner = THIS_MODULE,1046	},1047	{1048		.name = "LDO4",1049		.id = WM8350_LDO_4,1050		.ops = &wm8350_ldo_ops,1051		.irq = WM8350_IRQ_UV_LDO4,1052		.type = REGULATOR_VOLTAGE,1053		.n_voltages = WM8350_LDO4_VSEL_MASK + 1,1054		.linear_ranges = wm8350_ldo_ranges,1055		.n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),1056		.vsel_reg = WM8350_LDO4_CONTROL,1057		.vsel_mask = WM8350_LDO4_VSEL_MASK,1058		.enable_reg = WM8350_DCDC_LDO_REQUESTED,1059		.enable_mask = WM8350_LDO4_ENA,1060		.owner = THIS_MODULE,1061	},1062	{1063		.name = "ISINKA",1064		.id = WM8350_ISINK_A,1065		.ops = &wm8350_isink_ops,1066		.irq = WM8350_IRQ_CS1,1067		.type = REGULATOR_CURRENT,1068		.owner = THIS_MODULE,1069		.curr_table = isink_cur,1070		.n_current_limits = ARRAY_SIZE(isink_cur),1071		.csel_reg = WM8350_CURRENT_SINK_DRIVER_A,1072		.csel_mask = WM8350_CS1_ISEL_MASK,1073	 },1074	{1075		.name = "ISINKB",1076		.id = WM8350_ISINK_B,1077		.ops = &wm8350_isink_ops,1078		.irq = WM8350_IRQ_CS2,1079		.type = REGULATOR_CURRENT,1080		.owner = THIS_MODULE,1081		.curr_table = isink_cur,1082		.n_current_limits = ARRAY_SIZE(isink_cur),1083		.csel_reg = WM8350_CURRENT_SINK_DRIVER_B,1084		.csel_mask = WM8350_CS2_ISEL_MASK,1085	 },1086};1087 1088static irqreturn_t pmic_uv_handler(int irq, void *data)1089{1090	struct regulator_dev *rdev = (struct regulator_dev *)data;1091 1092	if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)1093		regulator_notifier_call_chain(rdev,1094					      REGULATOR_EVENT_REGULATION_OUT,1095					      NULL);1096	else1097		regulator_notifier_call_chain(rdev,1098					      REGULATOR_EVENT_UNDER_VOLTAGE,1099					      NULL);1100 1101	return IRQ_HANDLED;1102}1103 1104static int wm8350_regulator_probe(struct platform_device *pdev)1105{1106	struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev);1107	struct regulator_config config = { };1108	struct regulator_dev *rdev;1109	int ret;1110	u16 val;1111 1112	if (pdev->id < WM8350_DCDC_1 || pdev->id > WM8350_ISINK_B)1113		return -ENODEV;1114 1115	/* do any regulator specific init */1116	switch (pdev->id) {1117	case WM8350_DCDC_1:1118		val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER);1119		wm8350->pmic.dcdc1_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;1120		break;1121	case WM8350_DCDC_3:1122		val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER);1123		wm8350->pmic.dcdc3_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;1124		break;1125	case WM8350_DCDC_4:1126		val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER);1127		wm8350->pmic.dcdc4_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;1128		break;1129	case WM8350_DCDC_6:1130		val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER);1131		wm8350->pmic.dcdc6_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;1132		break;1133	}1134 1135	config.dev = &pdev->dev;1136	config.init_data = dev_get_platdata(&pdev->dev);1137	config.driver_data = dev_get_drvdata(&pdev->dev);1138	config.regmap = wm8350->regmap;1139 1140	/* register regulator */1141	rdev = devm_regulator_register(&pdev->dev, &wm8350_reg[pdev->id],1142				       &config);1143	if (IS_ERR(rdev)) {1144		dev_err(&pdev->dev, "failed to register %s\n",1145			wm8350_reg[pdev->id].name);1146		return PTR_ERR(rdev);1147	}1148 1149	/* register regulator IRQ */1150	ret = wm8350_register_irq(wm8350, wm8350_reg[pdev->id].irq,1151				  pmic_uv_handler, 0, "UV", rdev);1152	if (ret < 0) {1153		dev_err(&pdev->dev, "failed to register regulator %s IRQ\n",1154			wm8350_reg[pdev->id].name);1155		return ret;1156	}1157 1158	return 0;1159}1160 1161static void wm8350_regulator_remove(struct platform_device *pdev)1162{1163	struct regulator_dev *rdev = platform_get_drvdata(pdev);1164	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);1165 1166	wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq, rdev);1167}1168 1169int wm8350_register_regulator(struct wm8350 *wm8350, int reg,1170			      struct regulator_init_data *initdata)1171{1172	struct platform_device *pdev;1173	int ret;1174	if (reg < 0 || reg >= NUM_WM8350_REGULATORS)1175		return -EINVAL;1176 1177	if (wm8350->pmic.pdev[reg])1178		return -EBUSY;1179 1180	if (reg >= WM8350_DCDC_1 && reg <= WM8350_DCDC_6 &&1181	    reg > wm8350->pmic.max_dcdc)1182		return -ENODEV;1183	if (reg >= WM8350_ISINK_A && reg <= WM8350_ISINK_B &&1184	    reg > wm8350->pmic.max_isink)1185		return -ENODEV;1186 1187	pdev = platform_device_alloc("wm8350-regulator", reg);1188	if (!pdev)1189		return -ENOMEM;1190 1191	wm8350->pmic.pdev[reg] = pdev;1192 1193	initdata->driver_data = wm8350;1194 1195	pdev->dev.platform_data = initdata;1196	pdev->dev.parent = wm8350->dev;1197	platform_set_drvdata(pdev, wm8350);1198 1199	ret = platform_device_add(pdev);1200 1201	if (ret != 0) {1202		dev_err(wm8350->dev, "Failed to register regulator %d: %d\n",1203			reg, ret);1204		platform_device_put(pdev);1205		wm8350->pmic.pdev[reg] = NULL;1206	}1207 1208	return ret;1209}1210EXPORT_SYMBOL_GPL(wm8350_register_regulator);1211 1212/**1213 * wm8350_register_led - Register a WM8350 LED output1214 *1215 * @wm8350: The WM8350 device to configure.1216 * @lednum: LED device index to create.1217 * @dcdc: The DCDC to use for the LED.1218 * @isink: The ISINK to use for the LED.1219 * @pdata: Configuration for the LED.1220 *1221 * The WM8350 supports the use of an ISINK together with a DCDC to1222 * provide a power-efficient LED driver.  This function registers the1223 * regulators and instantiates the platform device for a LED.  The1224 * operating modes for the LED regulators must be configured using1225 * wm8350_isink_set_flash(), wm8350_dcdc25_set_mode() and1226 * wm8350_dcdc_set_slot() prior to calling this function.1227 */1228int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink,1229			struct wm8350_led_platform_data *pdata)1230{1231	struct wm8350_led *led;1232	struct platform_device *pdev;1233	int ret;1234 1235	if (lednum >= ARRAY_SIZE(wm8350->pmic.led) || lednum < 0) {1236		dev_err(wm8350->dev, "Invalid LED index %d\n", lednum);1237		return -ENODEV;1238	}1239 1240	led = &wm8350->pmic.led[lednum];1241 1242	if (led->pdev) {1243		dev_err(wm8350->dev, "LED %d already allocated\n", lednum);1244		return -EINVAL;1245	}1246 1247	pdev = platform_device_alloc("wm8350-led", lednum);1248	if (pdev == NULL) {1249		dev_err(wm8350->dev, "Failed to allocate LED %d\n", lednum);1250		return -ENOMEM;1251	}1252 1253	led->isink_consumer.dev_name = dev_name(&pdev->dev);1254	led->isink_consumer.supply = "led_isink";1255	led->isink_init.num_consumer_supplies = 1;1256	led->isink_init.consumer_supplies = &led->isink_consumer;1257	led->isink_init.constraints.min_uA = 0;1258	led->isink_init.constraints.max_uA = pdata->max_uA;1259	led->isink_init.constraints.valid_ops_mask1260		= REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS;1261	led->isink_init.constraints.valid_modes_mask = REGULATOR_MODE_NORMAL;1262	ret = wm8350_register_regulator(wm8350, isink, &led->isink_init);1263	if (ret != 0) {1264		platform_device_put(pdev);1265		return ret;1266	}1267 1268	led->dcdc_consumer.dev_name = dev_name(&pdev->dev);1269	led->dcdc_consumer.supply = "led_vcc";1270	led->dcdc_init.num_consumer_supplies = 1;1271	led->dcdc_init.consumer_supplies = &led->dcdc_consumer;1272	led->dcdc_init.constraints.valid_modes_mask = REGULATOR_MODE_NORMAL;1273	led->dcdc_init.constraints.valid_ops_mask =  REGULATOR_CHANGE_STATUS;1274	ret = wm8350_register_regulator(wm8350, dcdc, &led->dcdc_init);1275	if (ret != 0) {1276		platform_device_put(pdev);1277		return ret;1278	}1279 1280	switch (isink) {1281	case WM8350_ISINK_A:1282		wm8350->pmic.isink_A_dcdc = dcdc;1283		break;1284	case WM8350_ISINK_B:1285		wm8350->pmic.isink_B_dcdc = dcdc;1286		break;1287	}1288 1289	pdev->dev.platform_data = pdata;1290	pdev->dev.parent = wm8350->dev;1291	ret = platform_device_add(pdev);1292	if (ret != 0) {1293		dev_err(wm8350->dev, "Failed to register LED %d: %d\n",1294			lednum, ret);1295		platform_device_put(pdev);1296		return ret;1297	}1298 1299	led->pdev = pdev;1300 1301	return 0;1302}1303EXPORT_SYMBOL_GPL(wm8350_register_led);1304 1305static struct platform_driver wm8350_regulator_driver = {1306	.probe = wm8350_regulator_probe,1307	.remove_new = wm8350_regulator_remove,1308	.driver		= {1309		.name	= "wm8350-regulator",1310		.probe_type = PROBE_PREFER_ASYNCHRONOUS,1311	},1312};1313 1314static int __init wm8350_regulator_init(void)1315{1316	return platform_driver_register(&wm8350_regulator_driver);1317}1318subsys_initcall(wm8350_regulator_init);1319 1320static void __exit wm8350_regulator_exit(void)1321{1322	platform_driver_unregister(&wm8350_regulator_driver);1323}1324module_exit(wm8350_regulator_exit);1325 1326/* Module information */1327MODULE_AUTHOR("Liam Girdwood");1328MODULE_DESCRIPTION("WM8350 voltage and current regulator driver");1329MODULE_LICENSE("GPL");1330MODULE_ALIAS("platform:wm8350-regulator");1331