xref: /openbmc/linux/drivers/regulator/tps65219-regulator.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1  // SPDX-License-Identifier: GPL-2.0
2  //
3  // tps65219-regulator.c
4  //
5  // Regulator driver for TPS65219 PMIC
6  //
7  // Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
8  //
9  // This implementation derived from tps65218 authored by
10  // "J Keerthy <j-keerthy@ti.com>"
11  //
12  
13  #include <linux/kernel.h>
14  #include <linux/module.h>
15  #include <linux/device.h>
16  #include <linux/init.h>
17  #include <linux/err.h>
18  #include <linux/of.h>
19  #include <linux/platform_device.h>
20  #include <linux/regmap.h>
21  #include <linux/regulator/of_regulator.h>
22  #include <linux/regulator/driver.h>
23  #include <linux/regulator/machine.h>
24  #include <linux/mfd/tps65219.h>
25  
26  struct tps65219_regulator_irq_type {
27  	const char *irq_name;
28  	const char *regulator_name;
29  	const char *event_name;
30  	unsigned long event;
31  };
32  
33  static struct tps65219_regulator_irq_type tps65219_regulator_irq_types[] = {
34  	{ "LDO3_SCG", "LDO3", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
35  	{ "LDO3_OC", "LDO3", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
36  	{ "LDO3_UV", "LDO3", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
37  	{ "LDO4_SCG", "LDO4", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
38  	{ "LDO4_OC", "LDO4", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
39  	{ "LDO4_UV", "LDO4", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
40  	{ "LDO1_SCG", "LDO1", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
41  	{ "LDO1_OC", "LDO1", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
42  	{ "LDO1_UV", "LDO1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
43  	{ "LDO2_SCG", "LDO2", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
44  	{ "LDO2_OC", "LDO2", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
45  	{ "LDO2_UV", "LDO2", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
46  	{ "BUCK3_SCG", "BUCK3", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
47  	{ "BUCK3_OC", "BUCK3", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
48  	{ "BUCK3_NEG_OC", "BUCK3", "negative overcurrent", REGULATOR_EVENT_OVER_CURRENT },
49  	{ "BUCK3_UV", "BUCK3", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
50  	{ "BUCK1_SCG", "BUCK1", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
51  	{ "BUCK1_OC", "BUCK1", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
52  	{ "BUCK1_NEG_OC", "BUCK1", "negative overcurrent", REGULATOR_EVENT_OVER_CURRENT },
53  	{ "BUCK1_UV", "BUCK1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
54  	{ "BUCK2_SCG", "BUCK2", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
55  	{ "BUCK2_OC", "BUCK2", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
56  	{ "BUCK2_NEG_OC", "BUCK2", "negative overcurrent", REGULATOR_EVENT_OVER_CURRENT },
57  	{ "BUCK2_UV", "BUCK2", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
58  	{ "BUCK1_RV", "BUCK1", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
59  	{ "BUCK2_RV", "BUCK2", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
60  	{ "BUCK3_RV", "BUCK3", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
61  	{ "LDO1_RV", "LDO1", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
62  	{ "LDO2_RV", "LDO2", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
63  	{ "LDO3_RV", "LDO3", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
64  	{ "LDO4_RV", "LDO4", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
65  	{ "BUCK1_RV_SD", "BUCK1", "residual voltage on shutdown",
66  	 REGULATOR_EVENT_OVER_VOLTAGE_WARN },
67  	{ "BUCK2_RV_SD", "BUCK2", "residual voltage on shutdown",
68  	 REGULATOR_EVENT_OVER_VOLTAGE_WARN },
69  	{ "BUCK3_RV_SD", "BUCK3", "residual voltage on shutdown",
70  	 REGULATOR_EVENT_OVER_VOLTAGE_WARN },
71  	{ "LDO1_RV_SD", "LDO1", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
72  	{ "LDO2_RV_SD", "LDO2", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
73  	{ "LDO3_RV_SD", "LDO3", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
74  	{ "LDO4_RV_SD", "LDO4", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
75  	{ "SENSOR_3_WARM", "SENSOR3", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN},
76  	{ "SENSOR_2_WARM", "SENSOR2", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN },
77  	{ "SENSOR_1_WARM", "SENSOR1", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN },
78  	{ "SENSOR_0_WARM", "SENSOR0", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN },
79  	{ "SENSOR_3_HOT", "SENSOR3", "hot temperature", REGULATOR_EVENT_OVER_TEMP},
80  	{ "SENSOR_2_HOT", "SENSOR2", "hot temperature", REGULATOR_EVENT_OVER_TEMP },
81  	{ "SENSOR_1_HOT", "SENSOR1", "hot temperature", REGULATOR_EVENT_OVER_TEMP },
82  	{ "SENSOR_0_HOT", "SENSOR0", "hot temperature", REGULATOR_EVENT_OVER_TEMP },
83  	{ "TIMEOUT", "", "", REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE },
84  };
85  
86  struct tps65219_regulator_irq_data {
87  	struct device *dev;
88  	struct tps65219_regulator_irq_type *type;
89  	struct regulator_dev *rdev;
90  };
91  
92  #define TPS65219_REGULATOR(_name, _of, _id, _type, _ops, _n, _vr, _vm, _er, \
93  			   _em, _cr, _cm, _lr, _nlr, _delay, _fuv, \
94  			   _ct, _ncl, _bpm) \
95  	{								\
96  		.name			= _name,			\
97  		.of_match		= _of,				\
98  		.regulators_node	= of_match_ptr("regulators"),	\
99  		.supply_name		= _of,				\
100  		.id			= _id,				\
101  		.ops			= &(_ops),			\
102  		.n_voltages		= _n,				\
103  		.type			= _type,			\
104  		.owner			= THIS_MODULE,			\
105  		.vsel_reg		= _vr,				\
106  		.vsel_mask		= _vm,				\
107  		.csel_reg		= _cr,				\
108  		.csel_mask		= _cm,				\
109  		.curr_table		= _ct,				\
110  		.n_current_limits	= _ncl,				\
111  		.enable_reg		= _er,				\
112  		.enable_mask		= _em,				\
113  		.volt_table		= NULL,				\
114  		.linear_ranges		= _lr,				\
115  		.n_linear_ranges	= _nlr,				\
116  		.ramp_delay		= _delay,			\
117  		.fixed_uV		= _fuv,				\
118  		.bypass_reg		= _vr,				\
119  		.bypass_mask		= _bpm,				\
120  	}								\
121  
122  static const struct linear_range bucks_ranges[] = {
123  	REGULATOR_LINEAR_RANGE(600000, 0x0, 0x1f, 25000),
124  	REGULATOR_LINEAR_RANGE(1400000, 0x20, 0x33, 100000),
125  	REGULATOR_LINEAR_RANGE(3400000, 0x34, 0x3f, 0),
126  };
127  
128  static const struct linear_range ldos_1_2_ranges[] = {
129  	REGULATOR_LINEAR_RANGE(600000, 0x0, 0x37, 50000),
130  	REGULATOR_LINEAR_RANGE(3400000, 0x38, 0x3f, 0),
131  };
132  
133  static const struct linear_range ldos_3_4_ranges[] = {
134  	REGULATOR_LINEAR_RANGE(1200000, 0x0, 0xC, 0),
135  	REGULATOR_LINEAR_RANGE(1250000, 0xD, 0x35, 50000),
136  	REGULATOR_LINEAR_RANGE(3300000, 0x36, 0x3F, 0),
137  };
138  
tps65219_set_mode(struct regulator_dev * dev,unsigned int mode)139  static int tps65219_set_mode(struct regulator_dev *dev, unsigned int mode)
140  {
141  	struct tps65219 *tps = rdev_get_drvdata(dev);
142  
143  	switch (mode) {
144  	case REGULATOR_MODE_NORMAL:
145  		return regmap_set_bits(tps->regmap, TPS65219_REG_STBY_1_CONFIG,
146  				       dev->desc->enable_mask);
147  
148  	case REGULATOR_MODE_STANDBY:
149  		return regmap_clear_bits(tps->regmap,
150  					 TPS65219_REG_STBY_1_CONFIG,
151  					 dev->desc->enable_mask);
152  	default:
153  		return -EINVAL;
154  	}
155  }
156  
tps65219_get_mode(struct regulator_dev * dev)157  static unsigned int tps65219_get_mode(struct regulator_dev *dev)
158  {
159  	struct tps65219 *tps = rdev_get_drvdata(dev);
160  	unsigned int rid = rdev_get_id(dev);
161  	int ret, value = 0;
162  
163  	ret = regmap_read(tps->regmap, TPS65219_REG_STBY_1_CONFIG, &value);
164  	if (ret) {
165  		dev_dbg(tps->dev, "%s failed for regulator %s: %d ",
166  			__func__, dev->desc->name, ret);
167  		return ret;
168  	}
169  	value = (value & BIT(rid)) >> rid;
170  	if (value)
171  		return REGULATOR_MODE_STANDBY;
172  	else
173  		return REGULATOR_MODE_NORMAL;
174  }
175  
176  /* Operations permitted on BUCK1/2/3 */
177  static const struct regulator_ops tps65219_bucks_ops = {
178  	.is_enabled		= regulator_is_enabled_regmap,
179  	.enable			= regulator_enable_regmap,
180  	.disable		= regulator_disable_regmap,
181  	.set_mode		= tps65219_set_mode,
182  	.get_mode		= tps65219_get_mode,
183  	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
184  	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
185  	.list_voltage		= regulator_list_voltage_linear_range,
186  	.map_voltage		= regulator_map_voltage_linear_range,
187  	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
188  
189  };
190  
191  /* Operations permitted on LDO1/2 */
192  static const struct regulator_ops tps65219_ldos_1_2_ops = {
193  	.is_enabled		= regulator_is_enabled_regmap,
194  	.enable			= regulator_enable_regmap,
195  	.disable		= regulator_disable_regmap,
196  	.set_mode		= tps65219_set_mode,
197  	.get_mode		= tps65219_get_mode,
198  	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
199  	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
200  	.list_voltage		= regulator_list_voltage_linear_range,
201  	.map_voltage		= regulator_map_voltage_linear_range,
202  	.set_bypass		= regulator_set_bypass_regmap,
203  	.get_bypass		= regulator_get_bypass_regmap,
204  };
205  
206  /* Operations permitted on LDO3/4 */
207  static const struct regulator_ops tps65219_ldos_3_4_ops = {
208  	.is_enabled		= regulator_is_enabled_regmap,
209  	.enable			= regulator_enable_regmap,
210  	.disable		= regulator_disable_regmap,
211  	.set_mode		= tps65219_set_mode,
212  	.get_mode		= tps65219_get_mode,
213  	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
214  	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
215  	.list_voltage		= regulator_list_voltage_linear_range,
216  	.map_voltage		= regulator_map_voltage_linear_range,
217  };
218  
219  static const struct regulator_desc regulators[] = {
220  	TPS65219_REGULATOR("BUCK1", "buck1", TPS65219_BUCK_1,
221  			   REGULATOR_VOLTAGE, tps65219_bucks_ops, 64,
222  			   TPS65219_REG_BUCK1_VOUT,
223  			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
224  			   TPS65219_REG_ENABLE_CTRL,
225  			   TPS65219_ENABLE_BUCK1_EN_MASK, 0, 0, bucks_ranges,
226  			   3, 4000, 0, NULL, 0, 0),
227  	TPS65219_REGULATOR("BUCK2", "buck2", TPS65219_BUCK_2,
228  			   REGULATOR_VOLTAGE, tps65219_bucks_ops, 64,
229  			   TPS65219_REG_BUCK2_VOUT,
230  			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
231  			   TPS65219_REG_ENABLE_CTRL,
232  			   TPS65219_ENABLE_BUCK2_EN_MASK, 0, 0, bucks_ranges,
233  			   3, 4000, 0, NULL, 0, 0),
234  	TPS65219_REGULATOR("BUCK3", "buck3", TPS65219_BUCK_3,
235  			   REGULATOR_VOLTAGE, tps65219_bucks_ops, 64,
236  			   TPS65219_REG_BUCK3_VOUT,
237  			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
238  			   TPS65219_REG_ENABLE_CTRL,
239  			   TPS65219_ENABLE_BUCK3_EN_MASK, 0, 0, bucks_ranges,
240  			   3, 0, 0, NULL, 0, 0),
241  	TPS65219_REGULATOR("LDO1", "ldo1", TPS65219_LDO_1,
242  			   REGULATOR_VOLTAGE, tps65219_ldos_1_2_ops, 64,
243  			   TPS65219_REG_LDO1_VOUT,
244  			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
245  			   TPS65219_REG_ENABLE_CTRL,
246  			   TPS65219_ENABLE_LDO1_EN_MASK, 0, 0, ldos_1_2_ranges,
247  			   2, 0, 0, NULL, 0, TPS65219_LDOS_BYP_CONFIG_MASK),
248  	TPS65219_REGULATOR("LDO2", "ldo2", TPS65219_LDO_2,
249  			   REGULATOR_VOLTAGE, tps65219_ldos_1_2_ops, 64,
250  			   TPS65219_REG_LDO2_VOUT,
251  			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
252  			   TPS65219_REG_ENABLE_CTRL,
253  			   TPS65219_ENABLE_LDO2_EN_MASK, 0, 0, ldos_1_2_ranges,
254  			   2, 0, 0, NULL, 0, TPS65219_LDOS_BYP_CONFIG_MASK),
255  	TPS65219_REGULATOR("LDO3", "ldo3", TPS65219_LDO_3,
256  			   REGULATOR_VOLTAGE, tps65219_ldos_3_4_ops, 64,
257  			   TPS65219_REG_LDO3_VOUT,
258  			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
259  			   TPS65219_REG_ENABLE_CTRL,
260  			   TPS65219_ENABLE_LDO3_EN_MASK, 0, 0, ldos_3_4_ranges,
261  			   3, 0, 0, NULL, 0, 0),
262  	TPS65219_REGULATOR("LDO4", "ldo4", TPS65219_LDO_4,
263  			   REGULATOR_VOLTAGE, tps65219_ldos_3_4_ops, 64,
264  			   TPS65219_REG_LDO4_VOUT,
265  			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
266  			   TPS65219_REG_ENABLE_CTRL,
267  			   TPS65219_ENABLE_LDO4_EN_MASK, 0, 0, ldos_3_4_ranges,
268  			   3, 0, 0, NULL, 0, 0),
269  };
270  
tps65219_regulator_irq_handler(int irq,void * data)271  static irqreturn_t tps65219_regulator_irq_handler(int irq, void *data)
272  {
273  	struct tps65219_regulator_irq_data *irq_data = data;
274  
275  	if (irq_data->type->event_name[0] == '\0') {
276  		/* This is the timeout interrupt no specific regulator */
277  		dev_err(irq_data->dev,
278  			"System was put in shutdown due to timeout during an active or standby transition.\n");
279  		return IRQ_HANDLED;
280  	}
281  
282  	regulator_notifier_call_chain(irq_data->rdev,
283  				      irq_data->type->event, NULL);
284  
285  	dev_err(irq_data->dev, "Error IRQ trap %s for %s\n",
286  		irq_data->type->event_name, irq_data->type->regulator_name);
287  	return IRQ_HANDLED;
288  }
289  
tps65219_get_rdev_by_name(const char * regulator_name,struct regulator_dev * rdevtbl[7],struct regulator_dev ** dev)290  static int tps65219_get_rdev_by_name(const char *regulator_name,
291  				     struct regulator_dev *rdevtbl[7],
292  				     struct regulator_dev **dev)
293  {
294  	int i;
295  
296  	for (i = 0; i < ARRAY_SIZE(regulators); i++) {
297  		if (strcmp(regulator_name, regulators[i].name) == 0) {
298  			*dev = rdevtbl[i];
299  			return 0;
300  		}
301  	}
302  	return -EINVAL;
303  }
304  
tps65219_regulator_probe(struct platform_device * pdev)305  static int tps65219_regulator_probe(struct platform_device *pdev)
306  {
307  	struct tps65219 *tps = dev_get_drvdata(pdev->dev.parent);
308  	struct regulator_dev *rdev;
309  	struct regulator_config config = { };
310  	int i;
311  	int error;
312  	int irq;
313  	struct tps65219_regulator_irq_data *irq_data;
314  	struct tps65219_regulator_irq_type *irq_type;
315  	struct regulator_dev *rdevtbl[7];
316  
317  	config.dev = tps->dev;
318  	config.driver_data = tps;
319  	config.regmap = tps->regmap;
320  
321  	for (i = 0; i < ARRAY_SIZE(regulators); i++) {
322  		dev_dbg(tps->dev, "%s regul i= %d START", __func__, i);
323  		rdev = devm_regulator_register(&pdev->dev, &regulators[i],
324  					       &config);
325  		if (IS_ERR(rdev)) {
326  			dev_err(tps->dev, "failed to register %s regulator\n",
327  				regulators[i].name);
328  			return PTR_ERR(rdev);
329  		}
330  		rdevtbl[i] = rdev;
331  		dev_dbg(tps->dev, "%s regul i= %d COMPLETED", __func__, i);
332  	}
333  
334  	irq_data = devm_kmalloc(tps->dev,
335  				ARRAY_SIZE(tps65219_regulator_irq_types) *
336  				sizeof(struct tps65219_regulator_irq_data),
337  				GFP_KERNEL);
338  	if (!irq_data)
339  		return -ENOMEM;
340  
341  	for (i = 0; i < ARRAY_SIZE(tps65219_regulator_irq_types); ++i) {
342  		irq_type = &tps65219_regulator_irq_types[i];
343  
344  		irq = platform_get_irq_byname(pdev, irq_type->irq_name);
345  		if (irq < 0)
346  			return -EINVAL;
347  
348  		irq_data[i].dev = tps->dev;
349  		irq_data[i].type = irq_type;
350  
351  		tps65219_get_rdev_by_name(irq_type->regulator_name, rdevtbl, &rdev);
352  		if (IS_ERR(rdev)) {
353  			dev_err(tps->dev, "Failed to get rdev for %s\n",
354  				irq_type->regulator_name);
355  			return -EINVAL;
356  		}
357  		irq_data[i].rdev = rdev;
358  
359  		error = devm_request_threaded_irq(tps->dev, irq, NULL,
360  						  tps65219_regulator_irq_handler,
361  						  IRQF_ONESHOT,
362  						  irq_type->irq_name,
363  						  &irq_data[i]);
364  		if (error) {
365  			dev_err(tps->dev, "failed to request %s IRQ %d: %d\n",
366  				irq_type->irq_name, irq, error);
367  			return error;
368  		}
369  	}
370  
371  	return 0;
372  }
373  
374  static const struct platform_device_id tps65219_regulator_id_table[] = {
375  	{ "tps65219-regulator", },
376  	{ /* sentinel */ }
377  };
378  MODULE_DEVICE_TABLE(platform, tps65219_regulator_id_table);
379  
380  static struct platform_driver tps65219_regulator_driver = {
381  	.driver = {
382  		.name = "tps65219-pmic",
383  		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
384  	},
385  	.probe = tps65219_regulator_probe,
386  	.id_table = tps65219_regulator_id_table,
387  };
388  
389  module_platform_driver(tps65219_regulator_driver);
390  
391  MODULE_AUTHOR("Jerome Neanne <j-neanne@baylibre.com>");
392  MODULE_DESCRIPTION("TPS65219 voltage regulator driver");
393  MODULE_ALIAS("platform:tps65219-pmic");
394  MODULE_LICENSE("GPL");
395