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

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
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
/* Bit field in CMR */ /* Bit field in CMR */
#define PWM_CMR_CPOL (1 << 9) #define PWM_CMR_CPOL (1 << 9)
#define PWM_CMR_UPD_CDTY (1 << 10) #define PWM_CMR_UPD_CDTY (1 << 10)
#define PWM_CMR_CPRE_MSK 0xF
/* The following registers for PWM v1 */ /* The following registers for PWM v1 */
#define PWMV1_CDTY 0x04 #define PWMV1_CDTY 0x04
...@@ -104,6 +105,7 @@ static int atmel_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -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 clk_rate, prd, dty;
unsigned long long div; unsigned long long div;
unsigned int pres = 0; unsigned int pres = 0;
u32 val;
int ret; int ret;
if (test_bit(PWMF_ENABLED, &pwm->flags) && (period_ns != pwm->period)) { 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, ...@@ -139,7 +141,10 @@ static int atmel_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
return ret; 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); atmel_pwm->config(chip, pwm, dty, prd);
clk_disable(atmel_pwm->clk); clk_disable(atmel_pwm->clk);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment