Commit fa4d8178 authored by Clément Péron's avatar Clément Péron Committed by Thierry Reding

pwm: sun4i: Always calculate params when applying new parameters

Bypass mode will require to be re-calculated when the pwm state
is changed.

Remove the condition so pwm_sun4i_calculate is always called.
Reviewed-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: default avatarClément Péron <peron.clem@gmail.com>
Signed-off-by: default avatarThierry Reding <thierry.reding@gmail.com>
parent 5b090b43
...@@ -202,9 +202,9 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -202,9 +202,9 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
{ {
struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip); struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
struct pwm_state cstate; struct pwm_state cstate;
u32 ctrl; u32 ctrl, duty, period, val;
int ret; int ret;
unsigned int delay_us; unsigned int delay_us, prescaler;
unsigned long now; unsigned long now;
pwm_get_state(pwm, &cstate); pwm_get_state(pwm, &cstate);
...@@ -220,43 +220,37 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -220,43 +220,37 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
spin_lock(&sun4i_pwm->ctrl_lock); spin_lock(&sun4i_pwm->ctrl_lock);
ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG); ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
if ((cstate.period != state->period) || ret = sun4i_pwm_calculate(sun4i_pwm, state, &duty, &period, &prescaler);
(cstate.duty_cycle != state->duty_cycle)) { if (ret) {
u32 period, duty, val; dev_err(chip->dev, "period exceeds the maximum value\n");
unsigned int prescaler; spin_unlock(&sun4i_pwm->ctrl_lock);
if (!cstate.enabled)
ret = sun4i_pwm_calculate(sun4i_pwm, state, clk_disable_unprepare(sun4i_pwm->clk);
&duty, &period, &prescaler); return ret;
if (ret) { }
dev_err(chip->dev, "period exceeds the maximum value\n");
spin_unlock(&sun4i_pwm->ctrl_lock);
if (!cstate.enabled)
clk_disable_unprepare(sun4i_pwm->clk);
return ret;
}
if (PWM_REG_PRESCAL(ctrl, pwm->hwpwm) != prescaler) {
/* Prescaler changed, the clock has to be gated */
ctrl &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG);
ctrl &= ~BIT_CH(PWM_PRESCAL_MASK, pwm->hwpwm); if (PWM_REG_PRESCAL(ctrl, pwm->hwpwm) != prescaler) {
ctrl |= BIT_CH(prescaler, pwm->hwpwm); /* Prescaler changed, the clock has to be gated */
} ctrl &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG);
val = (duty & PWM_DTY_MASK) | PWM_PRD(period); ctrl &= ~BIT_CH(PWM_PRESCAL_MASK, pwm->hwpwm);
sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm)); ctrl |= BIT_CH(prescaler, pwm->hwpwm);
sun4i_pwm->next_period[pwm->hwpwm] = jiffies +
usecs_to_jiffies(cstate.period / 1000 + 1);
sun4i_pwm->needs_delay[pwm->hwpwm] = true;
} }
val = (duty & PWM_DTY_MASK) | PWM_PRD(period);
sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm));
sun4i_pwm->next_period[pwm->hwpwm] = jiffies +
usecs_to_jiffies(cstate.period / 1000 + 1);
sun4i_pwm->needs_delay[pwm->hwpwm] = true;
if (state->polarity != PWM_POLARITY_NORMAL) if (state->polarity != PWM_POLARITY_NORMAL)
ctrl &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm); ctrl &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
else else
ctrl |= BIT_CH(PWM_ACT_STATE, pwm->hwpwm); ctrl |= BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
ctrl |= BIT_CH(PWM_CLK_GATING, pwm->hwpwm); ctrl |= BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
if (state->enabled) { if (state->enabled) {
ctrl |= BIT_CH(PWM_EN, pwm->hwpwm); ctrl |= BIT_CH(PWM_EN, pwm->hwpwm);
} else if (!sun4i_pwm->needs_delay[pwm->hwpwm]) { } else if (!sun4i_pwm->needs_delay[pwm->hwpwm]) {
......
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