File Index
Files and directories
Sign in
FILE

adp5055-regulator.c

File preview with syntax highlighting.

linux-6.19.14/drivers/regulator/adp5055-regulator.c C
  1// SPDX-License-Identifier: GPL-2.0
  2//
  3// Regulator driver for Analog Devices ADP5055
  4//
  5// Copyright (C) 2025 Analog Devices, Inc.
  6
  7#include <linux/bitfield.h>
  8#include <linux/device.h>
  9#include <linux/gpio/consumer.h>
 10#include <linux/i2c.h>
 11#include <linux/module.h>
 12#include <linux/mod_devicetable.h>
 13#include <linux/regmap.h>
 14#include <linux/regulator/driver.h>
 15#include <linux/regulator/machine.h>
 16#include <linux/regulator/of_regulator.h>
 17
 18// ADP5055 Register Map.
 19
 20#define ADP5055_CTRL123         0xD1
 21#define ADP5055_CTRL_MODE1      0xD3
 22#define ADP5055_CTRL_MODE2      0xD4
 23#define ADP5055_DLY0            0xD5
 24#define ADP5055_DLY1            0xD6
 25#define ADP5055_DLY2            0xD7
 26#define ADP5055_VID0            0xD8
 27#define ADP5055_VID1            0xD9
 28#define ADP5055_VID2            0xDA
 29#define ADP5055_DVS_LIM0        0xDC
 30#define ADP5055_DVS_LIM1        0xDD
 31#define ADP5055_DVS_LIM2        0xDE
 32#define ADP5055_FT_CFG          0xDF
 33#define ADP5055_PG_CFG          0xE0
 34
 35// ADP5055 Field Masks.
 36
 37#define	ADP5055_MASK_EN_MODE		BIT(0)
 38#define	ADP5055_MASK_OCP_BLANKING	BIT(7)
 39#define	ADP5055_MASK_PSM		BIT(4)
 40#define	ADP5055_MASK_DIS2		BIT(2)
 41#define	ADP5055_MASK_DIS1		BIT(1)
 42#define	ADP5055_MASK_DIS0		BIT(0)
 43#define	ADP5055_MASK_DIS_DLY		GENMASK(6, 4)
 44#define	ADP5055_MASK_EN_DLY		GENMASK(2, 0)
 45#define	ADP5055_MASK_DVS_LIM_UPPER	GENMASK(7, 4)
 46#define	ADP5055_MASK_DVS_LIM_LOWER	GENMASK(3, 0)
 47#define	ADP5055_MASK_FAST_TRANSIENT2	GENMASK(5, 4)
 48#define	ADP5055_MASK_FAST_TRANSIENT1	GENMASK(3, 2)
 49#define	ADP5055_MASK_FAST_TRANSIENT0	GENMASK(1, 0)
 50#define	ADP5055_MASK_DLY_PWRGD		BIT(4)
 51#define	ADP5055_MASK_PWRGD2		BIT(2)
 52#define	ADP5055_MASK_PWRGD1		BIT(1)
 53#define	ADP5055_MASK_PWRGD0		BIT(0)
 54
 55#define	ADP5055_MIN_VOUT		408000
 56#define ADP5055_NUM_CH			3
 57
 58struct adp5055 {
 59	struct device *dev;
 60	struct regmap *regmap;
 61	u32 tset;
 62	struct gpio_desc *en_gpiod[ADP5055_NUM_CH];
 63	bool en_mode_software;
 64	int dvs_limit_upper[ADP5055_NUM_CH];
 65	int dvs_limit_lower[ADP5055_NUM_CH];
 66	u32 fast_transient[ADP5055_NUM_CH];
 67	bool mask_power_good[ADP5055_NUM_CH];
 68};
 69
 70static const unsigned int adp5055_tset_vals[] = {
 71	2600,
 72	20800,
 73};
 74
 75static const unsigned int adp5055_enable_delay_vals_2_6[] = {
 76	0,
 77	2600,
 78	5200,
 79	7800,
 80	10400,
 81	13000,
 82	15600,
 83	18200,
 84};
 85
 86static const unsigned int adp5055_enable_delay_vals_20_8[] = {
 87	0,
 88	20800,
 89	41600,
 90	62400,
 91	83200,
 92	104000,
 93	124800,
 94	145600,
 95};
 96
 97static const char * const adp5055_fast_transient_vals[] = {
 98	"none",
 99	"3G_1.5%",
100	"5G_1.5%",
101	"5G_2.5%",
102};
103
104static int adp5055_get_prop_index(const u32 *table, size_t table_size,
105				  u32 value)
106{
107	int i;
108
109	for (i = 0; i < table_size; i++)
110		if (table[i] == value)
111			return i;
112
113	return -EINVAL;
114}
115
116static const struct regmap_range adp5055_reg_ranges[] = {
117	regmap_reg_range(0xD1, 0xE0),
118};
119
120static const struct regmap_access_table adp5055_access_ranges_table = {
121	.yes_ranges	= adp5055_reg_ranges,
122	.n_yes_ranges	= ARRAY_SIZE(adp5055_reg_ranges),
123};
124
125static const struct regmap_config adp5055_regmap_config = {
126	.reg_bits = 8,
127	.val_bits = 8,
128	.max_register = 0xE0,
129	.wr_table = &adp5055_access_ranges_table,
130	.rd_table = &adp5055_access_ranges_table,
131};
132
133static const struct linear_range adp5055_voltage_ranges[] = {
134	REGULATOR_LINEAR_RANGE(ADP5055_MIN_VOUT, 0, 255, 1500),
135};
136
137static int adp5055_parse_fw(struct device *dev, struct  adp5055 *adp5055)
138{
139	int i, ret;
140	struct regmap *regmap = adp5055->regmap;
141	int val;
142	bool ocp_blanking;
143	bool delay_power_good;
144
145	ret = device_property_read_u32(dev, "adi,tset-us", &adp5055->tset);
146	if (!ret) {
147		ret = adp5055_get_prop_index(adp5055_tset_vals,
148					ARRAY_SIZE(adp5055_tset_vals), adp5055->tset);
149		if (ret < 0)
150			return dev_err_probe(dev, ret,
151				"Failed to initialize tset.");
152		adp5055->tset = adp5055_tset_vals[ret];
153	}
154
155	ocp_blanking = device_property_read_bool(dev, "adi,ocp-blanking");
156
157	delay_power_good = device_property_read_bool(dev,
158				    "adi,delay-power-good");
159
160	for (i = 0; i < ADP5055_NUM_CH; i++) {
161		val = FIELD_PREP(ADP5055_MASK_DVS_LIM_UPPER,
162				DIV_ROUND_CLOSEST_ULL(192000 - adp5055->dvs_limit_upper[i], 12000));
163		val |= FIELD_PREP(ADP5055_MASK_DVS_LIM_LOWER,
164				DIV_ROUND_CLOSEST_ULL(adp5055->dvs_limit_lower[i] + 190500, 12000));
165		ret = regmap_write(regmap, ADP5055_DVS_LIM0 + i, val);
166		if (ret)
167			return ret;
168	}
169
170	val = FIELD_PREP(ADP5055_MASK_EN_MODE, adp5055->en_mode_software);
171	ret = regmap_write(regmap, ADP5055_CTRL_MODE1, val);
172	if (ret)
173		return ret;
174
175	val = FIELD_PREP(ADP5055_MASK_OCP_BLANKING, ocp_blanking);
176	ret = regmap_update_bits(regmap, ADP5055_CTRL_MODE2,
177				ADP5055_MASK_OCP_BLANKING, val);
178	if (ret)
179		return ret;
180
181	val = FIELD_PREP(ADP5055_MASK_FAST_TRANSIENT2, adp5055->fast_transient[2]);
182	val |= FIELD_PREP(ADP5055_MASK_FAST_TRANSIENT1, adp5055->fast_transient[1]);
183	val |= FIELD_PREP(ADP5055_MASK_FAST_TRANSIENT0, adp5055->fast_transient[0]);
184	ret = regmap_write(regmap, ADP5055_FT_CFG, val);
185	if (ret)
186		return ret;
187
188	val = FIELD_PREP(ADP5055_MASK_DLY_PWRGD, delay_power_good);
189	val |= FIELD_PREP(ADP5055_MASK_PWRGD2, adp5055->mask_power_good[2]);
190	val |= FIELD_PREP(ADP5055_MASK_PWRGD1, adp5055->mask_power_good[1]);
191	val |= FIELD_PREP(ADP5055_MASK_PWRGD0, adp5055->mask_power_good[0]);
192	ret = regmap_write(regmap, ADP5055_PG_CFG, val);
193	if (ret)
194		return ret;
195
196	return 0;
197}
198
199static int adp5055_of_parse_cb(struct device_node *np,
200			      const struct regulator_desc *desc,
201			      struct regulator_config *config)
202{
203	struct adp5055 *adp5055 = config->driver_data;
204	int id, ret, pval, i;
205
206	id = desc->id;
207
208	if (of_property_read_bool(np, "enable-gpios")) {
209		adp5055->en_gpiod[id] = devm_fwnode_gpiod_get(config->dev,
210						of_fwnode_handle(np), "enable",
211						GPIOD_OUT_LOW, "enable");
212		if (IS_ERR(adp5055->en_gpiod[id]))
213			return dev_err_probe(config->dev, PTR_ERR(adp5055->en_gpiod[id]),
214					"Failed to get enable GPIO\n");
215
216		config->ena_gpiod = adp5055->en_gpiod[id];
217	} else {
218		adp5055->en_mode_software = true;
219	}
220
221	ret = of_property_read_u32(np, "adi,dvs-limit-upper-microvolt", &pval);
222	if (ret)
223		adp5055->dvs_limit_upper[id] = 192000;
224	else
225		adp5055->dvs_limit_upper[id] = pval;
226
227	if (adp5055->dvs_limit_upper[id] > 192000 || adp5055->dvs_limit_upper[id] < 12000)
228		return dev_err_probe(config->dev, adp5055->dvs_limit_upper[id],
229			"Out of range - dvs-limit-upper-microvolt value.");
230
231	ret = of_property_read_u32(np, "adi,dvs-limit-lower-microvolt", &pval);
232	if (ret)
233		adp5055->dvs_limit_lower[id] = -190500;
234	else
235		adp5055->dvs_limit_lower[id] = pval;
236
237	if (adp5055->dvs_limit_lower[id] > -10500 || adp5055->dvs_limit_lower[id] < -190500)
238		return dev_err_probe(config->dev, adp5055->dvs_limit_lower[id],
239			"Out of range - dvs-limit-lower-microvolt value.");
240
241	for (i = 0; i < 4; i++) {
242		ret = of_property_match_string(np, "adi,fast-transient",
243					adp5055_fast_transient_vals[i]);
244		if (!ret)
245			break;
246	}
247
248	if (ret < 0)
249		adp5055->fast_transient[id] = 3;
250	else
251		adp5055->fast_transient[id] = i;
252
253	adp5055->mask_power_good[id] = of_property_read_bool(np, "adi,mask-power-good");
254
255	return 0;
256}
257
258static int adp5055_set_mode(struct regulator_dev *rdev, u32 mode)
259{
260	struct adp5055 *adp5055 = rdev_get_drvdata(rdev);
261	int id, ret;
262
263	id = rdev_get_id(rdev);
264
265	switch (mode) {
266	case REGULATOR_MODE_NORMAL:
267		ret = regmap_update_bits(adp5055->regmap, ADP5055_CTRL_MODE2,
268					ADP5055_MASK_PSM << id, 0);
269		break;
270	case REGULATOR_MODE_IDLE:
271		ret = regmap_update_bits(adp5055->regmap, ADP5055_CTRL_MODE2,
272					ADP5055_MASK_PSM << id, ADP5055_MASK_PSM << id);
273		break;
274	default:
275		return dev_err_probe(&rdev->dev, -EINVAL,
276				"Unsupported mode: %d\n", mode);
277	}
278
279	return ret;
280}
281
282static unsigned int adp5055_get_mode(struct regulator_dev *rdev)
283{
284	struct adp5055 *adp5055 = rdev_get_drvdata(rdev);
285	int id, ret, regval;
286
287	id = rdev_get_id(rdev);
288
289	ret = regmap_read(adp5055->regmap, ADP5055_CTRL_MODE2, &regval);
290	if (ret)
291		return ret;
292
293	if (regval & (ADP5055_MASK_PSM << id))
294		return REGULATOR_MODE_IDLE;
295	else
296		return REGULATOR_MODE_NORMAL;
297}
298
299static const struct regulator_ops adp5055_ops = {
300	.list_voltage = regulator_list_voltage_linear_range,
301	.map_voltage = regulator_map_voltage_linear_range,
302	.set_voltage_sel = regulator_set_voltage_sel_regmap,
303	.get_voltage_sel = regulator_get_voltage_sel_regmap,
304	.set_active_discharge = regulator_set_active_discharge_regmap,
305	.enable = regulator_enable_regmap,
306	.disable = regulator_disable_regmap,
307	.is_enabled = regulator_is_enabled_regmap,
308	.set_mode = adp5055_set_mode,
309	.get_mode = adp5055_get_mode,
310	.set_ramp_delay = regulator_set_ramp_delay_regmap,
311};
312
313#define ADP5055_REG_(_name, _id, _ch, _ops) \
314	[_id] = { \
315		.name = _name, \
316		.of_match = of_match_ptr(_name), \
317		.of_parse_cb = adp5055_of_parse_cb, \
318		.id = _id, \
319		.ops = _ops, \
320		.linear_ranges = adp5055_voltage_ranges, \
321		.n_linear_ranges = ARRAY_SIZE(adp5055_voltage_ranges), \
322		.vsel_reg = ADP5055_VID##_ch, \
323		.vsel_mask = GENMASK(7, 0), \
324		.enable_reg = ADP5055_CTRL123, \
325		.enable_mask = BIT(_ch), \
326		.active_discharge_on = ADP5055_MASK_DIS##_id, \
327		.active_discharge_off = 0, \
328		.active_discharge_mask = ADP5055_MASK_DIS##_id, \
329		.active_discharge_reg = ADP5055_CTRL_MODE2, \
330		.ramp_reg = ADP5055_DLY##_ch, \
331		.ramp_mask = ADP5055_MASK_EN_DLY, \
332		.n_ramp_values = ARRAY_SIZE(adp5055_enable_delay_vals_2_6), \
333		.type = REGULATOR_VOLTAGE, \
334		.owner = THIS_MODULE, \
335	}
336
337#define ADP5055_REG(_name, _id, _ch) \
338	ADP5055_REG_(_name, _id, _ch, &adp5055_ops)
339
340static struct regulator_desc adp5055_regulators[] = {
341	ADP5055_REG("buck0", 0, 0),
342	ADP5055_REG("buck1", 1, 1),
343	ADP5055_REG("buck2", 2, 2),
344};
345
346static int adp5055_probe(struct i2c_client *client)
347{
348	struct regulator_init_data *init_data;
349	struct device *dev = &client->dev;
350	struct adp5055 *adp5055;
351	int i, ret;
352
353	init_data = of_get_regulator_init_data(dev, client->dev.of_node,
354					       &adp5055_regulators[0]);
355	if (!init_data)
356		return -EINVAL;
357
358	adp5055 = devm_kzalloc(dev, sizeof(struct adp5055), GFP_KERNEL);
359	if (!adp5055)
360		return -ENOMEM;
361
362	adp5055->tset = 2600;
363	adp5055->en_mode_software = false;
364
365	adp5055->regmap = devm_regmap_init_i2c(client, &adp5055_regmap_config);
366	if (IS_ERR(adp5055->regmap))
367		return dev_err_probe(dev, PTR_ERR(adp5055->regmap), "Failed to allocate reg map");
368
369	for (i = 0; i < ADP5055_NUM_CH; i++) {
370		const struct regulator_desc *desc;
371		struct regulator_config config = { };
372		struct regulator_dev *rdev;
373
374		if (adp5055->tset == 2600)
375			adp5055_regulators[i].ramp_delay_table = adp5055_enable_delay_vals_2_6;
376		else
377			adp5055_regulators[i].ramp_delay_table = adp5055_enable_delay_vals_20_8;
378
379		desc = &adp5055_regulators[i];
380
381		config.dev = dev;
382		config.driver_data = adp5055;
383		config.regmap = adp5055->regmap;
384		config.init_data = init_data;
385
386		rdev = devm_regulator_register(dev, desc, &config);
387		if (IS_ERR(rdev)) {
388			return dev_err_probe(dev, PTR_ERR(rdev),
389					"Failed to register %s\n", desc->name);
390		}
391	}
392
393	ret = adp5055_parse_fw(dev, adp5055);
394	if (ret < 0)
395		return ret;
396
397	return 0;
398}
399
400static const struct of_device_id adp5055_of_match[] = {
401	{ .compatible = "adi,adp5055", },
402	{ }
403};
404MODULE_DEVICE_TABLE(of, adp5055_of_match);
405
406static const struct i2c_device_id adp5055_ids[] = {
407	{ .name = "adp5055"},
408	{ },
409};
410MODULE_DEVICE_TABLE(i2c, adp5055_ids);
411
412static struct i2c_driver adp5055_driver = {
413	.driver	= {
414		.name	= "adp5055",
415		.of_match_table = adp5055_of_match,
416	},
417	.probe		= adp5055_probe,
418	.id_table	= adp5055_ids,
419};
420module_i2c_driver(adp5055_driver);
421
422MODULE_DESCRIPTION("ADP5055 Voltage Regulator Driver");
423MODULE_AUTHOR("Alexis Czezar Torreno <alexisczezar.torreno@analog.com>");
424MODULE_LICENSE("GPL");
~/ Read-only file preview.