2 * Asus PC WMI hotkey driver
4 * Copyright(C) 2010 Intel Corporation.
5 * Copyright(C) 2010-2011 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 <acpi/acpi_bus.h>
46 #include <acpi/acpi_drivers.h>
50 MODULE_AUTHOR("Corentin Chary <corentincj@iksaif.net>, "
51 "Yong Wang <yong.y.wang@intel.com>");
52 MODULE_DESCRIPTION("Asus Generic WMI Driver");
53 MODULE_LICENSE("GPL");
55 #define to_platform_driver(drv) \
56 (container_of((drv), struct platform_driver, driver))
58 #define to_asus_wmi_driver(pdrv) \
59 (container_of((pdrv), struct asus_wmi_driver, platform_driver))
61 #define ASUS_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66"
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 ASUS_WMI_METHODID_SPEC 0x43455053
70 #define ASUS_WMI_METHODID_SFUN 0x4E554653
71 #define ASUS_WMI_METHODID_DSTS 0x53544344
72 #define ASUS_WMI_METHODID_DSTS2 0x53545344
73 #define ASUS_WMI_METHODID_DEVS 0x53564544
74 #define ASUS_WMI_METHODID_CFVS 0x53564643
75 #define ASUS_WMI_METHODID_INIT 0x54494E49
77 #define ASUS_WMI_UNSUPPORTED_METHOD 0xFFFFFFFE
80 #define ASUS_WMI_DEVID_WLAN 0x00010011
81 #define ASUS_WMI_DEVID_BLUETOOTH 0x00010013
82 #define ASUS_WMI_DEVID_WIMAX 0x00010017
83 #define ASUS_WMI_DEVID_WWAN3G 0x00010019
85 /* Backlight and Brightness */
86 #define ASUS_WMI_DEVID_BACKLIGHT 0x00050011
87 #define ASUS_WMI_DEVID_BRIGHTNESS 0x00050012
90 #define ASUS_WMI_DEVID_CAMERA 0x00060013
93 #define ASUS_WMI_DEVID_CARDREADER 0x00080013
96 #define ASUS_WMI_DEVID_TOUCHPAD 0x00100011
97 #define ASUS_WMI_DEVID_TOUCHPAD_LED 0x00100012
100 #define ASUS_WMI_DSTS_STATUS_BIT 0x00000001
101 #define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002
102 #define ASUS_WMI_DSTS_PRESENCE_BIT 0x00010000
103 #define ASUS_WMI_DSTS_BRIGHTNESS_MASK 0x000000FF
104 #define ASUS_WMI_DSTS_MAX_BRIGTH_MASK 0x0000FF00
112 * <platform>/ - debugfs root directory
113 * dev_id - current dev_id
114 * ctrl_param - current ctrl_param
115 * method_id - current method_id
116 * devs - call DEVS(dev_id, ctrl_param) and print result
117 * dsts - call DSTS(dev_id) and print result
118 * call - call method_id(dev_id, ctrl_param) and print result
120 struct asus_wmi_debug {
128 struct asus_wmi *asus;
129 struct rfkill *rfkill;
138 struct input_dev *inputdev;
139 struct backlight_device *backlight_device;
140 struct platform_device *platform_device;
142 struct led_classdev tpd_led;
144 struct workqueue_struct *led_workqueue;
145 struct work_struct tpd_led_work;
147 struct asus_rfkill wlan;
148 struct asus_rfkill bluetooth;
149 struct asus_rfkill wimax;
150 struct asus_rfkill wwan3g;
152 struct hotplug_slot *hotplug_slot;
153 struct mutex hotplug_lock;
154 struct mutex wmi_lock;
155 struct workqueue_struct *hotplug_workqueue;
156 struct work_struct hotplug_work;
158 struct asus_wmi_debug debug;
160 struct asus_wmi_driver *driver;
163 static int asus_wmi_input_init(struct asus_wmi *asus)
167 asus->inputdev = input_allocate_device();
171 asus->inputdev->name = asus->driver->input_phys;
172 asus->inputdev->phys = asus->driver->input_name;
173 asus->inputdev->id.bustype = BUS_HOST;
174 asus->inputdev->dev.parent = &asus->platform_device->dev;
176 err = sparse_keymap_setup(asus->inputdev, asus->driver->keymap, NULL);
180 err = input_register_device(asus->inputdev);
182 goto err_free_keymap;
187 sparse_keymap_free(asus->inputdev);
189 input_free_device(asus->inputdev);
193 static void asus_wmi_input_exit(struct asus_wmi *asus)
195 if (asus->inputdev) {
196 sparse_keymap_free(asus->inputdev);
197 input_unregister_device(asus->inputdev);
200 asus->inputdev = NULL;
203 static int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
206 struct bios_args args = {
210 struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
211 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
213 union acpi_object *obj;
216 status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 1, method_id,
219 if (ACPI_FAILURE(status))
222 obj = (union acpi_object *)output.pointer;
223 if (obj && obj->type == ACPI_TYPE_INTEGER)
224 tmp = (u32) obj->integer.value;
234 if (ACPI_FAILURE(status))
237 if (tmp == ASUS_WMI_UNSUPPORTED_METHOD)
243 static int asus_wmi_get_devstate(struct asus_wmi *asus, u32 dev_id, u32 *retval)
245 return asus_wmi_evaluate_method(asus->dsts_id, dev_id, 0, retval);
248 static int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
251 return asus_wmi_evaluate_method(ASUS_WMI_METHODID_DEVS, dev_id,
255 /* Helper for special devices with magic return codes */
256 static int asus_wmi_get_devstate_bits(struct asus_wmi *asus,
257 u32 dev_id, u32 mask)
262 err = asus_wmi_get_devstate(asus, dev_id, &retval);
267 if (!(retval & ASUS_WMI_DSTS_PRESENCE_BIT))
270 if (mask == ASUS_WMI_DSTS_STATUS_BIT) {
271 if (retval & ASUS_WMI_DSTS_UNKNOWN_BIT)
275 return retval & mask;
278 static int asus_wmi_get_devstate_simple(struct asus_wmi *asus, u32 dev_id)
280 return asus_wmi_get_devstate_bits(asus, dev_id,
281 ASUS_WMI_DSTS_STATUS_BIT);
288 * These functions actually update the LED's, and are called from a
289 * workqueue. By doing this as separate work rather than when the LED
290 * subsystem asks, we avoid messing with the Asus ACPI stuff during a
291 * potentially bad time, such as a timer interrupt.
293 static void tpd_led_update(struct work_struct *work)
296 struct asus_wmi *asus;
298 asus = container_of(work, struct asus_wmi, tpd_led_work);
300 ctrl_param = asus->tpd_led_wk;
301 asus_wmi_set_devstate(ASUS_WMI_DEVID_TOUCHPAD_LED, ctrl_param, NULL);
304 static void tpd_led_set(struct led_classdev *led_cdev,
305 enum led_brightness value)
307 struct asus_wmi *asus;
309 asus = container_of(led_cdev, struct asus_wmi, tpd_led);
311 asus->tpd_led_wk = !!value;
312 queue_work(asus->led_workqueue, &asus->tpd_led_work);
315 static int read_tpd_led_state(struct asus_wmi *asus)
317 return asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_TOUCHPAD_LED);
320 static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
322 struct asus_wmi *asus;
324 asus = container_of(led_cdev, struct asus_wmi, tpd_led);
326 return read_tpd_led_state(asus);
329 static int asus_wmi_led_init(struct asus_wmi *asus)
333 if (read_tpd_led_state(asus) < 0)
336 asus->led_workqueue = create_singlethread_workqueue("led_workqueue");
337 if (!asus->led_workqueue)
339 INIT_WORK(&asus->tpd_led_work, tpd_led_update);
341 asus->tpd_led.name = "asus::touchpad";
342 asus->tpd_led.brightness_set = tpd_led_set;
343 asus->tpd_led.brightness_get = tpd_led_get;
344 asus->tpd_led.max_brightness = 1;
346 rv = led_classdev_register(&asus->platform_device->dev, &asus->tpd_led);
348 destroy_workqueue(asus->led_workqueue);
355 static void asus_wmi_led_exit(struct asus_wmi *asus)
357 if (asus->tpd_led.dev)
358 led_classdev_unregister(&asus->tpd_led);
359 if (asus->led_workqueue)
360 destroy_workqueue(asus->led_workqueue);
364 * PCI hotplug (for wlan rfkill)
366 static bool asus_wlan_rfkill_blocked(struct asus_wmi *asus)
368 int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
375 static void asus_rfkill_hotplug(struct asus_wmi *asus)
383 mutex_lock(&asus->wmi_lock);
384 blocked = asus_wlan_rfkill_blocked(asus);
385 mutex_unlock(&asus->wmi_lock);
387 mutex_lock(&asus->hotplug_lock);
389 if (asus->wlan.rfkill)
390 rfkill_set_sw_state(asus->wlan.rfkill, blocked);
392 if (asus->hotplug_slot) {
393 bus = pci_find_bus(0, 1);
395 pr_warning("Unable to find PCI bus 1?\n");
399 if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
400 pr_err("Unable to read PCI config space?\n");
403 absent = (l == 0xffffffff);
405 if (blocked != absent) {
406 pr_warning("BIOS says wireless lan is %s, "
407 "but the pci device is %s\n",
408 blocked ? "blocked" : "unblocked",
409 absent ? "absent" : "present");
410 pr_warning("skipped wireless hotplug as probably "
411 "inappropriate for this model\n");
416 dev = pci_get_slot(bus, 0);
418 /* Device already present */
422 dev = pci_scan_single_device(bus, 0);
424 pci_bus_assign_resources(bus);
425 if (pci_bus_add_device(dev))
426 pr_err("Unable to hotplug wifi\n");
429 dev = pci_get_slot(bus, 0);
431 pci_remove_bus_device(dev);
438 mutex_unlock(&asus->hotplug_lock);
441 static void asus_rfkill_notify(acpi_handle handle, u32 event, void *data)
443 struct asus_wmi *asus = data;
445 if (event != ACPI_NOTIFY_BUS_CHECK)
449 * We can't call directly asus_rfkill_hotplug because most
450 * of the time WMBC is still being executed and not reetrant.
451 * There is currently no way to tell ACPICA that we want this
452 * method to be serialized, we schedule a asus_rfkill_hotplug
453 * call later, in a safer context.
455 queue_work(asus->hotplug_workqueue, &asus->hotplug_work);
458 static int asus_register_rfkill_notifier(struct asus_wmi *asus, char *node)
463 status = acpi_get_handle(NULL, node, &handle);
465 if (ACPI_SUCCESS(status)) {
466 status = acpi_install_notify_handler(handle,
468 asus_rfkill_notify, asus);
469 if (ACPI_FAILURE(status))
470 pr_warning("Failed to register notify on %s\n", node);
477 static void asus_unregister_rfkill_notifier(struct asus_wmi *asus, char *node)
479 acpi_status status = AE_OK;
482 status = acpi_get_handle(NULL, node, &handle);
484 if (ACPI_SUCCESS(status)) {
485 status = acpi_remove_notify_handler(handle,
488 if (ACPI_FAILURE(status))
489 pr_err("Error removing rfkill notify handler %s\n",
494 static int asus_get_adapter_status(struct hotplug_slot *hotplug_slot,
497 struct asus_wmi *asus = hotplug_slot->private;
498 int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
507 static void asus_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
509 kfree(hotplug_slot->info);
513 static struct hotplug_slot_ops asus_hotplug_slot_ops = {
514 .owner = THIS_MODULE,
515 .get_adapter_status = asus_get_adapter_status,
516 .get_power_status = asus_get_adapter_status,
519 static void asus_hotplug_work(struct work_struct *work)
521 struct asus_wmi *asus;
523 asus = container_of(work, struct asus_wmi, hotplug_work);
524 asus_rfkill_hotplug(asus);
527 static int asus_setup_pci_hotplug(struct asus_wmi *asus)
530 struct pci_bus *bus = pci_find_bus(0, 1);
533 pr_err("Unable to find wifi PCI bus\n");
537 asus->hotplug_workqueue =
538 create_singlethread_workqueue("hotplug_workqueue");
539 if (!asus->hotplug_workqueue)
540 goto error_workqueue;
542 INIT_WORK(&asus->hotplug_work, asus_hotplug_work);
544 asus->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
545 if (!asus->hotplug_slot)
548 asus->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
550 if (!asus->hotplug_slot->info)
553 asus->hotplug_slot->private = asus;
554 asus->hotplug_slot->release = &asus_cleanup_pci_hotplug;
555 asus->hotplug_slot->ops = &asus_hotplug_slot_ops;
556 asus_get_adapter_status(asus->hotplug_slot,
557 &asus->hotplug_slot->info->adapter_status);
559 ret = pci_hp_register(asus->hotplug_slot, bus, 0, "asus-wifi");
561 pr_err("Unable to register hotplug slot - %d\n", ret);
568 kfree(asus->hotplug_slot->info);
570 kfree(asus->hotplug_slot);
571 asus->hotplug_slot = NULL;
573 destroy_workqueue(asus->hotplug_workqueue);
581 static int asus_rfkill_set(void *data, bool blocked)
583 struct asus_rfkill *priv = data;
584 u32 ctrl_param = !blocked;
586 return asus_wmi_set_devstate(priv->dev_id, ctrl_param, NULL);
589 static void asus_rfkill_query(struct rfkill *rfkill, void *data)
591 struct asus_rfkill *priv = data;
594 result = asus_wmi_get_devstate_simple(priv->asus, priv->dev_id);
599 rfkill_set_sw_state(priv->rfkill, !result);
602 static int asus_rfkill_wlan_set(void *data, bool blocked)
604 struct asus_rfkill *priv = data;
605 struct asus_wmi *asus = priv->asus;
609 * This handler is enabled only if hotplug is enabled.
610 * In this case, the asus_wmi_set_devstate() will
611 * trigger a wmi notification and we need to wait
612 * this call to finish before being able to call
615 mutex_lock(&asus->wmi_lock);
616 ret = asus_rfkill_set(data, blocked);
617 mutex_unlock(&asus->wmi_lock);
621 static const struct rfkill_ops asus_rfkill_wlan_ops = {
622 .set_block = asus_rfkill_wlan_set,
623 .query = asus_rfkill_query,
626 static const struct rfkill_ops asus_rfkill_ops = {
627 .set_block = asus_rfkill_set,
628 .query = asus_rfkill_query,
631 static int asus_new_rfkill(struct asus_wmi *asus,
632 struct asus_rfkill *arfkill,
633 const char *name, enum rfkill_type type, int dev_id)
635 int result = asus_wmi_get_devstate_simple(asus, dev_id);
636 struct rfkill **rfkill = &arfkill->rfkill;
641 arfkill->dev_id = dev_id;
642 arfkill->asus = asus;
644 if (dev_id == ASUS_WMI_DEVID_WLAN && asus->driver->hotplug_wireless)
645 *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type,
646 &asus_rfkill_wlan_ops, arfkill);
648 *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type,
649 &asus_rfkill_ops, arfkill);
654 rfkill_init_sw_state(*rfkill, !result);
655 result = rfkill_register(*rfkill);
657 rfkill_destroy(*rfkill);
664 static void asus_wmi_rfkill_exit(struct asus_wmi *asus)
666 asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P5");
667 asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P6");
668 asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P7");
669 if (asus->wlan.rfkill) {
670 rfkill_unregister(asus->wlan.rfkill);
671 rfkill_destroy(asus->wlan.rfkill);
672 asus->wlan.rfkill = NULL;
675 * Refresh pci hotplug in case the rfkill state was changed after
676 * asus_unregister_rfkill_notifier()
678 asus_rfkill_hotplug(asus);
679 if (asus->hotplug_slot)
680 pci_hp_deregister(asus->hotplug_slot);
681 if (asus->hotplug_workqueue)
682 destroy_workqueue(asus->hotplug_workqueue);
684 if (asus->bluetooth.rfkill) {
685 rfkill_unregister(asus->bluetooth.rfkill);
686 rfkill_destroy(asus->bluetooth.rfkill);
687 asus->bluetooth.rfkill = NULL;
689 if (asus->wimax.rfkill) {
690 rfkill_unregister(asus->wimax.rfkill);
691 rfkill_destroy(asus->wimax.rfkill);
692 asus->wimax.rfkill = NULL;
694 if (asus->wwan3g.rfkill) {
695 rfkill_unregister(asus->wwan3g.rfkill);
696 rfkill_destroy(asus->wwan3g.rfkill);
697 asus->wwan3g.rfkill = NULL;
701 static int asus_wmi_rfkill_init(struct asus_wmi *asus)
705 mutex_init(&asus->hotplug_lock);
706 mutex_init(&asus->wmi_lock);
708 result = asus_new_rfkill(asus, &asus->wlan, "asus-wlan",
709 RFKILL_TYPE_WLAN, ASUS_WMI_DEVID_WLAN);
711 if (result && result != -ENODEV)
714 result = asus_new_rfkill(asus, &asus->bluetooth,
715 "asus-bluetooth", RFKILL_TYPE_BLUETOOTH,
716 ASUS_WMI_DEVID_BLUETOOTH);
718 if (result && result != -ENODEV)
721 result = asus_new_rfkill(asus, &asus->wimax, "asus-wimax",
722 RFKILL_TYPE_WIMAX, ASUS_WMI_DEVID_WIMAX);
724 if (result && result != -ENODEV)
727 result = asus_new_rfkill(asus, &asus->wwan3g, "asus-wwan3g",
728 RFKILL_TYPE_WWAN, ASUS_WMI_DEVID_WWAN3G);
730 if (result && result != -ENODEV)
733 if (!asus->driver->hotplug_wireless)
736 result = asus_setup_pci_hotplug(asus);
738 * If we get -EBUSY then something else is handling the PCI hotplug -
739 * don't fail in this case
741 if (result == -EBUSY)
744 asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P5");
745 asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P6");
746 asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P7");
748 * Refresh pci hotplug in case the rfkill state was changed during
751 asus_rfkill_hotplug(asus);
754 if (result && result != -ENODEV)
755 asus_wmi_rfkill_exit(asus);
757 if (result == -ENODEV)
766 static int read_backlight_power(struct asus_wmi *asus)
768 int ret = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_BACKLIGHT);
773 return ret ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
776 static int read_brightness_max(struct asus_wmi *asus)
781 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval);
786 retval = retval & ASUS_WMI_DSTS_MAX_BRIGTH_MASK;
795 static int read_brightness(struct backlight_device *bd)
797 struct asus_wmi *asus = bl_get_data(bd);
800 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval);
805 return retval & ASUS_WMI_DSTS_BRIGHTNESS_MASK;
808 static int update_bl_status(struct backlight_device *bd)
810 struct asus_wmi *asus = bl_get_data(bd);
814 ctrl_param = bd->props.brightness;
816 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BRIGHTNESS,
822 power = read_backlight_power(asus);
823 if (power != -ENODEV && bd->props.power != power) {
824 ctrl_param = !!(bd->props.power == FB_BLANK_UNBLANK);
825 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BACKLIGHT,
831 static const struct backlight_ops asus_wmi_bl_ops = {
832 .get_brightness = read_brightness,
833 .update_status = update_bl_status,
836 static int asus_wmi_backlight_notify(struct asus_wmi *asus, int code)
838 struct backlight_device *bd = asus->backlight_device;
839 int old = bd->props.brightness;
842 if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
843 new = code - NOTIFY_BRNUP_MIN + 1;
844 else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
845 new = code - NOTIFY_BRNDOWN_MIN;
847 bd->props.brightness = new;
848 backlight_update_status(bd);
849 backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
854 static int asus_wmi_backlight_init(struct asus_wmi *asus)
856 struct backlight_device *bd;
857 struct backlight_properties props;
861 max = read_brightness_max(asus);
868 power = read_backlight_power(asus);
870 if (power == -ENODEV)
871 power = FB_BLANK_UNBLANK;
875 memset(&props, 0, sizeof(struct backlight_properties));
876 props.max_brightness = max;
877 bd = backlight_device_register(asus->driver->name,
878 &asus->platform_device->dev, asus,
879 &asus_wmi_bl_ops, &props);
881 pr_err("Could not register backlight device\n");
885 asus->backlight_device = bd;
887 bd->props.brightness = read_brightness(bd);
888 bd->props.power = power;
889 backlight_update_status(bd);
894 static void asus_wmi_backlight_exit(struct asus_wmi *asus)
896 if (asus->backlight_device)
897 backlight_device_unregister(asus->backlight_device);
899 asus->backlight_device = NULL;
902 static void asus_wmi_notify(u32 value, void *context)
904 struct asus_wmi *asus = context;
905 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
906 union acpi_object *obj;
911 status = wmi_get_event_data(value, &response);
912 if (status != AE_OK) {
913 pr_err("bad event status 0x%x\n", status);
917 obj = (union acpi_object *)response.pointer;
919 if (!obj || obj->type != ACPI_TYPE_INTEGER)
922 code = obj->integer.value;
925 if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
926 code = NOTIFY_BRNUP_MIN;
927 else if (code >= NOTIFY_BRNDOWN_MIN &&
928 code <= NOTIFY_BRNDOWN_MAX)
929 code = NOTIFY_BRNDOWN_MIN;
931 if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) {
932 if (!acpi_video_backlight_support())
933 asus_wmi_backlight_notify(asus, orig_code);
934 } else if (!sparse_keymap_report_event(asus->inputdev, code, 1, true))
935 pr_info("Unknown key %x pressed\n", code);
944 static int parse_arg(const char *buf, unsigned long count, int *val)
948 if (sscanf(buf, "%i", val) != 1)
953 static ssize_t store_sys_wmi(struct asus_wmi *asus, int devid,
954 const char *buf, size_t count)
959 value = asus_wmi_get_devstate_simple(asus, devid);
960 if (value == -ENODEV) /* Check device presence */
963 rv = parse_arg(buf, count, &value);
964 err = asus_wmi_set_devstate(devid, value, &retval);
972 static ssize_t show_sys_wmi(struct asus_wmi *asus, int devid, char *buf)
974 int value = asus_wmi_get_devstate_simple(asus, devid);
979 return sprintf(buf, "%d\n", value);
982 #define ASUS_WMI_CREATE_DEVICE_ATTR(_name, _mode, _cm) \
983 static ssize_t show_##_name(struct device *dev, \
984 struct device_attribute *attr, \
987 struct asus_wmi *asus = dev_get_drvdata(dev); \
989 return show_sys_wmi(asus, _cm, buf); \
991 static ssize_t store_##_name(struct device *dev, \
992 struct device_attribute *attr, \
993 const char *buf, size_t count) \
995 struct asus_wmi *asus = dev_get_drvdata(dev); \
997 return store_sys_wmi(asus, _cm, buf, count); \
999 static struct device_attribute dev_attr_##_name = { \
1001 .name = __stringify(_name), \
1003 .show = show_##_name, \
1004 .store = store_##_name, \
1007 ASUS_WMI_CREATE_DEVICE_ATTR(touchpad, 0644, ASUS_WMI_DEVID_TOUCHPAD);
1008 ASUS_WMI_CREATE_DEVICE_ATTR(camera, 0644, ASUS_WMI_DEVID_CAMERA);
1009 ASUS_WMI_CREATE_DEVICE_ATTR(cardr, 0644, ASUS_WMI_DEVID_CARDREADER);
1011 static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr,
1012 const char *buf, size_t count)
1016 if (!count || sscanf(buf, "%i", &value) != 1)
1018 if (value < 0 || value > 2)
1021 return asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL);
1024 static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv);
1026 static struct attribute *platform_attributes[] = {
1027 &dev_attr_cpufv.attr,
1028 &dev_attr_camera.attr,
1029 &dev_attr_cardr.attr,
1030 &dev_attr_touchpad.attr,
1034 static mode_t asus_sysfs_is_visible(struct kobject *kobj,
1035 struct attribute *attr, int idx)
1037 struct device *dev = container_of(kobj, struct device, kobj);
1038 struct platform_device *pdev = to_platform_device(dev);
1039 struct asus_wmi *asus = platform_get_drvdata(pdev);
1043 if (attr == &dev_attr_camera.attr)
1044 devid = ASUS_WMI_DEVID_CAMERA;
1045 else if (attr == &dev_attr_cardr.attr)
1046 devid = ASUS_WMI_DEVID_CARDREADER;
1047 else if (attr == &dev_attr_touchpad.attr)
1048 devid = ASUS_WMI_DEVID_TOUCHPAD;
1051 ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0);
1053 return ok ? attr->mode : 0;
1056 static struct attribute_group platform_attribute_group = {
1057 .is_visible = asus_sysfs_is_visible,
1058 .attrs = platform_attributes
1061 static void asus_wmi_sysfs_exit(struct platform_device *device)
1063 sysfs_remove_group(&device->dev.kobj, &platform_attribute_group);
1066 static int asus_wmi_sysfs_init(struct platform_device *device)
1068 return sysfs_create_group(&device->dev.kobj, &platform_attribute_group);
1074 static int __init asus_wmi_platform_init(struct asus_wmi *asus)
1078 /* INIT enable hotkeys on some models */
1079 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_INIT, 0, 0, &rv))
1080 pr_info("Initialization: %#x", rv);
1082 /* We don't know yet what to do with this version... */
1083 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SPEC, 0, 0x9, &rv)) {
1084 pr_info("BIOS WMI version: %d.%d", rv >> 8, rv & 0xFF);
1089 * The SFUN method probably allows the original driver to get the list
1090 * of features supported by a given model. For now, 0x0100 or 0x0800
1091 * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card.
1092 * The significance of others is yet to be found.
1094 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SFUN, 0, 0, &rv)) {
1095 pr_info("SFUN value: %#x", rv);
1100 * Eee PC and Notebooks seems to have different method_id for DSTS,
1101 * but it may also be related to the BIOS's SPEC.
1102 * Note, on most Eeepc, there is no way to check if a method exist
1103 * or note, while on notebooks, they returns 0xFFFFFFFE on failure,
1104 * but once again, SPEC may probably be used for that kind of things.
1106 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, 0, 0, NULL))
1107 asus->dsts_id = ASUS_WMI_METHODID_DSTS;
1108 else if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS2, 0, 0, NULL))
1109 asus->dsts_id = ASUS_WMI_METHODID_DSTS2;
1111 if (!asus->dsts_id) {
1112 pr_err("Can't find DSTS");
1116 return asus_wmi_sysfs_init(asus->platform_device);
1119 static void asus_wmi_platform_exit(struct asus_wmi *asus)
1121 asus_wmi_sysfs_exit(asus->platform_device);
1127 struct asus_wmi_debugfs_node {
1128 struct asus_wmi *asus;
1130 int (*show) (struct seq_file *m, void *data);
1133 static int show_dsts(struct seq_file *m, void *data)
1135 struct asus_wmi *asus = m->private;
1139 err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
1144 seq_printf(m, "DSTS(%#x) = %#x\n", asus->debug.dev_id, retval);
1149 static int show_devs(struct seq_file *m, void *data)
1151 struct asus_wmi *asus = m->private;
1155 err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
1161 seq_printf(m, "DEVS(%#x, %#x) = %#x\n", asus->debug.dev_id,
1162 asus->debug.ctrl_param, retval);
1167 static int show_call(struct seq_file *m, void *data)
1169 struct asus_wmi *asus = m->private;
1170 struct bios_args args = {
1171 .arg0 = asus->debug.dev_id,
1172 .arg1 = asus->debug.ctrl_param,
1174 struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
1175 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
1176 union acpi_object *obj;
1179 status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
1180 1, asus->debug.method_id,
1183 if (ACPI_FAILURE(status))
1186 obj = (union acpi_object *)output.pointer;
1187 if (obj && obj->type == ACPI_TYPE_INTEGER)
1188 seq_printf(m, "%#x(%#x, %#x) = %#x\n", asus->debug.method_id,
1189 asus->debug.dev_id, asus->debug.ctrl_param,
1190 (u32) obj->integer.value);
1192 seq_printf(m, "%#x(%#x, %#x) = t:%d\n", asus->debug.method_id,
1193 asus->debug.dev_id, asus->debug.ctrl_param,
1201 static struct asus_wmi_debugfs_node asus_wmi_debug_files[] = {
1202 {NULL, "devs", show_devs},
1203 {NULL, "dsts", show_dsts},
1204 {NULL, "call", show_call},
1207 static int asus_wmi_debugfs_open(struct inode *inode, struct file *file)
1209 struct asus_wmi_debugfs_node *node = inode->i_private;
1211 return single_open(file, node->show, node->asus);
1214 static const struct file_operations asus_wmi_debugfs_io_ops = {
1215 .owner = THIS_MODULE,
1216 .open = asus_wmi_debugfs_open,
1218 .llseek = seq_lseek,
1219 .release = single_release,
1222 static void asus_wmi_debugfs_exit(struct asus_wmi *asus)
1224 debugfs_remove_recursive(asus->debug.root);
1227 static int asus_wmi_debugfs_init(struct asus_wmi *asus)
1229 struct dentry *dent;
1232 asus->debug.root = debugfs_create_dir(asus->driver->name, NULL);
1233 if (!asus->debug.root) {
1234 pr_err("failed to create debugfs directory");
1238 dent = debugfs_create_x32("method_id", S_IRUGO | S_IWUSR,
1239 asus->debug.root, &asus->debug.method_id);
1243 dent = debugfs_create_x32("dev_id", S_IRUGO | S_IWUSR,
1244 asus->debug.root, &asus->debug.dev_id);
1248 dent = debugfs_create_x32("ctrl_param", S_IRUGO | S_IWUSR,
1249 asus->debug.root, &asus->debug.ctrl_param);
1253 for (i = 0; i < ARRAY_SIZE(asus_wmi_debug_files); i++) {
1254 struct asus_wmi_debugfs_node *node = &asus_wmi_debug_files[i];
1257 dent = debugfs_create_file(node->name, S_IFREG | S_IRUGO,
1258 asus->debug.root, node,
1259 &asus_wmi_debugfs_io_ops);
1261 pr_err("failed to create debug file: %s\n", node->name);
1269 asus_wmi_debugfs_exit(asus);
1276 static int asus_wmi_add(struct platform_device *pdev)
1278 struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
1279 struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv);
1280 struct asus_wmi *asus;
1284 asus = kzalloc(sizeof(struct asus_wmi), GFP_KERNEL);
1288 asus->driver = wdrv;
1289 asus->platform_device = pdev;
1290 wdrv->platform_device = pdev;
1291 platform_set_drvdata(asus->platform_device, asus);
1294 wdrv->quirks(asus->driver);
1296 err = asus_wmi_platform_init(asus);
1300 err = asus_wmi_input_init(asus);
1304 err = asus_wmi_led_init(asus);
1308 err = asus_wmi_rfkill_init(asus);
1312 if (!acpi_video_backlight_support()) {
1313 err = asus_wmi_backlight_init(asus);
1314 if (err && err != -ENODEV)
1315 goto fail_backlight;
1317 pr_info("Backlight controlled by ACPI video driver\n");
1319 status = wmi_install_notify_handler(asus->driver->event_guid,
1320 asus_wmi_notify, asus);
1321 if (ACPI_FAILURE(status)) {
1322 pr_err("Unable to register notify handler - %d\n", status);
1324 goto fail_wmi_handler;
1327 err = asus_wmi_debugfs_init(asus);
1334 wmi_remove_notify_handler(asus->driver->event_guid);
1336 asus_wmi_backlight_exit(asus);
1338 asus_wmi_rfkill_exit(asus);
1340 asus_wmi_led_exit(asus);
1342 asus_wmi_input_exit(asus);
1344 asus_wmi_platform_exit(asus);
1350 static int asus_wmi_remove(struct platform_device *device)
1352 struct asus_wmi *asus;
1354 asus = platform_get_drvdata(device);
1355 wmi_remove_notify_handler(asus->driver->event_guid);
1356 asus_wmi_backlight_exit(asus);
1357 asus_wmi_input_exit(asus);
1358 asus_wmi_led_exit(asus);
1359 asus_wmi_rfkill_exit(asus);
1360 asus_wmi_debugfs_exit(asus);
1361 asus_wmi_platform_exit(asus);
1368 * Platform driver - hibernate/resume callbacks
1370 static int asus_hotk_thaw(struct device *device)
1372 struct asus_wmi *asus = dev_get_drvdata(device);
1374 if (asus->wlan.rfkill) {
1378 * Work around bios bug - acpi _PTS turns off the wireless led
1379 * during suspend. Normally it restores it on resume, but
1380 * we should kick it ourselves in case hibernation is aborted.
1382 wlan = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
1383 asus_wmi_set_devstate(ASUS_WMI_DEVID_WLAN, wlan, NULL);
1389 static int asus_hotk_restore(struct device *device)
1391 struct asus_wmi *asus = dev_get_drvdata(device);
1394 /* Refresh both wlan rfkill state and pci hotplug */
1395 if (asus->wlan.rfkill)
1396 asus_rfkill_hotplug(asus);
1398 if (asus->bluetooth.rfkill) {
1399 bl = !asus_wmi_get_devstate_simple(asus,
1400 ASUS_WMI_DEVID_BLUETOOTH);
1401 rfkill_set_sw_state(asus->bluetooth.rfkill, bl);
1403 if (asus->wimax.rfkill) {
1404 bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WIMAX);
1405 rfkill_set_sw_state(asus->wimax.rfkill, bl);
1407 if (asus->wwan3g.rfkill) {
1408 bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WWAN3G);
1409 rfkill_set_sw_state(asus->wwan3g.rfkill, bl);
1415 static const struct dev_pm_ops asus_pm_ops = {
1416 .thaw = asus_hotk_thaw,
1417 .restore = asus_hotk_restore,
1420 static int asus_wmi_probe(struct platform_device *pdev)
1422 struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
1423 struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv);
1426 if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
1427 pr_warning("Management GUID not found\n");
1431 if (wdrv->event_guid && !wmi_has_guid(wdrv->event_guid)) {
1432 pr_warning("Event GUID not found\n");
1437 ret = wdrv->probe(pdev);
1442 return asus_wmi_add(pdev);
1447 int asus_wmi_register_driver(struct asus_wmi_driver *driver)
1449 struct platform_driver *platform_driver;
1450 struct platform_device *platform_device;
1455 platform_driver = &driver->platform_driver;
1456 platform_driver->remove = asus_wmi_remove;
1457 platform_driver->driver.owner = driver->owner;
1458 platform_driver->driver.name = driver->name;
1459 platform_driver->driver.pm = &asus_pm_ops;
1461 platform_device = platform_create_bundle(platform_driver,
1464 if (IS_ERR(platform_device))
1465 return PTR_ERR(platform_device);
1470 EXPORT_SYMBOL_GPL(asus_wmi_register_driver);
1472 void asus_wmi_unregister_driver(struct asus_wmi_driver *driver)
1474 platform_device_unregister(driver->platform_device);
1475 platform_driver_unregister(&driver->platform_driver);
1478 EXPORT_SYMBOL_GPL(asus_wmi_unregister_driver);
1480 static int __init asus_wmi_init(void)
1482 if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
1483 pr_info("Asus Management GUID not found");
1487 pr_info("ASUS WMI generic driver loaded");
1491 static void __exit asus_wmi_exit(void)
1493 pr_info("ASUS WMI generic driver unloaded");
1496 module_init(asus_wmi_init);
1497 module_exit(asus_wmi_exit);