pwm: atmel: Implement .get_state()
This function reads back the configured parameters from the hardware. As .apply() rounds down (mostly) I'm rounding up in .get_state() to achieve that applying a state just read from hardware is a no-op. Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org> Acked-by: Claudiu Beznea <claudiu.beznea@microchip.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
This commit is contained in:
parent
02afb811e0
commit
651b510a74
|
@ -295,8 +295,48 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void atmel_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
|
||||
u32 sr, cmr;
|
||||
|
||||
sr = atmel_pwm_readl(atmel_pwm, PWM_SR);
|
||||
cmr = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
|
||||
|
||||
if (sr & (1 << pwm->hwpwm)) {
|
||||
unsigned long rate = clk_get_rate(atmel_pwm->clk);
|
||||
u32 cdty, cprd, pres;
|
||||
u64 tmp;
|
||||
|
||||
pres = cmr & PWM_CMR_CPRE_MSK;
|
||||
|
||||
cprd = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,
|
||||
atmel_pwm->data->regs.period);
|
||||
tmp = (u64)cprd * NSEC_PER_SEC;
|
||||
tmp <<= pres;
|
||||
state->period = DIV64_U64_ROUND_UP(tmp, rate);
|
||||
|
||||
cdty = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,
|
||||
atmel_pwm->data->regs.duty);
|
||||
tmp = (u64)cdty * NSEC_PER_SEC;
|
||||
tmp <<= pres;
|
||||
state->duty_cycle = DIV64_U64_ROUND_UP(tmp, rate);
|
||||
|
||||
state->enabled = true;
|
||||
} else {
|
||||
state->enabled = false;
|
||||
}
|
||||
|
||||
if (cmr & PWM_CMR_CPOL)
|
||||
state->polarity = PWM_POLARITY_INVERSED;
|
||||
else
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
}
|
||||
|
||||
static const struct pwm_ops atmel_pwm_ops = {
|
||||
.apply = atmel_pwm_apply,
|
||||
.get_state = atmel_pwm_get_state,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user