[PATCH v4 0/1] leds: st1202: Add hardware-accelerated blink support

From: Manuel Fombuena

Date: Tue Jul 28 2026 - 07:02:04 EST


This patch adds blink_set() to the ST1202 LED driver, enabling
hardware-accelerated blinking via the timer trigger.

A series of nine fixes to the pattern engine and brightness handling
was recently applied to for-leds-next:

https://lore.kernel.org/all/GV1PR08MB8497C0B898789BB73ACE6EE3C5F52@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/

With those fixes in place, the pattern engine can be used reliably to
implement blink_set(): a two-step pattern (full brightness for delay_on,
off for delay_off) is programmed and started in infinite repeat mode.
Requested delays are clamped to the hardware range and rounded up to
the nearest 22ms step.

During review of the fix series, several pre-existing issues were
identified in the driver — including brightness_set() being assigned to
a non-blocking callback, the global sequencer affecting all channels on
pattern operations, and missing brightness scaling in pattern_set().
These do not affect blink_set(): the callback is not invoked from atomic
context, the function explicitly programs all other channels' PWM slots
to zero before starting the sequencer, and channel brightness is set
directly via the ILED register. The pre-existing issues will be
addressed in a follow-up submission.

Tested on LED1202 hardware via I2C on a Linksys MX4200v2 router running
OpenWrt. Hardware blinking confirmed functional with the timer trigger.

--- Changes in v4 ---

Fix delay clamping and rounding order following a review of the
changes introduced across v2 and v3:

v2 moved roundup() before clamp_val() so that rounding could not push
the result past the hardware maximum. However, this left roundup()
exposed to integer overflow for extreme inputs near ULONG_MAX, since
roundup(x, 22) internally computes x + 21 before dividing.

v3 addressed the overflow by prepending a min_t() cap at MAX before
roundup(), and retained a trailing clamp_val() for the full range.
The trailing clamp_val() turned out to be unreachable: ST1202_MILLIS_
PATTERN_DUR_MAX (5610) is an exact multiple of ST1202_MILLIS_PATTERN_
DUR_MIN (22), so roundup() on a value already capped at 5610 returns
5610 unchanged, and the result is always within range before the
trailing clamp_val() runs.

v4 reverts to clamp_val() before roundup(). Clamping first prevents
overflow for extreme inputs, and since MAX is an exact multiple of MIN
the rounded result cannot exceed MAX, addressing the v1 concern
without the redundant operations introduced in v3.

--- Changes in v3 ---

In response to automated review feedback (Sashiko) on v2:

Clamp delay inputs to the hardware maximum before calling roundup() to
prevent integer overflow for extreme values near ULONG_MAX.

Other pre-existing issues identified by the automated review are
outside the scope of this patch and will be addressed in a follow-up
submission.

--- Changes in v2 ---

In response to maintainer (Lee Jones) review on v1:

Use short-form ternary for default delay substitution.
Perform roundup before clamp_val to ensure rounding cannot exceed
the hardware maximum.
Capitalise commit subject per LED subsystem convention.
Drop Assisted-by tag per maintainer suggestion.

Manuel Fombuena (1):
leds: st1202: Add hardware-accelerated blink support

drivers/leds/leds-st1202.c | 82 ++++++++++++++++++++++++++++++++++++++
1 file changed, 82 insertions(+)

--
2.55.0