Message ID | 20231019200658.1754190-11-u.kleine-koenig@pengutronix.de |
---|---|
State | Accepted |
Delegated to: | Uwe Kleine-König |
Headers | show |
Series | pwm: stm32: Cleanups, get_state() and proper hw take over | expand |
On 10/19/23 22:07, Uwe Kleine-König wrote: > From: Philipp Zabel <p.zabel@pengutronix.de> > > Implement the &pwm_ops->get_state callback so drivers can inherit PWM > state set by the bootloader. > > Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> > [ukl: split off from a patch that also fixes clk enable count in .probe()] > Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> > --- > drivers/pwm/pwm-stm32.c | 42 +++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 42 insertions(+) > Hi Uwe, You can add my: Reviewed-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com> Thanks, Fabrice > diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c > index cc6cae07c02c..68239567a564 100644 > --- a/drivers/pwm/pwm-stm32.c > +++ b/drivers/pwm/pwm-stm32.c > @@ -471,8 +471,50 @@ static int stm32_pwm_apply_locked(struct pwm_chip *chip, struct pwm_device *pwm, > return ret; > } > > +static int stm32_pwm_get_state(struct pwm_chip *chip, > + struct pwm_device *pwm, struct pwm_state *state) > +{ > + struct stm32_pwm *priv = to_stm32_pwm_dev(chip); > + int ch = pwm->hwpwm; > + unsigned long rate; > + u32 ccer, psc, arr, ccr; > + u64 dty, prd; > + int ret; > + > + mutex_lock(&priv->lock); > + > + ret = regmap_read(priv->regmap, TIM_CCER, &ccer); > + if (ret) > + goto out; > + > + state->enabled = ccer & (TIM_CCER_CC1E << (ch * 4)); > + state->polarity = (ccer & (TIM_CCER_CC1P << (ch * 4))) ? > + PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL; > + ret = regmap_read(priv->regmap, TIM_PSC, &psc); > + if (ret) > + goto out; > + ret = regmap_read(priv->regmap, TIM_ARR, &arr); > + if (ret) > + goto out; > + ret = regmap_read(priv->regmap, TIM_CCR1 + 4 * ch, &ccr); > + if (ret) > + goto out; > + > + rate = clk_get_rate(priv->clk); > + > + prd = (u64)NSEC_PER_SEC * (psc + 1) * (arr + 1); > + state->period = DIV_ROUND_UP_ULL(prd, rate); > + dty = (u64)NSEC_PER_SEC * (psc + 1) * ccr; > + state->duty_cycle = DIV_ROUND_UP_ULL(dty, rate); > + > +out: > + mutex_unlock(&priv->lock); > + return ret; > +} > + > static const struct pwm_ops stm32pwm_ops = { > .apply = stm32_pwm_apply_locked, > + .get_state = stm32_pwm_get_state, > .capture = IS_ENABLED(CONFIG_DMA_ENGINE) ? stm32_pwm_capture : NULL, > }; >
diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index cc6cae07c02c..68239567a564 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -471,8 +471,50 @@ static int stm32_pwm_apply_locked(struct pwm_chip *chip, struct pwm_device *pwm, return ret; } +static int stm32_pwm_get_state(struct pwm_chip *chip, + struct pwm_device *pwm, struct pwm_state *state) +{ + struct stm32_pwm *priv = to_stm32_pwm_dev(chip); + int ch = pwm->hwpwm; + unsigned long rate; + u32 ccer, psc, arr, ccr; + u64 dty, prd; + int ret; + + mutex_lock(&priv->lock); + + ret = regmap_read(priv->regmap, TIM_CCER, &ccer); + if (ret) + goto out; + + state->enabled = ccer & (TIM_CCER_CC1E << (ch * 4)); + state->polarity = (ccer & (TIM_CCER_CC1P << (ch * 4))) ? + PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL; + ret = regmap_read(priv->regmap, TIM_PSC, &psc); + if (ret) + goto out; + ret = regmap_read(priv->regmap, TIM_ARR, &arr); + if (ret) + goto out; + ret = regmap_read(priv->regmap, TIM_CCR1 + 4 * ch, &ccr); + if (ret) + goto out; + + rate = clk_get_rate(priv->clk); + + prd = (u64)NSEC_PER_SEC * (psc + 1) * (arr + 1); + state->period = DIV_ROUND_UP_ULL(prd, rate); + dty = (u64)NSEC_PER_SEC * (psc + 1) * ccr; + state->duty_cycle = DIV_ROUND_UP_ULL(dty, rate); + +out: + mutex_unlock(&priv->lock); + return ret; +} + static const struct pwm_ops stm32pwm_ops = { .apply = stm32_pwm_apply_locked, + .get_state = stm32_pwm_get_state, .capture = IS_ENABLED(CONFIG_DMA_ENGINE) ? stm32_pwm_capture : NULL, };