From 71e6e93eb52397b24319be599bd0be9e5446148c Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 28 Mar 2019 09:54:34 -0600 Subject: [PATCH 1/3] Update the way touchpad is handled to use events from PS/2 instead of WMI --- debian/system76-dkms.install | 1 + lib/udev/hwdb.d/99-system76-dkms.hwdb | 3 +++ system76.c | 4 ++-- system76_input.c | 14 -------------- 4 files changed, 6 insertions(+), 16 deletions(-) create mode 100644 lib/udev/hwdb.d/99-system76-dkms.hwdb diff --git a/debian/system76-dkms.install b/debian/system76-dkms.install index 336a893..a040ca3 100644 --- a/debian/system76-dkms.install +++ b/debian/system76-dkms.install @@ -1 +1,2 @@ +lib/udev/hwdb.d usr/share/initramfs-tools diff --git a/lib/udev/hwdb.d/99-system76-dkms.hwdb b/lib/udev/hwdb.d/99-system76-dkms.hwdb new file mode 100644 index 0000000..0460d08 --- /dev/null +++ b/lib/udev/hwdb.d/99-system76-dkms.hwdb @@ -0,0 +1,3 @@ +evdev:atkbd:dmi:bvn*:bvr*:bd*:svnSystem76*:pn* + KEYBOARD_KEY_f7=f21 + KEYBOARD_KEY_f8=f21 diff --git a/system76.c b/system76.c index 49619a6..9ded30a 100644 --- a/system76.c +++ b/system76.c @@ -134,10 +134,10 @@ static void s76_wmi_notify(u32 value, void *context) { s76_input_airplane_wmi(); break; case 0xFC: - s76_input_touchpad_wmi(false); + // Touchpad WMI (disable) break; case 0xFD: - s76_input_touchpad_wmi(true); + // Touchpad WMI (enable) break; default: S76_DEBUG("Unknown WMI event code (%x)\n", event); diff --git a/system76_input.c b/system76_input.c index d230a97..1721ed6 100644 --- a/system76_input.c +++ b/system76_input.c @@ -20,8 +20,6 @@ */ #define AIRPLANE_KEY KEY_WLAN -#define TOUCHPAD_ON_KEY KEY_F21 -#define TOUCHPAD_OFF_KEY KEY_F21 static struct input_dev *s76_input_device; static DEFINE_MUTEX(s76_input_report_mutex); @@ -107,16 +105,6 @@ static void s76_input_airplane_wmi(void) { s76_input_key(AIRPLANE_KEY); } -static void s76_input_touchpad_wmi(bool enabled) { - S76_DEBUG("Touchpad Hotkey pressed (WMI) %d\n", enabled); - - if (enabled) { - s76_input_key(TOUCHPAD_ON_KEY); - } else { - s76_input_key(TOUCHPAD_OFF_KEY); - } -} - static int s76_input_open(struct input_dev *dev) { s76_input_polling_task = kthread_run( s76_input_polling_thread, @@ -156,8 +144,6 @@ static int __init s76_input_init(struct device *dev) { s76_input_device->dev.parent = dev; set_bit(EV_KEY, s76_input_device->evbit); set_bit(AIRPLANE_KEY, s76_input_device->keybit); - set_bit(TOUCHPAD_ON_KEY, s76_input_device->keybit); - set_bit(TOUCHPAD_OFF_KEY, s76_input_device->keybit); s76_input_device->open = s76_input_open; s76_input_device->close = s76_input_close; From 1425510cb55365e99dc42b85995325f870197e5a Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 29 Mar 2019 10:37:09 -0600 Subject: [PATCH 2/3] Add methods to disable unused driver functionality per model --- system76.c | 135 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 97 insertions(+), 38 deletions(-) diff --git a/system76.c b/system76.c index 9ded30a..3a073a5 100644 --- a/system76.c +++ b/system76.c @@ -58,6 +58,32 @@ /* method IDs for S76_GET */ #define GET_EVENT 0x01 /* 1 */ +struct s76_driver_data { + bool ap_led; + bool input; + bool kb_led; +}; + +static struct s76_driver_data driver_data_white_kb = { + .ap_led = true, + .input = true, + .kb_led = false, +}; + +static struct s76_driver_data driver_data_color_kb = { + .ap_led = true, + .input = true, + .kb_led = true, +}; + +static struct s76_driver_data driver_data_white_kb_hid = { + .ap_led = true, + .input = false, + .kb_led = false, +}; + +static struct s76_driver_data *driver_data = NULL; + struct platform_device *s76_platform_device; static int s76_wmbb(u32 method_id, u32 arg, u32 *retval) { @@ -113,13 +139,19 @@ static void s76_wmi_notify(u32 value, void *context) { switch (event) { case 0x81: - kb_wmi_dec(); + if (driver_data->kb_led) { + kb_wmi_dec(); + } break; case 0x82: - kb_wmi_inc(); + if (driver_data->kb_led) { + kb_wmi_inc(); + } break; case 0x83: - kb_wmi_color(); + if (driver_data->kb_led) { + kb_wmi_color(); + } break; case 0x7b: //TODO: Fn+Backspace @@ -128,10 +160,14 @@ static void s76_wmi_notify(u32 value, void *context) { //TODO: Fn+ESC break; case 0x9F: - kb_wmi_toggle(); + if (driver_data->kb_led) { + kb_wmi_toggle(); + } break; case 0xF4: - s76_input_airplane_wmi(); + if (driver_data->input) { + s76_input_airplane_wmi(); + } break; case 0xFC: // Touchpad WMI (disable) @@ -148,19 +184,25 @@ static void s76_wmi_notify(u32 value, void *context) { static int s76_probe(struct platform_device *dev) { int err; - err = ap_led_init(&dev->dev); - if (unlikely(err)) { - S76_ERROR("Could not register LED device\n"); + if (driver_data->ap_led) { + err = ap_led_init(&dev->dev); + if (unlikely(err)) { + S76_ERROR("Could not register LED device\n"); + } } - err = kb_led_init(&dev->dev); - if (unlikely(err)) { - S76_ERROR("Could not register LED device\n"); + if (driver_data->kb_led) { + err = kb_led_init(&dev->dev); + if (unlikely(err)) { + S76_ERROR("Could not register LED device\n"); + } } - err = s76_input_init(&dev->dev); - if (unlikely(err)) { - S76_ERROR("Could not register input device\n"); + if (driver_data->input) { + err = s76_input_init(&dev->dev); + if (unlikely(err)) { + S76_ERROR("Could not register input device\n"); + } } #ifdef S76_HAS_HWMON @@ -196,9 +238,15 @@ static int s76_remove(struct platform_device *dev) { #ifdef S76_HAS_HWMON s76_hwmon_fini(&dev->dev); #endif - s76_input_exit(); - kb_led_exit(); - ap_led_exit(); + if (driver_data->input) { + s76_input_exit(); + } + if (driver_data->kb_led) { + kb_led_exit(); + } + if (driver_data->ap_led) { + ap_led_exit(); + } return 0; } @@ -206,7 +254,9 @@ static int s76_remove(struct platform_device *dev) { static int s76_suspend(struct platform_device *dev, pm_message_t status) { S76_DEBUG("s76_suspend\n"); - kb_led_suspend(); + if (driver_data->kb_led) { + kb_led_suspend(); + } return 0; } @@ -216,8 +266,12 @@ static int s76_resume(struct platform_device *dev) { msleep(2000); - ap_led_resume(); - kb_led_resume(); + if (driver_data->ap_led) { + ap_led_resume(); + } + if (driver_data->kb_led) { + kb_led_resume(); + } // Enable hotkey support s76_wmbb(0x46, 0, NULL); @@ -242,12 +296,12 @@ static struct platform_driver s76_platform_driver = { static int __init s76_dmi_matched(const struct dmi_system_id *id) { S76_INFO("Model %s found\n", id->ident); - + driver_data = id->driver_data; return 1; } // Devices that did launch with DKMS support but have been updated with it -#define DMI_TABLE_LEGACY(PRODUCT) { \ +#define DMI_TABLE_LEGACY(PRODUCT, DATA) { \ .ident = "System76 " PRODUCT, \ .matches = { \ DMI_MATCH(DMI_SYS_VENDOR, "System76"), \ @@ -259,31 +313,31 @@ static int __init s76_dmi_matched(const struct dmi_system_id *id) { } // Devices that launched with DKMS support -#define DMI_TABLE(PRODUCT) { \ +#define DMI_TABLE(PRODUCT, DATA) { \ .ident = "System76 " PRODUCT, \ .matches = { \ DMI_MATCH(DMI_SYS_VENDOR, "System76"), \ DMI_MATCH(DMI_PRODUCT_VERSION, PRODUCT), \ }, \ .callback = s76_dmi_matched, \ - .driver_data = NULL, \ + .driver_data = &driver_data_ ## DATA, \ } static struct dmi_system_id s76_dmi_table[] __initdata = { - DMI_TABLE_LEGACY("bonw13"), - DMI_TABLE_LEGACY("galp2"), - DMI_TABLE_LEGACY("galp3"), - DMI_TABLE_LEGACY("serw11"), - DMI_TABLE("darp5"), - DMI_TABLE("galp3-b"), - DMI_TABLE("galp3-c"), - DMI_TABLE("gaze13"), - DMI_TABLE("kudu5"), - DMI_TABLE("oryp3-jeremy"), - DMI_TABLE("oryp4"), - DMI_TABLE("oryp4-b"), - DMI_TABLE("oryp5"), - DMI_TABLE("serw11-b"), + DMI_TABLE_LEGACY("bonw13", color_kb), + DMI_TABLE_LEGACY("galp2", white_kb), + DMI_TABLE_LEGACY("galp3", white_kb), + DMI_TABLE_LEGACY("serw11", color_kb), + DMI_TABLE("darp5", white_kb_hid), + DMI_TABLE("galp3-b", white_kb), + DMI_TABLE("galp3-c", white_kb_hid), + DMI_TABLE("gaze13", white_kb), + DMI_TABLE("kudu5", white_kb), + DMI_TABLE("oryp3-jeremy", color_kb), + DMI_TABLE("oryp4", color_kb), + DMI_TABLE("oryp4-b", color_kb), + DMI_TABLE("oryp5", color_kb), + DMI_TABLE("serw11-b", color_kb), {} }; @@ -295,6 +349,11 @@ static int __init s76_init(void) { return -ENODEV; } + if (!driver_data) { + S76_INFO("Driver data not defined"); + return -ENODEV; + } + if (!wmi_has_guid(S76_EVENT_GUID)) { S76_INFO("No known WMI event notification GUID found\n"); return -ENODEV; From b728a3db42c2337a985fa354c7ca105f6495d062 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 29 Mar 2019 11:30:03 -0600 Subject: [PATCH 3/3] Make oryp5 use HID airplane mode driver --- system76.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/system76.c b/system76.c index 3a073a5..2f46f10 100644 --- a/system76.c +++ b/system76.c @@ -70,16 +70,22 @@ static struct s76_driver_data driver_data_white_kb = { .kb_led = false, }; +static struct s76_driver_data driver_data_white_kb_hid = { + .ap_led = true, + .input = false, + .kb_led = false, +}; + static struct s76_driver_data driver_data_color_kb = { .ap_led = true, .input = true, .kb_led = true, }; -static struct s76_driver_data driver_data_white_kb_hid = { +static struct s76_driver_data driver_data_color_kb_hid = { .ap_led = true, .input = false, - .kb_led = false, + .kb_led = true, }; static struct s76_driver_data *driver_data = NULL; @@ -336,7 +342,7 @@ static struct dmi_system_id s76_dmi_table[] __initdata = { DMI_TABLE("oryp3-jeremy", color_kb), DMI_TABLE("oryp4", color_kb), DMI_TABLE("oryp4-b", color_kb), - DMI_TABLE("oryp5", color_kb), + DMI_TABLE("oryp5", color_kb_hid), DMI_TABLE("serw11-b", color_kb), {} };