]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/platform/x86/asus-wmi.c
945145df67b8a44a704b0aab98daf0f352a597fa
[karo-tx-linux.git] / drivers / platform / x86 / asus-wmi.c
1 /*
2  * Asus PC WMI hotkey driver
3  *
4  * Copyright(C) 2010 Intel Corporation.
5  * Copyright(C) 2010-2011 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/pci.h>
41 #include <linux/pci_hotplug.h>
42 #include <linux/hwmon.h>
43 #include <linux/hwmon-sysfs.h>
44 #include <linux/debugfs.h>
45 #include <linux/seq_file.h>
46 #include <linux/platform_device.h>
47 #include <linux/thermal.h>
48 #include <linux/acpi.h>
49 #include <linux/dmi.h>
50 #include <acpi/video.h>
51
52 #include "asus-wmi.h"
53
54 MODULE_AUTHOR("Corentin Chary <corentin.chary@gmail.com>, "
55               "Yong Wang <yong.y.wang@intel.com>");
56 MODULE_DESCRIPTION("Asus Generic WMI Driver");
57 MODULE_LICENSE("GPL");
58
59 #define to_platform_driver(drv)                                 \
60         (container_of((drv), struct platform_driver, driver))
61
62 #define to_asus_wmi_driver(pdrv)                                        \
63         (container_of((pdrv), struct asus_wmi_driver, platform_driver))
64
65 #define ASUS_WMI_MGMT_GUID      "97845ED0-4E6D-11DE-8A39-0800200C9A66"
66
67 #define NOTIFY_BRNUP_MIN                0x11
68 #define NOTIFY_BRNUP_MAX                0x1f
69 #define NOTIFY_BRNDOWN_MIN              0x20
70 #define NOTIFY_BRNDOWN_MAX              0x2e
71 #define NOTIFY_KBD_BRTUP                0xc4
72 #define NOTIFY_KBD_BRTDWN               0xc5
73
74 /* WMI Methods */
75 #define ASUS_WMI_METHODID_SPEC          0x43455053 /* BIOS SPECification */
76 #define ASUS_WMI_METHODID_SFBD          0x44424653 /* Set First Boot Device */
77 #define ASUS_WMI_METHODID_GLCD          0x44434C47 /* Get LCD status */
78 #define ASUS_WMI_METHODID_GPID          0x44495047 /* Get Panel ID?? (Resol) */
79 #define ASUS_WMI_METHODID_QMOD          0x444F4D51 /* Quiet MODe */
80 #define ASUS_WMI_METHODID_SPLV          0x4C425053 /* Set Panel Light Value */
81 #define ASUS_WMI_METHODID_SFUN          0x4E554653 /* FUNCtionalities */
82 #define ASUS_WMI_METHODID_SDSP          0x50534453 /* Set DiSPlay output */
83 #define ASUS_WMI_METHODID_GDSP          0x50534447 /* Get DiSPlay output */
84 #define ASUS_WMI_METHODID_DEVP          0x50564544 /* DEVice Policy */
85 #define ASUS_WMI_METHODID_OSVR          0x5256534F /* OS VeRsion */
86 #define ASUS_WMI_METHODID_DSTS          0x53544344 /* Device STatuS */
87 #define ASUS_WMI_METHODID_DSTS2         0x53545344 /* Device STatuS #2*/
88 #define ASUS_WMI_METHODID_BSTS          0x53545342 /* Bios STatuS ? */
89 #define ASUS_WMI_METHODID_DEVS          0x53564544 /* DEVice Set */
90 #define ASUS_WMI_METHODID_CFVS          0x53564643 /* CPU Frequency Volt Set */
91 #define ASUS_WMI_METHODID_KBFT          0x5446424B /* KeyBoard FilTer */
92 #define ASUS_WMI_METHODID_INIT          0x54494E49 /* INITialize */
93 #define ASUS_WMI_METHODID_HKEY          0x59454B48 /* Hot KEY ?? */
94
95 #define ASUS_WMI_UNSUPPORTED_METHOD     0xFFFFFFFE
96
97 /* Wireless */
98 #define ASUS_WMI_DEVID_HW_SWITCH        0x00010001
99 #define ASUS_WMI_DEVID_WIRELESS_LED     0x00010002
100 #define ASUS_WMI_DEVID_CWAP             0x00010003
101 #define ASUS_WMI_DEVID_WLAN             0x00010011
102 #define ASUS_WMI_DEVID_WLAN_LED         0x00010012
103 #define ASUS_WMI_DEVID_BLUETOOTH        0x00010013
104 #define ASUS_WMI_DEVID_GPS              0x00010015
105 #define ASUS_WMI_DEVID_WIMAX            0x00010017
106 #define ASUS_WMI_DEVID_WWAN3G           0x00010019
107 #define ASUS_WMI_DEVID_UWB              0x00010021
108
109 /* Leds */
110 /* 0x000200XX and 0x000400XX */
111 #define ASUS_WMI_DEVID_LED1             0x00020011
112 #define ASUS_WMI_DEVID_LED2             0x00020012
113 #define ASUS_WMI_DEVID_LED3             0x00020013
114 #define ASUS_WMI_DEVID_LED4             0x00020014
115 #define ASUS_WMI_DEVID_LED5             0x00020015
116 #define ASUS_WMI_DEVID_LED6             0x00020016
117
118 /* Backlight and Brightness */
119 #define ASUS_WMI_DEVID_BACKLIGHT        0x00050011
120 #define ASUS_WMI_DEVID_BRIGHTNESS       0x00050012
121 #define ASUS_WMI_DEVID_KBD_BACKLIGHT    0x00050021
122 #define ASUS_WMI_DEVID_LIGHT_SENSOR     0x00050022 /* ?? */
123
124 /* Misc */
125 #define ASUS_WMI_DEVID_CAMERA           0x00060013
126
127 /* Storage */
128 #define ASUS_WMI_DEVID_CARDREADER       0x00080013
129
130 /* Input */
131 #define ASUS_WMI_DEVID_TOUCHPAD         0x00100011
132 #define ASUS_WMI_DEVID_TOUCHPAD_LED     0x00100012
133
134 /* Fan, Thermal */
135 #define ASUS_WMI_DEVID_THERMAL_CTRL     0x00110011
136 #define ASUS_WMI_DEVID_FAN_CTRL         0x00110012
137
138 /* Power */
139 #define ASUS_WMI_DEVID_PROCESSOR_STATE  0x00120012
140
141 /* Deep S3 / Resume on LID open */
142 #define ASUS_WMI_DEVID_LID_RESUME       0x00120031
143
144 /* DSTS masks */
145 #define ASUS_WMI_DSTS_STATUS_BIT        0x00000001
146 #define ASUS_WMI_DSTS_UNKNOWN_BIT       0x00000002
147 #define ASUS_WMI_DSTS_PRESENCE_BIT      0x00010000
148 #define ASUS_WMI_DSTS_USER_BIT          0x00020000
149 #define ASUS_WMI_DSTS_BIOS_BIT          0x00040000
150 #define ASUS_WMI_DSTS_BRIGHTNESS_MASK   0x000000FF
151 #define ASUS_WMI_DSTS_MAX_BRIGTH_MASK   0x0000FF00
152
153 struct bios_args {
154         u32 arg0;
155         u32 arg1;
156 } __packed;
157
158 /*
159  * <platform>/    - debugfs root directory
160  *   dev_id      - current dev_id
161  *   ctrl_param  - current ctrl_param
162  *   method_id   - current method_id
163  *   devs        - call DEVS(dev_id, ctrl_param) and print result
164  *   dsts        - call DSTS(dev_id)  and print result
165  *   call        - call method_id(dev_id, ctrl_param) and print result
166  */
167 struct asus_wmi_debug {
168         struct dentry *root;
169         u32 method_id;
170         u32 dev_id;
171         u32 ctrl_param;
172 };
173
174 struct asus_rfkill {
175         struct asus_wmi *asus;
176         struct rfkill *rfkill;
177         u32 dev_id;
178 };
179
180 struct asus_wmi {
181         int dsts_id;
182         int spec;
183         int sfun;
184
185         struct input_dev *inputdev;
186         struct backlight_device *backlight_device;
187         struct platform_device *platform_device;
188
189         struct led_classdev wlan_led;
190         int wlan_led_wk;
191         struct led_classdev tpd_led;
192         int tpd_led_wk;
193         struct led_classdev kbd_led;
194         int kbd_led_wk;
195         struct workqueue_struct *led_workqueue;
196         struct work_struct tpd_led_work;
197         struct work_struct kbd_led_work;
198         struct work_struct wlan_led_work;
199
200         struct asus_rfkill wlan;
201         struct asus_rfkill bluetooth;
202         struct asus_rfkill wimax;
203         struct asus_rfkill wwan3g;
204         struct asus_rfkill gps;
205         struct asus_rfkill uwb;
206
207         struct hotplug_slot *hotplug_slot;
208         struct mutex hotplug_lock;
209         struct mutex wmi_lock;
210         struct workqueue_struct *hotplug_workqueue;
211         struct work_struct hotplug_work;
212
213         struct asus_wmi_debug debug;
214
215         struct asus_wmi_driver *driver;
216 };
217
218 static int asus_wmi_input_init(struct asus_wmi *asus)
219 {
220         int err;
221
222         asus->inputdev = input_allocate_device();
223         if (!asus->inputdev)
224                 return -ENOMEM;
225
226         asus->inputdev->name = asus->driver->input_name;
227         asus->inputdev->phys = asus->driver->input_phys;
228         asus->inputdev->id.bustype = BUS_HOST;
229         asus->inputdev->dev.parent = &asus->platform_device->dev;
230         set_bit(EV_REP, asus->inputdev->evbit);
231
232         err = sparse_keymap_setup(asus->inputdev, asus->driver->keymap, NULL);
233         if (err)
234                 goto err_free_dev;
235
236         err = input_register_device(asus->inputdev);
237         if (err)
238                 goto err_free_keymap;
239
240         return 0;
241
242 err_free_keymap:
243         sparse_keymap_free(asus->inputdev);
244 err_free_dev:
245         input_free_device(asus->inputdev);
246         return err;
247 }
248
249 static void asus_wmi_input_exit(struct asus_wmi *asus)
250 {
251         if (asus->inputdev) {
252                 sparse_keymap_free(asus->inputdev);
253                 input_unregister_device(asus->inputdev);
254         }
255
256         asus->inputdev = NULL;
257 }
258
259 static int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
260                                     u32 *retval)
261 {
262         struct bios_args args = {
263                 .arg0 = arg0,
264                 .arg1 = arg1,
265         };
266         struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
267         struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
268         acpi_status status;
269         union acpi_object *obj;
270         u32 tmp = 0;
271
272         status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 1, method_id,
273                                      &input, &output);
274
275         if (ACPI_FAILURE(status))
276                 goto exit;
277
278         obj = (union acpi_object *)output.pointer;
279         if (obj && obj->type == ACPI_TYPE_INTEGER)
280                 tmp = (u32) obj->integer.value;
281
282         if (retval)
283                 *retval = tmp;
284
285         kfree(obj);
286
287 exit:
288         if (ACPI_FAILURE(status))
289                 return -EIO;
290
291         if (tmp == ASUS_WMI_UNSUPPORTED_METHOD)
292                 return -ENODEV;
293
294         return 0;
295 }
296
297 static int asus_wmi_get_devstate(struct asus_wmi *asus, u32 dev_id, u32 *retval)
298 {
299         return asus_wmi_evaluate_method(asus->dsts_id, dev_id, 0, retval);
300 }
301
302 static int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
303                                  u32 *retval)
304 {
305         return asus_wmi_evaluate_method(ASUS_WMI_METHODID_DEVS, dev_id,
306                                         ctrl_param, retval);
307 }
308
309 /* Helper for special devices with magic return codes */
310 static int asus_wmi_get_devstate_bits(struct asus_wmi *asus,
311                                       u32 dev_id, u32 mask)
312 {
313         u32 retval = 0;
314         int err;
315
316         err = asus_wmi_get_devstate(asus, dev_id, &retval);
317
318         if (err < 0)
319                 return err;
320
321         if (!(retval & ASUS_WMI_DSTS_PRESENCE_BIT))
322                 return -ENODEV;
323
324         if (mask == ASUS_WMI_DSTS_STATUS_BIT) {
325                 if (retval & ASUS_WMI_DSTS_UNKNOWN_BIT)
326                         return -ENODEV;
327         }
328
329         return retval & mask;
330 }
331
332 static int asus_wmi_get_devstate_simple(struct asus_wmi *asus, u32 dev_id)
333 {
334         return asus_wmi_get_devstate_bits(asus, dev_id,
335                                           ASUS_WMI_DSTS_STATUS_BIT);
336 }
337
338 /*
339  * LEDs
340  */
341 /*
342  * These functions actually update the LED's, and are called from a
343  * workqueue. By doing this as separate work rather than when the LED
344  * subsystem asks, we avoid messing with the Asus ACPI stuff during a
345  * potentially bad time, such as a timer interrupt.
346  */
347 static void tpd_led_update(struct work_struct *work)
348 {
349         int ctrl_param;
350         struct asus_wmi *asus;
351
352         asus = container_of(work, struct asus_wmi, tpd_led_work);
353
354         ctrl_param = asus->tpd_led_wk;
355         asus_wmi_set_devstate(ASUS_WMI_DEVID_TOUCHPAD_LED, ctrl_param, NULL);
356 }
357
358 static void tpd_led_set(struct led_classdev *led_cdev,
359                         enum led_brightness value)
360 {
361         struct asus_wmi *asus;
362
363         asus = container_of(led_cdev, struct asus_wmi, tpd_led);
364
365         asus->tpd_led_wk = !!value;
366         queue_work(asus->led_workqueue, &asus->tpd_led_work);
367 }
368
369 static int read_tpd_led_state(struct asus_wmi *asus)
370 {
371         return asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_TOUCHPAD_LED);
372 }
373
374 static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
375 {
376         struct asus_wmi *asus;
377
378         asus = container_of(led_cdev, struct asus_wmi, tpd_led);
379
380         return read_tpd_led_state(asus);
381 }
382
383 static void kbd_led_update(struct work_struct *work)
384 {
385         int ctrl_param = 0;
386         struct asus_wmi *asus;
387
388         asus = container_of(work, struct asus_wmi, kbd_led_work);
389
390         /*
391          * bits 0-2: level
392          * bit 7: light on/off
393          */
394         if (asus->kbd_led_wk > 0)
395                 ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F);
396
397         asus_wmi_set_devstate(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param, NULL);
398 }
399
400 static int kbd_led_read(struct asus_wmi *asus, int *level, int *env)
401 {
402         int retval;
403
404         /*
405          * bits 0-2: level
406          * bit 7: light on/off
407          * bit 8-10: environment (0: dark, 1: normal, 2: light)
408          * bit 17: status unknown
409          */
410         retval = asus_wmi_get_devstate_bits(asus, ASUS_WMI_DEVID_KBD_BACKLIGHT,
411                                             0xFFFF);
412
413         /* Unknown status is considered as off */
414         if (retval == 0x8000)
415                 retval = 0;
416
417         if (retval >= 0) {
418                 if (level)
419                         *level = retval & 0x7F;
420                 if (env)
421                         *env = (retval >> 8) & 0x7F;
422                 retval = 0;
423         }
424
425         return retval;
426 }
427
428 static void kbd_led_set(struct led_classdev *led_cdev,
429                         enum led_brightness value)
430 {
431         struct asus_wmi *asus;
432
433         asus = container_of(led_cdev, struct asus_wmi, kbd_led);
434
435         if (value > asus->kbd_led.max_brightness)
436                 value = asus->kbd_led.max_brightness;
437         else if (value < 0)
438                 value = 0;
439
440         asus->kbd_led_wk = value;
441         queue_work(asus->led_workqueue, &asus->kbd_led_work);
442 }
443
444 static enum led_brightness kbd_led_get(struct led_classdev *led_cdev)
445 {
446         struct asus_wmi *asus;
447         int retval, value;
448
449         asus = container_of(led_cdev, struct asus_wmi, kbd_led);
450
451         retval = kbd_led_read(asus, &value, NULL);
452
453         if (retval < 0)
454                 return retval;
455
456         return value;
457 }
458
459 static int wlan_led_unknown_state(struct asus_wmi *asus)
460 {
461         u32 result;
462
463         asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WIRELESS_LED, &result);
464
465         return result & ASUS_WMI_DSTS_UNKNOWN_BIT;
466 }
467
468 static int wlan_led_presence(struct asus_wmi *asus)
469 {
470         u32 result;
471
472         asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WIRELESS_LED, &result);
473
474         return result & ASUS_WMI_DSTS_PRESENCE_BIT;
475 }
476
477 static void wlan_led_update(struct work_struct *work)
478 {
479         int ctrl_param;
480         struct asus_wmi *asus;
481
482         asus = container_of(work, struct asus_wmi, wlan_led_work);
483
484         ctrl_param = asus->wlan_led_wk;
485         asus_wmi_set_devstate(ASUS_WMI_DEVID_WIRELESS_LED, ctrl_param, NULL);
486 }
487
488 static void wlan_led_set(struct led_classdev *led_cdev,
489                          enum led_brightness value)
490 {
491         struct asus_wmi *asus;
492
493         asus = container_of(led_cdev, struct asus_wmi, wlan_led);
494
495         asus->wlan_led_wk = !!value;
496         queue_work(asus->led_workqueue, &asus->wlan_led_work);
497 }
498
499 static enum led_brightness wlan_led_get(struct led_classdev *led_cdev)
500 {
501         struct asus_wmi *asus;
502         u32 result;
503
504         asus = container_of(led_cdev, struct asus_wmi, wlan_led);
505         asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WIRELESS_LED, &result);
506
507         return result & ASUS_WMI_DSTS_BRIGHTNESS_MASK;
508 }
509
510 static void asus_wmi_led_exit(struct asus_wmi *asus)
511 {
512         if (!IS_ERR_OR_NULL(asus->kbd_led.dev))
513                 led_classdev_unregister(&asus->kbd_led);
514         if (!IS_ERR_OR_NULL(asus->tpd_led.dev))
515                 led_classdev_unregister(&asus->tpd_led);
516         if (!IS_ERR_OR_NULL(asus->wlan_led.dev))
517                 led_classdev_unregister(&asus->wlan_led);
518         if (asus->led_workqueue)
519                 destroy_workqueue(asus->led_workqueue);
520 }
521
522 static int asus_wmi_led_init(struct asus_wmi *asus)
523 {
524         int rv = 0;
525
526         asus->led_workqueue = create_singlethread_workqueue("led_workqueue");
527         if (!asus->led_workqueue)
528                 return -ENOMEM;
529
530         if (read_tpd_led_state(asus) >= 0) {
531                 INIT_WORK(&asus->tpd_led_work, tpd_led_update);
532
533                 asus->tpd_led.name = "asus::touchpad";
534                 asus->tpd_led.brightness_set = tpd_led_set;
535                 asus->tpd_led.brightness_get = tpd_led_get;
536                 asus->tpd_led.max_brightness = 1;
537
538                 rv = led_classdev_register(&asus->platform_device->dev,
539                                            &asus->tpd_led);
540                 if (rv)
541                         goto error;
542         }
543
544         if (kbd_led_read(asus, NULL, NULL) >= 0) {
545                 INIT_WORK(&asus->kbd_led_work, kbd_led_update);
546
547                 asus->kbd_led.name = "asus::kbd_backlight";
548                 asus->kbd_led.brightness_set = kbd_led_set;
549                 asus->kbd_led.brightness_get = kbd_led_get;
550                 asus->kbd_led.max_brightness = 3;
551
552                 rv = led_classdev_register(&asus->platform_device->dev,
553                                            &asus->kbd_led);
554                 if (rv)
555                         goto error;
556         }
557
558         if (wlan_led_presence(asus) && (asus->driver->quirks->wapf > 0)) {
559                 INIT_WORK(&asus->wlan_led_work, wlan_led_update);
560
561                 asus->wlan_led.name = "asus::wlan";
562                 asus->wlan_led.brightness_set = wlan_led_set;
563                 if (!wlan_led_unknown_state(asus))
564                         asus->wlan_led.brightness_get = wlan_led_get;
565                 asus->wlan_led.flags = LED_CORE_SUSPENDRESUME;
566                 asus->wlan_led.max_brightness = 1;
567                 asus->wlan_led.default_trigger = "asus-wlan";
568
569                 rv = led_classdev_register(&asus->platform_device->dev,
570                                            &asus->wlan_led);
571         }
572
573 error:
574         if (rv)
575                 asus_wmi_led_exit(asus);
576
577         return rv;
578 }
579
580
581 /*
582  * PCI hotplug (for wlan rfkill)
583  */
584 static bool asus_wlan_rfkill_blocked(struct asus_wmi *asus)
585 {
586         int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
587
588         if (result < 0)
589                 return false;
590         return !result;
591 }
592
593 static void asus_rfkill_hotplug(struct asus_wmi *asus)
594 {
595         struct pci_dev *dev;
596         struct pci_bus *bus;
597         bool blocked;
598         bool absent;
599         u32 l;
600
601         mutex_lock(&asus->wmi_lock);
602         blocked = asus_wlan_rfkill_blocked(asus);
603         mutex_unlock(&asus->wmi_lock);
604
605         mutex_lock(&asus->hotplug_lock);
606         pci_lock_rescan_remove();
607
608         if (asus->wlan.rfkill)
609                 rfkill_set_sw_state(asus->wlan.rfkill, blocked);
610
611         if (asus->hotplug_slot) {
612                 bus = pci_find_bus(0, 1);
613                 if (!bus) {
614                         pr_warn("Unable to find PCI bus 1?\n");
615                         goto out_unlock;
616                 }
617
618                 if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
619                         pr_err("Unable to read PCI config space?\n");
620                         goto out_unlock;
621                 }
622                 absent = (l == 0xffffffff);
623
624                 if (blocked != absent) {
625                         pr_warn("BIOS says wireless lan is %s, "
626                                 "but the pci device is %s\n",
627                                 blocked ? "blocked" : "unblocked",
628                                 absent ? "absent" : "present");
629                         pr_warn("skipped wireless hotplug as probably "
630                                 "inappropriate for this model\n");
631                         goto out_unlock;
632                 }
633
634                 if (!blocked) {
635                         dev = pci_get_slot(bus, 0);
636                         if (dev) {
637                                 /* Device already present */
638                                 pci_dev_put(dev);
639                                 goto out_unlock;
640                         }
641                         dev = pci_scan_single_device(bus, 0);
642                         if (dev) {
643                                 pci_bus_assign_resources(bus);
644                                 pci_bus_add_device(dev);
645                         }
646                 } else {
647                         dev = pci_get_slot(bus, 0);
648                         if (dev) {
649                                 pci_stop_and_remove_bus_device(dev);
650                                 pci_dev_put(dev);
651                         }
652                 }
653         }
654
655 out_unlock:
656         pci_unlock_rescan_remove();
657         mutex_unlock(&asus->hotplug_lock);
658 }
659
660 static void asus_rfkill_notify(acpi_handle handle, u32 event, void *data)
661 {
662         struct asus_wmi *asus = data;
663
664         if (event != ACPI_NOTIFY_BUS_CHECK)
665                 return;
666
667         /*
668          * We can't call directly asus_rfkill_hotplug because most
669          * of the time WMBC is still being executed and not reetrant.
670          * There is currently no way to tell ACPICA that  we want this
671          * method to be serialized, we schedule a asus_rfkill_hotplug
672          * call later, in a safer context.
673          */
674         queue_work(asus->hotplug_workqueue, &asus->hotplug_work);
675 }
676
677 static int asus_register_rfkill_notifier(struct asus_wmi *asus, char *node)
678 {
679         acpi_status status;
680         acpi_handle handle;
681
682         status = acpi_get_handle(NULL, node, &handle);
683
684         if (ACPI_SUCCESS(status)) {
685                 status = acpi_install_notify_handler(handle,
686                                                      ACPI_SYSTEM_NOTIFY,
687                                                      asus_rfkill_notify, asus);
688                 if (ACPI_FAILURE(status))
689                         pr_warn("Failed to register notify on %s\n", node);
690         } else
691                 return -ENODEV;
692
693         return 0;
694 }
695
696 static void asus_unregister_rfkill_notifier(struct asus_wmi *asus, char *node)
697 {
698         acpi_status status = AE_OK;
699         acpi_handle handle;
700
701         status = acpi_get_handle(NULL, node, &handle);
702
703         if (ACPI_SUCCESS(status)) {
704                 status = acpi_remove_notify_handler(handle,
705                                                     ACPI_SYSTEM_NOTIFY,
706                                                     asus_rfkill_notify);
707                 if (ACPI_FAILURE(status))
708                         pr_err("Error removing rfkill notify handler %s\n",
709                                node);
710         }
711 }
712
713 static int asus_get_adapter_status(struct hotplug_slot *hotplug_slot,
714                                    u8 *value)
715 {
716         struct asus_wmi *asus = hotplug_slot->private;
717         int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
718
719         if (result < 0)
720                 return result;
721
722         *value = !!result;
723         return 0;
724 }
725
726 static void asus_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
727 {
728         kfree(hotplug_slot->info);
729         kfree(hotplug_slot);
730 }
731
732 static struct hotplug_slot_ops asus_hotplug_slot_ops = {
733         .owner = THIS_MODULE,
734         .get_adapter_status = asus_get_adapter_status,
735         .get_power_status = asus_get_adapter_status,
736 };
737
738 static void asus_hotplug_work(struct work_struct *work)
739 {
740         struct asus_wmi *asus;
741
742         asus = container_of(work, struct asus_wmi, hotplug_work);
743         asus_rfkill_hotplug(asus);
744 }
745
746 static int asus_setup_pci_hotplug(struct asus_wmi *asus)
747 {
748         int ret = -ENOMEM;
749         struct pci_bus *bus = pci_find_bus(0, 1);
750
751         if (!bus) {
752                 pr_err("Unable to find wifi PCI bus\n");
753                 return -ENODEV;
754         }
755
756         asus->hotplug_workqueue =
757             create_singlethread_workqueue("hotplug_workqueue");
758         if (!asus->hotplug_workqueue)
759                 goto error_workqueue;
760
761         INIT_WORK(&asus->hotplug_work, asus_hotplug_work);
762
763         asus->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
764         if (!asus->hotplug_slot)
765                 goto error_slot;
766
767         asus->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
768                                            GFP_KERNEL);
769         if (!asus->hotplug_slot->info)
770                 goto error_info;
771
772         asus->hotplug_slot->private = asus;
773         asus->hotplug_slot->release = &asus_cleanup_pci_hotplug;
774         asus->hotplug_slot->ops = &asus_hotplug_slot_ops;
775         asus_get_adapter_status(asus->hotplug_slot,
776                                 &asus->hotplug_slot->info->adapter_status);
777
778         ret = pci_hp_register(asus->hotplug_slot, bus, 0, "asus-wifi");
779         if (ret) {
780                 pr_err("Unable to register hotplug slot - %d\n", ret);
781                 goto error_register;
782         }
783
784         return 0;
785
786 error_register:
787         kfree(asus->hotplug_slot->info);
788 error_info:
789         kfree(asus->hotplug_slot);
790         asus->hotplug_slot = NULL;
791 error_slot:
792         destroy_workqueue(asus->hotplug_workqueue);
793 error_workqueue:
794         return ret;
795 }
796
797 /*
798  * Rfkill devices
799  */
800 static int asus_rfkill_set(void *data, bool blocked)
801 {
802         struct asus_rfkill *priv = data;
803         u32 ctrl_param = !blocked;
804         u32 dev_id = priv->dev_id;
805
806         /*
807          * If the user bit is set, BIOS can't set and record the wlan status,
808          * it will report the value read from id ASUS_WMI_DEVID_WLAN_LED
809          * while we query the wlan status through WMI(ASUS_WMI_DEVID_WLAN).
810          * So, we have to record wlan status in id ASUS_WMI_DEVID_WLAN_LED
811          * while setting the wlan status through WMI.
812          * This is also the behavior that windows app will do.
813          */
814         if ((dev_id == ASUS_WMI_DEVID_WLAN) &&
815              priv->asus->driver->wlan_ctrl_by_user)
816                 dev_id = ASUS_WMI_DEVID_WLAN_LED;
817
818         return asus_wmi_set_devstate(dev_id, ctrl_param, NULL);
819 }
820
821 static void asus_rfkill_query(struct rfkill *rfkill, void *data)
822 {
823         struct asus_rfkill *priv = data;
824         int result;
825
826         result = asus_wmi_get_devstate_simple(priv->asus, priv->dev_id);
827
828         if (result < 0)
829                 return;
830
831         rfkill_set_sw_state(priv->rfkill, !result);
832 }
833
834 static int asus_rfkill_wlan_set(void *data, bool blocked)
835 {
836         struct asus_rfkill *priv = data;
837         struct asus_wmi *asus = priv->asus;
838         int ret;
839
840         /*
841          * This handler is enabled only if hotplug is enabled.
842          * In this case, the asus_wmi_set_devstate() will
843          * trigger a wmi notification and we need to wait
844          * this call to finish before being able to call
845          * any wmi method
846          */
847         mutex_lock(&asus->wmi_lock);
848         ret = asus_rfkill_set(data, blocked);
849         mutex_unlock(&asus->wmi_lock);
850         return ret;
851 }
852
853 static const struct rfkill_ops asus_rfkill_wlan_ops = {
854         .set_block = asus_rfkill_wlan_set,
855         .query = asus_rfkill_query,
856 };
857
858 static const struct rfkill_ops asus_rfkill_ops = {
859         .set_block = asus_rfkill_set,
860         .query = asus_rfkill_query,
861 };
862
863 static int asus_new_rfkill(struct asus_wmi *asus,
864                            struct asus_rfkill *arfkill,
865                            const char *name, enum rfkill_type type, int dev_id)
866 {
867         int result = asus_wmi_get_devstate_simple(asus, dev_id);
868         struct rfkill **rfkill = &arfkill->rfkill;
869
870         if (result < 0)
871                 return result;
872
873         arfkill->dev_id = dev_id;
874         arfkill->asus = asus;
875
876         if (dev_id == ASUS_WMI_DEVID_WLAN &&
877             asus->driver->quirks->hotplug_wireless)
878                 *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type,
879                                        &asus_rfkill_wlan_ops, arfkill);
880         else
881                 *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type,
882                                        &asus_rfkill_ops, arfkill);
883
884         if (!*rfkill)
885                 return -EINVAL;
886
887         if ((dev_id == ASUS_WMI_DEVID_WLAN) &&
888                         (asus->driver->quirks->wapf > 0))
889                 rfkill_set_led_trigger_name(*rfkill, "asus-wlan");
890
891         rfkill_init_sw_state(*rfkill, !result);
892         result = rfkill_register(*rfkill);
893         if (result) {
894                 rfkill_destroy(*rfkill);
895                 *rfkill = NULL;
896                 return result;
897         }
898         return 0;
899 }
900
901 static void asus_wmi_rfkill_exit(struct asus_wmi *asus)
902 {
903         asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P5");
904         asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P6");
905         asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P7");
906         if (asus->wlan.rfkill) {
907                 rfkill_unregister(asus->wlan.rfkill);
908                 rfkill_destroy(asus->wlan.rfkill);
909                 asus->wlan.rfkill = NULL;
910         }
911         /*
912          * Refresh pci hotplug in case the rfkill state was changed after
913          * asus_unregister_rfkill_notifier()
914          */
915         asus_rfkill_hotplug(asus);
916         if (asus->hotplug_slot)
917                 pci_hp_deregister(asus->hotplug_slot);
918         if (asus->hotplug_workqueue)
919                 destroy_workqueue(asus->hotplug_workqueue);
920
921         if (asus->bluetooth.rfkill) {
922                 rfkill_unregister(asus->bluetooth.rfkill);
923                 rfkill_destroy(asus->bluetooth.rfkill);
924                 asus->bluetooth.rfkill = NULL;
925         }
926         if (asus->wimax.rfkill) {
927                 rfkill_unregister(asus->wimax.rfkill);
928                 rfkill_destroy(asus->wimax.rfkill);
929                 asus->wimax.rfkill = NULL;
930         }
931         if (asus->wwan3g.rfkill) {
932                 rfkill_unregister(asus->wwan3g.rfkill);
933                 rfkill_destroy(asus->wwan3g.rfkill);
934                 asus->wwan3g.rfkill = NULL;
935         }
936         if (asus->gps.rfkill) {
937                 rfkill_unregister(asus->gps.rfkill);
938                 rfkill_destroy(asus->gps.rfkill);
939                 asus->gps.rfkill = NULL;
940         }
941         if (asus->uwb.rfkill) {
942                 rfkill_unregister(asus->uwb.rfkill);
943                 rfkill_destroy(asus->uwb.rfkill);
944                 asus->uwb.rfkill = NULL;
945         }
946 }
947
948 static int asus_wmi_rfkill_init(struct asus_wmi *asus)
949 {
950         int result = 0;
951
952         mutex_init(&asus->hotplug_lock);
953         mutex_init(&asus->wmi_lock);
954
955         result = asus_new_rfkill(asus, &asus->wlan, "asus-wlan",
956                                  RFKILL_TYPE_WLAN, ASUS_WMI_DEVID_WLAN);
957
958         if (result && result != -ENODEV)
959                 goto exit;
960
961         result = asus_new_rfkill(asus, &asus->bluetooth,
962                                  "asus-bluetooth", RFKILL_TYPE_BLUETOOTH,
963                                  ASUS_WMI_DEVID_BLUETOOTH);
964
965         if (result && result != -ENODEV)
966                 goto exit;
967
968         result = asus_new_rfkill(asus, &asus->wimax, "asus-wimax",
969                                  RFKILL_TYPE_WIMAX, ASUS_WMI_DEVID_WIMAX);
970
971         if (result && result != -ENODEV)
972                 goto exit;
973
974         result = asus_new_rfkill(asus, &asus->wwan3g, "asus-wwan3g",
975                                  RFKILL_TYPE_WWAN, ASUS_WMI_DEVID_WWAN3G);
976
977         if (result && result != -ENODEV)
978                 goto exit;
979
980         result = asus_new_rfkill(asus, &asus->gps, "asus-gps",
981                                  RFKILL_TYPE_GPS, ASUS_WMI_DEVID_GPS);
982
983         if (result && result != -ENODEV)
984                 goto exit;
985
986         result = asus_new_rfkill(asus, &asus->uwb, "asus-uwb",
987                                  RFKILL_TYPE_UWB, ASUS_WMI_DEVID_UWB);
988
989         if (result && result != -ENODEV)
990                 goto exit;
991
992         if (!asus->driver->quirks->hotplug_wireless)
993                 goto exit;
994
995         result = asus_setup_pci_hotplug(asus);
996         /*
997          * If we get -EBUSY then something else is handling the PCI hotplug -
998          * don't fail in this case
999          */
1000         if (result == -EBUSY)
1001                 result = 0;
1002
1003         asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P5");
1004         asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P6");
1005         asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P7");
1006         /*
1007          * Refresh pci hotplug in case the rfkill state was changed during
1008          * setup.
1009          */
1010         asus_rfkill_hotplug(asus);
1011
1012 exit:
1013         if (result && result != -ENODEV)
1014                 asus_wmi_rfkill_exit(asus);
1015
1016         if (result == -ENODEV)
1017                 result = 0;
1018
1019         return result;
1020 }
1021
1022 /*
1023  * Hwmon device
1024  */
1025 static ssize_t asus_hwmon_pwm1(struct device *dev,
1026                                struct device_attribute *attr,
1027                                char *buf)
1028 {
1029         struct asus_wmi *asus = dev_get_drvdata(dev);
1030         u32 value;
1031         int err;
1032
1033         err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, &value);
1034
1035         if (err < 0)
1036                 return err;
1037
1038         value &= 0xFF;
1039
1040         if (value == 1) /* Low Speed */
1041                 value = 85;
1042         else if (value == 2)
1043                 value = 170;
1044         else if (value == 3)
1045                 value = 255;
1046         else if (value != 0) {
1047                 pr_err("Unknown fan speed %#x\n", value);
1048                 value = -1;
1049         }
1050
1051         return sprintf(buf, "%d\n", value);
1052 }
1053
1054 static ssize_t asus_hwmon_temp1(struct device *dev,
1055                                 struct device_attribute *attr,
1056                                 char *buf)
1057 {
1058         struct asus_wmi *asus = dev_get_drvdata(dev);
1059         u32 value;
1060         int err;
1061
1062         err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_THERMAL_CTRL, &value);
1063
1064         if (err < 0)
1065                 return err;
1066
1067         value = KELVIN_TO_CELSIUS((value & 0xFFFF)) * 1000;
1068
1069         return sprintf(buf, "%d\n", value);
1070 }
1071
1072 static DEVICE_ATTR(pwm1, S_IRUGO, asus_hwmon_pwm1, NULL);
1073 static DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL);
1074
1075 static struct attribute *hwmon_attributes[] = {
1076         &dev_attr_pwm1.attr,
1077         &dev_attr_temp1_input.attr,
1078         NULL
1079 };
1080
1081 static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj,
1082                                           struct attribute *attr, int idx)
1083 {
1084         struct device *dev = container_of(kobj, struct device, kobj);
1085         struct platform_device *pdev = to_platform_device(dev->parent);
1086         struct asus_wmi *asus = platform_get_drvdata(pdev);
1087         bool ok = true;
1088         int dev_id = -1;
1089         u32 value = ASUS_WMI_UNSUPPORTED_METHOD;
1090
1091         if (attr == &dev_attr_pwm1.attr)
1092                 dev_id = ASUS_WMI_DEVID_FAN_CTRL;
1093         else if (attr == &dev_attr_temp1_input.attr)
1094                 dev_id = ASUS_WMI_DEVID_THERMAL_CTRL;
1095
1096         if (dev_id != -1) {
1097                 int err = asus_wmi_get_devstate(asus, dev_id, &value);
1098
1099                 if (err < 0)
1100                         return 0; /* can't return negative here */
1101         }
1102
1103         if (dev_id == ASUS_WMI_DEVID_FAN_CTRL) {
1104                 /*
1105                  * We need to find a better way, probably using sfun,
1106                  * bits or spec ...
1107                  * Currently we disable it if:
1108                  * - ASUS_WMI_UNSUPPORTED_METHOD is returned
1109                  * - reverved bits are non-zero
1110                  * - sfun and presence bit are not set
1111                  */
1112                 if (value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000
1113                     || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT)))
1114                         ok = false;
1115         } else if (dev_id == ASUS_WMI_DEVID_THERMAL_CTRL) {
1116                 /* If value is zero, something is clearly wrong */
1117                 if (value == 0)
1118                         ok = false;
1119         }
1120
1121         return ok ? attr->mode : 0;
1122 }
1123
1124 static struct attribute_group hwmon_attribute_group = {
1125         .is_visible = asus_hwmon_sysfs_is_visible,
1126         .attrs = hwmon_attributes
1127 };
1128 __ATTRIBUTE_GROUPS(hwmon_attribute);
1129
1130 static int asus_wmi_hwmon_init(struct asus_wmi *asus)
1131 {
1132         struct device *hwmon;
1133
1134         hwmon = hwmon_device_register_with_groups(&asus->platform_device->dev,
1135                                                   "asus", asus,
1136                                                   hwmon_attribute_groups);
1137         if (IS_ERR(hwmon)) {
1138                 pr_err("Could not register asus hwmon device\n");
1139                 return PTR_ERR(hwmon);
1140         }
1141         return 0;
1142 }
1143
1144 /*
1145  * Backlight
1146  */
1147 static int read_backlight_power(struct asus_wmi *asus)
1148 {
1149         int ret;
1150         if (asus->driver->quirks->store_backlight_power)
1151                 ret = !asus->driver->panel_power;
1152         else
1153                 ret = asus_wmi_get_devstate_simple(asus,
1154                                                    ASUS_WMI_DEVID_BACKLIGHT);
1155
1156         if (ret < 0)
1157                 return ret;
1158
1159         return ret ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
1160 }
1161
1162 static int read_brightness_max(struct asus_wmi *asus)
1163 {
1164         u32 retval;
1165         int err;
1166
1167         err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval);
1168
1169         if (err < 0)
1170                 return err;
1171
1172         retval = retval & ASUS_WMI_DSTS_MAX_BRIGTH_MASK;
1173         retval >>= 8;
1174
1175         if (!retval)
1176                 return -ENODEV;
1177
1178         return retval;
1179 }
1180
1181 static int read_brightness(struct backlight_device *bd)
1182 {
1183         struct asus_wmi *asus = bl_get_data(bd);
1184         u32 retval;
1185         int err;
1186
1187         err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval);
1188
1189         if (err < 0)
1190                 return err;
1191
1192         return retval & ASUS_WMI_DSTS_BRIGHTNESS_MASK;
1193 }
1194
1195 static u32 get_scalar_command(struct backlight_device *bd)
1196 {
1197         struct asus_wmi *asus = bl_get_data(bd);
1198         u32 ctrl_param = 0;
1199
1200         if ((asus->driver->brightness < bd->props.brightness) ||
1201             bd->props.brightness == bd->props.max_brightness)
1202                 ctrl_param = 0x00008001;
1203         else if ((asus->driver->brightness > bd->props.brightness) ||
1204                  bd->props.brightness == 0)
1205                 ctrl_param = 0x00008000;
1206
1207         asus->driver->brightness = bd->props.brightness;
1208
1209         return ctrl_param;
1210 }
1211
1212 static int update_bl_status(struct backlight_device *bd)
1213 {
1214         struct asus_wmi *asus = bl_get_data(bd);
1215         u32 ctrl_param;
1216         int power, err = 0;
1217
1218         power = read_backlight_power(asus);
1219         if (power != -ENODEV && bd->props.power != power) {
1220                 ctrl_param = !!(bd->props.power == FB_BLANK_UNBLANK);
1221                 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BACKLIGHT,
1222                                             ctrl_param, NULL);
1223                 if (asus->driver->quirks->store_backlight_power)
1224                         asus->driver->panel_power = bd->props.power;
1225
1226                 /* When using scalar brightness, updating the brightness
1227                  * will mess with the backlight power */
1228                 if (asus->driver->quirks->scalar_panel_brightness)
1229                         return err;
1230         }
1231
1232         if (asus->driver->quirks->scalar_panel_brightness)
1233                 ctrl_param = get_scalar_command(bd);
1234         else
1235                 ctrl_param = bd->props.brightness;
1236
1237         err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BRIGHTNESS,
1238                                     ctrl_param, NULL);
1239
1240         return err;
1241 }
1242
1243 static const struct backlight_ops asus_wmi_bl_ops = {
1244         .get_brightness = read_brightness,
1245         .update_status = update_bl_status,
1246 };
1247
1248 static int asus_wmi_backlight_notify(struct asus_wmi *asus, int code)
1249 {
1250         struct backlight_device *bd = asus->backlight_device;
1251         int old = bd->props.brightness;
1252         int new = old;
1253
1254         if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
1255                 new = code - NOTIFY_BRNUP_MIN + 1;
1256         else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
1257                 new = code - NOTIFY_BRNDOWN_MIN;
1258
1259         bd->props.brightness = new;
1260         backlight_update_status(bd);
1261         backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
1262
1263         return old;
1264 }
1265
1266 static int asus_wmi_backlight_init(struct asus_wmi *asus)
1267 {
1268         struct backlight_device *bd;
1269         struct backlight_properties props;
1270         int max;
1271         int power;
1272
1273         max = read_brightness_max(asus);
1274         if (max < 0)
1275                 return max;
1276
1277         power = read_backlight_power(asus);
1278
1279         if (power == -ENODEV)
1280                 power = FB_BLANK_UNBLANK;
1281         else if (power < 0)
1282                 return power;
1283
1284         memset(&props, 0, sizeof(struct backlight_properties));
1285         props.type = BACKLIGHT_PLATFORM;
1286         props.max_brightness = max;
1287         bd = backlight_device_register(asus->driver->name,
1288                                        &asus->platform_device->dev, asus,
1289                                        &asus_wmi_bl_ops, &props);
1290         if (IS_ERR(bd)) {
1291                 pr_err("Could not register backlight device\n");
1292                 return PTR_ERR(bd);
1293         }
1294
1295         asus->backlight_device = bd;
1296
1297         if (asus->driver->quirks->store_backlight_power)
1298                 asus->driver->panel_power = power;
1299
1300         bd->props.brightness = read_brightness(bd);
1301         bd->props.power = power;
1302         backlight_update_status(bd);
1303
1304         asus->driver->brightness = bd->props.brightness;
1305
1306         return 0;
1307 }
1308
1309 static void asus_wmi_backlight_exit(struct asus_wmi *asus)
1310 {
1311         backlight_device_unregister(asus->backlight_device);
1312
1313         asus->backlight_device = NULL;
1314 }
1315
1316 static int is_display_toggle(int code)
1317 {
1318         /* display toggle keys */
1319         if ((code >= 0x61 && code <= 0x67) ||
1320             (code >= 0x8c && code <= 0x93) ||
1321             (code >= 0xa0 && code <= 0xa7) ||
1322             (code >= 0xd0 && code <= 0xd5))
1323                 return 1;
1324
1325         return 0;
1326 }
1327
1328 static void asus_wmi_notify(u32 value, void *context)
1329 {
1330         struct asus_wmi *asus = context;
1331         struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
1332         union acpi_object *obj;
1333         acpi_status status;
1334         int code;
1335         int orig_code;
1336         unsigned int key_value = 1;
1337         bool autorelease = 1;
1338
1339         status = wmi_get_event_data(value, &response);
1340         if (status != AE_OK) {
1341                 pr_err("bad event status 0x%x\n", status);
1342                 return;
1343         }
1344
1345         obj = (union acpi_object *)response.pointer;
1346
1347         if (!obj || obj->type != ACPI_TYPE_INTEGER)
1348                 goto exit;
1349
1350         code = obj->integer.value;
1351         orig_code = code;
1352
1353         if (asus->driver->key_filter) {
1354                 asus->driver->key_filter(asus->driver, &code, &key_value,
1355                                          &autorelease);
1356                 if (code == ASUS_WMI_KEY_IGNORE)
1357                         goto exit;
1358         }
1359
1360         if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
1361                 code = ASUS_WMI_BRN_UP;
1362         else if (code >= NOTIFY_BRNDOWN_MIN &&
1363                  code <= NOTIFY_BRNDOWN_MAX)
1364                 code = ASUS_WMI_BRN_DOWN;
1365
1366         if (code == ASUS_WMI_BRN_DOWN || code == ASUS_WMI_BRN_UP) {
1367                 if (!acpi_video_backlight_support()) {
1368                         asus_wmi_backlight_notify(asus, orig_code);
1369                         goto exit;
1370                 }
1371         }
1372
1373         if (is_display_toggle(code) &&
1374             asus->driver->quirks->no_display_toggle)
1375                 goto exit;
1376
1377         if (!sparse_keymap_report_event(asus->inputdev, code,
1378                                         key_value, autorelease))
1379                 pr_info("Unknown key %x pressed\n", code);
1380
1381 exit:
1382         kfree(obj);
1383 }
1384
1385 /*
1386  * Sys helpers
1387  */
1388 static int parse_arg(const char *buf, unsigned long count, int *val)
1389 {
1390         if (!count)
1391                 return 0;
1392         if (sscanf(buf, "%i", val) != 1)
1393                 return -EINVAL;
1394         return count;
1395 }
1396
1397 static ssize_t store_sys_wmi(struct asus_wmi *asus, int devid,
1398                              const char *buf, size_t count)
1399 {
1400         u32 retval;
1401         int rv, err, value;
1402
1403         value = asus_wmi_get_devstate_simple(asus, devid);
1404         if (value == -ENODEV)   /* Check device presence */
1405                 return value;
1406
1407         rv = parse_arg(buf, count, &value);
1408         err = asus_wmi_set_devstate(devid, value, &retval);
1409
1410         if (err < 0)
1411                 return err;
1412
1413         return rv;
1414 }
1415
1416 static ssize_t show_sys_wmi(struct asus_wmi *asus, int devid, char *buf)
1417 {
1418         int value = asus_wmi_get_devstate_simple(asus, devid);
1419
1420         if (value < 0)
1421                 return value;
1422
1423         return sprintf(buf, "%d\n", value);
1424 }
1425
1426 #define ASUS_WMI_CREATE_DEVICE_ATTR(_name, _mode, _cm)                  \
1427         static ssize_t show_##_name(struct device *dev,                 \
1428                                     struct device_attribute *attr,      \
1429                                     char *buf)                          \
1430         {                                                               \
1431                 struct asus_wmi *asus = dev_get_drvdata(dev);           \
1432                                                                         \
1433                 return show_sys_wmi(asus, _cm, buf);                    \
1434         }                                                               \
1435         static ssize_t store_##_name(struct device *dev,                \
1436                                      struct device_attribute *attr,     \
1437                                      const char *buf, size_t count)     \
1438         {                                                               \
1439                 struct asus_wmi *asus = dev_get_drvdata(dev);           \
1440                                                                         \
1441                 return store_sys_wmi(asus, _cm, buf, count);            \
1442         }                                                               \
1443         static struct device_attribute dev_attr_##_name = {             \
1444                 .attr = {                                               \
1445                         .name = __stringify(_name),                     \
1446                         .mode = _mode },                                \
1447                 .show   = show_##_name,                                 \
1448                 .store  = store_##_name,                                \
1449         }
1450
1451 ASUS_WMI_CREATE_DEVICE_ATTR(touchpad, 0644, ASUS_WMI_DEVID_TOUCHPAD);
1452 ASUS_WMI_CREATE_DEVICE_ATTR(camera, 0644, ASUS_WMI_DEVID_CAMERA);
1453 ASUS_WMI_CREATE_DEVICE_ATTR(cardr, 0644, ASUS_WMI_DEVID_CARDREADER);
1454 ASUS_WMI_CREATE_DEVICE_ATTR(lid_resume, 0644, ASUS_WMI_DEVID_LID_RESUME);
1455
1456 static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr,
1457                            const char *buf, size_t count)
1458 {
1459         int value, rv;
1460
1461         if (!count || sscanf(buf, "%i", &value) != 1)
1462                 return -EINVAL;
1463         if (value < 0 || value > 2)
1464                 return -EINVAL;
1465
1466         rv = asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL);
1467         if (rv < 0)
1468                 return rv;
1469
1470         return count;
1471 }
1472
1473 static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv);
1474
1475 static struct attribute *platform_attributes[] = {
1476         &dev_attr_cpufv.attr,
1477         &dev_attr_camera.attr,
1478         &dev_attr_cardr.attr,
1479         &dev_attr_touchpad.attr,
1480         &dev_attr_lid_resume.attr,
1481         NULL
1482 };
1483
1484 static umode_t asus_sysfs_is_visible(struct kobject *kobj,
1485                                     struct attribute *attr, int idx)
1486 {
1487         struct device *dev = container_of(kobj, struct device, kobj);
1488         struct platform_device *pdev = to_platform_device(dev);
1489         struct asus_wmi *asus = platform_get_drvdata(pdev);
1490         bool ok = true;
1491         int devid = -1;
1492
1493         if (attr == &dev_attr_camera.attr)
1494                 devid = ASUS_WMI_DEVID_CAMERA;
1495         else if (attr == &dev_attr_cardr.attr)
1496                 devid = ASUS_WMI_DEVID_CARDREADER;
1497         else if (attr == &dev_attr_touchpad.attr)
1498                 devid = ASUS_WMI_DEVID_TOUCHPAD;
1499         else if (attr == &dev_attr_lid_resume.attr)
1500                 devid = ASUS_WMI_DEVID_LID_RESUME;
1501
1502         if (devid != -1)
1503                 ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0);
1504
1505         return ok ? attr->mode : 0;
1506 }
1507
1508 static struct attribute_group platform_attribute_group = {
1509         .is_visible = asus_sysfs_is_visible,
1510         .attrs = platform_attributes
1511 };
1512
1513 static void asus_wmi_sysfs_exit(struct platform_device *device)
1514 {
1515         sysfs_remove_group(&device->dev.kobj, &platform_attribute_group);
1516 }
1517
1518 static int asus_wmi_sysfs_init(struct platform_device *device)
1519 {
1520         return sysfs_create_group(&device->dev.kobj, &platform_attribute_group);
1521 }
1522
1523 /*
1524  * Platform device
1525  */
1526 static int asus_wmi_platform_init(struct asus_wmi *asus)
1527 {
1528         int rv;
1529
1530         /* INIT enable hotkeys on some models */
1531         if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_INIT, 0, 0, &rv))
1532                 pr_info("Initialization: %#x\n", rv);
1533
1534         /* We don't know yet what to do with this version... */
1535         if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SPEC, 0, 0x9, &rv)) {
1536                 pr_info("BIOS WMI version: %d.%d\n", rv >> 16, rv & 0xFF);
1537                 asus->spec = rv;
1538         }
1539
1540         /*
1541          * The SFUN method probably allows the original driver to get the list
1542          * of features supported by a given model. For now, 0x0100 or 0x0800
1543          * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card.
1544          * The significance of others is yet to be found.
1545          */
1546         if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SFUN, 0, 0, &rv)) {
1547                 pr_info("SFUN value: %#x\n", rv);
1548                 asus->sfun = rv;
1549         }
1550
1551         /*
1552          * Eee PC and Notebooks seems to have different method_id for DSTS,
1553          * but it may also be related to the BIOS's SPEC.
1554          * Note, on most Eeepc, there is no way to check if a method exist
1555          * or note, while on notebooks, they returns 0xFFFFFFFE on failure,
1556          * but once again, SPEC may probably be used for that kind of things.
1557          */
1558         if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, 0, 0, NULL))
1559                 asus->dsts_id = ASUS_WMI_METHODID_DSTS;
1560         else
1561                 asus->dsts_id = ASUS_WMI_METHODID_DSTS2;
1562
1563         /* CWAP allow to define the behavior of the Fn+F2 key,
1564          * this method doesn't seems to be present on Eee PCs */
1565         if (asus->driver->quirks->wapf >= 0)
1566                 asus_wmi_set_devstate(ASUS_WMI_DEVID_CWAP,
1567                                       asus->driver->quirks->wapf, NULL);
1568
1569         return asus_wmi_sysfs_init(asus->platform_device);
1570 }
1571
1572 static void asus_wmi_platform_exit(struct asus_wmi *asus)
1573 {
1574         asus_wmi_sysfs_exit(asus->platform_device);
1575 }
1576
1577 /*
1578  * debugfs
1579  */
1580 struct asus_wmi_debugfs_node {
1581         struct asus_wmi *asus;
1582         char *name;
1583         int (*show) (struct seq_file *m, void *data);
1584 };
1585
1586 static int show_dsts(struct seq_file *m, void *data)
1587 {
1588         struct asus_wmi *asus = m->private;
1589         int err;
1590         u32 retval = -1;
1591
1592         err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
1593
1594         if (err < 0)
1595                 return err;
1596
1597         seq_printf(m, "DSTS(%#x) = %#x\n", asus->debug.dev_id, retval);
1598
1599         return 0;
1600 }
1601
1602 static int show_devs(struct seq_file *m, void *data)
1603 {
1604         struct asus_wmi *asus = m->private;
1605         int err;
1606         u32 retval = -1;
1607
1608         err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
1609                                     &retval);
1610
1611         if (err < 0)
1612                 return err;
1613
1614         seq_printf(m, "DEVS(%#x, %#x) = %#x\n", asus->debug.dev_id,
1615                    asus->debug.ctrl_param, retval);
1616
1617         return 0;
1618 }
1619
1620 static int show_call(struct seq_file *m, void *data)
1621 {
1622         struct asus_wmi *asus = m->private;
1623         struct bios_args args = {
1624                 .arg0 = asus->debug.dev_id,
1625                 .arg1 = asus->debug.ctrl_param,
1626         };
1627         struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
1628         struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
1629         union acpi_object *obj;
1630         acpi_status status;
1631
1632         status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
1633                                      1, asus->debug.method_id,
1634                                      &input, &output);
1635
1636         if (ACPI_FAILURE(status))
1637                 return -EIO;
1638
1639         obj = (union acpi_object *)output.pointer;
1640         if (obj && obj->type == ACPI_TYPE_INTEGER)
1641                 seq_printf(m, "%#x(%#x, %#x) = %#x\n", asus->debug.method_id,
1642                            asus->debug.dev_id, asus->debug.ctrl_param,
1643                            (u32) obj->integer.value);
1644         else
1645                 seq_printf(m, "%#x(%#x, %#x) = t:%d\n", asus->debug.method_id,
1646                            asus->debug.dev_id, asus->debug.ctrl_param,
1647                            obj ? obj->type : -1);
1648
1649         kfree(obj);
1650
1651         return 0;
1652 }
1653
1654 static struct asus_wmi_debugfs_node asus_wmi_debug_files[] = {
1655         {NULL, "devs", show_devs},
1656         {NULL, "dsts", show_dsts},
1657         {NULL, "call", show_call},
1658 };
1659
1660 static int asus_wmi_debugfs_open(struct inode *inode, struct file *file)
1661 {
1662         struct asus_wmi_debugfs_node *node = inode->i_private;
1663
1664         return single_open(file, node->show, node->asus);
1665 }
1666
1667 static const struct file_operations asus_wmi_debugfs_io_ops = {
1668         .owner = THIS_MODULE,
1669         .open = asus_wmi_debugfs_open,
1670         .read = seq_read,
1671         .llseek = seq_lseek,
1672         .release = single_release,
1673 };
1674
1675 static void asus_wmi_debugfs_exit(struct asus_wmi *asus)
1676 {
1677         debugfs_remove_recursive(asus->debug.root);
1678 }
1679
1680 static int asus_wmi_debugfs_init(struct asus_wmi *asus)
1681 {
1682         struct dentry *dent;
1683         int i;
1684
1685         asus->debug.root = debugfs_create_dir(asus->driver->name, NULL);
1686         if (!asus->debug.root) {
1687                 pr_err("failed to create debugfs directory\n");
1688                 goto error_debugfs;
1689         }
1690
1691         dent = debugfs_create_x32("method_id", S_IRUGO | S_IWUSR,
1692                                   asus->debug.root, &asus->debug.method_id);
1693         if (!dent)
1694                 goto error_debugfs;
1695
1696         dent = debugfs_create_x32("dev_id", S_IRUGO | S_IWUSR,
1697                                   asus->debug.root, &asus->debug.dev_id);
1698         if (!dent)
1699                 goto error_debugfs;
1700
1701         dent = debugfs_create_x32("ctrl_param", S_IRUGO | S_IWUSR,
1702                                   asus->debug.root, &asus->debug.ctrl_param);
1703         if (!dent)
1704                 goto error_debugfs;
1705
1706         for (i = 0; i < ARRAY_SIZE(asus_wmi_debug_files); i++) {
1707                 struct asus_wmi_debugfs_node *node = &asus_wmi_debug_files[i];
1708
1709                 node->asus = asus;
1710                 dent = debugfs_create_file(node->name, S_IFREG | S_IRUGO,
1711                                            asus->debug.root, node,
1712                                            &asus_wmi_debugfs_io_ops);
1713                 if (!dent) {
1714                         pr_err("failed to create debug file: %s\n", node->name);
1715                         goto error_debugfs;
1716                 }
1717         }
1718
1719         return 0;
1720
1721 error_debugfs:
1722         asus_wmi_debugfs_exit(asus);
1723         return -ENOMEM;
1724 }
1725
1726 /*
1727  * WMI Driver
1728  */
1729 static int asus_wmi_add(struct platform_device *pdev)
1730 {
1731         struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
1732         struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv);
1733         struct asus_wmi *asus;
1734         const char *chassis_type;
1735         acpi_status status;
1736         int err;
1737         u32 result;
1738
1739         asus = kzalloc(sizeof(struct asus_wmi), GFP_KERNEL);
1740         if (!asus)
1741                 return -ENOMEM;
1742
1743         asus->driver = wdrv;
1744         asus->platform_device = pdev;
1745         wdrv->platform_device = pdev;
1746         platform_set_drvdata(asus->platform_device, asus);
1747
1748         if (wdrv->detect_quirks)
1749                 wdrv->detect_quirks(asus->driver);
1750
1751         err = asus_wmi_platform_init(asus);
1752         if (err)
1753                 goto fail_platform;
1754
1755         err = asus_wmi_input_init(asus);
1756         if (err)
1757                 goto fail_input;
1758
1759         err = asus_wmi_hwmon_init(asus);
1760         if (err)
1761                 goto fail_hwmon;
1762
1763         err = asus_wmi_led_init(asus);
1764         if (err)
1765                 goto fail_leds;
1766
1767         err = asus_wmi_rfkill_init(asus);
1768         if (err)
1769                 goto fail_rfkill;
1770
1771         /* Some Asus desktop boards export an acpi-video backlight interface,
1772            stop this from showing up */
1773         chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE);
1774         if (chassis_type && !strcmp(chassis_type, "3"))
1775                 acpi_video_dmi_promote_vendor();
1776         if (asus->driver->quirks->wmi_backlight_power)
1777                 acpi_video_dmi_promote_vendor();
1778         if (!acpi_video_backlight_support()) {
1779                 pr_info("Disabling ACPI video driver\n");
1780                 acpi_video_unregister_backlight();
1781                 err = asus_wmi_backlight_init(asus);
1782                 if (err && err != -ENODEV)
1783                         goto fail_backlight;
1784         } else
1785                 pr_info("Backlight controlled by ACPI video driver\n");
1786
1787         status = wmi_install_notify_handler(asus->driver->event_guid,
1788                                             asus_wmi_notify, asus);
1789         if (ACPI_FAILURE(status)) {
1790                 pr_err("Unable to register notify handler - %d\n", status);
1791                 err = -ENODEV;
1792                 goto fail_wmi_handler;
1793         }
1794
1795         err = asus_wmi_debugfs_init(asus);
1796         if (err)
1797                 goto fail_debugfs;
1798
1799         asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result);
1800         if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT))
1801                 asus->driver->wlan_ctrl_by_user = 1;
1802
1803         return 0;
1804
1805 fail_debugfs:
1806         wmi_remove_notify_handler(asus->driver->event_guid);
1807 fail_wmi_handler:
1808         asus_wmi_backlight_exit(asus);
1809 fail_backlight:
1810         asus_wmi_rfkill_exit(asus);
1811 fail_rfkill:
1812         asus_wmi_led_exit(asus);
1813 fail_leds:
1814 fail_hwmon:
1815         asus_wmi_input_exit(asus);
1816 fail_input:
1817         asus_wmi_platform_exit(asus);
1818 fail_platform:
1819         kfree(asus);
1820         return err;
1821 }
1822
1823 static int asus_wmi_remove(struct platform_device *device)
1824 {
1825         struct asus_wmi *asus;
1826
1827         asus = platform_get_drvdata(device);
1828         wmi_remove_notify_handler(asus->driver->event_guid);
1829         asus_wmi_backlight_exit(asus);
1830         asus_wmi_input_exit(asus);
1831         asus_wmi_led_exit(asus);
1832         asus_wmi_rfkill_exit(asus);
1833         asus_wmi_debugfs_exit(asus);
1834         asus_wmi_platform_exit(asus);
1835
1836         kfree(asus);
1837         return 0;
1838 }
1839
1840 /*
1841  * Platform driver - hibernate/resume callbacks
1842  */
1843 static int asus_hotk_thaw(struct device *device)
1844 {
1845         struct asus_wmi *asus = dev_get_drvdata(device);
1846
1847         if (asus->wlan.rfkill) {
1848                 bool wlan;
1849
1850                 /*
1851                  * Work around bios bug - acpi _PTS turns off the wireless led
1852                  * during suspend.  Normally it restores it on resume, but
1853                  * we should kick it ourselves in case hibernation is aborted.
1854                  */
1855                 wlan = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
1856                 asus_wmi_set_devstate(ASUS_WMI_DEVID_WLAN, wlan, NULL);
1857         }
1858
1859         return 0;
1860 }
1861
1862 static int asus_hotk_restore(struct device *device)
1863 {
1864         struct asus_wmi *asus = dev_get_drvdata(device);
1865         int bl;
1866
1867         /* Refresh both wlan rfkill state and pci hotplug */
1868         if (asus->wlan.rfkill)
1869                 asus_rfkill_hotplug(asus);
1870
1871         if (asus->bluetooth.rfkill) {
1872                 bl = !asus_wmi_get_devstate_simple(asus,
1873                                                    ASUS_WMI_DEVID_BLUETOOTH);
1874                 rfkill_set_sw_state(asus->bluetooth.rfkill, bl);
1875         }
1876         if (asus->wimax.rfkill) {
1877                 bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WIMAX);
1878                 rfkill_set_sw_state(asus->wimax.rfkill, bl);
1879         }
1880         if (asus->wwan3g.rfkill) {
1881                 bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WWAN3G);
1882                 rfkill_set_sw_state(asus->wwan3g.rfkill, bl);
1883         }
1884         if (asus->gps.rfkill) {
1885                 bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPS);
1886                 rfkill_set_sw_state(asus->gps.rfkill, bl);
1887         }
1888         if (asus->uwb.rfkill) {
1889                 bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_UWB);
1890                 rfkill_set_sw_state(asus->uwb.rfkill, bl);
1891         }
1892
1893         return 0;
1894 }
1895
1896 static const struct dev_pm_ops asus_pm_ops = {
1897         .thaw = asus_hotk_thaw,
1898         .restore = asus_hotk_restore,
1899 };
1900
1901 static int asus_wmi_probe(struct platform_device *pdev)
1902 {
1903         struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
1904         struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv);
1905         int ret;
1906
1907         if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
1908                 pr_warn("Management GUID not found\n");
1909                 return -ENODEV;
1910         }
1911
1912         if (wdrv->event_guid && !wmi_has_guid(wdrv->event_guid)) {
1913                 pr_warn("Event GUID not found\n");
1914                 return -ENODEV;
1915         }
1916
1917         if (wdrv->probe) {
1918                 ret = wdrv->probe(pdev);
1919                 if (ret)
1920                         return ret;
1921         }
1922
1923         return asus_wmi_add(pdev);
1924 }
1925
1926 static bool used;
1927
1928 int __init_or_module asus_wmi_register_driver(struct asus_wmi_driver *driver)
1929 {
1930         struct platform_driver *platform_driver;
1931         struct platform_device *platform_device;
1932
1933         if (used)
1934                 return -EBUSY;
1935
1936         platform_driver = &driver->platform_driver;
1937         platform_driver->remove = asus_wmi_remove;
1938         platform_driver->driver.owner = driver->owner;
1939         platform_driver->driver.name = driver->name;
1940         platform_driver->driver.pm = &asus_pm_ops;
1941
1942         platform_device = platform_create_bundle(platform_driver,
1943                                                  asus_wmi_probe,
1944                                                  NULL, 0, NULL, 0);
1945         if (IS_ERR(platform_device))
1946                 return PTR_ERR(platform_device);
1947
1948         used = true;
1949         return 0;
1950 }
1951 EXPORT_SYMBOL_GPL(asus_wmi_register_driver);
1952
1953 void asus_wmi_unregister_driver(struct asus_wmi_driver *driver)
1954 {
1955         platform_device_unregister(driver->platform_device);
1956         platform_driver_unregister(&driver->platform_driver);
1957         used = false;
1958 }
1959 EXPORT_SYMBOL_GPL(asus_wmi_unregister_driver);
1960
1961 static int __init asus_wmi_init(void)
1962 {
1963         if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
1964                 pr_info("Asus Management GUID not found\n");
1965                 return -ENODEV;
1966         }
1967
1968         pr_info("ASUS WMI generic driver loaded\n");
1969         return 0;
1970 }
1971
1972 static void __exit asus_wmi_exit(void)
1973 {
1974         pr_info("ASUS WMI generic driver unloaded\n");
1975 }
1976
1977 module_init(asus_wmi_init);
1978 module_exit(asus_wmi_exit);