Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ac99c58 authored by Paul Cercueil's avatar Paul Cercueil Committed by Thierry Reding
Browse files

pwm: jz4740: Apply configuration atomically



This is cleaner, more future-proof, and incidentally it also fixes the
PWM resetting its config when stopped/started several times.

Signed-off-by: default avatarPaul Cercueil <paul@crapouillou.net>
Signed-off-by: default avatarThierry Reding <thierry.reding@gmail.com>
parent 93808aca
Loading
Loading
Loading
Loading
+12 −25
Original line number Diff line number Diff line
@@ -83,17 +83,16 @@ static void jz4740_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
	jz4740_timer_disable(pwm->hwpwm);
}

static int jz4740_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
			     int duty_ns, int period_ns)
static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
			    struct pwm_state *state)
{
	struct jz4740_pwm_chip *jz4740 = to_jz4740(pwm->chip);
	unsigned long long tmp;
	unsigned long period, duty;
	unsigned int prescaler = 0;
	uint16_t ctrl;
	bool is_enabled;

	tmp = (unsigned long long)clk_get_rate(jz4740->clk) * period_ns;
	tmp = (unsigned long long)clk_get_rate(jz4740->clk) * state->period;
	do_div(tmp, 1000000000);
	period = tmp;

@@ -105,15 +104,13 @@ static int jz4740_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
	if (prescaler == 6)
		return -EINVAL;

	tmp = (unsigned long long)period * duty_ns;
	do_div(tmp, period_ns);
	tmp = (unsigned long long)period * state->duty_cycle;
	do_div(tmp, state->period);
	duty = period - tmp;

	if (duty >= period)
		duty = period - 1;

	is_enabled = jz4740_timer_is_enabled(pwm->hwpwm);
	if (is_enabled)
	jz4740_pwm_disable(chip, pwm);

	jz4740_timer_set_count(pwm->hwpwm, 0);
@@ -125,18 +122,7 @@ static int jz4740_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,

	jz4740_timer_set_ctrl(pwm->hwpwm, ctrl);

	if (is_enabled)
		jz4740_pwm_enable(chip, pwm);

	return 0;
}

static int jz4740_pwm_set_polarity(struct pwm_chip *chip,
		struct pwm_device *pwm, enum pwm_polarity polarity)
{
	uint32_t ctrl = jz4740_timer_get_ctrl(pwm->pwm);

	switch (polarity) {
	switch (state->polarity) {
	case PWM_POLARITY_NORMAL:
		ctrl &= ~JZ_TIMER_CTRL_PWM_ACTIVE_LOW;
		break;
@@ -146,16 +132,17 @@ static int jz4740_pwm_set_polarity(struct pwm_chip *chip,
	}

	jz4740_timer_set_ctrl(pwm->hwpwm, ctrl);

	if (state->enabled)
		jz4740_pwm_enable(chip, pwm);

	return 0;
}

static const struct pwm_ops jz4740_pwm_ops = {
	.request = jz4740_pwm_request,
	.free = jz4740_pwm_free,
	.config = jz4740_pwm_config,
	.set_polarity = jz4740_pwm_set_polarity,
	.enable = jz4740_pwm_enable,
	.disable = jz4740_pwm_disable,
	.apply = jz4740_pwm_apply,
	.owner = THIS_MODULE,
};