diff --git a/src/tuxedo_keyboard.c b/src/tuxedo_keyboard.c index 829d1d2..c6bbef6 100644 --- a/src/tuxedo_keyboard.c +++ b/src/tuxedo_keyboard.c @@ -28,15 +28,9 @@ MODULE_DESCRIPTION("TUXEDO Computers keyboard & keyboard backlight Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION("3.0.8"); -MODULE_ALIAS("wmi:" UNIWILL_WMI_EVENT_GUID_0); -MODULE_ALIAS("wmi:" UNIWILL_WMI_EVENT_GUID_1); -MODULE_ALIAS("wmi:" UNIWILL_WMI_EVENT_GUID_2); - static DEFINE_MUTEX(tuxedo_keyboard_init_driver_lock); -static struct tuxedo_keyboard_driver *driver_list[] = { - &uniwill_keyboard_driver -}; +// static struct tuxedo_keyboard_driver *driver_list[] = { }; static int tuxedo_input_init(const struct key_entry key_map[]) { @@ -134,44 +128,48 @@ static void __exit tuxedo_input_exit(void) } } -static int __init tuxedo_keyboard_init(void) +void tuxedo_keyboard_remove_driver(struct tuxedo_keyboard_driver *tk_driver) { - int i; - int num_drivers = sizeof(driver_list) / sizeof(*driver_list); - TUXEDO_INFO("Model '%s' found\n", - dmi_get_system_info(DMI_PRODUCT_NAME)); + bool specified_driver_differ_from_used = + tk_driver != NULL && + ( + strcmp( + tk_driver->platform_driver->driver.name, + current_driver->platform_driver->driver.name + ) != 0 + ); - // Attempt to load each available driver - // Associated probe decides if it fits - // Driver from first successful probe is used + if (specified_driver_differ_from_used) + return; - i = 0; - while (IS_ERR_OR_NULL(tuxedo_platform_device) && i < num_drivers) { - current_driver = driver_list[i]; - tuxedo_keyboard_init_driver(current_driver); - ++i; + TUXEDO_DEBUG("tuxedo_input_exit()\n"); + tuxedo_input_exit(); + TUXEDO_DEBUG("platform_device_unregister()\n"); + if (!IS_ERR_OR_NULL(tuxedo_platform_device)) { + platform_device_unregister(tuxedo_platform_device); + tuxedo_platform_device = NULL; } - - if (IS_ERR_OR_NULL(tuxedo_platform_device)) { - TUXEDO_DEBUG("No matching hardware found on init\n"); + TUXEDO_DEBUG("platform_driver_unregister()\n"); + if (!IS_ERR_OR_NULL(current_driver)) { + platform_driver_unregister(current_driver->platform_driver); current_driver = NULL; } +} +EXPORT_SYMBOL(tuxedo_keyboard_remove_driver); + +static int __init tuxedo_keyboard_init(void) +{ + TUXEDO_INFO("module init\n"); return 0; } static void __exit tuxedo_keyboard_exit(void) { - TUXEDO_DEBUG("tuxedo_input_exit()\n"); - tuxedo_input_exit(); - TUXEDO_DEBUG("platform_device_unregister()\n"); - if (!IS_ERR_OR_NULL(tuxedo_platform_device)) - platform_device_unregister(tuxedo_platform_device); - TUXEDO_DEBUG("platform_driver_unregister()\n"); - if (!IS_ERR_OR_NULL(current_driver)) - platform_driver_unregister(current_driver->platform_driver); + TUXEDO_INFO("module exit\n"); - TUXEDO_DEBUG("exit\n"); + if (tuxedo_platform_device != NULL) + tuxedo_keyboard_remove_driver(NULL); } module_init(tuxedo_keyboard_init); diff --git a/src/tuxedo_keyboard_common.h b/src/tuxedo_keyboard_common.h index 49651b4..84f6059 100644 --- a/src/tuxedo_keyboard_common.h +++ b/src/tuxedo_keyboard_common.h @@ -56,6 +56,7 @@ static struct input_dev *tuxedo_input_device = NULL; static struct tuxedo_keyboard_driver *current_driver = NULL; struct platform_device *tuxedo_keyboard_init_driver(struct tuxedo_keyboard_driver *tk_driver); +void tuxedo_keyboard_remove_driver(struct tuxedo_keyboard_driver *tk_driver); /** * Basically a copy of the existing report event but doesn't report unknown events diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 133d69e..16243b2 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -133,6 +133,10 @@ u32 uniwill_add_interface(struct uniwill_interface_t *interface) interface->event_callb = uniwill_event_callb; mutex_unlock(&uniwill_interface_modification_lock); + + // Initialize driver if not already present + tuxedo_keyboard_init_driver(&uniwill_keyboard_driver); + return 0; } EXPORT_SYMBOL(uniwill_add_interface); @@ -141,14 +145,18 @@ u32 uniwill_remove_interface(struct uniwill_interface_t *interface) { mutex_lock(&uniwill_interface_modification_lock); - if (strcmp(interface->string_id, UNIWILL_INTERFACE_WMI_STRID)) + if (strcmp(interface->string_id, UNIWILL_INTERFACE_WMI_STRID) == 0) { + // Remove driver if last interface is removed + tuxedo_keyboard_remove_driver(&uniwill_keyboard_driver); + uniwill_interfaces.wmi = NULL; - else { + } else { mutex_unlock(&uniwill_interface_modification_lock); return -EINVAL; } mutex_unlock(&uniwill_interface_modification_lock); + return 0; } EXPORT_SYMBOL(uniwill_remove_interface); @@ -342,7 +350,7 @@ void uniwill_event_callb(u32 code) } } -static void uniwill_wmi_handle_event(u32 value, void *context, u32 guid_nr) +/*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; @@ -367,9 +375,9 @@ static void uniwill_wmi_handle_event(u32 value, void *context, u32 guid_nr) } kfree(obj); -} +}*/ -static void uniwill_wmi_notify0(u32 value, void *context) +/*static void uniwill_wmi_notify0(u32 value, void *context) { uniwill_wmi_handle_event(value, context, 0); } @@ -382,7 +390,7 @@ static void uniwill_wmi_notify1(u32 value, void *context) static void uniwill_wmi_notify2(u32 value, void *context) { uniwill_wmi_handle_event(value, context, 2); -} +}*/ static ssize_t uw_brightness_show(struct device *child, struct device_attribute *attr, char *buffer) @@ -820,7 +828,7 @@ static int uw_lightbar_remove(struct platform_device *dev) return 0; } -static int uniwill_keyboard_probe(struct platform_device *dev) +/*static int uniwill_keyboard_probe(struct platform_device *dev) { int status; @@ -872,6 +880,40 @@ err_remove_notifiers: wmi_remove_notify_handler(UNIWILL_WMI_EVENT_GUID_2); return -ENODEV; +}*/ + +static int uniwill_keyboard_probe(struct platform_device *dev) +{ + u32 i; + u8 data; + int status; + + // FIXME Hard set balanced profile until we have implemented a way to + // switch it while tuxedo_io is loaded + // uw_ec_write_addr(0x51, 0x07, 0x00, 0x00, ®_write_return); + uniwill_write_ec_ram(0x0751, 0x00); + + // Set manual-mode fan-curve in 0x0743 - 0x0747 + // Some kind of default fan-curve is stored in 0x0786 - 0x078a: Using it to initialize manual-mode fan-curve + for (i = 0; i < 5; ++i) { + uniwill_read_ec_ram(0x0786 + i, &data); + uniwill_write_ec_ram(0x0743 + i, data); + } + + // Enable manual mode + uniwill_write_ec_ram(0x0741, 0x01); + + // Zero second fan temp for detection + uniwill_write_ec_ram(0x044f, 0x00); + + status = register_keyboard_notifier(&keyboard_notifier_block); + + uw_kbd_bl_init(dev); + + status = uw_lightbar_init(dev); + uw_lightbar_loaded = (status >= 0); + + return 0; } static int uniwill_keyboard_remove(struct platform_device *dev) @@ -887,9 +929,6 @@ static int uniwill_keyboard_remove(struct platform_device *dev) } unregister_keyboard_notifier(&keyboard_notifier_block); - wmi_remove_notify_handler(UNIWILL_WMI_EVENT_GUID_0); - wmi_remove_notify_handler(UNIWILL_WMI_EVENT_GUID_1); - wmi_remove_notify_handler(UNIWILL_WMI_EVENT_GUID_2); del_timer(&uw_kbd_bl_init_timer);