Commit 14d89565 authored by Uwe Kleine-König's avatar Uwe Kleine-König Committed by Thierry Reding
Browse files

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: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: default avatarThierry Reding <thierry.reding@gmail.com>
parent 0ee11b87
Loading
Loading
Loading
Loading
+50 −7
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ static inline void vt8500_pwm_busy_wait(struct vt8500_chip *vt8500, int nr, u8 b
}

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

	c = (unsigned long long)pv * duty_ns;
	do_div(c, period_ns);
	dc = c;

	dc = div64_u64(c, period_ns);

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

static int vt8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
			    const struct pwm_state *state)
{
	int err;
	bool enabled = pwm->state.enabled;

	if (state->polarity != pwm->state.polarity) {
		/*
		 * Changing the polarity of a running PWM is only allowed when
		 * the PWM driver implements ->apply().
		 */
		if (enabled) {
			vt8500_pwm_disable(chip, pwm);

			enabled = false;
		}

		err = vt8500_pwm_set_polarity(chip, pwm, state->polarity);
		if (err)
			return err;
	}

	if (!state->enabled) {
		if (enabled)
			vt8500_pwm_disable(chip, pwm);

		return 0;
	}

	/*
	 * We cannot skip calling ->config even if state->period ==
	 * pwm->state.period && state->duty_cycle == pwm->state.duty_cycle
	 * because we might have exited early in the last call to
	 * pwm_apply_state because of !state->enabled and so the two values in
	 * pwm->state might not be configured in hardware.
	 */
	err = vt8500_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period);
	if (err)
		return err;

	if (!enabled)
		err = vt8500_pwm_enable(chip, pwm);

	return err;
}

static const struct pwm_ops vt8500_pwm_ops = {
	.enable = vt8500_pwm_enable,
	.disable = vt8500_pwm_disable,
	.config = vt8500_pwm_config,
	.set_polarity = vt8500_pwm_set_polarity,
	.apply = vt8500_pwm_apply,
	.owner = THIS_MODULE,
};