From: leo60228 <leo@60228.dev>
To: hdegoede@redhat.com, platform-driver-x86@vger.kernel.org,
linux-leds@vger.kernel.org
Cc: leo60228 <leo@60228.dev>
Subject: [PATCH v2] platform/x86: add support for Acer Predator LEDs
Date: Tue, 15 Jun 2021 20:51:47 -0400 [thread overview]
Message-ID: <20210616005147.26212-1-leo@60228.dev> (raw)
In-Reply-To: <20210615221931.18148-1-leo@60228.dev>
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>
---
In addition to some smaller concerns from review, v2 registers
multicolor LEDs instead of independent red, green, and blue ones.
MAINTAINERS | 6 ++
drivers/platform/x86/Kconfig | 13 +++
drivers/platform/x86/Makefile | 1 +
drivers/platform/x86/acer-led.c | 143 ++++++++++++++++++++++++++++++++
4 files changed, 163 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..a6d6ed2ac 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_MULTICOLOR
+ 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..d618830e0
--- /dev/null
+++ b/drivers/platform/x86/acer-led.c
@@ -0,0 +1,143 @@
+// 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/led-class-multicolor.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_zone {
+ char name[32];
+ int id;
+ struct mc_subled channels[3];
+ struct led_classdev_mc cdev;
+};
+
+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_set(struct led_classdev *lcdev,
+ enum led_brightness value)
+{
+ struct led_classdev_mc *mccdev;
+ struct acer_led_zone *zone;
+ struct led_zone_set_param set_params;
+ struct acpi_buffer set_input;
+ int err;
+ acpi_status status;
+
+ mccdev = lcdev_to_mccdev(lcdev);
+
+ err = led_mc_calc_color_components(mccdev, value);
+ if (err)
+ return err;
+
+ zone = container_of(mccdev, struct acer_led_zone, cdev);
+
+ set_params = (struct led_zone_set_param) {
+ .zone = BIT(zone->id),
+ .red = zone->channels[0].brightness,
+ .green = zone->channels[1].brightness,
+ .blue = zone->channels[2].brightness,
+ };
+ set_input = (struct acpi_buffer) {
+ sizeof(set_params),
+ &set_params
+ };
+
+ status = wmi_evaluate_method(
+ ACER_LED_METHOD_GUID, 0, 0x6, &set_input, NULL);
+ if (ACPI_FAILURE(status))
+ return -EIO;
+
+ return 0;
+}
+
+static int acer_led_setup_zone(struct wmi_device *wdev,
+ struct acer_led_zone *zone)
+{
+ snprintf(zone->name, sizeof(zone->name), ":kbd_backlight-%d",
+ zone->id + 1);
+
+ zone->channels[0].color_index = LED_COLOR_ID_RED;
+ zone->channels[0].channel = 0;
+ zone->channels[1].color_index = LED_COLOR_ID_GREEN;
+ zone->channels[1].channel = 1;
+ zone->channels[2].color_index = LED_COLOR_ID_BLUE;
+ zone->channels[2].channel = 2;
+
+ zone->cdev.num_colors = 3;
+ zone->cdev.subled_info = zone->channels;
+
+ zone->cdev.led_cdev.name = zone->name;
+ zone->cdev.led_cdev.max_brightness = 255;
+ zone->cdev.led_cdev.brightness_set_blocking = acer_led_set;
+
+ return devm_led_classdev_multicolor_register(&wdev->dev, &zone->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 < ARRAY_SIZE(priv->zones); i++) {
+ priv->zones[i].id = i;
+
+ err = acer_led_setup_zone(wdev, &priv->zones[i]);
+ 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(*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,
+};
+
+module_wmi_driver(acer_led_driver);
+
+MODULE_DEVICE_TABLE(wmi, acer_led_id_table);
--
2.28.0
next prev parent reply other threads:[~2021-06-16 0:51 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20210615221931.18148-1-leo@60228.dev>
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 ` leo60228 [this message]
2021-06-16 15:43 ` [PATCH v2] " 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
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=20210616005147.26212-1-leo@60228.dev \
--to=leo@60228.dev \
--cc=hdegoede@redhat.com \
--cc=linux-leds@vger.kernel.org \
--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;
as well as URLs for NNTP newsgroup(s).