]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/platform/x86/eeepc-wmi.c
eb4c0ce88ac1c3fffdf1dedc2af0e532c6f62d81
[mv-sheeva.git] / drivers / platform / x86 / eeepc-wmi.c
1 /*
2  * Eee PC WMI hotkey driver
3  *
4  * Copyright(C) 2010 Intel Corporation.
5  * Copyright(C) 2010 Corentin Chary <corentin.chary@gmail.com>
6  *
7  * Portions based on wistron_btns.c:
8  * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
9  * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
10  * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  (at your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25  */
26
27 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
28
29 #include <linux/kernel.h>
30 #include <linux/module.h>
31 #include <linux/init.h>
32 #include <linux/types.h>
33 #include <linux/slab.h>
34 #include <linux/input.h>
35 #include <linux/input/sparse-keymap.h>
36 #include <linux/fb.h>
37 #include <linux/backlight.h>
38 #include <linux/leds.h>
39 #include <linux/rfkill.h>
40 #include <linux/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 <linux/dmi.h>
46 #include <acpi/acpi_bus.h>
47 #include <acpi/acpi_drivers.h>
48
49 #define EEEPC_WMI_FILE  "eeepc-wmi"
50
51 MODULE_AUTHOR("Yong Wang <yong.y.wang@intel.com>");
52 MODULE_DESCRIPTION("Eee PC WMI Hotkey Driver");
53 MODULE_LICENSE("GPL");
54
55 #define EEEPC_ACPI_HID          "ASUS010" /* old _HID used in eeepc-laptop */
56
57 #define EEEPC_WMI_EVENT_GUID    "ABBC0F72-8EA1-11D1-00A0-C90629100000"
58 #define EEEPC_WMI_MGMT_GUID     "97845ED0-4E6D-11DE-8A39-0800200C9A66"
59
60 MODULE_ALIAS("wmi:"EEEPC_WMI_EVENT_GUID);
61 MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
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 #define EEEPC_WMI_METHODID_DEVS 0x53564544
69 #define EEEPC_WMI_METHODID_DSTS 0x53544344
70 #define EEEPC_WMI_METHODID_CFVS 0x53564643
71
72 #define EEEPC_WMI_DEVID_BACKLIGHT       0x00050012
73 #define EEEPC_WMI_DEVID_TPDLED          0x00100011
74 #define EEEPC_WMI_DEVID_WLAN            0x00010011
75 #define EEEPC_WMI_DEVID_BLUETOOTH       0x00010013
76 #define EEEPC_WMI_DEVID_WWAN3G          0x00010019
77
78 static bool hotplug_wireless;
79
80 module_param(hotplug_wireless, bool, 0444);
81 MODULE_PARM_DESC(hotplug_wireless,
82                  "Enable hotplug for wireless device. "
83                  "If your laptop needs that, please report to "
84                  "acpi4asus-user@lists.sourceforge.net.");
85
86 static const struct key_entry eeepc_wmi_keymap[] = {
87         /* Sleep already handled via generic ACPI code */
88         { KE_IGNORE, NOTIFY_BRNDOWN_MIN, { KEY_BRIGHTNESSDOWN } },
89         { KE_IGNORE, NOTIFY_BRNUP_MIN, { KEY_BRIGHTNESSUP } },
90         { KE_KEY, 0x30, { KEY_VOLUMEUP } },
91         { KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
92         { KE_KEY, 0x32, { KEY_MUTE } },
93         { KE_KEY, 0x5c, { KEY_F15 } },
94         { KE_KEY, 0x5d, { KEY_WLAN } },
95         { KE_KEY, 0x6b, { KEY_F13 } }, /* Disable Touchpad */
96         { KE_KEY, 0x88, { KEY_WLAN } },
97         { KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } },
98         { KE_KEY, 0xe0, { KEY_PROG1 } },
99         { KE_KEY, 0xe1, { KEY_F14 } },
100         { KE_KEY, 0xe9, { KEY_DISPLAY_OFF } },
101         { KE_END, 0},
102 };
103
104 struct bios_args {
105         u32     dev_id;
106         u32     ctrl_param;
107 };
108
109 /*
110  * eeepc-wmi/    - debugfs root directory
111  *   dev_id      - current dev_id
112  *   ctrl_param  - current ctrl_param
113  *   devs        - call DEVS(dev_id, ctrl_param) and print result
114  *   dsts        - call DSTS(dev_id)  and print result
115  */
116 struct eeepc_wmi_debug {
117         struct dentry *root;
118         u32 dev_id;
119         u32 ctrl_param;
120 };
121
122 struct eeepc_wmi {
123         bool hotplug_wireless;
124
125         struct input_dev *inputdev;
126         struct backlight_device *backlight_device;
127         struct platform_device *platform_device;
128
129         struct led_classdev tpd_led;
130         int tpd_led_wk;
131         struct workqueue_struct *led_workqueue;
132         struct work_struct tpd_led_work;
133
134         struct rfkill *wlan_rfkill;
135         struct rfkill *bluetooth_rfkill;
136         struct rfkill *wwan3g_rfkill;
137
138         struct hotplug_slot *hotplug_slot;
139         struct mutex hotplug_lock;
140         struct mutex wmi_lock;
141         struct workqueue_struct *hotplug_workqueue;
142         struct work_struct hotplug_work;
143
144         struct eeepc_wmi_debug debug;
145 };
146
147 /* Only used in eeepc_wmi_init() and eeepc_wmi_exit() */
148 static struct platform_device *platform_device;
149
150 static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc)
151 {
152         int err;
153
154         eeepc->inputdev = input_allocate_device();
155         if (!eeepc->inputdev)
156                 return -ENOMEM;
157
158         eeepc->inputdev->name = "Eee PC WMI hotkeys";
159         eeepc->inputdev->phys = EEEPC_WMI_FILE "/input0";
160         eeepc->inputdev->id.bustype = BUS_HOST;
161         eeepc->inputdev->dev.parent = &eeepc->platform_device->dev;
162
163         err = sparse_keymap_setup(eeepc->inputdev, eeepc_wmi_keymap, NULL);
164         if (err)
165                 goto err_free_dev;
166
167         err = input_register_device(eeepc->inputdev);
168         if (err)
169                 goto err_free_keymap;
170
171         return 0;
172
173 err_free_keymap:
174         sparse_keymap_free(eeepc->inputdev);
175 err_free_dev:
176         input_free_device(eeepc->inputdev);
177         return err;
178 }
179
180 static void eeepc_wmi_input_exit(struct eeepc_wmi *eeepc)
181 {
182         if (eeepc->inputdev) {
183                 sparse_keymap_free(eeepc->inputdev);
184                 input_unregister_device(eeepc->inputdev);
185         }
186
187         eeepc->inputdev = NULL;
188 }
189
190 static acpi_status eeepc_wmi_get_devstate(u32 dev_id, u32 *retval)
191 {
192         struct acpi_buffer input = { (acpi_size)sizeof(u32), &dev_id };
193         struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
194         union acpi_object *obj;
195         acpi_status status;
196         u32 tmp;
197
198         status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
199                                      1, EEEPC_WMI_METHODID_DSTS,
200                                      &input, &output);
201
202         if (ACPI_FAILURE(status))
203                 return status;
204
205         obj = (union acpi_object *)output.pointer;
206         if (obj && obj->type == ACPI_TYPE_INTEGER)
207                 tmp = (u32)obj->integer.value;
208         else
209                 tmp = 0;
210
211         if (retval)
212                 *retval = tmp;
213
214         kfree(obj);
215
216         return status;
217
218 }
219
220 static acpi_status eeepc_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
221                                           u32 *retval)
222 {
223         struct bios_args args = {
224                 .dev_id = dev_id,
225                 .ctrl_param = ctrl_param,
226         };
227         struct acpi_buffer input = { (acpi_size)sizeof(args), &args };
228         acpi_status status;
229
230         if (!retval) {
231                 status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID, 1,
232                                              EEEPC_WMI_METHODID_DEVS,
233                                              &input, NULL);
234         } else {
235                 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
236                 union acpi_object *obj;
237                 u32 tmp;
238
239                 status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID, 1,
240                                              EEEPC_WMI_METHODID_DEVS,
241                                              &input, &output);
242
243                 if (ACPI_FAILURE(status))
244                         return status;
245
246                 obj = (union acpi_object *)output.pointer;
247                 if (obj && obj->type == ACPI_TYPE_INTEGER)
248                         tmp = (u32)obj->integer.value;
249                 else
250                         tmp = 0;
251
252                 *retval = tmp;
253
254                 kfree(obj);
255         }
256
257         return status;
258 }
259
260 /*
261  * LEDs
262  */
263 /*
264  * These functions actually update the LED's, and are called from a
265  * workqueue. By doing this as separate work rather than when the LED
266  * subsystem asks, we avoid messing with the Eeepc ACPI stuff during a
267  * potentially bad time, such as a timer interrupt.
268  */
269 static void tpd_led_update(struct work_struct *work)
270 {
271         int ctrl_param;
272         struct eeepc_wmi *eeepc;
273
274         eeepc = container_of(work, struct eeepc_wmi, tpd_led_work);
275
276         ctrl_param = eeepc->tpd_led_wk;
277         eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_TPDLED, ctrl_param, NULL);
278 }
279
280 static void tpd_led_set(struct led_classdev *led_cdev,
281                         enum led_brightness value)
282 {
283         struct eeepc_wmi *eeepc;
284
285         eeepc = container_of(led_cdev, struct eeepc_wmi, tpd_led);
286
287         eeepc->tpd_led_wk = !!value;
288         queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
289 }
290
291 static int read_tpd_state(struct eeepc_wmi *eeepc)
292 {
293         u32 retval;
294         acpi_status status;
295
296         status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_TPDLED, &retval);
297
298         if (ACPI_FAILURE(status))
299                 return -1;
300         else if (!retval || retval == 0x00060000)
301                 /*
302                  * if touchpad led is present, DSTS will set some bits,
303                  * usually 0x00020000.
304                  * 0x00060000 means that the device is not supported
305                  */
306                 return -ENODEV;
307         else
308                 /* Status is stored in the first bit */
309                 return retval & 0x1;
310 }
311
312 static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
313 {
314         struct eeepc_wmi *eeepc;
315
316         eeepc = container_of(led_cdev, struct eeepc_wmi, tpd_led);
317
318         return read_tpd_state(eeepc);
319 }
320
321 static int eeepc_wmi_led_init(struct eeepc_wmi *eeepc)
322 {
323         int rv;
324
325         if (read_tpd_state(eeepc) < 0)
326                 return 0;
327
328         eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
329         if (!eeepc->led_workqueue)
330                 return -ENOMEM;
331         INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);
332
333         eeepc->tpd_led.name = "eeepc::touchpad";
334         eeepc->tpd_led.brightness_set = tpd_led_set;
335         eeepc->tpd_led.brightness_get = tpd_led_get;
336         eeepc->tpd_led.max_brightness = 1;
337
338         rv = led_classdev_register(&eeepc->platform_device->dev,
339                                    &eeepc->tpd_led);
340         if (rv) {
341                 destroy_workqueue(eeepc->led_workqueue);
342                 return rv;
343         }
344
345         return 0;
346 }
347
348 static void eeepc_wmi_led_exit(struct eeepc_wmi *eeepc)
349 {
350         if (eeepc->tpd_led.dev)
351                 led_classdev_unregister(&eeepc->tpd_led);
352         if (eeepc->led_workqueue)
353                 destroy_workqueue(eeepc->led_workqueue);
354 }
355
356 /*
357  * PCI hotplug (for wlan rfkill)
358  */
359 static bool eeepc_wlan_rfkill_blocked(struct eeepc_wmi *eeepc)
360 {
361         u32 retval;
362         acpi_status status;
363
364         status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_WLAN, &retval);
365
366         if (ACPI_FAILURE(status))
367                 return false;
368
369         return !(retval & 0x1);
370 }
371
372 static void eeepc_rfkill_hotplug(struct eeepc_wmi *eeepc)
373 {
374         struct pci_dev *dev;
375         struct pci_bus *bus;
376         bool blocked;
377         bool absent;
378         u32 l;
379
380         mutex_lock(&eeepc->wmi_lock);
381         blocked = eeepc_wlan_rfkill_blocked(eeepc);
382         mutex_unlock(&eeepc->wmi_lock);
383
384         mutex_lock(&eeepc->hotplug_lock);
385
386         if (eeepc->wlan_rfkill)
387                 rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
388
389         if (eeepc->hotplug_slot) {
390                 bus = pci_find_bus(0, 1);
391                 if (!bus) {
392                         pr_warning("Unable to find PCI bus 1?\n");
393                         goto out_unlock;
394                 }
395
396                 if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
397                         pr_err("Unable to read PCI config space?\n");
398                         goto out_unlock;
399                 }
400                 absent = (l == 0xffffffff);
401
402                 if (blocked != absent) {
403                         pr_warning("BIOS says wireless lan is %s, "
404                                         "but the pci device is %s\n",
405                                 blocked ? "blocked" : "unblocked",
406                                 absent ? "absent" : "present");
407                         pr_warning("skipped wireless hotplug as probably "
408                                         "inappropriate for this model\n");
409                         goto out_unlock;
410                 }
411
412                 if (!blocked) {
413                         dev = pci_get_slot(bus, 0);
414                         if (dev) {
415                                 /* Device already present */
416                                 pci_dev_put(dev);
417                                 goto out_unlock;
418                         }
419                         dev = pci_scan_single_device(bus, 0);
420                         if (dev) {
421                                 pci_bus_assign_resources(bus);
422                                 if (pci_bus_add_device(dev))
423                                         pr_err("Unable to hotplug wifi\n");
424                         }
425                 } else {
426                         dev = pci_get_slot(bus, 0);
427                         if (dev) {
428                                 pci_remove_bus_device(dev);
429                                 pci_dev_put(dev);
430                         }
431                 }
432         }
433
434 out_unlock:
435         mutex_unlock(&eeepc->hotplug_lock);
436 }
437
438 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
439 {
440         struct eeepc_wmi *eeepc = data;
441
442         if (event != ACPI_NOTIFY_BUS_CHECK)
443                 return;
444
445         /*
446          * We can't call directly eeepc_rfkill_hotplug because most
447          * of the time WMBC is still being executed and not reetrant.
448          * There is currently no way to tell ACPICA that  we want this
449          * method to be serialized, we schedule a eeepc_rfkill_hotplug
450          * call later, in a safer context.
451          */
452         queue_work(eeepc->hotplug_workqueue, &eeepc->hotplug_work);
453 }
454
455 static int eeepc_register_rfkill_notifier(struct eeepc_wmi *eeepc,
456                                           char *node)
457 {
458         acpi_status status;
459         acpi_handle handle;
460
461         status = acpi_get_handle(NULL, node, &handle);
462
463         if (ACPI_SUCCESS(status)) {
464                 status = acpi_install_notify_handler(handle,
465                                                      ACPI_SYSTEM_NOTIFY,
466                                                      eeepc_rfkill_notify,
467                                                      eeepc);
468                 if (ACPI_FAILURE(status))
469                         pr_warning("Failed to register notify on %s\n", node);
470         } else
471                 return -ENODEV;
472
473         return 0;
474 }
475
476 static void eeepc_unregister_rfkill_notifier(struct eeepc_wmi *eeepc,
477                                              char *node)
478 {
479         acpi_status status = AE_OK;
480         acpi_handle handle;
481
482         status = acpi_get_handle(NULL, node, &handle);
483
484         if (ACPI_SUCCESS(status)) {
485                 status = acpi_remove_notify_handler(handle,
486                                                      ACPI_SYSTEM_NOTIFY,
487                                                      eeepc_rfkill_notify);
488                 if (ACPI_FAILURE(status))
489                         pr_err("Error removing rfkill notify handler %s\n",
490                                 node);
491         }
492 }
493
494 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
495                                     u8 *value)
496 {
497         u32 retval;
498         acpi_status status;
499
500         status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_WLAN, &retval);
501
502         if (ACPI_FAILURE(status))
503                 return -EIO;
504
505         if (!retval || retval == 0x00060000)
506                 return -ENODEV;
507         else
508                 *value = (retval & 0x1);
509
510         return 0;
511 }
512
513 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
514 {
515         kfree(hotplug_slot->info);
516         kfree(hotplug_slot);
517 }
518
519 static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
520         .owner = THIS_MODULE,
521         .get_adapter_status = eeepc_get_adapter_status,
522         .get_power_status = eeepc_get_adapter_status,
523 };
524
525 static void eeepc_hotplug_work(struct work_struct *work)
526 {
527         struct eeepc_wmi *eeepc;
528
529         eeepc = container_of(work, struct eeepc_wmi, hotplug_work);
530         eeepc_rfkill_hotplug(eeepc);
531 }
532
533 static int eeepc_setup_pci_hotplug(struct eeepc_wmi *eeepc)
534 {
535         int ret = -ENOMEM;
536         struct pci_bus *bus = pci_find_bus(0, 1);
537
538         if (!bus) {
539                 pr_err("Unable to find wifi PCI bus\n");
540                 return -ENODEV;
541         }
542
543         eeepc->hotplug_workqueue =
544                 create_singlethread_workqueue("hotplug_workqueue");
545         if (!eeepc->hotplug_workqueue)
546                 goto error_workqueue;
547
548         INIT_WORK(&eeepc->hotplug_work, eeepc_hotplug_work);
549
550         eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
551         if (!eeepc->hotplug_slot)
552                 goto error_slot;
553
554         eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
555                                             GFP_KERNEL);
556         if (!eeepc->hotplug_slot->info)
557                 goto error_info;
558
559         eeepc->hotplug_slot->private = eeepc;
560         eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
561         eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
562         eeepc_get_adapter_status(eeepc->hotplug_slot,
563                                  &eeepc->hotplug_slot->info->adapter_status);
564
565         ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
566         if (ret) {
567                 pr_err("Unable to register hotplug slot - %d\n", ret);
568                 goto error_register;
569         }
570
571         return 0;
572
573 error_register:
574         kfree(eeepc->hotplug_slot->info);
575 error_info:
576         kfree(eeepc->hotplug_slot);
577         eeepc->hotplug_slot = NULL;
578 error_slot:
579         destroy_workqueue(eeepc->hotplug_workqueue);
580 error_workqueue:
581         return ret;
582 }
583
584 /*
585  * Rfkill devices
586  */
587 static int eeepc_rfkill_set(void *data, bool blocked)
588 {
589         int dev_id = (unsigned long)data;
590         u32 ctrl_param = !blocked;
591
592         return eeepc_wmi_set_devstate(dev_id, ctrl_param, NULL);
593 }
594
595 static void eeepc_rfkill_query(struct rfkill *rfkill, void *data)
596 {
597         int dev_id = (unsigned long)data;
598         u32 retval;
599         acpi_status status;
600
601         status = eeepc_wmi_get_devstate(dev_id, &retval);
602
603         if (ACPI_FAILURE(status))
604                 return ;
605
606         rfkill_set_sw_state(rfkill, !(retval & 0x1));
607 }
608
609 static int eeepc_rfkill_wlan_set(void *data, bool blocked)
610 {
611         struct eeepc_wmi *eeepc = data;
612         int ret;
613
614         /*
615          * This handler is enabled only if hotplug is enabled.
616          * In this case, the eeepc_wmi_set_devstate() will
617          * trigger a wmi notification and we need to wait
618          * this call to finish before being able to call
619          * any wmi method
620          */
621         mutex_lock(&eeepc->wmi_lock);
622         ret = eeepc_rfkill_set((void *)(long)EEEPC_WMI_DEVID_WLAN, blocked);
623         mutex_unlock(&eeepc->wmi_lock);
624         return ret;
625 }
626
627 static void eeepc_rfkill_wlan_query(struct rfkill *rfkill, void *data)
628 {
629         eeepc_rfkill_query(rfkill, (void *)(long)EEEPC_WMI_DEVID_WLAN);
630 }
631
632 static const struct rfkill_ops eeepc_rfkill_wlan_ops = {
633         .set_block = eeepc_rfkill_wlan_set,
634         .query = eeepc_rfkill_wlan_query,
635 };
636
637 static const struct rfkill_ops eeepc_rfkill_ops = {
638         .set_block = eeepc_rfkill_set,
639         .query = eeepc_rfkill_query,
640 };
641
642 static int eeepc_new_rfkill(struct eeepc_wmi *eeepc,
643                             struct rfkill **rfkill,
644                             const char *name,
645                             enum rfkill_type type, int dev_id)
646 {
647         int result;
648         u32 retval;
649         acpi_status status;
650
651         status = eeepc_wmi_get_devstate(dev_id, &retval);
652
653         if (ACPI_FAILURE(status))
654                 return -1;
655
656         /* If the device is present, DSTS will always set some bits
657          * 0x00070000 - 1110000000000000000 - device supported
658          * 0x00060000 - 1100000000000000000 - not supported
659          * 0x00020000 - 0100000000000000000 - device supported
660          * 0x00010000 - 0010000000000000000 - not supported / special mode ?
661          */
662         if (!retval || retval == 0x00060000)
663                 return -ENODEV;
664
665         if (dev_id == EEEPC_WMI_DEVID_WLAN && eeepc->hotplug_wireless)
666                 *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
667                                        &eeepc_rfkill_wlan_ops, eeepc);
668         else
669                 *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
670                                        &eeepc_rfkill_ops, (void *)(long)dev_id);
671
672         if (!*rfkill)
673                 return -EINVAL;
674
675         rfkill_init_sw_state(*rfkill, !(retval & 0x1));
676         result = rfkill_register(*rfkill);
677         if (result) {
678                 rfkill_destroy(*rfkill);
679                 *rfkill = NULL;
680                 return result;
681         }
682         return 0;
683 }
684
685 static void eeepc_wmi_rfkill_exit(struct eeepc_wmi *eeepc)
686 {
687         eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
688         eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
689         eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
690         if (eeepc->wlan_rfkill) {
691                 rfkill_unregister(eeepc->wlan_rfkill);
692                 rfkill_destroy(eeepc->wlan_rfkill);
693                 eeepc->wlan_rfkill = NULL;
694         }
695         /*
696          * Refresh pci hotplug in case the rfkill state was changed after
697          * eeepc_unregister_rfkill_notifier()
698          */
699         eeepc_rfkill_hotplug(eeepc);
700         if (eeepc->hotplug_slot)
701                 pci_hp_deregister(eeepc->hotplug_slot);
702         if (eeepc->hotplug_workqueue)
703                 destroy_workqueue(eeepc->hotplug_workqueue);
704
705         if (eeepc->bluetooth_rfkill) {
706                 rfkill_unregister(eeepc->bluetooth_rfkill);
707                 rfkill_destroy(eeepc->bluetooth_rfkill);
708                 eeepc->bluetooth_rfkill = NULL;
709         }
710         if (eeepc->wwan3g_rfkill) {
711                 rfkill_unregister(eeepc->wwan3g_rfkill);
712                 rfkill_destroy(eeepc->wwan3g_rfkill);
713                 eeepc->wwan3g_rfkill = NULL;
714         }
715 }
716
717 static int eeepc_wmi_rfkill_init(struct eeepc_wmi *eeepc)
718 {
719         int result = 0;
720
721         mutex_init(&eeepc->hotplug_lock);
722         mutex_init(&eeepc->wmi_lock);
723
724         result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
725                                   "eeepc-wlan", RFKILL_TYPE_WLAN,
726                                   EEEPC_WMI_DEVID_WLAN);
727
728         if (result && result != -ENODEV)
729                 goto exit;
730
731         result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
732                                   "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
733                                   EEEPC_WMI_DEVID_BLUETOOTH);
734
735         if (result && result != -ENODEV)
736                 goto exit;
737
738         result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
739                                   "eeepc-wwan3g", RFKILL_TYPE_WWAN,
740                                   EEEPC_WMI_DEVID_WWAN3G);
741
742         if (result && result != -ENODEV)
743                 goto exit;
744
745         result = eeepc_setup_pci_hotplug(eeepc);
746         /*
747          * If we get -EBUSY then something else is handling the PCI hotplug -
748          * don't fail in this case
749          */
750         if (result == -EBUSY)
751                 result = 0;
752
753         eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
754         eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
755         eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
756         /*
757          * Refresh pci hotplug in case the rfkill state was changed during
758          * setup.
759          */
760         eeepc_rfkill_hotplug(eeepc);
761
762 exit:
763         if (result && result != -ENODEV)
764                 eeepc_wmi_rfkill_exit(eeepc);
765
766         if (result == -ENODEV)
767                 result = 0;
768
769         return result;
770 }
771
772 /*
773  * Backlight
774  */
775 static int read_brightness(struct backlight_device *bd)
776 {
777         u32 retval;
778         acpi_status status;
779
780         status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT, &retval);
781
782         if (ACPI_FAILURE(status))
783                 return -1;
784         else
785                 return retval & 0xFF;
786 }
787
788 static int update_bl_status(struct backlight_device *bd)
789 {
790
791         u32 ctrl_param;
792         acpi_status status;
793
794         ctrl_param = bd->props.brightness;
795
796         status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT,
797                                         ctrl_param, NULL);
798
799         if (ACPI_FAILURE(status))
800                 return -1;
801         else
802                 return 0;
803 }
804
805 static const struct backlight_ops eeepc_wmi_bl_ops = {
806         .get_brightness = read_brightness,
807         .update_status = update_bl_status,
808 };
809
810 static int eeepc_wmi_backlight_notify(struct eeepc_wmi *eeepc, int code)
811 {
812         struct backlight_device *bd = eeepc->backlight_device;
813         int old = bd->props.brightness;
814         int new = old;
815
816         if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
817                 new = code - NOTIFY_BRNUP_MIN + 1;
818         else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
819                 new = code - NOTIFY_BRNDOWN_MIN;
820
821         bd->props.brightness = new;
822         backlight_update_status(bd);
823         backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
824
825         return old;
826 }
827
828 static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
829 {
830         struct backlight_device *bd;
831         struct backlight_properties props;
832
833         memset(&props, 0, sizeof(struct backlight_properties));
834         props.max_brightness = 15;
835         bd = backlight_device_register(EEEPC_WMI_FILE,
836                                        &eeepc->platform_device->dev, eeepc,
837                                        &eeepc_wmi_bl_ops, &props);
838         if (IS_ERR(bd)) {
839                 pr_err("Could not register backlight device\n");
840                 return PTR_ERR(bd);
841         }
842
843         eeepc->backlight_device = bd;
844
845         bd->props.brightness = read_brightness(bd);
846         bd->props.power = FB_BLANK_UNBLANK;
847         backlight_update_status(bd);
848
849         return 0;
850 }
851
852 static void eeepc_wmi_backlight_exit(struct eeepc_wmi *eeepc)
853 {
854         if (eeepc->backlight_device)
855                 backlight_device_unregister(eeepc->backlight_device);
856
857         eeepc->backlight_device = NULL;
858 }
859
860 static void eeepc_wmi_notify(u32 value, void *context)
861 {
862         struct eeepc_wmi *eeepc = context;
863         struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
864         union acpi_object *obj;
865         acpi_status status;
866         int code;
867         int orig_code;
868
869         status = wmi_get_event_data(value, &response);
870         if (status != AE_OK) {
871                 pr_err("bad event status 0x%x\n", status);
872                 return;
873         }
874
875         obj = (union acpi_object *)response.pointer;
876
877         if (obj && obj->type == ACPI_TYPE_INTEGER) {
878                 code = obj->integer.value;
879                 orig_code = code;
880
881                 if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
882                         code = NOTIFY_BRNUP_MIN;
883                 else if (code >= NOTIFY_BRNDOWN_MIN &&
884                          code <= NOTIFY_BRNDOWN_MAX)
885                         code = NOTIFY_BRNDOWN_MIN;
886
887                 if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) {
888                         if (!acpi_video_backlight_support())
889                                 eeepc_wmi_backlight_notify(eeepc, orig_code);
890                 }
891
892                 if (!sparse_keymap_report_event(eeepc->inputdev,
893                                                 code, 1, true))
894                         pr_info("Unknown key %x pressed\n", code);
895         }
896
897         kfree(obj);
898 }
899
900 static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr,
901                            const char *buf, size_t count)
902 {
903         int value;
904         struct acpi_buffer input = { (acpi_size)sizeof(value), &value };
905         acpi_status status;
906
907         if (!count || sscanf(buf, "%i", &value) != 1)
908                 return -EINVAL;
909         if (value < 0 || value > 2)
910                 return -EINVAL;
911
912         status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
913                                      1, EEEPC_WMI_METHODID_CFVS, &input, NULL);
914
915         if (ACPI_FAILURE(status))
916                 return -EIO;
917         else
918                 return count;
919 }
920
921 static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv);
922
923 static struct attribute *platform_attributes[] = {
924         &dev_attr_cpufv.attr,
925         NULL
926 };
927
928 static struct attribute_group platform_attribute_group = {
929         .attrs = platform_attributes
930 };
931
932 static void eeepc_wmi_sysfs_exit(struct platform_device *device)
933 {
934         sysfs_remove_group(&device->dev.kobj, &platform_attribute_group);
935 }
936
937 static int eeepc_wmi_sysfs_init(struct platform_device *device)
938 {
939         return sysfs_create_group(&device->dev.kobj, &platform_attribute_group);
940 }
941
942 /*
943  * Platform device
944  */
945 static int __init eeepc_wmi_platform_init(struct eeepc_wmi *eeepc)
946 {
947         int err;
948
949         eeepc->platform_device = platform_device_alloc(EEEPC_WMI_FILE, -1);
950         if (!eeepc->platform_device)
951                 return -ENOMEM;
952         platform_set_drvdata(eeepc->platform_device, eeepc);
953
954         err = platform_device_add(eeepc->platform_device);
955         if (err)
956                 goto fail_platform_device;
957
958         err = eeepc_wmi_sysfs_init(eeepc->platform_device);
959         if (err)
960                 goto fail_sysfs;
961         return 0;
962
963 fail_sysfs:
964         platform_device_del(eeepc->platform_device);
965 fail_platform_device:
966         platform_device_put(eeepc->platform_device);
967         return err;
968 }
969
970 static void eeepc_wmi_platform_exit(struct eeepc_wmi *eeepc)
971 {
972         eeepc_wmi_sysfs_exit(eeepc->platform_device);
973         platform_device_unregister(eeepc->platform_device);
974 }
975
976 /*
977  * debugfs
978  */
979 struct eeepc_wmi_debugfs_node {
980         struct eeepc_wmi *eeepc;
981         char *name;
982         int (*show)(struct seq_file *m, void *data);
983 };
984
985 static int show_dsts(struct seq_file *m, void *data)
986 {
987         struct eeepc_wmi *eeepc = m->private;
988         acpi_status status;
989         u32 retval = -1;
990
991         status = eeepc_wmi_get_devstate(eeepc->debug.dev_id, &retval);
992
993         if (ACPI_FAILURE(status))
994                 return -EIO;
995
996         seq_printf(m, "DSTS(%x) = %x\n", eeepc->debug.dev_id, retval);
997
998         return 0;
999 }
1000
1001 static int show_devs(struct seq_file *m, void *data)
1002 {
1003         struct eeepc_wmi *eeepc = m->private;
1004         acpi_status status;
1005         u32 retval = -1;
1006
1007         status = eeepc_wmi_set_devstate(eeepc->debug.dev_id,
1008                                         eeepc->debug.ctrl_param, &retval);
1009         if (ACPI_FAILURE(status))
1010                 return -EIO;
1011
1012         seq_printf(m, "DEVS(%x, %x) = %x\n", eeepc->debug.dev_id,
1013                    eeepc->debug.ctrl_param, retval);
1014
1015         return 0;
1016 }
1017
1018 static struct eeepc_wmi_debugfs_node eeepc_wmi_debug_files[] = {
1019         { NULL, "devs", show_devs },
1020         { NULL, "dsts", show_dsts },
1021 };
1022
1023 static int eeepc_wmi_debugfs_open(struct inode *inode, struct file *file)
1024 {
1025         struct eeepc_wmi_debugfs_node *node = inode->i_private;
1026
1027         return single_open(file, node->show, node->eeepc);
1028 }
1029
1030 static const struct file_operations eeepc_wmi_debugfs_io_ops = {
1031         .owner = THIS_MODULE,
1032         .open  = eeepc_wmi_debugfs_open,
1033         .read = seq_read,
1034         .llseek = seq_lseek,
1035         .release = single_release,
1036 };
1037
1038 static void eeepc_wmi_debugfs_exit(struct eeepc_wmi *eeepc)
1039 {
1040         debugfs_remove_recursive(eeepc->debug.root);
1041 }
1042
1043 static int eeepc_wmi_debugfs_init(struct eeepc_wmi *eeepc)
1044 {
1045         struct dentry *dent;
1046         int i;
1047
1048         eeepc->debug.root = debugfs_create_dir(EEEPC_WMI_FILE, NULL);
1049         if (!eeepc->debug.root) {
1050                 pr_err("failed to create debugfs directory");
1051                 goto error_debugfs;
1052         }
1053
1054         dent = debugfs_create_x32("dev_id", S_IRUGO|S_IWUSR,
1055                                   eeepc->debug.root, &eeepc->debug.dev_id);
1056         if (!dent)
1057                 goto error_debugfs;
1058
1059         dent = debugfs_create_x32("ctrl_param", S_IRUGO|S_IWUSR,
1060                                   eeepc->debug.root, &eeepc->debug.ctrl_param);
1061         if (!dent)
1062                 goto error_debugfs;
1063
1064         for (i = 0; i < ARRAY_SIZE(eeepc_wmi_debug_files); i++) {
1065                 struct eeepc_wmi_debugfs_node *node = &eeepc_wmi_debug_files[i];
1066
1067                 node->eeepc = eeepc;
1068                 dent = debugfs_create_file(node->name, S_IFREG | S_IRUGO,
1069                                            eeepc->debug.root, node,
1070                                            &eeepc_wmi_debugfs_io_ops);
1071                 if (!dent) {
1072                         pr_err("failed to create debug file: %s\n", node->name);
1073                         goto error_debugfs;
1074                 }
1075         }
1076
1077         return 0;
1078
1079 error_debugfs:
1080         eeepc_wmi_debugfs_exit(eeepc);
1081         return -ENOMEM;
1082 }
1083
1084 /*
1085  * WMI Driver
1086  */
1087 static void eeepc_dmi_check(struct eeepc_wmi *eeepc)
1088 {
1089         const char *model;
1090
1091         model = dmi_get_system_info(DMI_PRODUCT_NAME);
1092         if (!model)
1093                 return;
1094
1095         /*
1096          * Whitelist for wlan hotplug
1097          *
1098          * Eeepc 1000H needs the current hotplug code to handle
1099          * Fn+F2 correctly. We may add other Eeepc here later, but
1100          * it seems that most of the laptops supported by eeepc-wmi
1101          * don't need to be on this list
1102          */
1103         if (strcmp(model, "1000H") == 0) {
1104                 eeepc->hotplug_wireless = true;
1105                 pr_info("wlan hotplug enabled\n");
1106         }
1107 }
1108
1109 static struct platform_device * __init eeepc_wmi_add(void)
1110 {
1111         struct eeepc_wmi *eeepc;
1112         acpi_status status;
1113         int err;
1114
1115         eeepc = kzalloc(sizeof(struct eeepc_wmi), GFP_KERNEL);
1116         if (!eeepc)
1117                 return ERR_PTR(-ENOMEM);
1118
1119         eeepc->hotplug_wireless = hotplug_wireless;
1120         eeepc_dmi_check(eeepc);
1121
1122         /*
1123          * Register the platform device first.  It is used as a parent for the
1124          * sub-devices below.
1125          */
1126         err = eeepc_wmi_platform_init(eeepc);
1127         if (err)
1128                 goto fail_platform;
1129
1130         err = eeepc_wmi_input_init(eeepc);
1131         if (err)
1132                 goto fail_input;
1133
1134         err = eeepc_wmi_led_init(eeepc);
1135         if (err)
1136                 goto fail_leds;
1137
1138         err = eeepc_wmi_rfkill_init(eeepc);
1139         if (err)
1140                 goto fail_rfkill;
1141
1142         if (!acpi_video_backlight_support()) {
1143                 err = eeepc_wmi_backlight_init(eeepc);
1144                 if (err)
1145                         goto fail_backlight;
1146         } else
1147                 pr_info("Backlight controlled by ACPI video driver\n");
1148
1149         status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID,
1150                                             eeepc_wmi_notify, eeepc);
1151         if (ACPI_FAILURE(status)) {
1152                 pr_err("Unable to register notify handler - %d\n",
1153                         status);
1154                 err = -ENODEV;
1155                 goto fail_wmi_handler;
1156         }
1157
1158         err = eeepc_wmi_debugfs_init(eeepc);
1159         if (err)
1160                 goto fail_debugfs;
1161
1162         return eeepc->platform_device;
1163
1164 fail_debugfs:
1165         wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
1166 fail_wmi_handler:
1167         eeepc_wmi_backlight_exit(eeepc);
1168 fail_backlight:
1169         eeepc_wmi_rfkill_exit(eeepc);
1170 fail_rfkill:
1171         eeepc_wmi_led_exit(eeepc);
1172 fail_leds:
1173         eeepc_wmi_input_exit(eeepc);
1174 fail_input:
1175         eeepc_wmi_platform_exit(eeepc);
1176 fail_platform:
1177         kfree(eeepc);
1178         return ERR_PTR(err);
1179 }
1180
1181 static int eeepc_wmi_remove(struct platform_device *device)
1182 {
1183         struct eeepc_wmi *eeepc;
1184
1185         eeepc = platform_get_drvdata(device);
1186         wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
1187         eeepc_wmi_backlight_exit(eeepc);
1188         eeepc_wmi_input_exit(eeepc);
1189         eeepc_wmi_led_exit(eeepc);
1190         eeepc_wmi_rfkill_exit(eeepc);
1191         eeepc_wmi_debugfs_exit(eeepc);
1192         eeepc_wmi_platform_exit(eeepc);
1193
1194         kfree(eeepc);
1195         return 0;
1196 }
1197
1198 static struct platform_driver platform_driver = {
1199         .driver = {
1200                 .name = EEEPC_WMI_FILE,
1201                 .owner = THIS_MODULE,
1202         },
1203 };
1204
1205 static acpi_status __init eeepc_wmi_parse_device(acpi_handle handle, u32 level,
1206                                                  void *context, void **retval)
1207 {
1208         pr_warning("Found legacy ATKD device (%s)", EEEPC_ACPI_HID);
1209         *(bool *)context = true;
1210         return AE_CTRL_TERMINATE;
1211 }
1212
1213 static int __init eeepc_wmi_check_atkd(void)
1214 {
1215         acpi_status status;
1216         bool found = false;
1217
1218         status = acpi_get_devices(EEEPC_ACPI_HID, eeepc_wmi_parse_device,
1219                                   &found, NULL);
1220
1221         if (ACPI_FAILURE(status) || !found)
1222                 return 0;
1223         return -1;
1224 }
1225
1226 static int __init eeepc_wmi_init(void)
1227 {
1228         int err;
1229
1230         if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID) ||
1231             !wmi_has_guid(EEEPC_WMI_MGMT_GUID)) {
1232                 pr_warning("No known WMI GUID found\n");
1233                 return -ENODEV;
1234         }
1235
1236         if (eeepc_wmi_check_atkd()) {
1237                 pr_warning("WMI device present, but legacy ATKD device is also "
1238                            "present and enabled.");
1239                 pr_warning("You probably booted with acpi_osi=\"Linux\" or "
1240                            "acpi_osi=\"!Windows 2009\"");
1241                 pr_warning("Can't load eeepc-wmi, use default acpi_osi "
1242                            "(preferred) or eeepc-laptop");
1243                 return -ENODEV;
1244         }
1245
1246         platform_device = eeepc_wmi_add();
1247         if (IS_ERR(platform_device)) {
1248                 err = PTR_ERR(platform_device);
1249                 goto fail_eeepc_wmi;
1250         }
1251
1252         err = platform_driver_register(&platform_driver);
1253         if (err) {
1254                 pr_warning("Unable to register platform driver\n");
1255                 goto fail_platform_driver;
1256         }
1257
1258         return 0;
1259
1260 fail_platform_driver:
1261         eeepc_wmi_remove(platform_device);
1262 fail_eeepc_wmi:
1263         return err;
1264 }
1265
1266 static void __exit eeepc_wmi_exit(void)
1267 {
1268         eeepc_wmi_remove(platform_device);
1269         platform_driver_unregister(&platform_driver);
1270 }
1271
1272 module_init(eeepc_wmi_init);
1273 module_exit(eeepc_wmi_exit);