aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86
diff options
context:
space:
mode:
authorMaxim Mikityanskiy <maxtram95@gmail.com>2012-12-15 12:31:36 -0500
committerMatthew Garrett <matthew.garrett@nebula.com>2013-02-24 17:49:54 -0500
commitc11ac2aa520b4777e5b063f8d8e99ce00337dcd9 (patch)
treeff68f6c8d94ab6af844117ae617ac2561d1b2f0a /drivers/platform/x86
parentfedda8e7385f5fb01acb8897beca90b6256fc7bd (diff)
msi-wmi: Add MSI Wind support
Add MSI Wind support to msi-wmi driver. MSI Wind has different GUID for key events, different WMI key scan codes, it does not need filtering consecutive identical events and it does not support backlight control via MSIWMI_BIOS_GUID WMI. Tested on MSI Wind U100. Signed-off-by: Maxim Mikityanskiy <maxtram95@gmail.com> Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
Diffstat (limited to 'drivers/platform/x86')
-rw-r--r--drivers/platform/x86/msi-wmi.c65
1 files changed, 50 insertions, 15 deletions
diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c
index 739bd4d17c23..70222f265f68 100644
--- a/drivers/platform/x86/msi-wmi.c
+++ b/drivers/platform/x86/msi-wmi.c
@@ -37,17 +37,27 @@ MODULE_LICENSE("GPL");
37#define DRV_NAME "msi-wmi" 37#define DRV_NAME "msi-wmi"
38 38
39#define MSIWMI_BIOS_GUID "551A1F84-FBDD-4125-91DB-3EA8F44F1D45" 39#define MSIWMI_BIOS_GUID "551A1F84-FBDD-4125-91DB-3EA8F44F1D45"
40#define MSIWMI_EVENT_GUID "B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2" 40#define MSIWMI_MSI_EVENT_GUID "B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2"
41#define MSIWMI_WIND_EVENT_GUID "5B3CC38A-40D9-7245-8AE6-1145B751BE3F"
41 42
42MODULE_ALIAS("wmi:" MSIWMI_BIOS_GUID); 43MODULE_ALIAS("wmi:" MSIWMI_BIOS_GUID);
43MODULE_ALIAS("wmi:" MSIWMI_EVENT_GUID); 44MODULE_ALIAS("wmi:" MSIWMI_MSI_EVENT_GUID);
45MODULE_ALIAS("wmi:" MSIWMI_WIND_EVENT_GUID);
44 46
45enum msi_scancodes { 47enum msi_scancodes {
48 /* Generic MSI keys (not present on MSI Wind) */
46 MSI_KEY_BRIGHTNESSUP = 0xD0, 49 MSI_KEY_BRIGHTNESSUP = 0xD0,
47 MSI_KEY_BRIGHTNESSDOWN, 50 MSI_KEY_BRIGHTNESSDOWN,
48 MSI_KEY_VOLUMEUP, 51 MSI_KEY_VOLUMEUP,
49 MSI_KEY_VOLUMEDOWN, 52 MSI_KEY_VOLUMEDOWN,
50 MSI_KEY_MUTE, 53 MSI_KEY_MUTE,
54 /* MSI Wind keys */
55 WIND_KEY_TOUCHPAD = 0x08, /* Fn+F3 touchpad toggle */
56 WIND_KEY_BLUETOOTH = 0x56, /* Fn+F11 Bluetooth toggle */
57 WIND_KEY_CAMERA, /* Fn+F6 webcam toggle */
58 WIND_KEY_WLAN = 0x5f, /* Fn+F11 Wi-Fi toggle */
59 WIND_KEY_TURBO, /* Fn+F10 turbo mode toggle */
60 WIND_KEY_ECO = 0x69, /* Fn+F10 ECO mode toggle */
51}; 61};
52static struct key_entry msi_wmi_keymap[] = { 62static struct key_entry msi_wmi_keymap[] = {
53 { KE_KEY, MSI_KEY_BRIGHTNESSUP, {KEY_BRIGHTNESSUP} }, 63 { KE_KEY, MSI_KEY_BRIGHTNESSUP, {KEY_BRIGHTNESSUP} },
@@ -55,13 +65,34 @@ static struct key_entry msi_wmi_keymap[] = {
55 { KE_KEY, MSI_KEY_VOLUMEUP, {KEY_VOLUMEUP} }, 65 { KE_KEY, MSI_KEY_VOLUMEUP, {KEY_VOLUMEUP} },
56 { KE_KEY, MSI_KEY_VOLUMEDOWN, {KEY_VOLUMEDOWN} }, 66 { KE_KEY, MSI_KEY_VOLUMEDOWN, {KEY_VOLUMEDOWN} },
57 { KE_KEY, MSI_KEY_MUTE, {KEY_MUTE} }, 67 { KE_KEY, MSI_KEY_MUTE, {KEY_MUTE} },
68
69 /* These keys work without WMI. Ignore them to avoid double keycodes */
70 { KE_IGNORE, WIND_KEY_TOUCHPAD, {KEY_TOUCHPAD_TOGGLE} },
71 { KE_IGNORE, WIND_KEY_BLUETOOTH, {KEY_BLUETOOTH} },
72 { KE_IGNORE, WIND_KEY_CAMERA, {KEY_CAMERA} },
73 { KE_IGNORE, WIND_KEY_WLAN, {KEY_WLAN} },
74
75 /* These are unknown WMI events found on MSI Wind */
76 { KE_IGNORE, 0x00 },
77 { KE_IGNORE, 0x62 },
78 { KE_IGNORE, 0x63 },
79
80 /* These are MSI Wind keys that should be handled via WMI */
81 { KE_KEY, WIND_KEY_TURBO, {KEY_PROG1} },
82 { KE_KEY, WIND_KEY_ECO, {KEY_PROG2} },
83
58 { KE_END, 0 } 84 { KE_END, 0 }
59}; 85};
60 86
61static ktime_t last_pressed; 87static ktime_t last_pressed;
62static bool quirk_last_pressed;
63 88
64static const char *event_wmi_guid; 89static const struct {
90 const char *guid;
91 bool quirk_last_pressed;
92} *event_wmi, event_wmis[] = {
93 { MSIWMI_MSI_EVENT_GUID, true },
94 { MSIWMI_WIND_EVENT_GUID, false },
95};
65 96
66static struct backlight_device *backlight; 97static struct backlight_device *backlight;
67 98
@@ -174,7 +205,7 @@ static void msi_wmi_notify(u32 value, void *context)
174 goto msi_wmi_notify_exit; 205 goto msi_wmi_notify_exit;
175 } 206 }
176 207
177 if (quirk_last_pressed) { 208 if (event_wmi->quirk_last_pressed) {
178 ktime_t cur = ktime_get_real(); 209 ktime_t cur = ktime_get_real();
179 ktime_t diff = ktime_sub(cur, last_pressed); 210 ktime_t diff = ktime_sub(cur, last_pressed);
180 /* Ignore event if any event happened in a 50 ms 211 /* Ignore event if any event happened in a 50 ms
@@ -265,15 +296,19 @@ err_free_dev:
265static int __init msi_wmi_init(void) 296static int __init msi_wmi_init(void)
266{ 297{
267 int err; 298 int err;
299 int i;
300
301 for (i = 0; i < ARRAY_SIZE(event_wmis); i++) {
302 if (!wmi_has_guid(event_wmis[i].guid))
303 continue;
268 304
269 if (wmi_has_guid(MSIWMI_EVENT_GUID)) {
270 err = msi_wmi_input_setup(); 305 err = msi_wmi_input_setup();
271 if (err) { 306 if (err) {
272 pr_err("Unable to setup input device\n"); 307 pr_err("Unable to setup input device\n");
273 return err; 308 return err;
274 } 309 }
275 310
276 err = wmi_install_notify_handler(MSIWMI_EVENT_GUID, 311 err = wmi_install_notify_handler(event_wmis[i].guid,
277 msi_wmi_notify, NULL); 312 msi_wmi_notify, NULL);
278 if (ACPI_FAILURE(err)) { 313 if (ACPI_FAILURE(err)) {
279 pr_err("Unable to setup WMI notify handler\n"); 314 pr_err("Unable to setup WMI notify handler\n");
@@ -281,8 +316,8 @@ static int __init msi_wmi_init(void)
281 } 316 }
282 317
283 pr_debug("Event handler installed\n"); 318 pr_debug("Event handler installed\n");
284 event_wmi_guid = MSIWMI_EVENT_GUID; 319 event_wmi = &event_wmis[i];
285 quirk_last_pressed = true; 320 break;
286 } 321 }
287 322
288 if (wmi_has_guid(MSIWMI_BIOS_GUID) && !acpi_video_backlight_support()) { 323 if (wmi_has_guid(MSIWMI_BIOS_GUID) && !acpi_video_backlight_support()) {
@@ -294,7 +329,7 @@ static int __init msi_wmi_init(void)
294 pr_debug("Backlight device created\n"); 329 pr_debug("Backlight device created\n");
295 } 330 }
296 331
297 if (!event_wmi_guid && !backlight) { 332 if (!event_wmi && !backlight) {
298 pr_err("This machine doesn't have neither MSI-hotkeys nor backlight through WMI\n"); 333 pr_err("This machine doesn't have neither MSI-hotkeys nor backlight through WMI\n");
299 return -ENODEV; 334 return -ENODEV;
300 } 335 }
@@ -302,10 +337,10 @@ static int __init msi_wmi_init(void)
302 return 0; 337 return 0;
303 338
304err_uninstall_handler: 339err_uninstall_handler:
305 if (event_wmi_guid) 340 if (event_wmi)
306 wmi_remove_notify_handler(event_wmi_guid); 341 wmi_remove_notify_handler(event_wmi->guid);
307err_free_input: 342err_free_input:
308 if (event_wmi_guid) { 343 if (event_wmi) {
309 sparse_keymap_free(msi_wmi_input_dev); 344 sparse_keymap_free(msi_wmi_input_dev);
310 input_unregister_device(msi_wmi_input_dev); 345 input_unregister_device(msi_wmi_input_dev);
311 } 346 }
@@ -314,8 +349,8 @@ err_free_input:
314 349
315static void __exit msi_wmi_exit(void) 350static void __exit msi_wmi_exit(void)
316{ 351{
317 if (event_wmi_guid) { 352 if (event_wmi) {
318 wmi_remove_notify_handler(event_wmi_guid); 353 wmi_remove_notify_handler(event_wmi->guid);
319 sparse_keymap_free(msi_wmi_input_dev); 354 sparse_keymap_free(msi_wmi_input_dev);
320 input_unregister_device(msi_wmi_input_dev); 355 input_unregister_device(msi_wmi_input_dev);
321 } 356 }