Re: [hwmon-next PATCH v4 3/4] hwmon: (adt7470) Expose fan control via PWM framework

From: Uwe Kleine-König

Date: Wed Jul 29 2026 - 17:36:01 EST


Hello Luiz,

On Wed, Jul 29, 2026 at 04:05:56PM -0300, Luiz Angelo Daros de Luca wrote:
> > Here the right thing is (untested):
> >
> > if (!wf->period_length_ns) {
> > wfhw->val = 0;
> > return 0;
> > }
> >
> > actual_period = NSEC_PER_SEC / data->pwm_freq;
> >
> > if (wf->duty_length_ns >= actual_period)
> > val = ADT7470_PWM_MAX;
> > else
> > val = mul_u64_u64_div_u64(wf->duty_length_ns, ADT7470_PWM_MAX, actual_period);
> >
> > return (actual_period < wf->period_length_ns) ? 0 : 1;
>
> Uwe, thank you for the waveform callbacks snippet. It was much
> cleaner. I only had to make one small mathematical adjustment to the
> actual_period calculation in tohw() to satisfy CONFIG_PWM_DEBUG.
>
> When using a truncating division (NSEC_PER_SEC / data->pwm_freq), it
> triggered a "Wrong rounding" error during testing:
>
> pwm pwmchip0: Wrong rounding: requested 714285/714286 [+0], result
> 714286/714286 [+0]
>
> For example, at 1400 Hz, the truncating division gives an
> actual_period of 714285 ns. If the framework requests a duty cycle of
> 714285 ns and a period of 714286 ns, the evaluation (714285 * 255) /
> 714285 yields a register value of 255. When read back in fromhw()
> (which correctly rounds the period up to 714286 ns), the resulting
> duty cycle becomes 714286 ns. Since 714286 > 714285, CONFIG_PWM_DEBUG
> rightfully complains about the duty cycle inflation.
>
> To ensure the calculated register value is strictly rounded down, I
> changed the actual_period denominator in tohw() to use
> DIV_ROUND_UP_ULL(NSEC_PER_SEC, data->pwm_freq). Maximizing the
> denominator guarantees the resulting duty cycle fraction never
> inflates, effectively passing all strict debug checks.

right, for the calculation of actual_period an uprounding division must
be used.

Best regards
Uwe

Attachment: signature.asc
Description: PGP signature