Adjust clevo driver init and remove accordingly

This commit is contained in:
Christoffer Sandberg 2021-09-16 00:14:39 +02:00
parent 9ec3dc927a
commit 16f7c246dd
4 changed files with 85 additions and 82 deletions

View file

@ -101,7 +101,7 @@ u32 clevo_acpi_interface_method_call(u8 cmd, u32 arg, u32 *result_value)
} }
struct clevo_interface_t clevo_acpi_interface = { struct clevo_interface_t clevo_acpi_interface = {
.string_id = "clevo_acpi", .string_id = CLEVO_INTERFACE_ACPI_STRID,
.method_call = clevo_acpi_interface_method_call, .method_call = clevo_acpi_interface_method_call,
}; };
@ -123,9 +123,6 @@ static int clevo_acpi_add(struct acpi_device *device)
// Add this interface // Add this interface
clevo_keyboard_add_interface(&clevo_acpi_interface); clevo_keyboard_add_interface(&clevo_acpi_interface);
// Initiate clevo keyboard, if not already loaded by other interface driver
clevo_keyboard_init();
pr_info("interface initialized\n"); pr_info("interface initialized\n");
return 0; return 0;
@ -195,7 +192,7 @@ module_acpi_driver(clevo_acpi_driver);
MODULE_AUTHOR("TUXEDO Computers GmbH <tux@tuxedocomputers.com>"); MODULE_AUTHOR("TUXEDO Computers GmbH <tux@tuxedocomputers.com>");
MODULE_DESCRIPTION("Driver for Clevo ACPI interface"); MODULE_DESCRIPTION("Driver for Clevo ACPI interface");
MODULE_VERSION("0.0.2"); MODULE_VERSION("0.0.3");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(acpi, clevo_acpi_device_ids); MODULE_DEVICE_TABLE(acpi, clevo_acpi_device_ids);

View file

@ -48,8 +48,6 @@
#define CLEVO_CMD_OPT 0x79 #define CLEVO_CMD_OPT 0x79
#define CLEVO_OPT_SUBCMD_SET_PERF_PROF 0x19 #define CLEVO_OPT_SUBCMD_SET_PERF_PROF 0x19
int clevo_keyboard_init(void);
struct clevo_interface_t { struct clevo_interface_t {
char *string_id; char *string_id;
void (*event_callb)(u32); void (*event_callb)(u32);
@ -65,6 +63,9 @@ u32 clevo_get_active_interface_id(char **id_str);
MODULE_ALIAS("wmi:" CLEVO_WMI_EVENT_GUID); \ MODULE_ALIAS("wmi:" CLEVO_WMI_EVENT_GUID); \
MODULE_ALIAS("wmi:" CLEVO_WMI_METHOD_GUID); MODULE_ALIAS("wmi:" CLEVO_WMI_METHOD_GUID);
#define CLEVO_INTERFACE_WMI_STRID "clevo_wmi"
#define CLEVO_INTERFACE_ACPI_STRID "clevo_acpi"
#define MODULE_ALIAS_CLEVO_ACPI() \ #define MODULE_ALIAS_CLEVO_ACPI() \
MODULE_ALIAS("acpi*:" CLEVO_ACPI_RESOURCE_HID ":*"); MODULE_ALIAS("acpi*:" CLEVO_ACPI_RESOURCE_HID ":*");

View file

@ -54,6 +54,8 @@
#define CLEVO_EVENT_RFKILL1 0x85 #define CLEVO_EVENT_RFKILL1 0x85
#define CLEVO_EVENT_RFKILL2 0x86 #define CLEVO_EVENT_RFKILL2 0x86
struct tuxedo_keyboard_driver clevo_keyboard_driver;
static struct clevo_interfaces_t { static struct clevo_interfaces_t {
struct clevo_interface_t *wmi; struct clevo_interface_t *wmi;
struct clevo_interface_t *acpi; struct clevo_interface_t *acpi;
@ -70,7 +72,7 @@ u32 clevo_keyboard_add_interface(struct clevo_interface_t *new_interface)
{ {
mutex_lock(&clevo_keyboard_interface_modification_lock); mutex_lock(&clevo_keyboard_interface_modification_lock);
if (strcmp(new_interface->string_id, "clevo_wmi") == 0) { if (strcmp(new_interface->string_id, CLEVO_INTERFACE_WMI_STRID) == 0) {
clevo_interfaces.wmi = new_interface; clevo_interfaces.wmi = new_interface;
clevo_interfaces.wmi->event_callb = clevo_keyboard_event_callb; clevo_interfaces.wmi->event_callb = clevo_keyboard_event_callb;
@ -82,7 +84,7 @@ u32 clevo_keyboard_add_interface(struct clevo_interface_t *new_interface)
active_clevo_interface = clevo_interfaces.wmi; active_clevo_interface = clevo_interfaces.wmi;
} }
} else if (strcmp(new_interface->string_id, "clevo_acpi") == 0) { } else if (strcmp(new_interface->string_id, CLEVO_INTERFACE_ACPI_STRID) == 0) {
clevo_interfaces.acpi = new_interface; clevo_interfaces.acpi = new_interface;
clevo_interfaces.acpi->event_callb = clevo_keyboard_event_callb; clevo_interfaces.acpi->event_callb = clevo_keyboard_event_callb;
@ -98,6 +100,9 @@ u32 clevo_keyboard_add_interface(struct clevo_interface_t *new_interface)
mutex_unlock(&clevo_keyboard_interface_modification_lock); mutex_unlock(&clevo_keyboard_interface_modification_lock);
if (active_clevo_interface != NULL)
tuxedo_keyboard_init_driver(&clevo_keyboard_driver);
return 0; return 0;
} }
EXPORT_SYMBOL(clevo_keyboard_add_interface); EXPORT_SYMBOL(clevo_keyboard_add_interface);
@ -106,17 +111,20 @@ u32 clevo_keyboard_remove_interface(struct clevo_interface_t *interface)
{ {
mutex_lock(&clevo_keyboard_interface_modification_lock); mutex_lock(&clevo_keyboard_interface_modification_lock);
if (strcmp(interface->string_id, "clevo_wmi") == 0) { if (strcmp(interface->string_id, CLEVO_INTERFACE_WMI_STRID) == 0) {
clevo_interfaces.wmi = NULL; clevo_interfaces.wmi = NULL;
} else if (strcmp(interface->string_id, "clevo_acpi") == 0) { } else if (strcmp(interface->string_id, CLEVO_INTERFACE_ACPI_STRID) == 0) {
clevo_interfaces.acpi = NULL; clevo_interfaces.acpi = NULL;
} else { } else {
mutex_unlock(&clevo_keyboard_interface_modification_lock); mutex_unlock(&clevo_keyboard_interface_modification_lock);
return -EINVAL; return -EINVAL;
} }
if (active_clevo_interface == interface) if (active_clevo_interface == interface) {
tuxedo_keyboard_remove_driver(&clevo_keyboard_driver);
active_clevo_interface = NULL; active_clevo_interface = NULL;
}
mutex_unlock(&clevo_keyboard_interface_modification_lock); mutex_unlock(&clevo_keyboard_interface_modification_lock);
@ -124,8 +132,6 @@ u32 clevo_keyboard_remove_interface(struct clevo_interface_t *interface)
} }
EXPORT_SYMBOL(clevo_keyboard_remove_interface); EXPORT_SYMBOL(clevo_keyboard_remove_interface);
struct tuxedo_keyboard_driver clevo_keyboard_driver;
static struct key_entry clevo_keymap[] = { static struct key_entry clevo_keymap[] = {
// Keyboard backlight (RGB versions) // Keyboard backlight (RGB versions)
{ KE_KEY, CLEVO_EVENT_DECREASE_BACKLIGHT, { KEY_KBDILLUMDOWN } }, { KE_KEY, CLEVO_EVENT_DECREASE_BACKLIGHT, { KEY_KBDILLUMDOWN } },
@ -299,7 +305,7 @@ static ssize_t show_hasextra_fs(struct device *child,
u32 clevo_evaluate_method(u8 cmd, u32 arg, u32 *result) u32 clevo_evaluate_method(u8 cmd, u32 arg, u32 *result)
{ {
if (IS_ERR_OR_NULL(active_clevo_interface)) { if (IS_ERR_OR_NULL(active_clevo_interface)) {
pr_err("clevo_keyboard: no active interface\n"); pr_err("clevo_keyboard: no active interface while attempting cmd %02x arg %08x\n", cmd, arg);
return -ENODEV; return -ENODEV;
} }
return active_clevo_interface->method_call(cmd, arg, result); return active_clevo_interface->method_call(cmd, arg, result);
@ -705,9 +711,65 @@ void clevo_keyboard_write_state(void)
set_enabled(kbd_led_state.enabled); set_enabled(kbd_led_state.enabled);
} }
static int clevo_keyboard_probe_only_init(struct platform_device *dev) /**
* strstr version of dmi_match
*/
static bool dmi_string_in(enum dmi_field f, const char *str)
{
const char *info = dmi_get_system_info(f);
if (info == NULL || str == NULL)
return info == str;
return strstr(info, str) != NULL;
}
int clevo_keyboard_init(void)
{
bool performance_profile_set_workaround;
// Init state from params
kbd_led_state.color.left = param_color_left;
kbd_led_state.color.center = param_color_center;
kbd_led_state.color.right = param_color_right;
kbd_led_state.color.extra = param_color_extra;
kbd_led_state.blinking_pattern = param_blinking_pattern;
if (param_brightness > BRIGHTNESS_MAX) param_brightness = BRIGHTNESS_DEFAULT;
kbd_led_state.brightness = param_brightness;
kbd_led_state.enabled = param_state;
clevo_keyboard_write_state();
// Workaround for firmware issue not setting selected performance profile.
// Explicitly set "performance" perf. profile on init regardless of what is chosen
// for these devices (Aura, XP14, IBS14v5)
performance_profile_set_workaround = false
|| dmi_string_in(DMI_BOARD_NAME, "AURA1501")
|| dmi_string_in(DMI_BOARD_NAME, "EDUBOOK1502")
|| dmi_string_in(DMI_BOARD_NAME, "NL5xRU")
|| dmi_string_in(DMI_BOARD_NAME, "NV4XMB,ME,MZ")
|| dmi_string_in(DMI_BOARD_NAME, "L140CU")
|| dmi_string_in(DMI_BOARD_NAME, "NS50MU")
|| dmi_string_in(DMI_BOARD_NAME, "PCX0DX")
|| dmi_string_in(DMI_BOARD_NAME, "PCx0Dx_GN20")
|| dmi_string_in(DMI_BOARD_NAME, "L14xMU")
;
if (performance_profile_set_workaround) {
TUXEDO_INFO("Performance profile 'performance' set workaround applied\n");
clevo_evaluate_method(0x79, 0x19000002, NULL);
}
return 0;
}
static int clevo_keyboard_probe(struct platform_device *dev)
{ {
clevo_keyboard_init_device_interface(dev); clevo_keyboard_init_device_interface(dev);
clevo_keyboard_init();
return 0; return 0;
} }
@ -759,66 +821,8 @@ static struct platform_driver platform_driver_clevo = {
}, },
}; };
struct tuxedo_keyboard_driver clevo_keyboard_driver_v2 = { struct tuxedo_keyboard_driver clevo_keyboard_driver = {
.platform_driver = &platform_driver_clevo, .platform_driver = &platform_driver_clevo,
.probe = clevo_keyboard_probe_only_init, .probe = clevo_keyboard_probe,
.key_map = clevo_keymap, .key_map = clevo_keymap,
}; };
/**
* strstr version of dmi_match
*/
static bool dmi_string_in(enum dmi_field f, const char *str)
{
const char *info = dmi_get_system_info(f);
if (info == NULL || str == NULL)
return info == str;
return strstr(info, str) != NULL;
}
int clevo_keyboard_init(void)
{
bool performance_profile_set_workaround;
if (IS_ERR_OR_NULL(tuxedo_keyboard_init_driver(&clevo_keyboard_driver_v2)))
return -EEXIST;
// Init state from params
kbd_led_state.color.left = param_color_left;
kbd_led_state.color.center = param_color_center;
kbd_led_state.color.right = param_color_right;
kbd_led_state.color.extra = param_color_extra;
kbd_led_state.blinking_pattern = param_blinking_pattern;
if (param_brightness > BRIGHTNESS_MAX) param_brightness = BRIGHTNESS_DEFAULT;
kbd_led_state.brightness = param_brightness;
kbd_led_state.enabled = param_state;
clevo_keyboard_write_state();
// Workaround for firmware issue not setting selected performance profile.
// Explicitly set "performance" perf. profile on init regardless of what is chosen
// for these devices (Aura, XP14, IBS14v5)
performance_profile_set_workaround = false
|| dmi_string_in(DMI_BOARD_NAME, "AURA1501")
|| dmi_string_in(DMI_BOARD_NAME, "EDUBOOK1502")
|| dmi_string_in(DMI_BOARD_NAME, "NL5xRU")
|| dmi_string_in(DMI_BOARD_NAME, "NV4XMB,ME,MZ")
|| dmi_string_in(DMI_BOARD_NAME, "L140CU")
|| dmi_string_in(DMI_BOARD_NAME, "NS50MU")
|| dmi_string_in(DMI_BOARD_NAME, "PCX0DX")
|| dmi_string_in(DMI_BOARD_NAME, "PCx0Dx_GN20")
|| dmi_string_in(DMI_BOARD_NAME, "L14xMU")
;
if (performance_profile_set_workaround) {
TUXEDO_INFO("Performance profile 'performance' set workaround applied\n");
clevo_evaluate_method(0x79, 0x19000002, NULL);
}
return 0;
}
EXPORT_SYMBOL(clevo_keyboard_init);

View file

@ -70,7 +70,7 @@ u32 clevo_wmi_interface_method_call(u8 cmd, u32 arg, u32 *result_value)
} }
struct clevo_interface_t clevo_wmi_interface = { struct clevo_interface_t clevo_wmi_interface = {
.string_id = "clevo_wmi", .string_id = CLEVO_INTERFACE_WMI_STRID,
.method_call = clevo_wmi_interface_method_call, .method_call = clevo_wmi_interface_method_call,
}; };
@ -110,9 +110,6 @@ static int clevo_wmi_probe(struct wmi_device *wdev, const void *dummy_context)
// Add this interface // Add this interface
clevo_keyboard_add_interface(&clevo_wmi_interface); clevo_keyboard_add_interface(&clevo_wmi_interface);
// Initiate clevo keyboard, if not already loaded by other interface driver
clevo_keyboard_init();
pr_info("interface initialized\n"); pr_info("interface initialized\n");
return 0; return 0;
@ -125,6 +122,7 @@ static void clevo_wmi_remove(struct wmi_device *wdev)
#endif #endif
{ {
pr_debug("clevo_wmi driver remove\n"); pr_debug("clevo_wmi driver remove\n");
clevo_keyboard_remove_interface(&clevo_wmi_interface);
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0) #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0)
return 0; return 0;
#endif #endif
@ -149,7 +147,10 @@ static const struct wmi_device_id clevo_wmi_device_ids[] = {
}; };
static struct wmi_driver clevo_wmi_driver = { static struct wmi_driver clevo_wmi_driver = {
.driver = { .name = "clevo_wmi", .owner = THIS_MODULE }, .driver = {
.name = CLEVO_INTERFACE_WMI_STRID,
.owner = THIS_MODULE
},
.id_table = clevo_wmi_device_ids, .id_table = clevo_wmi_device_ids,
.probe = clevo_wmi_probe, .probe = clevo_wmi_probe,
.remove = clevo_wmi_remove, .remove = clevo_wmi_remove,
@ -160,7 +161,7 @@ module_wmi_driver(clevo_wmi_driver);
MODULE_AUTHOR("TUXEDO Computers GmbH <tux@tuxedocomputers.com>"); MODULE_AUTHOR("TUXEDO Computers GmbH <tux@tuxedocomputers.com>");
MODULE_DESCRIPTION("Driver for Clevo WMI interface"); MODULE_DESCRIPTION("Driver for Clevo WMI interface");
MODULE_VERSION("0.0.3"); MODULE_VERSION("0.0.4");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(wmi, clevo_wmi_device_ids); MODULE_DEVICE_TABLE(wmi, clevo_wmi_device_ids);