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
69 #define EEEPC_WMI_METHODID_DSTS 0x53544344
70 #define EEEPC_WMI_METHODID_DEVS 0x53564544
71 #define EEEPC_WMI_METHODID_CFVS 0x53564643
74 #define EEEPC_WMI_DEVID_WLAN 0x00010011
75 #define EEEPC_WMI_DEVID_BLUETOOTH 0x00010013
76 #define EEEPC_WMI_DEVID_WIMAX 0x00010017
77 #define EEEPC_WMI_DEVID_WWAN3G 0x00010019
79 /* Backlight and Brightness */
80 #define EEEPC_WMI_DEVID_BACKLIGHT 0x00050011
81 #define EEEPC_WMI_DEVID_BRIGHTNESS 0x00050012
84 #define EEEPC_WMI_DEVID_CAMERA 0x00060013
87 #define EEEPC_WMI_DEVID_CARDREADER 0x00080013
90 #define EEEPC_WMI_DEVID_TOUCHPAD 0x00100011
91 #define EEEPC_WMI_DEVID_TOUCHPAD_LED 0x00100012
94 #define EEEPC_WMI_DSTS_STATUS_BIT 0x00000001
95 #define EEEPC_WMI_DSTS_PRESENCE_BIT 0x00010000
96 #define EEEPC_WMI_DSTS_BRIGHTNESS_MASK 0x000000FF
97 #define EEEPC_WMI_DSTS_MAX_BRIGTH_MASK 0x0000FF00
99 static bool hotplug_wireless;
101 module_param(hotplug_wireless, bool, 0444);
102 MODULE_PARM_DESC(hotplug_wireless,
103 "Enable hotplug for wireless device. "
104 "If your laptop needs that, please report to "
105 "acpi4asus-user@lists.sourceforge.net.");
107 /* Values for T101MT "Home" key */
108 #define HOME_PRESS 0xe4
109 #define HOME_HOLD 0xea
110 #define HOME_RELEASE 0xe5
112 #define EEEPC_WMI_KEY_IGNORE (-1)
114 static const struct key_entry eeepc_wmi_keymap[] = {
115 /* Sleep already handled via generic ACPI code */
116 { KE_IGNORE, NOTIFY_BRNDOWN_MIN, { KEY_BRIGHTNESSDOWN } },
117 { KE_IGNORE, NOTIFY_BRNUP_MIN, { KEY_BRIGHTNESSUP } },
118 { KE_KEY, 0x30, { KEY_VOLUMEUP } },
119 { KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
120 { KE_KEY, 0x32, { KEY_MUTE } },
121 { KE_KEY, 0x5c, { KEY_F15 } }, /* Power Gear key */
122 { KE_KEY, 0x5d, { KEY_WLAN } },
123 { KE_KEY, 0x6b, { KEY_F13 } }, /* Disable Touchpad */
124 { KE_KEY, 0x88, { KEY_WLAN } },
125 { KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } },
126 { KE_KEY, 0xe0, { KEY_PROG1 } }, /* Task Manager */
127 { KE_KEY, 0xe1, { KEY_F14 } }, /* Change Resolution */
128 { KE_KEY, HOME_PRESS, { KEY_CONFIG } },
129 { KE_KEY, 0xe9, { KEY_BRIGHTNESS_ZERO } },
139 * eeepc-wmi/ - debugfs root directory
140 * dev_id - current dev_id
141 * ctrl_param - current ctrl_param
142 * devs - call DEVS(dev_id, ctrl_param) and print result
143 * dsts - call DSTS(dev_id) and print result
145 struct eeepc_wmi_debug {
152 bool hotplug_wireless;
154 struct input_dev *inputdev;
155 struct backlight_device *backlight_device;
156 struct platform_device *platform_device;
158 struct led_classdev tpd_led;
160 struct workqueue_struct *led_workqueue;
161 struct work_struct tpd_led_work;
163 struct rfkill *wlan_rfkill;
164 struct rfkill *bluetooth_rfkill;
165 struct rfkill *wimax_rfkill;
166 struct rfkill *wwan3g_rfkill;
168 struct hotplug_slot *hotplug_slot;
169 struct mutex hotplug_lock;
170 struct mutex wmi_lock;
171 struct workqueue_struct *hotplug_workqueue;
172 struct work_struct hotplug_work;
174 struct eeepc_wmi_debug debug;
177 static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc)
181 eeepc->inputdev = input_allocate_device();
182 if (!eeepc->inputdev)
185 eeepc->inputdev->name = "Eee PC WMI hotkeys";
186 eeepc->inputdev->phys = EEEPC_WMI_FILE "/input0";
187 eeepc->inputdev->id.bustype = BUS_HOST;
188 eeepc->inputdev->dev.parent = &eeepc->platform_device->dev;
189 __set_bit(EV_REP, eeepc->inputdev->evbit);
191 err = sparse_keymap_setup(eeepc->inputdev, eeepc_wmi_keymap, NULL);
195 err = input_register_device(eeepc->inputdev);
197 goto err_free_keymap;
202 sparse_keymap_free(eeepc->inputdev);
204 input_free_device(eeepc->inputdev);
208 static void eeepc_wmi_input_exit(struct eeepc_wmi *eeepc)
210 if (eeepc->inputdev) {
211 sparse_keymap_free(eeepc->inputdev);
212 input_unregister_device(eeepc->inputdev);
215 eeepc->inputdev = NULL;
218 static acpi_status eeepc_wmi_get_devstate(u32 dev_id, u32 *retval)
220 struct acpi_buffer input = { (acpi_size)sizeof(u32), &dev_id };
221 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
222 union acpi_object *obj;
226 status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
227 1, EEEPC_WMI_METHODID_DSTS,
230 if (ACPI_FAILURE(status))
233 obj = (union acpi_object *)output.pointer;
234 if (obj && obj->type == ACPI_TYPE_INTEGER)
235 tmp = (u32)obj->integer.value;
248 static acpi_status eeepc_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
251 struct bios_args args = {
253 .ctrl_param = ctrl_param,
255 struct acpi_buffer input = { (acpi_size)sizeof(args), &args };
259 status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID, 1,
260 EEEPC_WMI_METHODID_DEVS,
263 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
264 union acpi_object *obj;
267 status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID, 1,
268 EEEPC_WMI_METHODID_DEVS,
271 if (ACPI_FAILURE(status))
274 obj = (union acpi_object *)output.pointer;
275 if (obj && obj->type == ACPI_TYPE_INTEGER)
276 tmp = (u32)obj->integer.value;
288 /* Helper for special devices with magic return codes */
289 static int eeepc_wmi_get_devstate_bits(u32 dev_id, u32 mask)
294 status = eeepc_wmi_get_devstate(dev_id, &retval);
296 if (ACPI_FAILURE(status))
299 if (!(retval & EEEPC_WMI_DSTS_PRESENCE_BIT))
302 return retval & mask;
305 static int eeepc_wmi_get_devstate_simple(u32 dev_id)
307 return eeepc_wmi_get_devstate_bits(dev_id, EEEPC_WMI_DSTS_STATUS_BIT);
314 * These functions actually update the LED's, and are called from a
315 * workqueue. By doing this as separate work rather than when the LED
316 * subsystem asks, we avoid messing with the Eeepc ACPI stuff during a
317 * potentially bad time, such as a timer interrupt.
319 static void tpd_led_update(struct work_struct *work)
322 struct eeepc_wmi *eeepc;
324 eeepc = container_of(work, struct eeepc_wmi, tpd_led_work);
326 ctrl_param = eeepc->tpd_led_wk;
327 eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_TOUCHPAD_LED, ctrl_param, NULL);
330 static void tpd_led_set(struct led_classdev *led_cdev,
331 enum led_brightness value)
333 struct eeepc_wmi *eeepc;
335 eeepc = container_of(led_cdev, struct eeepc_wmi, tpd_led);
337 eeepc->tpd_led_wk = !!value;
338 queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
341 static int read_tpd_led_state(struct eeepc_wmi *eeepc)
343 return eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_TOUCHPAD_LED);
346 static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
348 struct eeepc_wmi *eeepc;
350 eeepc = container_of(led_cdev, struct eeepc_wmi, tpd_led);
352 return read_tpd_led_state(eeepc);
355 static int eeepc_wmi_led_init(struct eeepc_wmi *eeepc)
359 if (read_tpd_led_state(eeepc) < 0)
362 eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
363 if (!eeepc->led_workqueue)
365 INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);
367 eeepc->tpd_led.name = "eeepc::touchpad";
368 eeepc->tpd_led.brightness_set = tpd_led_set;
369 eeepc->tpd_led.brightness_get = tpd_led_get;
370 eeepc->tpd_led.max_brightness = 1;
372 rv = led_classdev_register(&eeepc->platform_device->dev,
375 destroy_workqueue(eeepc->led_workqueue);
382 static void eeepc_wmi_led_exit(struct eeepc_wmi *eeepc)
384 if (eeepc->tpd_led.dev)
385 led_classdev_unregister(&eeepc->tpd_led);
386 if (eeepc->led_workqueue)
387 destroy_workqueue(eeepc->led_workqueue);
391 * PCI hotplug (for wlan rfkill)
393 static bool eeepc_wlan_rfkill_blocked(struct eeepc_wmi *eeepc)
395 int result = eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WLAN);
402 static void eeepc_rfkill_hotplug(struct eeepc_wmi *eeepc)
410 mutex_lock(&eeepc->wmi_lock);
411 blocked = eeepc_wlan_rfkill_blocked(eeepc);
412 mutex_unlock(&eeepc->wmi_lock);
414 mutex_lock(&eeepc->hotplug_lock);
416 if (eeepc->wlan_rfkill)
417 rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
419 if (eeepc->hotplug_slot) {
420 bus = pci_find_bus(0, 1);
422 pr_warning("Unable to find PCI bus 1?\n");
426 if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
427 pr_err("Unable to read PCI config space?\n");
430 absent = (l == 0xffffffff);
432 if (blocked != absent) {
433 pr_warning("BIOS says wireless lan is %s, "
434 "but the pci device is %s\n",
435 blocked ? "blocked" : "unblocked",
436 absent ? "absent" : "present");
437 pr_warning("skipped wireless hotplug as probably "
438 "inappropriate for this model\n");
443 dev = pci_get_slot(bus, 0);
445 /* Device already present */
449 dev = pci_scan_single_device(bus, 0);
451 pci_bus_assign_resources(bus);
452 if (pci_bus_add_device(dev))
453 pr_err("Unable to hotplug wifi\n");
456 dev = pci_get_slot(bus, 0);
458 pci_remove_bus_device(dev);
465 mutex_unlock(&eeepc->hotplug_lock);
468 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
470 struct eeepc_wmi *eeepc = data;
472 if (event != ACPI_NOTIFY_BUS_CHECK)
476 * We can't call directly eeepc_rfkill_hotplug because most
477 * of the time WMBC is still being executed and not reetrant.
478 * There is currently no way to tell ACPICA that we want this
479 * method to be serialized, we schedule a eeepc_rfkill_hotplug
480 * call later, in a safer context.
482 queue_work(eeepc->hotplug_workqueue, &eeepc->hotplug_work);
485 static int eeepc_register_rfkill_notifier(struct eeepc_wmi *eeepc,
491 status = acpi_get_handle(NULL, node, &handle);
493 if (ACPI_SUCCESS(status)) {
494 status = acpi_install_notify_handler(handle,
498 if (ACPI_FAILURE(status))
499 pr_warning("Failed to register notify on %s\n", node);
506 static void eeepc_unregister_rfkill_notifier(struct eeepc_wmi *eeepc,
509 acpi_status status = AE_OK;
512 status = acpi_get_handle(NULL, node, &handle);
514 if (ACPI_SUCCESS(status)) {
515 status = acpi_remove_notify_handler(handle,
517 eeepc_rfkill_notify);
518 if (ACPI_FAILURE(status))
519 pr_err("Error removing rfkill notify handler %s\n",
524 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
527 int result = eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WLAN);
536 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
538 kfree(hotplug_slot->info);
542 static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
543 .owner = THIS_MODULE,
544 .get_adapter_status = eeepc_get_adapter_status,
545 .get_power_status = eeepc_get_adapter_status,
548 static void eeepc_hotplug_work(struct work_struct *work)
550 struct eeepc_wmi *eeepc;
552 eeepc = container_of(work, struct eeepc_wmi, hotplug_work);
553 eeepc_rfkill_hotplug(eeepc);
556 static int eeepc_setup_pci_hotplug(struct eeepc_wmi *eeepc)
559 struct pci_bus *bus = pci_find_bus(0, 1);
562 pr_err("Unable to find wifi PCI bus\n");
566 eeepc->hotplug_workqueue =
567 create_singlethread_workqueue("hotplug_workqueue");
568 if (!eeepc->hotplug_workqueue)
569 goto error_workqueue;
571 INIT_WORK(&eeepc->hotplug_work, eeepc_hotplug_work);
573 eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
574 if (!eeepc->hotplug_slot)
577 eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
579 if (!eeepc->hotplug_slot->info)
582 eeepc->hotplug_slot->private = eeepc;
583 eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
584 eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
585 eeepc_get_adapter_status(eeepc->hotplug_slot,
586 &eeepc->hotplug_slot->info->adapter_status);
588 ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
590 pr_err("Unable to register hotplug slot - %d\n", ret);
597 kfree(eeepc->hotplug_slot->info);
599 kfree(eeepc->hotplug_slot);
600 eeepc->hotplug_slot = NULL;
602 destroy_workqueue(eeepc->hotplug_workqueue);
610 static int eeepc_rfkill_set(void *data, bool blocked)
612 int dev_id = (unsigned long)data;
613 u32 ctrl_param = !blocked;
616 status = eeepc_wmi_set_devstate(dev_id, ctrl_param, NULL);
618 if (ACPI_FAILURE(status))
624 static void eeepc_rfkill_query(struct rfkill *rfkill, void *data)
626 int dev_id = (unsigned long)data;
629 result = eeepc_wmi_get_devstate_simple(dev_id);
634 rfkill_set_sw_state(rfkill, !result);
637 static int eeepc_rfkill_wlan_set(void *data, bool blocked)
639 struct eeepc_wmi *eeepc = data;
643 * This handler is enabled only if hotplug is enabled.
644 * In this case, the eeepc_wmi_set_devstate() will
645 * trigger a wmi notification and we need to wait
646 * this call to finish before being able to call
649 mutex_lock(&eeepc->wmi_lock);
650 ret = eeepc_rfkill_set((void *)(long)EEEPC_WMI_DEVID_WLAN, blocked);
651 mutex_unlock(&eeepc->wmi_lock);
655 static void eeepc_rfkill_wlan_query(struct rfkill *rfkill, void *data)
657 eeepc_rfkill_query(rfkill, (void *)(long)EEEPC_WMI_DEVID_WLAN);
660 static const struct rfkill_ops eeepc_rfkill_wlan_ops = {
661 .set_block = eeepc_rfkill_wlan_set,
662 .query = eeepc_rfkill_wlan_query,
665 static const struct rfkill_ops eeepc_rfkill_ops = {
666 .set_block = eeepc_rfkill_set,
667 .query = eeepc_rfkill_query,
670 static int eeepc_new_rfkill(struct eeepc_wmi *eeepc,
671 struct rfkill **rfkill,
673 enum rfkill_type type, int dev_id)
675 int result = eeepc_wmi_get_devstate_simple(dev_id);
680 if (dev_id == EEEPC_WMI_DEVID_WLAN && eeepc->hotplug_wireless)
681 *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
682 &eeepc_rfkill_wlan_ops, eeepc);
684 *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
685 &eeepc_rfkill_ops, (void *)(long)dev_id);
690 rfkill_init_sw_state(*rfkill, !result);
691 result = rfkill_register(*rfkill);
693 rfkill_destroy(*rfkill);
700 static void eeepc_wmi_rfkill_exit(struct eeepc_wmi *eeepc)
702 eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
703 eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
704 eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
705 if (eeepc->wlan_rfkill) {
706 rfkill_unregister(eeepc->wlan_rfkill);
707 rfkill_destroy(eeepc->wlan_rfkill);
708 eeepc->wlan_rfkill = NULL;
711 * Refresh pci hotplug in case the rfkill state was changed after
712 * eeepc_unregister_rfkill_notifier()
714 eeepc_rfkill_hotplug(eeepc);
715 if (eeepc->hotplug_slot)
716 pci_hp_deregister(eeepc->hotplug_slot);
717 if (eeepc->hotplug_workqueue)
718 destroy_workqueue(eeepc->hotplug_workqueue);
720 if (eeepc->bluetooth_rfkill) {
721 rfkill_unregister(eeepc->bluetooth_rfkill);
722 rfkill_destroy(eeepc->bluetooth_rfkill);
723 eeepc->bluetooth_rfkill = NULL;
725 if (eeepc->wimax_rfkill) {
726 rfkill_unregister(eeepc->wimax_rfkill);
727 rfkill_destroy(eeepc->wimax_rfkill);
728 eeepc->wimax_rfkill = NULL;
730 if (eeepc->wwan3g_rfkill) {
731 rfkill_unregister(eeepc->wwan3g_rfkill);
732 rfkill_destroy(eeepc->wwan3g_rfkill);
733 eeepc->wwan3g_rfkill = NULL;
737 static int eeepc_wmi_rfkill_init(struct eeepc_wmi *eeepc)
741 mutex_init(&eeepc->hotplug_lock);
742 mutex_init(&eeepc->wmi_lock);
744 result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
745 "eeepc-wlan", RFKILL_TYPE_WLAN,
746 EEEPC_WMI_DEVID_WLAN);
748 if (result && result != -ENODEV)
751 result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
752 "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
753 EEEPC_WMI_DEVID_BLUETOOTH);
755 if (result && result != -ENODEV)
758 result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
759 "eeepc-wimax", RFKILL_TYPE_WIMAX,
760 EEEPC_WMI_DEVID_WIMAX);
762 if (result && result != -ENODEV)
765 result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
766 "eeepc-wwan3g", RFKILL_TYPE_WWAN,
767 EEEPC_WMI_DEVID_WWAN3G);
769 if (result && result != -ENODEV)
772 if (!eeepc->hotplug_wireless)
775 result = eeepc_setup_pci_hotplug(eeepc);
777 * If we get -EBUSY then something else is handling the PCI hotplug -
778 * don't fail in this case
780 if (result == -EBUSY)
783 eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
784 eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
785 eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
787 * Refresh pci hotplug in case the rfkill state was changed during
790 eeepc_rfkill_hotplug(eeepc);
793 if (result && result != -ENODEV)
794 eeepc_wmi_rfkill_exit(eeepc);
796 if (result == -ENODEV)
805 static int read_backlight_power(void)
807 int ret = eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_BACKLIGHT);
812 return ret ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
815 static int read_brightness(struct backlight_device *bd)
820 status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BRIGHTNESS, &retval);
822 if (ACPI_FAILURE(status))
825 return retval & EEEPC_WMI_DSTS_BRIGHTNESS_MASK;
828 static int update_bl_status(struct backlight_device *bd)
834 ctrl_param = bd->props.brightness;
836 status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BRIGHTNESS,
839 if (ACPI_FAILURE(status))
842 power = read_backlight_power();
843 if (power != -ENODEV && bd->props.power != power) {
844 ctrl_param = !!(bd->props.power == FB_BLANK_UNBLANK);
845 status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT,
848 if (ACPI_FAILURE(status))
854 static const struct backlight_ops eeepc_wmi_bl_ops = {
855 .get_brightness = read_brightness,
856 .update_status = update_bl_status,
859 static int eeepc_wmi_backlight_notify(struct eeepc_wmi *eeepc, int code)
861 struct backlight_device *bd = eeepc->backlight_device;
862 int old = bd->props.brightness;
865 if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
866 new = code - NOTIFY_BRNUP_MIN + 1;
867 else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
868 new = code - NOTIFY_BRNDOWN_MIN;
870 bd->props.brightness = new;
871 backlight_update_status(bd);
872 backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
877 static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
879 struct backlight_device *bd;
880 struct backlight_properties props;
884 max = eeepc_wmi_get_devstate_bits(EEEPC_WMI_DEVID_BRIGHTNESS,
885 EEEPC_WMI_DSTS_MAX_BRIGTH_MASK);
886 power = read_backlight_power();
888 if (max < 0 && power < 0) {
889 /* Try to keep the original error */
890 if (max == -ENODEV && power == -ENODEV)
899 if (power == -ENODEV)
900 power = FB_BLANK_UNBLANK;
902 memset(&props, 0, sizeof(struct backlight_properties));
903 props.max_brightness = max;
904 bd = backlight_device_register(EEEPC_WMI_FILE,
905 &eeepc->platform_device->dev, eeepc,
906 &eeepc_wmi_bl_ops, &props);
908 pr_err("Could not register backlight device\n");
912 eeepc->backlight_device = bd;
914 bd->props.brightness = read_brightness(bd);
915 bd->props.power = power;
916 backlight_update_status(bd);
921 static void eeepc_wmi_backlight_exit(struct eeepc_wmi *eeepc)
923 if (eeepc->backlight_device)
924 backlight_device_unregister(eeepc->backlight_device);
926 eeepc->backlight_device = NULL;
929 static void eeepc_wmi_homekey_filter(struct eeepc_wmi *eeepc, int *code,
930 unsigned int *value, bool *autorelease)
938 *code = EEEPC_WMI_KEY_IGNORE;
948 static void eeepc_wmi_notify(u32 value, void *context)
950 struct eeepc_wmi *eeepc = context;
951 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
952 union acpi_object *obj;
956 unsigned int key_value = 1;
957 bool autorelease = 1;
959 status = wmi_get_event_data(value, &response);
960 if (status != AE_OK) {
961 pr_err("bad event status 0x%x\n", status);
965 obj = (union acpi_object *)response.pointer;
967 if (obj && obj->type == ACPI_TYPE_INTEGER) {
968 code = obj->integer.value;
971 eeepc_wmi_homekey_filter(eeepc, &code, &key_value,
973 if (code == EEEPC_WMI_KEY_IGNORE)
976 if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
977 code = NOTIFY_BRNUP_MIN;
978 else if (code >= NOTIFY_BRNDOWN_MIN &&
979 code <= NOTIFY_BRNDOWN_MAX)
980 code = NOTIFY_BRNDOWN_MIN;
982 if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) {
983 if (!acpi_video_backlight_support())
984 eeepc_wmi_backlight_notify(eeepc, orig_code);
987 if (!sparse_keymap_report_event(eeepc->inputdev, code,
988 key_value, autorelease))
989 pr_info("Unknown key %x pressed\n", code);
999 static int parse_arg(const char *buf, unsigned long count, int *val)
1003 if (sscanf(buf, "%i", val) != 1)
1008 static ssize_t store_sys_wmi(int devid, const char *buf, size_t count)
1014 value = eeepc_wmi_get_devstate_simple(devid);
1015 if (value == -ENODEV) /* Check device presence */
1018 rv = parse_arg(buf, count, &value);
1019 status = eeepc_wmi_set_devstate(devid, value, &retval);
1021 if (ACPI_FAILURE(status))
1026 static ssize_t show_sys_wmi(int devid, char *buf)
1028 int value = eeepc_wmi_get_devstate_simple(devid);
1033 return sprintf(buf, "%d\n", value);
1036 #define EEEPC_WMI_CREATE_DEVICE_ATTR(_name, _mode, _cm) \
1037 static ssize_t show_##_name(struct device *dev, \
1038 struct device_attribute *attr, \
1041 return show_sys_wmi(_cm, buf); \
1043 static ssize_t store_##_name(struct device *dev, \
1044 struct device_attribute *attr, \
1045 const char *buf, size_t count) \
1047 return store_sys_wmi(_cm, buf, count); \
1049 static struct device_attribute dev_attr_##_name = { \
1051 .name = __stringify(_name), \
1053 .show = show_##_name, \
1054 .store = store_##_name, \
1057 EEEPC_WMI_CREATE_DEVICE_ATTR(touchpad, 0644, EEEPC_WMI_DEVID_TOUCHPAD);
1058 EEEPC_WMI_CREATE_DEVICE_ATTR(camera, 0644, EEEPC_WMI_DEVID_CAMERA);
1059 EEEPC_WMI_CREATE_DEVICE_ATTR(cardr, 0644, EEEPC_WMI_DEVID_CARDREADER);
1061 static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr,
1062 const char *buf, size_t count)
1065 struct acpi_buffer input = { (acpi_size)sizeof(value), &value };
1068 if (!count || sscanf(buf, "%i", &value) != 1)
1070 if (value < 0 || value > 2)
1073 status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
1074 1, EEEPC_WMI_METHODID_CFVS, &input, NULL);
1076 if (ACPI_FAILURE(status))
1082 static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv);
1084 static struct attribute *platform_attributes[] = {
1085 &dev_attr_cpufv.attr,
1086 &dev_attr_camera.attr,
1087 &dev_attr_cardr.attr,
1088 &dev_attr_touchpad.attr,
1092 static mode_t eeepc_sysfs_is_visible(struct kobject *kobj,
1093 struct attribute *attr,
1096 bool supported = true;
1099 if (attr == &dev_attr_camera.attr)
1100 devid = EEEPC_WMI_DEVID_CAMERA;
1101 else if (attr == &dev_attr_cardr.attr)
1102 devid = EEEPC_WMI_DEVID_CARDREADER;
1103 else if (attr == &dev_attr_touchpad.attr)
1104 devid = EEEPC_WMI_DEVID_TOUCHPAD;
1107 supported = eeepc_wmi_get_devstate_simple(devid) != -ENODEV;
1109 return supported ? attr->mode : 0;
1112 static struct attribute_group platform_attribute_group = {
1113 .is_visible = eeepc_sysfs_is_visible,
1114 .attrs = platform_attributes
1117 static void eeepc_wmi_sysfs_exit(struct platform_device *device)
1119 sysfs_remove_group(&device->dev.kobj, &platform_attribute_group);
1122 static int eeepc_wmi_sysfs_init(struct platform_device *device)
1124 return sysfs_create_group(&device->dev.kobj, &platform_attribute_group);
1130 static int __init eeepc_wmi_platform_init(struct eeepc_wmi *eeepc)
1132 return eeepc_wmi_sysfs_init(eeepc->platform_device);
1135 static void eeepc_wmi_platform_exit(struct eeepc_wmi *eeepc)
1137 eeepc_wmi_sysfs_exit(eeepc->platform_device);
1143 struct eeepc_wmi_debugfs_node {
1144 struct eeepc_wmi *eeepc;
1146 int (*show)(struct seq_file *m, void *data);
1149 static int show_dsts(struct seq_file *m, void *data)
1151 struct eeepc_wmi *eeepc = m->private;
1155 status = eeepc_wmi_get_devstate(eeepc->debug.dev_id, &retval);
1157 if (ACPI_FAILURE(status))
1160 seq_printf(m, "DSTS(%x) = %x\n", eeepc->debug.dev_id, retval);
1165 static int show_devs(struct seq_file *m, void *data)
1167 struct eeepc_wmi *eeepc = m->private;
1171 status = eeepc_wmi_set_devstate(eeepc->debug.dev_id,
1172 eeepc->debug.ctrl_param, &retval);
1173 if (ACPI_FAILURE(status))
1176 seq_printf(m, "DEVS(%x, %x) = %x\n", eeepc->debug.dev_id,
1177 eeepc->debug.ctrl_param, retval);
1182 static struct eeepc_wmi_debugfs_node eeepc_wmi_debug_files[] = {
1183 { NULL, "devs", show_devs },
1184 { NULL, "dsts", show_dsts },
1187 static int eeepc_wmi_debugfs_open(struct inode *inode, struct file *file)
1189 struct eeepc_wmi_debugfs_node *node = inode->i_private;
1191 return single_open(file, node->show, node->eeepc);
1194 static const struct file_operations eeepc_wmi_debugfs_io_ops = {
1195 .owner = THIS_MODULE,
1196 .open = eeepc_wmi_debugfs_open,
1198 .llseek = seq_lseek,
1199 .release = single_release,
1202 static void eeepc_wmi_debugfs_exit(struct eeepc_wmi *eeepc)
1204 debugfs_remove_recursive(eeepc->debug.root);
1207 static int eeepc_wmi_debugfs_init(struct eeepc_wmi *eeepc)
1209 struct dentry *dent;
1212 eeepc->debug.root = debugfs_create_dir(EEEPC_WMI_FILE, NULL);
1213 if (!eeepc->debug.root) {
1214 pr_err("failed to create debugfs directory");
1218 dent = debugfs_create_x32("dev_id", S_IRUGO|S_IWUSR,
1219 eeepc->debug.root, &eeepc->debug.dev_id);
1223 dent = debugfs_create_x32("ctrl_param", S_IRUGO|S_IWUSR,
1224 eeepc->debug.root, &eeepc->debug.ctrl_param);
1228 for (i = 0; i < ARRAY_SIZE(eeepc_wmi_debug_files); i++) {
1229 struct eeepc_wmi_debugfs_node *node = &eeepc_wmi_debug_files[i];
1231 node->eeepc = eeepc;
1232 dent = debugfs_create_file(node->name, S_IFREG | S_IRUGO,
1233 eeepc->debug.root, node,
1234 &eeepc_wmi_debugfs_io_ops);
1236 pr_err("failed to create debug file: %s\n", node->name);
1244 eeepc_wmi_debugfs_exit(eeepc);
1251 static void eeepc_dmi_check(struct eeepc_wmi *eeepc)
1255 model = dmi_get_system_info(DMI_PRODUCT_NAME);
1260 * Whitelist for wlan hotplug
1262 * Eeepc 1000H needs the current hotplug code to handle
1263 * Fn+F2 correctly. We may add other Eeepc here later, but
1264 * it seems that most of the laptops supported by eeepc-wmi
1265 * don't need to be on this list
1267 if (strcmp(model, "1000H") == 0) {
1268 eeepc->hotplug_wireless = true;
1269 pr_info("wlan hotplug enabled\n");
1273 static int __init eeepc_wmi_add(struct platform_device *pdev)
1275 struct eeepc_wmi *eeepc;
1279 eeepc = kzalloc(sizeof(struct eeepc_wmi), GFP_KERNEL);
1283 eeepc->platform_device = pdev;
1284 platform_set_drvdata(eeepc->platform_device, eeepc);
1286 eeepc->hotplug_wireless = hotplug_wireless;
1287 eeepc_dmi_check(eeepc);
1289 err = eeepc_wmi_platform_init(eeepc);
1293 err = eeepc_wmi_input_init(eeepc);
1297 err = eeepc_wmi_led_init(eeepc);
1301 err = eeepc_wmi_rfkill_init(eeepc);
1305 if (!acpi_video_backlight_support()) {
1306 err = eeepc_wmi_backlight_init(eeepc);
1307 if (err && err != -ENODEV)
1308 goto fail_backlight;
1310 pr_info("Backlight controlled by ACPI video driver\n");
1312 status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID,
1313 eeepc_wmi_notify, eeepc);
1314 if (ACPI_FAILURE(status)) {
1315 pr_err("Unable to register notify handler - %d\n",
1318 goto fail_wmi_handler;
1321 err = eeepc_wmi_debugfs_init(eeepc);
1328 wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
1330 eeepc_wmi_backlight_exit(eeepc);
1332 eeepc_wmi_rfkill_exit(eeepc);
1334 eeepc_wmi_led_exit(eeepc);
1336 eeepc_wmi_input_exit(eeepc);
1338 eeepc_wmi_platform_exit(eeepc);
1344 static int __exit eeepc_wmi_remove(struct platform_device *device)
1346 struct eeepc_wmi *eeepc;
1348 eeepc = platform_get_drvdata(device);
1349 wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
1350 eeepc_wmi_backlight_exit(eeepc);
1351 eeepc_wmi_input_exit(eeepc);
1352 eeepc_wmi_led_exit(eeepc);
1353 eeepc_wmi_rfkill_exit(eeepc);
1354 eeepc_wmi_debugfs_exit(eeepc);
1355 eeepc_wmi_platform_exit(eeepc);
1362 * Platform driver - hibernate/resume callbacks
1364 static int eeepc_hotk_thaw(struct device *device)
1366 struct eeepc_wmi *eeepc = dev_get_drvdata(device);
1368 if (eeepc->wlan_rfkill) {
1372 * Work around bios bug - acpi _PTS turns off the wireless led
1373 * during suspend. Normally it restores it on resume, but
1374 * we should kick it ourselves in case hibernation is aborted.
1376 wlan = eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WLAN);
1377 eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_WLAN, wlan, NULL);
1383 static int eeepc_hotk_restore(struct device *device)
1385 struct eeepc_wmi *eeepc = dev_get_drvdata(device);
1388 /* Refresh both wlan rfkill state and pci hotplug */
1389 if (eeepc->wlan_rfkill)
1390 eeepc_rfkill_hotplug(eeepc);
1392 if (eeepc->bluetooth_rfkill) {
1393 bl = !eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_BLUETOOTH);
1394 rfkill_set_sw_state(eeepc->bluetooth_rfkill, bl);
1396 if (eeepc->wimax_rfkill) {
1397 bl = !eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WIMAX);
1398 rfkill_set_sw_state(eeepc->wimax_rfkill, bl);
1400 if (eeepc->wwan3g_rfkill) {
1401 bl = !eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_WWAN3G);
1402 rfkill_set_sw_state(eeepc->wwan3g_rfkill, bl);
1408 static const struct dev_pm_ops eeepc_pm_ops = {
1409 .thaw = eeepc_hotk_thaw,
1410 .restore = eeepc_hotk_restore,
1413 static struct platform_driver platform_driver = {
1414 .remove = __exit_p(eeepc_wmi_remove),
1416 .name = EEEPC_WMI_FILE,
1417 .owner = THIS_MODULE,
1418 .pm = &eeepc_pm_ops,
1422 static acpi_status __init eeepc_wmi_parse_device(acpi_handle handle, u32 level,
1423 void *context, void **retval)
1425 pr_warning("Found legacy ATKD device (%s)", EEEPC_ACPI_HID);
1426 *(bool *)context = true;
1427 return AE_CTRL_TERMINATE;
1430 static int __init eeepc_wmi_check_atkd(void)
1435 status = acpi_get_devices(EEEPC_ACPI_HID, eeepc_wmi_parse_device,
1438 if (ACPI_FAILURE(status) || !found)
1443 static int __init eeepc_wmi_probe(struct platform_device *pdev)
1445 if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID) ||
1446 !wmi_has_guid(EEEPC_WMI_MGMT_GUID)) {
1447 pr_warning("No known WMI GUID found\n");
1451 if (eeepc_wmi_check_atkd()) {
1452 pr_warning("WMI device present, but legacy ATKD device is also "
1453 "present and enabled.");
1454 pr_warning("You probably booted with acpi_osi=\"Linux\" or "
1455 "acpi_osi=\"!Windows 2009\"");
1456 pr_warning("Can't load eeepc-wmi, use default acpi_osi "
1457 "(preferred) or eeepc-laptop");
1461 return eeepc_wmi_add(pdev);
1464 static struct platform_device *platform_device;
1466 static int __init eeepc_wmi_init(void)
1468 platform_device = platform_create_bundle(&platform_driver,
1471 if (IS_ERR(platform_device))
1472 return PTR_ERR(platform_device);
1476 static void __exit eeepc_wmi_exit(void)
1478 platform_device_unregister(platform_device);
1479 platform_driver_unregister(&platform_driver);
1482 module_init(eeepc_wmi_init);
1483 module_exit(eeepc_wmi_exit);