Re: [PATCH v1 6/6] pwm: tegra: Implement .get_state()
Mikko Perttunen <[email protected]> Wed, 15 Jul 2026 14:09:27 +0900
| Newsgroups | org.kernel.vger.linux-pwm,org.kernel.vger.linux-tegra |
|---|---|
| Message-ID | <[email protected]> |
On Tuesday, July 14, 2026 9:02 PM Uwe Kleine-König wrote: > The registers of the PWM IP are readable. Use that to implement the > .get_state() callback. I swear I was going to implement this after the Tegra264 series was accepted, but I don't mind this way either.. :) > > Signed-off-by: Uwe Kleine-König <[email protected]> > --- > drivers/pwm/pwm-tegra.c | 48 +++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 48 insertions(+) > > diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c > index 8e5e7e37f4ff..79bfc7589db8 100644 > --- a/drivers/pwm/pwm-tegra.c > +++ b/drivers/pwm/pwm-tegra.c > @@ -309,8 +309,56 @@ static int tegra_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, > return err; > } > > +static int tegra_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,(((1 << pc->soc->scale_width) - 1)) > + struct pwm_state *state) > +{ > + struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip); > + int rc; > + u32 val; > + > + rc = pm_runtime_resume_and_get(pwmchip_parent(chip)); > + if (rc) > + return rc; > + > + val = tegra_pwm_readl(pwm, pc->soc->enable_reg); > + if (val & TEGRA_PWM_ENABLE) { > + u32 scale, pwm0; > + > + if (pc->soc->enable_reg != TEGRA_PWM_CSR_0) > + val = tegra_pwm_readl(pwm, TEGRA_PWM_CSR_0); > + > + scale = (val >> TEGRA_PWM_SCALE_SHIFT) & (((1 << pc->soc->scale_width) - 1)); There's one unnecessary pair of parentheses. > + pwm0 = (val >> TEGRA_PWM_DUTY_SHIFT) & (2 * TEGRA_PWM_DEPTH - 1); > + > + if (pwm0 > TEGRA_PWM_DEPTH) > + pwm0 = TEGRA_PWM_DEPTH; > + > + /* > + * scale + 1 is at most 1 << 17, TEGRA_PWM_DEPTH is 256, so the > + * multiplication for .period doesn't overflow a u64. With > + * pwm0 ≤ TEGRA_PWM_DEPTH, .duty_cycle is also fine. > + */ > + *state = (struct pwm_state){ > + .period = DIV64_U64_ROUND_UP((u64)(scale + 1) * TEGRA_PWM_DEPTH * NSEC_PER_SEC, pc->clk_rate), > + .duty_cycle = DIV64_U64_ROUND_UP((u64)(scale + 1) * pwm0 * NSEC_PER_SEC, pc->clk_rate), > + .polarity = PWM_POLARITY_NORMAL, > + .enabled = true, > + }; > + > + } else { > + *state = (struct pwm_state){ > + .enabled = false, > + }; > + } > + > + pm_runtime_put(pwmchip_parent(chip)); > + > + return 0; > +} > + > static const struct pwm_ops tegra_pwm_ops = { > .apply = tegra_pwm_apply, > + .get_state = tegra_pwm_get_state, > }; > > static int tegra_pwm_probe(struct platform_device *pdev) > -- > 2.55.0.11.g153666a7d9bb > > Reviewed-by: Mikko Perttunen <[email protected]>