From 4dc6cc47d5fa927cc1a013b7b55fea04c9a7d222 Mon Sep 17 00:00:00 2001 From: Thomas BRUNEL Date: Mon, 7 Sep 2026 16:54:54 +0200 Subject: [PATCH] feat: add multi-intensity LED support Signed-off-by: Thomas BRUNEL --- src/led.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ src/led.h | 2 ++ tests/test_led.c | 15 ++++++++++++ 3 files changed, 80 insertions(+) diff --git a/src/led.c b/src/led.c index 5facbc4..80e7eed 100644 --- a/src/led.c +++ b/src/led.c @@ -101,6 +101,33 @@ void led_free(led_t *led) { free(led); } +int led_get_multi_intensity(led_t *led, unsigned int *red, unsigned int *green, unsigned int *blue) { + char led_path[P_PATH_MAX]; + char buf[16]; + int fd, ret; + + snprintf(led_path, sizeof(led_path), "/sys/class/leds/%s/multi_intensity", led->name); + + if ((fd = open(led_path, O_RDONLY)) < 0) + return _led_error(led, LED_ERROR_IO, errno, "Opening LED 'multi_intensity'"); + + if ((ret = read(fd, buf, sizeof(buf) - 1)) < 0) { + int errsv = errno; + close(fd); + return _led_error(led, LED_ERROR_IO, errsv, "Reading LED 'multi_intensity'"); + } + + buf[ret] = '\0'; + + if (close(fd) < 0) + return _led_error(led, LED_ERROR_IO, errno, "Closing LED 'multi_intensity'"); + + if (sscanf(buf, "%u %u %u", red, green, blue) != 3) + return _led_error(led, LED_ERROR_IO, 0, "Invalid LED 'multi_intensity' value"); + + return 0; +} + int led_get_brightness(led_t *led, unsigned int *brightness) { char led_path[P_PATH_MAX]; char buf[16]; @@ -264,6 +291,42 @@ int led_get_triggers_count(led_t *led, unsigned int *count) { return 0; } +int led_set_multi_intensity(led_t *led, unsigned int red, unsigned int green, unsigned int blue) { + char led_path[P_PATH_MAX]; + char buf[16]; + int fd, len; + + if (red > 255) { + return _led_error(led, LED_ERROR_ARG, 0, "Red out of bounds (max is 255)"); + } + + if (green > 255) { + return _led_error(led, LED_ERROR_ARG, 0, "Green out of bounds (max is 255)"); + } + + if (blue > 255) { + return _led_error(led, LED_ERROR_ARG, 0, "blue out of bounds (max is 255)"); + } + + snprintf(led_path, sizeof(led_path), "/sys/class/leds/%s/multi_intensity", led->name); + + if ((fd = open(led_path, O_WRONLY)) < 0) + return _led_error(led, LED_ERROR_IO, errno, "Opening LED 'multi_intensity'"); + + len = snprintf(buf, sizeof(buf), "%u %u %u\n", red, green, blue); + + if (write(fd, buf, len) < 0) { + int errsv = errno; + close(fd); + return _led_error(led, LED_ERROR_IO, errsv, "Writing LED 'multi_intensity'"); + } + + if (close(fd) < 0) + return _led_error(led, LED_ERROR_IO, errno, "Closing LED 'multi_intensity'"); + + return 0; +} + int led_set_brightness(led_t *led, unsigned int brightness) { char led_path[P_PATH_MAX]; char buf[16]; diff --git a/src/led.h b/src/led.h index 6de3414..6ea5b0b 100644 --- a/src/led.h +++ b/src/led.h @@ -34,6 +34,7 @@ int led_close(led_t *led); void led_free(led_t *led); /* Getters */ +int led_get_multi_intensity(led_t *led, unsigned int *red, unsigned int *green, unsigned int *blue); int led_get_brightness(led_t *led, unsigned int *brightness); int led_get_max_brightness(led_t *led, unsigned int *max_brightness); int led_get_trigger(led_t *led, char *str, size_t len); @@ -41,6 +42,7 @@ int led_get_triggers_entry(led_t *led, unsigned int index, char *str, size_t len int led_get_triggers_count(led_t *led, unsigned int *count); /* Setters */ +int led_set_multi_intensity(led_t *led, unsigned int red, unsigned int green, unsigned int blue); int led_set_brightness(led_t *led, unsigned int brightness); int led_set_trigger(led_t *led, const char *trigger); diff --git a/tests/test_led.c b/tests/test_led.c index fb58117..cf58802 100644 --- a/tests/test_led.c +++ b/tests/test_led.c @@ -28,6 +28,9 @@ void test_open_config_close(void) { unsigned int max_brightness; unsigned int brightness; unsigned int triggers_count; + unsigned int red; + unsigned int green; + unsigned int blue; bool value; ptest(); @@ -50,6 +53,18 @@ void test_open_config_close(void) { passert(led_get_max_brightness(led, &max_brightness) == 0); passert(max_brightness > 0); + /* Check multi-intensity values */ + passert(led_set_multi_intensity(led, 1, 2, 3) == 0); + usleep(10000); + passert(led_get_multi_intensity(led, &red, &green, &blue) == 0); + passert(red == 1); + passert(green == 2); + passert(blue == 3); + passert(led_set_multi_intensity(led, 256, 0, 0) == LED_ERROR_ARG); + passert(led_set_multi_intensity(led, 0, 256, 0) == LED_ERROR_ARG); + passert(led_set_multi_intensity(led, 0, 0, 256) == LED_ERROR_ARG); + passert(led_set_multi_intensity(led, 0, 0, 0) == 0); + /* Check setting invalid brightness */ passert(led_set_brightness(led, max_brightness + 1) == LED_ERROR_ARG);