diff options
author | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 2023-01-18 16:48:17 +0100 |
---|---|---|
committer | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 2023-01-25 16:57:35 +0100 |
commit | 7b98f1eabace46f4dd25b3861a99e23a7a97f2e0 (patch) | |
tree | a1e31f2b186f146a65f3ab8197f913ab9c0e1933 | |
parent | 5d35120cba07f61978c7f196315eea311c35adb3 (diff) | |
download | linux-pwm/for-next.tar.gz linux-pwm/for-next.tar.xz |
pwm: ab8500: Implement .get_state()pwm/for-next
The registers are readable, so it's possible to implement the
.get_state() callback for this PWM.
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20230118154817.97364-3-u.kleine-koenig@pengutronix.de
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
-rw-r--r-- | drivers/pwm/pwm-ab8500.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/pwm/pwm-ab8500.c b/drivers/pwm/pwm-ab8500.c index c5239eef3b8f..507ff0d5f7bd 100644 --- a/drivers/pwm/pwm-ab8500.c +++ b/drivers/pwm/pwm-ab8500.c @@ -136,8 +136,51 @@ static int ab8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, return ret; } +static int ab8500_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, + struct pwm_state *state) +{ + u8 ctrl7, lower_val, higher_val; + int ret; + struct ab8500_pwm_chip *ab8500 = ab8500_pwm_from_chip(chip); + unsigned int div, duty_steps; + + ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC, + AB8500_PWM_OUT_CTRL7_REG, + &ctrl7); + if (ret) + return ret; + + state->polarity = PWM_POLARITY_NORMAL; + + if (!(ctrl7 & 1 << ab8500->hwid)) { + state->enabled = false; + return 0; + } + + ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC, + AB8500_PWM_OUT_CTRL1_REG + (ab8500->hwid * 2), + &lower_val); + if (ret) + return ret; + + ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC, + AB8500_PWM_OUT_CTRL2_REG + (ab8500->hwid * 2), + &higher_val); + if (ret) + return ret; + + div = 32 - ((higher_val & 0xf0) >> 4); + duty_steps = ((higher_val & 3) << 8 | lower_val) + 1; + + state->period = DIV64_U64_ROUND_UP((u64)div << 10, AB8500_PWM_CLKRATE); + state->duty_cycle = DIV64_U64_ROUND_UP((u64)div * duty_steps, AB8500_PWM_CLKRATE); + + return 0; +} + static const struct pwm_ops ab8500_pwm_ops = { .apply = ab8500_pwm_apply, + .get_state = ab8500_pwm_get_state, .owner = THIS_MODULE, }; |