Handle new KBLED ACPI methods

The EC has been updated to detect if a white or RGB backlit keyboard is
attached at run-time instead of being set at compile-time. The ACPI
methods in coreboot have been updated to handle this new functionality.

Check for the new ACPI method `GKBK` "Get Keyboard Kind" to determine if
the module should use the new logic or the old logic.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
This commit is contained in:
Tim Crawford 2023-05-23 10:21:59 -06:00 committed by Jeremy Soller
parent ed0112437f
commit aaf10e3dac
1 changed files with 64 additions and 14 deletions

View File

@ -25,6 +25,12 @@
#include <acpi/battery.h> #include <acpi/battery.h>
enum kbled_type {
KBLED_NONE,
KBLED_WHITE,
KBLED_RGB,
};
struct system76_data { struct system76_data {
struct acpi_device *acpi_dev; struct acpi_device *acpi_dev;
struct led_classdev ap_led; struct led_classdev ap_led;
@ -37,6 +43,7 @@ struct system76_data {
union acpi_object *ntmp; union acpi_object *ntmp;
struct input_dev *input; struct input_dev *input;
bool has_open_ec; bool has_open_ec;
enum kbled_type kbled_type;
}; };
static const struct acpi_device_id device_ids[] = { static const struct acpi_device_id device_ids[] = {
@ -340,7 +347,11 @@ static int kb_led_set(struct led_classdev *led, enum led_brightness value)
data = container_of(led, struct system76_data, kb_led); data = container_of(led, struct system76_data, kb_led);
data->kb_brightness = value; data->kb_brightness = value;
return system76_set(data, "SKBL", (int)data->kb_brightness); if (acpi_has_method(acpi_device_handle(data->acpi_dev), "GKBK")) {
return system76_set(data, "SKBB", (int)data->kb_brightness);
} else {
return system76_set(data, "SKBL", (int)data->kb_brightness);
}
} }
// Get the last set keyboard LED color // Get the last set keyboard LED color
@ -416,7 +427,12 @@ static void kb_led_hotkey_hardware(struct system76_data *data)
{ {
int value; int value;
value = system76_get(data, "GKBL"); if (acpi_has_method(acpi_device_handle(data->acpi_dev), "GKBK")) {
value = system76_get(data, "GKBB");
} else {
value = system76_get(data, "GKBL");
}
if (value < 0) if (value < 0)
return; return;
data->kb_brightness = value; data->kb_brightness = value;
@ -700,20 +716,54 @@ static int system76_add(struct acpi_device *acpi_dev)
if (err) if (err)
return err; return err;
data->kb_led.name = "system76_acpi::kbd_backlight"; if (acpi_has_method(acpi_device_handle(data->acpi_dev), "GKBK")) {
data->kb_led.flags = LED_BRIGHT_HW_CHANGED | LED_CORE_SUSPENDRESUME; // Use the new ACPI methods
data->kb_led.brightness_get = kb_led_get; data->kbled_type = system76_get(data, "GKBK");
data->kb_led.brightness_set_blocking = kb_led_set;
if (acpi_has_method(acpi_device_handle(data->acpi_dev), "SKBC")) { switch (data->kbled_type) {
data->kb_led.max_brightness = 255; case KBLED_NONE:
data->kb_led.groups = system76_kb_led_color_groups; data->kb_led.max_brightness = 0;
data->kb_toggle_brightness = 72; data->kb_color = -1;
data->kb_color = 0xffffff; break;
system76_set(data, "SKBC", data->kb_color); case KBLED_WHITE:
data->kb_led.name = "system76_acpi::kbd_backlight";
data->kb_led.flags = LED_BRIGHT_HW_CHANGED | LED_CORE_SUSPENDRESUME;
data->kb_led.brightness_get = kb_led_get;
data->kb_led.brightness_set_blocking = kb_led_set;
data->kb_led.max_brightness = 255;
data->kb_toggle_brightness = 72;
data->kb_color = 0xffffff;
break;
case KBLED_RGB:
data->kb_led.name = "system76_acpi::kbd_backlight";
data->kb_led.flags = LED_BRIGHT_HW_CHANGED | LED_CORE_SUSPENDRESUME;
data->kb_led.brightness_get = kb_led_get;
data->kb_led.brightness_set_blocking = kb_led_set;
data->kb_led.max_brightness = 255;
data->kb_led.groups = system76_kb_led_color_groups;
data->kb_toggle_brightness = 72;
data->kb_color = 0xffffff;
system76_set(data, "SKBC", data->kb_color);
break;
}
} else { } else {
data->kb_led.max_brightness = 5; // Use the old ACPI methods
data->kb_color = -1; data->kb_led.name = "system76_acpi::kbd_backlight";
data->kb_led.flags = LED_BRIGHT_HW_CHANGED | LED_CORE_SUSPENDRESUME;
data->kb_led.brightness_get = kb_led_get;
data->kb_led.brightness_set_blocking = kb_led_set;
if (acpi_has_method(acpi_device_handle(data->acpi_dev), "SKBC")) {
data->kb_led.max_brightness = 255;
data->kb_led.groups = system76_kb_led_color_groups;
data->kb_toggle_brightness = 72;
data->kb_color = 0xffffff;
system76_set(data, "SKBC", data->kb_color);
} else {
data->kb_led.max_brightness = 5;
data->kb_color = -1;
}
} }
err = devm_led_classdev_register(&acpi_dev->dev, &data->kb_led); err = devm_led_classdev_register(&acpi_dev->dev, &data->kb_led);
if (err) if (err)
return err; return err;