From 8aa7213327857383c91ac5b28747e206c5c3f1a5 Mon Sep 17 00:00:00 2001 From: "Sicelo A. Mhlongo" Date: Sat, 28 Jun 2025 16:53:22 +0200 Subject: [PATCH 1/3] fbd-dev-led: Support LEDs with legacy naming As noted in include/dt-bindings/leds/common.h in the Linux kernel, the Nokia N900 has leds that use legacy naming. Until this naming scheme is removed from the kernel, support it through the use of an additional FEEDBACKD_LED_COLOR udev property, which must be set to the color corresponding to the LED. Signed-off-by: Sicelo A. Mhlongo --- src/fbd-dev-led.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fbd-dev-led.c b/src/fbd-dev-led.c index 2008e97..0b57466 100644 --- a/src/fbd-dev-led.c +++ b/src/fbd-dev-led.c @@ -51,11 +51,12 @@ static gboolean fbd_dev_led_probe_default (FbdDevLed *led, GError **error) { FbdDevLedPrivate *priv = fbd_dev_led_get_instance_private (led); - const gchar *name, *path; + const gchar *name, *path, *hint; gboolean success = FALSE; const char *pattern; name = g_udev_device_get_name (priv->dev); + hint = g_udev_device_get_property (priv->dev, "FEEDBACKD_LED_COLOR"); pattern = g_udev_device_get_sysfs_attr (priv->dev, LED_PATTERN_ATTR); if (!pattern) { g_set_error (error, @@ -72,7 +73,7 @@ fbd_dev_led_probe_default (FbdDevLed *led, GError **error) enum_name = g_enum_to_string (FBD_TYPE_FEEDBACK_LED_COLOR, i); c = strrchr (enum_name, '_'); color = g_ascii_strdown (c+1, -1); - if (g_strstr_len (name, -1, color)) { + if (g_strstr_len (name, -1, color) || !g_strcmp0 (hint, color)) { guint brightness = g_udev_device_get_sysfs_attr_as_int (priv->dev, LED_MAX_BRIGHTNESS_ATTR); if (!brightness) From cf848e08caef27ff7fdfa660fdea5d2bf60aa863 Mon Sep 17 00:00:00 2001 From: "Sicelo A. Mhlongo" Date: Mon, 30 Jun 2025 19:12:00 +0200 Subject: [PATCH 2/3] udev: Support legacy LED naming The Nokia N900 and Motorola Droid 4 use obsolete naming for LEDs, as indicated in include/dt-bindings/leds/common.h in the Linux kernel. Since the obsolete naming is still in wide use, support them in feedbackd until it is eventually removed in the kernel. Signed-off-by: Sicelo A. Mhlongo --- data/90-feedbackd.rules | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/data/90-feedbackd.rules b/data/90-feedbackd.rules index 8e039f5..b81f3b4 100644 --- a/data/90-feedbackd.rules +++ b/data/90-feedbackd.rules @@ -37,6 +37,13 @@ SUBSYSTEM=="leds", DEVPATH=="*/*:indicator", ENV{FEEDBACKD_TYPE}="led", RUN{buil # Camera Flash SUBSYSTEM=="leds", DEVPATH=="*/*:flash", ENV{FEEDBACKD_TYPE}="led", RUN{builtin}+="kmod load ledtrig-pattern", RUN+="/usr/libexec/fbd-ledctrl -p %S%p -t pattern -G feedbackd" SUBSYSTEM=="leds", DEVPATH=="*/*:torch", ENV{FEEDBACKD_TYPE}="led", RUN{builtin}+="kmod load ledtrig-pattern", RUN+="/usr/libexec/fbd-ledctrl -p %S%p -t pattern -G feedbackd" +# Legacy LEDs +### Motorola Droid 4 +SUBSYSTEM=="leds", DEVPATH=="*/status-led:*", ENV{FEEDBACKD_TYPE}="led", RUN{builtin}+="kmod load ledtrig-pattern", RUN+="/usr/libexec/fbd-ledctrl -p %S%p -t pattern -G feedbackd" +### Nokia N900 +SUBSYSTEM=="leds", DEVPATH=="*/lp5523:r", ENV{FEEDBACKD_LED_COLOR}="red", ENV{FEEDBACKD_TYPE}="led", RUN{builtin}+="kmod load ledtrig-pattern", RUN+="/usr/libexec/fbd-ledctrl -p %S%p -t pattern -G feedbackd" +SUBSYSTEM=="leds", DEVPATH=="*/lp5523:g", ENV{FEEDBACKD_LED_COLOR}="green", ENV{FEEDBACKD_TYPE}="led", RUN{builtin}+="kmod load ledtrig-pattern", RUN+="/usr/libexec/fbd-ledctrl -p %S%p -t pattern -G feedbackd" +SUBSYSTEM=="leds", DEVPATH=="*/lp5523:b", ENV{FEEDBACKD_LED_COLOR}="blue", ENV{FEEDBACKD_TYPE}="led", RUN{builtin}+="kmod load ledtrig-pattern", RUN+="/usr/libexec/fbd-ledctrl -p %S%p -t pattern -G feedbackd" # # Alert sliders From a31c636f142ba2be321b05356457f39efe29b40d Mon Sep 17 00:00:00 2001 From: "Sicelo A. Mhlongo" Date: Sat, 12 Jul 2025 12:50:11 +0200 Subject: [PATCH 3/3] tests: Test legacy LED name detection Signed-off-by: Sicelo A. Mhlongo --- tests/data/umockdev/led-legacy.umockdev | 183 ++++++++++++++++++++++++ tests/test-fbd-dev-led.c | 32 +++++ 2 files changed, 215 insertions(+) create mode 100644 tests/data/umockdev/led-legacy.umockdev diff --git a/tests/data/umockdev/led-legacy.umockdev b/tests/data/umockdev/led-legacy.umockdev new file mode 100644 index 0000000..cc9e58a --- /dev/null +++ b/tests/data/umockdev/led-legacy.umockdev @@ -0,0 +1,183 @@ +P: /devices/platform/68000000.ocp/48072000.i2c/i2c-2/2-0032/leds/lp5523:r +E: FEEDBACKD_LED_COLOR=red +E: FEEDBACKD_TYPE=led +E: ID_FOR_SEAT=leds-platform-48072000_i2c +E: ID_PATH=platform-48072000.i2c +E: ID_PATH_TAG=platform-48072000_i2c +E: SUBSYSTEM=leds +E: TAGS=:seat: +A: brightness=0\n +L: device=../../../2-0032 +A: hr_pattern= +A: led_current=50\n +A: max_brightness=255\n +A: max_current=100\n +A: pattern= +A: power/control=auto\n +A: power/runtime_active_time=0\n +A: power/runtime_status=unsupported\n +A: power/runtime_suspended_time=0\n +A: repeat=-1\n +A: trigger=none kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock cpu cpu0 mmc0 mmc1 bq24150a-0-online bq27200-0-charging-or-full bq27200-0-charging bq27200-0-full bq27200-0-charging-blink-full-solid bq27200-0-charging-orange-full-green isp1704-online rc-feedback [pattern] rfkill-any rfkill-none rfkill0\n + +P: /devices/platform/68000000.ocp/48072000.i2c/i2c-2/2-0032 +E: DRIVER=lp5523x +E: MODALIAS=of:Nlp5523T(null)Cnational,lp5523 +E: OF_COMPATIBLE_0=national,lp5523 +E: OF_COMPATIBLE_N=1 +E: OF_FULLNAME=/ocp@68000000/i2c@48072000/lp5523@32 +E: OF_NAME=lp5523 +E: SUBSYSTEM=i2c +L: driver=../../../../../../bus/i2c/drivers/lp5523x +A: engine1_leds=000000000\n +A: engine1_mode=disabled\n +A: engine2_leds=000000000\n +A: engine2_mode=disabled\n +A: engine3_leds=000000000\n +A: engine3_mode=disabled\n +A: master_fader1=0\n +A: master_fader2=0\n +A: master_fader3=0\n +A: master_fader_leds=000000000\n +A: modalias=of:Nlp5523T(null)Cnational,lp5523\n +A: name=lp5523\n +L: of_node=../../../../../../firmware/devicetree/base/ocp@68000000/i2c@48072000/lp5523@32 +A: power/control=auto\n +A: power/runtime_active_time=0\n +A: power/runtime_status=unsupported\n +A: power/runtime_suspended_time=0\n +A: select_engine=3\n +A: selftest=OK\n +L: supplier:platform:68000000.ocp=../../../../../virtual/devlink/platform:68000000.ocp--i2c:2-0032 + +P: /devices/platform/68000000.ocp/48072000.i2c/i2c-2 +E: OF_ALIAS_0=i2c2 +E: OF_COMPATIBLE_0=ti,omap3-i2c +E: OF_COMPATIBLE_N=1 +E: OF_FULLNAME=/ocp@68000000/i2c@48072000 +E: OF_NAME=i2c +E: SUBSYSTEM=i2c +A: name=OMAP I2C adapter\n +L: of_node=../../../../../firmware/devicetree/base/ocp@68000000/i2c@48072000 + +P: /devices/platform/68000000.ocp/48072000.i2c +E: DRIVER=omap_i2c +E: MODALIAS=of:Ni2cT(null)Cti,omap3-i2c +E: OF_ALIAS_0=i2c2 +E: OF_COMPATIBLE_0=ti,omap3-i2c +E: OF_COMPATIBLE_N=1 +E: OF_FULLNAME=/ocp@68000000/i2c@48072000 +E: OF_NAME=i2c +E: SUBSYSTEM=platform +L: driver=../../../../bus/platform/drivers/omap_i2c +A: driver_override=(null)\n +A: modalias=of:Ni2cT(null)Cti,omap3-i2c\n +L: of_node=../../../../firmware/devicetree/base/ocp@68000000/i2c@48072000 +A: power/autosuspend_delay_ms=1000\n +A: power/control=auto\n +A: power/runtime_active_time=105291617\n +A: power/runtime_status=active\n +A: power/runtime_suspended_time=565173173\n +L: supplier:platform:68000000.ocp=../../../virtual/devlink/platform:68000000.ocp--platform:48072000.i2c + +P: /devices/platform/68000000.ocp +E: DRIVER=omap_l3_smx +E: MODALIAS=of:NocpT(null)Cti,omap3-l3-smxCsimple-bus +E: OF_COMPATIBLE_0=ti,omap3-l3-smx +E: OF_COMPATIBLE_1=simple-bus +E: OF_COMPATIBLE_N=2 +E: OF_FULLNAME=/ocp@68000000 +E: OF_NAME=ocp +E: SUBSYSTEM=platform +L: consumer:i2c:1-0048=../../virtual/devlink/platform:68000000.ocp--i2c:1-0048 +L: consumer:i2c:2-0018=../../virtual/devlink/platform:68000000.ocp--i2c:2-0018 +L: consumer:i2c:2-0019=../../virtual/devlink/platform:68000000.ocp--i2c:2-0019 +L: consumer:i2c:2-0030=../../virtual/devlink/platform:68000000.ocp--i2c:2-0030 +L: consumer:i2c:2-0032=../../virtual/devlink/platform:68000000.ocp--i2c:2-0032 +L: consumer:i2c:2-0055=../../virtual/devlink/platform:68000000.ocp--i2c:2-0055 +L: consumer:i2c:2-0060=../../virtual/devlink/platform:68000000.ocp--i2c:2-0060 +L: consumer:i2c:2-0063=../../virtual/devlink/platform:68000000.ocp--i2c:2-0063 +L: consumer:i2c:3-000c=../../virtual/devlink/platform:68000000.ocp--i2c:3-000c +L: consumer:i2c:3-001d=../../virtual/devlink/platform:68000000.ocp--i2c:3-001d +L: consumer:i2c:3-003e=../../virtual/devlink/platform:68000000.ocp--i2c:3-003e +L: consumer:platform:2000000.ethernet=../../virtual/devlink/platform:68000000.ocp--platform:2000000.ethernet +L: consumer:platform:48002000.scm=../../virtual/devlink/platform:68000000.ocp--platform:48002000.scm +L: consumer:platform:48002270.scm_conf=../../virtual/devlink/platform:68000000.ocp--platform:48002270.scm_conf +L: consumer:platform:48004000.cm=../../virtual/devlink/platform:68000000.ocp--platform:48004000.cm +L: consumer:platform:48050400.dispc=../../virtual/devlink/platform:68000000.ocp--platform:48050400.dispc +L: consumer:platform:48050c00.encoder=../../virtual/devlink/platform:68000000.ocp--platform:48050c00.encoder +L: consumer:platform:48056000.dma-controller=../../virtual/devlink/platform:68000000.ocp--platform:48056000.dma-controller +L: consumer:platform:48056000.target-module=../../virtual/devlink/platform:68000000.ocp--platform:48056000.target-module +L: consumer:platform:48058000.ssi-controller=../../virtual/devlink/platform:68000000.ocp--platform:48058000.ssi-controller +L: consumer:platform:4805a000.ssi-port=../../virtual/devlink/platform:68000000.ocp--platform:4805a000.ssi-port +L: consumer:platform:48060000.i2c=../../virtual/devlink/platform:68000000.ocp--platform:48060000.i2c +L: consumer:platform:48062000.usbhstll=../../virtual/devlink/platform:68000000.ocp--platform:48062000.usbhstll +L: consumer:platform:48064400.ohci=../../virtual/devlink/platform:68000000.ocp--platform:48064400.ohci +L: consumer:platform:48064800.ehci=../../virtual/devlink/platform:68000000.ocp--platform:48064800.ehci +L: consumer:platform:4806c000.serial=../../virtual/devlink/platform:68000000.ocp--platform:4806c000.serial +L: consumer:platform:48070000.i2c=../../virtual/devlink/platform:68000000.ocp--platform:48070000.i2c +L: consumer:platform:48070000.i2c:twl@48:charger=../../virtual/devlink/platform:68000000.ocp--platform:48070000.i2c:twl@48:charger +L: consumer:platform:48070000.i2c:twl@48:keypad=../../virtual/devlink/platform:68000000.ocp--platform:48070000.i2c:twl@48:keypad +L: consumer:platform:48070000.i2c:twl@48:madc=../../virtual/devlink/platform:68000000.ocp--platform:48070000.i2c:twl@48:madc +L: consumer:platform:48070000.i2c:twl@48:pwrbutton=../../virtual/devlink/platform:68000000.ocp--platform:48070000.i2c:twl@48:pwrbutton +L: consumer:platform:48070000.i2c:twl@48:rtc=../../virtual/devlink/platform:68000000.ocp--platform:48070000.i2c:twl@48:rtc +L: consumer:platform:48070000.i2c:twl@48:twl4030-usb=../../virtual/devlink/platform:68000000.ocp--platform:48070000.i2c:twl@48:twl4030-usb +L: consumer:platform:48072000.i2c=../../virtual/devlink/platform:68000000.ocp--platform:48072000.i2c +L: consumer:platform:48086000.timer=../../virtual/devlink/platform:68000000.ocp--platform:48086000.timer +L: consumer:platform:48088000.timer=../../virtual/devlink/platform:68000000.ocp--platform:48088000.timer +L: consumer:platform:48094000.mailbox=../../virtual/devlink/platform:68000000.ocp--platform:48094000.mailbox +L: consumer:platform:48098000.spi=../../virtual/devlink/platform:68000000.ocp--platform:48098000.spi +L: consumer:platform:4809a000.spi=../../virtual/devlink/platform:68000000.ocp--platform:4809a000.spi +L: consumer:platform:4809c000.mmc=../../virtual/devlink/platform:68000000.ocp--platform:4809c000.mmc +L: consumer:platform:480ab000.usb=../../virtual/devlink/platform:68000000.ocp--platform:480ab000.usb +L: consumer:platform:480ab400.target-module=../../virtual/devlink/platform:68000000.ocp--platform:480ab400.target-module +L: consumer:platform:480b2000.1w=../../virtual/devlink/platform:68000000.ocp--platform:480b2000.1w +L: consumer:platform:480b4000.mmc=../../virtual/devlink/platform:68000000.ocp--platform:480b4000.mmc +L: consumer:platform:480b8000.spi=../../virtual/devlink/platform:68000000.ocp--platform:480b8000.spi +L: consumer:platform:480ba000.spi=../../virtual/devlink/platform:68000000.ocp--platform:480ba000.spi +L: consumer:platform:480bc000.isp=../../virtual/devlink/platform:68000000.ocp--platform:480bc000.isp +L: consumer:platform:480bd400.mmu=../../virtual/devlink/platform:68000000.ocp--platform:480bd400.mmu +L: consumer:platform:480c3000.sham=../../virtual/devlink/platform:68000000.ocp--platform:480c3000.sham +L: consumer:platform:480c9000.smartreflex=../../virtual/devlink/platform:68000000.ocp--platform:480c9000.smartreflex +L: consumer:platform:480c9024.target-module=../../virtual/devlink/platform:68000000.ocp--platform:480c9024.target-module +L: consumer:platform:480cb000.smartreflex=../../virtual/devlink/platform:68000000.ocp--platform:480cb000.smartreflex +L: consumer:platform:480cb024.target-module=../../virtual/devlink/platform:68000000.ocp--platform:480cb024.target-module +L: consumer:platform:48304000.target-module=../../virtual/devlink/platform:68000000.ocp--platform:48304000.target-module +L: consumer:platform:48310000.gpio=../../virtual/devlink/platform:68000000.ocp--platform:48310000.gpio +L: consumer:platform:48318000.target-module=../../virtual/devlink/platform:68000000.ocp--platform:48318000.target-module +L: consumer:platform:48320000.target-module=../../virtual/devlink/platform:68000000.ocp--platform:48320000.target-module +L: consumer:platform:49020000.serial=../../virtual/devlink/platform:68000000.ocp--platform:49020000.serial +L: consumer:platform:49022000.mcbsp=../../virtual/devlink/platform:68000000.ocp--platform:49022000.mcbsp +L: consumer:platform:49032000.target-module=../../virtual/devlink/platform:68000000.ocp--platform:49032000.target-module +L: consumer:platform:49032000.timer=../../virtual/devlink/platform:68000000.ocp--platform:49032000.timer +L: consumer:platform:49034000.timer=../../virtual/devlink/platform:68000000.ocp--platform:49034000.timer +L: consumer:platform:49036000.timer=../../virtual/devlink/platform:68000000.ocp--platform:49036000.timer +L: consumer:platform:49038000.timer=../../virtual/devlink/platform:68000000.ocp--platform:49038000.timer +L: consumer:platform:4903a000.timer=../../virtual/devlink/platform:68000000.ocp--platform:4903a000.timer +L: consumer:platform:4903c000.timer=../../virtual/devlink/platform:68000000.ocp--platform:4903c000.timer +L: consumer:platform:4903e000.timer=../../virtual/devlink/platform:68000000.ocp--platform:4903e000.timer +L: consumer:platform:49040000.timer=../../virtual/devlink/platform:68000000.ocp--platform:49040000.timer +L: consumer:platform:49050000.gpio=../../virtual/devlink/platform:68000000.ocp--platform:49050000.gpio +L: consumer:platform:49052000.gpio=../../virtual/devlink/platform:68000000.ocp--platform:49052000.gpio +L: consumer:platform:49054000.gpio=../../virtual/devlink/platform:68000000.ocp--platform:49054000.gpio +L: consumer:platform:49056000.gpio=../../virtual/devlink/platform:68000000.ocp--platform:49056000.gpio +L: consumer:platform:49058000.gpio=../../virtual/devlink/platform:68000000.ocp--platform:49058000.gpio +L: consumer:platform:50000000.gpu=../../virtual/devlink/platform:68000000.ocp--platform:50000000.gpu +L: consumer:platform:50000014.target-module=../../virtual/devlink/platform:68000000.ocp--platform:50000014.target-module +L: consumer:platform:68000000.ocp:l4@48000000=../../virtual/devlink/platform:68000000.ocp--platform:68000000.ocp:l4@48000000 +L: consumer:platform:6e000000.gpmc=../../virtual/devlink/platform:68000000.ocp--platform:6e000000.gpmc +L: consumer:platform:isp1707=../../virtual/devlink/platform:68000000.ocp--platform:isp1707 +L: consumer:platform:leds=../../virtual/devlink/platform:68000000.ocp--platform:leds +L: consumer:platform:n900-audio=../../virtual/devlink/platform:68000000.ocp--platform:n900-audio +L: consumer:serial:serial0-0=../../virtual/devlink/platform:68000000.ocp--serial:serial0-0 +L: consumer:spi:spi0.0=../../virtual/devlink/platform:68000000.ocp--spi:spi0.0 +L: consumer:spi:spi3.0=../../virtual/devlink/platform:68000000.ocp--spi:spi3.0 +L: driver=../../../bus/platform/drivers/omap_l3_smx +A: driver_override=(null)\n +A: modalias=of:NocpT(null)Cti,omap3-l3-smxCsimple-bus\n +L: of_node=../../../firmware/devicetree/base/ocp@68000000 +A: power/control=auto\n +A: power/runtime_active_time=0\n +A: power/runtime_status=unsupported\n +A: power/runtime_suspended_time=0\n + diff --git a/tests/test-fbd-dev-led.c b/tests/test-fbd-dev-led.c index afa0207..af47def 100644 --- a/tests/test-fbd-dev-led.c +++ b/tests/test-fbd-dev-led.c @@ -159,6 +159,35 @@ test_fbd_dev_led_qcom_multicolor (FbdUmockdevFixture *fixture, gconstpointer unu } +static void +test_fbd_dev_led_legacy (FbdUmockdevFixture *fixture, gconstpointer unused) +{ + GUdevClient *client; + g_autolist (GUdevDevice) leds = NULL; + FbdDevLed *led; + g_autoptr (GError) err = NULL; + GUdevDevice *dev; + + client = g_udev_client_new ((const char *const []){ "leds", NULL}); + leds = g_udev_client_query_by_subsystem (client, "leds"); + + /* There should be a single device only */ + g_assert_cmpint (g_list_length (leds), ==, 1); + dev = G_UDEV_DEVICE (leds->data); + + g_assert_cmpstr (g_udev_device_get_property (dev, "FEEDBACKD_TYPE"), ==, "led"); + g_assert_cmpstr (g_udev_device_get_property (dev, "FEEDBACKD_LED_COLOR"), ==, "red"); + + led = fbd_dev_led_new (dev, &err); + g_assert_no_error (err); + g_assert_cmpint (fbd_dev_led_get_max_brightness (led), ==, 255); + g_assert_cmpint (fbd_dev_led_get_priority (led), ==, 10); + g_assert_true (fbd_dev_led_supports_color (led, FBD_FEEDBACK_LED_COLOR_RED)); + g_assert_true (fbd_dev_led_start_periodic (led, 50, 50)); + g_assert_finalize_object (led); +} + + gint main (gint argc, gchar *argv[]) { @@ -179,6 +208,9 @@ main (gint argc, gchar *argv[]) FBD_UMOCKDEV_TEST_ADD ("/feedbackd/fbd/dev/led/qcom/multicolor", test_fbd_dev_led_qcom_multicolor, "led-qcom-multicolor"); + FBD_UMOCKDEV_TEST_ADD ("/feedbackd/fbd/dev/led/legacy", + test_fbd_dev_led_legacy, + "led-legacy"); return g_test_run(); }