Thread (16 messages) 16 messages, 3 authors, 2025-08-06

Re: [PATCH v12 04/10] pwm: max7360: Add MAX7360 PWM support

From: Uwe Kleine-König <ukleinek@kernel.org>
Date: 2025-08-06 14:02:57
Also in: linux-devicetree, linux-gpio, linux-pwm, lkml

On Wed, Aug 06, 2025 at 02:07:15PM +0200, Mathieu Dubois-Briand wrote:
On Fri Aug 1, 2025 at 12:11 PM CEST, Uwe Kleine-König wrote:
quoted
On Tue, Jul 22, 2025 at 06:23:48PM +0200, Mathieu Dubois-Briand wrote:
quoted
+static int max7360_pwm_round_waveform_tohw(struct pwm_chip *chip,
+					   struct pwm_device *pwm,
+					   const struct pwm_waveform *wf,
+					   void *_wfhw)
+{
+	struct max7360_pwm_waveform *wfhw = _wfhw;
+	u64 duty_steps;
+
+	/*
+	 * Ignore user provided values for period_length_ns and duty_offset_ns:
+	 * we only support fixed period of MAX7360_PWM_PERIOD_NS and offset of 0.
+	 * Values from 0 to 254 as duty_steps will provide duty cycles of 0/256
+	 * to 254/256, while value 255 will provide a duty cycle of 100%.
+	 */
+	if (wf->duty_length_ns >= MAX7360_PWM_PERIOD_NS) {
+		duty_steps = MAX7360_PWM_MAX;
+	} else {
+		duty_steps = (u32)wf->duty_length_ns * MAX7360_PWM_STEPS / MAX7360_PWM_PERIOD_NS;
+		if (duty_steps == MAX7360_PWM_MAX)
+			duty_steps = MAX7360_PWM_MAX - 1;
+	}
+
+	wfhw->duty_steps = min(MAX7360_PWM_MAX, duty_steps);
+	wfhw->enabled = !!wf->period_length_ns;
+
+	return 0;
The unconditional return 0 is wrong and testing with PWM_DEBUG enabled
should tell you that.
When you say should, does that mean the current version of PWM core will
tell me that with PWM_DEBUG enabled, or does that mean we should modify
the code so it does show a warning? As I did not see any warning when
specifying a wf->period_length_ns > MAX7360_PWM_PERIOD_NS, even with
PWM_DEBUG enabled.

On the other hand, if I specify a wf->period_length_ns value below
MAX7360_PWM_PERIOD_NS, I indeed get an error:
pwm pwmchip0: Wrong rounding: requested 1000000/1000000 [+0], result 1000000/2000000 [+0]
Yes, that's how I expect it.
quoted
I think the right thing to do here is:

	if (wf->period_length_ns > MAX7360_PWM_PERIOD_NS)
		return 1;
	else
		return 0;
I can definitely do that, but now I'm a bit confused by the meaning of
this return value: is it 0 on success, 1 if some rounding was made,
-errno on error? So I believe I should only return 0 if
wf->period_length_ns == MAX7360_PWM_PERIOD_NS, no?

Or reading this comment on pwm_round_waveform_might_sleep(), maybe we
only have to return 1 if some value is rounded UP. So I believe the test
should be (wf->period_length_ns < MAX7360_PWM_PERIOD_NS).
Right,

	if (wf->period_length_ns < MAX7360_PWM_PERIOD_NS)
		return 1;
	else
		return 0;

So 0 = request could be matched by only rounding down, 1 = request could
be matched but rounding up was needed, negative value = error.
quoted
 * Returns: 0 on success, 1 if at least one value had to be rounded up or a
 * negative errno.
This is kinda confirmed by this other comment, in the code checking the
above returned value in __pwm_apply(), even its just typical examples:
pwm_apply() has different rules. (.apply() fails when .period is too
small. This has the downside that finding a valid period is hard. For
that reason the waveform callbacks round up and signal that by returning
1.)

Best regards
Uwe

Attachments

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help