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: Alexandre Belloni <alexandre.belloni@free-electrons.com> Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
This commit is contained in:
Родитель
42586315b7
Коммит
8db9e29fe5
|
@ -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,
|
||||||
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,
|
||||||
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);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче