Add serw14 with hack
The WMI interface is deprecated and does not work on serw14. Hack in a call to the underlying ECMD to fix it for now. Signed-off-by: Tim Crawford <tcrawford@system76.com>
This commit is contained in:
parent
f886317ae8
commit
af173d245a
78
src/kb-led.c
78
src/kb-led.c
|
|
@ -72,11 +72,11 @@ static int kb_led_set(struct led_classdev *led_cdev, enum led_brightness value)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kb_led_color_set(enum kb_led_region region, union kb_led_color color)
|
static void kb_led_color_set_wmi(enum kb_led_region region, union kb_led_color color)
|
||||||
{
|
{
|
||||||
u32 cmd;
|
u32 cmd;
|
||||||
|
|
||||||
pr_debug("kb_led_color_set %d %06X\n", (int)region, (int)color.rgb);
|
pr_debug("%s %d %06X\n", __func__, (int)region, (int)color.rgb);
|
||||||
|
|
||||||
switch (region) {
|
switch (region) {
|
||||||
case KB_LED_REGION_LEFT:
|
case KB_LED_REGION_LEFT:
|
||||||
|
|
@ -104,6 +104,71 @@ static void kb_led_color_set(enum kb_led_region region, union kb_led_color color
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HACK: Directly call ECMD to fix serw14
|
||||||
|
static void kb_led_color_set(enum kb_led_region region, union kb_led_color color)
|
||||||
|
{
|
||||||
|
struct acpi_object_list input;
|
||||||
|
union acpi_object obj;
|
||||||
|
acpi_handle handle;
|
||||||
|
acpi_status status;
|
||||||
|
u8 *buf;
|
||||||
|
|
||||||
|
buf = (u8 *)kzalloc(8, GFP_KERNEL);
|
||||||
|
|
||||||
|
pr_debug("%s %d %06X\n", __func__, (int)region, (int)color.rgb);
|
||||||
|
|
||||||
|
buf[0] = 5;
|
||||||
|
buf[2] = 0xCA;
|
||||||
|
buf[4] = color.b;
|
||||||
|
buf[5] = color.r;
|
||||||
|
buf[6] = color.g;
|
||||||
|
|
||||||
|
switch (region) {
|
||||||
|
case KB_LED_REGION_LEFT:
|
||||||
|
buf[3] = 0x03;
|
||||||
|
break;
|
||||||
|
case KB_LED_REGION_CENTER:
|
||||||
|
buf[3] = 0x04;
|
||||||
|
break;
|
||||||
|
case KB_LED_REGION_RIGHT:
|
||||||
|
buf[3] = 0x05;
|
||||||
|
break;
|
||||||
|
case KB_LED_REGION_EXTRA:
|
||||||
|
buf[3] = 0x0B;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.type = ACPI_TYPE_BUFFER;
|
||||||
|
obj.buffer.length = 8;
|
||||||
|
obj.buffer.pointer = buf;
|
||||||
|
|
||||||
|
input.count = 1;
|
||||||
|
input.pointer = &obj;
|
||||||
|
|
||||||
|
status = acpi_get_handle(NULL, (acpi_string)"\\_SB.PC00.LPCB.EC", &handle);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
pr_err("%s failed to get handle: %x\n", __func__, status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = acpi_evaluate_object(handle, "ECMD", &input, NULL);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
pr_err("%s failed to call EC_CMD: %x\n", __func__, status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update lightbar to match keyboard color
|
||||||
|
buf[3] = 0x07;
|
||||||
|
status = acpi_evaluate_object(handle, "ECMD", &input, NULL);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
pr_err("%s failed to call EC_CMD: %x\n", __func__, status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(buf);
|
||||||
|
kb_led_regions[region] = color;
|
||||||
|
}
|
||||||
|
|
||||||
static struct led_classdev kb_led = {
|
static struct led_classdev kb_led = {
|
||||||
.name = "system76::kbd_backlight",
|
.name = "system76::kbd_backlight",
|
||||||
.flags = LED_BRIGHT_HW_CHANGED,
|
.flags = LED_BRIGHT_HW_CHANGED,
|
||||||
|
|
@ -129,6 +194,9 @@ static ssize_t kb_led_color_store(enum kb_led_region region, const char *buf, si
|
||||||
}
|
}
|
||||||
|
|
||||||
color.rgb = (u32)val;
|
color.rgb = (u32)val;
|
||||||
|
if (driver_flags & DRIVER_KB_LED_WMI)
|
||||||
|
kb_led_color_set_wmi(region, color);
|
||||||
|
else
|
||||||
kb_led_color_set(region, color);
|
kb_led_color_set(region, color);
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
|
|
@ -243,6 +311,9 @@ static void kb_led_resume(void)
|
||||||
|
|
||||||
// Reset current color
|
// Reset current color
|
||||||
for (region = 0; region < sizeof(kb_led_regions)/sizeof(union kb_led_color); region++) {
|
for (region = 0; region < sizeof(kb_led_regions)/sizeof(union kb_led_color); region++) {
|
||||||
|
if (driver_flags & DRIVER_KB_LED_WMI)
|
||||||
|
kb_led_color_set_wmi(region, kb_led_regions[region]);
|
||||||
|
else
|
||||||
kb_led_color_set(region, kb_led_regions[region]);
|
kb_led_color_set(region, kb_led_regions[region]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -355,6 +426,9 @@ static void kb_wmi_color(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (region = 0; region < sizeof(kb_led_regions)/sizeof(union kb_led_color); region++) {
|
for (region = 0; region < sizeof(kb_led_regions)/sizeof(union kb_led_color); region++) {
|
||||||
|
if (driver_flags & DRIVER_KB_LED_WMI)
|
||||||
|
kb_led_color_set_wmi(region, kb_led_colors[kb_led_colors_i]);
|
||||||
|
else
|
||||||
kb_led_color_set(region, kb_led_colors[kb_led_colors_i]);
|
kb_led_color_set(region, kb_led_colors[kb_led_colors_i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,9 +54,10 @@
|
||||||
#define DRIVER_AP_KEY (1 << 0)
|
#define DRIVER_AP_KEY (1 << 0)
|
||||||
#define DRIVER_AP_LED (1 << 1)
|
#define DRIVER_AP_LED (1 << 1)
|
||||||
#define DRIVER_HWMON (1 << 2)
|
#define DRIVER_HWMON (1 << 2)
|
||||||
#define DRIVER_KB_LED (1 << 3)
|
#define DRIVER_KB_LED_WMI (1 << 3)
|
||||||
#define DRIVER_OLED (1 << 4)
|
#define DRIVER_OLED (1 << 4)
|
||||||
#define DRIVER_AP_WMI (1 << 5)
|
#define DRIVER_AP_WMI (1 << 5)
|
||||||
|
#define DRIVER_KB_LED (1 << 6)
|
||||||
|
|
||||||
#define DRIVER_INPUT (DRIVER_AP_KEY | DRIVER_OLED)
|
#define DRIVER_INPUT (DRIVER_AP_KEY | DRIVER_OLED)
|
||||||
|
|
||||||
|
|
@ -130,17 +131,17 @@ static void s76_wmi_notify(u32 value, void *context)
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case 0x81:
|
case 0x81:
|
||||||
if (driver_flags & DRIVER_KB_LED) {
|
if (driver_flags & (DRIVER_KB_LED_WMI | DRIVER_KB_LED)) {
|
||||||
kb_wmi_dec();
|
kb_wmi_dec();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x82:
|
case 0x82:
|
||||||
if (driver_flags & DRIVER_KB_LED) {
|
if (driver_flags & (DRIVER_KB_LED_WMI | DRIVER_KB_LED)) {
|
||||||
kb_wmi_inc();
|
kb_wmi_inc();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x83:
|
case 0x83:
|
||||||
if (driver_flags & DRIVER_KB_LED) {
|
if (driver_flags & (DRIVER_KB_LED_WMI | DRIVER_KB_LED)) {
|
||||||
kb_wmi_color();
|
kb_wmi_color();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -151,7 +152,7 @@ static void s76_wmi_notify(u32 value, void *context)
|
||||||
//TODO: Fn+ESC
|
//TODO: Fn+ESC
|
||||||
break;
|
break;
|
||||||
case 0x9F:
|
case 0x9F:
|
||||||
if (driver_flags & DRIVER_KB_LED) {
|
if (driver_flags & (DRIVER_KB_LED_WMI | DRIVER_KB_LED)) {
|
||||||
kb_wmi_toggle();
|
kb_wmi_toggle();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -189,7 +190,7 @@ static int __init s76_probe(struct platform_device *dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (driver_flags & DRIVER_KB_LED) {
|
if (driver_flags & (DRIVER_KB_LED_WMI | DRIVER_KB_LED)) {
|
||||||
err = kb_led_init(&dev->dev);
|
err = kb_led_init(&dev->dev);
|
||||||
if (unlikely(err)) {
|
if (unlikely(err)) {
|
||||||
pr_err("Could not register LED device\n");
|
pr_err("Could not register LED device\n");
|
||||||
|
|
@ -248,7 +249,7 @@ static int s76_remove(struct platform_device *dev)
|
||||||
if (driver_flags & DRIVER_INPUT) {
|
if (driver_flags & DRIVER_INPUT) {
|
||||||
s76_input_exit();
|
s76_input_exit();
|
||||||
}
|
}
|
||||||
if (driver_flags & DRIVER_KB_LED) {
|
if (driver_flags & (DRIVER_KB_LED_WMI | DRIVER_KB_LED)) {
|
||||||
kb_led_exit();
|
kb_led_exit();
|
||||||
}
|
}
|
||||||
if (driver_flags & DRIVER_AP_LED) {
|
if (driver_flags & DRIVER_AP_LED) {
|
||||||
|
|
@ -264,7 +265,7 @@ static int s76_suspend(struct platform_device *dev, pm_message_t status)
|
||||||
{
|
{
|
||||||
pr_debug("s76_suspend\n");
|
pr_debug("s76_suspend\n");
|
||||||
|
|
||||||
if (driver_flags & DRIVER_KB_LED) {
|
if (driver_flags & (DRIVER_KB_LED_WMI | DRIVER_KB_LED)) {
|
||||||
kb_led_suspend();
|
kb_led_suspend();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -280,7 +281,7 @@ static int s76_resume(struct platform_device *dev)
|
||||||
if (driver_flags & DRIVER_AP_LED) {
|
if (driver_flags & DRIVER_AP_LED) {
|
||||||
ap_led_resume();
|
ap_led_resume();
|
||||||
}
|
}
|
||||||
if (driver_flags & DRIVER_KB_LED) {
|
if (driver_flags & (DRIVER_KB_LED_WMI | DRIVER_KB_LED)) {
|
||||||
kb_led_resume();
|
kb_led_resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -334,36 +335,36 @@ static int __init s76_dmi_matched(const struct dmi_system_id *id)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dmi_system_id s76_dmi_table[] __initdata = {
|
static struct dmi_system_id s76_dmi_table[] __initdata = {
|
||||||
DMI_TABLE_LEGACY("bonw13", DRIVER_HWMON | DRIVER_KB_LED),
|
DMI_TABLE_LEGACY("bonw13", DRIVER_HWMON | DRIVER_KB_LED_WMI),
|
||||||
DMI_TABLE("addw1", DRIVER_AP_LED | DRIVER_KB_LED | DRIVER_OLED),
|
DMI_TABLE("addw1", DRIVER_AP_LED | DRIVER_KB_LED_WMI | DRIVER_OLED),
|
||||||
DMI_TABLE("addw2", DRIVER_AP_LED | DRIVER_KB_LED | DRIVER_OLED),
|
DMI_TABLE("addw2", DRIVER_AP_LED | DRIVER_KB_LED_WMI | DRIVER_OLED),
|
||||||
DMI_TABLE("bonw15-b", DRIVER_HWMON | DRIVER_KB_LED),
|
DMI_TABLE("bonw15-b", DRIVER_HWMON | DRIVER_KB_LED_WMI),
|
||||||
DMI_TABLE("bonw16", DRIVER_HWMON | DRIVER_KB_LED),
|
DMI_TABLE("bonw16", DRIVER_HWMON | DRIVER_KB_LED_WMI),
|
||||||
DMI_TABLE("darp5", DRIVER_AP_LED | DRIVER_HWMON | DRIVER_KB_LED),
|
DMI_TABLE("darp5", DRIVER_AP_LED | DRIVER_HWMON | DRIVER_KB_LED_WMI),
|
||||||
DMI_TABLE("darp6", DRIVER_AP_LED | DRIVER_HWMON | DRIVER_KB_LED),
|
DMI_TABLE("darp6", DRIVER_AP_LED | DRIVER_HWMON | DRIVER_KB_LED_WMI),
|
||||||
DMI_TABLE("galp2", DRIVER_HWMON),
|
DMI_TABLE("galp2", DRIVER_HWMON),
|
||||||
DMI_TABLE("galp3", DRIVER_HWMON),
|
DMI_TABLE("galp3", DRIVER_HWMON),
|
||||||
DMI_TABLE("galp3-b", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_HWMON),
|
DMI_TABLE("galp3-b", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_HWMON),
|
||||||
DMI_TABLE("galp3-c", DRIVER_AP_LED | DRIVER_HWMON),
|
DMI_TABLE("galp3-c", DRIVER_AP_LED | DRIVER_HWMON),
|
||||||
DMI_TABLE("galp4", DRIVER_AP_LED | DRIVER_HWMON),
|
DMI_TABLE("galp4", DRIVER_AP_LED | DRIVER_HWMON),
|
||||||
DMI_TABLE("gaze13", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_HWMON),
|
DMI_TABLE("gaze13", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_HWMON),
|
||||||
DMI_TABLE("gaze14", DRIVER_AP_LED | DRIVER_KB_LED),
|
DMI_TABLE("gaze14", DRIVER_AP_LED | DRIVER_KB_LED_WMI),
|
||||||
DMI_TABLE("gaze15", DRIVER_AP_LED | DRIVER_KB_LED),
|
DMI_TABLE("gaze15", DRIVER_AP_LED | DRIVER_KB_LED_WMI),
|
||||||
DMI_TABLE("kudu5", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_HWMON),
|
DMI_TABLE("kudu5", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_HWMON),
|
||||||
DMI_TABLE("kudu6", DRIVER_AP_KEY | DRIVER_AP_WMI | DRIVER_KB_LED),
|
DMI_TABLE("kudu6", DRIVER_AP_KEY | DRIVER_AP_WMI | DRIVER_KB_LED_WMI),
|
||||||
DMI_TABLE("oryp3-jeremy", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_HWMON | DRIVER_KB_LED),
|
DMI_TABLE("oryp3-jeremy", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_HWMON | DRIVER_KB_LED_WMI),
|
||||||
DMI_TABLE("oryp4", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_HWMON | DRIVER_KB_LED),
|
DMI_TABLE("oryp4", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_HWMON | DRIVER_KB_LED_WMI),
|
||||||
DMI_TABLE("oryp4-b", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_HWMON | DRIVER_KB_LED),
|
DMI_TABLE("oryp4-b", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_HWMON | DRIVER_KB_LED_WMI),
|
||||||
DMI_TABLE("oryp5", DRIVER_AP_LED | DRIVER_HWMON | DRIVER_KB_LED),
|
DMI_TABLE("oryp5", DRIVER_AP_LED | DRIVER_HWMON | DRIVER_KB_LED_WMI),
|
||||||
DMI_TABLE("oryp6", DRIVER_AP_LED | DRIVER_KB_LED),
|
DMI_TABLE("oryp6", DRIVER_AP_LED | DRIVER_KB_LED_WMI),
|
||||||
DMI_TABLE("pang10", DRIVER_AP_KEY | DRIVER_AP_WMI | DRIVER_KB_LED),
|
DMI_TABLE("pang10", DRIVER_AP_KEY | DRIVER_AP_WMI | DRIVER_KB_LED_WMI),
|
||||||
DMI_TABLE("pang11", DRIVER_AP_KEY | DRIVER_AP_WMI | DRIVER_KB_LED),
|
DMI_TABLE("pang11", DRIVER_AP_KEY | DRIVER_AP_WMI | DRIVER_KB_LED_WMI),
|
||||||
DMI_TABLE("serw11", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_HWMON | DRIVER_KB_LED),
|
DMI_TABLE("serw11", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_HWMON | DRIVER_KB_LED_WMI),
|
||||||
DMI_TABLE("serw11-b", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_HWMON | DRIVER_KB_LED),
|
DMI_TABLE("serw11-b", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_HWMON | DRIVER_KB_LED_WMI),
|
||||||
DMI_TABLE("serw12", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_AP_WMI | DRIVER_KB_LED),
|
DMI_TABLE("serw12", DRIVER_AP_KEY | DRIVER_AP_LED | DRIVER_AP_WMI | DRIVER_KB_LED_WMI),
|
||||||
|
DMI_TABLE("serw14", DRIVER_HWMON | DRIVER_KB_LED),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
MODULE_DEVICE_TABLE(dmi, s76_dmi_table);
|
MODULE_DEVICE_TABLE(dmi, s76_dmi_table);
|
||||||
|
|
||||||
static int __init s76_init(void)
|
static int __init s76_init(void)
|
||||||
|
|
@ -397,14 +398,13 @@ static int __init s76_init(void)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
module_init(s76_init);
|
||||||
|
|
||||||
static void __exit s76_exit(void)
|
static void __exit s76_exit(void)
|
||||||
{
|
{
|
||||||
platform_device_unregister(s76_platform_device);
|
platform_device_unregister(s76_platform_device);
|
||||||
platform_driver_unregister(&s76_platform_driver);
|
platform_driver_unregister(&s76_platform_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(s76_init);
|
|
||||||
module_exit(s76_exit);
|
module_exit(s76_exit);
|
||||||
|
|
||||||
MODULE_AUTHOR("Jeremy Soller <jeremy@system76.com>");
|
MODULE_AUTHOR("Jeremy Soller <jeremy@system76.com>");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue