2 * Regulator driver for ST's PWM Regulators
4 * Copyright (C) 2014 - STMicroelectronics Inc.
6 * Author: Lee Jones <lee.jones@linaro.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/err.h>
16 #include <linux/regulator/driver.h>
17 #include <linux/regulator/machine.h>
18 #include <linux/regulator/of_regulator.h>
20 #include <linux/of_device.h>
21 #include <linux/pwm.h>
23 #define ST_PWM_REG_PERIOD 8448
25 struct st_pwm_regulator_pdata
{
26 const struct regulator_desc
*desc
;
27 struct st_pwm_voltages
*duty_cycle_table
;
30 struct st_pwm_regulator_data
{
31 const struct st_pwm_regulator_pdata
*pdata
;
32 struct pwm_device
*pwm
;
37 struct st_pwm_voltages
{
39 unsigned int dutycycle
;
42 static int st_pwm_regulator_get_voltage_sel(struct regulator_dev
*dev
)
44 struct st_pwm_regulator_data
*drvdata
= rdev_get_drvdata(dev
);
46 return drvdata
->state
;
49 static int st_pwm_regulator_set_voltage_sel(struct regulator_dev
*dev
,
52 struct st_pwm_regulator_data
*drvdata
= rdev_get_drvdata(dev
);
56 dutycycle
= (ST_PWM_REG_PERIOD
/ 100) *
57 drvdata
->pdata
->duty_cycle_table
[selector
].dutycycle
;
59 ret
= pwm_config(drvdata
->pwm
, dutycycle
, ST_PWM_REG_PERIOD
);
61 dev_err(&dev
->dev
, "Failed to configure PWM\n");
65 drvdata
->state
= selector
;
67 if (!drvdata
->enabled
) {
68 ret
= pwm_enable(drvdata
->pwm
);
70 dev_err(&dev
->dev
, "Failed to enable PWM\n");
73 drvdata
->enabled
= true;
79 static int st_pwm_regulator_list_voltage(struct regulator_dev
*dev
,
82 struct st_pwm_regulator_data
*drvdata
= rdev_get_drvdata(dev
);
84 if (selector
>= dev
->desc
->n_voltages
)
87 return drvdata
->pdata
->duty_cycle_table
[selector
].uV
;
90 static struct regulator_ops st_pwm_regulator_voltage_ops
= {
91 .set_voltage_sel
= st_pwm_regulator_set_voltage_sel
,
92 .get_voltage_sel
= st_pwm_regulator_get_voltage_sel
,
93 .list_voltage
= st_pwm_regulator_list_voltage
,
94 .map_voltage
= regulator_map_voltage_iterate
,
97 static struct st_pwm_voltages b2105_duty_cycle_table
[] = {
98 { .uV
= 1114000, .dutycycle
= 0, },
99 { .uV
= 1095000, .dutycycle
= 10, },
100 { .uV
= 1076000, .dutycycle
= 20, },
101 { .uV
= 1056000, .dutycycle
= 30, },
102 { .uV
= 1036000, .dutycycle
= 40, },
103 { .uV
= 1016000, .dutycycle
= 50, },
104 /* WARNING: Values above 50% duty-cycle cause boot failures. */
107 static const struct regulator_desc b2105_desc
= {
108 .name
= "b2105-pwm-regulator",
109 .ops
= &st_pwm_regulator_voltage_ops
,
110 .type
= REGULATOR_VOLTAGE
,
111 .owner
= THIS_MODULE
,
112 .n_voltages
= ARRAY_SIZE(b2105_duty_cycle_table
),
113 .supply_name
= "pwm",
116 static const struct st_pwm_regulator_pdata b2105_info
= {
118 .duty_cycle_table
= b2105_duty_cycle_table
,
121 static struct of_device_id st_pwm_of_match
[] = {
122 { .compatible
= "st,b2105-pwm-regulator", .data
= &b2105_info
, },
125 MODULE_DEVICE_TABLE(of
, st_pwm_of_match
);
127 static int st_pwm_regulator_probe(struct platform_device
*pdev
)
129 struct st_pwm_regulator_data
*drvdata
;
130 struct regulator_dev
*regulator
;
131 struct regulator_config config
= { };
132 struct device_node
*np
= pdev
->dev
.of_node
;
133 const struct of_device_id
*of_match
;
136 dev_err(&pdev
->dev
, "Device Tree node missing\n");
140 drvdata
= devm_kzalloc(&pdev
->dev
, sizeof(*drvdata
), GFP_KERNEL
);
144 of_match
= of_match_device(st_pwm_of_match
, &pdev
->dev
);
146 dev_err(&pdev
->dev
, "failed to match of device\n");
149 drvdata
->pdata
= of_match
->data
;
151 config
.init_data
= of_get_regulator_init_data(&pdev
->dev
, np
);
152 if (!config
.init_data
)
156 config
.dev
= &pdev
->dev
;
157 config
.driver_data
= drvdata
;
159 drvdata
->pwm
= devm_pwm_get(&pdev
->dev
, NULL
);
160 if (IS_ERR(drvdata
->pwm
)) {
161 dev_err(&pdev
->dev
, "Failed to get PWM\n");
162 return PTR_ERR(drvdata
->pwm
);
165 regulator
= devm_regulator_register(&pdev
->dev
,
166 drvdata
->pdata
->desc
, &config
);
167 if (IS_ERR(regulator
)) {
168 dev_err(&pdev
->dev
, "Failed to register regulator %s\n",
169 drvdata
->pdata
->desc
->name
);
170 return PTR_ERR(regulator
);
176 static struct platform_driver st_pwm_regulator_driver
= {
178 .name
= "st-pwm-regulator",
179 .owner
= THIS_MODULE
,
180 .of_match_table
= of_match_ptr(st_pwm_of_match
),
182 .probe
= st_pwm_regulator_probe
,
185 module_platform_driver(st_pwm_regulator_driver
);
187 MODULE_LICENSE("GPL");
188 MODULE_AUTHOR("Lee Jones <lee.jones@linaro.org>");
189 MODULE_DESCRIPTION("ST PWM Regulator Driver");
190 MODULE_ALIAS("platform:st_pwm-regulator");