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