[PATCH v7 5/7] leds: Add driver for ASUS Transformer LEDs
From: Svyatoslav Ryhel
Date: Mon May 18 2026 - 06:02:24 EST
From: Michał Mirosław <mirq-linux@xxxxxxxxxxxx>
ASUS Transformer tablets have a green and an amber LED on both the Pad
and the Dock. If both LEDs are enabled simultaneously, the emitted light
will be yellow.
Co-developed-by: Svyatoslav Ryhel <clamor95@xxxxxxxxx>
Signed-off-by: Svyatoslav Ryhel <clamor95@xxxxxxxxx>
Signed-off-by: Michał Mirosław <mirq-linux@xxxxxxxxxxxx>
---
drivers/leds/Kconfig | 11 +++
drivers/leds/Makefile | 1 +
drivers/leds/leds-asus-transformer-ec.c | 109 ++++++++++++++++++++++++
3 files changed, 121 insertions(+)
create mode 100644 drivers/leds/leds-asus-transformer-ec.c
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index f4a0a3c8c870..f637d23400a8 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -120,6 +120,17 @@ config LEDS_OSRAM_AMS_AS3668
To compile this driver as a module, choose M here: the module
will be called leds-as3668.
+config LEDS_ASUS_TRANSFORMER_EC
+ tristate "LED Support for Asus Transformer charging LED"
+ depends on LEDS_CLASS
+ depends on MFD_ASUS_TRANSFORMER_EC
+ help
+ This option enables support for charging indicator on
+ Asus Transformer's Pad and it's Dock.
+
+ To compile this driver as a module, choose M here: the module
+ will be called leds-asus-transformer-ec.
+
config LEDS_AW200XX
tristate "LED support for Awinic AW20036/AW20054/AW20072/AW20108"
depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 8fdb45d5b439..d5395c3f1124 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_LEDS_AN30259A) += leds-an30259a.o
obj-$(CONFIG_LEDS_APU) += leds-apu.o
obj-$(CONFIG_LEDS_ARIEL) += leds-ariel.o
obj-$(CONFIG_LEDS_AS3668) += leds-as3668.o
+obj-$(CONFIG_LEDS_ASUS_TRANSFORMER_EC) += leds-asus-transformer-ec.o
obj-$(CONFIG_LEDS_AW200XX) += leds-aw200xx.o
obj-$(CONFIG_LEDS_AW2013) += leds-aw2013.o
obj-$(CONFIG_LEDS_BCM6328) += leds-bcm6328.o
diff --git a/drivers/leds/leds-asus-transformer-ec.c b/drivers/leds/leds-asus-transformer-ec.c
new file mode 100644
index 000000000000..c9bdc46c02e1
--- /dev/null
+++ b/drivers/leds/leds-asus-transformer-ec.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/err.h>
+#include <linux/leds.h>
+#include <linux/mfd/asus-transformer-ec.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+enum {
+ ASUSEC_LED_AMBER,
+ ASUSEC_LED_GREEN,
+ ASUSEC_LED_MAX
+};
+
+struct asus_ec_led_config {
+ const char *name;
+ unsigned int color;
+ unsigned long long ctrl_bit;
+};
+
+struct asus_ec_led {
+ struct asus_ec_leds_data *ddata;
+ struct led_classdev cdev;
+ unsigned long long ctrl_bit;
+};
+
+struct asus_ec_leds_data {
+ const struct asusec_core *ec;
+ struct asus_ec_led leds[ASUSEC_LED_MAX];
+};
+
+static const struct asus_ec_led_config asus_ec_leds[] = {
+ [ASUSEC_LED_AMBER] = {
+ .name = "amber",
+ .color = LED_COLOR_ID_AMBER,
+ .ctrl_bit = ASUSEC_CTL_LED_AMBER,
+ },
+ [ASUSEC_LED_GREEN] = {
+ .name = "green",
+ .color = LED_COLOR_ID_GREEN,
+ .ctrl_bit = ASUSEC_CTL_LED_GREEN,
+ },
+};
+
+static int asus_ec_led_set_brightness(struct led_classdev *cdev,
+ enum led_brightness brightness)
+{
+ struct asus_ec_led *led = container_of(cdev, struct asus_ec_led, cdev);
+ const struct asusec_core *ec = led->ddata->ec;
+
+ if (brightness)
+ return asus_dockram_access_ctl(ec->dockram, NULL,
+ led->ctrl_bit, led->ctrl_bit);
+
+ return asus_dockram_access_ctl(ec->dockram, NULL, led->ctrl_bit, 0);
+}
+
+static int asus_ec_led_probe(struct platform_device *pdev)
+{
+ const struct asusec_core *ec = dev_get_drvdata(pdev->dev.parent);
+ struct asus_ec_leds_data *ddata;
+ struct device *dev = &pdev->dev;
+ int i, ret;
+
+ ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
+ if (!ddata)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, ddata);
+ ddata->ec = ec;
+
+ for (i = 0; i < ASUSEC_LED_MAX; i++) {
+ const struct asus_ec_led_config *cfg = &asus_ec_leds[i];
+ struct asus_ec_led *led = &ddata->leds[i];
+
+ led->cdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s::%s",
+ ddata->ec->name, cfg->name);
+ if (!led->cdev.name)
+ return -ENOMEM;
+
+ led->cdev.max_brightness = 1;
+ led->cdev.color = cfg->color;
+ led->cdev.flags = LED_CORE_SUSPENDRESUME | LED_RETAIN_AT_SHUTDOWN;
+ led->cdev.brightness_set_blocking = asus_ec_led_set_brightness;
+
+ led->ddata = ddata;
+ led->ctrl_bit = cfg->ctrl_bit;
+
+ ret = devm_led_classdev_register(dev, &led->cdev);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "failed to register %s LED\n",
+ cfg->name);
+ }
+
+ return 0;
+}
+
+static struct platform_driver asus_ec_led_driver = {
+ .driver.name = "asus-transformer-ec-led",
+ .probe = asus_ec_led_probe,
+};
+module_platform_driver(asus_ec_led_driver);
+
+MODULE_AUTHOR("Michał Mirosław <mirq-linux@xxxxxxxxxxxx>");
+MODULE_AUTHOR("Svyatoslav Ryhel <clamor95@xxxxxxxxx>");
+MODULE_DESCRIPTION("ASUS Transformer's charging LED driver");
+MODULE_LICENSE("GPL");
--
2.51.0