Add uniwill interface methods

This commit is contained in:
Christoffer Sandberg 2021-09-07 21:44:00 +02:00
parent 9db498b836
commit 54c6da280e
3 changed files with 139 additions and 47 deletions

View file

@ -19,6 +19,8 @@
#ifndef UNIWILL_INTERFACES_H #ifndef UNIWILL_INTERFACES_H
#define UNIWILL_INTERFACES_H #define UNIWILL_INTERFACES_H
#include <linux/types.h>
#define UNIWILL_WMI_MGMT_GUID_BA "ABBC0F6D-8EA1-11D1-00A0-C90629100000" #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_BB "ABBC0F6E-8EA1-11D1-00A0-C90629100000"
#define UNIWILL_WMI_MGMT_GUID_BC "ABBC0F6F-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_EVENT_GUID_2); \
MODULE_ALIAS("wmi:" UNIWILL_WMI_MGMT_GUID_BC); 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 #endif

View file

@ -1,5 +1,5 @@
/*! /*!
* Copyright (c) 2020 TUXEDO Computers GmbH <tux@tuxedocomputers.com> * Copyright (c) 2020-2021 TUXEDO Computers GmbH <tux@tuxedocomputers.com>
* *
* This file is part of tuxedo-keyboard. * This file is part of tuxedo-keyboard.
* *
@ -27,6 +27,7 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/version.h> #include <linux/version.h>
#include "uw_io.h" #include "uw_io.h"
#include "uniwill_interfaces.h"
#define UNIWILL_WMI_MGMT_GUID_BA "ABBC0F6D-8EA1-11D1-00A0-C90629100000" #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_BB "ABBC0F6E-8EA1-11D1-00A0-C90629100000"
@ -88,6 +89,69 @@ static struct key_entry uniwill_wmi_keymap[] = {
{ KE_END, 0 } { 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) static void key_event_work(struct work_struct *work)
{ {
sparse_keymap_report_known_event( sparse_keymap_report_known_event(
@ -228,26 +292,10 @@ static void uniwill_write_kbd_bl_reset(void)
__uw_ec_write_addr(0x8c, 0x07, 0x10, 0x00, &reg_write_return); __uw_ec_write_addr(0x8c, 0x07, 0x10, 0x00, &reg_write_return);
} }
static void uniwill_wmi_handle_event(u32 value, void *context, u32 guid_nr) void uniwill_event_callb(u32 code)
{ {
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj;
acpi_status status;
int code;
status = wmi_get_event_data(value, &response);
if (status != AE_OK) {
TUXEDO_ERROR("uniwill handle event -> bad event status\n");
return;
}
obj = (union acpi_object *) response.pointer;
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)) { 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); TUXEDO_DEBUG("Unknown code - %d (%0#6x)\n", code, code);
} }
// Special key combination when mode change key is pressed // Special key combination when mode change key is pressed
@ -291,6 +339,27 @@ static void uniwill_wmi_handle_event(u32 value, void *context, u32 guid_nr)
break; break;
} }
} }
}
static void uniwill_wmi_handle_event(u32 value, void *context, u32 guid_nr)
{
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj;
acpi_status status;
int code;
status = wmi_get_event_data(value, &response);
if (status != AE_OK) {
TUXEDO_ERROR("uniwill handle event -> bad event status\n");
return;
}
obj = (union acpi_object *) response.pointer;
if (obj) {
if (obj->type == ACPI_TYPE_INTEGER) {
code = obj->integer.value;
uniwill_event_callb(code);
} else { } else {
TUXEDO_DEBUG("[Ev %d] Unknown event type - %d (%0#6x)\n", guid_nr, obj->type, obj->type); TUXEDO_DEBUG("[Ev %d] Unknown event type - %d (%0#6x)\n", guid_nr, obj->type, obj->type);
} }

View file

@ -92,7 +92,10 @@ static const struct wmi_device_id uniwill_wmi_device_ids[] = {
}; };
static struct wmi_driver uniwill_wmi_driver = { 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, .id_table = uniwill_wmi_device_ids,
.probe = uniwill_wmi_probe, .probe = uniwill_wmi_probe,
.remove = uniwill_wmi_remove, .remove = uniwill_wmi_remove,