brintos

brintos / linux-shallow public Read only

0
0
Text · 10.2 KiB · 3334b5b Raw
359 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * tps65023-regulator.c4 *5 * Supports TPS65023 Regulator6 *7 * Copyright (C) 2009 Texas Instrument Incorporated - https://www.ti.com/8 */9 10#include <linux/kernel.h>11#include <linux/module.h>12#include <linux/init.h>13#include <linux/err.h>14#include <linux/platform_device.h>15#include <linux/regulator/driver.h>16#include <linux/regulator/machine.h>17#include <linux/i2c.h>18#include <linux/slab.h>19#include <linux/regmap.h>20 21/* Register definitions */22#define	TPS65023_REG_VERSION		023#define	TPS65023_REG_PGOODZ		124#define	TPS65023_REG_MASK		225#define	TPS65023_REG_REG_CTRL		326#define	TPS65023_REG_CON_CTRL		427#define	TPS65023_REG_CON_CTRL2		528#define	TPS65023_REG_DEF_CORE		629#define	TPS65023_REG_DEFSLEW		730#define	TPS65023_REG_LDO_CTRL		831 32/* PGOODZ bitfields */33#define	TPS65023_PGOODZ_PWRFAILZ	BIT(7)34#define	TPS65023_PGOODZ_LOWBATTZ	BIT(6)35#define	TPS65023_PGOODZ_VDCDC1		BIT(5)36#define	TPS65023_PGOODZ_VDCDC2		BIT(4)37#define	TPS65023_PGOODZ_VDCDC3		BIT(3)38#define	TPS65023_PGOODZ_LDO2		BIT(2)39#define	TPS65023_PGOODZ_LDO1		BIT(1)40 41/* MASK bitfields */42#define	TPS65023_MASK_PWRFAILZ		BIT(7)43#define	TPS65023_MASK_LOWBATTZ		BIT(6)44#define	TPS65023_MASK_VDCDC1		BIT(5)45#define	TPS65023_MASK_VDCDC2		BIT(4)46#define	TPS65023_MASK_VDCDC3		BIT(3)47#define	TPS65023_MASK_LDO2		BIT(2)48#define	TPS65023_MASK_LDO1		BIT(1)49 50/* REG_CTRL bitfields */51#define TPS65023_REG_CTRL_VDCDC1_EN	BIT(5)52#define TPS65023_REG_CTRL_VDCDC2_EN	BIT(4)53#define TPS65023_REG_CTRL_VDCDC3_EN	BIT(3)54#define TPS65023_REG_CTRL_LDO2_EN	BIT(2)55#define TPS65023_REG_CTRL_LDO1_EN	BIT(1)56 57/* REG_CTRL2 bitfields */58#define TPS65023_REG_CTRL2_GO		BIT(7)59#define TPS65023_REG_CTRL2_CORE_ADJ	BIT(6)60#define TPS65023_REG_CTRL2_DCDC2	BIT(2)61#define TPS65023_REG_CTRL2_DCDC1	BIT(1)62#define TPS65023_REG_CTRL2_DCDC3	BIT(0)63 64/* Number of step-down converters available */65#define TPS65023_NUM_DCDC		366/* Number of LDO voltage regulators  available */67#define TPS65023_NUM_LDO		268/* Number of total regulators available */69#define TPS65023_NUM_REGULATOR	(TPS65023_NUM_DCDC + TPS65023_NUM_LDO)70 71/* DCDCs */72#define TPS65023_DCDC_1			073#define TPS65023_DCDC_2			174#define TPS65023_DCDC_3			275/* LDOs */76#define TPS65023_LDO_1			377#define TPS65023_LDO_2			478 79#define TPS65023_MAX_REG_ID		TPS65023_LDO_280 81#define TPS65023_REGULATOR_DCDC(_num, _t, _em)			\82	{							\83		.name		= "VDCDC"#_num,			\84		.of_match	= of_match_ptr("VDCDC"#_num),	\85		.regulators_node = of_match_ptr("regulators"),	\86		.id		= TPS65023_DCDC_##_num,		\87		.n_voltages     = ARRAY_SIZE(_t),		\88		.ops		= &tps65023_dcdc_ops,		\89		.type		= REGULATOR_VOLTAGE,		\90		.owner		= THIS_MODULE,			\91		.volt_table	= _t,				\92		.vsel_reg	= TPS65023_REG_DEF_CORE,	\93		.vsel_mask	= ARRAY_SIZE(_t) - 1,		\94		.enable_mask	= _em,				\95		.enable_reg	= TPS65023_REG_REG_CTRL,	\96		.apply_reg	= TPS65023_REG_CON_CTRL2,	\97		.apply_bit	= TPS65023_REG_CTRL2_GO,	\98	}							\99 100#define TPS65023_REGULATOR_LDO(_num, _t, _vm)			\101	{							\102		.name		= "LDO"#_num,			\103		.of_match	= of_match_ptr("LDO"#_num),	\104		.regulators_node = of_match_ptr("regulators"),	\105		.id		= TPS65023_LDO_##_num,		\106		.n_voltages     = ARRAY_SIZE(_t),		\107		.ops		= &tps65023_ldo_ops,		\108		.type		= REGULATOR_VOLTAGE,		\109		.owner		= THIS_MODULE,			\110		.volt_table	= _t,				\111		.vsel_reg	= TPS65023_REG_LDO_CTRL,	\112		.vsel_mask	= _vm,				\113		.enable_mask	= 1 << (_num),			\114		.enable_reg	= TPS65023_REG_REG_CTRL,	\115	}							\116 117/* Supported voltage values for regulators */118static const unsigned int VCORE_VSEL_table[] = {119	800000, 825000, 850000, 875000,120	900000, 925000, 950000, 975000,121	1000000, 1025000, 1050000, 1075000,122	1100000, 1125000, 1150000, 1175000,123	1200000, 1225000, 1250000, 1275000,124	1300000, 1325000, 1350000, 1375000,125	1400000, 1425000, 1450000, 1475000,126	1500000, 1525000, 1550000, 1600000,127};128 129static const unsigned int DCDC_FIXED_3300000_VSEL_table[] = {130	3300000,131};132 133static const unsigned int DCDC_FIXED_1800000_VSEL_table[] = {134	1800000,135};136 137/* Supported voltage values for LDO regulators for tps65020 */138static const unsigned int TPS65020_LDO_VSEL_table[] = {139	1000000, 1050000, 1100000, 1300000,140	1800000, 2500000, 3000000, 3300000,141};142 143/* Supported voltage values for LDO regulators144 * for tps65021 and tps65023 */145static const unsigned int TPS65023_LDO1_VSEL_table[] = {146	1000000, 1100000, 1300000, 1800000,147	2200000, 2600000, 2800000, 3150000,148};149 150static const unsigned int TPS65023_LDO2_VSEL_table[] = {151	1050000, 1200000, 1300000, 1800000,152	2500000, 2800000, 3000000, 3300000,153};154 155/* PMIC details */156struct tps_pmic {157	struct regulator_dev *rdev[TPS65023_NUM_REGULATOR];158	const struct tps_driver_data *driver_data;159	struct regmap *regmap;160};161 162/* Struct passed as driver data */163struct tps_driver_data {164	const struct regulator_desc *desc;165	u8 core_regulator;166};167 168static int tps65023_dcdc_get_voltage_sel(struct regulator_dev *dev)169{170	struct tps_pmic *tps = rdev_get_drvdata(dev);171	int dcdc = rdev_get_id(dev);172 173	if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)174		return -EINVAL;175 176	if (dcdc != tps->driver_data->core_regulator)177		return 0;178 179	return regulator_get_voltage_sel_regmap(dev);180}181 182static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev,183					 unsigned selector)184{185	struct tps_pmic *tps = rdev_get_drvdata(dev);186	int dcdc = rdev_get_id(dev);187 188	if (dcdc != tps->driver_data->core_regulator)189		return -EINVAL;190 191	return regulator_set_voltage_sel_regmap(dev, selector);192}193 194/* Operations permitted on VDCDCx */195static const struct regulator_ops tps65023_dcdc_ops = {196	.is_enabled = regulator_is_enabled_regmap,197	.enable = regulator_enable_regmap,198	.disable = regulator_disable_regmap,199	.get_voltage_sel = tps65023_dcdc_get_voltage_sel,200	.set_voltage_sel = tps65023_dcdc_set_voltage_sel,201	.list_voltage = regulator_list_voltage_table,202	.map_voltage = regulator_map_voltage_ascend,203};204 205/* Operations permitted on LDOx */206static const struct regulator_ops tps65023_ldo_ops = {207	.is_enabled = regulator_is_enabled_regmap,208	.enable = regulator_enable_regmap,209	.disable = regulator_disable_regmap,210	.get_voltage_sel = regulator_get_voltage_sel_regmap,211	.set_voltage_sel = regulator_set_voltage_sel_regmap,212	.list_voltage = regulator_list_voltage_table,213	.map_voltage = regulator_map_voltage_ascend,214};215 216static const struct regmap_config tps65023_regmap_config = {217	.reg_bits = 8,218	.val_bits = 8,219};220 221static const struct regulator_desc tps65020_regulators[] = {222	TPS65023_REGULATOR_DCDC(1, DCDC_FIXED_3300000_VSEL_table, 0x20),223	TPS65023_REGULATOR_DCDC(2, DCDC_FIXED_1800000_VSEL_table, 0x10),224	TPS65023_REGULATOR_DCDC(3, VCORE_VSEL_table, 0x08),225	TPS65023_REGULATOR_LDO(1, TPS65020_LDO_VSEL_table, 0x07),226	TPS65023_REGULATOR_LDO(2, TPS65020_LDO_VSEL_table, 0x70),227};228 229static const struct regulator_desc tps65021_regulators[] = {230	TPS65023_REGULATOR_DCDC(1, DCDC_FIXED_3300000_VSEL_table, 0x20),231	TPS65023_REGULATOR_DCDC(2, DCDC_FIXED_1800000_VSEL_table, 0x10),232	TPS65023_REGULATOR_DCDC(3, VCORE_VSEL_table, 0x08),233	TPS65023_REGULATOR_LDO(1, TPS65023_LDO1_VSEL_table, 0x07),234	TPS65023_REGULATOR_LDO(2, TPS65023_LDO2_VSEL_table, 0x70),235};236 237static const struct regulator_desc tps65023_regulators[] = {238	TPS65023_REGULATOR_DCDC(1, VCORE_VSEL_table, 0x20),239	TPS65023_REGULATOR_DCDC(2, DCDC_FIXED_3300000_VSEL_table, 0x10),240	TPS65023_REGULATOR_DCDC(3, DCDC_FIXED_1800000_VSEL_table, 0x08),241	TPS65023_REGULATOR_LDO(1, TPS65023_LDO1_VSEL_table, 0x07),242	TPS65023_REGULATOR_LDO(2, TPS65023_LDO2_VSEL_table, 0x70),243};244 245static const struct tps_driver_data tps65020_drv_data = {246	.desc = tps65020_regulators,247	.core_regulator = TPS65023_DCDC_3,248};249 250static const struct tps_driver_data tps65021_drv_data = {251	.desc = tps65021_regulators,252	.core_regulator = TPS65023_DCDC_3,253};254 255static const struct tps_driver_data tps65023_drv_data = {256	.desc = tps65023_regulators,257	.core_regulator = TPS65023_DCDC_1,258};259 260static int tps_65023_probe(struct i2c_client *client)261{262	const struct i2c_device_id *id = i2c_client_get_device_id(client);263	struct regulator_init_data *init_data = dev_get_platdata(&client->dev);264	struct regulator_config config = { };265	struct tps_pmic *tps;266	int i;267	int error;268 269	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);270	if (!tps)271		return -ENOMEM;272 273	tps->driver_data = (struct tps_driver_data *)id->driver_data;274 275	tps->regmap = devm_regmap_init_i2c(client, &tps65023_regmap_config);276	if (IS_ERR(tps->regmap)) {277		error = PTR_ERR(tps->regmap);278		dev_err(&client->dev, "Failed to allocate register map: %d\n",279			error);280		return error;281	}282 283	/* common for all regulators */284	config.dev = &client->dev;285	config.driver_data = tps;286	config.regmap = tps->regmap;287 288	for (i = 0; i < TPS65023_NUM_REGULATOR; i++) {289		if (init_data)290			config.init_data = &init_data[i];291 292		/* Register the regulators */293		tps->rdev[i] = devm_regulator_register(&client->dev,294					&tps->driver_data->desc[i], &config);295		if (IS_ERR(tps->rdev[i])) {296			dev_err(&client->dev, "failed to register %s\n",297				id->name);298			return PTR_ERR(tps->rdev[i]);299		}300	}301 302	i2c_set_clientdata(client, tps);303 304	/* Enable setting output voltage by I2C */305	regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,306			   TPS65023_REG_CTRL2_CORE_ADJ, 0);307 308	return 0;309}310 311static const struct of_device_id __maybe_unused tps65023_of_match[] = {312	{ .compatible = "ti,tps65020", .data = &tps65020_drv_data},313	{ .compatible = "ti,tps65021", .data = &tps65021_drv_data},314	{ .compatible = "ti,tps65023", .data = &tps65023_drv_data},315	{},316};317MODULE_DEVICE_TABLE(of, tps65023_of_match);318 319static const struct i2c_device_id tps_65023_id[] = {320	{321		.name = "tps65023",322		.driver_data = (kernel_ulong_t)&tps65023_drv_data323	}, {324		.name = "tps65021",325		.driver_data = (kernel_ulong_t)&tps65021_drv_data326	}, {327		.name = "tps65020",328		.driver_data = (kernel_ulong_t)&tps65020_drv_data329	},330	{ },331};332MODULE_DEVICE_TABLE(i2c, tps_65023_id);333 334static struct i2c_driver tps_65023_i2c_driver = {335	.driver = {336		.name = "tps65023",337		.probe_type = PROBE_PREFER_ASYNCHRONOUS,338		.of_match_table = of_match_ptr(tps65023_of_match),339	},340	.probe = tps_65023_probe,341	.id_table = tps_65023_id,342};343 344static int __init tps_65023_init(void)345{346	return i2c_add_driver(&tps_65023_i2c_driver);347}348subsys_initcall(tps_65023_init);349 350static void __exit tps_65023_cleanup(void)351{352	i2c_del_driver(&tps_65023_i2c_driver);353}354module_exit(tps_65023_cleanup);355 356MODULE_AUTHOR("Texas Instruments");357MODULE_DESCRIPTION("TPS65023 voltage regulator driver");358MODULE_LICENSE("GPL v2");359