brintos

brintos / linux-shallow public Read only

0
0
Text · 24.8 KiB · 942f370 Raw
959 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright 2012 Texas Instruments4 *5 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>6 */7 8#include <linux/module.h>9#include <linux/slab.h>10#include <linux/i2c.h>11#include <linux/regmap.h>12#include <linux/err.h>13#include <linux/gpio/consumer.h>14#include <linux/delay.h>15#include <linux/regulator/lp872x.h>16#include <linux/regulator/driver.h>17#include <linux/platform_device.h>18#include <linux/of.h>19#include <linux/regulator/of_regulator.h>20 21/* Registers : LP8720/8725 shared */22#define LP872X_GENERAL_CFG		0x0023#define LP872X_LDO1_VOUT		0x0124#define LP872X_LDO2_VOUT		0x0225#define LP872X_LDO3_VOUT		0x0326#define LP872X_LDO4_VOUT		0x0427#define LP872X_LDO5_VOUT		0x0528 29/* Registers : LP8720 */30#define LP8720_BUCK_VOUT1		0x0631#define LP8720_BUCK_VOUT2		0x0732#define LP8720_ENABLE			0x0833 34/* Registers : LP8725 */35#define LP8725_LILO1_VOUT		0x0636#define LP8725_LILO2_VOUT		0x0737#define LP8725_BUCK1_VOUT1		0x0838#define LP8725_BUCK1_VOUT2		0x0939#define LP8725_BUCK2_VOUT1		0x0A40#define LP8725_BUCK2_VOUT2		0x0B41#define LP8725_BUCK_CTRL		0x0C42#define LP8725_LDO_CTRL			0x0D43 44/* Mask/shift : LP8720/LP8725 shared */45#define LP872X_VOUT_M			0x1F46#define LP872X_START_DELAY_M		0xE047#define LP872X_START_DELAY_S		548#define LP872X_EN_LDO1_M		BIT(0)49#define LP872X_EN_LDO2_M		BIT(1)50#define LP872X_EN_LDO3_M		BIT(2)51#define LP872X_EN_LDO4_M		BIT(3)52#define LP872X_EN_LDO5_M		BIT(4)53 54/* Mask/shift : LP8720 */55#define LP8720_TIMESTEP_S		0		/* Addr 00h */56#define LP8720_TIMESTEP_M		BIT(0)57#define LP8720_EXT_DVS_M		BIT(2)58#define LP8720_BUCK_FPWM_S		5		/* Addr 07h */59#define LP8720_BUCK_FPWM_M		BIT(5)60#define LP8720_EN_BUCK_M		BIT(5)		/* Addr 08h */61#define LP8720_DVS_SEL_M		BIT(7)62 63/* Mask/shift : LP8725 */64#define LP8725_TIMESTEP_M		0xC0		/* Addr 00h */65#define LP8725_TIMESTEP_S		666#define LP8725_BUCK1_EN_M		BIT(0)67#define LP8725_DVS1_M			BIT(2)68#define LP8725_DVS2_M			BIT(3)69#define LP8725_BUCK2_EN_M		BIT(4)70#define LP8725_BUCK_CL_M		0xC0		/* Addr 09h, 0Bh */71#define LP8725_BUCK_CL_S		672#define LP8725_BUCK1_FPWM_S		1		/* Addr 0Ch */73#define LP8725_BUCK1_FPWM_M		BIT(1)74#define LP8725_BUCK2_FPWM_S		575#define LP8725_BUCK2_FPWM_M		BIT(5)76#define LP8725_EN_LILO1_M		BIT(5)		/* Addr 0Dh */77#define LP8725_EN_LILO2_M		BIT(6)78 79/* PWM mode */80#define LP872X_FORCE_PWM		181#define LP872X_AUTO_PWM			082 83#define LP8720_NUM_REGULATORS		684#define LP8725_NUM_REGULATORS		985#define EXTERN_DVS_USED			086#define MAX_DELAY			687 88/* Default DVS Mode */89#define LP8720_DEFAULT_DVS		090#define LP8725_DEFAULT_DVS		BIT(2)91 92/* dump registers in regmap-debugfs */93#define MAX_REGISTERS			0x0F94 95enum lp872x_id {96	LP8720,97	LP8725,98};99 100struct lp872x {101	struct regmap *regmap;102	struct device *dev;103	enum lp872x_id chipid;104	struct lp872x_platform_data *pdata;105	int num_regulators;106	enum gpiod_flags dvs_pin;107};108 109/* LP8720/LP8725 shared voltage table for LDOs */110static const unsigned int lp872x_ldo_vtbl[] = {111	1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 1550000,112	1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, 2000000,113	2100000, 2200000, 2300000, 2400000, 2500000, 2600000, 2650000, 2700000,114	2750000, 2800000, 2850000, 2900000, 2950000, 3000000, 3100000, 3300000,115};116 117/* LP8720 LDO4 voltage table */118static const unsigned int lp8720_ldo4_vtbl[] = {119	 800000,  850000,  900000, 1000000, 1100000, 1200000, 1250000, 1300000,120	1350000, 1400000, 1450000, 1500000, 1550000, 1600000, 1650000, 1700000,121	1750000, 1800000, 1850000, 1900000, 2000000, 2100000, 2200000, 2300000,122	2400000, 2500000, 2600000, 2650000, 2700000, 2750000, 2800000, 2850000,123};124 125/* LP8725 LILO(Low Input Low Output) voltage table */126static const unsigned int lp8725_lilo_vtbl[] = {127	 800000,  850000,  900000,  950000, 1000000, 1050000, 1100000, 1150000,128	1200000, 1250000, 1300000, 1350000, 1400000, 1500000, 1600000, 1700000,129	1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000,130	2600000, 2700000, 2800000, 2850000, 2900000, 3000000, 3100000, 3300000,131};132 133/* LP8720 BUCK voltage table */134#define EXT_R		0	/* external resistor divider */135static const unsigned int lp8720_buck_vtbl[] = {136	  EXT_R,  800000,  850000,  900000,  950000, 1000000, 1050000, 1100000,137	1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000,138	1550000, 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000,139	1950000, 2000000, 2050000, 2100000, 2150000, 2200000, 2250000, 2300000,140};141 142/* LP8725 BUCK voltage table */143static const unsigned int lp8725_buck_vtbl[] = {144	 800000,  850000,  900000,  950000, 1000000, 1050000, 1100000, 1150000,145	1200000, 1250000, 1300000, 1350000, 1400000, 1500000, 1600000, 1700000,146	1750000, 1800000, 1850000, 1900000, 2000000, 2100000, 2200000, 2300000,147	2400000, 2500000, 2600000, 2700000, 2800000, 2850000, 2900000, 3000000,148};149 150/* LP8725 BUCK current limit */151static const unsigned int lp8725_buck_uA[] = {152	460000, 780000, 1050000, 1370000,153};154 155static int lp872x_read_byte(struct lp872x *lp, u8 addr, u8 *data)156{157	int ret;158	unsigned int val;159 160	ret = regmap_read(lp->regmap, addr, &val);161	if (ret < 0) {162		dev_err(lp->dev, "failed to read 0x%.2x\n", addr);163		return ret;164	}165 166	*data = (u8)val;167	return 0;168}169 170static inline int lp872x_write_byte(struct lp872x *lp, u8 addr, u8 data)171{172	return regmap_write(lp->regmap, addr, data);173}174 175static inline int lp872x_update_bits(struct lp872x *lp, u8 addr,176				unsigned int mask, u8 data)177{178	return regmap_update_bits(lp->regmap, addr, mask, data);179}180 181static int lp872x_get_timestep_usec(struct lp872x *lp)182{183	enum lp872x_id chip = lp->chipid;184	u8 val, mask, shift;185	int *time_usec, size, ret;186	int lp8720_time_usec[] = { 25, 50 };187	int lp8725_time_usec[] = { 32, 64, 128, 256 };188 189	switch (chip) {190	case LP8720:191		mask = LP8720_TIMESTEP_M;192		shift = LP8720_TIMESTEP_S;193		time_usec = &lp8720_time_usec[0];194		size = ARRAY_SIZE(lp8720_time_usec);195		break;196	case LP8725:197		mask = LP8725_TIMESTEP_M;198		shift = LP8725_TIMESTEP_S;199		time_usec = &lp8725_time_usec[0];200		size = ARRAY_SIZE(lp8725_time_usec);201		break;202	default:203		return -EINVAL;204	}205 206	ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val);207	if (ret)208		return ret;209 210	val = (val & mask) >> shift;211	if (val >= size)212		return -EINVAL;213 214	return *(time_usec + val);215}216 217static int lp872x_regulator_enable_time(struct regulator_dev *rdev)218{219	struct lp872x *lp = rdev_get_drvdata(rdev);220	enum lp872x_regulator_id rid = rdev_get_id(rdev);221	int time_step_us = lp872x_get_timestep_usec(lp);222	int ret;223	u8 addr, val;224 225	if (time_step_us < 0)226		return time_step_us;227 228	switch (rid) {229	case LP8720_ID_LDO1 ... LP8720_ID_BUCK:230		addr = LP872X_LDO1_VOUT + rid;231		break;232	case LP8725_ID_LDO1 ... LP8725_ID_BUCK1:233		addr = LP872X_LDO1_VOUT + rid - LP8725_ID_BASE;234		break;235	case LP8725_ID_BUCK2:236		addr = LP8725_BUCK2_VOUT1;237		break;238	default:239		return -EINVAL;240	}241 242	ret = lp872x_read_byte(lp, addr, &val);243	if (ret)244		return ret;245 246	val = (val & LP872X_START_DELAY_M) >> LP872X_START_DELAY_S;247 248	return val > MAX_DELAY ? 0 : val * time_step_us;249}250 251static void lp872x_set_dvs(struct lp872x *lp, enum lp872x_dvs_sel dvs_sel,252			struct gpio_desc *gpio)253{254	enum gpiod_flags state;255 256	state = dvs_sel == SEL_V1 ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;257	gpiod_set_value(gpio, state);258	lp->dvs_pin = state;259}260 261static u8 lp872x_select_buck_vout_addr(struct lp872x *lp,262				enum lp872x_regulator_id buck)263{264	u8 val, addr;265 266	if (lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val))267		return 0;268 269	switch (buck) {270	case LP8720_ID_BUCK:271		if (val & LP8720_EXT_DVS_M) {272			addr = (lp->dvs_pin == GPIOD_OUT_HIGH) ?273				LP8720_BUCK_VOUT1 : LP8720_BUCK_VOUT2;274		} else {275			if (lp872x_read_byte(lp, LP8720_ENABLE, &val))276				return 0;277 278			addr = val & LP8720_DVS_SEL_M ?279				LP8720_BUCK_VOUT1 : LP8720_BUCK_VOUT2;280		}281		break;282	case LP8725_ID_BUCK1:283		if (val & LP8725_DVS1_M)284			addr = LP8725_BUCK1_VOUT1;285		else286			addr = (lp->dvs_pin == GPIOD_OUT_HIGH) ?287				LP8725_BUCK1_VOUT1 : LP8725_BUCK1_VOUT2;288		break;289	case LP8725_ID_BUCK2:290		addr =  val & LP8725_DVS2_M ?291			LP8725_BUCK2_VOUT1 : LP8725_BUCK2_VOUT2;292		break;293	default:294		return 0;295	}296 297	return addr;298}299 300static bool lp872x_is_valid_buck_addr(u8 addr)301{302	switch (addr) {303	case LP8720_BUCK_VOUT1:304	case LP8720_BUCK_VOUT2:305	case LP8725_BUCK1_VOUT1:306	case LP8725_BUCK1_VOUT2:307	case LP8725_BUCK2_VOUT1:308	case LP8725_BUCK2_VOUT2:309		return true;310	default:311		return false;312	}313}314 315static int lp872x_buck_set_voltage_sel(struct regulator_dev *rdev,316					unsigned selector)317{318	struct lp872x *lp = rdev_get_drvdata(rdev);319	enum lp872x_regulator_id buck = rdev_get_id(rdev);320	u8 addr, mask = LP872X_VOUT_M;321	struct lp872x_dvs *dvs = lp->pdata ? lp->pdata->dvs : NULL;322 323	if (dvs && dvs->gpio)324		lp872x_set_dvs(lp, dvs->vsel, dvs->gpio);325 326	addr = lp872x_select_buck_vout_addr(lp, buck);327	if (!lp872x_is_valid_buck_addr(addr))328		return -EINVAL;329 330	return lp872x_update_bits(lp, addr, mask, selector);331}332 333static int lp872x_buck_get_voltage_sel(struct regulator_dev *rdev)334{335	struct lp872x *lp = rdev_get_drvdata(rdev);336	enum lp872x_regulator_id buck = rdev_get_id(rdev);337	u8 addr, val;338	int ret;339 340	addr = lp872x_select_buck_vout_addr(lp, buck);341	if (!lp872x_is_valid_buck_addr(addr))342		return -EINVAL;343 344	ret = lp872x_read_byte(lp, addr, &val);345	if (ret)346		return ret;347 348	return val & LP872X_VOUT_M;349}350 351static int lp872x_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)352{353	struct lp872x *lp = rdev_get_drvdata(rdev);354	enum lp872x_regulator_id buck = rdev_get_id(rdev);355	u8 addr, mask, shift, val;356 357	switch (buck) {358	case LP8720_ID_BUCK:359		addr = LP8720_BUCK_VOUT2;360		mask = LP8720_BUCK_FPWM_M;361		shift = LP8720_BUCK_FPWM_S;362		break;363	case LP8725_ID_BUCK1:364		addr = LP8725_BUCK_CTRL;365		mask = LP8725_BUCK1_FPWM_M;366		shift = LP8725_BUCK1_FPWM_S;367		break;368	case LP8725_ID_BUCK2:369		addr = LP8725_BUCK_CTRL;370		mask = LP8725_BUCK2_FPWM_M;371		shift = LP8725_BUCK2_FPWM_S;372		break;373	default:374		return -EINVAL;375	}376 377	if (mode == REGULATOR_MODE_FAST)378		val = LP872X_FORCE_PWM << shift;379	else if (mode == REGULATOR_MODE_NORMAL)380		val = LP872X_AUTO_PWM << shift;381	else382		return -EINVAL;383 384	return lp872x_update_bits(lp, addr, mask, val);385}386 387static unsigned int lp872x_buck_get_mode(struct regulator_dev *rdev)388{389	struct lp872x *lp = rdev_get_drvdata(rdev);390	enum lp872x_regulator_id buck = rdev_get_id(rdev);391	u8 addr, mask, val;392	int ret;393 394	switch (buck) {395	case LP8720_ID_BUCK:396		addr = LP8720_BUCK_VOUT2;397		mask = LP8720_BUCK_FPWM_M;398		break;399	case LP8725_ID_BUCK1:400		addr = LP8725_BUCK_CTRL;401		mask = LP8725_BUCK1_FPWM_M;402		break;403	case LP8725_ID_BUCK2:404		addr = LP8725_BUCK_CTRL;405		mask = LP8725_BUCK2_FPWM_M;406		break;407	default:408		return -EINVAL;409	}410 411	ret = lp872x_read_byte(lp, addr, &val);412	if (ret)413		return ret;414 415	return val & mask ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;416}417 418static const struct regulator_ops lp872x_ldo_ops = {419	.list_voltage = regulator_list_voltage_table,420	.map_voltage = regulator_map_voltage_ascend,421	.set_voltage_sel = regulator_set_voltage_sel_regmap,422	.get_voltage_sel = regulator_get_voltage_sel_regmap,423	.enable = regulator_enable_regmap,424	.disable = regulator_disable_regmap,425	.is_enabled = regulator_is_enabled_regmap,426	.enable_time = lp872x_regulator_enable_time,427};428 429static const struct regulator_ops lp8720_buck_ops = {430	.list_voltage = regulator_list_voltage_table,431	.map_voltage = regulator_map_voltage_ascend,432	.set_voltage_sel = lp872x_buck_set_voltage_sel,433	.get_voltage_sel = lp872x_buck_get_voltage_sel,434	.enable = regulator_enable_regmap,435	.disable = regulator_disable_regmap,436	.is_enabled = regulator_is_enabled_regmap,437	.enable_time = lp872x_regulator_enable_time,438	.set_mode = lp872x_buck_set_mode,439	.get_mode = lp872x_buck_get_mode,440};441 442static const struct regulator_ops lp8725_buck_ops = {443	.list_voltage = regulator_list_voltage_table,444	.map_voltage = regulator_map_voltage_ascend,445	.set_voltage_sel = lp872x_buck_set_voltage_sel,446	.get_voltage_sel = lp872x_buck_get_voltage_sel,447	.enable = regulator_enable_regmap,448	.disable = regulator_disable_regmap,449	.is_enabled = regulator_is_enabled_regmap,450	.enable_time = lp872x_regulator_enable_time,451	.set_mode = lp872x_buck_set_mode,452	.get_mode = lp872x_buck_get_mode,453	.set_current_limit = regulator_set_current_limit_regmap,454	.get_current_limit = regulator_get_current_limit_regmap,455};456 457static const struct regulator_desc lp8720_regulator_desc[] = {458	{459		.name = "ldo1",460		.of_match = of_match_ptr("ldo1"),461		.id = LP8720_ID_LDO1,462		.ops = &lp872x_ldo_ops,463		.n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl),464		.volt_table = lp872x_ldo_vtbl,465		.type = REGULATOR_VOLTAGE,466		.owner = THIS_MODULE,467		.vsel_reg = LP872X_LDO1_VOUT,468		.vsel_mask = LP872X_VOUT_M,469		.enable_reg = LP8720_ENABLE,470		.enable_mask = LP872X_EN_LDO1_M,471	},472	{473		.name = "ldo2",474		.of_match = of_match_ptr("ldo2"),475		.id = LP8720_ID_LDO2,476		.ops = &lp872x_ldo_ops,477		.n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl),478		.volt_table = lp872x_ldo_vtbl,479		.type = REGULATOR_VOLTAGE,480		.owner = THIS_MODULE,481		.vsel_reg = LP872X_LDO2_VOUT,482		.vsel_mask = LP872X_VOUT_M,483		.enable_reg = LP8720_ENABLE,484		.enable_mask = LP872X_EN_LDO2_M,485	},486	{487		.name = "ldo3",488		.of_match = of_match_ptr("ldo3"),489		.id = LP8720_ID_LDO3,490		.ops = &lp872x_ldo_ops,491		.n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl),492		.volt_table = lp872x_ldo_vtbl,493		.type = REGULATOR_VOLTAGE,494		.owner = THIS_MODULE,495		.vsel_reg = LP872X_LDO3_VOUT,496		.vsel_mask = LP872X_VOUT_M,497		.enable_reg = LP8720_ENABLE,498		.enable_mask = LP872X_EN_LDO3_M,499	},500	{501		.name = "ldo4",502		.of_match = of_match_ptr("ldo4"),503		.id = LP8720_ID_LDO4,504		.ops = &lp872x_ldo_ops,505		.n_voltages = ARRAY_SIZE(lp8720_ldo4_vtbl),506		.volt_table = lp8720_ldo4_vtbl,507		.type = REGULATOR_VOLTAGE,508		.owner = THIS_MODULE,509		.vsel_reg = LP872X_LDO4_VOUT,510		.vsel_mask = LP872X_VOUT_M,511		.enable_reg = LP8720_ENABLE,512		.enable_mask = LP872X_EN_LDO4_M,513	},514	{515		.name = "ldo5",516		.of_match = of_match_ptr("ldo5"),517		.id = LP8720_ID_LDO5,518		.ops = &lp872x_ldo_ops,519		.n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl),520		.volt_table = lp872x_ldo_vtbl,521		.type = REGULATOR_VOLTAGE,522		.owner = THIS_MODULE,523		.vsel_reg = LP872X_LDO5_VOUT,524		.vsel_mask = LP872X_VOUT_M,525		.enable_reg = LP8720_ENABLE,526		.enable_mask = LP872X_EN_LDO5_M,527	},528	{529		.name = "buck",530		.of_match = of_match_ptr("buck"),531		.id = LP8720_ID_BUCK,532		.ops = &lp8720_buck_ops,533		.n_voltages = ARRAY_SIZE(lp8720_buck_vtbl),534		.volt_table = lp8720_buck_vtbl,535		.type = REGULATOR_VOLTAGE,536		.owner = THIS_MODULE,537		.enable_reg = LP8720_ENABLE,538		.enable_mask = LP8720_EN_BUCK_M,539	},540};541 542static const struct regulator_desc lp8725_regulator_desc[] = {543	{544		.name = "ldo1",545		.of_match = of_match_ptr("ldo1"),546		.id = LP8725_ID_LDO1,547		.ops = &lp872x_ldo_ops,548		.n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl),549		.volt_table = lp872x_ldo_vtbl,550		.type = REGULATOR_VOLTAGE,551		.owner = THIS_MODULE,552		.vsel_reg = LP872X_LDO1_VOUT,553		.vsel_mask = LP872X_VOUT_M,554		.enable_reg = LP8725_LDO_CTRL,555		.enable_mask = LP872X_EN_LDO1_M,556	},557	{558		.name = "ldo2",559		.of_match = of_match_ptr("ldo2"),560		.id = LP8725_ID_LDO2,561		.ops = &lp872x_ldo_ops,562		.n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl),563		.volt_table = lp872x_ldo_vtbl,564		.type = REGULATOR_VOLTAGE,565		.owner = THIS_MODULE,566		.vsel_reg = LP872X_LDO2_VOUT,567		.vsel_mask = LP872X_VOUT_M,568		.enable_reg = LP8725_LDO_CTRL,569		.enable_mask = LP872X_EN_LDO2_M,570	},571	{572		.name = "ldo3",573		.of_match = of_match_ptr("ldo3"),574		.id = LP8725_ID_LDO3,575		.ops = &lp872x_ldo_ops,576		.n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl),577		.volt_table = lp872x_ldo_vtbl,578		.type = REGULATOR_VOLTAGE,579		.owner = THIS_MODULE,580		.vsel_reg = LP872X_LDO3_VOUT,581		.vsel_mask = LP872X_VOUT_M,582		.enable_reg = LP8725_LDO_CTRL,583		.enable_mask = LP872X_EN_LDO3_M,584	},585	{586		.name = "ldo4",587		.of_match = of_match_ptr("ldo4"),588		.id = LP8725_ID_LDO4,589		.ops = &lp872x_ldo_ops,590		.n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl),591		.volt_table = lp872x_ldo_vtbl,592		.type = REGULATOR_VOLTAGE,593		.owner = THIS_MODULE,594		.vsel_reg = LP872X_LDO4_VOUT,595		.vsel_mask = LP872X_VOUT_M,596		.enable_reg = LP8725_LDO_CTRL,597		.enable_mask = LP872X_EN_LDO4_M,598	},599	{600		.name = "ldo5",601		.of_match = of_match_ptr("ldo5"),602		.id = LP8725_ID_LDO5,603		.ops = &lp872x_ldo_ops,604		.n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl),605		.volt_table = lp872x_ldo_vtbl,606		.type = REGULATOR_VOLTAGE,607		.owner = THIS_MODULE,608		.vsel_reg = LP872X_LDO5_VOUT,609		.vsel_mask = LP872X_VOUT_M,610		.enable_reg = LP8725_LDO_CTRL,611		.enable_mask = LP872X_EN_LDO5_M,612	},613	{614		.name = "lilo1",615		.of_match = of_match_ptr("lilo1"),616		.id = LP8725_ID_LILO1,617		.ops = &lp872x_ldo_ops,618		.n_voltages = ARRAY_SIZE(lp8725_lilo_vtbl),619		.volt_table = lp8725_lilo_vtbl,620		.type = REGULATOR_VOLTAGE,621		.owner = THIS_MODULE,622		.vsel_reg = LP8725_LILO1_VOUT,623		.vsel_mask = LP872X_VOUT_M,624		.enable_reg = LP8725_LDO_CTRL,625		.enable_mask = LP8725_EN_LILO1_M,626	},627	{628		.name = "lilo2",629		.of_match = of_match_ptr("lilo2"),630		.id = LP8725_ID_LILO2,631		.ops = &lp872x_ldo_ops,632		.n_voltages = ARRAY_SIZE(lp8725_lilo_vtbl),633		.volt_table = lp8725_lilo_vtbl,634		.type = REGULATOR_VOLTAGE,635		.owner = THIS_MODULE,636		.vsel_reg = LP8725_LILO2_VOUT,637		.vsel_mask = LP872X_VOUT_M,638		.enable_reg = LP8725_LDO_CTRL,639		.enable_mask = LP8725_EN_LILO2_M,640	},641	{642		.name = "buck1",643		.of_match = of_match_ptr("buck1"),644		.id = LP8725_ID_BUCK1,645		.ops = &lp8725_buck_ops,646		.n_voltages = ARRAY_SIZE(lp8725_buck_vtbl),647		.volt_table = lp8725_buck_vtbl,648		.type = REGULATOR_VOLTAGE,649		.owner = THIS_MODULE,650		.enable_reg = LP872X_GENERAL_CFG,651		.enable_mask = LP8725_BUCK1_EN_M,652		.curr_table = lp8725_buck_uA,653		.n_current_limits = ARRAY_SIZE(lp8725_buck_uA),654		.csel_reg = LP8725_BUCK1_VOUT2,655		.csel_mask = LP8725_BUCK_CL_M,656	},657	{658		.name = "buck2",659		.of_match = of_match_ptr("buck2"),660		.id = LP8725_ID_BUCK2,661		.ops = &lp8725_buck_ops,662		.n_voltages = ARRAY_SIZE(lp8725_buck_vtbl),663		.volt_table = lp8725_buck_vtbl,664		.type = REGULATOR_VOLTAGE,665		.owner = THIS_MODULE,666		.enable_reg = LP872X_GENERAL_CFG,667		.enable_mask = LP8725_BUCK2_EN_M,668		.curr_table = lp8725_buck_uA,669		.n_current_limits = ARRAY_SIZE(lp8725_buck_uA),670		.csel_reg = LP8725_BUCK2_VOUT2,671		.csel_mask = LP8725_BUCK_CL_M,672	},673};674 675static int lp872x_init_dvs(struct lp872x *lp)676{677	struct lp872x_dvs *dvs = lp->pdata ? lp->pdata->dvs : NULL;678	enum gpiod_flags pinstate;679	u8 mask[] = { LP8720_EXT_DVS_M, LP8725_DVS1_M | LP8725_DVS2_M };680	u8 default_dvs_mode[] = { LP8720_DEFAULT_DVS, LP8725_DEFAULT_DVS };681 682	if (!dvs)683		goto set_default_dvs_mode;684 685	if (!dvs->gpio)686		goto set_default_dvs_mode;687 688	pinstate = dvs->init_state;689	dvs->gpio = devm_gpiod_get_optional(lp->dev, "ti,dvs", pinstate);690 691	if (IS_ERR(dvs->gpio)) {692		dev_err(lp->dev, "gpio request err: %ld\n", PTR_ERR(dvs->gpio));693		return PTR_ERR(dvs->gpio);694	}695 696	lp->dvs_pin = pinstate;697 698	return 0;699 700set_default_dvs_mode:701	return lp872x_update_bits(lp, LP872X_GENERAL_CFG, mask[lp->chipid],702				default_dvs_mode[lp->chipid]);703}704 705static int lp872x_hw_enable(struct lp872x *lp)706{707	if (!lp->pdata)708		return -EINVAL;709 710	if (!lp->pdata->enable_gpio)711		return 0;712 713	/* Always set enable GPIO high. */714	lp->pdata->enable_gpio = devm_gpiod_get_optional(lp->dev, "enable", GPIOD_OUT_HIGH);715	if (IS_ERR(lp->pdata->enable_gpio)) {716		dev_err(lp->dev, "gpio request err: %ld\n", PTR_ERR(lp->pdata->enable_gpio));717		return PTR_ERR(lp->pdata->enable_gpio);718	}719 720	/* Each chip has a different enable delay. */721	if (lp->chipid == LP8720)722		usleep_range(LP8720_ENABLE_DELAY, 1.5 * LP8720_ENABLE_DELAY);723	else724		usleep_range(LP8725_ENABLE_DELAY, 1.5 * LP8725_ENABLE_DELAY);725 726	return 0;727}728 729static int lp872x_config(struct lp872x *lp)730{731	struct lp872x_platform_data *pdata = lp->pdata;732	int ret;733 734	if (!pdata || !pdata->update_config)735		goto init_dvs;736 737	ret = lp872x_write_byte(lp, LP872X_GENERAL_CFG, pdata->general_config);738	if (ret)739		return ret;740 741init_dvs:742	return lp872x_init_dvs(lp);743}744 745static struct regulator_init_data746*lp872x_find_regulator_init_data(int id, struct lp872x *lp)747{748	struct lp872x_platform_data *pdata = lp->pdata;749	int i;750 751	if (!pdata)752		return NULL;753 754	for (i = 0; i < lp->num_regulators; i++) {755		if (pdata->regulator_data[i].id == id)756			return pdata->regulator_data[i].init_data;757	}758 759	return NULL;760}761 762static int lp872x_regulator_register(struct lp872x *lp)763{764	const struct regulator_desc *desc;765	struct regulator_config cfg = { };766	struct regulator_dev *rdev;767	int i;768 769	for (i = 0; i < lp->num_regulators; i++) {770		desc = (lp->chipid == LP8720) ? &lp8720_regulator_desc[i] :771						&lp8725_regulator_desc[i];772 773		cfg.dev = lp->dev;774		cfg.init_data = lp872x_find_regulator_init_data(desc->id, lp);775		cfg.driver_data = lp;776		cfg.regmap = lp->regmap;777 778		rdev = devm_regulator_register(lp->dev, desc, &cfg);779		if (IS_ERR(rdev)) {780			dev_err(lp->dev, "regulator register err");781			return PTR_ERR(rdev);782		}783	}784 785	return 0;786}787 788static const struct regmap_config lp872x_regmap_config = {789	.reg_bits = 8,790	.val_bits = 8,791	.max_register = MAX_REGISTERS,792};793 794#ifdef CONFIG_OF795 796#define LP872X_VALID_OPMODE	(REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL)797 798static struct of_regulator_match lp8720_matches[] = {799	{ .name = "ldo1", .driver_data = (void *)LP8720_ID_LDO1, },800	{ .name = "ldo2", .driver_data = (void *)LP8720_ID_LDO2, },801	{ .name = "ldo3", .driver_data = (void *)LP8720_ID_LDO3, },802	{ .name = "ldo4", .driver_data = (void *)LP8720_ID_LDO4, },803	{ .name = "ldo5", .driver_data = (void *)LP8720_ID_LDO5, },804	{ .name = "buck", .driver_data = (void *)LP8720_ID_BUCK, },805};806 807static struct of_regulator_match lp8725_matches[] = {808	{ .name = "ldo1", .driver_data = (void *)LP8725_ID_LDO1, },809	{ .name = "ldo2", .driver_data = (void *)LP8725_ID_LDO2, },810	{ .name = "ldo3", .driver_data = (void *)LP8725_ID_LDO3, },811	{ .name = "ldo4", .driver_data = (void *)LP8725_ID_LDO4, },812	{ .name = "ldo5", .driver_data = (void *)LP8725_ID_LDO5, },813	{ .name = "lilo1", .driver_data = (void *)LP8725_ID_LILO1, },814	{ .name = "lilo2", .driver_data = (void *)LP8725_ID_LILO2, },815	{ .name = "buck1", .driver_data = (void *)LP8725_ID_BUCK1, },816	{ .name = "buck2", .driver_data = (void *)LP8725_ID_BUCK2, },817};818 819static struct lp872x_platform_data820*lp872x_populate_pdata_from_dt(struct device *dev, enum lp872x_id which)821{822	struct device_node *np = dev->of_node;823	struct lp872x_platform_data *pdata;824	struct of_regulator_match *match;825	int num_matches;826	int count;827	int i;828	u8 dvs_state;829 830	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);831	if (!pdata)832		return ERR_PTR(-ENOMEM);833 834	of_property_read_u8(np, "ti,general-config", &pdata->general_config);835	pdata->update_config = of_property_read_bool(np, "ti,update-config");836 837	pdata->dvs = devm_kzalloc(dev, sizeof(struct lp872x_dvs), GFP_KERNEL);838	if (!pdata->dvs)839		return ERR_PTR(-ENOMEM);840 841	of_property_read_u8(np, "ti,dvs-vsel", (u8 *)&pdata->dvs->vsel);842	of_property_read_u8(np, "ti,dvs-state", &dvs_state);843	pdata->dvs->init_state = dvs_state ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;844 845	if (of_get_child_count(np) == 0)846		goto out;847 848	switch (which) {849	case LP8720:850		match = lp8720_matches;851		num_matches = ARRAY_SIZE(lp8720_matches);852		break;853	case LP8725:854		match = lp8725_matches;855		num_matches = ARRAY_SIZE(lp8725_matches);856		break;857	default:858		goto out;859	}860 861	count = of_regulator_match(dev, np, match, num_matches);862	if (count <= 0)863		goto out;864 865	for (i = 0; i < num_matches; i++) {866		pdata->regulator_data[i].id =867				(uintptr_t)match[i].driver_data;868		pdata->regulator_data[i].init_data = match[i].init_data;869	}870out:871	return pdata;872}873#else874static struct lp872x_platform_data875*lp872x_populate_pdata_from_dt(struct device *dev, enum lp872x_id which)876{877	return NULL;878}879#endif880 881static int lp872x_probe(struct i2c_client *cl)882{883	const struct i2c_device_id *id = i2c_client_get_device_id(cl);884	struct lp872x *lp;885	struct lp872x_platform_data *pdata;886	int ret;887	static const int lp872x_num_regulators[] = {888		[LP8720] = LP8720_NUM_REGULATORS,889		[LP8725] = LP8725_NUM_REGULATORS,890	};891 892	if (cl->dev.of_node) {893		pdata = lp872x_populate_pdata_from_dt(&cl->dev,894					      (enum lp872x_id)id->driver_data);895		if (IS_ERR(pdata))896			return PTR_ERR(pdata);897	} else {898		pdata = dev_get_platdata(&cl->dev);899	}900 901	lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL);902	if (!lp)903		return -ENOMEM;904 905	lp->num_regulators = lp872x_num_regulators[id->driver_data];906 907	lp->regmap = devm_regmap_init_i2c(cl, &lp872x_regmap_config);908	if (IS_ERR(lp->regmap)) {909		ret = PTR_ERR(lp->regmap);910		dev_err(&cl->dev, "regmap init i2c err: %d\n", ret);911		return ret;912	}913 914	lp->dev = &cl->dev;915	lp->pdata = pdata;916	lp->chipid = id->driver_data;917	i2c_set_clientdata(cl, lp);918 919	ret = lp872x_hw_enable(lp);920	if (ret)921		return ret;922 923	ret = lp872x_config(lp);924	if (ret)925		return ret;926 927	return lp872x_regulator_register(lp);928}929 930static const struct of_device_id lp872x_dt_ids[] __maybe_unused = {931	{ .compatible = "ti,lp8720", },932	{ .compatible = "ti,lp8725", },933	{ }934};935MODULE_DEVICE_TABLE(of, lp872x_dt_ids);936 937static const struct i2c_device_id lp872x_ids[] = {938	{"lp8720", LP8720},939	{"lp8725", LP8725},940	{ }941};942MODULE_DEVICE_TABLE(i2c, lp872x_ids);943 944static struct i2c_driver lp872x_driver = {945	.driver = {946		.name = "lp872x",947		.probe_type = PROBE_PREFER_ASYNCHRONOUS,948		.of_match_table = of_match_ptr(lp872x_dt_ids),949	},950	.probe = lp872x_probe,951	.id_table = lp872x_ids,952};953 954module_i2c_driver(lp872x_driver);955 956MODULE_DESCRIPTION("TI/National Semiconductor LP872x PMU Regulator Driver");957MODULE_AUTHOR("Milo Kim");958MODULE_LICENSE("GPL");959