diff options
author | Philipp Zabel <p.zabel@pengutronix.de> | 2023-10-19 22:07:03 +0200 |
---|---|---|
committer | Thierry Reding <thierry.reding@gmail.com> | 2023-12-20 16:04:14 +0100 |
commit | e56ec7b7527c2be54a0c15064c71838fd5c49d4b (patch) | |
tree | 57d7bb7d992dd800cf29ef937555f550861f7435 /drivers/pwm/pwm-stm32.c | |
parent | 41fa8f57c0d269243fe3bde2bce71e82c884b9ad (diff) | |
download | lwn-e56ec7b7527c2be54a0c15064c71838fd5c49d4b.tar.gz lwn-e56ec7b7527c2be54a0c15064c71838fd5c49d4b.zip |
pwm: stm32: Implement .get_state()
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>
Reviewed-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Diffstat (limited to 'drivers/pwm/pwm-stm32.c')
-rw-r--r-- | drivers/pwm/pwm-stm32.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index 0da371291cef..9a7d7891edde 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, }; |