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

3
debian/control vendored
View File

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

24
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 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); 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_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); input_sync(s76_input_device);
mutex_unlock(&s76_input_report_mutex); 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_INFO("Airplane-Mode Hotkey pressed (EC)\n");
s76_input_airplane_key(); s76_input_key(AIRPLANE_KEY);
} }
msleep_interruptible(1000 / param_poll_freq); msleep_interruptible(1000 / param_poll_freq);
@ -100,7 +102,17 @@ static void s76_input_airplane_wmi(void) {
s76_input_polling_task = NULL; 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) { static int s76_input_open(struct input_dev *dev) {
@ -142,6 +154,8 @@ static int __init s76_input_init(void) {
s76_input_device->dev.parent = &s76_platform_device->dev; s76_input_device->dev.parent = &s76_platform_device->dev;
set_bit(EV_KEY, s76_input_device->evbit); set_bit(EV_KEY, s76_input_device->evbit);
set_bit(AIRPLANE_KEY, s76_input_device->keybit); 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->open = s76_input_open;
s76_input_device->close = s76_input_close; s76_input_device->close = s76_input_close;

View File

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