brintos

brintos / linux-shallow public Read only

0
0
Text · 14.4 KiB · 8f916ee Raw
535 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Regulator driver for tps65090 power management chip.4 *5 * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.6 7 */8 9#include <linux/module.h>10#include <linux/delay.h>11#include <linux/init.h>12#include <linux/of.h>13#include <linux/gpio/consumer.h>14#include <linux/slab.h>15#include <linux/err.h>16#include <linux/platform_device.h>17#include <linux/regulator/driver.h>18#include <linux/regulator/machine.h>19#include <linux/regulator/of_regulator.h>20#include <linux/mfd/tps65090.h>21 22#define MAX_CTRL_READ_TRIES	523#define MAX_FET_ENABLE_TRIES	100024 25#define CTRL_EN_BIT		0 /* Regulator enable bit, active high */26#define CTRL_WT_BIT		2 /* Regulator wait time 0 bit */27#define CTRL_PG_BIT		4 /* Regulator power good bit, 1=good */28#define CTRL_TO_BIT		7 /* Regulator timeout bit, 1=wait */29 30#define MAX_OVERCURRENT_WAIT	3 /* Overcurrent wait must be <= this */31 32/**33 * struct tps65090_regulator - Per-regulator data for a tps65090 regulator34 *35 * @dev: Pointer to our device.36 * @desc: The struct regulator_desc for the regulator.37 * @rdev: The struct regulator_dev for the regulator.38 * @overcurrent_wait_valid: True if overcurrent_wait is valid.39 * @overcurrent_wait: For FETs, the value to put in the WTFET bitfield.40 */41 42struct tps65090_regulator {43	struct device		*dev;44	struct regulator_desc	*desc;45	struct regulator_dev	*rdev;46	bool			overcurrent_wait_valid;47	int			overcurrent_wait;48};49 50static const struct regulator_ops tps65090_ext_control_ops = {51};52 53/**54 * tps65090_reg_set_overcurrent_wait - Setup overcurrent wait55 *56 * This will set the overcurrent wait time based on what's in the regulator57 * info.58 *59 * @ri:		Overall regulator data60 * @rdev:	Regulator device61 *62 * Return: 0 if no error, non-zero if there was an error writing the register.63 */64static int tps65090_reg_set_overcurrent_wait(struct tps65090_regulator *ri,65					     struct regulator_dev *rdev)66{67	int ret;68 69	ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,70				 MAX_OVERCURRENT_WAIT << CTRL_WT_BIT,71				 ri->overcurrent_wait << CTRL_WT_BIT);72	if (ret) {73		dev_err(&rdev->dev, "Error updating overcurrent wait %#x\n",74			rdev->desc->enable_reg);75	}76 77	return ret;78}79 80/**81 * tps65090_try_enable_fet - Try to enable a FET82 *83 * @rdev:	Regulator device84 *85 * Return: 0 if ok, -ENOTRECOVERABLE if the FET power good bit did not get86 * set, or some other -ve value if another error occurred (e.g. i2c error)87 */88static int tps65090_try_enable_fet(struct regulator_dev *rdev)89{90	unsigned int control;91	int ret, i;92 93	ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,94				 rdev->desc->enable_mask,95				 rdev->desc->enable_mask);96	if (ret < 0) {97		dev_err(&rdev->dev, "Error in updating reg %#x\n",98			rdev->desc->enable_reg);99		return ret;100	}101 102	for (i = 0; i < MAX_CTRL_READ_TRIES; i++) {103		ret = regmap_read(rdev->regmap, rdev->desc->enable_reg,104				  &control);105		if (ret < 0)106			return ret;107 108		if (!(control & BIT(CTRL_TO_BIT)))109			break;110 111		usleep_range(1000, 1500);112	}113	if (!(control & BIT(CTRL_PG_BIT)))114		return -ENOTRECOVERABLE;115 116	return 0;117}118 119/**120 * tps65090_fet_enable - Enable a FET, trying a few times if it fails121 *122 * Some versions of the tps65090 have issues when turning on the FETs.123 * This function goes through several steps to ensure the best chance of the124 * FET going on.  Specifically:125 * - We'll make sure that we bump the "overcurrent wait" to the maximum, which126 *   increases the chances that we'll turn on properly.127 * - We'll retry turning the FET on multiple times (turning off in between).128 *129 * @rdev:	Regulator device130 *131 * Return: 0 if ok, non-zero if it fails.132 */133static int tps65090_fet_enable(struct regulator_dev *rdev)134{135	int ret, tries;136 137	/*138	 * Try enabling multiple times until we succeed since sometimes the139	 * first try times out.140	 */141	tries = 0;142	while (true) {143		ret = tps65090_try_enable_fet(rdev);144		if (!ret)145			break;146		if (ret != -ENOTRECOVERABLE || tries == MAX_FET_ENABLE_TRIES)147			goto err;148 149		/* Try turning the FET off (and then on again) */150		ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,151					 rdev->desc->enable_mask, 0);152		if (ret)153			goto err;154 155		tries++;156	}157 158	if (tries)159		dev_warn(&rdev->dev, "reg %#x enable ok after %d tries\n",160			 rdev->desc->enable_reg, tries);161 162	return 0;163err:164	dev_warn(&rdev->dev, "reg %#x enable failed\n", rdev->desc->enable_reg);165	WARN_ON(1);166 167	return ret;168}169 170static const struct regulator_ops tps65090_reg_control_ops = {171	.enable		= regulator_enable_regmap,172	.disable	= regulator_disable_regmap,173	.is_enabled	= regulator_is_enabled_regmap,174};175 176static const struct regulator_ops tps65090_fet_control_ops = {177	.enable		= tps65090_fet_enable,178	.disable	= regulator_disable_regmap,179	.is_enabled	= regulator_is_enabled_regmap,180};181 182static const struct regulator_ops tps65090_ldo_ops = {183};184 185#define tps65090_REG_DESC(_id, _sname, _en_reg, _en_bits, _nvolt, _volt, _ops) \186{							\187	.name = "TPS65090_RAILS"#_id,			\188	.supply_name = _sname,				\189	.id = TPS65090_REGULATOR_##_id,			\190	.n_voltages = _nvolt,				\191	.ops = &_ops,					\192	.fixed_uV = _volt,				\193	.enable_reg = _en_reg,				\194	.enable_val = _en_bits,				\195	.enable_mask = _en_bits,			\196	.type = REGULATOR_VOLTAGE,			\197	.owner = THIS_MODULE,				\198}199 200#define tps65090_REG_FIXEDV(_id, _sname, en_reg, _en_bits, _volt, _ops) \201	tps65090_REG_DESC(_id, _sname, en_reg, _en_bits, 1, _volt, _ops)202 203#define tps65090_REG_SWITCH(_id, _sname, en_reg, _en_bits, _ops) \204	tps65090_REG_DESC(_id, _sname, en_reg, _en_bits, 0, 0, _ops)205 206static struct regulator_desc tps65090_regulator_desc[] = {207	tps65090_REG_FIXEDV(DCDC1, "vsys1",   0x0C, BIT(CTRL_EN_BIT), 5000000,208			    tps65090_reg_control_ops),209	tps65090_REG_FIXEDV(DCDC2, "vsys2",   0x0D, BIT(CTRL_EN_BIT), 3300000,210			    tps65090_reg_control_ops),211	tps65090_REG_SWITCH(DCDC3, "vsys3",   0x0E, BIT(CTRL_EN_BIT),212			    tps65090_reg_control_ops),213 214	tps65090_REG_SWITCH(FET1,  "infet1",  0x0F,215			    BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),216			    tps65090_fet_control_ops),217	tps65090_REG_SWITCH(FET2,  "infet2",  0x10,218			    BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),219			    tps65090_fet_control_ops),220	tps65090_REG_SWITCH(FET3,  "infet3",  0x11,221			    BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),222			    tps65090_fet_control_ops),223	tps65090_REG_SWITCH(FET4,  "infet4",  0x12,224			    BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),225			    tps65090_fet_control_ops),226	tps65090_REG_SWITCH(FET5,  "infet5",  0x13,227			    BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),228			    tps65090_fet_control_ops),229	tps65090_REG_SWITCH(FET6,  "infet6",  0x14,230			    BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),231			    tps65090_fet_control_ops),232	tps65090_REG_SWITCH(FET7,  "infet7",  0x15,233			    BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),234			    tps65090_fet_control_ops),235 236	tps65090_REG_FIXEDV(LDO1,  "vsys-l1", 0, 0, 5000000,237			    tps65090_ldo_ops),238	tps65090_REG_FIXEDV(LDO2,  "vsys-l2", 0, 0, 3300000,239			    tps65090_ldo_ops),240};241 242static inline bool is_dcdc(int id)243{244	switch (id) {245	case TPS65090_REGULATOR_DCDC1:246	case TPS65090_REGULATOR_DCDC2:247	case TPS65090_REGULATOR_DCDC3:248		return true;249	default:250		return false;251	}252}253 254static int tps65090_config_ext_control(255	struct tps65090_regulator *ri, bool enable)256{257	int ret;258	struct device *parent = ri->dev->parent;259	unsigned int reg_en_reg = ri->desc->enable_reg;260 261	if (enable)262		ret = tps65090_set_bits(parent, reg_en_reg, 1);263	else264		ret =  tps65090_clr_bits(parent, reg_en_reg, 1);265	if (ret < 0)266		dev_err(ri->dev, "Error in updating reg 0x%x\n", reg_en_reg);267	return ret;268}269 270static int tps65090_regulator_disable_ext_control(271		struct tps65090_regulator *ri,272		struct tps65090_regulator_plat_data *tps_pdata)273{274	int ret = 0;275	struct device *parent = ri->dev->parent;276	unsigned int reg_en_reg = ri->desc->enable_reg;277 278	/*279	 * First enable output for internal control if require.280	 * And then disable external control.281	 */282	if (tps_pdata->reg_init_data->constraints.always_on ||283			tps_pdata->reg_init_data->constraints.boot_on) {284		ret =  tps65090_set_bits(parent, reg_en_reg, 0);285		if (ret < 0) {286			dev_err(ri->dev, "Error in set reg 0x%x\n", reg_en_reg);287			return ret;288		}289	}290	return tps65090_config_ext_control(ri, false);291}292 293#ifdef CONFIG_OF294static struct of_regulator_match tps65090_matches[] = {295	{ .name = "dcdc1", },296	{ .name = "dcdc2", },297	{ .name = "dcdc3", },298	{ .name = "fet1",  },299	{ .name = "fet2",  },300	{ .name = "fet3",  },301	{ .name = "fet4",  },302	{ .name = "fet5",  },303	{ .name = "fet6",  },304	{ .name = "fet7",  },305	{ .name = "ldo1",  },306	{ .name = "ldo2",  },307};308 309static struct tps65090_platform_data *tps65090_parse_dt_reg_data(310		struct platform_device *pdev,311		struct of_regulator_match **tps65090_reg_matches)312{313	struct tps65090_platform_data *tps65090_pdata;314	struct device_node *np = pdev->dev.parent->of_node;315	struct device_node *regulators;316	int idx = 0, ret;317	struct tps65090_regulator_plat_data *reg_pdata;318 319	tps65090_pdata = devm_kzalloc(&pdev->dev, sizeof(*tps65090_pdata),320				GFP_KERNEL);321	if (!tps65090_pdata)322		return ERR_PTR(-ENOMEM);323 324	reg_pdata = devm_kcalloc(&pdev->dev,325				 TPS65090_REGULATOR_MAX, sizeof(*reg_pdata),326				 GFP_KERNEL);327	if (!reg_pdata)328		return ERR_PTR(-ENOMEM);329 330	regulators = of_get_child_by_name(np, "regulators");331	if (!regulators) {332		dev_err(&pdev->dev, "regulator node not found\n");333		return ERR_PTR(-ENODEV);334	}335 336	ret = of_regulator_match(&pdev->dev, regulators, tps65090_matches,337			ARRAY_SIZE(tps65090_matches));338	of_node_put(regulators);339	if (ret < 0) {340		dev_err(&pdev->dev,341			"Error parsing regulator init data: %d\n", ret);342		return ERR_PTR(ret);343	}344 345	*tps65090_reg_matches = tps65090_matches;346	for (idx = 0; idx < ARRAY_SIZE(tps65090_matches); idx++) {347		struct regulator_init_data *ri_data;348		struct tps65090_regulator_plat_data *rpdata;349		struct device_node *np;350 351		rpdata = &reg_pdata[idx];352		ri_data = tps65090_matches[idx].init_data;353		if (!ri_data)354			continue;355 356		np = tps65090_matches[idx].of_node;357		if (!np)358			continue;359 360		rpdata->reg_init_data = ri_data;361		rpdata->enable_ext_control = of_property_read_bool(np,362						"ti,enable-ext-control");363		if (rpdata->enable_ext_control) {364			enum gpiod_flags gflags;365 366			if (ri_data->constraints.always_on ||367			    ri_data->constraints.boot_on)368				gflags = GPIOD_OUT_HIGH;369			else370				gflags = GPIOD_OUT_LOW;371			gflags |= GPIOD_FLAGS_BIT_NONEXCLUSIVE;372 373			rpdata->gpiod = devm_fwnode_gpiod_get(374							&pdev->dev,375							of_fwnode_handle(np),376							"dcdc-ext-control",377							gflags,378							"tps65090");379			if (PTR_ERR(rpdata->gpiod) == -ENOENT) {380				dev_err(&pdev->dev,381					"could not find DCDC external control GPIO\n");382				rpdata->gpiod = NULL;383			} else if (IS_ERR(rpdata->gpiod))384				return ERR_CAST(rpdata->gpiod);385		}386 387		if (of_property_read_u32(np, "ti,overcurrent-wait",388					 &rpdata->overcurrent_wait) == 0)389			rpdata->overcurrent_wait_valid = true;390 391		tps65090_pdata->reg_pdata[idx] = rpdata;392	}393	return tps65090_pdata;394}395#else396static inline struct tps65090_platform_data *tps65090_parse_dt_reg_data(397			struct platform_device *pdev,398			struct of_regulator_match **tps65090_reg_matches)399{400	*tps65090_reg_matches = NULL;401	return NULL;402}403#endif404 405static int tps65090_regulator_probe(struct platform_device *pdev)406{407	struct tps65090 *tps65090_mfd = dev_get_drvdata(pdev->dev.parent);408	struct tps65090_regulator *ri = NULL;409	struct regulator_config config = { };410	struct regulator_dev *rdev;411	struct tps65090_regulator_plat_data *tps_pdata;412	struct tps65090_regulator *pmic;413	struct tps65090_platform_data *tps65090_pdata;414	struct of_regulator_match *tps65090_reg_matches = NULL;415	int num;416	int ret;417 418	dev_dbg(&pdev->dev, "Probing regulator\n");419 420	tps65090_pdata = dev_get_platdata(pdev->dev.parent);421	if (!tps65090_pdata && tps65090_mfd->dev->of_node)422		tps65090_pdata = tps65090_parse_dt_reg_data(pdev,423					&tps65090_reg_matches);424	if (IS_ERR_OR_NULL(tps65090_pdata)) {425		dev_err(&pdev->dev, "Platform data missing\n");426		return tps65090_pdata ? PTR_ERR(tps65090_pdata) : -EINVAL;427	}428 429	pmic = devm_kcalloc(&pdev->dev,430			    TPS65090_REGULATOR_MAX, sizeof(*pmic),431			    GFP_KERNEL);432	if (!pmic)433		return -ENOMEM;434 435	for (num = 0; num < TPS65090_REGULATOR_MAX; num++) {436		tps_pdata = tps65090_pdata->reg_pdata[num];437 438		ri = &pmic[num];439		ri->dev = &pdev->dev;440		ri->desc = &tps65090_regulator_desc[num];441		if (tps_pdata) {442			ri->overcurrent_wait_valid =443				tps_pdata->overcurrent_wait_valid;444			ri->overcurrent_wait = tps_pdata->overcurrent_wait;445		}446 447		/*448		 * TPS5090 DCDC support the control from external digital input.449		 * Configure it as per platform data.450		 */451		if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data) {452			if (tps_pdata->enable_ext_control) {453				config.ena_gpiod = tps_pdata->gpiod;454				ri->desc->ops = &tps65090_ext_control_ops;455			} else {456				ret = tps65090_regulator_disable_ext_control(457						ri, tps_pdata);458				if (ret < 0) {459					dev_err(&pdev->dev,460						"failed disable ext control\n");461					return ret;462				}463			}464		}465 466		config.dev = pdev->dev.parent;467		config.driver_data = ri;468		config.regmap = tps65090_mfd->rmap;469		if (tps_pdata)470			config.init_data = tps_pdata->reg_init_data;471		else472			config.init_data = NULL;473		if (tps65090_reg_matches)474			config.of_node = tps65090_reg_matches[num].of_node;475		else476			config.of_node = NULL;477 478		/*479		 * Hand the GPIO descriptor management over to the regulator480		 * core, remove it from devres management.481		 */482		if (config.ena_gpiod)483			devm_gpiod_unhinge(&pdev->dev, config.ena_gpiod);484		rdev = devm_regulator_register(&pdev->dev, ri->desc, &config);485		if (IS_ERR(rdev)) {486			dev_err(&pdev->dev, "failed to register regulator %s\n",487				ri->desc->name);488			return PTR_ERR(rdev);489		}490		ri->rdev = rdev;491 492		if (ri->overcurrent_wait_valid) {493			ret = tps65090_reg_set_overcurrent_wait(ri, rdev);494			if (ret < 0)495				return ret;496		}497 498		/* Enable external control if it is require */499		if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data &&500				tps_pdata->enable_ext_control) {501			ret = tps65090_config_ext_control(ri, true);502			if (ret < 0)503				return ret;504		}505	}506 507	platform_set_drvdata(pdev, pmic);508	return 0;509}510 511static struct platform_driver tps65090_regulator_driver = {512	.driver	= {513		.name	= "tps65090-pmic",514		.probe_type = PROBE_PREFER_ASYNCHRONOUS,515	},516	.probe		= tps65090_regulator_probe,517};518 519static int __init tps65090_regulator_init(void)520{521	return platform_driver_register(&tps65090_regulator_driver);522}523subsys_initcall(tps65090_regulator_init);524 525static void __exit tps65090_regulator_exit(void)526{527	platform_driver_unregister(&tps65090_regulator_driver);528}529module_exit(tps65090_regulator_exit);530 531MODULE_DESCRIPTION("tps65090 regulator driver");532MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>");533MODULE_LICENSE("GPL v2");534MODULE_ALIAS("platform:tps65090-pmic");535