1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver for voltage controller regulators
5 * Copyright (C) 2017 Google, Inc.
8 #include <linux/delay.h>
10 #include <linux/init.h>
11 #include <linux/module.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>
21 struct vctrl_voltage_range
{
26 struct vctrl_voltage_ranges
{
27 struct vctrl_voltage_range ctrl
;
28 struct vctrl_voltage_range out
;
31 struct vctrl_voltage_table
{
38 struct regulator_dev
*rdev
;
39 struct regulator_desc desc
;
40 struct regulator
*ctrl_reg
;
42 unsigned int min_slew_down_rate
;
43 unsigned int ovp_threshold
;
44 struct vctrl_voltage_ranges vrange
;
45 struct vctrl_voltage_table
*vtable
;
49 static int vctrl_calc_ctrl_voltage(struct vctrl_data
*vctrl
, int out_uV
)
51 struct vctrl_voltage_range
*ctrl
= &vctrl
->vrange
.ctrl
;
52 struct vctrl_voltage_range
*out
= &vctrl
->vrange
.out
;
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
);
60 static int vctrl_calc_output_voltage(struct vctrl_data
*vctrl
, int ctrl_uV
)
62 struct vctrl_voltage_range
*ctrl
= &vctrl
->vrange
.ctrl
;
63 struct vctrl_voltage_range
*out
= &vctrl
->vrange
.out
;
66 pr_err("vctrl: failed to get control voltage\n");
70 if (ctrl_uV
< ctrl
->min_uV
)
73 if (ctrl_uV
> ctrl
->max_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
);
82 static int vctrl_get_voltage(struct regulator_dev
*rdev
)
84 struct vctrl_data
*vctrl
= rdev_get_drvdata(rdev
);
85 int ctrl_uV
= regulator_get_voltage_rdev(vctrl
->ctrl_reg
->rdev
);
87 return vctrl_calc_output_voltage(vctrl
, ctrl_uV
);
90 static int vctrl_set_voltage(struct regulator_dev
*rdev
,
91 int req_min_uV
, int req_max_uV
,
92 unsigned int *selector
)
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
);
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
),
107 while (uV
> req_min_uV
) {
108 int max_drop_uV
= (uV
* vctrl
->ovp_threshold
) / 100;
113 /* Make sure no infinite loop even in crazy cases */
114 if (max_drop_uV
== 0)
117 next_uV
= max_t(int, req_min_uV
, uV
- max_drop_uV
);
118 next_ctrl_uV
= vctrl_calc_ctrl_voltage(vctrl
, next_uV
);
120 ret
= regulator_set_voltage_rdev(ctrl_reg
->rdev
,
127 delay
= DIV_ROUND_UP(uV
- next_uV
, vctrl
->min_slew_down_rate
);
128 usleep_range(delay
, delay
+ DIV_ROUND_UP(delay
, 10));
136 /* Try to go back to original voltage */
137 regulator_set_voltage_rdev(ctrl_reg
->rdev
, orig_ctrl_uV
, orig_ctrl_uV
,
143 static int vctrl_get_voltage_sel(struct regulator_dev
*rdev
)
145 struct vctrl_data
*vctrl
= rdev_get_drvdata(rdev
);
150 static int vctrl_set_voltage_sel(struct regulator_dev
*rdev
,
151 unsigned int selector
)
153 struct vctrl_data
*vctrl
= rdev_get_drvdata(rdev
);
154 struct regulator
*ctrl_reg
= vctrl
->ctrl_reg
;
155 unsigned int orig_sel
= vctrl
->sel
;
158 if (selector
>= rdev
->desc
->n_voltages
)
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
,
168 vctrl
->sel
= selector
;
173 while (vctrl
->sel
!= selector
) {
174 unsigned int next_sel
;
177 if (selector
>= vctrl
->vtable
[vctrl
->sel
].ovp_min_sel
)
180 next_sel
= vctrl
->vtable
[vctrl
->sel
].ovp_min_sel
;
182 ret
= regulator_set_voltage_rdev(ctrl_reg
->rdev
,
183 vctrl
->vtable
[next_sel
].ctrl
,
184 vctrl
->vtable
[next_sel
].ctrl
,
188 "failed to set control voltage to %duV\n",
189 vctrl
->vtable
[next_sel
].ctrl
);
192 vctrl
->sel
= next_sel
;
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));
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
,
209 vctrl
->sel
= orig_sel
;
212 "failed to restore original voltage\n");
218 static int vctrl_list_voltage(struct regulator_dev
*rdev
,
219 unsigned int selector
)
221 struct vctrl_data
*vctrl
= rdev_get_drvdata(rdev
);
223 if (selector
>= rdev
->desc
->n_voltages
)
226 return vctrl
->vtable
[selector
].out
;
229 static int vctrl_parse_dt(struct platform_device
*pdev
,
230 struct vctrl_data
*vctrl
)
233 struct device_node
*np
= pdev
->dev
.of_node
;
237 vctrl
->ctrl_reg
= devm_regulator_get(&pdev
->dev
, "ctrl");
238 if (IS_ERR(vctrl
->ctrl_reg
))
239 return PTR_ERR(vctrl
->ctrl_reg
);
241 ret
= of_property_read_u32(np
, "ovp-threshold-percent", &pval
);
243 vctrl
->ovp_threshold
= pval
;
244 if (vctrl
->ovp_threshold
> 100) {
246 "ovp-threshold-percent (%u) > 100\n",
247 vctrl
->ovp_threshold
);
252 ret
= of_property_read_u32(np
, "min-slew-down-rate", &pval
);
254 vctrl
->min_slew_down_rate
= pval
;
256 /* We use the value as int and as divider; sanity check */
257 if (vctrl
->min_slew_down_rate
== 0) {
259 "min-slew-down-rate must not be 0\n");
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
);
268 if (vctrl
->ovp_threshold
&& !vctrl
->min_slew_down_rate
) {
270 "ovp-threshold-percent requires min-slew-down-rate\n");
274 ret
= of_property_read_u32(np
, "regulator-min-microvolt", &pval
);
277 "failed to read regulator-min-microvolt: %d\n", ret
);
280 vctrl
->vrange
.out
.min_uV
= pval
;
282 ret
= of_property_read_u32(np
, "regulator-max-microvolt", &pval
);
285 "failed to read regulator-max-microvolt: %d\n", ret
);
288 vctrl
->vrange
.out
.max_uV
= pval
;
290 ret
= of_property_read_u32_array(np
, "ctrl-voltage-range", vrange_ctrl
,
293 dev_err(&pdev
->dev
, "failed to read ctrl-voltage-range: %d\n",
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]);
304 vctrl
->vrange
.ctrl
.min_uV
= vrange_ctrl
[0];
305 vctrl
->vrange
.ctrl
.max_uV
= vrange_ctrl
[1];
310 static int vctrl_cmp_ctrl_uV(const void *a
, const void *b
)
312 const struct vctrl_voltage_table
*at
= a
;
313 const struct vctrl_voltage_table
*bt
= b
;
315 return at
->ctrl
- bt
->ctrl
;
318 static int vctrl_init_vtable(struct platform_device
*pdev
)
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
;
328 n_voltages
= regulator_count_voltages(ctrl_reg
);
330 rdesc
->n_voltages
= n_voltages
;
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
);
336 if (ctrl_uV
< vrange_ctrl
->min_uV
||
337 ctrl_uV
> vrange_ctrl
->max_uV
)
341 if (rdesc
->n_voltages
== 0) {
342 dev_err(&pdev
->dev
, "invalid configuration\n");
346 vctrl
->vtable
= devm_kcalloc(&pdev
->dev
, rdesc
->n_voltages
,
347 sizeof(struct vctrl_voltage_table
),
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
);
356 if (ctrl_uV
< vrange_ctrl
->min_uV
||
357 ctrl_uV
> vrange_ctrl
->max_uV
)
360 vctrl
->vtable
[idx_vt
].ctrl
= ctrl_uV
;
361 vctrl
->vtable
[idx_vt
].out
=
362 vctrl_calc_output_voltage(vctrl
, ctrl_uV
);
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
,
371 /* pre-calculate OVP-safe downward transitions */
372 for (i
= rdesc
->n_voltages
- 1; i
> 0; i
--) {
374 int ovp_min_uV
= (vctrl
->vtable
[i
].out
*
375 (100 - vctrl
->ovp_threshold
)) / 100;
377 for (j
= 0; j
< i
; j
++) {
378 if (vctrl
->vtable
[j
].out
>= ovp_min_uV
) {
379 vctrl
->vtable
[i
].ovp_min_sel
= j
;
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;
395 static int vctrl_enable(struct regulator_dev
*rdev
)
397 struct vctrl_data
*vctrl
= rdev_get_drvdata(rdev
);
398 int ret
= regulator_enable(vctrl
->ctrl_reg
);
401 vctrl
->enabled
= true;
406 static int vctrl_disable(struct regulator_dev
*rdev
)
408 struct vctrl_data
*vctrl
= rdev_get_drvdata(rdev
);
409 int ret
= regulator_disable(vctrl
->ctrl_reg
);
412 vctrl
->enabled
= false;
417 static int vctrl_is_enabled(struct regulator_dev
*rdev
)
419 struct vctrl_data
*vctrl
= rdev_get_drvdata(rdev
);
421 return vctrl
->enabled
;
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
,
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
,
442 static int vctrl_probe(struct platform_device
*pdev
)
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
;
453 vctrl
= devm_kzalloc(&pdev
->dev
, sizeof(struct vctrl_data
),
458 platform_set_drvdata(pdev
, vctrl
);
460 ret
= vctrl_parse_dt(pdev
, vctrl
);
464 vrange_ctrl
= &vctrl
->vrange
.ctrl
;
466 rdesc
= &vctrl
->desc
;
467 rdesc
->name
= "vctrl";
468 rdesc
->type
= REGULATOR_VOLTAGE
;
469 rdesc
->owner
= THIS_MODULE
;
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
;
476 rdesc
->ops
= &vctrl_ops_non_cont
;
479 init_data
= of_get_regulator_init_data(&pdev
->dev
, np
, rdesc
);
484 cfg
.dev
= &pdev
->dev
;
485 cfg
.driver_data
= vctrl
;
486 cfg
.init_data
= init_data
;
488 if (!rdesc
->continuous_voltage_range
) {
489 ret
= vctrl_init_vtable(pdev
);
493 ctrl_uV
= regulator_get_voltage_rdev(vctrl
->ctrl_reg
->rdev
);
495 dev_err(&pdev
->dev
, "failed to get control voltage\n");
499 /* determine current voltage selector from control voltage */
500 if (ctrl_uV
< vrange_ctrl
->min_uV
) {
502 } else if (ctrl_uV
> vrange_ctrl
->max_uV
) {
503 vctrl
->sel
= rdesc
->n_voltages
- 1;
507 for (i
= 0; i
< rdesc
->n_voltages
; i
++) {
508 if (ctrl_uV
== vctrl
->vtable
[i
].ctrl
) {
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
);
526 static const struct of_device_id vctrl_of_match
[] = {
527 { .compatible
= "vctrl-regulator", },
530 MODULE_DEVICE_TABLE(of
, vctrl_of_match
);
532 static struct platform_driver vctrl_driver
= {
533 .probe
= vctrl_probe
,
535 .name
= "vctrl-regulator",
536 .of_match_table
= of_match_ptr(vctrl_of_match
),
540 module_platform_driver(vctrl_driver
);
542 MODULE_DESCRIPTION("Voltage Controlled Regulator Driver");
543 MODULE_AUTHOR("Matthias Kaehlcke <mka@chromium.org>");
544 MODULE_LICENSE("GPL v2");