Re: [PATCH v1 6/6] pwm: tegra: Implement .get_state()

Mikko Perttunen <[email protected]>
Newsgroups org.kernel.vger.linux-tegra,org.kernel.vger.linux-pwm
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]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.