From: leo60228 <leo@60228.dev>
To: hdegoede@redhat.com, platform-driver-x86@vger.kernel.org
Cc: leo60228 <leo@60228.dev>
Subject: [PATCH] platform/x86: add support for Acer Predator LEDs
Date: Tue, 15 Jun 2021 18:19:31 -0400 [thread overview]
Message-ID: <20210615221931.18148-1-leo@60228.dev> (raw)
The Acer Predator Helios 500's keyboard has four zones of RGB LEDs.
This driver allows them to be controlled from Linux.
Signed-off-by: leo60228 <leo@60228.dev>
---
MAINTAINERS | 6 ++
drivers/platform/x86/Kconfig | 13 +++
drivers/platform/x86/Makefile | 1 +
drivers/platform/x86/acer-led.c | 156 ++++++++++++++++++++++++++++++++
4 files changed, 176 insertions(+)
create mode 100644 drivers/platform/x86/acer-led.c
diff --git a/MAINTAINERS b/MAINTAINERS
index bc0ceef87..f647ea81c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -327,6 +327,12 @@ S: Maintained
W: http://piie.net/?section=acerhdf
F: drivers/platform/x86/acerhdf.c
+ACER PREDATOR LAPTOP LEDS
+M: leo60228 <leo@60228.dev>
+L: platform-driver-x86@vger.kernel.org
+S: Maintained
+F: drivers/platform/x86/acer-led.c
+
ACER WMI LAPTOP EXTRAS
M: "Lee, Chun-Yi" <jlee@suse.com>
L: platform-driver-x86@vger.kernel.org
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 60592fb88..7dc4fd1ef 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -190,6 +190,19 @@ config ACER_WMI
If you have an ACPI-WMI compatible Acer/ Wistron laptop, say Y or M
here.
+config ACER_LED
+ tristate "Acer Predator Laptop LEDs"
+ depends on ACPI
+ depends on ACPI_WMI
+ depends on LEDS_CLASS
+ depends on NEW_LEDS
+ help
+ This is a driver for the RGB keyboard LEDs in Acer Predator laptops.
+ It was designed for the Acer Predator Helios 500.
+
+ If you choose to compile this driver as a module the module will be
+ called acer-led.
+
config AMD_PMC
tristate "AMD SoC PMC driver"
depends on ACPI && PCI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index dcc8cdb95..36722207b 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_GIGABYTE_WMI) += gigabyte-wmi.o
obj-$(CONFIG_ACERHDF) += acerhdf.o
obj-$(CONFIG_ACER_WIRELESS) += acer-wireless.o
obj-$(CONFIG_ACER_WMI) += acer-wmi.o
+obj-$(CONFIG_ACER_LED) += acer-led.o
# AMD
obj-$(CONFIG_AMD_PMC) += amd-pmc.o
diff --git a/drivers/platform/x86/acer-led.c b/drivers/platform/x86/acer-led.c
new file mode 100644
index 000000000..82a7b099a
--- /dev/null
+++ b/drivers/platform/x86/acer-led.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Acer LED Driver
+ *
+ * Copyright (C) 2021 leo60228
+ */
+
+#include <linux/acpi.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/leds.h>
+#include <linux/wmi.h>
+
+MODULE_AUTHOR("leo60228");
+MODULE_DESCRIPTION("Acer LED Driver");
+MODULE_LICENSE("GPL");
+
+#define ACER_LED_METHOD_GUID "7A4DDFE7-5B5D-40B4-8595-4408E0CC7F56"
+
+struct acer_led {
+ char name[32];
+ struct led_classdev cdev;
+ struct acer_led_zone *zone;
+};
+
+struct acer_led_zone {
+ int id;
+ struct acer_led red;
+ struct acer_led green;
+ struct acer_led blue;
+};
+
+struct acer_led_priv {
+ struct acer_led_zone zones[4];
+};
+
+struct led_zone_set_param {
+ u8 zone;
+ u8 red;
+ u8 green;
+ u8 blue;
+} __packed;
+
+static int acer_led_update_zone(struct acer_led_zone *zone)
+{
+ int status;
+
+ struct led_zone_set_param set_params = {
+ .zone = 1 << zone->id,
+ .red = zone->red.cdev.brightness,
+ .green = zone->green.cdev.brightness,
+ .blue = zone->blue.cdev.brightness,
+ };
+ struct acpi_buffer set_input = {
+ sizeof(struct led_zone_set_param),
+ &set_params
+ };
+
+ status = wmi_evaluate_method(
+ ACER_LED_METHOD_GUID, 0, 0x6, &set_input, NULL);
+ if (ACPI_FAILURE(status))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int acer_led_set(struct led_classdev *cdev,
+ enum led_brightness value)
+{
+ struct acer_led *led = container_of(cdev, struct acer_led, cdev);
+
+ return acer_led_update_zone(led->zone);
+}
+
+static int acer_led_setup_led(struct wmi_device *wdev,
+ struct acer_led *led,
+ struct acer_led_zone *zone,
+ const char *color)
+{
+ snprintf(led->name, sizeof(led->name), "%s:kbd_backlight-%d",
+ color, zone->id + 1);
+ led->cdev.name = led->name;
+ led->cdev.max_brightness = 255;
+ led->cdev.brightness_set_blocking = acer_led_set;
+ led->zone = zone;
+
+ return devm_led_classdev_register(&wdev->dev, &led->cdev);
+}
+
+static int acer_led_setup(struct wmi_device *wdev)
+{
+ struct acer_led_priv *priv = dev_get_drvdata(&wdev->dev);
+ int i, err = 0;
+
+ for (i = 0; i < 4; i++) {
+ priv->zones[i].id = i;
+
+ err = acer_led_setup_led(wdev, &priv->zones[i].red,
+ &priv->zones[i], "red");
+ if (err)
+ return err;
+
+ err = acer_led_setup_led(wdev, &priv->zones[i].green,
+ &priv->zones[i], "green");
+ if (err)
+ return err;
+
+ err = acer_led_setup_led(wdev, &priv->zones[i].blue,
+ &priv->zones[i], "blue");
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int acer_led_probe(struct wmi_device *wdev, const void *context)
+{
+ struct acer_led_priv *priv;
+
+ priv = devm_kzalloc(
+ &wdev->dev, sizeof(struct acer_led_priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+ dev_set_drvdata(&wdev->dev, priv);
+
+ return acer_led_setup(wdev);
+}
+
+static const struct wmi_device_id acer_led_id_table[] = {
+ { .guid_string = ACER_LED_METHOD_GUID },
+ { },
+};
+
+static struct wmi_driver acer_led_driver = {
+ .driver = {
+ .name = "acer-led",
+ },
+ .id_table = acer_led_id_table,
+ .probe = acer_led_probe,
+};
+
+static int __init acer_led_init(void)
+{
+ return wmi_driver_register(&acer_led_driver);
+}
+late_initcall(acer_led_init);
+
+static void __exit acer_led_exit(void)
+{
+ wmi_driver_unregister(&acer_led_driver);
+}
+module_exit(acer_led_exit);
+
+MODULE_DEVICE_TABLE(wmi, acer_led_id_table);
base-commit: 009c9aa5be652675a06d5211e1640e02bbb1c33d
--
2.28.0
next reply other threads:[~2021-06-15 22:19 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-15 22:19 leo60228 [this message]
2021-06-15 23:24 ` [PATCH] platform/x86: add support for Acer Predator LEDs Barnabás Pőcze
[not found] ` <CAPRrO0xZunTfYYSOg-Gvk18FMHPufAURZ=fWjQN1bmP=RuuzGA@mail.gmail.com>
2021-06-16 0:21 ` Barnabás Pőcze
2021-06-16 0:24 ` leo60228
2021-06-16 0:51 ` [PATCH v2] " leo60228
2021-06-16 15:43 ` Enrico Weigelt, metux IT consult
2021-06-16 15:56 ` leo60228
2021-06-16 17:20 ` Enrico Weigelt, metux IT consult
2021-06-16 17:50 ` Hans de Goede
2021-06-21 19:23 ` Enrico Weigelt, metux IT consult
2021-06-21 19:43 ` Hans de Goede
2021-06-22 10:19 ` input devices vs. keyboard backlights [WAS: [PATCH v2] platform/x86: add support for Acer Predator LEDs] Enrico Weigelt, metux IT consult
2021-06-22 10:46 ` Hans de Goede
2021-06-16 15:41 ` [PATCH] platform/x86: add support for Acer Predator LEDs Enrico Weigelt, metux IT consult
2021-06-16 16:06 ` leo60228
2021-06-16 17:22 ` Enrico Weigelt, metux IT consult
2021-06-16 16:00 ` Hans de Goede
2021-06-16 16:16 ` leo60228
2021-06-16 16:39 ` Hans de Goede
2021-06-16 17:01 ` leo60228
2021-06-16 17:13 ` Jafar Akhondali
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210615221931.18148-1-leo@60228.dev \
--to=leo@60228.dev \
--cc=hdegoede@redhat.com \
--cc=platform-driver-x86@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox