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

Commit 8db9e29f authored by Alexandre Belloni's avatar Alexandre Belloni Committed by Thierry Reding
Browse files

pwm: atmel: Fix polarity handling



When atmel_pwm_config() calculates and then sets the prescaler, it is
overwriting the channel's CMR register so we are losing the CPOL
configuration.

As atmel_pwm_config() is always called before enabling a channel,
inverting the polarity doesn't work.

Fix that by reading CMR first and only overwriting the prescaler bits.

Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: default avatarNicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: default avatarThierry Reding <thierry.reding@gmail.com>
parent 42586315
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
/* Bit field in CMR */
#define PWM_CMR_CPOL		(1 << 9)
#define PWM_CMR_UPD_CDTY	(1 << 10)
#define PWM_CMR_CPRE_MSK	0xF

/* The following registers for PWM v1 */
#define PWMV1_CDTY		0x04
@@ -104,6 +105,7 @@ static int atmel_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
	unsigned long clk_rate, prd, dty;
	unsigned long long div;
	unsigned int pres = 0;
	u32 val;
	int ret;

	if (test_bit(PWMF_ENABLED, &pwm->flags) && (period_ns != pwm->period)) {
@@ -139,7 +141,10 @@ static int atmel_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
		return ret;
	}

	atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, pres);
	/* It is necessary to preserve CPOL, inside CMR */
	val = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
	val = (val & ~PWM_CMR_CPRE_MSK) | (pres & PWM_CMR_CPRE_MSK);
	atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
	atmel_pwm->config(chip, pwm, dty, prd);

	clk_disable(atmel_pwm->clk);