Linux 6.9-rc1
[linux-2.6-microblaze.git] / drivers / regulator / pv88080-regulator.c
1 // SPDX-License-Identifier: GPL-2.0+
2 //
3 // pv88080-regulator.c - Regulator device driver for PV88080
4 // Copyright (C) 2016  Powerventure Semiconductor Ltd.
5
6 #include <linux/err.h>
7 #include <linux/i2c.h>
8 #include <linux/mod_devicetable.h>
9 #include <linux/module.h>
10 #include <linux/of.h>
11 #include <linux/init.h>
12 #include <linux/slab.h>
13 #include <linux/regulator/driver.h>
14 #include <linux/regulator/machine.h>
15 #include <linux/regmap.h>
16 #include <linux/irq.h>
17 #include <linux/interrupt.h>
18 #include <linux/regulator/of_regulator.h>
19 #include "pv88080-regulator.h"
20
21 #define PV88080_MAX_REGULATORS  4
22
23 /* PV88080 REGULATOR IDs */
24 enum {
25         /* BUCKs */
26         PV88080_ID_BUCK1,
27         PV88080_ID_BUCK2,
28         PV88080_ID_BUCK3,
29         PV88080_ID_HVBUCK,
30 };
31
32 struct pv88080_regulator {
33         struct regulator_desc desc;
34         unsigned int mode_reg;
35         unsigned int conf2;
36         unsigned int conf5;
37 };
38
39 struct pv88080 {
40         struct device *dev;
41         struct regmap *regmap;
42         struct regulator_dev *rdev[PV88080_MAX_REGULATORS];
43         unsigned long type;
44         const struct pv88080_compatible_regmap *regmap_config;
45 };
46
47 struct pv88080_buck_voltage {
48         int min_uV;
49         int max_uV;
50         int uV_step;
51 };
52
53 struct pv88080_buck_regmap {
54         /* REGS */
55         int buck_enable_reg;
56         int buck_vsel_reg;
57         int buck_mode_reg;
58         int buck_limit_reg;
59         int buck_vdac_range_reg;
60         int buck_vrange_gain_reg;
61         /* MASKS */
62         int buck_enable_mask;
63         int buck_vsel_mask;
64         int buck_limit_mask;
65 };
66
67 struct pv88080_compatible_regmap {
68         /* BUCK1, 2, 3 */
69         struct pv88080_buck_regmap buck_regmap[PV88080_MAX_REGULATORS-1];
70         /* HVBUCK */
71         int hvbuck_enable_reg;
72         int hvbuck_vsel_reg;
73         int hvbuck_enable_mask;
74         int hvbuck_vsel_mask;
75 };
76
77 static const struct regmap_config pv88080_regmap_config = {
78         .reg_bits = 8,
79         .val_bits = 8,
80 };
81
82 /* Current limits array (in uA) for BUCK1, BUCK2, BUCK3.
83  * Entry indexes corresponds to register values.
84  */
85
86 static const unsigned int pv88080_buck1_limits[] = {
87         3230000, 5130000, 6960000, 8790000
88 };
89
90 static const unsigned int pv88080_buck23_limits[] = {
91         1496000, 2393000, 3291000, 4189000
92 };
93
94 static const struct pv88080_buck_voltage pv88080_buck_vol[2] = {
95         {
96                 .min_uV = 600000,
97                 .max_uV = 1393750,
98                 .uV_step = 6250,
99         },
100         {
101                 .min_uV = 1400000,
102                 .max_uV = 2193750,
103                 .uV_step = 6250,
104         },
105 };
106
107 static const struct pv88080_compatible_regmap pv88080_aa_regs = {
108         /* BUCK1 */
109         .buck_regmap[0] = {
110                 .buck_enable_reg      = PV88080AA_REG_BUCK1_CONF0,
111                 .buck_vsel_reg        = PV88080AA_REG_BUCK1_CONF0,
112                 .buck_mode_reg        = PV88080AA_REG_BUCK1_CONF1,
113                 .buck_limit_reg       = PV88080AA_REG_BUCK1_CONF1,
114                 .buck_vdac_range_reg  = PV88080AA_REG_BUCK1_CONF2,
115                 .buck_vrange_gain_reg = PV88080AA_REG_BUCK1_CONF5,
116                 .buck_enable_mask     = PV88080_BUCK1_EN,
117                 .buck_vsel_mask       = PV88080_VBUCK1_MASK,
118                 .buck_limit_mask      = PV88080_BUCK1_ILIM_MASK,
119         },
120         /* BUCK2 */
121         .buck_regmap[1] = {
122                 .buck_enable_reg      = PV88080AA_REG_BUCK2_CONF0,
123                 .buck_vsel_reg        = PV88080AA_REG_BUCK2_CONF0,
124                 .buck_mode_reg        = PV88080AA_REG_BUCK2_CONF1,
125                 .buck_limit_reg       = PV88080AA_REG_BUCK2_CONF1,
126                 .buck_vdac_range_reg  = PV88080AA_REG_BUCK2_CONF2,
127                 .buck_vrange_gain_reg = PV88080AA_REG_BUCK2_CONF5,
128                 .buck_enable_mask         = PV88080_BUCK2_EN,
129                 .buck_vsel_mask       = PV88080_VBUCK2_MASK,
130                 .buck_limit_mask      = PV88080_BUCK2_ILIM_MASK,
131         },
132         /* BUCK3 */
133         .buck_regmap[2] = {
134                 .buck_enable_reg          = PV88080AA_REG_BUCK3_CONF0,
135                 .buck_vsel_reg        = PV88080AA_REG_BUCK3_CONF0,
136                 .buck_mode_reg        = PV88080AA_REG_BUCK3_CONF1,
137                 .buck_limit_reg       = PV88080AA_REG_BUCK3_CONF1,
138                 .buck_vdac_range_reg  = PV88080AA_REG_BUCK3_CONF2,
139                 .buck_vrange_gain_reg = PV88080AA_REG_BUCK3_CONF5,
140                 .buck_enable_mask         = PV88080_BUCK3_EN,
141                 .buck_vsel_mask       = PV88080_VBUCK3_MASK,
142                 .buck_limit_mask      = PV88080_BUCK3_ILIM_MASK,
143         },
144         /* HVBUCK */
145         .hvbuck_enable_reg            = PV88080AA_REG_HVBUCK_CONF2,
146         .hvbuck_vsel_reg          = PV88080AA_REG_HVBUCK_CONF1,
147         .hvbuck_enable_mask       = PV88080_HVBUCK_EN,
148         .hvbuck_vsel_mask         = PV88080_VHVBUCK_MASK,
149 };
150
151 static const struct pv88080_compatible_regmap pv88080_ba_regs = {
152         /* BUCK1 */
153         .buck_regmap[0] = {
154                 .buck_enable_reg          = PV88080BA_REG_BUCK1_CONF0,
155                 .buck_vsel_reg        = PV88080BA_REG_BUCK1_CONF0,
156                 .buck_mode_reg        = PV88080BA_REG_BUCK1_CONF1,
157                 .buck_limit_reg       = PV88080BA_REG_BUCK1_CONF1,
158                 .buck_vdac_range_reg  = PV88080BA_REG_BUCK1_CONF2,
159                 .buck_vrange_gain_reg = PV88080BA_REG_BUCK1_CONF5,
160                 .buck_enable_mask     = PV88080_BUCK1_EN,
161                 .buck_vsel_mask       = PV88080_VBUCK1_MASK,
162                 .buck_limit_mask          = PV88080_BUCK1_ILIM_MASK,
163         },
164         /* BUCK2 */
165         .buck_regmap[1] = {
166                 .buck_enable_reg          = PV88080BA_REG_BUCK2_CONF0,
167                 .buck_vsel_reg        = PV88080BA_REG_BUCK2_CONF0,
168                 .buck_mode_reg        = PV88080BA_REG_BUCK2_CONF1,
169                 .buck_limit_reg       = PV88080BA_REG_BUCK2_CONF1,
170                 .buck_vdac_range_reg  = PV88080BA_REG_BUCK2_CONF2,
171                 .buck_vrange_gain_reg = PV88080BA_REG_BUCK2_CONF5,
172                 .buck_enable_mask         = PV88080_BUCK2_EN,
173                 .buck_vsel_mask       = PV88080_VBUCK2_MASK,
174                 .buck_limit_mask          = PV88080_BUCK2_ILIM_MASK,
175         },
176         /* BUCK3 */
177         .buck_regmap[2] = {
178                 .buck_enable_reg          = PV88080BA_REG_BUCK3_CONF0,
179                 .buck_vsel_reg        = PV88080BA_REG_BUCK3_CONF0,
180                 .buck_mode_reg        = PV88080BA_REG_BUCK3_CONF1,
181                 .buck_limit_reg       = PV88080BA_REG_BUCK3_CONF1,
182                 .buck_vdac_range_reg  = PV88080BA_REG_BUCK3_CONF2,
183                 .buck_vrange_gain_reg = PV88080BA_REG_BUCK3_CONF5,
184                 .buck_enable_mask         = PV88080_BUCK3_EN,
185                 .buck_vsel_mask       = PV88080_VBUCK3_MASK,
186                 .buck_limit_mask          = PV88080_BUCK3_ILIM_MASK,
187         },
188         /* HVBUCK */
189         .hvbuck_enable_reg            = PV88080BA_REG_HVBUCK_CONF2,
190         .hvbuck_vsel_reg          = PV88080BA_REG_HVBUCK_CONF1,
191         .hvbuck_enable_mask       = PV88080_HVBUCK_EN,
192         .hvbuck_vsel_mask                 = PV88080_VHVBUCK_MASK,
193 };
194
195 static unsigned int pv88080_buck_get_mode(struct regulator_dev *rdev)
196 {
197         struct pv88080_regulator *info = rdev_get_drvdata(rdev);
198         unsigned int data;
199         int ret, mode = 0;
200
201         ret = regmap_read(rdev->regmap, info->mode_reg, &data);
202         if (ret < 0)
203                 return ret;
204
205         switch (data & PV88080_BUCK1_MODE_MASK) {
206         case PV88080_BUCK_MODE_SYNC:
207                 mode = REGULATOR_MODE_FAST;
208                 break;
209         case PV88080_BUCK_MODE_AUTO:
210                 mode = REGULATOR_MODE_NORMAL;
211                 break;
212         case PV88080_BUCK_MODE_SLEEP:
213                 mode = REGULATOR_MODE_STANDBY;
214                 break;
215         default:
216                 return -EINVAL;
217         }
218
219         return mode;
220 }
221
222 static int pv88080_buck_set_mode(struct regulator_dev *rdev,
223                                         unsigned int mode)
224 {
225         struct pv88080_regulator *info = rdev_get_drvdata(rdev);
226         int val = 0;
227
228         switch (mode) {
229         case REGULATOR_MODE_FAST:
230                 val = PV88080_BUCK_MODE_SYNC;
231                 break;
232         case REGULATOR_MODE_NORMAL:
233                 val = PV88080_BUCK_MODE_AUTO;
234                 break;
235         case REGULATOR_MODE_STANDBY:
236                 val = PV88080_BUCK_MODE_SLEEP;
237                 break;
238         default:
239                 return -EINVAL;
240         }
241
242         return regmap_update_bits(rdev->regmap, info->mode_reg,
243                                         PV88080_BUCK1_MODE_MASK, val);
244 }
245
246 static const struct regulator_ops pv88080_buck_ops = {
247         .get_mode = pv88080_buck_get_mode,
248         .set_mode = pv88080_buck_set_mode,
249         .enable = regulator_enable_regmap,
250         .disable = regulator_disable_regmap,
251         .is_enabled = regulator_is_enabled_regmap,
252         .set_voltage_sel = regulator_set_voltage_sel_regmap,
253         .get_voltage_sel = regulator_get_voltage_sel_regmap,
254         .list_voltage = regulator_list_voltage_linear,
255         .set_current_limit = regulator_set_current_limit_regmap,
256         .get_current_limit = regulator_get_current_limit_regmap,
257 };
258
259 static const struct regulator_ops pv88080_hvbuck_ops = {
260         .enable = regulator_enable_regmap,
261         .disable = regulator_disable_regmap,
262         .is_enabled = regulator_is_enabled_regmap,
263         .set_voltage_sel = regulator_set_voltage_sel_regmap,
264         .get_voltage_sel = regulator_get_voltage_sel_regmap,
265         .list_voltage = regulator_list_voltage_linear,
266 };
267
268 #define PV88080_BUCK(chip, regl_name, min, step, max, limits_array) \
269 {\
270         .desc   =       {\
271                 .id = chip##_ID_##regl_name,\
272                 .name = __stringify(chip##_##regl_name),\
273                 .of_match = of_match_ptr(#regl_name),\
274                 .regulators_node = of_match_ptr("regulators"),\
275                 .type = REGULATOR_VOLTAGE,\
276                 .owner = THIS_MODULE,\
277                 .ops = &pv88080_buck_ops,\
278                 .min_uV = min, \
279                 .uV_step = step, \
280                 .n_voltages = ((max) - (min))/(step) + 1, \
281                 .curr_table = limits_array, \
282                 .n_current_limits = ARRAY_SIZE(limits_array), \
283         },\
284 }
285
286 #define PV88080_HVBUCK(chip, regl_name, min, step, max) \
287 {\
288         .desc   =       {\
289                 .id = chip##_ID_##regl_name,\
290                 .name = __stringify(chip##_##regl_name),\
291                 .of_match = of_match_ptr(#regl_name),\
292                 .regulators_node = of_match_ptr("regulators"),\
293                 .type = REGULATOR_VOLTAGE,\
294                 .owner = THIS_MODULE,\
295                 .ops = &pv88080_hvbuck_ops,\
296                 .min_uV = min, \
297                 .uV_step = step, \
298                 .n_voltages = ((max) - (min))/(step) + 1, \
299         },\
300 }
301
302 static struct pv88080_regulator pv88080_regulator_info[] = {
303         PV88080_BUCK(PV88080, BUCK1, 600000, 6250, 1393750,
304                 pv88080_buck1_limits),
305         PV88080_BUCK(PV88080, BUCK2, 600000, 6250, 1393750,
306                 pv88080_buck23_limits),
307         PV88080_BUCK(PV88080, BUCK3, 600000, 6250, 1393750,
308                 pv88080_buck23_limits),
309         PV88080_HVBUCK(PV88080, HVBUCK, 0, 5000, 1275000),
310 };
311
312 static irqreturn_t pv88080_irq_handler(int irq, void *data)
313 {
314         struct pv88080 *chip = data;
315         int i, reg_val, err, ret = IRQ_NONE;
316
317         err = regmap_read(chip->regmap, PV88080_REG_EVENT_A, &reg_val);
318         if (err < 0)
319                 goto error_i2c;
320
321         if (reg_val & PV88080_E_VDD_FLT) {
322                 for (i = 0; i < PV88080_MAX_REGULATORS; i++) {
323                         if (chip->rdev[i] != NULL)
324                                 regulator_notifier_call_chain(chip->rdev[i],
325                                         REGULATOR_EVENT_UNDER_VOLTAGE,
326                                         NULL);
327                 }
328
329                 err = regmap_write(chip->regmap, PV88080_REG_EVENT_A,
330                         PV88080_E_VDD_FLT);
331                 if (err < 0)
332                         goto error_i2c;
333
334                 ret = IRQ_HANDLED;
335         }
336
337         if (reg_val & PV88080_E_OVER_TEMP) {
338                 for (i = 0; i < PV88080_MAX_REGULATORS; i++) {
339                         if (chip->rdev[i] != NULL)
340                                 regulator_notifier_call_chain(chip->rdev[i],
341                                         REGULATOR_EVENT_OVER_TEMP,
342                                         NULL);
343                 }
344
345                 err = regmap_write(chip->regmap, PV88080_REG_EVENT_A,
346                         PV88080_E_OVER_TEMP);
347                 if (err < 0)
348                         goto error_i2c;
349
350                 ret = IRQ_HANDLED;
351         }
352
353         return ret;
354
355 error_i2c:
356         dev_err(chip->dev, "I2C error : %d\n", err);
357         return IRQ_NONE;
358 }
359
360 /*
361  * I2C driver interface functions
362  */
363 static int pv88080_i2c_probe(struct i2c_client *i2c)
364 {
365         struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
366         struct pv88080 *chip;
367         const struct pv88080_compatible_regmap *regmap_config;
368         struct regulator_config config = { };
369         int i, error, ret;
370         unsigned int conf2, conf5;
371
372         chip = devm_kzalloc(&i2c->dev, sizeof(struct pv88080), GFP_KERNEL);
373         if (!chip)
374                 return -ENOMEM;
375
376         chip->dev = &i2c->dev;
377         chip->regmap = devm_regmap_init_i2c(i2c, &pv88080_regmap_config);
378         if (IS_ERR(chip->regmap)) {
379                 error = PTR_ERR(chip->regmap);
380                 dev_err(chip->dev, "Failed to allocate register map: %d\n",
381                         error);
382                 return error;
383         }
384
385         chip->regmap_config = i2c_get_match_data(i2c);
386         if (!chip->regmap_config)
387                 return -ENODEV;
388
389         i2c_set_clientdata(i2c, chip);
390
391         if (i2c->irq != 0) {
392                 ret = regmap_write(chip->regmap, PV88080_REG_MASK_A, 0xFF);
393                 if (ret < 0) {
394                         dev_err(chip->dev,
395                                 "Failed to mask A reg: %d\n", ret);
396                         return ret;
397                 }
398                 ret = regmap_write(chip->regmap, PV88080_REG_MASK_B, 0xFF);
399                 if (ret < 0) {
400                         dev_err(chip->dev,
401                                 "Failed to mask B reg: %d\n", ret);
402                         return ret;
403                 }
404                 ret = regmap_write(chip->regmap, PV88080_REG_MASK_C, 0xFF);
405                 if (ret < 0) {
406                         dev_err(chip->dev,
407                                 "Failed to mask C reg: %d\n", ret);
408                         return ret;
409                 }
410
411                 ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
412                                         pv88080_irq_handler,
413                                         IRQF_TRIGGER_LOW|IRQF_ONESHOT,
414                                         "pv88080", chip);
415                 if (ret != 0) {
416                         dev_err(chip->dev, "Failed to request IRQ: %d\n",
417                                 i2c->irq);
418                         return ret;
419                 }
420
421                 ret = regmap_update_bits(chip->regmap, PV88080_REG_MASK_A,
422                         PV88080_M_VDD_FLT | PV88080_M_OVER_TEMP, 0);
423                 if (ret < 0) {
424                         dev_err(chip->dev,
425                                 "Failed to update mask reg: %d\n", ret);
426                         return ret;
427                 }
428         } else {
429                 dev_warn(chip->dev, "No IRQ configured\n");
430         }
431
432         regmap_config = chip->regmap_config;
433         config.dev = chip->dev;
434         config.regmap = chip->regmap;
435
436         /* Registeration for BUCK1, 2, 3 */
437         for (i = 0; i < PV88080_MAX_REGULATORS-1; i++) {
438                 if (init_data)
439                         config.init_data = &init_data[i];
440
441                 pv88080_regulator_info[i].desc.csel_reg
442                         = regmap_config->buck_regmap[i].buck_limit_reg;
443                 pv88080_regulator_info[i].desc.csel_mask
444                         = regmap_config->buck_regmap[i].buck_limit_mask;
445                 pv88080_regulator_info[i].mode_reg
446                         = regmap_config->buck_regmap[i].buck_mode_reg;
447                 pv88080_regulator_info[i].conf2
448                         = regmap_config->buck_regmap[i].buck_vdac_range_reg;
449                 pv88080_regulator_info[i].conf5
450                         = regmap_config->buck_regmap[i].buck_vrange_gain_reg;
451                 pv88080_regulator_info[i].desc.enable_reg
452                         = regmap_config->buck_regmap[i].buck_enable_reg;
453                 pv88080_regulator_info[i].desc.enable_mask
454                         = regmap_config->buck_regmap[i].buck_enable_mask;
455                 pv88080_regulator_info[i].desc.vsel_reg
456                         = regmap_config->buck_regmap[i].buck_vsel_reg;
457                 pv88080_regulator_info[i].desc.vsel_mask
458                         = regmap_config->buck_regmap[i].buck_vsel_mask;
459
460                 ret = regmap_read(chip->regmap,
461                                 pv88080_regulator_info[i].conf2, &conf2);
462                 if (ret < 0)
463                         return ret;
464                 conf2 = ((conf2 >> PV88080_BUCK_VDAC_RANGE_SHIFT) &
465                         PV88080_BUCK_VDAC_RANGE_MASK);
466
467                 ret = regmap_read(chip->regmap,
468                                 pv88080_regulator_info[i].conf5, &conf5);
469                 if (ret < 0)
470                         return ret;
471                 conf5 = ((conf5 >> PV88080_BUCK_VRANGE_GAIN_SHIFT) &
472                         PV88080_BUCK_VRANGE_GAIN_MASK);
473
474                 pv88080_regulator_info[i].desc.min_uV =
475                         pv88080_buck_vol[conf2].min_uV * (conf5+1);
476                 pv88080_regulator_info[i].desc.uV_step =
477                         pv88080_buck_vol[conf2].uV_step * (conf5+1);
478                 pv88080_regulator_info[i].desc.n_voltages =
479                         ((pv88080_buck_vol[conf2].max_uV * (conf5+1))
480                         - (pv88080_regulator_info[i].desc.min_uV))
481                         /(pv88080_regulator_info[i].desc.uV_step) + 1;
482
483                 config.driver_data = (void *)&pv88080_regulator_info[i];
484                 chip->rdev[i] = devm_regulator_register(chip->dev,
485                         &pv88080_regulator_info[i].desc, &config);
486                 if (IS_ERR(chip->rdev[i])) {
487                         dev_err(chip->dev,
488                                 "Failed to register PV88080 regulator\n");
489                         return PTR_ERR(chip->rdev[i]);
490                 }
491         }
492
493         pv88080_regulator_info[PV88080_ID_HVBUCK].desc.enable_reg
494                 = regmap_config->hvbuck_enable_reg;
495         pv88080_regulator_info[PV88080_ID_HVBUCK].desc.enable_mask
496                 = regmap_config->hvbuck_enable_mask;
497         pv88080_regulator_info[PV88080_ID_HVBUCK].desc.vsel_reg
498                 = regmap_config->hvbuck_vsel_reg;
499         pv88080_regulator_info[PV88080_ID_HVBUCK].desc.vsel_mask
500                 = regmap_config->hvbuck_vsel_mask;
501
502         /* Registeration for HVBUCK */
503         if (init_data)
504                 config.init_data = &init_data[PV88080_ID_HVBUCK];
505
506         config.driver_data = (void *)&pv88080_regulator_info[PV88080_ID_HVBUCK];
507         chip->rdev[PV88080_ID_HVBUCK] = devm_regulator_register(chip->dev,
508                 &pv88080_regulator_info[PV88080_ID_HVBUCK].desc, &config);
509         if (IS_ERR(chip->rdev[PV88080_ID_HVBUCK])) {
510                 dev_err(chip->dev, "Failed to register PV88080 regulator\n");
511                 return PTR_ERR(chip->rdev[PV88080_ID_HVBUCK]);
512         }
513
514         return 0;
515 }
516
517 static const struct of_device_id pv88080_dt_ids[] = {
518         { .compatible = "pvs,pv88080",    .data = &pv88080_aa_regs },
519         { .compatible = "pvs,pv88080-aa", .data = &pv88080_aa_regs },
520         { .compatible = "pvs,pv88080-ba", .data = &pv88080_ba_regs },
521         {}
522 };
523 MODULE_DEVICE_TABLE(of, pv88080_dt_ids);
524
525 static const struct i2c_device_id pv88080_i2c_id[] = {
526         { "pv88080",    (kernel_ulong_t)&pv88080_aa_regs },
527         { "pv88080-aa", (kernel_ulong_t)&pv88080_aa_regs },
528         { "pv88080-ba", (kernel_ulong_t)&pv88080_ba_regs },
529         {}
530 };
531 MODULE_DEVICE_TABLE(i2c, pv88080_i2c_id);
532
533 static struct i2c_driver pv88080_regulator_driver = {
534         .driver = {
535                 .name = "pv88080",
536                 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
537                 .of_match_table = pv88080_dt_ids,
538         },
539         .probe = pv88080_i2c_probe,
540         .id_table = pv88080_i2c_id,
541 };
542
543 module_i2c_driver(pv88080_regulator_driver);
544
545 MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>");
546 MODULE_DESCRIPTION("Regulator device driver for Powerventure PV88080");
547 MODULE_LICENSE("GPL");