eeepc-wmi: add wlan key found on 1015P
[pandora-kernel.git] / drivers / platform / x86 / eeepc-wmi.c
1 /*
2  * Eee PC WMI hotkey driver
3  *
4  * Copyright(C) 2010 Intel Corporation.
5  * Copyright(C) 2010 Corentin Chary <corentin.chary@gmail.com>
6  *
7  * Portions based on wistron_btns.c:
8  * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
9  * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
10  * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  (at your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25  */
26
27 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
28
29 #include <linux/kernel.h>
30 #include <linux/module.h>
31 #include <linux/init.h>
32 #include <linux/types.h>
33 #include <linux/slab.h>
34 #include <linux/input.h>
35 #include <linux/input/sparse-keymap.h>
36 #include <linux/fb.h>
37 #include <linux/backlight.h>
38 #include <linux/leds.h>
39 #include <linux/rfkill.h>
40 #include <linux/debugfs.h>
41 #include <linux/seq_file.h>
42 #include <linux/platform_device.h>
43 #include <acpi/acpi_bus.h>
44 #include <acpi/acpi_drivers.h>
45
46 #define EEEPC_WMI_FILE  "eeepc-wmi"
47
48 MODULE_AUTHOR("Yong Wang <yong.y.wang@intel.com>");
49 MODULE_DESCRIPTION("Eee PC WMI Hotkey Driver");
50 MODULE_LICENSE("GPL");
51
52 #define EEEPC_ACPI_HID          "ASUS010" /* old _HID used in eeepc-laptop */
53
54 #define EEEPC_WMI_EVENT_GUID    "ABBC0F72-8EA1-11D1-00A0-C90629100000"
55 #define EEEPC_WMI_MGMT_GUID     "97845ED0-4E6D-11DE-8A39-0800200C9A66"
56
57 MODULE_ALIAS("wmi:"EEEPC_WMI_EVENT_GUID);
58 MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
59
60 #define NOTIFY_BRNUP_MIN        0x11
61 #define NOTIFY_BRNUP_MAX        0x1f
62 #define NOTIFY_BRNDOWN_MIN      0x20
63 #define NOTIFY_BRNDOWN_MAX      0x2e
64
65 #define EEEPC_WMI_METHODID_DEVS 0x53564544
66 #define EEEPC_WMI_METHODID_DSTS 0x53544344
67 #define EEEPC_WMI_METHODID_CFVS 0x53564643
68
69 #define EEEPC_WMI_DEVID_BACKLIGHT       0x00050012
70 #define EEEPC_WMI_DEVID_TPDLED          0x00100011
71 #define EEEPC_WMI_DEVID_WLAN            0x00010011
72 #define EEEPC_WMI_DEVID_BLUETOOTH       0x00010013
73 #define EEEPC_WMI_DEVID_WWAN3G          0x00010019
74
75 static const struct key_entry eeepc_wmi_keymap[] = {
76         /* Sleep already handled via generic ACPI code */
77         { KE_IGNORE, NOTIFY_BRNDOWN_MIN, { KEY_BRIGHTNESSDOWN } },
78         { KE_IGNORE, NOTIFY_BRNUP_MIN, { KEY_BRIGHTNESSUP } },
79         { KE_KEY, 0x30, { KEY_VOLUMEUP } },
80         { KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
81         { KE_KEY, 0x32, { KEY_MUTE } },
82         { KE_KEY, 0x5c, { KEY_F15 } },
83         { KE_KEY, 0x5d, { KEY_WLAN } },
84         { KE_KEY, 0x6b, { KEY_F13 } }, /* Disable Touchpad */
85         { KE_KEY, 0x88, { KEY_WLAN } },
86         { KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } },
87         { KE_KEY, 0xe0, { KEY_PROG1 } },
88         { KE_KEY, 0xe1, { KEY_F14 } },
89         { KE_KEY, 0xe9, { KEY_DISPLAY_OFF } },
90         { KE_END, 0},
91 };
92
93 struct bios_args {
94         u32     dev_id;
95         u32     ctrl_param;
96 };
97
98 /*
99  * eeepc-wmi/    - debugfs root directory
100  *   dev_id      - current dev_id
101  *   ctrl_param  - current ctrl_param
102  *   devs        - call DEVS(dev_id, ctrl_param) and print result
103  *   dsts        - call DSTS(dev_id)  and print result
104  */
105 struct eeepc_wmi_debug {
106         struct dentry *root;
107         u32 dev_id;
108         u32 ctrl_param;
109 };
110
111 struct eeepc_wmi {
112         struct input_dev *inputdev;
113         struct backlight_device *backlight_device;
114         struct platform_device *platform_device;
115
116         struct led_classdev tpd_led;
117         int tpd_led_wk;
118         struct workqueue_struct *led_workqueue;
119         struct work_struct tpd_led_work;
120
121         struct rfkill *wlan_rfkill;
122         struct rfkill *bluetooth_rfkill;
123         struct rfkill *wwan3g_rfkill;
124
125         struct eeepc_wmi_debug debug;
126 };
127
128 /* Only used in eeepc_wmi_init() and eeepc_wmi_exit() */
129 static struct platform_device *platform_device;
130
131 static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc)
132 {
133         int err;
134
135         eeepc->inputdev = input_allocate_device();
136         if (!eeepc->inputdev)
137                 return -ENOMEM;
138
139         eeepc->inputdev->name = "Eee PC WMI hotkeys";
140         eeepc->inputdev->phys = EEEPC_WMI_FILE "/input0";
141         eeepc->inputdev->id.bustype = BUS_HOST;
142         eeepc->inputdev->dev.parent = &eeepc->platform_device->dev;
143
144         err = sparse_keymap_setup(eeepc->inputdev, eeepc_wmi_keymap, NULL);
145         if (err)
146                 goto err_free_dev;
147
148         err = input_register_device(eeepc->inputdev);
149         if (err)
150                 goto err_free_keymap;
151
152         return 0;
153
154 err_free_keymap:
155         sparse_keymap_free(eeepc->inputdev);
156 err_free_dev:
157         input_free_device(eeepc->inputdev);
158         return err;
159 }
160
161 static void eeepc_wmi_input_exit(struct eeepc_wmi *eeepc)
162 {
163         if (eeepc->inputdev) {
164                 sparse_keymap_free(eeepc->inputdev);
165                 input_unregister_device(eeepc->inputdev);
166         }
167
168         eeepc->inputdev = NULL;
169 }
170
171 static acpi_status eeepc_wmi_get_devstate(u32 dev_id, u32 *retval)
172 {
173         struct acpi_buffer input = { (acpi_size)sizeof(u32), &dev_id };
174         struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
175         union acpi_object *obj;
176         acpi_status status;
177         u32 tmp;
178
179         status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
180                         1, EEEPC_WMI_METHODID_DSTS, &input, &output);
181
182         if (ACPI_FAILURE(status))
183                 return status;
184
185         obj = (union acpi_object *)output.pointer;
186         if (obj && obj->type == ACPI_TYPE_INTEGER)
187                 tmp = (u32)obj->integer.value;
188         else
189                 tmp = 0;
190
191         if (retval)
192                 *retval = tmp;
193
194         kfree(obj);
195
196         return status;
197
198 }
199
200 static acpi_status eeepc_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
201                                           u32 *retval)
202 {
203         struct bios_args args = {
204                 .dev_id = dev_id,
205                 .ctrl_param = ctrl_param,
206         };
207         struct acpi_buffer input = { (acpi_size)sizeof(args), &args };
208         acpi_status status;
209
210         if (!retval) {
211                 status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID, 1,
212                                              EEEPC_WMI_METHODID_DEVS,
213                                              &input, NULL);
214         } else {
215                 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
216                 union acpi_object *obj;
217                 u32 tmp;
218
219                 status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID, 1,
220                                              EEEPC_WMI_METHODID_DEVS,
221                                              &input, &output);
222
223                 if (ACPI_FAILURE(status))
224                         return status;
225
226                 obj = (union acpi_object *)output.pointer;
227                 if (obj && obj->type == ACPI_TYPE_INTEGER)
228                         tmp = (u32)obj->integer.value;
229                 else
230                         tmp = 0;
231
232                 *retval = tmp;
233
234                 kfree(obj);
235         }
236
237         return status;
238 }
239
240 /*
241  * LEDs
242  */
243 /*
244  * These functions actually update the LED's, and are called from a
245  * workqueue. By doing this as separate work rather than when the LED
246  * subsystem asks, we avoid messing with the Eeepc ACPI stuff during a
247  * potentially bad time, such as a timer interrupt.
248  */
249 static void tpd_led_update(struct work_struct *work)
250 {
251         int ctrl_param;
252         struct eeepc_wmi *eeepc;
253
254         eeepc = container_of(work, struct eeepc_wmi, tpd_led_work);
255
256         ctrl_param = eeepc->tpd_led_wk;
257         eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_TPDLED, ctrl_param, NULL);
258 }
259
260 static void tpd_led_set(struct led_classdev *led_cdev,
261                         enum led_brightness value)
262 {
263         struct eeepc_wmi *eeepc;
264
265         eeepc = container_of(led_cdev, struct eeepc_wmi, tpd_led);
266
267         eeepc->tpd_led_wk = !!value;
268         queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
269 }
270
271 static int read_tpd_state(struct eeepc_wmi *eeepc)
272 {
273         u32 retval;
274         acpi_status status;
275
276         status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_TPDLED, &retval);
277
278         if (ACPI_FAILURE(status))
279                 return -1;
280         else if (!retval || retval == 0x00060000)
281                 /*
282                  * if touchpad led is present, DSTS will set some bits,
283                  * usually 0x00020000.
284                  * 0x00060000 means that the device is not supported
285                  */
286                 return -ENODEV;
287         else
288                 /* Status is stored in the first bit */
289                 return retval & 0x1;
290 }
291
292 static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
293 {
294         struct eeepc_wmi *eeepc;
295
296         eeepc = container_of(led_cdev, struct eeepc_wmi, tpd_led);
297
298         return read_tpd_state(eeepc);
299 }
300
301 static int eeepc_wmi_led_init(struct eeepc_wmi *eeepc)
302 {
303         int rv;
304
305         if (read_tpd_state(eeepc) < 0)
306                 return 0;
307
308         eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
309         if (!eeepc->led_workqueue)
310                 return -ENOMEM;
311         INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);
312
313         eeepc->tpd_led.name = "eeepc::touchpad";
314         eeepc->tpd_led.brightness_set = tpd_led_set;
315         eeepc->tpd_led.brightness_get = tpd_led_get;
316         eeepc->tpd_led.max_brightness = 1;
317
318         rv = led_classdev_register(&eeepc->platform_device->dev,
319                                    &eeepc->tpd_led);
320         if (rv) {
321                 destroy_workqueue(eeepc->led_workqueue);
322                 return rv;
323         }
324
325         return 0;
326 }
327
328 static void eeepc_wmi_led_exit(struct eeepc_wmi *eeepc)
329 {
330         if (eeepc->tpd_led.dev)
331                 led_classdev_unregister(&eeepc->tpd_led);
332         if (eeepc->led_workqueue)
333                 destroy_workqueue(eeepc->led_workqueue);
334 }
335
336 /*
337  * Rfkill devices
338  */
339 static int eeepc_rfkill_set(void *data, bool blocked)
340 {
341         int dev_id = (unsigned long)data;
342         u32 ctrl_param = !blocked;
343
344         return eeepc_wmi_set_devstate(dev_id, ctrl_param, NULL);
345 }
346
347 static void eeepc_rfkill_query(struct rfkill *rfkill, void *data)
348 {
349         int dev_id = (unsigned long)data;
350         u32 retval;
351         acpi_status status;
352
353         status = eeepc_wmi_get_devstate(dev_id, &retval);
354
355         if (ACPI_FAILURE(status))
356                 return ;
357
358         rfkill_set_sw_state(rfkill, !(retval & 0x1));
359 }
360
361 static const struct rfkill_ops eeepc_rfkill_ops = {
362         .set_block = eeepc_rfkill_set,
363         .query = eeepc_rfkill_query,
364 };
365
366 static int eeepc_new_rfkill(struct eeepc_wmi *eeepc,
367                             struct rfkill **rfkill,
368                             const char *name,
369                             enum rfkill_type type, int dev_id)
370 {
371         int result;
372         u32 retval;
373         acpi_status status;
374
375         status = eeepc_wmi_get_devstate(dev_id, &retval);
376
377         if (ACPI_FAILURE(status))
378                 return -1;
379
380         /* If the device is present, DSTS will always set some bits
381          * 0x00070000 - 1110000000000000000 - device supported
382          * 0x00060000 - 1100000000000000000 - not supported
383          * 0x00020000 - 0100000000000000000 - device supported
384          * 0x00010000 - 0010000000000000000 - not supported / special mode ?
385          */
386         if (!retval || retval == 0x00060000)
387                 return -ENODEV;
388
389         *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
390                                &eeepc_rfkill_ops, (void *)(long)dev_id);
391
392         if (!*rfkill)
393                 return -EINVAL;
394
395         rfkill_init_sw_state(*rfkill, !(retval & 0x1));
396         result = rfkill_register(*rfkill);
397         if (result) {
398                 rfkill_destroy(*rfkill);
399                 *rfkill = NULL;
400                 return result;
401         }
402         return 0;
403 }
404
405 static void eeepc_wmi_rfkill_exit(struct eeepc_wmi *eeepc)
406 {
407         if (eeepc->wlan_rfkill) {
408                 rfkill_unregister(eeepc->wlan_rfkill);
409                 rfkill_destroy(eeepc->wlan_rfkill);
410                 eeepc->wlan_rfkill = NULL;
411         }
412         if (eeepc->bluetooth_rfkill) {
413                 rfkill_unregister(eeepc->bluetooth_rfkill);
414                 rfkill_destroy(eeepc->bluetooth_rfkill);
415                 eeepc->bluetooth_rfkill = NULL;
416         }
417         if (eeepc->wwan3g_rfkill) {
418                 rfkill_unregister(eeepc->wwan3g_rfkill);
419                 rfkill_destroy(eeepc->wwan3g_rfkill);
420                 eeepc->wwan3g_rfkill = NULL;
421         }
422 }
423
424 static int eeepc_wmi_rfkill_init(struct eeepc_wmi *eeepc)
425 {
426         int result = 0;
427
428         result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
429                                   "eeepc-wlan", RFKILL_TYPE_WLAN,
430                                   EEEPC_WMI_DEVID_WLAN);
431
432         if (result && result != -ENODEV)
433                 goto exit;
434
435         result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
436                                   "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
437                                   EEEPC_WMI_DEVID_BLUETOOTH);
438
439         if (result && result != -ENODEV)
440                 goto exit;
441
442         result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
443                                   "eeepc-wwan3g", RFKILL_TYPE_WWAN,
444                                   EEEPC_WMI_DEVID_WWAN3G);
445
446         if (result && result != -ENODEV)
447                 goto exit;
448
449 exit:
450         if (result && result != -ENODEV)
451                 eeepc_wmi_rfkill_exit(eeepc);
452
453         if (result == -ENODEV)
454                 result = 0;
455
456         return result;
457 }
458
459 /*
460  * Backlight
461  */
462 static int read_brightness(struct backlight_device *bd)
463 {
464         u32 retval;
465         acpi_status status;
466
467         status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT, &retval);
468
469         if (ACPI_FAILURE(status))
470                 return -1;
471         else
472                 return retval & 0xFF;
473 }
474
475 static int update_bl_status(struct backlight_device *bd)
476 {
477
478         u32 ctrl_param;
479         acpi_status status;
480
481         ctrl_param = bd->props.brightness;
482
483         status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT,
484                                         ctrl_param, NULL);
485
486         if (ACPI_FAILURE(status))
487                 return -1;
488         else
489                 return 0;
490 }
491
492 static const struct backlight_ops eeepc_wmi_bl_ops = {
493         .get_brightness = read_brightness,
494         .update_status = update_bl_status,
495 };
496
497 static int eeepc_wmi_backlight_notify(struct eeepc_wmi *eeepc, int code)
498 {
499         struct backlight_device *bd = eeepc->backlight_device;
500         int old = bd->props.brightness;
501         int new = old;
502
503         if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
504                 new = code - NOTIFY_BRNUP_MIN + 1;
505         else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
506                 new = code - NOTIFY_BRNDOWN_MIN;
507
508         bd->props.brightness = new;
509         backlight_update_status(bd);
510         backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
511
512         return old;
513 }
514
515 static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
516 {
517         struct backlight_device *bd;
518         struct backlight_properties props;
519
520         memset(&props, 0, sizeof(struct backlight_properties));
521         props.max_brightness = 15;
522         bd = backlight_device_register(EEEPC_WMI_FILE,
523                                        &eeepc->platform_device->dev, eeepc,
524                                        &eeepc_wmi_bl_ops, &props);
525         if (IS_ERR(bd)) {
526                 pr_err("Could not register backlight device\n");
527                 return PTR_ERR(bd);
528         }
529
530         eeepc->backlight_device = bd;
531
532         bd->props.brightness = read_brightness(bd);
533         bd->props.power = FB_BLANK_UNBLANK;
534         backlight_update_status(bd);
535
536         return 0;
537 }
538
539 static void eeepc_wmi_backlight_exit(struct eeepc_wmi *eeepc)
540 {
541         if (eeepc->backlight_device)
542                 backlight_device_unregister(eeepc->backlight_device);
543
544         eeepc->backlight_device = NULL;
545 }
546
547 static void eeepc_wmi_notify(u32 value, void *context)
548 {
549         struct eeepc_wmi *eeepc = context;
550         struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
551         union acpi_object *obj;
552         acpi_status status;
553         int code;
554         int orig_code;
555
556         status = wmi_get_event_data(value, &response);
557         if (status != AE_OK) {
558                 pr_err("bad event status 0x%x\n", status);
559                 return;
560         }
561
562         obj = (union acpi_object *)response.pointer;
563
564         if (obj && obj->type == ACPI_TYPE_INTEGER) {
565                 code = obj->integer.value;
566                 orig_code = code;
567
568                 if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
569                         code = NOTIFY_BRNUP_MIN;
570                 else if (code >= NOTIFY_BRNDOWN_MIN &&
571                          code <= NOTIFY_BRNDOWN_MAX)
572                         code = NOTIFY_BRNDOWN_MIN;
573
574                 if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) {
575                         if (!acpi_video_backlight_support())
576                                 eeepc_wmi_backlight_notify(eeepc, orig_code);
577                 }
578
579                 if (!sparse_keymap_report_event(eeepc->inputdev,
580                                                 code, 1, true))
581                         pr_info("Unknown key %x pressed\n", code);
582         }
583
584         kfree(obj);
585 }
586
587 static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr,
588                            const char *buf, size_t count)
589 {
590         int value;
591         struct acpi_buffer input = { (acpi_size)sizeof(value), &value };
592         acpi_status status;
593
594         if (!count || sscanf(buf, "%i", &value) != 1)
595                 return -EINVAL;
596         if (value < 0 || value > 2)
597                 return -EINVAL;
598
599         status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
600                                      1, EEEPC_WMI_METHODID_CFVS, &input, NULL);
601
602         if (ACPI_FAILURE(status))
603                 return -EIO;
604         else
605                 return count;
606 }
607
608 static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv);
609
610 static struct attribute *platform_attributes[] = {
611         &dev_attr_cpufv.attr,
612         NULL
613 };
614
615 static struct attribute_group platform_attribute_group = {
616         .attrs = platform_attributes
617 };
618
619 static void eeepc_wmi_sysfs_exit(struct platform_device *device)
620 {
621         sysfs_remove_group(&device->dev.kobj, &platform_attribute_group);
622 }
623
624 static int eeepc_wmi_sysfs_init(struct platform_device *device)
625 {
626         return sysfs_create_group(&device->dev.kobj, &platform_attribute_group);
627 }
628
629 /*
630  * Platform device
631  */
632 static int __init eeepc_wmi_platform_init(struct eeepc_wmi *eeepc)
633 {
634         int err;
635
636         eeepc->platform_device = platform_device_alloc(EEEPC_WMI_FILE, -1);
637         if (!eeepc->platform_device)
638                 return -ENOMEM;
639         platform_set_drvdata(eeepc->platform_device, eeepc);
640
641         err = platform_device_add(eeepc->platform_device);
642         if (err)
643                 goto fail_platform_device;
644
645         err = eeepc_wmi_sysfs_init(eeepc->platform_device);
646         if (err)
647                 goto fail_sysfs;
648         return 0;
649
650 fail_sysfs:
651         platform_device_del(eeepc->platform_device);
652 fail_platform_device:
653         platform_device_put(eeepc->platform_device);
654         return err;
655 }
656
657 static void eeepc_wmi_platform_exit(struct eeepc_wmi *eeepc)
658 {
659         eeepc_wmi_sysfs_exit(eeepc->platform_device);
660         platform_device_unregister(eeepc->platform_device);
661 }
662
663 /*
664  * debugfs
665  */
666 struct eeepc_wmi_debugfs_node {
667         struct eeepc_wmi *eeepc;
668         char *name;
669         int (*show)(struct seq_file *m, void *data);
670 };
671
672 static int show_dsts(struct seq_file *m, void *data)
673 {
674         struct eeepc_wmi *eeepc = m->private;
675         acpi_status status;
676         u32 retval = -1;
677
678         status = eeepc_wmi_get_devstate(eeepc->debug.dev_id, &retval);
679
680         if (ACPI_FAILURE(status))
681                 return -EIO;
682
683         seq_printf(m, "DSTS(%x) = %x\n", eeepc->debug.dev_id, retval);
684
685         return 0;
686 }
687
688 static int show_devs(struct seq_file *m, void *data)
689 {
690         struct eeepc_wmi *eeepc = m->private;
691         acpi_status status;
692         u32 retval = -1;
693
694         status = eeepc_wmi_set_devstate(eeepc->debug.dev_id,
695                                         eeepc->debug.ctrl_param, &retval);
696         if (ACPI_FAILURE(status))
697                 return -EIO;
698
699         seq_printf(m, "DEVS(%x, %x) = %x\n", eeepc->debug.dev_id,
700                    eeepc->debug.ctrl_param, retval);
701
702         return 0;
703 }
704
705 static struct eeepc_wmi_debugfs_node eeepc_wmi_debug_files[] = {
706         { NULL, "devs", show_devs },
707         { NULL, "dsts", show_dsts },
708 };
709
710 static int eeepc_wmi_debugfs_open(struct inode *inode, struct file *file)
711 {
712         struct eeepc_wmi_debugfs_node *node = inode->i_private;
713
714         return single_open(file, node->show, node->eeepc);
715 }
716
717 static const struct file_operations eeepc_wmi_debugfs_io_ops = {
718         .owner = THIS_MODULE,
719         .open  = eeepc_wmi_debugfs_open,
720         .read = seq_read,
721         .llseek = seq_lseek,
722         .release = single_release,
723 };
724
725 static void eeepc_wmi_debugfs_exit(struct eeepc_wmi *eeepc)
726 {
727         debugfs_remove_recursive(eeepc->debug.root);
728 }
729
730 static int eeepc_wmi_debugfs_init(struct eeepc_wmi *eeepc)
731 {
732         struct dentry *dent;
733         int i;
734
735         eeepc->debug.root = debugfs_create_dir(EEEPC_WMI_FILE, NULL);
736         if (!eeepc->debug.root) {
737                 pr_err("failed to create debugfs directory");
738                 goto error_debugfs;
739         }
740
741         dent = debugfs_create_x32("dev_id", S_IRUGO|S_IWUSR,
742                                   eeepc->debug.root, &eeepc->debug.dev_id);
743         if (!dent)
744                 goto error_debugfs;
745
746         dent = debugfs_create_x32("ctrl_param", S_IRUGO|S_IWUSR,
747                                   eeepc->debug.root, &eeepc->debug.ctrl_param);
748         if (!dent)
749                 goto error_debugfs;
750
751         for (i = 0; i < ARRAY_SIZE(eeepc_wmi_debug_files); i++) {
752                 struct eeepc_wmi_debugfs_node *node = &eeepc_wmi_debug_files[i];
753
754                 node->eeepc = eeepc;
755                 dent = debugfs_create_file(node->name, S_IFREG | S_IRUGO,
756                                            eeepc->debug.root, node,
757                                            &eeepc_wmi_debugfs_io_ops);
758                 if (!dent) {
759                         pr_err("failed to create debug file: %s\n", node->name);
760                         goto error_debugfs;
761                 }
762         }
763
764         return 0;
765
766 error_debugfs:
767         eeepc_wmi_debugfs_exit(eeepc);
768         return -ENOMEM;
769 }
770
771 /*
772  * WMI Driver
773  */
774 static struct platform_device * __init eeepc_wmi_add(void)
775 {
776         struct eeepc_wmi *eeepc;
777         acpi_status status;
778         int err;
779
780         eeepc = kzalloc(sizeof(struct eeepc_wmi), GFP_KERNEL);
781         if (!eeepc)
782                 return ERR_PTR(-ENOMEM);
783
784         /*
785          * Register the platform device first.  It is used as a parent for the
786          * sub-devices below.
787          */
788         err = eeepc_wmi_platform_init(eeepc);
789         if (err)
790                 goto fail_platform;
791
792         err = eeepc_wmi_input_init(eeepc);
793         if (err)
794                 goto fail_input;
795
796         err = eeepc_wmi_led_init(eeepc);
797         if (err)
798                 goto fail_leds;
799
800         err = eeepc_wmi_rfkill_init(eeepc);
801         if (err)
802                 goto fail_rfkill;
803
804         if (!acpi_video_backlight_support()) {
805                 err = eeepc_wmi_backlight_init(eeepc);
806                 if (err)
807                         goto fail_backlight;
808         } else
809                 pr_info("Backlight controlled by ACPI video driver\n");
810
811         status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID,
812                                             eeepc_wmi_notify, eeepc);
813         if (ACPI_FAILURE(status)) {
814                 pr_err("Unable to register notify handler - %d\n",
815                         status);
816                 err = -ENODEV;
817                 goto fail_wmi_handler;
818         }
819
820         err = eeepc_wmi_debugfs_init(eeepc);
821         if (err)
822                 goto fail_debugfs;
823
824         return eeepc->platform_device;
825
826 fail_debugfs:
827         wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
828 fail_wmi_handler:
829         eeepc_wmi_backlight_exit(eeepc);
830 fail_backlight:
831         eeepc_wmi_rfkill_exit(eeepc);
832 fail_rfkill:
833         eeepc_wmi_led_exit(eeepc);
834 fail_leds:
835         eeepc_wmi_input_exit(eeepc);
836 fail_input:
837         eeepc_wmi_platform_exit(eeepc);
838 fail_platform:
839         kfree(eeepc);
840         return ERR_PTR(err);
841 }
842
843 static int eeepc_wmi_remove(struct platform_device *device)
844 {
845         struct eeepc_wmi *eeepc;
846
847         eeepc = platform_get_drvdata(device);
848         wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
849         eeepc_wmi_backlight_exit(eeepc);
850         eeepc_wmi_input_exit(eeepc);
851         eeepc_wmi_led_exit(eeepc);
852         eeepc_wmi_rfkill_exit(eeepc);
853         eeepc_wmi_debugfs_exit(eeepc);
854         eeepc_wmi_platform_exit(eeepc);
855
856         kfree(eeepc);
857         return 0;
858 }
859
860 static struct platform_driver platform_driver = {
861         .driver = {
862                 .name = EEEPC_WMI_FILE,
863                 .owner = THIS_MODULE,
864         },
865 };
866
867 static acpi_status __init eeepc_wmi_parse_device(acpi_handle handle, u32 level,
868                                                  void *context, void **retval)
869 {
870         pr_warning("Found legacy ATKD device (%s)", EEEPC_ACPI_HID);
871         *(bool *)context = true;
872         return AE_CTRL_TERMINATE;
873 }
874
875 static int __init eeepc_wmi_check_atkd(void)
876 {
877         acpi_status status;
878         bool found = false;
879
880         status = acpi_get_devices(EEEPC_ACPI_HID, eeepc_wmi_parse_device,
881                                   &found, NULL);
882
883         if (ACPI_FAILURE(status) || !found)
884                 return 0;
885         return -1;
886 }
887
888 static int __init eeepc_wmi_init(void)
889 {
890         int err;
891
892         if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID) ||
893             !wmi_has_guid(EEEPC_WMI_MGMT_GUID)) {
894                 pr_warning("No known WMI GUID found\n");
895                 return -ENODEV;
896         }
897
898         if (eeepc_wmi_check_atkd()) {
899                 pr_warning("WMI device present, but legacy ATKD device is also "
900                            "present and enabled.");
901                 pr_warning("You probably booted with acpi_osi=\"Linux\" or "
902                            "acpi_osi=\"!Windows 2009\"");
903                 pr_warning("Can't load eeepc-wmi, use default acpi_osi "
904                            "(preferred) or eeepc-laptop");
905                 return -ENODEV;
906         }
907
908         platform_device = eeepc_wmi_add();
909         if (IS_ERR(platform_device)) {
910                 err = PTR_ERR(platform_device);
911                 goto fail_eeepc_wmi;
912         }
913
914         err = platform_driver_register(&platform_driver);
915         if (err) {
916                 pr_warning("Unable to register platform driver\n");
917                 goto fail_platform_driver;
918         }
919
920         return 0;
921
922 fail_platform_driver:
923         eeepc_wmi_remove(platform_device);
924 fail_eeepc_wmi:
925         return err;
926 }
927
928 static void __exit eeepc_wmi_exit(void)
929 {
930         eeepc_wmi_remove(platform_device);
931         platform_driver_unregister(&platform_driver);
932 }
933
934 module_init(eeepc_wmi_init);
935 module_exit(eeepc_wmi_exit);