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