From 9c019a8cb95d820e0bd03e75cfbad2c5b13941b7 Mon Sep 17 00:00:00 2001 From: Manuel Fombuena Date: Thu, 2 Jul 2026 23:27:22 +0100 Subject: [PATCH] leds: st1202: Stop pattern sequence before reprogramming The LED1202 datasheet (section 4.8) states that modifications to the Pattern Sequence Repetition register (PAT_REP) and pattern duration registers are only applied after the sequence has completed or been stopped. When the device is running in infinite loop mode (PAT_REP = 0xFF) the sequence never completes on its own, so these writes are silently ignored by the hardware. Neither pattern_clear() nor pattern_set() stop the running sequence before modifying pattern registers, causing any subsequent pattern reprogramming to have no effect when the previous pattern was set to infinite repeat. Fix this by clearing PATS in the Configuration register before touching any pattern registers in both functions, ensuring the hardware accepts the new values immediately. Note that the LED1202 has a single global pattern sequencer shared by all channels: PATS, PATSR, the duration registers, and PAT_REP are chip-wide. Stopping the sequencer in pattern_clear() therefore halts any pattern running on other channels. This is an inherent hardware constraint; pattern_set() restarts the sequencer when a new pattern is programmed. Fixes: 259230378c65 ("leds: Add LED1202 I2C driver") Signed-off-by: Manuel Fombuena Assisted-by: Claude:claude-sonnet-4-6 Link: https://patch.msgid.link/GV1PR08MB84978D0F499774773C7DA1FCC5F52@GV1PR08MB8497.eurprd08.prod.outlook.com Signed-off-by: Lee Jones --- 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 7f68d956f694..316ed8eb054f 100644 --- a/drivers/leds/leds-st1202.c +++ b/drivers/leds/leds-st1202.c @@ -200,6 +200,10 @@ static int st1202_led_pattern_clear(struct led_classdev *ldev) guard(mutex)(&chip->lock); + ret = st1202_write_reg(chip, ST1202_CONFIG_REG, ST1202_CONFIG_REG_SHFT); + if (ret != 0) + return ret; + for (int patt = 0; patt < ST1202_MAX_PATTERNS; patt++) { ret = st1202_pwm_pattern_write(chip, led->led_num, patt, LED_OFF); if (ret != 0) @@ -226,6 +230,10 @@ static int st1202_led_pattern_set(struct led_classdev *ldev, guard(mutex)(&chip->lock); + ret = st1202_write_reg(chip, ST1202_CONFIG_REG, ST1202_CONFIG_REG_SHFT); + if (ret != 0) + return ret; + for (int patt = 0; patt < len; patt++) { if (pattern[patt].delta_t < ST1202_MILLIS_PATTERN_DUR_MIN || pattern[patt].delta_t > ST1202_MILLIS_PATTERN_DUR_MAX)