Add touchpad lock code, fixes for new laptops

This commit is contained in:
Jeremy Soller 2018-02-08 17:08:07 -07:00
parent 1cc36c89ec
commit fb11bf952b
3 changed files with 47 additions and 23 deletions

5
debian/control vendored
View File

@ -10,8 +10,7 @@ Homepage: https://github.com/pop-os/system76-dkms
Package: system76-dkms
Architecture: amd64
Depends: system76-driver,
${misc:Depends}
Depends: ${misc:Depends}
Description: System76 DKMS driver
This DKMS driver provides airplane mode, keyboard backlight, and fan support
for System76 laptops
for System76 laptops

36
input.c
View File

@ -55,13 +55,15 @@ MODULE_PARM_DESC(poll_freq, "Set polling frequency");
static struct task_struct *s76_input_polling_task;
static void s76_input_airplane_key(void) {
static void s76_input_key(unsigned int code) {
S76_INFO("Send key %x\n", code);
mutex_lock(&s76_input_report_mutex);
input_report_key(s76_input_device, AIRPLANE_KEY, 1);
input_report_key(s76_input_device, code, 1);
input_sync(s76_input_device);
input_report_key(s76_input_device, AIRPLANE_KEY, 0);
input_report_key(s76_input_device, code, 0);
input_sync(s76_input_device);
mutex_unlock(&s76_input_report_mutex);
@ -80,7 +82,7 @@ static int s76_input_polling_thread(void *data) {
S76_INFO("Airplane-Mode Hotkey pressed (EC)\n");
s76_input_airplane_key();
s76_input_key(AIRPLANE_KEY);
}
msleep_interruptible(1000 / param_poll_freq);
@ -93,14 +95,24 @@ static int s76_input_polling_thread(void *data) {
static void s76_input_airplane_wmi(void) {
S76_INFO("Airplane-Mode Hotkey pressed (WMI)\n");
if (s76_input_polling_task) {
S76_INFO("Stopping polling thread\n");
kthread_stop(s76_input_polling_task);
s76_input_polling_task = NULL;
}
s76_input_airplane_key();
s76_input_key(AIRPLANE_KEY);
}
static void s76_input_touchpad_wmi(bool enabled) {
S76_INFO("Touchpad Hotkey pressed (WMI) %d\n", enabled);
if (enabled) {
s76_input_key(KEY_TOUCHPAD_ON);
} else {
s76_input_key(KEY_TOUCHPAD_OFF);
}
}
static int s76_input_open(struct input_dev *dev) {
@ -142,7 +154,9 @@ static int __init s76_input_init(void) {
s76_input_device->dev.parent = &s76_platform_device->dev;
set_bit(EV_KEY, s76_input_device->evbit);
set_bit(AIRPLANE_KEY, s76_input_device->keybit);
set_bit(KEY_TOUCHPAD_ON, s76_input_device->keybit);
set_bit(KEY_TOUCHPAD_OFF, s76_input_device->keybit);
s76_input_device->open = s76_input_open;
s76_input_device->close = s76_input_close;
@ -170,4 +184,4 @@ static void __exit s76_input_exit(void) {
input_unregister_device(s76_input_device);
s76_input_device = NULL;
}
}

View File

@ -27,6 +27,7 @@
#include <linux/dmi.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/i8042.h>
#include <linux/input.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
@ -47,7 +48,7 @@
__func__, __LINE__, ##__VA_ARGS__)
#define S76_EVENT_GUID "ABBC0F6B-8EA1-11D1-00A0-C90629100000"
#define S76_GET_GUID "ABBC0F6D-8EA1-11D1-00A0-C90629100000"
#define S76_WMBB_GUID "ABBC0F6D-8EA1-11D1-00A0-C90629100000"
#define S76_HAS_HWMON (defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)))
@ -63,9 +64,9 @@ static int s76_wmbb(u32 method_id, u32 arg, u32 *retval) {
acpi_status status;
u32 tmp;
S76_DEBUG("%0#4x IN : %0#6x\n", method_id, arg);
S76_INFO("%0#4x IN : %0#6x\n", method_id, arg);
status = wmi_evaluate_method(S76_GET_GUID, 0x01, method_id, &in, &out);
status = wmi_evaluate_method(S76_WMBB_GUID, 0, method_id, &in, &out);
if (unlikely(ACPI_FAILURE(status))) {
return -EIO;
@ -78,7 +79,7 @@ static int s76_wmbb(u32 method_id, u32 arg, u32 *retval) {
tmp = 0;
}
S76_DEBUG("%0#4x OUT: %0#6x (IN: %0#6x)\n", method_id, tmp, arg);
S76_INFO("%0#4x OUT: %0#6x (IN: %0#6x)\n", method_id, tmp, arg);
if (likely(retval)) {
*retval = tmp;
@ -111,6 +112,12 @@ static void s76_wmi_notify(u32 value, void *context) {
case 0xF4:
s76_input_airplane_wmi();
break;
case 0xFC:
s76_input_touchpad_wmi(false);
break;
case 0xFD:
s76_input_touchpad_wmi(true);
break;
default:
kb_wmi(event);
break;
@ -129,6 +136,11 @@ static int s76_probe(struct platform_device *dev) {
// Enable hotkey support
s76_wmbb(0x46, 0, NULL);
// Enable touchpad lock
i8042_lock_chip();
i8042_command(NULL, 0x97);
i8042_unlock_chip();
if (kb_backlight.ops) {
kb_backlight.ops->init();
}
@ -172,16 +184,15 @@ static int __init s76_dmi_matched(const struct dmi_system_id *id) {
#define DMI_TABLE(PRODUCT, DATA) { \
.ident = "System76 " PRODUCT, \
.matches = { \
DMI_MATCH(DMI_SYS_VENDOR, "System76"), \
DMI_MATCH(DMI_PRODUCT_VERSION, PRODUCT), \
DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), \
DMI_MATCH(DMI_PRODUCT_NAME, PRODUCT), \
}, \
.callback = s76_dmi_matched, \
.driver_data = DATA, \
}
static struct dmi_system_id s76_dmi_table[] __initdata = {
DMI_TABLE("bonw13", &kb_full_color_with_extra_ops),
DMI_TABLE("oryp3-b", &kb_full_color_ops),
DMI_TABLE("P95_HP", &kb_full_color_ops),
{}
};
@ -205,7 +216,7 @@ static int __init s76_init(void) {
return -ENODEV;
}
if (!wmi_has_guid(S76_GET_GUID)) {
if (!wmi_has_guid(S76_WMBB_GUID)) {
S76_INFO("No known WMI control method GUID found\n");
return -ENODEV;
}