1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Regulator driver for PWM Regulators
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2014 - STMicroelectronics Inc.
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Author: Lee Jones <lee.jones@linaro.org>
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <linux/module.h>
11*4882a593Smuzhiyun #include <linux/init.h>
12*4882a593Smuzhiyun #include <linux/err.h>
13*4882a593Smuzhiyun #include <linux/regulator/driver.h>
14*4882a593Smuzhiyun #include <linux/regulator/machine.h>
15*4882a593Smuzhiyun #include <linux/regulator/of_regulator.h>
16*4882a593Smuzhiyun #include <linux/of.h>
17*4882a593Smuzhiyun #include <linux/of_device.h>
18*4882a593Smuzhiyun #include <linux/pwm.h>
19*4882a593Smuzhiyun #include <linux/gpio/consumer.h>
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun struct pwm_continuous_reg_data {
22*4882a593Smuzhiyun unsigned int min_uV_dutycycle;
23*4882a593Smuzhiyun unsigned int max_uV_dutycycle;
24*4882a593Smuzhiyun unsigned int dutycycle_unit;
25*4882a593Smuzhiyun };
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun struct pwm_regulator_data {
28*4882a593Smuzhiyun /* Shared */
29*4882a593Smuzhiyun struct pwm_device *pwm;
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun /* Voltage table */
32*4882a593Smuzhiyun struct pwm_voltages *duty_cycle_table;
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun /* Continuous mode info */
35*4882a593Smuzhiyun struct pwm_continuous_reg_data continuous;
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun /* regulator descriptor */
38*4882a593Smuzhiyun struct regulator_desc desc;
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun int state;
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun /* Enable GPIO */
43*4882a593Smuzhiyun struct gpio_desc *enb_gpio;
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun /* Init voltage */
46*4882a593Smuzhiyun int init_uv;
47*4882a593Smuzhiyun };
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun struct pwm_voltages {
50*4882a593Smuzhiyun unsigned int uV;
51*4882a593Smuzhiyun unsigned int dutycycle;
52*4882a593Smuzhiyun };
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun static int pwm_regulator_set_voltage(struct regulator_dev *rdev,
55*4882a593Smuzhiyun int req_min_uV, int req_max_uV,
56*4882a593Smuzhiyun unsigned int *selector);
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun /*
59*4882a593Smuzhiyun * Voltage table call-backs
60*4882a593Smuzhiyun */
pwm_regulator_init_state(struct regulator_dev * rdev)61*4882a593Smuzhiyun static void pwm_regulator_init_state(struct regulator_dev *rdev)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
64*4882a593Smuzhiyun struct pwm_state pwm_state;
65*4882a593Smuzhiyun unsigned int dutycycle;
66*4882a593Smuzhiyun int i;
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun pwm_get_state(drvdata->pwm, &pwm_state);
69*4882a593Smuzhiyun dutycycle = pwm_get_relative_duty_cycle(&pwm_state, 100);
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun for (i = 0; i < rdev->desc->n_voltages; i++) {
72*4882a593Smuzhiyun if (dutycycle == drvdata->duty_cycle_table[i].dutycycle) {
73*4882a593Smuzhiyun drvdata->state = i;
74*4882a593Smuzhiyun return;
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun
pwm_regulator_get_voltage_sel(struct regulator_dev * rdev)79*4882a593Smuzhiyun static int pwm_regulator_get_voltage_sel(struct regulator_dev *rdev)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun if (drvdata->state < 0)
84*4882a593Smuzhiyun pwm_regulator_init_state(rdev);
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun return drvdata->state;
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun
pwm_regulator_set_voltage_sel(struct regulator_dev * rdev,unsigned selector)89*4882a593Smuzhiyun static int pwm_regulator_set_voltage_sel(struct regulator_dev *rdev,
90*4882a593Smuzhiyun unsigned selector)
91*4882a593Smuzhiyun {
92*4882a593Smuzhiyun struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
93*4882a593Smuzhiyun struct pwm_state pstate;
94*4882a593Smuzhiyun int ret;
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun pwm_init_state(drvdata->pwm, &pstate);
97*4882a593Smuzhiyun pwm_set_relative_duty_cycle(&pstate,
98*4882a593Smuzhiyun drvdata->duty_cycle_table[selector].dutycycle, 100);
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun ret = pwm_apply_state(drvdata->pwm, &pstate);
101*4882a593Smuzhiyun if (ret) {
102*4882a593Smuzhiyun dev_err(&rdev->dev, "Failed to configure PWM: %d\n", ret);
103*4882a593Smuzhiyun return ret;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun drvdata->state = selector;
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun return 0;
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun
pwm_regulator_list_voltage(struct regulator_dev * rdev,unsigned selector)111*4882a593Smuzhiyun static int pwm_regulator_list_voltage(struct regulator_dev *rdev,
112*4882a593Smuzhiyun unsigned selector)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun if (selector >= rdev->desc->n_voltages)
117*4882a593Smuzhiyun return -EINVAL;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun return drvdata->duty_cycle_table[selector].uV;
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
pwm_regulator_enable(struct regulator_dev * dev)122*4882a593Smuzhiyun static int pwm_regulator_enable(struct regulator_dev *dev)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun if (drvdata->init_uv && !pwm_get_duty_cycle(drvdata->pwm))
127*4882a593Smuzhiyun pwm_regulator_set_voltage(dev, drvdata->init_uv,
128*4882a593Smuzhiyun drvdata->init_uv, NULL);
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun gpiod_set_value_cansleep(drvdata->enb_gpio, 1);
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun return pwm_enable(drvdata->pwm);
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun
pwm_regulator_disable(struct regulator_dev * dev)135*4882a593Smuzhiyun static int pwm_regulator_disable(struct regulator_dev *dev)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun pwm_disable(drvdata->pwm);
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun gpiod_set_value_cansleep(drvdata->enb_gpio, 0);
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun return 0;
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun
pwm_regulator_is_enabled(struct regulator_dev * dev)146*4882a593Smuzhiyun static int pwm_regulator_is_enabled(struct regulator_dev *dev)
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun if (drvdata->enb_gpio && !gpiod_get_value_cansleep(drvdata->enb_gpio))
151*4882a593Smuzhiyun return false;
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun return pwm_is_enabled(drvdata->pwm);
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun
pwm_regulator_get_voltage(struct regulator_dev * rdev)156*4882a593Smuzhiyun static int pwm_regulator_get_voltage(struct regulator_dev *rdev)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
159*4882a593Smuzhiyun unsigned int min_uV_duty = drvdata->continuous.min_uV_dutycycle;
160*4882a593Smuzhiyun unsigned int max_uV_duty = drvdata->continuous.max_uV_dutycycle;
161*4882a593Smuzhiyun unsigned int duty_unit = drvdata->continuous.dutycycle_unit;
162*4882a593Smuzhiyun int min_uV = rdev->constraints->min_uV;
163*4882a593Smuzhiyun int max_uV = rdev->constraints->max_uV;
164*4882a593Smuzhiyun int diff_uV = max_uV - min_uV;
165*4882a593Smuzhiyun struct pwm_state pstate;
166*4882a593Smuzhiyun unsigned int diff_duty;
167*4882a593Smuzhiyun unsigned int voltage;
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun pwm_get_state(drvdata->pwm, &pstate);
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun voltage = pwm_get_relative_duty_cycle(&pstate, duty_unit);
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun /*
174*4882a593Smuzhiyun * The dutycycle for min_uV might be greater than the one for max_uV.
175*4882a593Smuzhiyun * This is happening when the user needs an inversed polarity, but the
176*4882a593Smuzhiyun * PWM device does not support inversing it in hardware.
177*4882a593Smuzhiyun */
178*4882a593Smuzhiyun if (max_uV_duty < min_uV_duty) {
179*4882a593Smuzhiyun voltage = min_uV_duty - voltage;
180*4882a593Smuzhiyun diff_duty = min_uV_duty - max_uV_duty;
181*4882a593Smuzhiyun } else {
182*4882a593Smuzhiyun voltage = voltage - min_uV_duty;
183*4882a593Smuzhiyun diff_duty = max_uV_duty - min_uV_duty;
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun voltage = DIV_ROUND_CLOSEST_ULL((u64)voltage * diff_uV, diff_duty);
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun return voltage + min_uV;
189*4882a593Smuzhiyun }
190*4882a593Smuzhiyun
pwm_regulator_set_voltage(struct regulator_dev * rdev,int req_min_uV,int req_max_uV,unsigned int * selector)191*4882a593Smuzhiyun static int pwm_regulator_set_voltage(struct regulator_dev *rdev,
192*4882a593Smuzhiyun int req_min_uV, int req_max_uV,
193*4882a593Smuzhiyun unsigned int *selector)
194*4882a593Smuzhiyun {
195*4882a593Smuzhiyun struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
196*4882a593Smuzhiyun unsigned int min_uV_duty = drvdata->continuous.min_uV_dutycycle;
197*4882a593Smuzhiyun unsigned int max_uV_duty = drvdata->continuous.max_uV_dutycycle;
198*4882a593Smuzhiyun unsigned int duty_unit = drvdata->continuous.dutycycle_unit;
199*4882a593Smuzhiyun int min_uV = rdev->constraints->min_uV;
200*4882a593Smuzhiyun int max_uV = rdev->constraints->max_uV;
201*4882a593Smuzhiyun int diff_uV = max_uV - min_uV;
202*4882a593Smuzhiyun struct pwm_state pstate;
203*4882a593Smuzhiyun unsigned int diff_duty;
204*4882a593Smuzhiyun unsigned int dutycycle;
205*4882a593Smuzhiyun int ret;
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun pwm_init_state(drvdata->pwm, &pstate);
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun /*
210*4882a593Smuzhiyun * The dutycycle for min_uV might be greater than the one for max_uV.
211*4882a593Smuzhiyun * This is happening when the user needs an inversed polarity, but the
212*4882a593Smuzhiyun * PWM device does not support inversing it in hardware.
213*4882a593Smuzhiyun */
214*4882a593Smuzhiyun if (max_uV_duty < min_uV_duty)
215*4882a593Smuzhiyun diff_duty = min_uV_duty - max_uV_duty;
216*4882a593Smuzhiyun else
217*4882a593Smuzhiyun diff_duty = max_uV_duty - min_uV_duty;
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun dutycycle = DIV_ROUND_CLOSEST_ULL((u64)(req_min_uV - min_uV) *
220*4882a593Smuzhiyun diff_duty,
221*4882a593Smuzhiyun diff_uV);
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun if (max_uV_duty < min_uV_duty)
224*4882a593Smuzhiyun dutycycle = min_uV_duty - dutycycle;
225*4882a593Smuzhiyun else
226*4882a593Smuzhiyun dutycycle = min_uV_duty + dutycycle;
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun pwm_set_relative_duty_cycle(&pstate, dutycycle, duty_unit);
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun ret = pwm_apply_state(drvdata->pwm, &pstate);
231*4882a593Smuzhiyun if (ret) {
232*4882a593Smuzhiyun dev_err(&rdev->dev, "Failed to configure PWM: %d\n", ret);
233*4882a593Smuzhiyun return ret;
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun return 0;
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun static const struct regulator_ops pwm_regulator_voltage_table_ops = {
240*4882a593Smuzhiyun .set_voltage_sel = pwm_regulator_set_voltage_sel,
241*4882a593Smuzhiyun .get_voltage_sel = pwm_regulator_get_voltage_sel,
242*4882a593Smuzhiyun .list_voltage = pwm_regulator_list_voltage,
243*4882a593Smuzhiyun .map_voltage = regulator_map_voltage_iterate,
244*4882a593Smuzhiyun .enable = pwm_regulator_enable,
245*4882a593Smuzhiyun .disable = pwm_regulator_disable,
246*4882a593Smuzhiyun .is_enabled = pwm_regulator_is_enabled,
247*4882a593Smuzhiyun };
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun static const struct regulator_ops pwm_regulator_voltage_continuous_ops = {
250*4882a593Smuzhiyun .get_voltage = pwm_regulator_get_voltage,
251*4882a593Smuzhiyun .set_voltage = pwm_regulator_set_voltage,
252*4882a593Smuzhiyun .enable = pwm_regulator_enable,
253*4882a593Smuzhiyun .disable = pwm_regulator_disable,
254*4882a593Smuzhiyun .is_enabled = pwm_regulator_is_enabled,
255*4882a593Smuzhiyun };
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun static const struct regulator_desc pwm_regulator_desc = {
258*4882a593Smuzhiyun .name = "pwm-regulator",
259*4882a593Smuzhiyun .type = REGULATOR_VOLTAGE,
260*4882a593Smuzhiyun .owner = THIS_MODULE,
261*4882a593Smuzhiyun .supply_name = "pwm",
262*4882a593Smuzhiyun };
263*4882a593Smuzhiyun
pwm_regulator_init_table(struct platform_device * pdev,struct pwm_regulator_data * drvdata)264*4882a593Smuzhiyun static int pwm_regulator_init_table(struct platform_device *pdev,
265*4882a593Smuzhiyun struct pwm_regulator_data *drvdata)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun struct device_node *np = pdev->dev.of_node;
268*4882a593Smuzhiyun struct pwm_voltages *duty_cycle_table;
269*4882a593Smuzhiyun unsigned int length = 0;
270*4882a593Smuzhiyun int ret;
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun of_find_property(np, "voltage-table", &length);
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun if ((length < sizeof(*duty_cycle_table)) ||
275*4882a593Smuzhiyun (length % sizeof(*duty_cycle_table))) {
276*4882a593Smuzhiyun dev_err(&pdev->dev, "voltage-table length(%d) is invalid\n",
277*4882a593Smuzhiyun length);
278*4882a593Smuzhiyun return -EINVAL;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun duty_cycle_table = devm_kzalloc(&pdev->dev, length, GFP_KERNEL);
282*4882a593Smuzhiyun if (!duty_cycle_table)
283*4882a593Smuzhiyun return -ENOMEM;
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun ret = of_property_read_u32_array(np, "voltage-table",
286*4882a593Smuzhiyun (u32 *)duty_cycle_table,
287*4882a593Smuzhiyun length / sizeof(u32));
288*4882a593Smuzhiyun if (ret) {
289*4882a593Smuzhiyun dev_err(&pdev->dev, "Failed to read voltage-table: %d\n", ret);
290*4882a593Smuzhiyun return ret;
291*4882a593Smuzhiyun }
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun drvdata->state = -ENOTRECOVERABLE;
294*4882a593Smuzhiyun drvdata->duty_cycle_table = duty_cycle_table;
295*4882a593Smuzhiyun drvdata->desc.ops = &pwm_regulator_voltage_table_ops;
296*4882a593Smuzhiyun drvdata->desc.n_voltages = length / sizeof(*duty_cycle_table);
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun return 0;
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun
pwm_regulator_init_continuous(struct platform_device * pdev,struct pwm_regulator_data * drvdata)301*4882a593Smuzhiyun static int pwm_regulator_init_continuous(struct platform_device *pdev,
302*4882a593Smuzhiyun struct pwm_regulator_data *drvdata)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun u32 dutycycle_range[2] = { 0, 100 };
305*4882a593Smuzhiyun u32 dutycycle_unit = 100;
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun drvdata->desc.ops = &pwm_regulator_voltage_continuous_ops;
308*4882a593Smuzhiyun drvdata->desc.continuous_voltage_range = true;
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun of_property_read_u32_array(pdev->dev.of_node,
311*4882a593Smuzhiyun "pwm-dutycycle-range",
312*4882a593Smuzhiyun dutycycle_range, 2);
313*4882a593Smuzhiyun of_property_read_u32(pdev->dev.of_node, "pwm-dutycycle-unit",
314*4882a593Smuzhiyun &dutycycle_unit);
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun if (dutycycle_range[0] > dutycycle_unit ||
317*4882a593Smuzhiyun dutycycle_range[1] > dutycycle_unit)
318*4882a593Smuzhiyun return -EINVAL;
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun drvdata->continuous.dutycycle_unit = dutycycle_unit;
321*4882a593Smuzhiyun drvdata->continuous.min_uV_dutycycle = dutycycle_range[0];
322*4882a593Smuzhiyun drvdata->continuous.max_uV_dutycycle = dutycycle_range[1];
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun return 0;
325*4882a593Smuzhiyun }
326*4882a593Smuzhiyun
pwm_regulator_probe(struct platform_device * pdev)327*4882a593Smuzhiyun static int pwm_regulator_probe(struct platform_device *pdev)
328*4882a593Smuzhiyun {
329*4882a593Smuzhiyun const struct regulator_init_data *init_data;
330*4882a593Smuzhiyun struct pwm_regulator_data *drvdata;
331*4882a593Smuzhiyun struct regulator_dev *regulator;
332*4882a593Smuzhiyun struct regulator_config config = { };
333*4882a593Smuzhiyun struct device_node *np = pdev->dev.of_node;
334*4882a593Smuzhiyun enum gpiod_flags gpio_flags;
335*4882a593Smuzhiyun int ret;
336*4882a593Smuzhiyun u32 init_uv;
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun if (!np) {
339*4882a593Smuzhiyun dev_err(&pdev->dev, "Device Tree node missing\n");
340*4882a593Smuzhiyun return -EINVAL;
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
344*4882a593Smuzhiyun if (!drvdata)
345*4882a593Smuzhiyun return -ENOMEM;
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun memcpy(&drvdata->desc, &pwm_regulator_desc, sizeof(drvdata->desc));
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun if (of_find_property(np, "voltage-table", NULL))
350*4882a593Smuzhiyun ret = pwm_regulator_init_table(pdev, drvdata);
351*4882a593Smuzhiyun else
352*4882a593Smuzhiyun ret = pwm_regulator_init_continuous(pdev, drvdata);
353*4882a593Smuzhiyun if (ret)
354*4882a593Smuzhiyun return ret;
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun if (!of_property_read_u32(np, "regulator-init-microvolt", &init_uv))
357*4882a593Smuzhiyun drvdata->init_uv = init_uv;
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun init_data = of_get_regulator_init_data(&pdev->dev, np,
360*4882a593Smuzhiyun &drvdata->desc);
361*4882a593Smuzhiyun if (!init_data)
362*4882a593Smuzhiyun return -ENOMEM;
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun config.of_node = np;
365*4882a593Smuzhiyun config.dev = &pdev->dev;
366*4882a593Smuzhiyun config.driver_data = drvdata;
367*4882a593Smuzhiyun config.init_data = init_data;
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun drvdata->pwm = devm_pwm_get(&pdev->dev, NULL);
370*4882a593Smuzhiyun if (IS_ERR(drvdata->pwm)) {
371*4882a593Smuzhiyun ret = PTR_ERR(drvdata->pwm);
372*4882a593Smuzhiyun if (ret == -EPROBE_DEFER)
373*4882a593Smuzhiyun dev_dbg(&pdev->dev,
374*4882a593Smuzhiyun "Failed to get PWM, deferring probe\n");
375*4882a593Smuzhiyun else
376*4882a593Smuzhiyun dev_err(&pdev->dev, "Failed to get PWM: %d\n", ret);
377*4882a593Smuzhiyun return ret;
378*4882a593Smuzhiyun }
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun if (init_data->constraints.boot_on || init_data->constraints.always_on)
381*4882a593Smuzhiyun gpio_flags = GPIOD_OUT_HIGH;
382*4882a593Smuzhiyun else
383*4882a593Smuzhiyun gpio_flags = GPIOD_OUT_LOW;
384*4882a593Smuzhiyun drvdata->enb_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
385*4882a593Smuzhiyun gpio_flags);
386*4882a593Smuzhiyun if (IS_ERR(drvdata->enb_gpio)) {
387*4882a593Smuzhiyun ret = PTR_ERR(drvdata->enb_gpio);
388*4882a593Smuzhiyun dev_err(&pdev->dev, "Failed to get enable GPIO: %d\n", ret);
389*4882a593Smuzhiyun return ret;
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun ret = pwm_adjust_config(drvdata->pwm);
393*4882a593Smuzhiyun if (ret)
394*4882a593Smuzhiyun return ret;
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun regulator = devm_regulator_register(&pdev->dev,
397*4882a593Smuzhiyun &drvdata->desc, &config);
398*4882a593Smuzhiyun if (IS_ERR(regulator)) {
399*4882a593Smuzhiyun ret = PTR_ERR(regulator);
400*4882a593Smuzhiyun dev_err(&pdev->dev, "Failed to register regulator %s: %d\n",
401*4882a593Smuzhiyun drvdata->desc.name, ret);
402*4882a593Smuzhiyun return ret;
403*4882a593Smuzhiyun }
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun return 0;
406*4882a593Smuzhiyun }
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun static const struct of_device_id __maybe_unused pwm_of_match[] = {
409*4882a593Smuzhiyun { .compatible = "pwm-regulator" },
410*4882a593Smuzhiyun { },
411*4882a593Smuzhiyun };
412*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, pwm_of_match);
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun static struct platform_driver pwm_regulator_driver = {
415*4882a593Smuzhiyun .driver = {
416*4882a593Smuzhiyun .name = "pwm-regulator",
417*4882a593Smuzhiyun .of_match_table = of_match_ptr(pwm_of_match),
418*4882a593Smuzhiyun },
419*4882a593Smuzhiyun .probe = pwm_regulator_probe,
420*4882a593Smuzhiyun };
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun module_platform_driver(pwm_regulator_driver);
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun MODULE_LICENSE("GPL");
425*4882a593Smuzhiyun MODULE_AUTHOR("Lee Jones <lee.jones@linaro.org>");
426*4882a593Smuzhiyun MODULE_DESCRIPTION("PWM Regulator Driver");
427*4882a593Smuzhiyun MODULE_ALIAS("platform:pwm-regulator");
428