* [PATCH v7 1/9] leds: st1202: stop pattern sequence before reprogramming
2026-07-02 22:23 [PATCH v7 0/9] leds: st1202: fix multiple bugs in pattern engine and brightness handling Manuel Fombuena
@ 2026-07-02 22:27 ` Manuel Fombuena
2026-07-02 22:28 ` [PATCH v7 2/9] leds: st1202: validate pattern input before stopping the sequence Manuel Fombuena
` (9 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Manuel Fombuena @ 2026-07-02 22:27 UTC (permalink / raw)
To: lee, pavel, vicentiu.galanopulo, linux-leds, linux-kernel
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 <fombuena@outlook.com>
Assisted-by: Claude:claude-sonnet-4-6
---
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)
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v7 2/9] leds: st1202: validate pattern input before stopping the sequence
2026-07-02 22:23 [PATCH v7 0/9] leds: st1202: fix multiple bugs in pattern engine and brightness handling Manuel Fombuena
2026-07-02 22:27 ` [PATCH v7 1/9] leds: st1202: stop pattern sequence before reprogramming Manuel Fombuena
@ 2026-07-02 22:28 ` Manuel Fombuena
2026-07-02 22:29 ` [PATCH v7 3/9] leds: st1202: fix pattern duration prescaler and pattern_clear skip marker Manuel Fombuena
` (8 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Manuel Fombuena @ 2026-07-02 22:28 UTC (permalink / raw)
To: lee, pavel, vicentiu.galanopulo, linux-leds, linux-kernel
Input validation for pattern duration is performed inside the write
loop, after the pattern sequence has already been stopped. If
validation fails mid-loop the chip is left with the sequence stopped
and partially written pattern data, with no recovery.
Move all input validation before the mutex and before any hardware
interaction, so an invalid input leaves the chip state unchanged.
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: Claude:claude-sonnet-4-6
---
drivers/leds/leds-st1202.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/leds/leds-st1202.c b/drivers/leds/leds-st1202.c
index 316ed8eb054f..a750c95ef3f8 100644
--- a/drivers/leds/leds-st1202.c
+++ b/drivers/leds/leds-st1202.c
@@ -228,6 +228,12 @@ static int st1202_led_pattern_set(struct led_classdev *ldev,
if (len > ST1202_MAX_PATTERNS)
return -EINVAL;
+ 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)
+ return -EINVAL;
+ }
+
guard(mutex)(&chip->lock);
ret = st1202_write_reg(chip, ST1202_CONFIG_REG, ST1202_CONFIG_REG_SHFT);
@@ -235,10 +241,6 @@ static int st1202_led_pattern_set(struct led_classdev *ldev,
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)
- return -EINVAL;
-
ret = st1202_pwm_pattern_write(chip, led->led_num, patt, pattern[patt].brightness);
if (ret != 0)
return ret;
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v7 3/9] leds: st1202: fix pattern duration prescaler and pattern_clear skip marker
2026-07-02 22:23 [PATCH v7 0/9] leds: st1202: fix multiple bugs in pattern engine and brightness handling Manuel Fombuena
2026-07-02 22:27 ` [PATCH v7 1/9] leds: st1202: stop pattern sequence before reprogramming Manuel Fombuena
2026-07-02 22:28 ` [PATCH v7 2/9] leds: st1202: validate pattern input before stopping the sequence Manuel Fombuena
@ 2026-07-02 22:29 ` Manuel Fombuena
2026-07-02 22:30 ` [PATCH v7 4/9] leds: st1202: set all pattern PWM slots to full after clearing pattern Manuel Fombuena
` (7 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Manuel Fombuena @ 2026-07-02 22:29 UTC (permalink / raw)
To: lee, pavel, vicentiu.galanopulo, linux-leds, linux-kernel
The PATy_DUR register encodes duration as N × 22.2 ms, with register
value 0 reserved as a pattern skip indicator (§7.10). The driver
incorrectly subtracted 1 from the register value:
value / ST1202_MILLIS_PATTERN_DUR_MIN - 1
This caused two problems:
- All programmed durations were off by one step (~22 ms too short).
- Writing the minimum duration (22 ms) produced register value 0,
silently skipping the pattern step instead of setting a 22 ms
duration.
The maximum duration constant was also wrong at 5660 ms. The 8-bit
register saturates at 255, giving a maximum of 5610 ms (22 ms × 255).
Values above 5653 ms were already producing a uint8_t overflow and
writing 0 to the hardware.
Fix the formula by removing the erroneous subtraction, and derive the
maximum from the register width so the relationship is explicit. Update
the documentation to reflect the correct maximum.
This exposes a secondary issue: pattern_clear() was calling
st1202_duration_pattern_write() with ST1202_MILLIS_PATTERN_DUR_MIN to
reset unused slots, accidentally relying on the broken formula to
produce register value 0. With the corrected formula, the same call
writes 0x01 (22 ms), leaving unused slots as valid 22 ms zero-PWM
steps and making the LED appear off for 7 × 22 ms out of every cycle.
Write 0 directly to the duration registers in pattern_clear() so unused
slots are always explicitly marked as skip, independently of the
conversion formula.
Fixes: 259230378c65 ("leds: Add LED1202 I2C driver")
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: Claude:claude-sonnet-4-6
---
Documentation/leds/leds-st1202.rst | 2 +-
drivers/leds/leds-st1202.c | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Documentation/leds/leds-st1202.rst b/Documentation/leds/leds-st1202.rst
index 1a09fbfcedcf..a2353549469e 100644
--- a/Documentation/leds/leds-st1202.rst
+++ b/Documentation/leds/leds-st1202.rst
@@ -17,7 +17,7 @@ To be compatible with the hardware pattern format, maximum 8 tuples of
brightness (PWM) and duration must be written to hw_pattern.
- Min pattern duration: 22 ms
-- Max pattern duration: 5660 ms
+- Max pattern duration: 5610 ms
The format of the hardware pattern values should be:
"brightness duration brightness duration ..."
diff --git a/drivers/leds/leds-st1202.c b/drivers/leds/leds-st1202.c
index a750c95ef3f8..b4adade49898 100644
--- a/drivers/leds/leds-st1202.c
+++ b/drivers/leds/leds-st1202.c
@@ -31,7 +31,7 @@
#define ST1202_ILED_REG0 0x09
#define ST1202_MAX_LEDS 12
#define ST1202_MAX_PATTERNS 8
-#define ST1202_MILLIS_PATTERN_DUR_MAX 5660
+#define ST1202_MILLIS_PATTERN_DUR_MAX (ST1202_MILLIS_PATTERN_DUR_MIN * U8_MAX)
#define ST1202_MILLIS_PATTERN_DUR_MIN 22
#define ST1202_PATTERN_DUR 0x16
#define ST1202_PATTERN_PWM 0x1E
@@ -85,7 +85,7 @@ static int st1202_write_reg(struct st1202_chip *chip, int reg, uint8_t val)
static uint8_t st1202_prescalar_to_miliseconds(unsigned int value)
{
- return value / ST1202_MILLIS_PATTERN_DUR_MIN - 1;
+ return value / ST1202_MILLIS_PATTERN_DUR_MIN;
}
static int st1202_pwm_pattern_write(struct st1202_chip *chip, int led_num,
@@ -209,7 +209,7 @@ static int st1202_led_pattern_clear(struct led_classdev *ldev)
if (ret != 0)
return ret;
- ret = st1202_duration_pattern_write(chip, patt, ST1202_MILLIS_PATTERN_DUR_MIN);
+ ret = st1202_write_reg(chip, ST1202_PATTERN_DUR + patt, 0);
if (ret != 0)
return ret;
}
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v7 4/9] leds: st1202: set all pattern PWM slots to full after clearing pattern
2026-07-02 22:23 [PATCH v7 0/9] leds: st1202: fix multiple bugs in pattern engine and brightness handling Manuel Fombuena
` (2 preceding siblings ...)
2026-07-02 22:29 ` [PATCH v7 3/9] leds: st1202: fix pattern duration prescaler and pattern_clear skip marker Manuel Fombuena
@ 2026-07-02 22:30 ` Manuel Fombuena
2026-07-02 22:31 ` [PATCH v7 5/9] leds: st1202: fix spurious pattern sequence start in setup Manuel Fombuena
` (6 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Manuel Fombuena @ 2026-07-02 22:30 UTC (permalink / raw)
To: lee, pavel, vicentiu.galanopulo, linux-leds, linux-kernel
pattern_clear() sets all PWM registers for the channel to LED_OFF (0).
In static mode (PATS=0), the LED output is ILED x Pattern0_PWM / 4095;
with Pattern0 at zero the LED remains dark regardless of the ILED value.
The LED1202 has a single global sequencer shared across all channels.
If another channel starts the sequencer after this one has been cleared,
the cleared channel runs through all 8 steps at zero duty cycle and
stays dark regardless of ILED.
Set all 8 PWM slots to ST1202_PATTERN_PWM_FULL so that ILED alone
controls the channel brightness in both static and sequencer modes.
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: Claude:claude-sonnet-4-6
---
drivers/leds/leds-st1202.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/leds/leds-st1202.c b/drivers/leds/leds-st1202.c
index b4adade49898..3203b3768ec5 100644
--- a/drivers/leds/leds-st1202.c
+++ b/drivers/leds/leds-st1202.c
@@ -35,6 +35,7 @@
#define ST1202_MILLIS_PATTERN_DUR_MIN 22
#define ST1202_PATTERN_DUR 0x16
#define ST1202_PATTERN_PWM 0x1E
+#define ST1202_PATTERN_PWM_FULL 0x0FFF
#define ST1202_PATTERN_REP 0x15
struct st1202_led {
@@ -205,7 +206,7 @@ static int st1202_led_pattern_clear(struct led_classdev *ldev)
return ret;
for (int patt = 0; patt < ST1202_MAX_PATTERNS; patt++) {
- ret = st1202_pwm_pattern_write(chip, led->led_num, patt, LED_OFF);
+ ret = st1202_pwm_pattern_write(chip, led->led_num, patt, ST1202_PATTERN_PWM_FULL);
if (ret != 0)
return ret;
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v7 5/9] leds: st1202: fix spurious pattern sequence start in setup
2026-07-02 22:23 [PATCH v7 0/9] leds: st1202: fix multiple bugs in pattern engine and brightness handling Manuel Fombuena
` (3 preceding siblings ...)
2026-07-02 22:30 ` [PATCH v7 4/9] leds: st1202: set all pattern PWM slots to full after clearing pattern Manuel Fombuena
@ 2026-07-02 22:31 ` Manuel Fombuena
2026-07-02 22:33 ` [PATCH v7 6/9] leds: st1202: fix brightness having no effect while pattern mode is active Manuel Fombuena
` (5 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Manuel Fombuena @ 2026-07-02 22:31 UTC (permalink / raw)
To: lee, pavel, vicentiu.galanopulo, linux-leds, linux-kernel
st1202_setup() writes PATS and PATSR to the Configuration register as
its final step, which starts the hardware pattern sequencer during
device probe before any patterns have been programmed. This causes the
device to run a sequence with whatever values happen to be in the
pattern registers at the time.
Remove the write. The device reset at the start of setup restores all
registers to their power-on defaults, leaving PATS and PATSR cleared.
Fixes: 259230378c65 ("leds: Add LED1202 I2C driver")
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: Claude:claude-sonnet-4-6
---
drivers/leds/leds-st1202.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/drivers/leds/leds-st1202.c b/drivers/leds/leds-st1202.c
index 3203b3768ec5..b8a571282900 100644
--- a/drivers/leds/leds-st1202.c
+++ b/drivers/leds/leds-st1202.c
@@ -333,11 +333,6 @@ static int st1202_setup(struct st1202_chip *chip)
if (ret < 0)
return ret;
- ret = st1202_write_reg(chip, ST1202_CONFIG_REG,
- ST1202_CONFIG_REG_PATS | ST1202_CONFIG_REG_PATSR);
- if (ret < 0)
- return ret;
-
return 0;
}
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v7 6/9] leds: st1202: fix brightness having no effect while pattern mode is active
2026-07-02 22:23 [PATCH v7 0/9] leds: st1202: fix multiple bugs in pattern engine and brightness handling Manuel Fombuena
` (4 preceding siblings ...)
2026-07-02 22:31 ` [PATCH v7 5/9] leds: st1202: fix spurious pattern sequence start in setup Manuel Fombuena
@ 2026-07-02 22:33 ` Manuel Fombuena
2026-07-02 22:34 ` [PATCH v7 7/9] leds: st1202: disable channel when brightness is set to zero Manuel Fombuena
` (4 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Manuel Fombuena @ 2026-07-02 22:33 UTC (permalink / raw)
To: lee, pavel, vicentiu.galanopulo, linux-leds, linux-kernel
Once a hardware pattern is running (PATS=1), writing to the brightness
sysfs attribute only updates the ILED register. The visible output is
ILED x Pattern_PWM / 4095, so the change has little effect and the LED
never returns to steady static operation as the user expects.
The LED1202 has a single global sequencer shared across all channels.
Stopping it in brightness_set() to force static mode would halt running
patterns on all other active LEDs.
Instead, set all 8 PWM slots for the channel to ST1202_PATTERN_PWM_FULL
before writing ILED. With every step at full duty cycle, the output is
ILED x FULL / 4095 = ILED regardless of the sequencer state, without
disturbing other channels.
This also enables basic LED operation without the pattern trigger: with
the trigger set to none, the brightness sysfs attribute fully controls
the LED as a simple on/off device.
Fixes: 259230378c65 ("leds: Add LED1202 I2C driver")
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: Claude:claude-sonnet-4-6
---
drivers/leds/leds-st1202.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/leds/leds-st1202.c b/drivers/leds/leds-st1202.c
index b8a571282900..4909985ade04 100644
--- a/drivers/leds/leds-st1202.c
+++ b/drivers/leds/leds-st1202.c
@@ -136,6 +136,8 @@ static void st1202_brightness_set(struct led_classdev *led_cdev,
guard(mutex)(&chip->lock);
+ for (int patt = 0; patt < ST1202_MAX_PATTERNS; patt++)
+ st1202_pwm_pattern_write(chip, led->led_num, patt, ST1202_PATTERN_PWM_FULL);
st1202_write_reg(chip, ST1202_ILED_REG0 + led->led_num, value);
}
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v7 7/9] leds: st1202: disable channel when brightness is set to zero
2026-07-02 22:23 [PATCH v7 0/9] leds: st1202: fix multiple bugs in pattern engine and brightness handling Manuel Fombuena
` (5 preceding siblings ...)
2026-07-02 22:33 ` [PATCH v7 6/9] leds: st1202: fix brightness having no effect while pattern mode is active Manuel Fombuena
@ 2026-07-02 22:34 ` Manuel Fombuena
2026-07-02 22:35 ` [PATCH v7 8/9] leds: st1202: validate LED reg property against channel count Manuel Fombuena
` (3 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Manuel Fombuena @ 2026-07-02 22:34 UTC (permalink / raw)
To: lee, pavel, vicentiu.galanopulo, linux-leds, linux-kernel
When brightness_set() is called with LED_OFF, only the ILED register is
zeroed; the channel enable bit is left set from probe time. A hardware
channel enabled with ILED=0 still draws a small residual current, causing
a dim glow even when the LED is supposed to be off.
Fix this by splitting st1202_channel_set() into a lockless inner function
__st1202_channel_set() and a locking wrapper, then calling the inner
function from brightness_set() while it already holds the mutex. The
channel is now disabled when value is zero and re-enabled when non-zero,
in the same lock region as the ILED write.
Fixes: 259230378c65 ("leds: Add LED1202 I2C driver")
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: Claude:claude-sonnet-4-6
---
drivers/leds/leds-st1202.c | 68 ++++++++++++++++++++++----------------
1 file changed, 39 insertions(+), 29 deletions(-)
diff --git a/drivers/leds/leds-st1202.c b/drivers/leds/leds-st1202.c
index 4909985ade04..2ecd36aae336 100644
--- a/drivers/leds/leds-st1202.c
+++ b/drivers/leds/leds-st1202.c
@@ -128,39 +128,11 @@ static int st1202_duration_pattern_write(struct st1202_chip *chip, int pattern,
st1202_prescalar_to_miliseconds(value));
}
-static void st1202_brightness_set(struct led_classdev *led_cdev,
- enum led_brightness value)
-{
- struct st1202_led *led = cdev_to_st1202_led(led_cdev);
- struct st1202_chip *chip = led->chip;
-
- guard(mutex)(&chip->lock);
-
- for (int patt = 0; patt < ST1202_MAX_PATTERNS; patt++)
- st1202_pwm_pattern_write(chip, led->led_num, patt, ST1202_PATTERN_PWM_FULL);
- st1202_write_reg(chip, ST1202_ILED_REG0 + led->led_num, value);
-}
-
-static enum led_brightness st1202_brightness_get(struct led_classdev *led_cdev)
-{
- struct st1202_led *led = cdev_to_st1202_led(led_cdev);
- struct st1202_chip *chip = led->chip;
- u8 value = 0;
-
- guard(mutex)(&chip->lock);
-
- st1202_read_reg(chip, ST1202_ILED_REG0 + led->led_num, &value);
-
- return value;
-}
-
-static int st1202_channel_set(struct st1202_chip *chip, int led_num, bool active)
+static int __st1202_channel_set(struct st1202_chip *chip, int led_num, bool active)
{
u8 chan_low, chan_high;
int ret;
- guard(mutex)(&chip->lock);
-
if (led_num <= 7) {
ret = st1202_read_reg(chip, ST1202_CHAN_ENABLE_LOW, &chan_low);
if (ret < 0)
@@ -188,6 +160,40 @@ static int st1202_channel_set(struct st1202_chip *chip, int led_num, bool active
return 0;
}
+static int st1202_channel_set(struct st1202_chip *chip, int led_num, bool active)
+{
+ guard(mutex)(&chip->lock);
+
+ return __st1202_channel_set(chip, led_num, active);
+}
+
+static void st1202_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ struct st1202_led *led = cdev_to_st1202_led(led_cdev);
+ struct st1202_chip *chip = led->chip;
+
+ guard(mutex)(&chip->lock);
+
+ for (int patt = 0; patt < ST1202_MAX_PATTERNS; patt++)
+ st1202_pwm_pattern_write(chip, led->led_num, patt, ST1202_PATTERN_PWM_FULL);
+ st1202_write_reg(chip, ST1202_ILED_REG0 + led->led_num, value);
+ __st1202_channel_set(chip, led->led_num, !!value);
+}
+
+static enum led_brightness st1202_brightness_get(struct led_classdev *led_cdev)
+{
+ struct st1202_led *led = cdev_to_st1202_led(led_cdev);
+ struct st1202_chip *chip = led->chip;
+ u8 value = 0;
+
+ guard(mutex)(&chip->lock);
+
+ st1202_read_reg(chip, ST1202_ILED_REG0 + led->led_num, &value);
+
+ return value;
+}
+
static int st1202_led_set(struct led_classdev *ldev, enum led_brightness value)
{
struct st1202_led *led = cdev_to_st1202_led(ldev);
@@ -257,6 +263,10 @@ static int st1202_led_pattern_set(struct led_classdev *ldev,
if (ret != 0)
return ret;
+ ret = __st1202_channel_set(chip, led->led_num, true);
+ if (ret != 0)
+ return ret;
+
ret = st1202_write_reg(chip, ST1202_CONFIG_REG, (ST1202_CONFIG_REG_PATSR |
ST1202_CONFIG_REG_PATS | ST1202_CONFIG_REG_SHFT));
if (ret != 0)
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v7 8/9] leds: st1202: validate LED reg property against channel count
2026-07-02 22:23 [PATCH v7 0/9] leds: st1202: fix multiple bugs in pattern engine and brightness handling Manuel Fombuena
` (6 preceding siblings ...)
2026-07-02 22:34 ` [PATCH v7 7/9] leds: st1202: disable channel when brightness is set to zero Manuel Fombuena
@ 2026-07-02 22:35 ` Manuel Fombuena
2026-07-02 22:37 ` [PATCH v7 9/9] leds: st1202: correct and extend hw_pattern documentation Manuel Fombuena
` (2 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Manuel Fombuena @ 2026-07-02 22:35 UTC (permalink / raw)
To: lee, pavel, vicentiu.galanopulo, linux-leds, linux-kernel
The reg property from the device tree is used directly as an array index
into chip->leds[] without bounds checking. A value >= ST1202_MAX_LEDS
would cause an out-of-bounds write during probe.
Fixes: 259230378c65 ("leds: Add LED1202 I2C driver")
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: Claude:claude-sonnet-4-6
---
drivers/leds/leds-st1202.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/leds/leds-st1202.c b/drivers/leds/leds-st1202.c
index 2ecd36aae336..168df5ecf27b 100644
--- a/drivers/leds/leds-st1202.c
+++ b/drivers/leds/leds-st1202.c
@@ -279,13 +279,19 @@ static int st1202_dt_init(struct st1202_chip *chip)
{
struct device *dev = &chip->client->dev;
struct st1202_led *led;
- int err, reg;
+ int err;
+ u32 reg;
for_each_available_child_of_node_scoped(dev_of_node(dev), child) {
err = of_property_read_u32(child, "reg", ®);
if (err)
return dev_err_probe(dev, err, "Invalid register\n");
+ if (reg >= ST1202_MAX_LEDS)
+ return dev_err_probe(dev, -EINVAL,
+ "LED reg %u out of range [0, %d]\n",
+ reg, ST1202_MAX_LEDS - 1);
+
led = &chip->leds[reg];
led->is_active = true;
led->fwnode = of_fwnode_handle(child);
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v7 9/9] leds: st1202: correct and extend hw_pattern documentation
2026-07-02 22:23 [PATCH v7 0/9] leds: st1202: fix multiple bugs in pattern engine and brightness handling Manuel Fombuena
` (7 preceding siblings ...)
2026-07-02 22:35 ` [PATCH v7 8/9] leds: st1202: validate LED reg property against channel count Manuel Fombuena
@ 2026-07-02 22:37 ` Manuel Fombuena
2026-07-03 11:21 ` [PATCH v7 0/9] leds: st1202: fix multiple bugs in pattern engine and brightness handling Manuel Fombuena
2026-07-09 9:53 ` Lee Jones
10 siblings, 0 replies; 12+ messages in thread
From: Manuel Fombuena @ 2026-07-02 22:37 UTC (permalink / raw)
To: lee, pavel, vicentiu.galanopulo, linux-leds, linux-kernel
Fix the repeat section: -1 is a valid value meaning infinite repeat,
as accepted by the ledtrig-pattern sysfs interface; only 0 and values
below -1 are rejected. The previous text incorrectly stated all negative
numbers were invalid. Also remove the redundant trailing sentence since
the behaviour is now covered inline.
Add the brightness range (0-255) to the hw_pattern section, which was
previously undocumented.
Fixes: b1816b22381b ("Documentation:leds: Add leds-st1202.rst")
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: Claude:claude-sonnet-4-6
---
Documentation/leds/leds-st1202.rst | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/Documentation/leds/leds-st1202.rst b/Documentation/leds/leds-st1202.rst
index a2353549469e..ed32eb3a27d4 100644
--- a/Documentation/leds/leds-st1202.rst
+++ b/Documentation/leds/leds-st1202.rst
@@ -16,6 +16,7 @@ in terms of PWM duty-cycle and duration (ms).
To be compatible with the hardware pattern format, maximum 8 tuples of
brightness (PWM) and duration must be written to hw_pattern.
+- Brightness range: 0-255
- Min pattern duration: 22 ms
- Max pattern duration: 5610 ms
@@ -26,9 +27,7 @@ The format of the hardware pattern values should be:
----------------------------
Specify a pattern repeat number, which is common for all channels.
-Default is 1; negative numbers and 0 are invalid.
+Default is 1. Writing 0 is invalid. Writing -1 or 255 repeats the
+pattern indefinitely.
This file will always return the originally written repeat number.
-
-When the 255 value is written to it, all patterns will repeat
-indefinitely.
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH v7 0/9] leds: st1202: fix multiple bugs in pattern engine and brightness handling
2026-07-02 22:23 [PATCH v7 0/9] leds: st1202: fix multiple bugs in pattern engine and brightness handling Manuel Fombuena
` (8 preceding siblings ...)
2026-07-02 22:37 ` [PATCH v7 9/9] leds: st1202: correct and extend hw_pattern documentation Manuel Fombuena
@ 2026-07-03 11:21 ` Manuel Fombuena
2026-07-09 9:53 ` Lee Jones
10 siblings, 0 replies; 12+ messages in thread
From: Manuel Fombuena @ 2026-07-03 11:21 UTC (permalink / raw)
To: lee, pavel, vicentiu.galanopulo, linux-leds, linux-kernel
All Sashiko's comments on v7 are pre-existing issues outside the scope of
this series, with the exception of one comment each on Patch 4 and Patch
6. Unless there are any other reviewer comments, there will not be a v8.
The pre-existing issues will be addressed in a follow-up submission.
For the sake of clarity, these are the responses to the non-pre-existing
issues.
Patch 4 comment: after pattern_clear() sets all 8 PWM slots to FULL, a
shorter pattern programmed with len < 8 leaves the trailing slots at
100% duty cycle. If another channel runs an 8-step sequence, the
cleared channel flashes at maximum brightness during its unused steps.
Response: this is a consequence of the pre-existing issue where
st1202_led_pattern_set() does not zero trailing slots when
len < ST1202_MAX_PATTERNS. The root fix is outside the scope of this
series and will be addressed in a follow-up submission.
Patch 6 comment: the loop in st1202_brightness_set() ignores the
return value of st1202_pwm_pattern_write(), potentially continuing
writes after a bus failure.
Response: as noted in the response to the v6 review, this is
intentional. A transient I2C error on one slot does not guarantee
subsequent writes will also fail. Breaking early would leave remaining
PWM slots unwritten unnecessarily, putting the channel in a partially
updated state. brightness_set() is a void callback and cannot propagate
errors regardless, and st1202_write_reg() already logs each individual
failure via dev_err().
--
Manuel Fombuena
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH v7 0/9] leds: st1202: fix multiple bugs in pattern engine and brightness handling
2026-07-02 22:23 [PATCH v7 0/9] leds: st1202: fix multiple bugs in pattern engine and brightness handling Manuel Fombuena
` (9 preceding siblings ...)
2026-07-03 11:21 ` [PATCH v7 0/9] leds: st1202: fix multiple bugs in pattern engine and brightness handling Manuel Fombuena
@ 2026-07-09 9:53 ` Lee Jones
10 siblings, 0 replies; 12+ messages in thread
From: Lee Jones @ 2026-07-09 9:53 UTC (permalink / raw)
To: lee, pavel, vicentiu.galanopulo, linux-leds, linux-kernel,
Manuel Fombuena
On Thu, 02 Jul 2026 23:23:37 +0100, Manuel Fombuena wrote:
> This series fixes several bugs in the LED1202 driver related to hardware
> pattern programming and brightness control. The issues were found during
> testing on a Linksys MX4200v2 router running OpenWrt.
>
> --- Pattern sequence not stopped before reprogramming ---
>
> The LED1202 datasheet (section 4.8) states that writes to PAT_REP and
> pattern duration registers are only applied after the sequence completes
> or is stopped. When running in infinite loop mode the sequence never
> completes on its own, so these writes are silently ignored by the
> hardware.
>
> [...]
Applied, thanks!
[1/9] leds: st1202: stop pattern sequence before reprogramming
commit: 9c019a8cb95d820e0bd03e75cfbad2c5b13941b7
[2/9] leds: st1202: validate pattern input before stopping the sequence
commit: fd2529ba8fb44cd4b56f1069363b949644b42cec
[3/9] leds: st1202: fix pattern duration prescaler and pattern_clear skip marker
commit: d32f8bdc2b417a3013e1316a54a0b314f973bbc1
[4/9] leds: st1202: set all pattern PWM slots to full after clearing pattern
commit: d2ca0e2b6d6430f9c60bb2e0ee0b2b3dc4e5d86a
[5/9] leds: st1202: fix spurious pattern sequence start in setup
commit: dcc31246aaf0d330a3ba9a725f56c33e6d634caa
[6/9] leds: st1202: fix brightness having no effect while pattern mode is active
commit: 7cbe470366bdd43c7e8114fb2c4d74fa69093121
[7/9] leds: st1202: disable channel when brightness is set to zero
commit: 0767335233a8cbab00bbe260a4e4bd380c7677fd
[8/9] leds: st1202: validate LED reg property against channel count
commit: cf197514bdfd3877f42b5dce1efd40b7b686547e
[9/9] leds: st1202: correct and extend hw_pattern documentation
commit: 96fa4d69958cf90740d756d1e45cdb02cface41b
--
Lee Jones [李琼斯]
^ permalink raw reply [flat|nested] 12+ messages in thread