Skip to content

Commit 14d8956

Browse files
Uwe Kleine-Königthierryreding
authored andcommitted
pwm: vt8500: Implement .apply() callback
To eventually get rid of all legacy drivers convert this driver to the modern world implementing .apply(). This just pushes down a slightly optimized variant of how legacy drivers are handled in the core. Signed-off-by: Uwe Kleine-König <[email protected]> Signed-off-by: Thierry Reding <[email protected]>
1 parent 0ee11b8 commit 14d8956

File tree

1 file changed

+50
-7
lines changed

1 file changed

+50
-7
lines changed

drivers/pwm/pwm-vt8500.c

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ static inline void vt8500_pwm_busy_wait(struct vt8500_chip *vt8500, int nr, u8 b
7070
}
7171

7272
static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
73-
int duty_ns, int period_ns)
73+
u64 duty_ns, u64 period_ns)
7474
{
7575
struct vt8500_chip *vt8500 = to_vt8500_chip(chip);
7676
unsigned long long c;
@@ -102,8 +102,8 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
102102
}
103103

104104
c = (unsigned long long)pv * duty_ns;
105-
do_div(c, period_ns);
106-
dc = c;
105+
106+
dc = div64_u64(c, period_ns);
107107

108108
writel(prescale, vt8500->base + REG_SCALAR(pwm->hwpwm));
109109
vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_SCALAR_UPDATE);
@@ -176,11 +176,54 @@ static int vt8500_pwm_set_polarity(struct pwm_chip *chip,
176176
return 0;
177177
}
178178

179+
static int vt8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
180+
const struct pwm_state *state)
181+
{
182+
int err;
183+
bool enabled = pwm->state.enabled;
184+
185+
if (state->polarity != pwm->state.polarity) {
186+
/*
187+
* Changing the polarity of a running PWM is only allowed when
188+
* the PWM driver implements ->apply().
189+
*/
190+
if (enabled) {
191+
vt8500_pwm_disable(chip, pwm);
192+
193+
enabled = false;
194+
}
195+
196+
err = vt8500_pwm_set_polarity(chip, pwm, state->polarity);
197+
if (err)
198+
return err;
199+
}
200+
201+
if (!state->enabled) {
202+
if (enabled)
203+
vt8500_pwm_disable(chip, pwm);
204+
205+
return 0;
206+
}
207+
208+
/*
209+
* We cannot skip calling ->config even if state->period ==
210+
* pwm->state.period && state->duty_cycle == pwm->state.duty_cycle
211+
* because we might have exited early in the last call to
212+
* pwm_apply_state because of !state->enabled and so the two values in
213+
* pwm->state might not be configured in hardware.
214+
*/
215+
err = vt8500_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period);
216+
if (err)
217+
return err;
218+
219+
if (!enabled)
220+
err = vt8500_pwm_enable(chip, pwm);
221+
222+
return err;
223+
}
224+
179225
static const struct pwm_ops vt8500_pwm_ops = {
180-
.enable = vt8500_pwm_enable,
181-
.disable = vt8500_pwm_disable,
182-
.config = vt8500_pwm_config,
183-
.set_polarity = vt8500_pwm_set_polarity,
226+
.apply = vt8500_pwm_apply,
184227
.owner = THIS_MODULE,
185228
};
186229

0 commit comments

Comments
 (0)