block: add QUEUE_FLAG_NOWAIT
[linux-2.6-microblaze.git] / drivers / regulator / vctrl-regulator.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Driver for voltage controller regulators
4  *
5  * Copyright (C) 2017 Google, Inc.
6  */
7
8 #include <linux/delay.h>
9 #include <linux/err.h>
10 #include <linux/init.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/of_device.h>
14 #include <linux/regulator/coupler.h>
15 #include <linux/regulator/driver.h>
16 #include <linux/regulator/of_regulator.h>
17 #include <linux/sort.h>
18
19 #include "internal.h"
20
21 struct vctrl_voltage_range {
22         int min_uV;
23         int max_uV;
24 };
25
26 struct vctrl_voltage_ranges {
27         struct vctrl_voltage_range ctrl;
28         struct vctrl_voltage_range out;
29 };
30
31 struct vctrl_voltage_table {
32         int ctrl;
33         int out;
34         int ovp_min_sel;
35 };
36
37 struct vctrl_data {
38         struct regulator_dev *rdev;
39         struct regulator_desc desc;
40         struct regulator *ctrl_reg;
41         bool enabled;
42         unsigned int min_slew_down_rate;
43         unsigned int ovp_threshold;
44         struct vctrl_voltage_ranges vrange;
45         struct vctrl_voltage_table *vtable;
46         unsigned int sel;
47 };
48
49 static int vctrl_calc_ctrl_voltage(struct vctrl_data *vctrl, int out_uV)
50 {
51         struct vctrl_voltage_range *ctrl = &vctrl->vrange.ctrl;
52         struct vctrl_voltage_range *out = &vctrl->vrange.out;
53
54         return ctrl->min_uV +
55                 DIV_ROUND_CLOSEST_ULL((s64)(out_uV - out->min_uV) *
56                                       (ctrl->max_uV - ctrl->min_uV),
57                                       out->max_uV - out->min_uV);
58 }
59
60 static int vctrl_calc_output_voltage(struct vctrl_data *vctrl, int ctrl_uV)
61 {
62         struct vctrl_voltage_range *ctrl = &vctrl->vrange.ctrl;
63         struct vctrl_voltage_range *out = &vctrl->vrange.out;
64
65         if (ctrl_uV < 0) {
66                 pr_err("vctrl: failed to get control voltage\n");
67                 return ctrl_uV;
68         }
69
70         if (ctrl_uV < ctrl->min_uV)
71                 return out->min_uV;
72
73         if (ctrl_uV > ctrl->max_uV)
74                 return out->max_uV;
75
76         return out->min_uV +
77                 DIV_ROUND_CLOSEST_ULL((s64)(ctrl_uV - ctrl->min_uV) *
78                                       (out->max_uV - out->min_uV),
79                                       ctrl->max_uV - ctrl->min_uV);
80 }
81
82 static int vctrl_get_voltage(struct regulator_dev *rdev)
83 {
84         struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
85         int ctrl_uV = regulator_get_voltage_rdev(vctrl->ctrl_reg->rdev);
86
87         return vctrl_calc_output_voltage(vctrl, ctrl_uV);
88 }
89
90 static int vctrl_set_voltage(struct regulator_dev *rdev,
91                              int req_min_uV, int req_max_uV,
92                              unsigned int *selector)
93 {
94         struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
95         struct regulator *ctrl_reg = vctrl->ctrl_reg;
96         int orig_ctrl_uV = regulator_get_voltage_rdev(ctrl_reg->rdev);
97         int uV = vctrl_calc_output_voltage(vctrl, orig_ctrl_uV);
98         int ret;
99
100         if (req_min_uV >= uV || !vctrl->ovp_threshold)
101                 /* voltage rising or no OVP */
102                 return regulator_set_voltage_rdev(ctrl_reg->rdev,
103                         vctrl_calc_ctrl_voltage(vctrl, req_min_uV),
104                         vctrl_calc_ctrl_voltage(vctrl, req_max_uV),
105                         PM_SUSPEND_ON);
106
107         while (uV > req_min_uV) {
108                 int max_drop_uV = (uV * vctrl->ovp_threshold) / 100;
109                 int next_uV;
110                 int next_ctrl_uV;
111                 int delay;
112
113                 /* Make sure no infinite loop even in crazy cases */
114                 if (max_drop_uV == 0)
115                         max_drop_uV = 1;
116
117                 next_uV = max_t(int, req_min_uV, uV - max_drop_uV);
118                 next_ctrl_uV = vctrl_calc_ctrl_voltage(vctrl, next_uV);
119
120                 ret = regulator_set_voltage_rdev(ctrl_reg->rdev,
121                                             next_ctrl_uV,
122                                             next_ctrl_uV,
123                                             PM_SUSPEND_ON);
124                 if (ret)
125                         goto err;
126
127                 delay = DIV_ROUND_UP(uV - next_uV, vctrl->min_slew_down_rate);
128                 usleep_range(delay, delay + DIV_ROUND_UP(delay, 10));
129
130                 uV = next_uV;
131         }
132
133         return 0;
134
135 err:
136         /* Try to go back to original voltage */
137         regulator_set_voltage_rdev(ctrl_reg->rdev, orig_ctrl_uV, orig_ctrl_uV,
138                                    PM_SUSPEND_ON);
139
140         return ret;
141 }
142
143 static int vctrl_get_voltage_sel(struct regulator_dev *rdev)
144 {
145         struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
146
147         return vctrl->sel;
148 }
149
150 static int vctrl_set_voltage_sel(struct regulator_dev *rdev,
151                                  unsigned int selector)
152 {
153         struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
154         struct regulator *ctrl_reg = vctrl->ctrl_reg;
155         unsigned int orig_sel = vctrl->sel;
156         int ret;
157
158         if (selector >= rdev->desc->n_voltages)
159                 return -EINVAL;
160
161         if (selector >= vctrl->sel || !vctrl->ovp_threshold) {
162                 /* voltage rising or no OVP */
163                 ret = regulator_set_voltage_rdev(ctrl_reg->rdev,
164                                             vctrl->vtable[selector].ctrl,
165                                             vctrl->vtable[selector].ctrl,
166                                             PM_SUSPEND_ON);
167                 if (!ret)
168                         vctrl->sel = selector;
169
170                 return ret;
171         }
172
173         while (vctrl->sel != selector) {
174                 unsigned int next_sel;
175                 int delay;
176
177                 if (selector >= vctrl->vtable[vctrl->sel].ovp_min_sel)
178                         next_sel = selector;
179                 else
180                         next_sel = vctrl->vtable[vctrl->sel].ovp_min_sel;
181
182                 ret = regulator_set_voltage_rdev(ctrl_reg->rdev,
183                                             vctrl->vtable[next_sel].ctrl,
184                                             vctrl->vtable[next_sel].ctrl,
185                                             PM_SUSPEND_ON);
186                 if (ret) {
187                         dev_err(&rdev->dev,
188                                 "failed to set control voltage to %duV\n",
189                                 vctrl->vtable[next_sel].ctrl);
190                         goto err;
191                 }
192                 vctrl->sel = next_sel;
193
194                 delay = DIV_ROUND_UP(vctrl->vtable[vctrl->sel].out -
195                                      vctrl->vtable[next_sel].out,
196                                      vctrl->min_slew_down_rate);
197                 usleep_range(delay, delay + DIV_ROUND_UP(delay, 10));
198         }
199
200         return 0;
201
202 err:
203         if (vctrl->sel != orig_sel) {
204                 /* Try to go back to original voltage */
205                 if (!regulator_set_voltage_rdev(ctrl_reg->rdev,
206                                            vctrl->vtable[orig_sel].ctrl,
207                                            vctrl->vtable[orig_sel].ctrl,
208                                            PM_SUSPEND_ON))
209                         vctrl->sel = orig_sel;
210                 else
211                         dev_warn(&rdev->dev,
212                                  "failed to restore original voltage\n");
213         }
214
215         return ret;
216 }
217
218 static int vctrl_list_voltage(struct regulator_dev *rdev,
219                               unsigned int selector)
220 {
221         struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
222
223         if (selector >= rdev->desc->n_voltages)
224                 return -EINVAL;
225
226         return vctrl->vtable[selector].out;
227 }
228
229 static int vctrl_parse_dt(struct platform_device *pdev,
230                           struct vctrl_data *vctrl)
231 {
232         int ret;
233         struct device_node *np = pdev->dev.of_node;
234         u32 pval;
235         u32 vrange_ctrl[2];
236
237         vctrl->ctrl_reg = devm_regulator_get(&pdev->dev, "ctrl");
238         if (IS_ERR(vctrl->ctrl_reg))
239                 return PTR_ERR(vctrl->ctrl_reg);
240
241         ret = of_property_read_u32(np, "ovp-threshold-percent", &pval);
242         if (!ret) {
243                 vctrl->ovp_threshold = pval;
244                 if (vctrl->ovp_threshold > 100) {
245                         dev_err(&pdev->dev,
246                                 "ovp-threshold-percent (%u) > 100\n",
247                                 vctrl->ovp_threshold);
248                         return -EINVAL;
249                 }
250         }
251
252         ret = of_property_read_u32(np, "min-slew-down-rate", &pval);
253         if (!ret) {
254                 vctrl->min_slew_down_rate = pval;
255
256                 /* We use the value as int and as divider; sanity check */
257                 if (vctrl->min_slew_down_rate == 0) {
258                         dev_err(&pdev->dev,
259                                 "min-slew-down-rate must not be 0\n");
260                         return -EINVAL;
261                 } else if (vctrl->min_slew_down_rate > INT_MAX) {
262                         dev_err(&pdev->dev, "min-slew-down-rate (%u) too big\n",
263                                 vctrl->min_slew_down_rate);
264                         return -EINVAL;
265                 }
266         }
267
268         if (vctrl->ovp_threshold && !vctrl->min_slew_down_rate) {
269                 dev_err(&pdev->dev,
270                         "ovp-threshold-percent requires min-slew-down-rate\n");
271                 return -EINVAL;
272         }
273
274         ret = of_property_read_u32(np, "regulator-min-microvolt", &pval);
275         if (ret) {
276                 dev_err(&pdev->dev,
277                         "failed to read regulator-min-microvolt: %d\n", ret);
278                 return ret;
279         }
280         vctrl->vrange.out.min_uV = pval;
281
282         ret = of_property_read_u32(np, "regulator-max-microvolt", &pval);
283         if (ret) {
284                 dev_err(&pdev->dev,
285                         "failed to read regulator-max-microvolt: %d\n", ret);
286                 return ret;
287         }
288         vctrl->vrange.out.max_uV = pval;
289
290         ret = of_property_read_u32_array(np, "ctrl-voltage-range", vrange_ctrl,
291                                          2);
292         if (ret) {
293                 dev_err(&pdev->dev, "failed to read ctrl-voltage-range: %d\n",
294                         ret);
295                 return ret;
296         }
297
298         if (vrange_ctrl[0] >= vrange_ctrl[1]) {
299                 dev_err(&pdev->dev, "ctrl-voltage-range is invalid: %d-%d\n",
300                         vrange_ctrl[0], vrange_ctrl[1]);
301                 return -EINVAL;
302         }
303
304         vctrl->vrange.ctrl.min_uV = vrange_ctrl[0];
305         vctrl->vrange.ctrl.max_uV = vrange_ctrl[1];
306
307         return 0;
308 }
309
310 static int vctrl_cmp_ctrl_uV(const void *a, const void *b)
311 {
312         const struct vctrl_voltage_table *at = a;
313         const struct vctrl_voltage_table *bt = b;
314
315         return at->ctrl - bt->ctrl;
316 }
317
318 static int vctrl_init_vtable(struct platform_device *pdev)
319 {
320         struct vctrl_data *vctrl = platform_get_drvdata(pdev);
321         struct regulator_desc *rdesc = &vctrl->desc;
322         struct regulator *ctrl_reg = vctrl->ctrl_reg;
323         struct vctrl_voltage_range *vrange_ctrl = &vctrl->vrange.ctrl;
324         int n_voltages;
325         int ctrl_uV;
326         int i, idx_vt;
327
328         n_voltages = regulator_count_voltages(ctrl_reg);
329
330         rdesc->n_voltages = n_voltages;
331
332         /* determine number of steps within the range of the vctrl regulator */
333         for (i = 0; i < n_voltages; i++) {
334                 ctrl_uV = regulator_list_voltage(ctrl_reg, i);
335
336                 if (ctrl_uV < vrange_ctrl->min_uV ||
337                     ctrl_uV > vrange_ctrl->max_uV)
338                         rdesc->n_voltages--;
339         }
340
341         if (rdesc->n_voltages == 0) {
342                 dev_err(&pdev->dev, "invalid configuration\n");
343                 return -EINVAL;
344         }
345
346         vctrl->vtable = devm_kcalloc(&pdev->dev, rdesc->n_voltages,
347                                      sizeof(struct vctrl_voltage_table),
348                                      GFP_KERNEL);
349         if (!vctrl->vtable)
350                 return -ENOMEM;
351
352         /* create mapping control <=> output voltage */
353         for (i = 0, idx_vt = 0; i < n_voltages; i++) {
354                 ctrl_uV = regulator_list_voltage(ctrl_reg, i);
355
356                 if (ctrl_uV < vrange_ctrl->min_uV ||
357                     ctrl_uV > vrange_ctrl->max_uV)
358                         continue;
359
360                 vctrl->vtable[idx_vt].ctrl = ctrl_uV;
361                 vctrl->vtable[idx_vt].out =
362                         vctrl_calc_output_voltage(vctrl, ctrl_uV);
363                 idx_vt++;
364         }
365
366         /* we rely on the table to be ordered by ascending voltage */
367         sort(vctrl->vtable, rdesc->n_voltages,
368              sizeof(struct vctrl_voltage_table), vctrl_cmp_ctrl_uV,
369              NULL);
370
371         /* pre-calculate OVP-safe downward transitions */
372         for (i = rdesc->n_voltages - 1; i > 0; i--) {
373                 int j;
374                 int ovp_min_uV = (vctrl->vtable[i].out *
375                                   (100 - vctrl->ovp_threshold)) / 100;
376
377                 for (j = 0; j < i; j++) {
378                         if (vctrl->vtable[j].out >= ovp_min_uV) {
379                                 vctrl->vtable[i].ovp_min_sel = j;
380                                 break;
381                         }
382                 }
383
384                 if (j == i) {
385                         dev_warn(&pdev->dev, "switching down from %duV may cause OVP shutdown\n",
386                                 vctrl->vtable[i].out);
387                         /* use next lowest voltage */
388                         vctrl->vtable[i].ovp_min_sel = i - 1;
389                 }
390         }
391
392         return 0;
393 }
394
395 static int vctrl_enable(struct regulator_dev *rdev)
396 {
397         struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
398         int ret = regulator_enable(vctrl->ctrl_reg);
399
400         if (!ret)
401                 vctrl->enabled = true;
402
403         return ret;
404 }
405
406 static int vctrl_disable(struct regulator_dev *rdev)
407 {
408         struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
409         int ret = regulator_disable(vctrl->ctrl_reg);
410
411         if (!ret)
412                 vctrl->enabled = false;
413
414         return ret;
415 }
416
417 static int vctrl_is_enabled(struct regulator_dev *rdev)
418 {
419         struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
420
421         return vctrl->enabled;
422 }
423
424 static const struct regulator_ops vctrl_ops_cont = {
425         .enable           = vctrl_enable,
426         .disable          = vctrl_disable,
427         .is_enabled       = vctrl_is_enabled,
428         .get_voltage      = vctrl_get_voltage,
429         .set_voltage      = vctrl_set_voltage,
430 };
431
432 static const struct regulator_ops vctrl_ops_non_cont = {
433         .enable           = vctrl_enable,
434         .disable          = vctrl_disable,
435         .is_enabled       = vctrl_is_enabled,
436         .set_voltage_sel = vctrl_set_voltage_sel,
437         .get_voltage_sel = vctrl_get_voltage_sel,
438         .list_voltage    = vctrl_list_voltage,
439         .map_voltage     = regulator_map_voltage_iterate,
440 };
441
442 static int vctrl_probe(struct platform_device *pdev)
443 {
444         struct device_node *np = pdev->dev.of_node;
445         struct vctrl_data *vctrl;
446         const struct regulator_init_data *init_data;
447         struct regulator_desc *rdesc;
448         struct regulator_config cfg = { };
449         struct vctrl_voltage_range *vrange_ctrl;
450         int ctrl_uV;
451         int ret;
452
453         vctrl = devm_kzalloc(&pdev->dev, sizeof(struct vctrl_data),
454                              GFP_KERNEL);
455         if (!vctrl)
456                 return -ENOMEM;
457
458         platform_set_drvdata(pdev, vctrl);
459
460         ret = vctrl_parse_dt(pdev, vctrl);
461         if (ret)
462                 return ret;
463
464         vrange_ctrl = &vctrl->vrange.ctrl;
465
466         rdesc = &vctrl->desc;
467         rdesc->name = "vctrl";
468         rdesc->type = REGULATOR_VOLTAGE;
469         rdesc->owner = THIS_MODULE;
470
471         if ((regulator_get_linear_step(vctrl->ctrl_reg) == 1) ||
472             (regulator_count_voltages(vctrl->ctrl_reg) == -EINVAL)) {
473                 rdesc->continuous_voltage_range = true;
474                 rdesc->ops = &vctrl_ops_cont;
475         } else {
476                 rdesc->ops = &vctrl_ops_non_cont;
477         }
478
479         init_data = of_get_regulator_init_data(&pdev->dev, np, rdesc);
480         if (!init_data)
481                 return -ENOMEM;
482
483         cfg.of_node = np;
484         cfg.dev = &pdev->dev;
485         cfg.driver_data = vctrl;
486         cfg.init_data = init_data;
487
488         if (!rdesc->continuous_voltage_range) {
489                 ret = vctrl_init_vtable(pdev);
490                 if (ret)
491                         return ret;
492
493                 ctrl_uV = regulator_get_voltage_rdev(vctrl->ctrl_reg->rdev);
494                 if (ctrl_uV < 0) {
495                         dev_err(&pdev->dev, "failed to get control voltage\n");
496                         return ctrl_uV;
497                 }
498
499                 /* determine current voltage selector from control voltage */
500                 if (ctrl_uV < vrange_ctrl->min_uV) {
501                         vctrl->sel = 0;
502                 } else if (ctrl_uV > vrange_ctrl->max_uV) {
503                         vctrl->sel = rdesc->n_voltages - 1;
504                 } else {
505                         int i;
506
507                         for (i = 0; i < rdesc->n_voltages; i++) {
508                                 if (ctrl_uV == vctrl->vtable[i].ctrl) {
509                                         vctrl->sel = i;
510                                         break;
511                                 }
512                         }
513                 }
514         }
515
516         vctrl->rdev = devm_regulator_register(&pdev->dev, rdesc, &cfg);
517         if (IS_ERR(vctrl->rdev)) {
518                 ret = PTR_ERR(vctrl->rdev);
519                 dev_err(&pdev->dev, "failed to register regulator: %d\n", ret);
520                 return ret;
521         }
522
523         return 0;
524 }
525
526 static const struct of_device_id vctrl_of_match[] = {
527         { .compatible = "vctrl-regulator", },
528         {},
529 };
530 MODULE_DEVICE_TABLE(of, vctrl_of_match);
531
532 static struct platform_driver vctrl_driver = {
533         .probe          = vctrl_probe,
534         .driver         = {
535                 .name           = "vctrl-regulator",
536                 .of_match_table = of_match_ptr(vctrl_of_match),
537         },
538 };
539
540 module_platform_driver(vctrl_driver);
541
542 MODULE_DESCRIPTION("Voltage Controlled Regulator Driver");
543 MODULE_AUTHOR("Matthias Kaehlcke <mka@chromium.org>");
544 MODULE_LICENSE("GPL v2");