2 * Eee PC WMI hotkey driver
4 * Copyright(C) 2010 Intel Corporation.
5 * Copyright(C) 2010 Corentin Chary <corentin.chary@gmail.com>
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>
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.
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.
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
27 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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>
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>
49 #define EEEPC_WMI_FILE "eeepc-wmi"
51 MODULE_AUTHOR("Yong Wang <yong.y.wang@intel.com>");
52 MODULE_DESCRIPTION("Eee PC WMI Hotkey Driver");
53 MODULE_LICENSE("GPL");
55 #define EEEPC_ACPI_HID "ASUS010" /* old _HID used in eeepc-laptop */
57 #define EEEPC_WMI_EVENT_GUID "ABBC0F72-8EA1-11D1-00A0-C90629100000"
58 #define EEEPC_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66"
60 MODULE_ALIAS("wmi:"EEEPC_WMI_EVENT_GUID
);
61 MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID
);
63 #define NOTIFY_BRNUP_MIN 0x11
64 #define NOTIFY_BRNUP_MAX 0x1f
65 #define NOTIFY_BRNDOWN_MIN 0x20
66 #define NOTIFY_BRNDOWN_MAX 0x2e
68 #define EEEPC_WMI_METHODID_DSTS 0x53544344
69 #define EEEPC_WMI_METHODID_DEVS 0x53564544
70 #define EEEPC_WMI_METHODID_CFVS 0x53564643
72 #define EEEPC_WMI_DEVID_WLAN 0x00010011
73 #define EEEPC_WMI_DEVID_BLUETOOTH 0x00010013
74 #define EEEPC_WMI_DEVID_WWAN3G 0x00010019
75 #define EEEPC_WMI_DEVID_BACKLIGHT 0x00050012
76 #define EEEPC_WMI_DEVID_CAMERA 0x00060013
77 #define EEEPC_WMI_DEVID_CARDREADER 0x00080013
78 #define EEEPC_WMI_DEVID_TPDLED 0x00100011
80 #define EEEPC_WMI_DSTS_STATUS_BIT 0x00000001
81 #define EEEPC_WMI_DSTS_PRESENCE_BIT 0x00010000
83 static bool hotplug_wireless
;
85 module_param(hotplug_wireless
, bool, 0444);
86 MODULE_PARM_DESC(hotplug_wireless
,
87 "Enable hotplug for wireless device. "
88 "If your laptop needs that, please report to "
89 "acpi4asus-user@lists.sourceforge.net.");
91 static const struct key_entry eeepc_wmi_keymap
[] = {
92 /* Sleep already handled via generic ACPI code */
93 { KE_IGNORE
, NOTIFY_BRNDOWN_MIN
, { KEY_BRIGHTNESSDOWN
} },
94 { KE_IGNORE
, NOTIFY_BRNUP_MIN
, { KEY_BRIGHTNESSUP
} },
95 { KE_KEY
, 0x30, { KEY_VOLUMEUP
} },
96 { KE_KEY
, 0x31, { KEY_VOLUMEDOWN
} },
97 { KE_KEY
, 0x32, { KEY_MUTE
} },
98 { KE_KEY
, 0x5c, { KEY_F15
} },
99 { KE_KEY
, 0x5d, { KEY_WLAN
} },
100 { KE_KEY
, 0x6b, { KEY_F13
} }, /* Disable Touchpad */
101 { KE_KEY
, 0x88, { KEY_WLAN
} },
102 { KE_KEY
, 0xcc, { KEY_SWITCHVIDEOMODE
} },
103 { KE_KEY
, 0xe0, { KEY_PROG1
} },
104 { KE_KEY
, 0xe1, { KEY_F14
} },
105 { KE_KEY
, 0xe9, { KEY_DISPLAY_OFF
} },
115 * eeepc-wmi/ - debugfs root directory
116 * dev_id - current dev_id
117 * ctrl_param - current ctrl_param
118 * devs - call DEVS(dev_id, ctrl_param) and print result
119 * dsts - call DSTS(dev_id) and print result
121 struct eeepc_wmi_debug
{
128 bool hotplug_wireless
;
130 struct input_dev
*inputdev
;
131 struct backlight_device
*backlight_device
;
132 struct platform_device
*platform_device
;
134 struct led_classdev tpd_led
;
136 struct workqueue_struct
*led_workqueue
;
137 struct work_struct tpd_led_work
;
139 struct rfkill
*wlan_rfkill
;
140 struct rfkill
*bluetooth_rfkill
;
141 struct rfkill
*wwan3g_rfkill
;
143 struct hotplug_slot
*hotplug_slot
;
144 struct mutex hotplug_lock
;
145 struct mutex wmi_lock
;
146 struct workqueue_struct
*hotplug_workqueue
;
147 struct work_struct hotplug_work
;
149 struct eeepc_wmi_debug debug
;
152 static int eeepc_wmi_input_init(struct eeepc_wmi
*eeepc
)
156 eeepc
->inputdev
= input_allocate_device();
157 if (!eeepc
->inputdev
)
160 eeepc
->inputdev
->name
= "Eee PC WMI hotkeys";
161 eeepc
->inputdev
->phys
= EEEPC_WMI_FILE
"/input0";
162 eeepc
->inputdev
->id
.bustype
= BUS_HOST
;
163 eeepc
->inputdev
->dev
.parent
= &eeepc
->platform_device
->dev
;
165 err
= sparse_keymap_setup(eeepc
->inputdev
, eeepc_wmi_keymap
, NULL
);
169 err
= input_register_device(eeepc
->inputdev
);
171 goto err_free_keymap
;
176 sparse_keymap_free(eeepc
->inputdev
);
178 input_free_device(eeepc
->inputdev
);
182 static void eeepc_wmi_input_exit(struct eeepc_wmi
*eeepc
)
184 if (eeepc
->inputdev
) {
185 sparse_keymap_free(eeepc
->inputdev
);
186 input_unregister_device(eeepc
->inputdev
);
189 eeepc
->inputdev
= NULL
;
192 static acpi_status
eeepc_wmi_get_devstate(u32 dev_id
, u32
*retval
)
194 struct acpi_buffer input
= { (acpi_size
)sizeof(u32
), &dev_id
};
195 struct acpi_buffer output
= { ACPI_ALLOCATE_BUFFER
, NULL
};
196 union acpi_object
*obj
;
200 status
= wmi_evaluate_method(EEEPC_WMI_MGMT_GUID
,
201 1, EEEPC_WMI_METHODID_DSTS
,
204 if (ACPI_FAILURE(status
))
207 obj
= (union acpi_object
*)output
.pointer
;
208 if (obj
&& obj
->type
== ACPI_TYPE_INTEGER
)
209 tmp
= (u32
)obj
->integer
.value
;
222 static acpi_status
eeepc_wmi_set_devstate(u32 dev_id
, u32 ctrl_param
,
225 struct bios_args args
= {
227 .ctrl_param
= ctrl_param
,
229 struct acpi_buffer input
= { (acpi_size
)sizeof(args
), &args
};
233 status
= wmi_evaluate_method(EEEPC_WMI_MGMT_GUID
, 1,
234 EEEPC_WMI_METHODID_DEVS
,
237 struct acpi_buffer output
= { ACPI_ALLOCATE_BUFFER
, NULL
};
238 union acpi_object
*obj
;
241 status
= wmi_evaluate_method(EEEPC_WMI_MGMT_GUID
, 1,
242 EEEPC_WMI_METHODID_DEVS
,
245 if (ACPI_FAILURE(status
))
248 obj
= (union acpi_object
*)output
.pointer
;
249 if (obj
&& obj
->type
== ACPI_TYPE_INTEGER
)
250 tmp
= (u32
)obj
->integer
.value
;
262 /* Helper for special devices with magic return codes */
263 static int eeepc_wmi_get_devstate_simple(u32 dev_id
)
268 status
= eeepc_wmi_get_devstate(dev_id
, &retval
);
270 if (ACPI_FAILURE(status
))
273 if (!(retval
& EEEPC_WMI_DSTS_PRESENCE_BIT
))
276 return retval
& EEEPC_WMI_DSTS_STATUS_BIT
;
283 * These functions actually update the LED's, and are called from a
284 * workqueue. By doing this as separate work rather than when the LED
285 * subsystem asks, we avoid messing with the Eeepc ACPI stuff during a
286 * potentially bad time, such as a timer interrupt.
288 static void tpd_led_update(struct work_struct
*work
)
291 struct eeepc_wmi
*eeepc
;
293 eeepc
= container_of(work
, struct eeepc_wmi
, tpd_led_work
);
295 ctrl_param
= eeepc
->tpd_led_wk
;
296 eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_TPDLED
, ctrl_param
, NULL
);
299 static void tpd_led_set(struct led_classdev
*led_cdev
,
300 enum led_brightness value
)
302 struct eeepc_wmi
*eeepc
;
304 eeepc
= container_of(led_cdev
, struct eeepc_wmi
, tpd_led
);
306 eeepc
->tpd_led_wk
= !!value
;
307 queue_work(eeepc
->led_workqueue
, &eeepc
->tpd_led_work
);
310 static int read_tpd_state(struct eeepc_wmi
*eeepc
)
312 return eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_TPDLED
);
315 static enum led_brightness
tpd_led_get(struct led_classdev
*led_cdev
)
317 struct eeepc_wmi
*eeepc
;
319 eeepc
= container_of(led_cdev
, struct eeepc_wmi
, tpd_led
);
321 return read_tpd_state(eeepc
);
324 static int eeepc_wmi_led_init(struct eeepc_wmi
*eeepc
)
328 if (read_tpd_state(eeepc
) < 0)
331 eeepc
->led_workqueue
= create_singlethread_workqueue("led_workqueue");
332 if (!eeepc
->led_workqueue
)
334 INIT_WORK(&eeepc
->tpd_led_work
, tpd_led_update
);
336 eeepc
->tpd_led
.name
= "eeepc::touchpad";
337 eeepc
->tpd_led
.brightness_set
= tpd_led_set
;
338 eeepc
->tpd_led
.brightness_get
= tpd_led_get
;
339 eeepc
->tpd_led
.max_brightness
= 1;
341 rv
= led_classdev_register(&eeepc
->platform_device
->dev
,
344 destroy_workqueue(eeepc
->led_workqueue
);
351 static void eeepc_wmi_led_exit(struct eeepc_wmi
*eeepc
)
353 if (eeepc
->tpd_led
.dev
)
354 led_classdev_unregister(&eeepc
->tpd_led
);
355 if (eeepc
->led_workqueue
)
356 destroy_workqueue(eeepc
->led_workqueue
);
360 * PCI hotplug (for wlan rfkill)
362 static bool eeepc_wlan_rfkill_blocked(struct eeepc_wmi
*eeepc
)
364 int result
= eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WLAN
);
371 static void eeepc_rfkill_hotplug(struct eeepc_wmi
*eeepc
)
379 mutex_lock(&eeepc
->wmi_lock
);
380 blocked
= eeepc_wlan_rfkill_blocked(eeepc
);
381 mutex_unlock(&eeepc
->wmi_lock
);
383 mutex_lock(&eeepc
->hotplug_lock
);
385 if (eeepc
->wlan_rfkill
)
386 rfkill_set_sw_state(eeepc
->wlan_rfkill
, blocked
);
388 if (eeepc
->hotplug_slot
) {
389 bus
= pci_find_bus(0, 1);
391 pr_warning("Unable to find PCI bus 1?\n");
395 if (pci_bus_read_config_dword(bus
, 0, PCI_VENDOR_ID
, &l
)) {
396 pr_err("Unable to read PCI config space?\n");
399 absent
= (l
== 0xffffffff);
401 if (blocked
!= absent
) {
402 pr_warning("BIOS says wireless lan is %s, "
403 "but the pci device is %s\n",
404 blocked
? "blocked" : "unblocked",
405 absent
? "absent" : "present");
406 pr_warning("skipped wireless hotplug as probably "
407 "inappropriate for this model\n");
412 dev
= pci_get_slot(bus
, 0);
414 /* Device already present */
418 dev
= pci_scan_single_device(bus
, 0);
420 pci_bus_assign_resources(bus
);
421 if (pci_bus_add_device(dev
))
422 pr_err("Unable to hotplug wifi\n");
425 dev
= pci_get_slot(bus
, 0);
427 pci_remove_bus_device(dev
);
434 mutex_unlock(&eeepc
->hotplug_lock
);
437 static void eeepc_rfkill_notify(acpi_handle handle
, u32 event
, void *data
)
439 struct eeepc_wmi
*eeepc
= data
;
441 if (event
!= ACPI_NOTIFY_BUS_CHECK
)
445 * We can't call directly eeepc_rfkill_hotplug because most
446 * of the time WMBC is still being executed and not reetrant.
447 * There is currently no way to tell ACPICA that we want this
448 * method to be serialized, we schedule a eeepc_rfkill_hotplug
449 * call later, in a safer context.
451 queue_work(eeepc
->hotplug_workqueue
, &eeepc
->hotplug_work
);
454 static int eeepc_register_rfkill_notifier(struct eeepc_wmi
*eeepc
,
460 status
= acpi_get_handle(NULL
, node
, &handle
);
462 if (ACPI_SUCCESS(status
)) {
463 status
= acpi_install_notify_handler(handle
,
467 if (ACPI_FAILURE(status
))
468 pr_warning("Failed to register notify on %s\n", node
);
475 static void eeepc_unregister_rfkill_notifier(struct eeepc_wmi
*eeepc
,
478 acpi_status status
= AE_OK
;
481 status
= acpi_get_handle(NULL
, node
, &handle
);
483 if (ACPI_SUCCESS(status
)) {
484 status
= acpi_remove_notify_handler(handle
,
486 eeepc_rfkill_notify
);
487 if (ACPI_FAILURE(status
))
488 pr_err("Error removing rfkill notify handler %s\n",
493 static int eeepc_get_adapter_status(struct hotplug_slot
*hotplug_slot
,
496 int result
= eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WLAN
);
505 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot
*hotplug_slot
)
507 kfree(hotplug_slot
->info
);
511 static struct hotplug_slot_ops eeepc_hotplug_slot_ops
= {
512 .owner
= THIS_MODULE
,
513 .get_adapter_status
= eeepc_get_adapter_status
,
514 .get_power_status
= eeepc_get_adapter_status
,
517 static void eeepc_hotplug_work(struct work_struct
*work
)
519 struct eeepc_wmi
*eeepc
;
521 eeepc
= container_of(work
, struct eeepc_wmi
, hotplug_work
);
522 eeepc_rfkill_hotplug(eeepc
);
525 static int eeepc_setup_pci_hotplug(struct eeepc_wmi
*eeepc
)
528 struct pci_bus
*bus
= pci_find_bus(0, 1);
531 pr_err("Unable to find wifi PCI bus\n");
535 eeepc
->hotplug_workqueue
=
536 create_singlethread_workqueue("hotplug_workqueue");
537 if (!eeepc
->hotplug_workqueue
)
538 goto error_workqueue
;
540 INIT_WORK(&eeepc
->hotplug_work
, eeepc_hotplug_work
);
542 eeepc
->hotplug_slot
= kzalloc(sizeof(struct hotplug_slot
), GFP_KERNEL
);
543 if (!eeepc
->hotplug_slot
)
546 eeepc
->hotplug_slot
->info
= kzalloc(sizeof(struct hotplug_slot_info
),
548 if (!eeepc
->hotplug_slot
->info
)
551 eeepc
->hotplug_slot
->private = eeepc
;
552 eeepc
->hotplug_slot
->release
= &eeepc_cleanup_pci_hotplug
;
553 eeepc
->hotplug_slot
->ops
= &eeepc_hotplug_slot_ops
;
554 eeepc_get_adapter_status(eeepc
->hotplug_slot
,
555 &eeepc
->hotplug_slot
->info
->adapter_status
);
557 ret
= pci_hp_register(eeepc
->hotplug_slot
, bus
, 0, "eeepc-wifi");
559 pr_err("Unable to register hotplug slot - %d\n", ret
);
566 kfree(eeepc
->hotplug_slot
->info
);
568 kfree(eeepc
->hotplug_slot
);
569 eeepc
->hotplug_slot
= NULL
;
571 destroy_workqueue(eeepc
->hotplug_workqueue
);
579 static int eeepc_rfkill_set(void *data
, bool blocked
)
581 int dev_id
= (unsigned long)data
;
582 u32 ctrl_param
= !blocked
;
585 status
= eeepc_wmi_set_devstate(dev_id
, ctrl_param
, NULL
);
587 if (ACPI_FAILURE(status
))
593 static void eeepc_rfkill_query(struct rfkill
*rfkill
, void *data
)
595 int dev_id
= (unsigned long)data
;
598 result
= eeepc_wmi_get_devstate_simple(dev_id
);
603 rfkill_set_sw_state(rfkill
, !result
);
606 static int eeepc_rfkill_wlan_set(void *data
, bool blocked
)
608 struct eeepc_wmi
*eeepc
= data
;
612 * This handler is enabled only if hotplug is enabled.
613 * In this case, the eeepc_wmi_set_devstate() will
614 * trigger a wmi notification and we need to wait
615 * this call to finish before being able to call
618 mutex_lock(&eeepc
->wmi_lock
);
619 ret
= eeepc_rfkill_set((void *)(long)EEEPC_WMI_DEVID_WLAN
, blocked
);
620 mutex_unlock(&eeepc
->wmi_lock
);
624 static void eeepc_rfkill_wlan_query(struct rfkill
*rfkill
, void *data
)
626 eeepc_rfkill_query(rfkill
, (void *)(long)EEEPC_WMI_DEVID_WLAN
);
629 static const struct rfkill_ops eeepc_rfkill_wlan_ops
= {
630 .set_block
= eeepc_rfkill_wlan_set
,
631 .query
= eeepc_rfkill_wlan_query
,
634 static const struct rfkill_ops eeepc_rfkill_ops
= {
635 .set_block
= eeepc_rfkill_set
,
636 .query
= eeepc_rfkill_query
,
639 static int eeepc_new_rfkill(struct eeepc_wmi
*eeepc
,
640 struct rfkill
**rfkill
,
642 enum rfkill_type type
, int dev_id
)
644 int result
= eeepc_wmi_get_devstate_simple(dev_id
);
649 if (dev_id
== EEEPC_WMI_DEVID_WLAN
&& eeepc
->hotplug_wireless
)
650 *rfkill
= rfkill_alloc(name
, &eeepc
->platform_device
->dev
, type
,
651 &eeepc_rfkill_wlan_ops
, eeepc
);
653 *rfkill
= rfkill_alloc(name
, &eeepc
->platform_device
->dev
, type
,
654 &eeepc_rfkill_ops
, (void *)(long)dev_id
);
659 rfkill_init_sw_state(*rfkill
, !result
);
660 result
= rfkill_register(*rfkill
);
662 rfkill_destroy(*rfkill
);
669 static void eeepc_wmi_rfkill_exit(struct eeepc_wmi
*eeepc
)
671 eeepc_unregister_rfkill_notifier(eeepc
, "\\_SB.PCI0.P0P5");
672 eeepc_unregister_rfkill_notifier(eeepc
, "\\_SB.PCI0.P0P6");
673 eeepc_unregister_rfkill_notifier(eeepc
, "\\_SB.PCI0.P0P7");
674 if (eeepc
->wlan_rfkill
) {
675 rfkill_unregister(eeepc
->wlan_rfkill
);
676 rfkill_destroy(eeepc
->wlan_rfkill
);
677 eeepc
->wlan_rfkill
= NULL
;
680 * Refresh pci hotplug in case the rfkill state was changed after
681 * eeepc_unregister_rfkill_notifier()
683 eeepc_rfkill_hotplug(eeepc
);
684 if (eeepc
->hotplug_slot
)
685 pci_hp_deregister(eeepc
->hotplug_slot
);
686 if (eeepc
->hotplug_workqueue
)
687 destroy_workqueue(eeepc
->hotplug_workqueue
);
689 if (eeepc
->bluetooth_rfkill
) {
690 rfkill_unregister(eeepc
->bluetooth_rfkill
);
691 rfkill_destroy(eeepc
->bluetooth_rfkill
);
692 eeepc
->bluetooth_rfkill
= NULL
;
694 if (eeepc
->wwan3g_rfkill
) {
695 rfkill_unregister(eeepc
->wwan3g_rfkill
);
696 rfkill_destroy(eeepc
->wwan3g_rfkill
);
697 eeepc
->wwan3g_rfkill
= NULL
;
701 static int eeepc_wmi_rfkill_init(struct eeepc_wmi
*eeepc
)
705 mutex_init(&eeepc
->hotplug_lock
);
706 mutex_init(&eeepc
->wmi_lock
);
708 result
= eeepc_new_rfkill(eeepc
, &eeepc
->wlan_rfkill
,
709 "eeepc-wlan", RFKILL_TYPE_WLAN
,
710 EEEPC_WMI_DEVID_WLAN
);
712 if (result
&& result
!= -ENODEV
)
715 result
= eeepc_new_rfkill(eeepc
, &eeepc
->bluetooth_rfkill
,
716 "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH
,
717 EEEPC_WMI_DEVID_BLUETOOTH
);
719 if (result
&& result
!= -ENODEV
)
722 result
= eeepc_new_rfkill(eeepc
, &eeepc
->wwan3g_rfkill
,
723 "eeepc-wwan3g", RFKILL_TYPE_WWAN
,
724 EEEPC_WMI_DEVID_WWAN3G
);
726 if (result
&& result
!= -ENODEV
)
729 result
= eeepc_setup_pci_hotplug(eeepc
);
731 * If we get -EBUSY then something else is handling the PCI hotplug -
732 * don't fail in this case
734 if (result
== -EBUSY
)
737 eeepc_register_rfkill_notifier(eeepc
, "\\_SB.PCI0.P0P5");
738 eeepc_register_rfkill_notifier(eeepc
, "\\_SB.PCI0.P0P6");
739 eeepc_register_rfkill_notifier(eeepc
, "\\_SB.PCI0.P0P7");
741 * Refresh pci hotplug in case the rfkill state was changed during
744 eeepc_rfkill_hotplug(eeepc
);
747 if (result
&& result
!= -ENODEV
)
748 eeepc_wmi_rfkill_exit(eeepc
);
750 if (result
== -ENODEV
)
759 static int read_brightness(struct backlight_device
*bd
)
764 status
= eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT
, &retval
);
766 if (ACPI_FAILURE(status
))
769 return retval
& 0xFF;
772 static int update_bl_status(struct backlight_device
*bd
)
778 ctrl_param
= bd
->props
.brightness
;
780 status
= eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT
,
783 if (ACPI_FAILURE(status
))
789 static const struct backlight_ops eeepc_wmi_bl_ops
= {
790 .get_brightness
= read_brightness
,
791 .update_status
= update_bl_status
,
794 static int eeepc_wmi_backlight_notify(struct eeepc_wmi
*eeepc
, int code
)
796 struct backlight_device
*bd
= eeepc
->backlight_device
;
797 int old
= bd
->props
.brightness
;
800 if (code
>= NOTIFY_BRNUP_MIN
&& code
<= NOTIFY_BRNUP_MAX
)
801 new = code
- NOTIFY_BRNUP_MIN
+ 1;
802 else if (code
>= NOTIFY_BRNDOWN_MIN
&& code
<= NOTIFY_BRNDOWN_MAX
)
803 new = code
- NOTIFY_BRNDOWN_MIN
;
805 bd
->props
.brightness
= new;
806 backlight_update_status(bd
);
807 backlight_force_update(bd
, BACKLIGHT_UPDATE_HOTKEY
);
812 static int eeepc_wmi_backlight_init(struct eeepc_wmi
*eeepc
)
814 struct backlight_device
*bd
;
815 struct backlight_properties props
;
817 memset(&props
, 0, sizeof(struct backlight_properties
));
818 props
.max_brightness
= 15;
819 bd
= backlight_device_register(EEEPC_WMI_FILE
,
820 &eeepc
->platform_device
->dev
, eeepc
,
821 &eeepc_wmi_bl_ops
, &props
);
823 pr_err("Could not register backlight device\n");
827 eeepc
->backlight_device
= bd
;
829 bd
->props
.brightness
= read_brightness(bd
);
830 bd
->props
.power
= FB_BLANK_UNBLANK
;
831 backlight_update_status(bd
);
836 static void eeepc_wmi_backlight_exit(struct eeepc_wmi
*eeepc
)
838 if (eeepc
->backlight_device
)
839 backlight_device_unregister(eeepc
->backlight_device
);
841 eeepc
->backlight_device
= NULL
;
844 static void eeepc_wmi_notify(u32 value
, void *context
)
846 struct eeepc_wmi
*eeepc
= context
;
847 struct acpi_buffer response
= { ACPI_ALLOCATE_BUFFER
, NULL
};
848 union acpi_object
*obj
;
853 status
= wmi_get_event_data(value
, &response
);
854 if (status
!= AE_OK
) {
855 pr_err("bad event status 0x%x\n", status
);
859 obj
= (union acpi_object
*)response
.pointer
;
861 if (obj
&& obj
->type
== ACPI_TYPE_INTEGER
) {
862 code
= obj
->integer
.value
;
865 if (code
>= NOTIFY_BRNUP_MIN
&& code
<= NOTIFY_BRNUP_MAX
)
866 code
= NOTIFY_BRNUP_MIN
;
867 else if (code
>= NOTIFY_BRNDOWN_MIN
&&
868 code
<= NOTIFY_BRNDOWN_MAX
)
869 code
= NOTIFY_BRNDOWN_MIN
;
871 if (code
== NOTIFY_BRNUP_MIN
|| code
== NOTIFY_BRNDOWN_MIN
) {
872 if (!acpi_video_backlight_support())
873 eeepc_wmi_backlight_notify(eeepc
, orig_code
);
876 if (!sparse_keymap_report_event(eeepc
->inputdev
,
878 pr_info("Unknown key %x pressed\n", code
);
887 static int parse_arg(const char *buf
, unsigned long count
, int *val
)
891 if (sscanf(buf
, "%i", val
) != 1)
896 static ssize_t
store_sys_wmi(int devid
, const char *buf
, size_t count
)
902 value
= eeepc_wmi_get_devstate_simple(devid
);
903 if (value
== -ENODEV
) /* Check device presence */
906 rv
= parse_arg(buf
, count
, &value
);
907 status
= eeepc_wmi_set_devstate(devid
, value
, &retval
);
909 if (ACPI_FAILURE(status
))
914 static ssize_t
show_sys_wmi(int devid
, char *buf
)
916 int value
= eeepc_wmi_get_devstate_simple(devid
);
921 return sprintf(buf
, "%d\n", value
);
924 #define EEEPC_WMI_CREATE_DEVICE_ATTR(_name, _mode, _cm) \
925 static ssize_t show_##_name(struct device *dev, \
926 struct device_attribute *attr, \
929 return show_sys_wmi(_cm, buf); \
931 static ssize_t store_##_name(struct device *dev, \
932 struct device_attribute *attr, \
933 const char *buf, size_t count) \
935 return store_sys_wmi(_cm, buf, count); \
937 static struct device_attribute dev_attr_##_name = { \
939 .name = __stringify(_name), \
941 .show = show_##_name, \
942 .store = store_##_name, \
945 EEEPC_WMI_CREATE_DEVICE_ATTR(camera
, 0644, EEEPC_WMI_DEVID_CAMERA
);
946 EEEPC_WMI_CREATE_DEVICE_ATTR(cardr
, 0644, EEEPC_WMI_DEVID_CARDREADER
);
948 static ssize_t
store_cpufv(struct device
*dev
, struct device_attribute
*attr
,
949 const char *buf
, size_t count
)
952 struct acpi_buffer input
= { (acpi_size
)sizeof(value
), &value
};
955 if (!count
|| sscanf(buf
, "%i", &value
) != 1)
957 if (value
< 0 || value
> 2)
960 status
= wmi_evaluate_method(EEEPC_WMI_MGMT_GUID
,
961 1, EEEPC_WMI_METHODID_CFVS
, &input
, NULL
);
963 if (ACPI_FAILURE(status
))
969 static DEVICE_ATTR(cpufv
, S_IRUGO
| S_IWUSR
, NULL
, store_cpufv
);
971 static struct attribute
*platform_attributes
[] = {
972 &dev_attr_cpufv
.attr
,
973 &dev_attr_camera
.attr
,
974 &dev_attr_cardr
.attr
,
978 static mode_t
eeepc_sysfs_is_visible(struct kobject
*kobj
,
979 struct attribute
*attr
,
982 bool supported
= true;
985 if (attr
== &dev_attr_camera
.attr
)
986 devid
= EEEPC_WMI_DEVID_CAMERA
;
987 else if (attr
== &dev_attr_cardr
.attr
)
988 devid
= EEEPC_WMI_DEVID_CARDREADER
;
991 supported
= eeepc_wmi_get_devstate_simple(devid
) != -ENODEV
;
993 return supported
? attr
->mode
: 0;
996 static struct attribute_group platform_attribute_group
= {
997 .is_visible
= eeepc_sysfs_is_visible
,
998 .attrs
= platform_attributes
1001 static void eeepc_wmi_sysfs_exit(struct platform_device
*device
)
1003 sysfs_remove_group(&device
->dev
.kobj
, &platform_attribute_group
);
1006 static int eeepc_wmi_sysfs_init(struct platform_device
*device
)
1008 return sysfs_create_group(&device
->dev
.kobj
, &platform_attribute_group
);
1014 static int __init
eeepc_wmi_platform_init(struct eeepc_wmi
*eeepc
)
1016 return eeepc_wmi_sysfs_init(eeepc
->platform_device
);
1019 static void eeepc_wmi_platform_exit(struct eeepc_wmi
*eeepc
)
1021 eeepc_wmi_sysfs_exit(eeepc
->platform_device
);
1027 struct eeepc_wmi_debugfs_node
{
1028 struct eeepc_wmi
*eeepc
;
1030 int (*show
)(struct seq_file
*m
, void *data
);
1033 static int show_dsts(struct seq_file
*m
, void *data
)
1035 struct eeepc_wmi
*eeepc
= m
->private;
1039 status
= eeepc_wmi_get_devstate(eeepc
->debug
.dev_id
, &retval
);
1041 if (ACPI_FAILURE(status
))
1044 seq_printf(m
, "DSTS(%x) = %x\n", eeepc
->debug
.dev_id
, retval
);
1049 static int show_devs(struct seq_file
*m
, void *data
)
1051 struct eeepc_wmi
*eeepc
= m
->private;
1055 status
= eeepc_wmi_set_devstate(eeepc
->debug
.dev_id
,
1056 eeepc
->debug
.ctrl_param
, &retval
);
1057 if (ACPI_FAILURE(status
))
1060 seq_printf(m
, "DEVS(%x, %x) = %x\n", eeepc
->debug
.dev_id
,
1061 eeepc
->debug
.ctrl_param
, retval
);
1066 static struct eeepc_wmi_debugfs_node eeepc_wmi_debug_files
[] = {
1067 { NULL
, "devs", show_devs
},
1068 { NULL
, "dsts", show_dsts
},
1071 static int eeepc_wmi_debugfs_open(struct inode
*inode
, struct file
*file
)
1073 struct eeepc_wmi_debugfs_node
*node
= inode
->i_private
;
1075 return single_open(file
, node
->show
, node
->eeepc
);
1078 static const struct file_operations eeepc_wmi_debugfs_io_ops
= {
1079 .owner
= THIS_MODULE
,
1080 .open
= eeepc_wmi_debugfs_open
,
1082 .llseek
= seq_lseek
,
1083 .release
= single_release
,
1086 static void eeepc_wmi_debugfs_exit(struct eeepc_wmi
*eeepc
)
1088 debugfs_remove_recursive(eeepc
->debug
.root
);
1091 static int eeepc_wmi_debugfs_init(struct eeepc_wmi
*eeepc
)
1093 struct dentry
*dent
;
1096 eeepc
->debug
.root
= debugfs_create_dir(EEEPC_WMI_FILE
, NULL
);
1097 if (!eeepc
->debug
.root
) {
1098 pr_err("failed to create debugfs directory");
1102 dent
= debugfs_create_x32("dev_id", S_IRUGO
|S_IWUSR
,
1103 eeepc
->debug
.root
, &eeepc
->debug
.dev_id
);
1107 dent
= debugfs_create_x32("ctrl_param", S_IRUGO
|S_IWUSR
,
1108 eeepc
->debug
.root
, &eeepc
->debug
.ctrl_param
);
1112 for (i
= 0; i
< ARRAY_SIZE(eeepc_wmi_debug_files
); i
++) {
1113 struct eeepc_wmi_debugfs_node
*node
= &eeepc_wmi_debug_files
[i
];
1115 node
->eeepc
= eeepc
;
1116 dent
= debugfs_create_file(node
->name
, S_IFREG
| S_IRUGO
,
1117 eeepc
->debug
.root
, node
,
1118 &eeepc_wmi_debugfs_io_ops
);
1120 pr_err("failed to create debug file: %s\n", node
->name
);
1128 eeepc_wmi_debugfs_exit(eeepc
);
1135 static void eeepc_dmi_check(struct eeepc_wmi
*eeepc
)
1139 model
= dmi_get_system_info(DMI_PRODUCT_NAME
);
1144 * Whitelist for wlan hotplug
1146 * Eeepc 1000H needs the current hotplug code to handle
1147 * Fn+F2 correctly. We may add other Eeepc here later, but
1148 * it seems that most of the laptops supported by eeepc-wmi
1149 * don't need to be on this list
1151 if (strcmp(model
, "1000H") == 0) {
1152 eeepc
->hotplug_wireless
= true;
1153 pr_info("wlan hotplug enabled\n");
1157 static int __init
eeepc_wmi_add(struct platform_device
*pdev
)
1159 struct eeepc_wmi
*eeepc
;
1163 eeepc
= kzalloc(sizeof(struct eeepc_wmi
), GFP_KERNEL
);
1167 eeepc
->platform_device
= pdev
;
1168 platform_set_drvdata(eeepc
->platform_device
, eeepc
);
1170 eeepc
->hotplug_wireless
= hotplug_wireless
;
1171 eeepc_dmi_check(eeepc
);
1173 err
= eeepc_wmi_platform_init(eeepc
);
1177 err
= eeepc_wmi_input_init(eeepc
);
1181 err
= eeepc_wmi_led_init(eeepc
);
1185 err
= eeepc_wmi_rfkill_init(eeepc
);
1189 if (!acpi_video_backlight_support()) {
1190 err
= eeepc_wmi_backlight_init(eeepc
);
1192 goto fail_backlight
;
1194 pr_info("Backlight controlled by ACPI video driver\n");
1196 status
= wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID
,
1197 eeepc_wmi_notify
, eeepc
);
1198 if (ACPI_FAILURE(status
)) {
1199 pr_err("Unable to register notify handler - %d\n",
1202 goto fail_wmi_handler
;
1205 err
= eeepc_wmi_debugfs_init(eeepc
);
1212 wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID
);
1214 eeepc_wmi_backlight_exit(eeepc
);
1216 eeepc_wmi_rfkill_exit(eeepc
);
1218 eeepc_wmi_led_exit(eeepc
);
1220 eeepc_wmi_input_exit(eeepc
);
1222 eeepc_wmi_platform_exit(eeepc
);
1228 static int __exit
eeepc_wmi_remove(struct platform_device
*device
)
1230 struct eeepc_wmi
*eeepc
;
1232 eeepc
= platform_get_drvdata(device
);
1233 wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID
);
1234 eeepc_wmi_backlight_exit(eeepc
);
1235 eeepc_wmi_input_exit(eeepc
);
1236 eeepc_wmi_led_exit(eeepc
);
1237 eeepc_wmi_rfkill_exit(eeepc
);
1238 eeepc_wmi_debugfs_exit(eeepc
);
1239 eeepc_wmi_platform_exit(eeepc
);
1246 * Platform driver - hibernate/resume callbacks
1248 static int eeepc_hotk_thaw(struct device
*device
)
1250 struct eeepc_wmi
*eeepc
= dev_get_drvdata(device
);
1252 if (eeepc
->wlan_rfkill
) {
1256 * Work around bios bug - acpi _PTS turns off the wireless led
1257 * during suspend. Normally it restores it on resume, but
1258 * we should kick it ourselves in case hibernation is aborted.
1260 wlan
= eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WLAN
);
1261 eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_WLAN
, wlan
, NULL
);
1267 static int eeepc_hotk_restore(struct device
*device
)
1269 struct eeepc_wmi
*eeepc
= dev_get_drvdata(device
);
1272 /* Refresh both wlan rfkill state and pci hotplug */
1273 if (eeepc
->wlan_rfkill
)
1274 eeepc_rfkill_hotplug(eeepc
);
1276 if (eeepc
->bluetooth_rfkill
) {
1277 bl
= !eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_BLUETOOTH
);
1278 rfkill_set_sw_state(eeepc
->bluetooth_rfkill
, bl
);
1280 if (eeepc
->wwan3g_rfkill
) {
1281 bl
= !eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WWAN3G
);
1282 rfkill_set_sw_state(eeepc
->wwan3g_rfkill
, bl
);
1288 static const struct dev_pm_ops eeepc_pm_ops
= {
1289 .thaw
= eeepc_hotk_thaw
,
1290 .restore
= eeepc_hotk_restore
,
1293 static struct platform_driver platform_driver
= {
1294 .remove
= __exit_p(eeepc_wmi_remove
),
1296 .name
= EEEPC_WMI_FILE
,
1297 .owner
= THIS_MODULE
,
1298 .pm
= &eeepc_pm_ops
,
1302 static acpi_status __init
eeepc_wmi_parse_device(acpi_handle handle
, u32 level
,
1303 void *context
, void **retval
)
1305 pr_warning("Found legacy ATKD device (%s)", EEEPC_ACPI_HID
);
1306 *(bool *)context
= true;
1307 return AE_CTRL_TERMINATE
;
1310 static int __init
eeepc_wmi_check_atkd(void)
1315 status
= acpi_get_devices(EEEPC_ACPI_HID
, eeepc_wmi_parse_device
,
1318 if (ACPI_FAILURE(status
) || !found
)
1323 static int __init
eeepc_wmi_probe(struct platform_device
*pdev
)
1325 if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID
) ||
1326 !wmi_has_guid(EEEPC_WMI_MGMT_GUID
)) {
1327 pr_warning("No known WMI GUID found\n");
1331 if (eeepc_wmi_check_atkd()) {
1332 pr_warning("WMI device present, but legacy ATKD device is also "
1333 "present and enabled.");
1334 pr_warning("You probably booted with acpi_osi=\"Linux\" or "
1335 "acpi_osi=\"!Windows 2009\"");
1336 pr_warning("Can't load eeepc-wmi, use default acpi_osi "
1337 "(preferred) or eeepc-laptop");
1341 return eeepc_wmi_add(pdev
);
1344 static struct platform_device
*platform_device
;
1346 static int __init
eeepc_wmi_init(void)
1348 platform_device
= platform_create_bundle(&platform_driver
,
1351 if (IS_ERR(platform_device
))
1352 return PTR_ERR(platform_device
);
1356 static void __exit
eeepc_wmi_exit(void)
1358 platform_device_unregister(platform_device
);
1359 platform_driver_unregister(&platform_driver
);
1362 module_init(eeepc_wmi_init
);
1363 module_exit(eeepc_wmi_exit
);