4c3f68a495d780fddd0ace985d0332d51ec852ef
[platform/adaptation/renesas_rcar/renesas_kernel.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/debugfs.h>
43 #include <linux/seq_file.h>
44 #include <linux/platform_device.h>
45 #include <acpi/acpi_bus.h>
46 #include <acpi/acpi_drivers.h>
47
48 #include "asus-wmi.h"
49
50 MODULE_AUTHOR("Corentin Chary <corentincj@iksaif.net>, "
51               "Yong Wang <yong.y.wang@intel.com>");
52 MODULE_DESCRIPTION("Asus Generic WMI Driver");
53 MODULE_LICENSE("GPL");
54
55 #define to_platform_driver(drv)                                 \
56         (container_of((drv), struct platform_driver, driver))
57
58 #define to_asus_wmi_driver(pdrv)                                        \
59         (container_of((pdrv), struct asus_wmi_driver, platform_driver))
60
61 #define ASUS_WMI_MGMT_GUID      "97845ED0-4E6D-11DE-8A39-0800200C9A66"
62
63 #define NOTIFY_BRNUP_MIN                0x11
64 #define NOTIFY_BRNUP_MAX                0x1f
65 #define NOTIFY_BRNDOWN_MIN              0x20
66 #define NOTIFY_BRNDOWN_MAX              0x2e
67
68 /* WMI Methods */
69 #define ASUS_WMI_METHODID_DSTS          0x53544344
70 #define ASUS_WMI_METHODID_DEVS          0x53564544
71 #define ASUS_WMI_METHODID_CFVS          0x53564643
72
73 /* Wireless */
74 #define ASUS_WMI_DEVID_WLAN             0x00010011
75 #define ASUS_WMI_DEVID_BLUETOOTH        0x00010013
76 #define ASUS_WMI_DEVID_WIMAX            0x00010017
77 #define ASUS_WMI_DEVID_WWAN3G           0x00010019
78
79 /* Backlight and Brightness */
80 #define ASUS_WMI_DEVID_BACKLIGHT        0x00050011
81 #define ASUS_WMI_DEVID_BRIGHTNESS       0x00050012
82
83 /* Misc */
84 #define ASUS_WMI_DEVID_CAMERA           0x00060013
85
86 /* Storage */
87 #define ASUS_WMI_DEVID_CARDREADER       0x00080013
88
89 /* Input */
90 #define ASUS_WMI_DEVID_TOUCHPAD         0x00100011
91 #define ASUS_WMI_DEVID_TOUCHPAD_LED     0x00100012
92
93 /* DSTS masks */
94 #define ASUS_WMI_DSTS_STATUS_BIT        0x00000001
95 #define ASUS_WMI_DSTS_PRESENCE_BIT      0x00010000
96 #define ASUS_WMI_DSTS_BRIGHTNESS_MASK   0x000000FF
97 #define ASUS_WMI_DSTS_MAX_BRIGTH_MASK   0x0000FF00
98
99 struct bios_args {
100         u32 dev_id;
101         u32 ctrl_param;
102 };
103
104 /*
105  * <platform>/    - debugfs root directory
106  *   dev_id      - current dev_id
107  *   ctrl_param  - current ctrl_param
108  *   devs        - call DEVS(dev_id, ctrl_param) and print result
109  *   dsts        - call DSTS(dev_id)  and print result
110  */
111 struct asus_wmi_debug {
112         struct dentry *root;
113         u32 dev_id;
114         u32 ctrl_param;
115 };
116
117 struct asus_wmi {
118         struct input_dev *inputdev;
119         struct backlight_device *backlight_device;
120         struct platform_device *platform_device;
121
122         struct led_classdev tpd_led;
123         int tpd_led_wk;
124         struct workqueue_struct *led_workqueue;
125         struct work_struct tpd_led_work;
126
127         struct rfkill *wlan_rfkill;
128         struct rfkill *bluetooth_rfkill;
129         struct rfkill *wimax_rfkill;
130         struct rfkill *wwan3g_rfkill;
131
132         struct hotplug_slot *hotplug_slot;
133         struct mutex hotplug_lock;
134         struct mutex wmi_lock;
135         struct workqueue_struct *hotplug_workqueue;
136         struct work_struct hotplug_work;
137
138         struct asus_wmi_debug debug;
139
140         struct asus_wmi_driver *driver;
141 };
142
143 static int asus_wmi_input_init(struct asus_wmi *asus)
144 {
145         int err;
146
147         asus->inputdev = input_allocate_device();
148         if (!asus->inputdev)
149                 return -ENOMEM;
150
151         asus->inputdev->name = asus->driver->input_phys;
152         asus->inputdev->phys = asus->driver->input_name;
153         asus->inputdev->id.bustype = BUS_HOST;
154         asus->inputdev->dev.parent = &asus->platform_device->dev;
155
156         err = sparse_keymap_setup(asus->inputdev, asus->driver->keymap, NULL);
157         if (err)
158                 goto err_free_dev;
159
160         err = input_register_device(asus->inputdev);
161         if (err)
162                 goto err_free_keymap;
163
164         return 0;
165
166 err_free_keymap:
167         sparse_keymap_free(asus->inputdev);
168 err_free_dev:
169         input_free_device(asus->inputdev);
170         return err;
171 }
172
173 static void asus_wmi_input_exit(struct asus_wmi *asus)
174 {
175         if (asus->inputdev) {
176                 sparse_keymap_free(asus->inputdev);
177                 input_unregister_device(asus->inputdev);
178         }
179
180         asus->inputdev = NULL;
181 }
182
183 static acpi_status asus_wmi_get_devstate(u32 dev_id, u32 *retval)
184 {
185         struct acpi_buffer input = { (acpi_size) sizeof(u32), &dev_id };
186         struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
187         union acpi_object *obj;
188         acpi_status status;
189         u32 tmp;
190
191         status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
192                                      1, ASUS_WMI_METHODID_DSTS,
193                                      &input, &output);
194
195         if (ACPI_FAILURE(status))
196                 return status;
197
198         obj = (union acpi_object *)output.pointer;
199         if (obj && obj->type == ACPI_TYPE_INTEGER)
200                 tmp = (u32) obj->integer.value;
201         else
202                 tmp = 0;
203
204         if (retval)
205                 *retval = tmp;
206
207         kfree(obj);
208
209         return status;
210
211 }
212
213 static acpi_status asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
214                                          u32 *retval)
215 {
216         struct bios_args args = {
217                 .dev_id = dev_id,
218                 .ctrl_param = ctrl_param,
219         };
220         struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
221         acpi_status status;
222
223         if (!retval) {
224                 status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 1,
225                                              ASUS_WMI_METHODID_DEVS,
226                                              &input, NULL);
227         } else {
228                 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
229                 union acpi_object *obj;
230                 u32 tmp;
231
232                 status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 1,
233                                              ASUS_WMI_METHODID_DEVS,
234                                              &input, &output);
235
236                 if (ACPI_FAILURE(status))
237                         return status;
238
239                 obj = (union acpi_object *)output.pointer;
240                 if (obj && obj->type == ACPI_TYPE_INTEGER)
241                         tmp = (u32) obj->integer.value;
242                 else
243                         tmp = 0;
244
245                 *retval = tmp;
246
247                 kfree(obj);
248         }
249
250         return status;
251 }
252
253 /* Helper for special devices with magic return codes */
254 static int asus_wmi_get_devstate_bits(u32 dev_id, u32 mask)
255 {
256         u32 retval = 0;
257         acpi_status status;
258
259         status = asus_wmi_get_devstate(dev_id, &retval);
260
261         if (ACPI_FAILURE(status))
262                 return -EINVAL;
263
264         if (!(retval & ASUS_WMI_DSTS_PRESENCE_BIT))
265                 return -ENODEV;
266
267         return retval & mask;
268 }
269
270 static int asus_wmi_get_devstate_simple(u32 dev_id)
271 {
272         return asus_wmi_get_devstate_bits(dev_id, ASUS_WMI_DSTS_STATUS_BIT);
273 }
274
275 /*
276  * LEDs
277  */
278 /*
279  * These functions actually update the LED's, and are called from a
280  * workqueue. By doing this as separate work rather than when the LED
281  * subsystem asks, we avoid messing with the Asus ACPI stuff during a
282  * potentially bad time, such as a timer interrupt.
283  */
284 static void tpd_led_update(struct work_struct *work)
285 {
286         int ctrl_param;
287         struct asus_wmi *asus;
288
289         asus = container_of(work, struct asus_wmi, tpd_led_work);
290
291         ctrl_param = asus->tpd_led_wk;
292         asus_wmi_set_devstate(ASUS_WMI_DEVID_TOUCHPAD_LED, ctrl_param, NULL);
293 }
294
295 static void tpd_led_set(struct led_classdev *led_cdev,
296                         enum led_brightness value)
297 {
298         struct asus_wmi *asus;
299
300         asus = container_of(led_cdev, struct asus_wmi, tpd_led);
301
302         asus->tpd_led_wk = !!value;
303         queue_work(asus->led_workqueue, &asus->tpd_led_work);
304 }
305
306 static int read_tpd_led_state(struct asus_wmi *asus)
307 {
308         return asus_wmi_get_devstate_simple(ASUS_WMI_DEVID_TOUCHPAD_LED);
309 }
310
311 static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
312 {
313         struct asus_wmi *asus;
314
315         asus = container_of(led_cdev, struct asus_wmi, tpd_led);
316
317         return read_tpd_led_state(asus);
318 }
319
320 static int asus_wmi_led_init(struct asus_wmi *asus)
321 {
322         int rv;
323
324         if (read_tpd_led_state(asus) < 0)
325                 return 0;
326
327         asus->led_workqueue = create_singlethread_workqueue("led_workqueue");
328         if (!asus->led_workqueue)
329                 return -ENOMEM;
330         INIT_WORK(&asus->tpd_led_work, tpd_led_update);
331
332         asus->tpd_led.name = "asus::touchpad";
333         asus->tpd_led.brightness_set = tpd_led_set;
334         asus->tpd_led.brightness_get = tpd_led_get;
335         asus->tpd_led.max_brightness = 1;
336
337         rv = led_classdev_register(&asus->platform_device->dev, &asus->tpd_led);
338         if (rv) {
339                 destroy_workqueue(asus->led_workqueue);
340                 return rv;
341         }
342
343         return 0;
344 }
345
346 static void asus_wmi_led_exit(struct asus_wmi *asus)
347 {
348         if (asus->tpd_led.dev)
349                 led_classdev_unregister(&asus->tpd_led);
350         if (asus->led_workqueue)
351                 destroy_workqueue(asus->led_workqueue);
352 }
353
354 /*
355  * PCI hotplug (for wlan rfkill)
356  */
357 static bool asus_wlan_rfkill_blocked(struct asus_wmi *asus)
358 {
359         int result = asus_wmi_get_devstate_simple(ASUS_WMI_DEVID_WLAN);
360
361         if (result < 0)
362                 return false;
363         return !result;
364 }
365
366 static void asus_rfkill_hotplug(struct asus_wmi *asus)
367 {
368         struct pci_dev *dev;
369         struct pci_bus *bus;
370         bool blocked;
371         bool absent;
372         u32 l;
373
374         mutex_lock(&asus->wmi_lock);
375         blocked = asus_wlan_rfkill_blocked(asus);
376         mutex_unlock(&asus->wmi_lock);
377
378         mutex_lock(&asus->hotplug_lock);
379
380         if (asus->wlan_rfkill)
381                 rfkill_set_sw_state(asus->wlan_rfkill, blocked);
382
383         if (asus->hotplug_slot) {
384                 bus = pci_find_bus(0, 1);
385                 if (!bus) {
386                         pr_warning("Unable to find PCI bus 1?\n");
387                         goto out_unlock;
388                 }
389
390                 if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
391                         pr_err("Unable to read PCI config space?\n");
392                         goto out_unlock;
393                 }
394                 absent = (l == 0xffffffff);
395
396                 if (blocked != absent) {
397                         pr_warning("BIOS says wireless lan is %s, "
398                                    "but the pci device is %s\n",
399                                    blocked ? "blocked" : "unblocked",
400                                    absent ? "absent" : "present");
401                         pr_warning("skipped wireless hotplug as probably "
402                                    "inappropriate for this model\n");
403                         goto out_unlock;
404                 }
405
406                 if (!blocked) {
407                         dev = pci_get_slot(bus, 0);
408                         if (dev) {
409                                 /* Device already present */
410                                 pci_dev_put(dev);
411                                 goto out_unlock;
412                         }
413                         dev = pci_scan_single_device(bus, 0);
414                         if (dev) {
415                                 pci_bus_assign_resources(bus);
416                                 if (pci_bus_add_device(dev))
417                                         pr_err("Unable to hotplug wifi\n");
418                         }
419                 } else {
420                         dev = pci_get_slot(bus, 0);
421                         if (dev) {
422                                 pci_remove_bus_device(dev);
423                                 pci_dev_put(dev);
424                         }
425                 }
426         }
427
428 out_unlock:
429         mutex_unlock(&asus->hotplug_lock);
430 }
431
432 static void asus_rfkill_notify(acpi_handle handle, u32 event, void *data)
433 {
434         struct asus_wmi *asus = data;
435
436         if (event != ACPI_NOTIFY_BUS_CHECK)
437                 return;
438
439         /*
440          * We can't call directly asus_rfkill_hotplug because most
441          * of the time WMBC is still being executed and not reetrant.
442          * There is currently no way to tell ACPICA that  we want this
443          * method to be serialized, we schedule a asus_rfkill_hotplug
444          * call later, in a safer context.
445          */
446         queue_work(asus->hotplug_workqueue, &asus->hotplug_work);
447 }
448
449 static int asus_register_rfkill_notifier(struct asus_wmi *asus, char *node)
450 {
451         acpi_status status;
452         acpi_handle handle;
453
454         status = acpi_get_handle(NULL, node, &handle);
455
456         if (ACPI_SUCCESS(status)) {
457                 status = acpi_install_notify_handler(handle,
458                                                      ACPI_SYSTEM_NOTIFY,
459                                                      asus_rfkill_notify, asus);
460                 if (ACPI_FAILURE(status))
461                         pr_warning("Failed to register notify on %s\n", node);
462         } else
463                 return -ENODEV;
464
465         return 0;
466 }
467
468 static void asus_unregister_rfkill_notifier(struct asus_wmi *asus, char *node)
469 {
470         acpi_status status = AE_OK;
471         acpi_handle handle;
472
473         status = acpi_get_handle(NULL, node, &handle);
474
475         if (ACPI_SUCCESS(status)) {
476                 status = acpi_remove_notify_handler(handle,
477                                                     ACPI_SYSTEM_NOTIFY,
478                                                     asus_rfkill_notify);
479                 if (ACPI_FAILURE(status))
480                         pr_err("Error removing rfkill notify handler %s\n",
481                                node);
482         }
483 }
484
485 static int asus_get_adapter_status(struct hotplug_slot *hotplug_slot,
486                                    u8 *value)
487 {
488         int result = asus_wmi_get_devstate_simple(ASUS_WMI_DEVID_WLAN);
489
490         if (result < 0)
491                 return result;
492
493         *value = !!result;
494         return 0;
495 }
496
497 static void asus_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
498 {
499         kfree(hotplug_slot->info);
500         kfree(hotplug_slot);
501 }
502
503 static struct hotplug_slot_ops asus_hotplug_slot_ops = {
504         .owner = THIS_MODULE,
505         .get_adapter_status = asus_get_adapter_status,
506         .get_power_status = asus_get_adapter_status,
507 };
508
509 static void asus_hotplug_work(struct work_struct *work)
510 {
511         struct asus_wmi *asus;
512
513         asus = container_of(work, struct asus_wmi, hotplug_work);
514         asus_rfkill_hotplug(asus);
515 }
516
517 static int asus_setup_pci_hotplug(struct asus_wmi *asus)
518 {
519         int ret = -ENOMEM;
520         struct pci_bus *bus = pci_find_bus(0, 1);
521
522         if (!bus) {
523                 pr_err("Unable to find wifi PCI bus\n");
524                 return -ENODEV;
525         }
526
527         asus->hotplug_workqueue =
528             create_singlethread_workqueue("hotplug_workqueue");
529         if (!asus->hotplug_workqueue)
530                 goto error_workqueue;
531
532         INIT_WORK(&asus->hotplug_work, asus_hotplug_work);
533
534         asus->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
535         if (!asus->hotplug_slot)
536                 goto error_slot;
537
538         asus->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
539                                            GFP_KERNEL);
540         if (!asus->hotplug_slot->info)
541                 goto error_info;
542
543         asus->hotplug_slot->private = asus;
544         asus->hotplug_slot->release = &asus_cleanup_pci_hotplug;
545         asus->hotplug_slot->ops = &asus_hotplug_slot_ops;
546         asus_get_adapter_status(asus->hotplug_slot,
547                                 &asus->hotplug_slot->info->adapter_status);
548
549         ret = pci_hp_register(asus->hotplug_slot, bus, 0, "asus-wifi");
550         if (ret) {
551                 pr_err("Unable to register hotplug slot - %d\n", ret);
552                 goto error_register;
553         }
554
555         return 0;
556
557 error_register:
558         kfree(asus->hotplug_slot->info);
559 error_info:
560         kfree(asus->hotplug_slot);
561         asus->hotplug_slot = NULL;
562 error_slot:
563         destroy_workqueue(asus->hotplug_workqueue);
564 error_workqueue:
565         return ret;
566 }
567
568 /*
569  * Rfkill devices
570  */
571 static int asus_rfkill_set(void *data, bool blocked)
572 {
573         int dev_id = (unsigned long)data;
574         u32 ctrl_param = !blocked;
575         acpi_status status;
576
577         status = asus_wmi_set_devstate(dev_id, ctrl_param, NULL);
578
579         if (ACPI_FAILURE(status))
580                 return -EIO;
581
582         return 0;
583 }
584
585 static void asus_rfkill_query(struct rfkill *rfkill, void *data)
586 {
587         int dev_id = (unsigned long)data;
588         int result;
589
590         result = asus_wmi_get_devstate_simple(dev_id);
591
592         if (result < 0)
593                 return;
594
595         rfkill_set_sw_state(rfkill, !result);
596 }
597
598 static int asus_rfkill_wlan_set(void *data, bool blocked)
599 {
600         struct asus_wmi *asus = data;
601         int ret;
602
603         /*
604          * This handler is enabled only if hotplug is enabled.
605          * In this case, the asus_wmi_set_devstate() will
606          * trigger a wmi notification and we need to wait
607          * this call to finish before being able to call
608          * any wmi method
609          */
610         mutex_lock(&asus->wmi_lock);
611         ret = asus_rfkill_set((void *)(long)ASUS_WMI_DEVID_WLAN, blocked);
612         mutex_unlock(&asus->wmi_lock);
613         return ret;
614 }
615
616 static void asus_rfkill_wlan_query(struct rfkill *rfkill, void *data)
617 {
618         asus_rfkill_query(rfkill, (void *)(long)ASUS_WMI_DEVID_WLAN);
619 }
620
621 static const struct rfkill_ops asus_rfkill_wlan_ops = {
622         .set_block = asus_rfkill_wlan_set,
623         .query = asus_rfkill_wlan_query,
624 };
625
626 static const struct rfkill_ops asus_rfkill_ops = {
627         .set_block = asus_rfkill_set,
628         .query = asus_rfkill_query,
629 };
630
631 static int asus_new_rfkill(struct asus_wmi *asus,
632                            struct rfkill **rfkill,
633                            const char *name, enum rfkill_type type, int dev_id)
634 {
635         int result = asus_wmi_get_devstate_simple(dev_id);
636
637         if (result < 0)
638                 return result;
639
640         if (dev_id == ASUS_WMI_DEVID_WLAN && asus->driver->hotplug_wireless)
641                 *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type,
642                                        &asus_rfkill_wlan_ops, asus);
643         else
644                 *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type,
645                                        &asus_rfkill_ops, (void *)(long)dev_id);
646
647         if (!*rfkill)
648                 return -EINVAL;
649
650         rfkill_init_sw_state(*rfkill, !result);
651         result = rfkill_register(*rfkill);
652         if (result) {
653                 rfkill_destroy(*rfkill);
654                 *rfkill = NULL;
655                 return result;
656         }
657         return 0;
658 }
659
660 static void asus_wmi_rfkill_exit(struct asus_wmi *asus)
661 {
662         asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P5");
663         asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P6");
664         asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P7");
665         if (asus->wlan_rfkill) {
666                 rfkill_unregister(asus->wlan_rfkill);
667                 rfkill_destroy(asus->wlan_rfkill);
668                 asus->wlan_rfkill = NULL;
669         }
670         /*
671          * Refresh pci hotplug in case the rfkill state was changed after
672          * asus_unregister_rfkill_notifier()
673          */
674         asus_rfkill_hotplug(asus);
675         if (asus->hotplug_slot)
676                 pci_hp_deregister(asus->hotplug_slot);
677         if (asus->hotplug_workqueue)
678                 destroy_workqueue(asus->hotplug_workqueue);
679
680         if (asus->bluetooth_rfkill) {
681                 rfkill_unregister(asus->bluetooth_rfkill);
682                 rfkill_destroy(asus->bluetooth_rfkill);
683                 asus->bluetooth_rfkill = NULL;
684         }
685         if (asus->wimax_rfkill) {
686                 rfkill_unregister(asus->wimax_rfkill);
687                 rfkill_destroy(asus->wimax_rfkill);
688                 asus->wimax_rfkill = NULL;
689         }
690         if (asus->wwan3g_rfkill) {
691                 rfkill_unregister(asus->wwan3g_rfkill);
692                 rfkill_destroy(asus->wwan3g_rfkill);
693                 asus->wwan3g_rfkill = NULL;
694         }
695 }
696
697 static int asus_wmi_rfkill_init(struct asus_wmi *asus)
698 {
699         int result = 0;
700
701         mutex_init(&asus->hotplug_lock);
702         mutex_init(&asus->wmi_lock);
703
704         result = asus_new_rfkill(asus, &asus->wlan_rfkill,
705                                  "asus-wlan", RFKILL_TYPE_WLAN,
706                                  ASUS_WMI_DEVID_WLAN);
707
708         if (result && result != -ENODEV)
709                 goto exit;
710
711         result = asus_new_rfkill(asus, &asus->bluetooth_rfkill,
712                                  "asus-bluetooth", RFKILL_TYPE_BLUETOOTH,
713                                  ASUS_WMI_DEVID_BLUETOOTH);
714
715         if (result && result != -ENODEV)
716                 goto exit;
717
718         result = asus_new_rfkill(asus, &asus->wimax_rfkill,
719                                  "asus-wimax", RFKILL_TYPE_WIMAX,
720                                  ASUS_WMI_DEVID_WIMAX);
721
722         if (result && result != -ENODEV)
723                 goto exit;
724
725         result = asus_new_rfkill(asus, &asus->wwan3g_rfkill,
726                                  "asus-wwan3g", RFKILL_TYPE_WWAN,
727                                  ASUS_WMI_DEVID_WWAN3G);
728
729         if (result && result != -ENODEV)
730                 goto exit;
731
732         if (!asus->driver->hotplug_wireless)
733                 goto exit;
734
735         result = asus_setup_pci_hotplug(asus);
736         /*
737          * If we get -EBUSY then something else is handling the PCI hotplug -
738          * don't fail in this case
739          */
740         if (result == -EBUSY)
741                 result = 0;
742
743         asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P5");
744         asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P6");
745         asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P7");
746         /*
747          * Refresh pci hotplug in case the rfkill state was changed during
748          * setup.
749          */
750         asus_rfkill_hotplug(asus);
751
752 exit:
753         if (result && result != -ENODEV)
754                 asus_wmi_rfkill_exit(asus);
755
756         if (result == -ENODEV)
757                 result = 0;
758
759         return result;
760 }
761
762 /*
763  * Backlight
764  */
765 static int read_backlight_power(void)
766 {
767         int ret = asus_wmi_get_devstate_simple(ASUS_WMI_DEVID_BACKLIGHT);
768
769         if (ret < 0)
770                 return ret;
771
772         return ret ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
773 }
774
775 static int read_brightness(struct backlight_device *bd)
776 {
777         u32 retval;
778         acpi_status status;
779
780         status = asus_wmi_get_devstate(ASUS_WMI_DEVID_BRIGHTNESS, &retval);
781
782         if (ACPI_FAILURE(status))
783                 return -EIO;
784         else
785                 return retval & ASUS_WMI_DSTS_BRIGHTNESS_MASK;
786 }
787
788 static int update_bl_status(struct backlight_device *bd)
789 {
790         u32 ctrl_param;
791         acpi_status status;
792         int power;
793
794         ctrl_param = bd->props.brightness;
795
796         status = asus_wmi_set_devstate(ASUS_WMI_DEVID_BRIGHTNESS,
797                                        ctrl_param, NULL);
798
799         if (ACPI_FAILURE(status))
800                 return -EIO;
801
802         power = read_backlight_power();
803         if (power != -ENODEV && bd->props.power != power) {
804                 ctrl_param = !!(bd->props.power == FB_BLANK_UNBLANK);
805                 status = asus_wmi_set_devstate(ASUS_WMI_DEVID_BACKLIGHT,
806                                                ctrl_param, NULL);
807
808                 if (ACPI_FAILURE(status))
809                         return -EIO;
810         }
811         return 0;
812 }
813
814 static const struct backlight_ops asus_wmi_bl_ops = {
815         .get_brightness = read_brightness,
816         .update_status = update_bl_status,
817 };
818
819 static int asus_wmi_backlight_notify(struct asus_wmi *asus, int code)
820 {
821         struct backlight_device *bd = asus->backlight_device;
822         int old = bd->props.brightness;
823         int new = old;
824
825         if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
826                 new = code - NOTIFY_BRNUP_MIN + 1;
827         else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
828                 new = code - NOTIFY_BRNDOWN_MIN;
829
830         bd->props.brightness = new;
831         backlight_update_status(bd);
832         backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
833
834         return old;
835 }
836
837 static int asus_wmi_backlight_init(struct asus_wmi *asus)
838 {
839         struct backlight_device *bd;
840         struct backlight_properties props;
841         int max;
842         int power;
843
844         max = asus_wmi_get_devstate_bits(ASUS_WMI_DEVID_BRIGHTNESS,
845                                          ASUS_WMI_DSTS_MAX_BRIGTH_MASK);
846         power = read_backlight_power();
847
848         if (max < 0 && power < 0) {
849                 /* Try to keep the original error */
850                 if (max == -ENODEV && power == -ENODEV)
851                         return -ENODEV;
852                 if (max != -ENODEV)
853                         return max;
854                 else
855                         return power;
856         }
857         if (max == -ENODEV)
858                 max = 0;
859         if (power == -ENODEV)
860                 power = FB_BLANK_UNBLANK;
861
862         memset(&props, 0, sizeof(struct backlight_properties));
863         props.max_brightness = max;
864         bd = backlight_device_register(asus->driver->name,
865                                        &asus->platform_device->dev, asus,
866                                        &asus_wmi_bl_ops, &props);
867         if (IS_ERR(bd)) {
868                 pr_err("Could not register backlight device\n");
869                 return PTR_ERR(bd);
870         }
871
872         asus->backlight_device = bd;
873
874         bd->props.brightness = read_brightness(bd);
875         bd->props.power = power;
876         backlight_update_status(bd);
877
878         return 0;
879 }
880
881 static void asus_wmi_backlight_exit(struct asus_wmi *asus)
882 {
883         if (asus->backlight_device)
884                 backlight_device_unregister(asus->backlight_device);
885
886         asus->backlight_device = NULL;
887 }
888
889 static void asus_wmi_notify(u32 value, void *context)
890 {
891         struct asus_wmi *asus = context;
892         struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
893         union acpi_object *obj;
894         acpi_status status;
895         int code;
896         int orig_code;
897
898         status = wmi_get_event_data(value, &response);
899         if (status != AE_OK) {
900                 pr_err("bad event status 0x%x\n", status);
901                 return;
902         }
903
904         obj = (union acpi_object *)response.pointer;
905
906         if (!obj || obj->type != ACPI_TYPE_INTEGER)
907                 goto exit;
908
909         code = obj->integer.value;
910         orig_code = code;
911
912         if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
913                 code = NOTIFY_BRNUP_MIN;
914         else if (code >= NOTIFY_BRNDOWN_MIN &&
915                  code <= NOTIFY_BRNDOWN_MAX)
916                 code = NOTIFY_BRNDOWN_MIN;
917
918         if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) {
919                 if (!acpi_video_backlight_support())
920                         asus_wmi_backlight_notify(asus, orig_code);
921         } else if (!sparse_keymap_report_event(asus->inputdev, code, 1, true))
922                 pr_info("Unknown key %x pressed\n", code);
923
924 exit:
925         kfree(obj);
926 }
927
928 /*
929  * Sys helpers
930  */
931 static int parse_arg(const char *buf, unsigned long count, int *val)
932 {
933         if (!count)
934                 return 0;
935         if (sscanf(buf, "%i", val) != 1)
936                 return -EINVAL;
937         return count;
938 }
939
940 static ssize_t store_sys_wmi(int devid, const char *buf, size_t count)
941 {
942         acpi_status status;
943         u32 retval;
944         int rv, value;
945
946         value = asus_wmi_get_devstate_simple(devid);
947         if (value == -ENODEV)   /* Check device presence */
948                 return value;
949
950         rv = parse_arg(buf, count, &value);
951         status = asus_wmi_set_devstate(devid, value, &retval);
952
953         if (ACPI_FAILURE(status))
954                 return -EIO;
955         return rv;
956 }
957
958 static ssize_t show_sys_wmi(int devid, char *buf)
959 {
960         int value = asus_wmi_get_devstate_simple(devid);
961
962         if (value < 0)
963                 return value;
964
965         return sprintf(buf, "%d\n", value);
966 }
967
968 #define ASUS_WMI_CREATE_DEVICE_ATTR(_name, _mode, _cm)                  \
969         static ssize_t show_##_name(struct device *dev,                 \
970                                     struct device_attribute *attr,      \
971                                     char *buf)                          \
972         {                                                               \
973                 return show_sys_wmi(_cm, buf);                          \
974         }                                                               \
975         static ssize_t store_##_name(struct device *dev,                \
976                                      struct device_attribute *attr,     \
977                                      const char *buf, size_t count)     \
978         {                                                               \
979                 return store_sys_wmi(_cm, buf, count);                  \
980         }                                                               \
981         static struct device_attribute dev_attr_##_name = {             \
982                 .attr = {                                               \
983                         .name = __stringify(_name),                     \
984                         .mode = _mode },                                \
985                 .show   = show_##_name,                                 \
986                 .store  = store_##_name,                                \
987         }
988
989 ASUS_WMI_CREATE_DEVICE_ATTR(touchpad, 0644, ASUS_WMI_DEVID_TOUCHPAD);
990 ASUS_WMI_CREATE_DEVICE_ATTR(camera, 0644, ASUS_WMI_DEVID_CAMERA);
991 ASUS_WMI_CREATE_DEVICE_ATTR(cardr, 0644, ASUS_WMI_DEVID_CARDREADER);
992
993 static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr,
994                            const char *buf, size_t count)
995 {
996         int value;
997         struct acpi_buffer input = { (acpi_size) sizeof(value), &value };
998         acpi_status status;
999
1000         if (!count || sscanf(buf, "%i", &value) != 1)
1001                 return -EINVAL;
1002         if (value < 0 || value > 2)
1003                 return -EINVAL;
1004
1005         status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
1006                                      1, ASUS_WMI_METHODID_CFVS, &input, NULL);
1007
1008         if (ACPI_FAILURE(status))
1009                 return -EIO;
1010         else
1011                 return count;
1012 }
1013
1014 static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv);
1015
1016 static struct attribute *platform_attributes[] = {
1017         &dev_attr_cpufv.attr,
1018         &dev_attr_camera.attr,
1019         &dev_attr_cardr.attr,
1020         &dev_attr_touchpad.attr,
1021         NULL
1022 };
1023
1024 static mode_t asus_sysfs_is_visible(struct kobject *kobj,
1025                                     struct attribute *attr, int idx)
1026 {
1027         bool supported = true;
1028         int devid = -1;
1029
1030         if (attr == &dev_attr_camera.attr)
1031                 devid = ASUS_WMI_DEVID_CAMERA;
1032         else if (attr == &dev_attr_cardr.attr)
1033                 devid = ASUS_WMI_DEVID_CARDREADER;
1034         else if (attr == &dev_attr_touchpad.attr)
1035                 devid = ASUS_WMI_DEVID_TOUCHPAD;
1036
1037         if (devid != -1)
1038                 supported = asus_wmi_get_devstate_simple(devid) != -ENODEV;
1039
1040         return supported ? attr->mode : 0;
1041 }
1042
1043 static struct attribute_group platform_attribute_group = {
1044         .is_visible = asus_sysfs_is_visible,
1045         .attrs = platform_attributes
1046 };
1047
1048 static void asus_wmi_sysfs_exit(struct platform_device *device)
1049 {
1050         sysfs_remove_group(&device->dev.kobj, &platform_attribute_group);
1051 }
1052
1053 static int asus_wmi_sysfs_init(struct platform_device *device)
1054 {
1055         return sysfs_create_group(&device->dev.kobj, &platform_attribute_group);
1056 }
1057
1058 /*
1059  * Platform device
1060  */
1061 static int __init asus_wmi_platform_init(struct asus_wmi *asus)
1062 {
1063         return asus_wmi_sysfs_init(asus->platform_device);
1064 }
1065
1066 static void asus_wmi_platform_exit(struct asus_wmi *asus)
1067 {
1068         asus_wmi_sysfs_exit(asus->platform_device);
1069 }
1070
1071 /*
1072  * debugfs
1073  */
1074 struct asus_wmi_debugfs_node {
1075         struct asus_wmi *asus;
1076         char *name;
1077         int (*show) (struct seq_file *m, void *data);
1078 };
1079
1080 static int show_dsts(struct seq_file *m, void *data)
1081 {
1082         struct asus_wmi *asus = m->private;
1083         acpi_status status;
1084         u32 retval = -1;
1085
1086         status = asus_wmi_get_devstate(asus->debug.dev_id, &retval);
1087
1088         if (ACPI_FAILURE(status))
1089                 return -EIO;
1090
1091         seq_printf(m, "DSTS(%x) = %x\n", asus->debug.dev_id, retval);
1092
1093         return 0;
1094 }
1095
1096 static int show_devs(struct seq_file *m, void *data)
1097 {
1098         struct asus_wmi *asus = m->private;
1099         acpi_status status;
1100         u32 retval = -1;
1101
1102         status = asus_wmi_set_devstate(asus->debug.dev_id,
1103                                        asus->debug.ctrl_param, &retval);
1104         if (ACPI_FAILURE(status))
1105                 return -EIO;
1106
1107         seq_printf(m, "DEVS(%x, %x) = %x\n", asus->debug.dev_id,
1108                    asus->debug.ctrl_param, retval);
1109
1110         return 0;
1111 }
1112
1113 static struct asus_wmi_debugfs_node asus_wmi_debug_files[] = {
1114         {NULL, "devs", show_devs},
1115         {NULL, "dsts", show_dsts},
1116 };
1117
1118 static int asus_wmi_debugfs_open(struct inode *inode, struct file *file)
1119 {
1120         struct asus_wmi_debugfs_node *node = inode->i_private;
1121
1122         return single_open(file, node->show, node->asus);
1123 }
1124
1125 static const struct file_operations asus_wmi_debugfs_io_ops = {
1126         .owner = THIS_MODULE,
1127         .open = asus_wmi_debugfs_open,
1128         .read = seq_read,
1129         .llseek = seq_lseek,
1130         .release = single_release,
1131 };
1132
1133 static void asus_wmi_debugfs_exit(struct asus_wmi *asus)
1134 {
1135         debugfs_remove_recursive(asus->debug.root);
1136 }
1137
1138 static int asus_wmi_debugfs_init(struct asus_wmi *asus)
1139 {
1140         struct dentry *dent;
1141         int i;
1142
1143         asus->debug.root = debugfs_create_dir(asus->driver->name, NULL);
1144         if (!asus->debug.root) {
1145                 pr_err("failed to create debugfs directory");
1146                 goto error_debugfs;
1147         }
1148
1149         dent = debugfs_create_x32("dev_id", S_IRUGO | S_IWUSR,
1150                                   asus->debug.root, &asus->debug.dev_id);
1151         if (!dent)
1152                 goto error_debugfs;
1153
1154         dent = debugfs_create_x32("ctrl_param", S_IRUGO | S_IWUSR,
1155                                   asus->debug.root, &asus->debug.ctrl_param);
1156         if (!dent)
1157                 goto error_debugfs;
1158
1159         for (i = 0; i < ARRAY_SIZE(asus_wmi_debug_files); i++) {
1160                 struct asus_wmi_debugfs_node *node = &asus_wmi_debug_files[i];
1161
1162                 node->asus = asus;
1163                 dent = debugfs_create_file(node->name, S_IFREG | S_IRUGO,
1164                                            asus->debug.root, node,
1165                                            &asus_wmi_debugfs_io_ops);
1166                 if (!dent) {
1167                         pr_err("failed to create debug file: %s\n", node->name);
1168                         goto error_debugfs;
1169                 }
1170         }
1171
1172         return 0;
1173
1174 error_debugfs:
1175         asus_wmi_debugfs_exit(asus);
1176         return -ENOMEM;
1177 }
1178
1179 /*
1180  * WMI Driver
1181  */
1182 static int asus_wmi_add(struct platform_device *pdev)
1183 {
1184         struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
1185         struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv);
1186         struct asus_wmi *asus;
1187         acpi_status status;
1188         int err;
1189
1190         asus = kzalloc(sizeof(struct asus_wmi), GFP_KERNEL);
1191         if (!asus)
1192                 return -ENOMEM;
1193
1194         asus->driver = wdrv;
1195         asus->platform_device = pdev;
1196         wdrv->platform_device = pdev;
1197         platform_set_drvdata(asus->platform_device, asus);
1198
1199         if (wdrv->quirks)
1200                 wdrv->quirks(asus->driver);
1201
1202         err = asus_wmi_platform_init(asus);
1203         if (err)
1204                 goto fail_platform;
1205
1206         err = asus_wmi_input_init(asus);
1207         if (err)
1208                 goto fail_input;
1209
1210         err = asus_wmi_led_init(asus);
1211         if (err)
1212                 goto fail_leds;
1213
1214         err = asus_wmi_rfkill_init(asus);
1215         if (err)
1216                 goto fail_rfkill;
1217
1218         if (!acpi_video_backlight_support()) {
1219                 err = asus_wmi_backlight_init(asus);
1220                 if (err && err != -ENODEV)
1221                         goto fail_backlight;
1222         } else
1223                 pr_info("Backlight controlled by ACPI video driver\n");
1224
1225         status = wmi_install_notify_handler(asus->driver->event_guid,
1226                                             asus_wmi_notify, asus);
1227         if (ACPI_FAILURE(status)) {
1228                 pr_err("Unable to register notify handler - %d\n", status);
1229                 err = -ENODEV;
1230                 goto fail_wmi_handler;
1231         }
1232
1233         err = asus_wmi_debugfs_init(asus);
1234         if (err)
1235                 goto fail_debugfs;
1236
1237         return 0;
1238
1239 fail_debugfs:
1240         wmi_remove_notify_handler(asus->driver->event_guid);
1241 fail_wmi_handler:
1242         asus_wmi_backlight_exit(asus);
1243 fail_backlight:
1244         asus_wmi_rfkill_exit(asus);
1245 fail_rfkill:
1246         asus_wmi_led_exit(asus);
1247 fail_leds:
1248         asus_wmi_input_exit(asus);
1249 fail_input:
1250         asus_wmi_platform_exit(asus);
1251 fail_platform:
1252         kfree(asus);
1253         return err;
1254 }
1255
1256 static int asus_wmi_remove(struct platform_device *device)
1257 {
1258         struct asus_wmi *asus;
1259
1260         asus = platform_get_drvdata(device);
1261         wmi_remove_notify_handler(asus->driver->event_guid);
1262         asus_wmi_backlight_exit(asus);
1263         asus_wmi_input_exit(asus);
1264         asus_wmi_led_exit(asus);
1265         asus_wmi_rfkill_exit(asus);
1266         asus_wmi_debugfs_exit(asus);
1267         asus_wmi_platform_exit(asus);
1268
1269         kfree(asus);
1270         return 0;
1271 }
1272
1273 /*
1274  * Platform driver - hibernate/resume callbacks
1275  */
1276 static int asus_hotk_thaw(struct device *device)
1277 {
1278         struct asus_wmi *asus = dev_get_drvdata(device);
1279
1280         if (asus->wlan_rfkill) {
1281                 bool wlan;
1282
1283                 /*
1284                  * Work around bios bug - acpi _PTS turns off the wireless led
1285                  * during suspend.  Normally it restores it on resume, but
1286                  * we should kick it ourselves in case hibernation is aborted.
1287                  */
1288                 wlan = asus_wmi_get_devstate_simple(ASUS_WMI_DEVID_WLAN);
1289                 asus_wmi_set_devstate(ASUS_WMI_DEVID_WLAN, wlan, NULL);
1290         }
1291
1292         return 0;
1293 }
1294
1295 static int asus_hotk_restore(struct device *device)
1296 {
1297         struct asus_wmi *asus = dev_get_drvdata(device);
1298         int bl;
1299
1300         /* Refresh both wlan rfkill state and pci hotplug */
1301         if (asus->wlan_rfkill)
1302                 asus_rfkill_hotplug(asus);
1303
1304         if (asus->bluetooth_rfkill) {
1305                 bl = !asus_wmi_get_devstate_simple(ASUS_WMI_DEVID_BLUETOOTH);
1306                 rfkill_set_sw_state(asus->bluetooth_rfkill, bl);
1307         }
1308         if (asus->wimax_rfkill) {
1309                 bl = !asus_wmi_get_devstate_simple(ASUS_WMI_DEVID_WIMAX);
1310                 rfkill_set_sw_state(asus->wimax_rfkill, bl);
1311         }
1312         if (asus->wwan3g_rfkill) {
1313                 bl = !asus_wmi_get_devstate_simple(ASUS_WMI_DEVID_WWAN3G);
1314                 rfkill_set_sw_state(asus->wwan3g_rfkill, bl);
1315         }
1316
1317         return 0;
1318 }
1319
1320 static const struct dev_pm_ops asus_pm_ops = {
1321         .thaw = asus_hotk_thaw,
1322         .restore = asus_hotk_restore,
1323 };
1324
1325 static int asus_wmi_probe(struct platform_device *pdev)
1326 {
1327         struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
1328         struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv);
1329         int ret;
1330
1331         if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
1332                 pr_warning("Management GUID not found\n");
1333                 return -ENODEV;
1334         }
1335
1336         if (wdrv->event_guid && !wmi_has_guid(wdrv->event_guid)) {
1337                 pr_warning("Event GUID not found\n");
1338                 return -ENODEV;
1339         }
1340
1341         if (wdrv->probe) {
1342                 ret = wdrv->probe(pdev);
1343                 if (ret)
1344                         return ret;
1345         }
1346
1347         return asus_wmi_add(pdev);
1348 }
1349
1350 static bool used;
1351
1352 int asus_wmi_register_driver(struct asus_wmi_driver *driver)
1353 {
1354         struct platform_driver *platform_driver;
1355         struct platform_device *platform_device;
1356
1357         if (used)
1358                 return -EBUSY;
1359
1360         platform_driver = &driver->platform_driver;
1361         platform_driver->remove = asus_wmi_remove;
1362         platform_driver->driver.owner = driver->owner;
1363         platform_driver->driver.name = driver->name;
1364         platform_driver->driver.pm = &asus_pm_ops;
1365
1366         platform_device = platform_create_bundle(platform_driver,
1367                                                  asus_wmi_probe,
1368                                                  NULL, 0, NULL, 0);
1369         if (IS_ERR(platform_device))
1370                 return PTR_ERR(platform_device);
1371
1372         used = true;
1373         return 0;
1374 }
1375 EXPORT_SYMBOL_GPL(asus_wmi_register_driver);
1376
1377 void asus_wmi_unregister_driver(struct asus_wmi_driver *driver)
1378 {
1379         platform_device_unregister(driver->platform_device);
1380         platform_driver_unregister(&driver->platform_driver);
1381         used = false;
1382 }
1383 EXPORT_SYMBOL_GPL(asus_wmi_unregister_driver);
1384
1385 static int __init asus_wmi_init(void)
1386 {
1387         if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
1388                 pr_info("Asus Management GUID not found");
1389                 return -ENODEV;
1390         }
1391
1392         pr_info("ASUS WMI generic driver loaded");
1393         return 0;
1394 }
1395
1396 static void __exit asus_wmi_exit(void)
1397 {
1398         pr_info("ASUS WMI generic driver unloaded");
1399 }
1400
1401 module_init(asus_wmi_init);
1402 module_exit(asus_wmi_exit);