pca9532 unexpectedly stopped blinking when changing brightness to a
non-zero value. To reproduce:
echo timer > /sys/class/leds/led-1/trigger # blinks
echo 255 > /sys/class/leds/led-1/brightness # blinking stops, light on
cat /sys/class/leds/led-1/trigger # still claims [timer]
According to Documentation/leds/leds-class.rst, only brightness = 0
shall be a stop condition:
> You can change the brightness value of a LED independently of the
> timer trigger. However, if you set the brightness value to LED_OFF it
> will also disable the timer trigger.
Therefore add a guard to continue blinking when brightness != LED_OFF,
similar to how pca955x does it since 575f10dc64a2 ("leds: pca955x: Add
HW blink support").
Signed-off-by: Tobias Deiminger <tobias.deiminger@linutronix.de>
---
Changes in v2:
- Fix code style (capitalize start of comment, brace-placement).
- Link to v1: https://lore.kernel.org/r/20260321102121.1563365-1-tobias.deiminger@linutronix.de
Notes:
A more advanced solution was to not simply return early on
set_brightness, but actually support blinking at arbitrary brightness.
This would however require conditional fallback to SW blinking, since
PCA 9532 doesn't support routing PWM 0 (dim) and PWM 1 (blink) in
series. The bugfix here keeps it simple. Optional SW blinking could be
tried in a separate patch.
drivers/leds/leds-pca9532.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index 0344189bb991..dae7c6760508 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -182,11 +182,13 @@ static int pca9532_set_brightness(struct led_classdev *led_cdev,
int err = 0;
struct pca9532_led *led = ldev_to_led(led_cdev);
- if (value == LED_OFF)
+ if (value == LED_OFF) {
led->state = PCA9532_OFF;
- else if (value == LED_FULL)
+ } else if (led->state == PCA9532_PWM1) {
+ return 0; /* Non-zero brightness shall not stop HW blinking */
+ } else if (value == LED_FULL) {
led->state = PCA9532_ON;
- else {
+ } else {
led->state = PCA9532_PWM0; /* Thecus: hardcode one pwm */
err = pca9532_calcpwm(led->client, PCA9532_PWM_ID_0, 0, value);
if (err)
base-commit: b2c87f5e98cd88095dbc6802197526703d5e4e48
--
2.47.3