diff options
author | Boris Brezillon <boris.brezillon@free-electrons.com> | 2016-06-14 05:13:18 -0400 |
---|---|---|
committer | Thierry Reding <thierry.reding@gmail.com> | 2016-07-11 02:43:21 -0400 |
commit | 3f4eb39be9b1402ea01a5c67441d0b0bcb74b4b2 (patch) | |
tree | 45f961742b2ef54d9c1e7dcc4c5119519e51e1ba /drivers/regulator | |
parent | fd4f99c4c3ce8ccd9b8ea751afc614a7624ecef2 (diff) |
regulator: pwm: Switch to the atomic PWM API
Use the atomic API wherever appropriate and get rid of pwm_apply_args()
call (the reference period and polarity are now explicitly set when
calling pwm_apply_state()).
We also make use of the pwm_set_relative_duty_cycle() helper to ease
relative to absolute duty_cycle conversion.
Note that changes introduced by commit fd786fb0276a ("regulator: pwm:
Try to avoid voltage error in duty cycle calculation") are no longer
needed because pwm_set_relative_duty_cycle() takes care of all rounding
approximation for us.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Reviewed-by: Brian Norris <briannorris@chromium.org>
Tested-by: Brian Norris <briannorris@chromium.org>
Acked-by: Laxman Dewangan <ldewangan@nvidia.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/pwm-regulator.c | 38 |
1 files changed, 10 insertions, 28 deletions
diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index cb2f22c02469..7920411057af 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c | |||
@@ -63,16 +63,14 @@ static int pwm_regulator_set_voltage_sel(struct regulator_dev *rdev, | |||
63 | unsigned selector) | 63 | unsigned selector) |
64 | { | 64 | { |
65 | struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev); | 65 | struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev); |
66 | struct pwm_args pargs; | 66 | struct pwm_state pstate; |
67 | int dutycycle; | ||
68 | int ret; | 67 | int ret; |
69 | 68 | ||
70 | pwm_get_args(drvdata->pwm, &pargs); | 69 | pwm_init_state(drvdata->pwm, &pstate); |
70 | pwm_set_relative_duty_cycle(&pstate, | ||
71 | drvdata->duty_cycle_table[selector].dutycycle, 100); | ||
71 | 72 | ||
72 | dutycycle = (pargs.period * | 73 | ret = pwm_apply_state(drvdata->pwm, &pstate); |
73 | drvdata->duty_cycle_table[selector].dutycycle) / 100; | ||
74 | |||
75 | ret = pwm_config(drvdata->pwm, dutycycle, pargs.period); | ||
76 | if (ret) { | 74 | if (ret) { |
77 | dev_err(&rdev->dev, "Failed to configure PWM: %d\n", ret); | 75 | dev_err(&rdev->dev, "Failed to configure PWM: %d\n", ret); |
78 | return ret; | 76 | return ret; |
@@ -139,35 +137,19 @@ static int pwm_regulator_set_voltage(struct regulator_dev *rdev, | |||
139 | { | 137 | { |
140 | struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev); | 138 | struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev); |
141 | unsigned int ramp_delay = rdev->constraints->ramp_delay; | 139 | unsigned int ramp_delay = rdev->constraints->ramp_delay; |
142 | struct pwm_args pargs; | ||
143 | unsigned int req_diff = min_uV - rdev->constraints->min_uV; | 140 | unsigned int req_diff = min_uV - rdev->constraints->min_uV; |
141 | struct pwm_state pstate; | ||
144 | unsigned int diff; | 142 | unsigned int diff; |
145 | unsigned int duty_pulse; | ||
146 | u64 req_period; | ||
147 | u32 rem; | ||
148 | int old_uV = pwm_regulator_get_voltage(rdev); | 143 | int old_uV = pwm_regulator_get_voltage(rdev); |
149 | int ret; | 144 | int ret; |
150 | 145 | ||
151 | pwm_get_args(drvdata->pwm, &pargs); | 146 | pwm_init_state(drvdata->pwm, &pstate); |
152 | diff = rdev->constraints->max_uV - rdev->constraints->min_uV; | 147 | diff = rdev->constraints->max_uV - rdev->constraints->min_uV; |
153 | 148 | ||
154 | /* First try to find out if we get the iduty cycle time which is | 149 | /* We pass diff as the scale to get a uV precision. */ |
155 | * factor of PWM period time. If (request_diff_to_min * pwm_period) | 150 | pwm_set_relative_duty_cycle(&pstate, req_diff, diff); |
156 | * is perfect divided by voltage_range_diff then it is possible to | ||
157 | * get duty cycle time which is factor of PWM period. This will help | ||
158 | * to get output voltage nearer to requested value as there is no | ||
159 | * calculation loss. | ||
160 | */ | ||
161 | req_period = req_diff * pargs.period; | ||
162 | div_u64_rem(req_period, diff, &rem); | ||
163 | if (!rem) { | ||
164 | do_div(req_period, diff); | ||
165 | duty_pulse = (unsigned int)req_period; | ||
166 | } else { | ||
167 | duty_pulse = (pargs.period / 100) * ((req_diff * 100) / diff); | ||
168 | } | ||
169 | 151 | ||
170 | ret = pwm_config(drvdata->pwm, duty_pulse, pargs.period); | 152 | ret = pwm_apply_state(drvdata->pwm, &pstate); |
171 | if (ret) { | 153 | if (ret) { |
172 | dev_err(&rdev->dev, "Failed to configure PWM: %d\n", ret); | 154 | dev_err(&rdev->dev, "Failed to configure PWM: %d\n", ret); |
173 | return ret; | 155 | return ret; |