[PATCH v1 07/11] leds: st1202: Program the channel current for hardware patterns

From: Manuel Fombuena

Date: Sat Sep 12 2026 - 18:36:32 EST


A channel's output is ILED x Pattern_PWM / 4095, so a pattern is only
visible while the analog current register holds a non-zero value.
st1202_led_pattern_set() programs the PWM slots and starts the sequencer
but never writes ILED, so a channel whose current is zero stays dark
while pattern_set() reports success.

Zero is reached by ordinary use. Writing 0 to brightness sets it, and so
does switching away from the pattern trigger, because
pattern_trig_deactivate() ends with led_set_brightness(LED_OFF). A
sequence as simple as

echo none > trigger
echo pattern > trigger
echo "255 500 0 500" > hw_pattern

therefore programs a pattern that never lights up.

Program the current in pattern_set() and release it in pattern_clear(),
so the pattern path owns ILED for as long as a pattern is loaded.
Releasing it matters because the trigger calls pattern_clear() before it
parses a new pattern: without that, a rejected or empty hw_pattern write
would leave the channel at full current with every PWM slot at full
scale, latching the LED on. Clearing before the slots are raised also
avoids a brief full-brightness flash on every reprogram.

Release the current first in pattern_clear(), before the sequencer is
stopped, and write it last in pattern_set(), once the channel is enabled
and the sequencer started. An I2C error partway through then cannot
leave the current raised on a channel whose pattern is being cleared,
nor raise it for a pattern that failed to start.

The current is programmed to the same max_brightness the PWM values are
scaled against, so a pattern step of N produces the same output as
writing N to brightness, and a board declaring a lower ceiling through
the max-brightness property keeps it on both paths.

Note that this makes a hardware pattern take the channel to its maximum
current, so brightness reads back as max_brightness once a pattern is
loaded and as zero once it is cleared. The pattern's own values, not the
last brightness written, decide what the channel shows while a pattern
is running.

Fixes: 259230378c65 ("leds: Add LED1202 I2C driver")
Signed-off-by: Manuel Fombuena <fombuena@xxxxxxxxxxx>
Assisted-by: LLM
---
drivers/leds/leds-st1202.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/drivers/leds/leds-st1202.c b/drivers/leds/leds-st1202.c
index 5558ac9612a1..5042fe88fbff 100644
--- a/drivers/leds/leds-st1202.c
+++ b/drivers/leds/leds-st1202.c
@@ -221,6 +221,10 @@ static int st1202_led_pattern_clear(struct led_classdev *ldev)

guard(mutex)(&chip->lock);

+ ret = st1202_write_reg(chip, ST1202_ILED_REG0 + led->led_num, LED_OFF);
+ if (ret != 0)
+ return ret;
+
ret = st1202_write_reg(chip, ST1202_CONFIG_REG, ST1202_CONFIG_REG_PHASE_SHIFT);
if (ret != 0)
return ret;
@@ -297,6 +301,10 @@ static int st1202_led_pattern_set(struct led_classdev *ldev,
if (ret != 0)
return ret;

+ ret = st1202_write_reg(chip, ST1202_ILED_REG0 + led->led_num, max_brightness);
+ if (ret != 0)
+ return ret;
+
return 0;
}

--
2.55.0