xref: /linux/drivers/regulator/rt6190-regulator.c (revision d2c9a99135da931377240942d44f3dea104cedb8)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2022 Richtek Technology Corp.
4  *
5  * Author: ChiYuan Huang <cy_huang@richtek.com>
6  *
7  */
8 
9 #include <linux/bits.h>
10 #include <linux/delay.h>
11 #include <linux/gpio/consumer.h>
12 #include <linux/i2c.h>
13 #include <linux/interrupt.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/regmap.h>
18 #include <linux/regulator/consumer.h>
19 #include <linux/regulator/driver.h>
20 #include <linux/regulator/of_regulator.h>
21 
22 #define RT6190_REG_VID		0x00
23 #define RT6190_REG_OUTV		0x01
24 #define RT6190_REG_OUTC		0x03
25 #define RT6190_REG_SET1		0x0D
26 #define RT6190_REG_SET2		0x0E
27 #define RT6190_REG_SET4		0x10
28 #define RT6190_REG_RATIO	0x11
29 #define RT6190_REG_OUT_VOLT_L	0x12
30 #define RT6190_REG_TEMP_H	0x1B
31 #define RT6190_REG_STAT1	0x1C
32 #define RT6190_REG_ALERT1	0x1E
33 #define RT6190_REG_ALERT2	0x1F
34 #define RT6190_REG_MASK2	0x21
35 #define RT6190_REG_OCPEN	0x28
36 #define RT6190_REG_SET5		0x29
37 #define RT6190_REG_VBUSC_ADC	0x32
38 #define RT6190_REG_BUSC_VOLT_L	0x33
39 #define RT6190_REG_BUSC_VOLT_H	0x34
40 #define RT6190_REG_STAT3	0x37
41 #define RT6190_REG_ALERT3	0x38
42 #define RT6190_REG_MASK3	0x39
43 
44 #define RT6190_ENPWM_MASK	BIT(7)
45 #define RT6190_ENDCHG_MASK	BIT(4)
46 #define RT6190_ALERT_OTPEVT	BIT(6)
47 #define RT6190_ALERT_UVPEVT	BIT(5)
48 #define RT6190_ALERT_OVPEVT	BIT(4)
49 #define RT6190_ENGCP_MASK	BIT(1)
50 #define RT6190_FCCM_MASK	BIT(7)
51 
52 #define RICHTEK_VID		0x82
53 #define RT6190_OUT_MIN_UV	3000000
54 #define RT6190_OUT_MAX_UV	32000000
55 #define RT6190_OUT_STEP_UV	20000
56 #define RT6190_OUT_N_VOLT	(RT6190_OUT_MAX_UV / RT6190_OUT_STEP_UV + 1)
57 #define RT6190_OUTV_MINSEL	150
58 #define RT6190_OUT_MIN_UA	306000
59 #define RT6190_OUT_MAX_UA	12114000
60 #define RT6190_OUT_STEP_UA	24000
61 #define RT6190_OUTC_MINSEL	19
62 #define RT6190_EN_TIME_US	500
63 
64 #define RT6190_PSM_MODE		0
65 #define RT6190_FCCM_MODE	1
66 
67 struct rt6190_data {
68 	struct device *dev;
69 	struct regmap *regmap;
70 	struct gpio_desc *enable_gpio;
71 	unsigned int cached_alert_evt;
72 };
73 
rt6190_out_set_voltage_sel(struct regulator_dev * rdev,unsigned int selector)74 static int rt6190_out_set_voltage_sel(struct regulator_dev *rdev,
75 				      unsigned int selector)
76 {
77 	struct regmap *regmap = rdev_get_regmap(rdev);
78 	__le16 le_sel = cpu_to_le16(selector);
79 
80 	return regmap_raw_write(regmap, RT6190_REG_OUTV, &le_sel,
81 				sizeof(le_sel));
82 }
83 
rt6190_out_get_voltage_sel(struct regulator_dev * rdev)84 static int rt6190_out_get_voltage_sel(struct regulator_dev *rdev)
85 {
86 	struct regmap *regmap = rdev_get_regmap(rdev);
87 	__le16 le_sel;
88 	int ret;
89 
90 	ret = regmap_raw_read(regmap, RT6190_REG_OUTV, &le_sel, sizeof(le_sel));
91 
92 	return ret ?: le16_to_cpu(le_sel);
93 }
94 
rt6190_out_enable(struct regulator_dev * rdev)95 static int rt6190_out_enable(struct regulator_dev *rdev)
96 {
97 	struct rt6190_data *data = rdev_get_drvdata(rdev);
98 	struct regmap *regmap = rdev_get_regmap(rdev);
99 	u8 out_cfg[4];
100 	int ret;
101 
102 	pm_runtime_get_sync(data->dev);
103 
104 	/*
105 	 * From off to on, vout config will restore to IC default.
106 	 * Read vout configs before enable, and restore them after enable
107 	 */
108 	ret = regmap_raw_read(regmap, RT6190_REG_OUTV, out_cfg,
109 			      sizeof(out_cfg));
110 	if (ret)
111 		return ret;
112 
113 	ret = regulator_enable_regmap(rdev);
114 	if (ret)
115 		return ret;
116 
117 	ret = regmap_raw_write(regmap, RT6190_REG_OUTV, out_cfg,
118 			       sizeof(out_cfg));
119 	if (ret)
120 		return ret;
121 
122 	return regmap_update_bits(regmap, RT6190_REG_SET5, RT6190_ENGCP_MASK,
123 				  RT6190_ENGCP_MASK);
124 }
125 
rt6190_out_disable(struct regulator_dev * rdev)126 static int rt6190_out_disable(struct regulator_dev *rdev)
127 {
128 	struct rt6190_data *data = rdev_get_drvdata(rdev);
129 	struct regmap *regmap = rdev_get_regmap(rdev);
130 	int ret;
131 
132 	ret = regmap_update_bits(regmap, RT6190_REG_SET5, RT6190_ENGCP_MASK, 0);
133 	if (ret)
134 		return ret;
135 
136 	ret = regulator_disable_regmap(rdev);
137 	if (ret)
138 		return ret;
139 
140 	/* cleared cached alert event */
141 	data->cached_alert_evt = 0;
142 
143 	pm_runtime_put(data->dev);
144 
145 	return 0;
146 }
147 
rt6190_out_set_current_limit(struct regulator_dev * rdev,int min_uA,int max_uA)148 static int rt6190_out_set_current_limit(struct regulator_dev *rdev, int min_uA,
149 					int max_uA)
150 {
151 	struct regmap *regmap = rdev_get_regmap(rdev);
152 	int csel, clim;
153 	__le16 le_csel;
154 
155 	if (min_uA < RT6190_OUT_MIN_UA || max_uA > RT6190_OUT_MAX_UA)
156 		return -EINVAL;
157 
158 	csel = DIV_ROUND_UP(min_uA - RT6190_OUT_MIN_UA, RT6190_OUT_STEP_UA);
159 
160 	clim = RT6190_OUT_MIN_UA + RT6190_OUT_STEP_UA * csel;
161 	if (clim > max_uA)
162 		return -EINVAL;
163 
164 	csel += RT6190_OUTC_MINSEL;
165 	le_csel = cpu_to_le16(csel);
166 
167 	return regmap_raw_write(regmap, RT6190_REG_OUTC, &le_csel,
168 				sizeof(le_csel));
169 }
170 
rt6190_out_get_current_limit(struct regulator_dev * rdev)171 static int rt6190_out_get_current_limit(struct regulator_dev *rdev)
172 {
173 	struct regmap *regmap = rdev_get_regmap(rdev);
174 	__le16 le_csel;
175 	int csel, ret;
176 
177 	ret = regmap_raw_read(regmap, RT6190_REG_OUTC, &le_csel,
178 			      sizeof(le_csel));
179 	if (ret)
180 		return ret;
181 
182 	csel = le16_to_cpu(le_csel);
183 	csel -= RT6190_OUTC_MINSEL;
184 
185 	return RT6190_OUT_MIN_UA + RT6190_OUT_STEP_UA * csel;
186 }
187 
rt6190_out_set_mode(struct regulator_dev * rdev,unsigned int mode)188 static int rt6190_out_set_mode(struct regulator_dev *rdev, unsigned int mode)
189 {
190 	struct regmap *regmap = rdev_get_regmap(rdev);
191 	unsigned int val;
192 
193 	switch (mode) {
194 	case REGULATOR_MODE_FAST:
195 		val = RT6190_FCCM_MASK;
196 		break;
197 	case REGULATOR_MODE_NORMAL:
198 		val = 0;
199 		break;
200 	default:
201 		return -EINVAL;
202 	}
203 
204 	return regmap_update_bits(regmap, RT6190_REG_SET1, RT6190_FCCM_MASK,
205 				  val);
206 }
207 
rt6190_out_get_mode(struct regulator_dev * rdev)208 static unsigned int rt6190_out_get_mode(struct regulator_dev *rdev)
209 {
210 	struct regmap *regmap = rdev_get_regmap(rdev);
211 	unsigned int config;
212 	int ret;
213 
214 	ret = regmap_read(regmap, RT6190_REG_SET1, &config);
215 	if (ret)
216 		return REGULATOR_MODE_INVALID;
217 
218 	if (config & RT6190_FCCM_MASK)
219 		return REGULATOR_MODE_FAST;
220 
221 	return REGULATOR_MODE_NORMAL;
222 }
223 
rt6190_out_get_error_flags(struct regulator_dev * rdev,unsigned int * flags)224 static int rt6190_out_get_error_flags(struct regulator_dev *rdev,
225 				      unsigned int *flags)
226 {
227 	struct rt6190_data *data = rdev_get_drvdata(rdev);
228 	unsigned int state, rpt_flags = 0;
229 	int ret;
230 
231 	ret = regmap_read(data->regmap, RT6190_REG_STAT1, &state);
232 	if (ret)
233 		return ret;
234 
235 	state |= data->cached_alert_evt;
236 
237 	if (state & RT6190_ALERT_OTPEVT)
238 		rpt_flags |= REGULATOR_ERROR_OVER_TEMP;
239 
240 	if (state & RT6190_ALERT_UVPEVT)
241 		rpt_flags |= REGULATOR_ERROR_UNDER_VOLTAGE;
242 
243 	if (state & RT6190_ALERT_OVPEVT)
244 		rpt_flags |= REGULATOR_ERROR_REGULATION_OUT;
245 
246 	*flags = rpt_flags;
247 
248 	return 0;
249 }
250 
rt6190_out_of_map_mode(unsigned int mode)251 static unsigned int rt6190_out_of_map_mode(unsigned int mode)
252 {
253 	switch (mode) {
254 	case RT6190_PSM_MODE:
255 		return REGULATOR_MODE_NORMAL;
256 	case RT6190_FCCM_MODE:
257 		return REGULATOR_MODE_FAST;
258 	default:
259 		return REGULATOR_MODE_INVALID;
260 	}
261 }
262 
263 static const struct regulator_ops rt6190_regulator_ops = {
264 	.list_voltage = regulator_list_voltage_linear,
265 	.set_voltage_sel = rt6190_out_set_voltage_sel,
266 	.get_voltage_sel = rt6190_out_get_voltage_sel,
267 	.enable = rt6190_out_enable,
268 	.disable = rt6190_out_disable,
269 	.is_enabled = regulator_is_enabled_regmap,
270 	.set_current_limit = rt6190_out_set_current_limit,
271 	.get_current_limit = rt6190_out_get_current_limit,
272 	.set_active_discharge = regulator_set_active_discharge_regmap,
273 	.set_mode = rt6190_out_set_mode,
274 	.get_mode = rt6190_out_get_mode,
275 	.get_error_flags = rt6190_out_get_error_flags,
276 };
277 
278 static const struct regulator_desc rt6190_regulator_desc = {
279 	.name = "rt6190-regulator",
280 	.type = REGULATOR_VOLTAGE,
281 	.owner = THIS_MODULE,
282 	.ops = &rt6190_regulator_ops,
283 	.min_uV = RT6190_OUT_MIN_UV,
284 	.uV_step = RT6190_OUT_STEP_UV,
285 	.n_voltages = RT6190_OUT_N_VOLT,
286 	.linear_min_sel = RT6190_OUTV_MINSEL,
287 	.enable_reg = RT6190_REG_SET2,
288 	.enable_mask = RT6190_ENPWM_MASK,
289 	.active_discharge_reg = RT6190_REG_SET2,
290 	.active_discharge_mask = RT6190_ENDCHG_MASK,
291 	.active_discharge_on = RT6190_ENDCHG_MASK,
292 	.of_map_mode = rt6190_out_of_map_mode,
293 };
294 
rt6190_is_volatile_reg(struct device * dev,unsigned int reg)295 static bool rt6190_is_volatile_reg(struct device *dev, unsigned int reg)
296 {
297 	switch (reg) {
298 	case RT6190_REG_OUT_VOLT_L ... RT6190_REG_ALERT2:
299 	case RT6190_REG_BUSC_VOLT_L ... RT6190_REG_BUSC_VOLT_H:
300 	case RT6190_REG_STAT3 ... RT6190_REG_ALERT3:
301 		return true;
302 	default:
303 		return false;
304 	}
305 }
306 
307 static const struct regmap_config rt6190_regmap_config = {
308 	.name = "rt6190",
309 	.cache_type = REGCACHE_FLAT,
310 	.reg_bits = 8,
311 	.val_bits = 8,
312 	.max_register = RT6190_REG_MASK3,
313 	.num_reg_defaults_raw = RT6190_REG_MASK3 + 1,
314 	.volatile_reg = rt6190_is_volatile_reg,
315 };
316 
rt6190_irq_handler(int irq,void * devid)317 static irqreturn_t rt6190_irq_handler(int irq, void *devid)
318 {
319 	struct regulator_dev *rdev = devid;
320 	struct rt6190_data *data = rdev_get_drvdata(rdev);
321 	unsigned int alert;
322 	int ret;
323 
324 	ret = regmap_read(data->regmap, RT6190_REG_ALERT1, &alert);
325 	if (ret)
326 		return IRQ_NONE;
327 
328 	/* Write clear alert events */
329 	ret = regmap_write(data->regmap, RT6190_REG_ALERT1, alert);
330 	if (ret)
331 		return IRQ_NONE;
332 
333 	data->cached_alert_evt |= alert;
334 
335 	if (alert & RT6190_ALERT_OTPEVT)
336 		regulator_notifier_call_chain(rdev, REGULATOR_EVENT_OVER_TEMP, NULL);
337 
338 	if (alert & RT6190_ALERT_UVPEVT)
339 		regulator_notifier_call_chain(rdev, REGULATOR_EVENT_UNDER_VOLTAGE, NULL);
340 
341 	if (alert & RT6190_ALERT_OVPEVT)
342 		regulator_notifier_call_chain(rdev, REGULATOR_EVENT_REGULATION_OUT, NULL);
343 
344 	return IRQ_HANDLED;
345 }
346 
rt6190_init_registers(struct regmap * regmap)347 static int rt6190_init_registers(struct regmap *regmap)
348 {
349 	int ret;
350 
351 	/* Enable_ADC = 1 */
352 	ret = regmap_write(regmap, RT6190_REG_SET4, 0x82);
353 	if (ret)
354 		return ret;
355 
356 	/* Config default VOUT ratio to be higher */
357 	ret = regmap_write(regmap, RT6190_REG_RATIO, 0x20);
358 
359 	/* Mask unused alert */
360 	ret = regmap_write(regmap, RT6190_REG_MASK2, 0);
361 	if (ret)
362 		return ret;
363 
364 	/* OCP config */
365 	ret = regmap_write(regmap, RT6190_REG_OCPEN, 0);
366 	if (ret)
367 		return ret;
368 
369 	/* Enable VBUSC ADC */
370 	return regmap_write(regmap, RT6190_REG_VBUSC_ADC, 0x02);
371 }
372 
rt6190_probe(struct i2c_client * i2c)373 static int rt6190_probe(struct i2c_client *i2c)
374 {
375 	struct device *dev = &i2c->dev;
376 	struct rt6190_data *data;
377 	struct gpio_desc *enable_gpio;
378 	struct regmap *regmap;
379 	struct regulator_dev *rdev;
380 	struct regulator_config cfg = {};
381 	unsigned int vid;
382 	int ret;
383 
384 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
385 	if (!data)
386 		return -ENOMEM;
387 
388 	enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH);
389 	if (IS_ERR(enable_gpio))
390 		return dev_err_probe(dev, PTR_ERR(enable_gpio), "Failed to get 'enable' gpio\n");
391 	else if (enable_gpio)
392 		usleep_range(RT6190_EN_TIME_US, RT6190_EN_TIME_US * 2);
393 
394 	regmap = devm_regmap_init_i2c(i2c, &rt6190_regmap_config);
395 	if (IS_ERR(regmap))
396 		return dev_err_probe(dev, PTR_ERR(regmap), "Failed to init regmap\n");
397 
398 	data->dev = dev;
399 	data->enable_gpio = enable_gpio;
400 	data->regmap = regmap;
401 	i2c_set_clientdata(i2c, data);
402 
403 	ret = regmap_read(regmap, RT6190_REG_VID, &vid);
404 	if (ret)
405 		return dev_err_probe(dev, ret, "Failed to read VID\n");
406 
407 	if (vid != RICHTEK_VID)
408 		return dev_err_probe(dev, -ENODEV, "Incorrect VID 0x%02x\n", vid);
409 
410 	ret = rt6190_init_registers(regmap);
411 	if (ret)
412 		return dev_err_probe(dev, ret, "Failed to init registers\n");
413 
414 	pm_runtime_set_active(dev);
415 	ret = devm_pm_runtime_enable(dev);
416 	if (ret)
417 		return dev_err_probe(dev, ret, "Failed to set pm_runtime enable\n");
418 
419 	cfg.dev = dev;
420 	cfg.of_node = dev->of_node;
421 	cfg.driver_data = data;
422 	cfg.init_data = of_get_regulator_init_data(dev, dev->of_node,
423 						   &rt6190_regulator_desc);
424 
425 	rdev = devm_regulator_register(dev, &rt6190_regulator_desc, &cfg);
426 	if (IS_ERR(rdev))
427 		return dev_err_probe(dev, PTR_ERR(rdev), "Failed to register regulator\n");
428 
429 	if (i2c->irq) {
430 		ret = devm_request_threaded_irq(dev, i2c->irq, NULL,
431 						rt6190_irq_handler,
432 						IRQF_ONESHOT, dev_name(dev),
433 						rdev);
434 		if (ret)
435 			return dev_err_probe(dev, ret, "Failed to register interrupt\n");
436 	}
437 
438 	return 0;
439 }
440 
rt6190_runtime_suspend(struct device * dev)441 static int rt6190_runtime_suspend(struct device *dev)
442 {
443 	struct rt6190_data *data = dev_get_drvdata(dev);
444 	struct regmap *regmap = data->regmap;
445 
446 	if (!data->enable_gpio)
447 		return 0;
448 
449 	regcache_cache_only(regmap, true);
450 	regcache_mark_dirty(regmap);
451 
452 	gpiod_set_value(data->enable_gpio, 0);
453 
454 	return 0;
455 }
456 
rt6190_runtime_resume(struct device * dev)457 static int rt6190_runtime_resume(struct device *dev)
458 {
459 	struct rt6190_data *data = dev_get_drvdata(dev);
460 	struct regmap *regmap = data->regmap;
461 
462 	if (!data->enable_gpio)
463 		return 0;
464 
465 	gpiod_set_value(data->enable_gpio, 1);
466 	usleep_range(RT6190_EN_TIME_US, RT6190_EN_TIME_US * 2);
467 
468 	regcache_cache_only(regmap, false);
469 	return regcache_sync(regmap);
470 }
471 
472 static const struct dev_pm_ops __maybe_unused rt6190_dev_pm = {
473 	RUNTIME_PM_OPS(rt6190_runtime_suspend, rt6190_runtime_resume, NULL)
474 };
475 
476 static const struct of_device_id rt6190_of_dev_table[] = {
477 	{ .compatible = "richtek,rt6190" },
478 	{}
479 };
480 MODULE_DEVICE_TABLE(of, rt6190_of_dev_table);
481 
482 static struct i2c_driver rt6190_driver = {
483 	.driver = {
484 		.name = "rt6190",
485 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
486 		.of_match_table = rt6190_of_dev_table,
487 		.pm = pm_ptr(&rt6190_dev_pm),
488 	},
489 	.probe = rt6190_probe,
490 };
491 module_i2c_driver(rt6190_driver);
492 
493 MODULE_DESCRIPTION("Richtek RT6190 regulator driver");
494 MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
495 MODULE_LICENSE("GPL");
496