diff --git a/src/uniwill_interfaces.h b/src/uniwill_interfaces.h index b2184bf..d222d52 100644 --- a/src/uniwill_interfaces.h +++ b/src/uniwill_interfaces.h @@ -19,6 +19,8 @@ #ifndef UNIWILL_INTERFACES_H #define UNIWILL_INTERFACES_H +#include + #define UNIWILL_WMI_MGMT_GUID_BA "ABBC0F6D-8EA1-11D1-00A0-C90629100000" #define UNIWILL_WMI_MGMT_GUID_BB "ABBC0F6E-8EA1-11D1-00A0-C90629100000" #define UNIWILL_WMI_MGMT_GUID_BC "ABBC0F6F-8EA1-11D1-00A0-C90629100000" @@ -31,4 +33,22 @@ MODULE_ALIAS("wmi:" UNIWILL_WMI_EVENT_GUID_2); \ MODULE_ALIAS("wmi:" UNIWILL_WMI_MGMT_GUID_BC); +#define UNIWILL_INTERFACE_WMI_STRID "uniwill_wmi" + +typedef u32 (uniwill_read_ec_ram_t)(u16, u8*); +typedef u32 (uniwill_write_ec_ram_t)(u16, u8); +typedef void (uniwill_event_callb_t)(u32); + +struct uniwill_interface_t { + char *string_id; + uniwill_event_callb_t *event_callb; + uniwill_read_ec_ram_t *read_ec_ram; + uniwill_write_ec_ram_t *write_ec_ram; +}; + +u32 uniwill_add_interface(struct uniwill_interface_t *new_interface); +u32 uniwill_remove_interface(struct uniwill_interface_t *interface); +uniwill_read_ec_ram_t uniwill_read_ec_ram; +uniwill_write_ec_ram_t uniwill_write_ec_ram; + #endif diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 39c04a0..1a25b79 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -1,5 +1,5 @@ /*! - * Copyright (c) 2020 TUXEDO Computers GmbH + * Copyright (c) 2020-2021 TUXEDO Computers GmbH * * This file is part of tuxedo-keyboard. * @@ -27,6 +27,7 @@ #include #include #include "uw_io.h" +#include "uniwill_interfaces.h" #define UNIWILL_WMI_MGMT_GUID_BA "ABBC0F6D-8EA1-11D1-00A0-C90629100000" #define UNIWILL_WMI_MGMT_GUID_BB "ABBC0F6E-8EA1-11D1-00A0-C90629100000" @@ -88,6 +89,69 @@ static struct key_entry uniwill_wmi_keymap[] = { { KE_END, 0 } }; +static struct uniwill_interfaces_t { + struct uniwill_interface_t *wmi; +} uniwill_interfaces; + +uniwill_event_callb_t uniwill_event_callb; + +u32 uniwill_read_ec_ram(u16 address, u8 *data) +{ + if (!IS_ERR_OR_NULL(uniwill_interfaces.wmi)) + uniwill_interfaces.wmi->read_ec_ram(address, data); + else + return -EIO; + + return 0; +} +EXPORT_SYMBOL(uniwill_read_ec_ram); + +u32 uniwill_write_ec_ram(u16 address, u8 data) +{ + if (!IS_ERR_OR_NULL(uniwill_interfaces.wmi)) + uniwill_interfaces.wmi->write_ec_ram(address, data); + else + return -EIO; + + return 0; +} +EXPORT_SYMBOL(uniwill_write_ec_ram); + +static DEFINE_MUTEX(uniwill_interface_modification_lock); + +u32 uniwill_add_interface(struct uniwill_interface_t *interface) +{ + mutex_lock(&uniwill_interface_modification_lock); + + if (strcmp(interface->string_id, UNIWILL_INTERFACE_WMI_STRID)) + uniwill_interfaces.wmi = interface; + else { + mutex_unlock(&uniwill_interface_modification_lock); + return -EINVAL; + + interface->event_callb = uniwill_event_callb; + + mutex_unlock(&uniwill_interface_modification_lock); + return 0; +} +EXPORT_SYMBOL(uniwill_add_interface); + +u32 uniwill_remove_interface(struct uniwill_interface_t *interface) +{ + mutex_lock(&uniwill_interface_modification_lock); + + if (strcmp(interface->string_id, UNIWILL_INTERFACE_WMI_STRID)) + uniwill_interfaces.wmi = NULL; + else { + mutex_unlock(&uniwill_interface_modification_lock); + return -EINVAL; + } + + mutex_unlock(&uniwill_interface_modification_lock); + return 0; +} +EXPORT_SYMBOL(uniwill_remove_interface); + static void key_event_work(struct work_struct *work) { sparse_keymap_report_known_event( @@ -228,6 +292,55 @@ static void uniwill_write_kbd_bl_reset(void) __uw_ec_write_addr(0x8c, 0x07, 0x10, 0x00, ®_write_return); } +void uniwill_event_callb(u32 code) +{ + if (!sparse_keymap_report_known_event(uniwill_keyboard_driver.input_device, code, 1, true)) { + TUXEDO_DEBUG("Unknown code - %d (%0#6x)\n", code, code); + } + + // Special key combination when mode change key is pressed + if (code == 0xb0) { + input_report_key(uniwill_keyboard_driver.input_device, KEY_LEFTMETA, 1); + input_report_key(uniwill_keyboard_driver.input_device, KEY_LEFTALT, 1); + input_report_key(uniwill_keyboard_driver.input_device, KEY_F6, 1); + input_sync(uniwill_keyboard_driver.input_device); + input_report_key(uniwill_keyboard_driver.input_device, KEY_F6, 0); + input_report_key(uniwill_keyboard_driver.input_device, KEY_LEFTALT, 0); + input_report_key(uniwill_keyboard_driver.input_device, KEY_LEFTMETA, 0); + input_sync(uniwill_keyboard_driver.input_device); + } + + // Keyboard backlight brightness toggle + if (uniwill_kbd_bl_type_rgb_single_color) { + switch (code) { + case UNIWILL_OSD_KB_LED_LEVEL0: + kbd_led_state_uw.brightness = 0x00; + uniwill_write_kbd_bl_state(); + break; + case UNIWILL_OSD_KB_LED_LEVEL1: + kbd_led_state_uw.brightness = 0x20; + uniwill_write_kbd_bl_state(); + break; + case UNIWILL_OSD_KB_LED_LEVEL2: + kbd_led_state_uw.brightness = 0x50; + uniwill_write_kbd_bl_state(); + break; + case UNIWILL_OSD_KB_LED_LEVEL3: + kbd_led_state_uw.brightness = 0x80; + uniwill_write_kbd_bl_state(); + break; + case UNIWILL_OSD_KB_LED_LEVEL4: + kbd_led_state_uw.brightness = 0xc8; + uniwill_write_kbd_bl_state(); + break; + // Also refresh keyboard state on cable switch event + case UNIWILL_OSD_DC_ADAPTER_CHANGE: + uniwill_write_kbd_bl_state(); + break; + } + } +} + static void uniwill_wmi_handle_event(u32 value, void *context, u32 guid_nr) { struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; @@ -246,51 +359,7 @@ static void uniwill_wmi_handle_event(u32 value, void *context, u32 guid_nr) if (obj) { if (obj->type == ACPI_TYPE_INTEGER) { code = obj->integer.value; - if (!sparse_keymap_report_known_event(uniwill_keyboard_driver.input_device, code, 1, true)) { - TUXEDO_DEBUG("[Ev %d] Unknown key - %d (%0#6x)\n", guid_nr, code, code); - } - - // Special key combination when mode change key is pressed - if (code == 0xb0) { - input_report_key(uniwill_keyboard_driver.input_device, KEY_LEFTMETA, 1); - input_report_key(uniwill_keyboard_driver.input_device, KEY_LEFTALT, 1); - input_report_key(uniwill_keyboard_driver.input_device, KEY_F6, 1); - input_sync(uniwill_keyboard_driver.input_device); - input_report_key(uniwill_keyboard_driver.input_device, KEY_F6, 0); - input_report_key(uniwill_keyboard_driver.input_device, KEY_LEFTALT, 0); - input_report_key(uniwill_keyboard_driver.input_device, KEY_LEFTMETA, 0); - input_sync(uniwill_keyboard_driver.input_device); - } - - // Keyboard backlight brightness toggle - if (uniwill_kbd_bl_type_rgb_single_color) { - switch (code) { - case UNIWILL_OSD_KB_LED_LEVEL0: - kbd_led_state_uw.brightness = 0x00; - uniwill_write_kbd_bl_state(); - break; - case UNIWILL_OSD_KB_LED_LEVEL1: - kbd_led_state_uw.brightness = 0x20; - uniwill_write_kbd_bl_state(); - break; - case UNIWILL_OSD_KB_LED_LEVEL2: - kbd_led_state_uw.brightness = 0x50; - uniwill_write_kbd_bl_state(); - break; - case UNIWILL_OSD_KB_LED_LEVEL3: - kbd_led_state_uw.brightness = 0x80; - uniwill_write_kbd_bl_state(); - break; - case UNIWILL_OSD_KB_LED_LEVEL4: - kbd_led_state_uw.brightness = 0xc8; - uniwill_write_kbd_bl_state(); - break; - // Also refresh keyboard state on cable switch event - case UNIWILL_OSD_DC_ADAPTER_CHANGE: - uniwill_write_kbd_bl_state(); - break; - } - } + uniwill_event_callb(code); } else { TUXEDO_DEBUG("[Ev %d] Unknown event type - %d (%0#6x)\n", guid_nr, obj->type, obj->type); } diff --git a/src/uniwill_wmi.c b/src/uniwill_wmi.c index f3a839a..c775a07 100644 --- a/src/uniwill_wmi.c +++ b/src/uniwill_wmi.c @@ -92,7 +92,10 @@ static const struct wmi_device_id uniwill_wmi_device_ids[] = { }; static struct wmi_driver uniwill_wmi_driver = { - .driver = { .name = "uniwill_wmi", .owner = THIS_MODULE }, + .driver = { + .name = UNIWILL_INTERFACE_WMI_STRID, + .owner = THIS_MODULE + }, .id_table = uniwill_wmi_device_ids, .probe = uniwill_wmi_probe, .remove = uniwill_wmi_remove,