From e39061347c3fe10f044be1597bb102a99694f6a2 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 11 Nov 2025 15:44:39 +0000 Subject: [PATCH 1/2] pwm: rp1: Silently correct illegal values Remove the need for the user to know the limitations of this PWM implementation by adjusting configuration requests to be the closest acceptable value. Add a get_state method so that the actual values can be queried. Signed-off-by: Phil Elwell --- drivers/pwm/pwm-pio-rp1.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/pwm/pwm-pio-rp1.c b/drivers/pwm/pwm-pio-rp1.c index 1c9c0e987e58d1..226e46451e3ecc 100644 --- a/drivers/pwm/pwm-pio-rp1.c +++ b/drivers/pwm/pwm-pio-rp1.c @@ -101,15 +101,12 @@ static int pwm_pio_rp1_apply(struct pwm_chip *chip, struct pwm_device *pwm, uint32_t new_duty_cycle; uint32_t new_period; - if (state->duty_cycle && state->duty_cycle < pwm_pio_resolution) - return -EINVAL; - - if (state->duty_cycle != state->period && - (state->period - state->duty_cycle < pwm_pio_resolution)) - return -EINVAL; - - new_period = state->period / pwm_pio_resolution; - new_duty_cycle = state->duty_cycle / pwm_pio_resolution; + new_period = DIV_ROUND_CLOSEST(state->period, pwm_pio_resolution); + if (new_period < 2) + new_period = 2; + new_duty_cycle = DIV_ROUND_CLOSEST(state->duty_cycle, pwm_pio_resolution); + if (new_duty_cycle > new_period - 1) + new_duty_cycle = new_period - 1; mutex_lock(&ppwm->mutex); @@ -145,8 +142,22 @@ static int pwm_pio_rp1_apply(struct pwm_chip *chip, struct pwm_device *pwm, return 0; } +static int pwm_pio_rp1_get_state(struct pwm_chip *chip, struct pwm_device *pwm, + struct pwm_state *state) +{ + struct pwm_pio_rp1 *ppwm = pwmchip_get_drvdata(chip); + + state->enabled = ppwm->enabled; + state->polarity = ppwm->polarity; + state->period = ppwm->period * pwm_pio_resolution; + state->duty_cycle = ppwm->duty_cycle * pwm_pio_resolution; + + return 0; +} + static const struct pwm_ops pwm_pio_rp1_ops = { .apply = pwm_pio_rp1_apply, + .get_state = pwm_pio_rp1_get_state, }; static int pwm_pio_rp1_probe(struct platform_device *pdev) From bfbbca10c3373748e212c0f2077404c967ae2099 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 11 Nov 2025 15:50:34 +0000 Subject: [PATCH 2/2] pwm: rp1: Correct period off-by-1 error Correct the set_period method to pass (period - 1), as required by the PIO state machine. Signed-off-by: Phil Elwell --- drivers/pwm/pwm-pio-rp1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pwm/pwm-pio-rp1.c b/drivers/pwm/pwm-pio-rp1.c index 226e46451e3ecc..f2dec72cb7e601 100644 --- a/drivers/pwm/pwm-pio-rp1.c +++ b/drivers/pwm/pwm-pio-rp1.c @@ -83,7 +83,7 @@ static inline void pwm_program_init(PIO pio, uint sm, uint offset, uint pin) /* Write `period` to the input shift register - must be disabled */ static void pio_pwm_set_period(PIO pio, uint sm, uint32_t period) { - pio_sm_put_blocking(pio, sm, period); + pio_sm_put_blocking(pio, sm, period - 1); pio_sm_exec(pio, sm, pio_encode_pull(false, false)); pio_sm_exec(pio, sm, pio_encode_out(pio_isr, 32)); }