diff options
author | Maxim Mikityanskiy <maxtram95@gmail.com> | 2012-12-15 19:31:34 +0200 |
---|---|---|
committer | Matthew Garrett <matthew.garrett@nebula.com> | 2013-02-24 14:49:54 -0800 |
commit | da8506288fc4b2cc62d0ba477c2fe2a16f8891b0 (patch) | |
tree | 83b2a000ad38cf0c88362223fe137aa821bdae3c /drivers | |
parent | b0d3bb53beaba866ce80424fb512b1669ed88da0 (diff) |
msi-wmi: Make keys and backlight independent
Introduced function msi_wmi_backlight_setup() that initializes backlight
device. Made driver load and work if only one WMI (only for hotkeys or
only for backlight) is present.
Signed-off-by: Maxim Mikityanskiy <maxtram95@gmail.com>
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/platform/x86/msi-wmi.c | 101 |
1 files changed, 64 insertions, 37 deletions
diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index 112ec1488ea8..3a6061985e4d 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c @@ -60,6 +60,8 @@ static struct key_entry msi_wmi_keymap[] = { }; static ktime_t last_pressed[ARRAY_SIZE(msi_wmi_keymap) - 1]; +static const char *event_wmi_guid; + static struct backlight_device *backlight; static int backlight_map[] = { 0x00, 0x33, 0x66, 0x99, 0xCC, 0xFF }; @@ -184,7 +186,7 @@ static void msi_wmi_notify(u32 value, void *context) if (key->type == KE_KEY && /* Brightness is served via acpi video driver */ - (!acpi_video_backlight_support() || + (backlight || (key->code != MSI_KEY_BRIGHTNESSUP && key->code != MSI_KEY_BRIGHTNESSDOWN))) { pr_debug("Send key: 0x%X - " @@ -202,6 +204,31 @@ msi_wmi_notify_exit: kfree(response.pointer); } +static int __init msi_wmi_backlight_setup(void) +{ + int err; + struct backlight_properties props; + + memset(&props, 0, sizeof(struct backlight_properties)); + props.type = BACKLIGHT_PLATFORM; + props.max_brightness = ARRAY_SIZE(backlight_map) - 1; + backlight = backlight_device_register(DRV_NAME, NULL, NULL, + &msi_backlight_ops, + &props); + if (IS_ERR(backlight)) + return PTR_ERR(backlight); + + err = bl_get(NULL); + if (err < 0) { + backlight_device_unregister(backlight); + return err; + } + + backlight->props.brightness = err; + + return 0; +} + static int __init msi_wmi_input_setup(void) { int err; @@ -238,60 +265,60 @@ static int __init msi_wmi_init(void) { int err; - if (!wmi_has_guid(MSIWMI_EVENT_GUID)) { - pr_err("This machine doesn't have MSI-hotkeys through WMI\n"); - return -ENODEV; - } - err = wmi_install_notify_handler(MSIWMI_EVENT_GUID, - msi_wmi_notify, NULL); - if (ACPI_FAILURE(err)) - return -EINVAL; + if (wmi_has_guid(MSIWMI_EVENT_GUID)) { + err = msi_wmi_input_setup(); + if (err) { + pr_err("Unable to setup input device\n"); + return err; + } - err = msi_wmi_input_setup(); - if (err) - goto err_uninstall_notifier; - - if (!acpi_video_backlight_support()) { - struct backlight_properties props; - memset(&props, 0, sizeof(struct backlight_properties)); - props.type = BACKLIGHT_PLATFORM; - props.max_brightness = ARRAY_SIZE(backlight_map) - 1; - backlight = backlight_device_register(DRV_NAME, NULL, NULL, - &msi_backlight_ops, - &props); - if (IS_ERR(backlight)) { - err = PTR_ERR(backlight); + err = wmi_install_notify_handler(MSIWMI_EVENT_GUID, + msi_wmi_notify, NULL); + if (ACPI_FAILURE(err)) { + pr_err("Unable to setup WMI notify handler\n"); goto err_free_input; } - err = bl_get(NULL); - if (err < 0) - goto err_free_backlight; + pr_debug("Event handler installed\n"); + event_wmi_guid = MSIWMI_EVENT_GUID; + } + + if (wmi_has_guid(MSIWMI_BIOS_GUID) && !acpi_video_backlight_support()) { + err = msi_wmi_backlight_setup(); + if (err) { + pr_err("Unable to setup backlight device\n"); + goto err_uninstall_handler; + } + pr_debug("Backlight device created\n"); + } - backlight->props.brightness = err; + if (!event_wmi_guid && !backlight) { + pr_err("This machine doesn't have neither MSI-hotkeys nor backlight through WMI\n"); + return -ENODEV; } - pr_debug("Event handler installed\n"); return 0; -err_free_backlight: - backlight_device_unregister(backlight); +err_uninstall_handler: + if (event_wmi_guid) + wmi_remove_notify_handler(event_wmi_guid); err_free_input: - sparse_keymap_free(msi_wmi_input_dev); - input_unregister_device(msi_wmi_input_dev); -err_uninstall_notifier: - wmi_remove_notify_handler(MSIWMI_EVENT_GUID); + if (event_wmi_guid) { + sparse_keymap_free(msi_wmi_input_dev); + input_unregister_device(msi_wmi_input_dev); + } return err; } static void __exit msi_wmi_exit(void) { - if (wmi_has_guid(MSIWMI_EVENT_GUID)) { - wmi_remove_notify_handler(MSIWMI_EVENT_GUID); + if (event_wmi_guid) { + wmi_remove_notify_handler(event_wmi_guid); sparse_keymap_free(msi_wmi_input_dev); input_unregister_device(msi_wmi_input_dev); - backlight_device_unregister(backlight); } + if (backlight) + backlight_device_unregister(backlight); } module_init(msi_wmi_init); |