1 // SPDX-License-Identifier: GPL-2.0-only
3 * Regulator driver for PWM Regulators
5 * Copyright (C) 2014 - STMicroelectronics Inc.
7 * Author: Lee Jones <lee.jones@linaro.org>
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/err.h>
13 #include <linux/platform_device.h>
14 #include <linux/regulator/driver.h>
15 #include <linux/regulator/machine.h>
16 #include <linux/regulator/of_regulator.h>
18 #include <linux/pwm.h>
19 #include <linux/gpio/consumer.h>
21 struct pwm_continuous_reg_data
{
22 unsigned int min_uV_dutycycle
;
23 unsigned int max_uV_dutycycle
;
24 unsigned int dutycycle_unit
;
27 struct pwm_regulator_data
{
29 struct pwm_device
*pwm
;
32 struct pwm_voltages
*duty_cycle_table
;
34 /* Continuous mode info */
35 struct pwm_continuous_reg_data continuous
;
37 /* regulator descriptor */
38 struct regulator_desc desc
;
43 struct gpio_desc
*enb_gpio
;
48 unsigned int dutycycle
;
52 * Voltage table call-backs
54 static void pwm_regulator_init_state(struct regulator_dev
*rdev
)
56 struct pwm_regulator_data
*drvdata
= rdev_get_drvdata(rdev
);
57 struct pwm_state pwm_state
;
58 unsigned int dutycycle
;
61 pwm_get_state(drvdata
->pwm
, &pwm_state
);
62 dutycycle
= pwm_get_relative_duty_cycle(&pwm_state
, 100);
64 for (i
= 0; i
< rdev
->desc
->n_voltages
; i
++) {
65 if (dutycycle
== drvdata
->duty_cycle_table
[i
].dutycycle
) {
72 static int pwm_regulator_get_voltage_sel(struct regulator_dev
*rdev
)
74 struct pwm_regulator_data
*drvdata
= rdev_get_drvdata(rdev
);
76 if (drvdata
->state
< 0)
77 pwm_regulator_init_state(rdev
);
79 return drvdata
->state
;
82 static int pwm_regulator_set_voltage_sel(struct regulator_dev
*rdev
,
85 struct pwm_regulator_data
*drvdata
= rdev_get_drvdata(rdev
);
86 struct pwm_state pstate
;
89 pwm_init_state(drvdata
->pwm
, &pstate
);
90 pwm_set_relative_duty_cycle(&pstate
,
91 drvdata
->duty_cycle_table
[selector
].dutycycle
, 100);
93 ret
= pwm_apply_might_sleep(drvdata
->pwm
, &pstate
);
95 dev_err(&rdev
->dev
, "Failed to configure PWM: %d\n", ret
);
99 drvdata
->state
= selector
;
104 static int pwm_regulator_list_voltage(struct regulator_dev
*rdev
,
107 struct pwm_regulator_data
*drvdata
= rdev_get_drvdata(rdev
);
109 if (selector
>= rdev
->desc
->n_voltages
)
112 return drvdata
->duty_cycle_table
[selector
].uV
;
115 static int pwm_regulator_enable(struct regulator_dev
*dev
)
117 struct pwm_regulator_data
*drvdata
= rdev_get_drvdata(dev
);
119 gpiod_set_value_cansleep(drvdata
->enb_gpio
, 1);
121 return pwm_enable(drvdata
->pwm
);
124 static int pwm_regulator_disable(struct regulator_dev
*dev
)
126 struct pwm_regulator_data
*drvdata
= rdev_get_drvdata(dev
);
128 pwm_disable(drvdata
->pwm
);
130 gpiod_set_value_cansleep(drvdata
->enb_gpio
, 0);
135 static int pwm_regulator_is_enabled(struct regulator_dev
*dev
)
137 struct pwm_regulator_data
*drvdata
= rdev_get_drvdata(dev
);
139 if (drvdata
->enb_gpio
&& !gpiod_get_value_cansleep(drvdata
->enb_gpio
))
142 return pwm_is_enabled(drvdata
->pwm
);
145 static int pwm_regulator_get_voltage(struct regulator_dev
*rdev
)
147 struct pwm_regulator_data
*drvdata
= rdev_get_drvdata(rdev
);
148 unsigned int min_uV_duty
= drvdata
->continuous
.min_uV_dutycycle
;
149 unsigned int max_uV_duty
= drvdata
->continuous
.max_uV_dutycycle
;
150 unsigned int duty_unit
= drvdata
->continuous
.dutycycle_unit
;
151 int min_uV
= rdev
->constraints
->min_uV
;
152 int max_uV
= rdev
->constraints
->max_uV
;
153 int diff_uV
= max_uV
- min_uV
;
154 struct pwm_state pstate
;
155 unsigned int diff_duty
;
156 unsigned int voltage
;
158 pwm_get_state(drvdata
->pwm
, &pstate
);
160 if (!pstate
.enabled
) {
161 if (pstate
.polarity
== PWM_POLARITY_INVERSED
)
162 pstate
.duty_cycle
= pstate
.period
;
164 pstate
.duty_cycle
= 0;
167 voltage
= pwm_get_relative_duty_cycle(&pstate
, duty_unit
);
168 if (voltage
< min(max_uV_duty
, min_uV_duty
) ||
169 voltage
> max(max_uV_duty
, min_uV_duty
))
170 return -ENOTRECOVERABLE
;
173 * The dutycycle for min_uV might be greater than the one for max_uV.
174 * This is happening when the user needs an inversed polarity, but the
175 * PWM device does not support inversing it in hardware.
177 if (max_uV_duty
< min_uV_duty
) {
178 voltage
= min_uV_duty
- voltage
;
179 diff_duty
= min_uV_duty
- max_uV_duty
;
181 voltage
= voltage
- min_uV_duty
;
182 diff_duty
= max_uV_duty
- min_uV_duty
;
185 voltage
= DIV_ROUND_CLOSEST_ULL((u64
)voltage
* diff_uV
, diff_duty
);
187 return voltage
+ min_uV
;
190 static int pwm_regulator_set_voltage(struct regulator_dev
*rdev
,
191 int req_min_uV
, int req_max_uV
,
192 unsigned int *selector
)
194 struct pwm_regulator_data
*drvdata
= rdev_get_drvdata(rdev
);
195 unsigned int min_uV_duty
= drvdata
->continuous
.min_uV_dutycycle
;
196 unsigned int max_uV_duty
= drvdata
->continuous
.max_uV_dutycycle
;
197 unsigned int duty_unit
= drvdata
->continuous
.dutycycle_unit
;
198 int min_uV
= rdev
->constraints
->min_uV
;
199 int max_uV
= rdev
->constraints
->max_uV
;
200 int diff_uV
= max_uV
- min_uV
;
201 struct pwm_state pstate
;
202 unsigned int diff_duty
;
203 unsigned int dutycycle
;
206 pwm_init_state(drvdata
->pwm
, &pstate
);
209 * The dutycycle for min_uV might be greater than the one for max_uV.
210 * This is happening when the user needs an inversed polarity, but the
211 * PWM device does not support inversing it in hardware.
213 if (max_uV_duty
< min_uV_duty
)
214 diff_duty
= min_uV_duty
- max_uV_duty
;
216 diff_duty
= max_uV_duty
- min_uV_duty
;
218 dutycycle
= DIV_ROUND_CLOSEST_ULL((u64
)(req_min_uV
- min_uV
) *
222 if (max_uV_duty
< min_uV_duty
)
223 dutycycle
= min_uV_duty
- dutycycle
;
225 dutycycle
= min_uV_duty
+ dutycycle
;
227 pwm_set_relative_duty_cycle(&pstate
, dutycycle
, duty_unit
);
229 ret
= pwm_apply_might_sleep(drvdata
->pwm
, &pstate
);
231 dev_err(&rdev
->dev
, "Failed to configure PWM: %d\n", ret
);
238 static const struct regulator_ops pwm_regulator_voltage_table_ops
= {
239 .set_voltage_sel
= pwm_regulator_set_voltage_sel
,
240 .get_voltage_sel
= pwm_regulator_get_voltage_sel
,
241 .list_voltage
= pwm_regulator_list_voltage
,
242 .map_voltage
= regulator_map_voltage_iterate
,
243 .enable
= pwm_regulator_enable
,
244 .disable
= pwm_regulator_disable
,
245 .is_enabled
= pwm_regulator_is_enabled
,
248 static const struct regulator_ops pwm_regulator_voltage_continuous_ops
= {
249 .get_voltage
= pwm_regulator_get_voltage
,
250 .set_voltage
= pwm_regulator_set_voltage
,
251 .enable
= pwm_regulator_enable
,
252 .disable
= pwm_regulator_disable
,
253 .is_enabled
= pwm_regulator_is_enabled
,
256 static const struct regulator_desc pwm_regulator_desc
= {
257 .name
= "pwm-regulator",
258 .type
= REGULATOR_VOLTAGE
,
259 .owner
= THIS_MODULE
,
260 .supply_name
= "pwm",
263 static int pwm_regulator_init_table(struct platform_device
*pdev
,
264 struct pwm_regulator_data
*drvdata
)
266 struct device_node
*np
= pdev
->dev
.of_node
;
267 struct pwm_voltages
*duty_cycle_table
;
268 unsigned int length
= 0;
271 of_find_property(np
, "voltage-table", &length
);
273 if ((length
< sizeof(*duty_cycle_table
)) ||
274 (length
% sizeof(*duty_cycle_table
)))
275 return dev_err_probe(&pdev
->dev
, -EINVAL
,
276 "voltage-table length(%d) is invalid\n",
279 duty_cycle_table
= devm_kzalloc(&pdev
->dev
, length
, GFP_KERNEL
);
280 if (!duty_cycle_table
)
283 ret
= of_property_read_u32_array(np
, "voltage-table",
284 (u32
*)duty_cycle_table
,
285 length
/ sizeof(u32
));
287 return dev_err_probe(&pdev
->dev
, ret
,
288 "Failed to read voltage-table\n");
290 drvdata
->state
= -ENOTRECOVERABLE
;
291 drvdata
->duty_cycle_table
= duty_cycle_table
;
292 drvdata
->desc
.ops
= &pwm_regulator_voltage_table_ops
;
293 drvdata
->desc
.n_voltages
= length
/ sizeof(*duty_cycle_table
);
298 static int pwm_regulator_init_continuous(struct platform_device
*pdev
,
299 struct pwm_regulator_data
*drvdata
)
301 u32 dutycycle_range
[2] = { 0, 100 };
302 u32 dutycycle_unit
= 100;
304 drvdata
->desc
.ops
= &pwm_regulator_voltage_continuous_ops
;
305 drvdata
->desc
.continuous_voltage_range
= true;
307 of_property_read_u32_array(pdev
->dev
.of_node
,
308 "pwm-dutycycle-range",
310 of_property_read_u32(pdev
->dev
.of_node
, "pwm-dutycycle-unit",
313 if (dutycycle_range
[0] > dutycycle_unit
||
314 dutycycle_range
[1] > dutycycle_unit
)
317 drvdata
->continuous
.dutycycle_unit
= dutycycle_unit
;
318 drvdata
->continuous
.min_uV_dutycycle
= dutycycle_range
[0];
319 drvdata
->continuous
.max_uV_dutycycle
= dutycycle_range
[1];
324 static int pwm_regulator_init_boot_on(struct platform_device
*pdev
,
325 struct pwm_regulator_data
*drvdata
,
326 const struct regulator_init_data
*init_data
)
328 struct pwm_state pstate
;
330 if (!init_data
->constraints
.boot_on
|| drvdata
->enb_gpio
)
333 pwm_get_state(drvdata
->pwm
, &pstate
);
338 * Update the duty cycle so the output does not change
339 * when the regulator core enables the regulator (and
340 * thus the PWM channel).
342 if (pstate
.polarity
== PWM_POLARITY_INVERSED
)
343 pstate
.duty_cycle
= pstate
.period
;
345 pstate
.duty_cycle
= 0;
347 return pwm_apply_might_sleep(drvdata
->pwm
, &pstate
);
350 static int pwm_regulator_probe(struct platform_device
*pdev
)
352 const struct regulator_init_data
*init_data
;
353 struct pwm_regulator_data
*drvdata
;
354 struct regulator_dev
*regulator
;
355 struct regulator_config config
= { };
356 struct device_node
*np
= pdev
->dev
.of_node
;
357 enum gpiod_flags gpio_flags
;
361 return dev_err_probe(&pdev
->dev
, -EINVAL
,
362 "Device Tree node missing\n");
364 drvdata
= devm_kzalloc(&pdev
->dev
, sizeof(*drvdata
), GFP_KERNEL
);
368 memcpy(&drvdata
->desc
, &pwm_regulator_desc
, sizeof(drvdata
->desc
));
370 if (of_property_present(np
, "voltage-table"))
371 ret
= pwm_regulator_init_table(pdev
, drvdata
);
373 ret
= pwm_regulator_init_continuous(pdev
, drvdata
);
377 init_data
= of_get_regulator_init_data(&pdev
->dev
, np
,
383 config
.dev
= &pdev
->dev
;
384 config
.driver_data
= drvdata
;
385 config
.init_data
= init_data
;
387 drvdata
->pwm
= devm_pwm_get(&pdev
->dev
, NULL
);
388 if (IS_ERR(drvdata
->pwm
))
389 return dev_err_probe(&pdev
->dev
, PTR_ERR(drvdata
->pwm
),
390 "Failed to get PWM\n");
392 if (init_data
->constraints
.boot_on
|| init_data
->constraints
.always_on
)
393 gpio_flags
= GPIOD_OUT_HIGH
;
395 gpio_flags
= GPIOD_OUT_LOW
;
396 drvdata
->enb_gpio
= devm_gpiod_get_optional(&pdev
->dev
, "enable",
398 if (IS_ERR(drvdata
->enb_gpio
)) {
399 ret
= PTR_ERR(drvdata
->enb_gpio
);
400 return dev_err_probe(&pdev
->dev
, ret
, "Failed to get enable GPIO\n");
403 ret
= pwm_adjust_config(drvdata
->pwm
);
407 ret
= pwm_regulator_init_boot_on(pdev
, drvdata
, init_data
);
409 return dev_err_probe(&pdev
->dev
, ret
,
410 "Failed to apply boot_on settings\n");
412 regulator
= devm_regulator_register(&pdev
->dev
,
413 &drvdata
->desc
, &config
);
414 if (IS_ERR(regulator
)) {
415 ret
= PTR_ERR(regulator
);
416 return dev_err_probe(&pdev
->dev
, ret
,
417 "Failed to register regulator %s\n",
424 static const struct of_device_id __maybe_unused pwm_of_match
[] = {
425 { .compatible
= "pwm-regulator" },
428 MODULE_DEVICE_TABLE(of
, pwm_of_match
);
430 static struct platform_driver pwm_regulator_driver
= {
432 .name
= "pwm-regulator",
433 .probe_type
= PROBE_PREFER_ASYNCHRONOUS
,
434 .of_match_table
= of_match_ptr(pwm_of_match
),
436 .probe
= pwm_regulator_probe
,
439 module_platform_driver(pwm_regulator_driver
);
441 MODULE_LICENSE("GPL");
442 MODULE_AUTHOR("Lee Jones <lee.jones@linaro.org>");
443 MODULE_DESCRIPTION("PWM Regulator Driver");
444 MODULE_ALIAS("platform:pwm-regulator");