• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Device driver for regulators in MAX5970 and MAX5978 IC
4  *
5  * Copyright (c) 2022 9elements GmbH
6  *
7  * Author: Patrick Rudolph <patrick.rudolph@9elements.com>
8  */
9 
10 #include <linux/bitops.h>
11 #include <linux/device.h>
12 #include <linux/err.h>
13 #include <linux/module.h>
14 #include <linux/io.h>
15 #include <linux/of.h>
16 #include <linux/i2c.h>
17 #include <linux/regmap.h>
18 #include <linux/regulator/driver.h>
19 #include <linux/regulator/machine.h>
20 #include <linux/regulator/of_regulator.h>
21 #include <linux/platform_device.h>
22 
23 #include <linux/mfd/max5970.h>
24 
25 struct max5970_regulator {
26 	int num_switches, mon_rng, irng, shunt_micro_ohms, lim_uA;
27 	struct regmap *regmap;
28 };
29 
30 enum max597x_regulator_id {
31 	MAX597X_sw0,
32 	MAX597X_sw1,
33 };
34 
max597x_uvp_ovp_check_mode(struct regulator_dev * rdev,int severity)35 static int max597x_uvp_ovp_check_mode(struct regulator_dev *rdev, int severity)
36 {
37 	int ret, reg;
38 
39 	/* Status1 register contains the soft strap values sampled at POR */
40 	ret = regmap_read(rdev->regmap, MAX5970_REG_STATUS1, &reg);
41 	if (ret)
42 		return ret;
43 
44 	/* Check soft straps match requested mode */
45 	if (severity == REGULATOR_SEVERITY_PROT) {
46 		if (STATUS1_PROT(reg) != STATUS1_PROT_SHUTDOWN)
47 			return -EOPNOTSUPP;
48 
49 		return 0;
50 	}
51 	if (STATUS1_PROT(reg) == STATUS1_PROT_SHUTDOWN)
52 		return -EOPNOTSUPP;
53 
54 	return 0;
55 }
56 
max597x_set_vp(struct regulator_dev * rdev,int lim_uV,int severity,bool enable,bool overvoltage)57 static int max597x_set_vp(struct regulator_dev *rdev, int lim_uV, int severity,
58 			  bool enable, bool overvoltage)
59 {
60 	int off_h, off_l, reg, ret;
61 	struct max5970_regulator *data = rdev_get_drvdata(rdev);
62 	int channel = rdev_get_id(rdev);
63 
64 	if (overvoltage) {
65 		if (severity == REGULATOR_SEVERITY_WARN) {
66 			off_h = MAX5970_REG_CH_OV_WARN_H(channel);
67 			off_l = MAX5970_REG_CH_OV_WARN_L(channel);
68 		} else {
69 			off_h = MAX5970_REG_CH_OV_CRIT_H(channel);
70 			off_l = MAX5970_REG_CH_OV_CRIT_L(channel);
71 		}
72 	} else {
73 		if (severity == REGULATOR_SEVERITY_WARN) {
74 			off_h = MAX5970_REG_CH_UV_WARN_H(channel);
75 			off_l = MAX5970_REG_CH_UV_WARN_L(channel);
76 		} else {
77 			off_h = MAX5970_REG_CH_UV_CRIT_H(channel);
78 			off_l = MAX5970_REG_CH_UV_CRIT_L(channel);
79 		}
80 	}
81 
82 	if (enable)
83 		/* reg = ADC_MASK * (lim_uV / 1000000) / (data->mon_rng / 1000000) */
84 		reg = ADC_MASK * lim_uV / data->mon_rng;
85 	else
86 		reg = 0;
87 
88 	ret = regmap_write(rdev->regmap, off_h, MAX5970_VAL2REG_H(reg));
89 	if (ret)
90 		return ret;
91 
92 	ret = regmap_write(rdev->regmap, off_l, MAX5970_VAL2REG_L(reg));
93 	if (ret)
94 		return ret;
95 
96 	return 0;
97 }
98 
max597x_set_uvp(struct regulator_dev * rdev,int lim_uV,int severity,bool enable)99 static int max597x_set_uvp(struct regulator_dev *rdev, int lim_uV, int severity,
100 			   bool enable)
101 {
102 	int ret;
103 
104 	/*
105 	 * MAX5970 has enable control as a special value in limit reg. Can't
106 	 * set limit but keep feature disabled or enable W/O given limit.
107 	 */
108 	if ((lim_uV && !enable) || (!lim_uV && enable))
109 		return -EINVAL;
110 
111 	ret = max597x_uvp_ovp_check_mode(rdev, severity);
112 	if (ret)
113 		return ret;
114 
115 	return max597x_set_vp(rdev, lim_uV, severity, enable, false);
116 }
117 
max597x_set_ovp(struct regulator_dev * rdev,int lim_uV,int severity,bool enable)118 static int max597x_set_ovp(struct regulator_dev *rdev, int lim_uV, int severity,
119 			   bool enable)
120 {
121 	int ret;
122 
123 	/*
124 	 * MAX5970 has enable control as a special value in limit reg. Can't
125 	 * set limit but keep feature disabled or enable W/O given limit.
126 	 */
127 	if ((lim_uV && !enable) || (!lim_uV && enable))
128 		return -EINVAL;
129 
130 	ret = max597x_uvp_ovp_check_mode(rdev, severity);
131 	if (ret)
132 		return ret;
133 
134 	return max597x_set_vp(rdev, lim_uV, severity, enable, true);
135 }
136 
max597x_set_ocp(struct regulator_dev * rdev,int lim_uA,int severity,bool enable)137 static int max597x_set_ocp(struct regulator_dev *rdev, int lim_uA,
138 			   int severity, bool enable)
139 {
140 	int val, reg;
141 	unsigned int vthst, vthfst;
142 
143 	struct max5970_regulator *data = rdev_get_drvdata(rdev);
144 	int rdev_id = rdev_get_id(rdev);
145 	/*
146 	 * MAX5970 doesn't has enable control for ocp.
147 	 * If limit is specified but enable is not set then hold the value in
148 	 * variable & later use it when ocp needs to be enabled.
149 	 */
150 	if (lim_uA != 0 && lim_uA != data->lim_uA)
151 		data->lim_uA = lim_uA;
152 
153 	if (severity != REGULATOR_SEVERITY_PROT)
154 		return -EINVAL;
155 
156 	if (enable) {
157 
158 		/* Calc Vtrip threshold in uV. */
159 		vthst =
160 		    div_u64(mul_u32_u32(data->shunt_micro_ohms, data->lim_uA),
161 			    1000000);
162 
163 		/*
164 		 * As recommended in datasheed, add 20% margin to avoid
165 		 * spurious event & passive component tolerance.
166 		 */
167 		vthst = div_u64(mul_u32_u32(vthst, 120), 100);
168 
169 		/* Calc fast Vtrip threshold in uV */
170 		vthfst = vthst * (MAX5970_FAST2SLOW_RATIO / 100);
171 
172 		if (vthfst > data->irng) {
173 			dev_err(&rdev->dev, "Current limit out of range\n");
174 			return -EINVAL;
175 		}
176 		/* Fast trip threshold to be programmed */
177 		val = div_u64(mul_u32_u32(0xFF, vthfst), data->irng);
178 	} else
179 		/*
180 		 * Since there is no option to disable ocp, set limit to max
181 		 * value
182 		 */
183 		val = 0xFF;
184 
185 	reg = MAX5970_REG_DAC_FAST(rdev_id);
186 
187 	return regmap_write(rdev->regmap, reg, val);
188 }
189 
max597x_get_status(struct regulator_dev * rdev)190 static int max597x_get_status(struct regulator_dev *rdev)
191 {
192 	int val, ret;
193 
194 	ret = regmap_read(rdev->regmap, MAX5970_REG_STATUS3, &val);
195 	if (ret)
196 		return ret;
197 
198 	if (val & MAX5970_STATUS3_ALERT)
199 		return REGULATOR_STATUS_ERROR;
200 
201 	ret = regulator_is_enabled_regmap(rdev);
202 	if (ret < 0)
203 		return ret;
204 
205 	if (ret)
206 		return REGULATOR_STATUS_ON;
207 
208 	return REGULATOR_STATUS_OFF;
209 }
210 
211 static const struct regulator_ops max597x_switch_ops = {
212 	.enable = regulator_enable_regmap,
213 	.disable = regulator_disable_regmap,
214 	.is_enabled = regulator_is_enabled_regmap,
215 	.get_status = max597x_get_status,
216 	.set_over_voltage_protection = max597x_set_ovp,
217 	.set_under_voltage_protection = max597x_set_uvp,
218 	.set_over_current_protection = max597x_set_ocp,
219 };
220 
max597x_dt_parse(struct device_node * np,const struct regulator_desc * desc,struct regulator_config * cfg)221 static int max597x_dt_parse(struct device_node *np,
222 			    const struct regulator_desc *desc,
223 			    struct regulator_config *cfg)
224 {
225 	struct max5970_regulator *data = cfg->driver_data;
226 	int ret = 0;
227 
228 	ret =
229 	    of_property_read_u32(np, "shunt-resistor-micro-ohms",
230 				 &data->shunt_micro_ohms);
231 	if (ret < 0)
232 		dev_err(cfg->dev,
233 			"property 'shunt-resistor-micro-ohms' not found, err %d\n",
234 			ret);
235 	return ret;
236 
237 }
238 
239 #define MAX597X_SWITCH(_ID, _ereg, _chan, _supply) {     \
240 	.name            = #_ID,                         \
241 	.of_match        = of_match_ptr(#_ID),           \
242 	.ops             = &max597x_switch_ops,          \
243 	.regulators_node = of_match_ptr("regulators"),   \
244 	.type            = REGULATOR_VOLTAGE,            \
245 	.id              = MAX597X_##_ID,                \
246 	.owner           = THIS_MODULE,                  \
247 	.supply_name     = _supply,                      \
248 	.enable_reg      = _ereg,                        \
249 	.enable_mask     = CHXEN((_chan)),               \
250 	.of_parse_cb	 = max597x_dt_parse,		 \
251 }
252 
253 static const struct regulator_desc regulators[] = {
254 	MAX597X_SWITCH(sw0, MAX5970_REG_CHXEN, 0, "vss1"),
255 	MAX597X_SWITCH(sw1, MAX5970_REG_CHXEN, 1, "vss2"),
256 };
257 
max597x_regmap_read_clear(struct regmap * map,unsigned int reg,unsigned int * val)258 static int max597x_regmap_read_clear(struct regmap *map, unsigned int reg,
259 				     unsigned int *val)
260 {
261 	int ret;
262 
263 	ret = regmap_read(map, reg, val);
264 	if (ret)
265 		return ret;
266 
267 	if (*val)
268 		return regmap_write(map, reg, 0);
269 
270 	return 0;
271 }
272 
max597x_irq_handler(int irq,struct regulator_irq_data * rid,unsigned long * dev_mask)273 static int max597x_irq_handler(int irq, struct regulator_irq_data *rid,
274 			       unsigned long *dev_mask)
275 {
276 	struct regulator_err_state *stat;
277 	struct max5970_regulator *d = (struct max5970_regulator *)rid->data;
278 	int val, ret, i;
279 
280 	ret = max597x_regmap_read_clear(d->regmap, MAX5970_REG_FAULT0, &val);
281 	if (ret)
282 		return REGULATOR_FAILED_RETRY;
283 
284 	*dev_mask = 0;
285 	for (i = 0; i < d->num_switches; i++) {
286 		stat = &rid->states[i];
287 		stat->notifs = 0;
288 		stat->errors = 0;
289 	}
290 
291 	for (i = 0; i < d->num_switches; i++) {
292 		stat = &rid->states[i];
293 
294 		if (val & UV_STATUS_CRIT(i)) {
295 			*dev_mask |= 1 << i;
296 			stat->notifs |= REGULATOR_EVENT_UNDER_VOLTAGE;
297 			stat->errors |= REGULATOR_ERROR_UNDER_VOLTAGE;
298 		} else if (val & UV_STATUS_WARN(i)) {
299 			*dev_mask |= 1 << i;
300 			stat->notifs |= REGULATOR_EVENT_UNDER_VOLTAGE_WARN;
301 			stat->errors |= REGULATOR_ERROR_UNDER_VOLTAGE_WARN;
302 		}
303 	}
304 
305 	ret = max597x_regmap_read_clear(d->regmap, MAX5970_REG_FAULT1, &val);
306 	if (ret)
307 		return REGULATOR_FAILED_RETRY;
308 
309 	for (i = 0; i < d->num_switches; i++) {
310 		stat = &rid->states[i];
311 
312 		if (val & OV_STATUS_CRIT(i)) {
313 			*dev_mask |= 1 << i;
314 			stat->notifs |= REGULATOR_EVENT_REGULATION_OUT;
315 			stat->errors |= REGULATOR_ERROR_REGULATION_OUT;
316 		} else if (val & OV_STATUS_WARN(i)) {
317 			*dev_mask |= 1 << i;
318 			stat->notifs |= REGULATOR_EVENT_OVER_VOLTAGE_WARN;
319 			stat->errors |= REGULATOR_ERROR_OVER_VOLTAGE_WARN;
320 		}
321 	}
322 
323 	ret = max597x_regmap_read_clear(d->regmap, MAX5970_REG_FAULT2, &val);
324 	if (ret)
325 		return REGULATOR_FAILED_RETRY;
326 
327 	for (i = 0; i < d->num_switches; i++) {
328 		stat = &rid->states[i];
329 
330 		if (val & OC_STATUS_WARN(i)) {
331 			*dev_mask |= 1 << i;
332 			stat->notifs |= REGULATOR_EVENT_OVER_CURRENT_WARN;
333 			stat->errors |= REGULATOR_ERROR_OVER_CURRENT_WARN;
334 		}
335 	}
336 
337 	ret = regmap_read(d->regmap, MAX5970_REG_STATUS0, &val);
338 	if (ret)
339 		return REGULATOR_FAILED_RETRY;
340 
341 	for (i = 0; i < d->num_switches; i++) {
342 		stat = &rid->states[i];
343 
344 		if ((val & MAX5970_CB_IFAULTF(i))
345 		    || (val & MAX5970_CB_IFAULTS(i))) {
346 			*dev_mask |= 1 << i;
347 			stat->notifs |=
348 			    REGULATOR_EVENT_OVER_CURRENT |
349 			    REGULATOR_EVENT_DISABLE;
350 			stat->errors |=
351 			    REGULATOR_ERROR_OVER_CURRENT | REGULATOR_ERROR_FAIL;
352 
353 			/* Clear the sub-IRQ status */
354 			regulator_disable_regmap(stat->rdev);
355 		}
356 	}
357 	return 0;
358 }
359 
max597x_adc_range(struct regmap * regmap,const int ch,u32 * irng,u32 * mon_rng)360 static int max597x_adc_range(struct regmap *regmap, const int ch,
361 			     u32 *irng, u32 *mon_rng)
362 {
363 	unsigned int reg;
364 	int ret;
365 
366 	/* Decode current ADC range */
367 	ret = regmap_read(regmap, MAX5970_REG_STATUS2, &reg);
368 	if (ret)
369 		return ret;
370 	switch (MAX5970_IRNG(reg, ch)) {
371 	case 0:
372 		*irng = 100000;	/* 100 mV */
373 		break;
374 	case 1:
375 		*irng = 50000;	/* 50 mV */
376 		break;
377 	case 2:
378 		*irng = 25000;	/* 25 mV */
379 		break;
380 	default:
381 		return -EINVAL;
382 	}
383 
384 	/* Decode current voltage monitor range */
385 	ret = regmap_read(regmap, MAX5970_REG_MON_RANGE, &reg);
386 	if (ret)
387 		return ret;
388 
389 	*mon_rng = MAX5970_MON_MAX_RANGE_UV >> MAX5970_MON(reg, ch);
390 
391 	return 0;
392 }
393 
max597x_setup_irq(struct device * dev,int irq,struct regulator_dev * rdevs[MAX5970_NUM_SWITCHES],int num_switches,struct max5970_regulator * data)394 static int max597x_setup_irq(struct device *dev,
395 			     int irq,
396 			     struct regulator_dev *rdevs[MAX5970_NUM_SWITCHES],
397 			     int num_switches, struct max5970_regulator *data)
398 {
399 	struct regulator_irq_desc max597x_notif = {
400 		.name = "max597x-irq",
401 		.map_event = max597x_irq_handler,
402 		.data = data,
403 	};
404 	int errs = REGULATOR_ERROR_UNDER_VOLTAGE |
405 	    REGULATOR_ERROR_UNDER_VOLTAGE_WARN |
406 	    REGULATOR_ERROR_OVER_VOLTAGE_WARN |
407 	    REGULATOR_ERROR_REGULATION_OUT |
408 	    REGULATOR_ERROR_OVER_CURRENT |
409 	    REGULATOR_ERROR_OVER_CURRENT_WARN | REGULATOR_ERROR_FAIL;
410 	void *irq_helper;
411 
412 	/* Register notifiers - can fail if IRQ is not given */
413 	irq_helper = devm_regulator_irq_helper(dev, &max597x_notif,
414 					       irq, 0, errs, NULL,
415 					       &rdevs[0], num_switches);
416 	if (IS_ERR(irq_helper)) {
417 		if (PTR_ERR(irq_helper) == -EPROBE_DEFER)
418 			return -EPROBE_DEFER;
419 
420 		dev_warn(dev, "IRQ disabled %pe\n", irq_helper);
421 	}
422 
423 	return 0;
424 }
425 
max597x_regulator_probe(struct platform_device * pdev)426 static int max597x_regulator_probe(struct platform_device *pdev)
427 {
428 	struct max5970_data *max597x;
429 	struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL);
430 	struct max5970_regulator *data;
431 	struct i2c_client *i2c = to_i2c_client(pdev->dev.parent);
432 	struct regulator_config config = { };
433 	struct regulator_dev *rdev;
434 	struct regulator_dev *rdevs[MAX5970_NUM_SWITCHES];
435 	int num_switches;
436 	int ret, i;
437 
438 	if (!regmap)
439 		return -EPROBE_DEFER;
440 
441 	max597x = devm_kzalloc(&i2c->dev, sizeof(struct max5970_data), GFP_KERNEL);
442 	if (!max597x)
443 		return -ENOMEM;
444 
445 	i2c_set_clientdata(i2c, max597x);
446 
447 	if (of_device_is_compatible(i2c->dev.of_node, "maxim,max5978"))
448 		max597x->num_switches = MAX5978_NUM_SWITCHES;
449 	else if (of_device_is_compatible(i2c->dev.of_node, "maxim,max5970"))
450 		max597x->num_switches = MAX5970_NUM_SWITCHES;
451 	else
452 		return -ENODEV;
453 
454 	i2c_set_clientdata(i2c, max597x);
455 	num_switches = max597x->num_switches;
456 
457 	for (i = 0; i < num_switches; i++) {
458 		data =
459 		    devm_kzalloc(&i2c->dev, sizeof(struct max5970_regulator),
460 				 GFP_KERNEL);
461 		if (!data)
462 			return -ENOMEM;
463 
464 		data->num_switches = num_switches;
465 		data->regmap = regmap;
466 
467 		ret = max597x_adc_range(regmap, i, &max597x->irng[i], &max597x->mon_rng[i]);
468 		if (ret < 0)
469 			return ret;
470 
471 		data->irng = max597x->irng[i];
472 		data->mon_rng = max597x->mon_rng[i];
473 
474 		config.dev = &i2c->dev;
475 		config.driver_data = (void *)data;
476 		config.regmap = data->regmap;
477 		rdev = devm_regulator_register(&i2c->dev,
478 					       &regulators[i], &config);
479 		if (IS_ERR(rdev)) {
480 			dev_err(&i2c->dev, "failed to register regulator %s\n",
481 				regulators[i].name);
482 			return PTR_ERR(rdev);
483 		}
484 		rdevs[i] = rdev;
485 		max597x->shunt_micro_ohms[i] = data->shunt_micro_ohms;
486 	}
487 
488 	if (i2c->irq) {
489 		ret =
490 		    max597x_setup_irq(&i2c->dev, i2c->irq, rdevs, num_switches,
491 				      data);
492 		if (ret) {
493 			dev_err(&i2c->dev, "IRQ setup failed");
494 			return ret;
495 		}
496 	}
497 
498 	return ret;
499 }
500 
501 static struct platform_driver max597x_regulator_driver = {
502 	.driver = {
503 		.name = "max5970-regulator",
504 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
505 	},
506 	.probe = max597x_regulator_probe,
507 };
508 
509 module_platform_driver(max597x_regulator_driver);
510 
511 
512 MODULE_AUTHOR("Patrick Rudolph <patrick.rudolph@9elements.com>");
513 MODULE_DESCRIPTION("MAX5970_hot-swap controller driver");
514 MODULE_LICENSE("GPL v2");
515