2 * Eee PC WMI hotkey driver
4 * Copyright(C) 2010 Intel Corporation.
6 * Portions based on wistron_btns.c:
7 * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
8 * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
9 * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
28 #include <linux/kernel.h>
29 #include <linux/module.h>
30 #include <linux/init.h>
31 #include <linux/types.h>
32 #include <linux/slab.h>
33 #include <linux/input.h>
34 #include <linux/input/sparse-keymap.h>
36 #include <linux/backlight.h>
37 #include <linux/leds.h>
38 #include <linux/rfkill.h>
39 #include <linux/debugfs.h>
40 #include <linux/seq_file.h>
41 #include <linux/platform_device.h>
42 #include <acpi/acpi_bus.h>
43 #include <acpi/acpi_drivers.h>
45 #define EEEPC_WMI_FILE "eeepc-wmi"
47 MODULE_AUTHOR("Yong Wang <yong.y.wang@intel.com>");
48 MODULE_DESCRIPTION("Eee PC WMI Hotkey Driver");
49 MODULE_LICENSE("GPL");
51 #define EEEPC_WMI_EVENT_GUID "ABBC0F72-8EA1-11D1-00A0-C90629100000"
52 #define EEEPC_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66"
54 MODULE_ALIAS("wmi:"EEEPC_WMI_EVENT_GUID
);
55 MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID
);
57 #define NOTIFY_BRNUP_MIN 0x11
58 #define NOTIFY_BRNUP_MAX 0x1f
59 #define NOTIFY_BRNDOWN_MIN 0x20
60 #define NOTIFY_BRNDOWN_MAX 0x2e
62 #define EEEPC_WMI_METHODID_DEVS 0x53564544
63 #define EEEPC_WMI_METHODID_DSTS 0x53544344
64 #define EEEPC_WMI_METHODID_CFVS 0x53564643
66 #define EEEPC_WMI_DEVID_BACKLIGHT 0x00050012
67 #define EEEPC_WMI_DEVID_TPDLED 0x00100011
68 #define EEEPC_WMI_DEVID_WLAN 0x00010011
69 #define EEEPC_WMI_DEVID_BLUETOOTH 0x00010013
70 #define EEEPC_WMI_DEVID_WWAN3G 0x00010019
72 static const struct key_entry eeepc_wmi_keymap
[] = {
73 /* Sleep already handled via generic ACPI code */
74 { KE_KEY
, 0x5d, { KEY_WLAN
} },
75 { KE_KEY
, 0x32, { KEY_MUTE
} },
76 { KE_KEY
, 0x31, { KEY_VOLUMEDOWN
} },
77 { KE_KEY
, 0x30, { KEY_VOLUMEUP
} },
78 { KE_IGNORE
, NOTIFY_BRNDOWN_MIN
, { KEY_BRIGHTNESSDOWN
} },
79 { KE_IGNORE
, NOTIFY_BRNUP_MIN
, { KEY_BRIGHTNESSUP
} },
80 { KE_KEY
, 0xcc, { KEY_SWITCHVIDEOMODE
} },
81 { KE_KEY
, 0x6b, { KEY_F13
} }, /* Disable Touchpad */
82 { KE_KEY
, 0xe1, { KEY_F14
} },
83 { KE_KEY
, 0xe9, { KEY_DISPLAY_OFF
} },
84 { KE_KEY
, 0xe0, { KEY_PROG1
} },
85 { KE_KEY
, 0x5c, { KEY_F15
} },
95 * eeepc-wmi/ - debugfs root directory
96 * dev_id - current dev_id
97 * ctrl_param - current ctrl_param
98 * devs - call DEVS(dev_id, ctrl_param) and print result
99 * dsts - call DSTS(dev_id) and print result
101 struct eeepc_wmi_debug
{
108 struct input_dev
*inputdev
;
109 struct backlight_device
*backlight_device
;
110 struct platform_device
*platform_device
;
112 struct led_classdev tpd_led
;
114 struct workqueue_struct
*led_workqueue
;
115 struct work_struct tpd_led_work
;
117 struct rfkill
*wlan_rfkill
;
118 struct rfkill
*bluetooth_rfkill
;
119 struct rfkill
*wwan3g_rfkill
;
121 struct eeepc_wmi_debug debug
;
124 /* Only used in eeepc_wmi_init() and eeepc_wmi_exit() */
125 static struct platform_device
*platform_device
;
127 static int eeepc_wmi_input_init(struct eeepc_wmi
*eeepc
)
131 eeepc
->inputdev
= input_allocate_device();
132 if (!eeepc
->inputdev
)
135 eeepc
->inputdev
->name
= "Eee PC WMI hotkeys";
136 eeepc
->inputdev
->phys
= EEEPC_WMI_FILE
"/input0";
137 eeepc
->inputdev
->id
.bustype
= BUS_HOST
;
138 eeepc
->inputdev
->dev
.parent
= &eeepc
->platform_device
->dev
;
140 err
= sparse_keymap_setup(eeepc
->inputdev
, eeepc_wmi_keymap
, NULL
);
144 err
= input_register_device(eeepc
->inputdev
);
146 goto err_free_keymap
;
151 sparse_keymap_free(eeepc
->inputdev
);
153 input_free_device(eeepc
->inputdev
);
157 static void eeepc_wmi_input_exit(struct eeepc_wmi
*eeepc
)
159 if (eeepc
->inputdev
) {
160 sparse_keymap_free(eeepc
->inputdev
);
161 input_unregister_device(eeepc
->inputdev
);
164 eeepc
->inputdev
= NULL
;
167 static acpi_status
eeepc_wmi_get_devstate(u32 dev_id
, u32
*ctrl_param
)
169 struct acpi_buffer input
= { (acpi_size
)sizeof(u32
), &dev_id
};
170 struct acpi_buffer output
= { ACPI_ALLOCATE_BUFFER
, NULL
};
171 union acpi_object
*obj
;
175 status
= wmi_evaluate_method(EEEPC_WMI_MGMT_GUID
,
176 1, EEEPC_WMI_METHODID_DSTS
, &input
, &output
);
178 if (ACPI_FAILURE(status
))
181 obj
= (union acpi_object
*)output
.pointer
;
182 if (obj
&& obj
->type
== ACPI_TYPE_INTEGER
)
183 tmp
= (u32
)obj
->integer
.value
;
196 static acpi_status
eeepc_wmi_set_devstate(u32 dev_id
, u32 ctrl_param
,
199 struct bios_args args
= {
201 .ctrl_param
= ctrl_param
,
203 struct acpi_buffer input
= { (acpi_size
)sizeof(args
), &args
};
207 status
= wmi_evaluate_method(EEEPC_WMI_MGMT_GUID
, 1,
208 EEEPC_WMI_METHODID_DEVS
,
211 struct acpi_buffer output
= { ACPI_ALLOCATE_BUFFER
, NULL
};
212 union acpi_object
*obj
;
215 status
= wmi_evaluate_method(EEEPC_WMI_MGMT_GUID
, 1,
216 EEEPC_WMI_METHODID_DEVS
,
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
;
240 * These functions actually update the LED's, and are called from a
241 * workqueue. By doing this as separate work rather than when the LED
242 * subsystem asks, we avoid messing with the Eeepc ACPI stuff during a
243 * potentially bad time, such as a timer interrupt.
245 static void tpd_led_update(struct work_struct
*work
)
248 struct eeepc_wmi
*eeepc
;
250 eeepc
= container_of(work
, struct eeepc_wmi
, tpd_led_work
);
252 ctrl_param
= eeepc
->tpd_led_wk
;
253 eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_TPDLED
, ctrl_param
, NULL
);
256 static void tpd_led_set(struct led_classdev
*led_cdev
,
257 enum led_brightness value
)
259 struct eeepc_wmi
*eeepc
;
261 eeepc
= container_of(led_cdev
, struct eeepc_wmi
, tpd_led
);
263 eeepc
->tpd_led_wk
= !!value
;
264 queue_work(eeepc
->led_workqueue
, &eeepc
->tpd_led_work
);
267 static int read_tpd_state(struct eeepc_wmi
*eeepc
)
269 static u32 ctrl_param
;
272 status
= eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_TPDLED
, &ctrl_param
);
274 if (ACPI_FAILURE(status
))
276 else if (!ctrl_param
|| ctrl_param
== 0x00060000)
278 * if touchpad led is present, DSTS will set some bits,
279 * usually 0x00020000.
280 * 0x00060000 means that the device is not supported
284 /* Status is stored in the first bit */
285 return ctrl_param
& 0x1;
288 static enum led_brightness
tpd_led_get(struct led_classdev
*led_cdev
)
290 struct eeepc_wmi
*eeepc
;
292 eeepc
= container_of(led_cdev
, struct eeepc_wmi
, tpd_led
);
294 return read_tpd_state(eeepc
);
297 static int eeepc_wmi_led_init(struct eeepc_wmi
*eeepc
)
301 if (read_tpd_state(eeepc
) < 0)
304 eeepc
->led_workqueue
= create_singlethread_workqueue("led_workqueue");
305 if (!eeepc
->led_workqueue
)
307 INIT_WORK(&eeepc
->tpd_led_work
, tpd_led_update
);
309 eeepc
->tpd_led
.name
= "eeepc::touchpad";
310 eeepc
->tpd_led
.brightness_set
= tpd_led_set
;
311 eeepc
->tpd_led
.brightness_get
= tpd_led_get
;
312 eeepc
->tpd_led
.max_brightness
= 1;
314 rv
= led_classdev_register(&eeepc
->platform_device
->dev
,
317 destroy_workqueue(eeepc
->led_workqueue
);
324 static void eeepc_wmi_led_exit(struct eeepc_wmi
*eeepc
)
326 if (eeepc
->tpd_led
.dev
)
327 led_classdev_unregister(&eeepc
->tpd_led
);
328 if (eeepc
->led_workqueue
)
329 destroy_workqueue(eeepc
->led_workqueue
);
335 static int eeepc_rfkill_set(void *data
, bool blocked
)
337 int dev_id
= (unsigned long)data
;
338 u32 ctrl_param
= !blocked
;
340 return eeepc_wmi_set_devstate(dev_id
, ctrl_param
, NULL
);
343 static void eeepc_rfkill_query(struct rfkill
*rfkill
, void *data
)
345 int dev_id
= (unsigned long)data
;
349 status
= eeepc_wmi_get_devstate(dev_id
, &ctrl_param
);
351 if (ACPI_FAILURE(status
))
354 rfkill_set_sw_state(rfkill
, !(ctrl_param
& 0x1));
357 static const struct rfkill_ops eeepc_rfkill_ops
= {
358 .set_block
= eeepc_rfkill_set
,
359 .query
= eeepc_rfkill_query
,
362 static int eeepc_new_rfkill(struct eeepc_wmi
*eeepc
,
363 struct rfkill
**rfkill
,
365 enum rfkill_type type
, int dev_id
)
371 status
= eeepc_wmi_get_devstate(dev_id
, &ctrl_param
);
373 if (ACPI_FAILURE(status
))
376 /* If the device is present, DSTS will always set some bits
377 * 0x00070000 - 1110000000000000000 - device supported
378 * 0x00060000 - 1100000000000000000 - not supported
379 * 0x00020000 - 0100000000000000000 - device supported
380 * 0x00010000 - 0010000000000000000 - not supported / special mode ?
382 if (!ctrl_param
|| ctrl_param
== 0x00060000)
385 *rfkill
= rfkill_alloc(name
, &eeepc
->platform_device
->dev
, type
,
386 &eeepc_rfkill_ops
, (void *)(long)dev_id
);
391 rfkill_init_sw_state(*rfkill
, !(ctrl_param
& 0x1));
392 result
= rfkill_register(*rfkill
);
394 rfkill_destroy(*rfkill
);
401 static void eeepc_wmi_rfkill_exit(struct eeepc_wmi
*eeepc
)
403 if (eeepc
->wlan_rfkill
) {
404 rfkill_unregister(eeepc
->wlan_rfkill
);
405 rfkill_destroy(eeepc
->wlan_rfkill
);
406 eeepc
->wlan_rfkill
= NULL
;
408 if (eeepc
->bluetooth_rfkill
) {
409 rfkill_unregister(eeepc
->bluetooth_rfkill
);
410 rfkill_destroy(eeepc
->bluetooth_rfkill
);
411 eeepc
->bluetooth_rfkill
= NULL
;
413 if (eeepc
->wwan3g_rfkill
) {
414 rfkill_unregister(eeepc
->wwan3g_rfkill
);
415 rfkill_destroy(eeepc
->wwan3g_rfkill
);
416 eeepc
->wwan3g_rfkill
= NULL
;
420 static int eeepc_wmi_rfkill_init(struct eeepc_wmi
*eeepc
)
424 result
= eeepc_new_rfkill(eeepc
, &eeepc
->wlan_rfkill
,
425 "eeepc-wlan", RFKILL_TYPE_WLAN
,
426 EEEPC_WMI_DEVID_WLAN
);
428 if (result
&& result
!= -ENODEV
)
431 result
= eeepc_new_rfkill(eeepc
, &eeepc
->bluetooth_rfkill
,
432 "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH
,
433 EEEPC_WMI_DEVID_BLUETOOTH
);
435 if (result
&& result
!= -ENODEV
)
438 result
= eeepc_new_rfkill(eeepc
, &eeepc
->wwan3g_rfkill
,
439 "eeepc-wwan3g", RFKILL_TYPE_WWAN
,
440 EEEPC_WMI_DEVID_WWAN3G
);
442 if (result
&& result
!= -ENODEV
)
446 if (result
&& result
!= -ENODEV
)
447 eeepc_wmi_rfkill_exit(eeepc
);
449 if (result
== -ENODEV
)
458 static int read_brightness(struct backlight_device
*bd
)
460 static u32 ctrl_param
;
463 status
= eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT
, &ctrl_param
);
465 if (ACPI_FAILURE(status
))
468 return ctrl_param
& 0xFF;
471 static int update_bl_status(struct backlight_device
*bd
)
474 static u32 ctrl_param
;
477 ctrl_param
= bd
->props
.brightness
;
479 status
= eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT
,
482 if (ACPI_FAILURE(status
))
488 static const struct backlight_ops eeepc_wmi_bl_ops
= {
489 .get_brightness
= read_brightness
,
490 .update_status
= update_bl_status
,
493 static int eeepc_wmi_backlight_notify(struct eeepc_wmi
*eeepc
, int code
)
495 struct backlight_device
*bd
= eeepc
->backlight_device
;
496 int old
= bd
->props
.brightness
;
499 if (code
>= NOTIFY_BRNUP_MIN
&& code
<= NOTIFY_BRNUP_MAX
)
500 new = code
- NOTIFY_BRNUP_MIN
+ 1;
501 else if (code
>= NOTIFY_BRNDOWN_MIN
&& code
<= NOTIFY_BRNDOWN_MAX
)
502 new = code
- NOTIFY_BRNDOWN_MIN
;
504 bd
->props
.brightness
= new;
505 backlight_update_status(bd
);
506 backlight_force_update(bd
, BACKLIGHT_UPDATE_HOTKEY
);
511 static int eeepc_wmi_backlight_init(struct eeepc_wmi
*eeepc
)
513 struct backlight_device
*bd
;
514 struct backlight_properties props
;
516 memset(&props
, 0, sizeof(struct backlight_properties
));
517 props
.max_brightness
= 15;
518 bd
= backlight_device_register(EEEPC_WMI_FILE
,
519 &eeepc
->platform_device
->dev
, eeepc
,
520 &eeepc_wmi_bl_ops
, &props
);
522 pr_err("Could not register backlight device\n");
526 eeepc
->backlight_device
= bd
;
528 bd
->props
.brightness
= read_brightness(bd
);
529 bd
->props
.power
= FB_BLANK_UNBLANK
;
530 backlight_update_status(bd
);
535 static void eeepc_wmi_backlight_exit(struct eeepc_wmi
*eeepc
)
537 if (eeepc
->backlight_device
)
538 backlight_device_unregister(eeepc
->backlight_device
);
540 eeepc
->backlight_device
= NULL
;
543 static void eeepc_wmi_notify(u32 value
, void *context
)
545 struct eeepc_wmi
*eeepc
= context
;
546 struct acpi_buffer response
= { ACPI_ALLOCATE_BUFFER
, NULL
};
547 union acpi_object
*obj
;
552 status
= wmi_get_event_data(value
, &response
);
553 if (status
!= AE_OK
) {
554 pr_err("bad event status 0x%x\n", status
);
558 obj
= (union acpi_object
*)response
.pointer
;
560 if (obj
&& obj
->type
== ACPI_TYPE_INTEGER
) {
561 code
= obj
->integer
.value
;
564 if (code
>= NOTIFY_BRNUP_MIN
&& code
<= NOTIFY_BRNUP_MAX
)
565 code
= NOTIFY_BRNUP_MIN
;
566 else if (code
>= NOTIFY_BRNDOWN_MIN
&&
567 code
<= NOTIFY_BRNDOWN_MAX
)
568 code
= NOTIFY_BRNDOWN_MIN
;
570 if (code
== NOTIFY_BRNUP_MIN
|| code
== NOTIFY_BRNDOWN_MIN
) {
571 if (!acpi_video_backlight_support())
572 eeepc_wmi_backlight_notify(eeepc
, orig_code
);
575 if (!sparse_keymap_report_event(eeepc
->inputdev
,
577 pr_info("Unknown key %x pressed\n", code
);
583 static ssize_t
store_cpufv(struct device
*dev
, struct device_attribute
*attr
,
584 const char *buf
, size_t count
)
587 struct acpi_buffer input
= { (acpi_size
)sizeof(value
), &value
};
590 if (!count
|| sscanf(buf
, "%i", &value
) != 1)
592 if (value
< 0 || value
> 2)
595 status
= wmi_evaluate_method(EEEPC_WMI_MGMT_GUID
,
596 1, EEEPC_WMI_METHODID_CFVS
, &input
, NULL
);
598 if (ACPI_FAILURE(status
))
604 static DEVICE_ATTR(cpufv
, S_IRUGO
| S_IWUSR
, NULL
, store_cpufv
);
606 static struct attribute
*platform_attributes
[] = {
607 &dev_attr_cpufv
.attr
,
611 static struct attribute_group platform_attribute_group
= {
612 .attrs
= platform_attributes
615 static void eeepc_wmi_sysfs_exit(struct platform_device
*device
)
617 sysfs_remove_group(&device
->dev
.kobj
, &platform_attribute_group
);
620 static int eeepc_wmi_sysfs_init(struct platform_device
*device
)
622 return sysfs_create_group(&device
->dev
.kobj
, &platform_attribute_group
);
628 static int __init
eeepc_wmi_platform_init(struct eeepc_wmi
*eeepc
)
632 eeepc
->platform_device
= platform_device_alloc(EEEPC_WMI_FILE
, -1);
633 if (!eeepc
->platform_device
)
635 platform_set_drvdata(eeepc
->platform_device
, eeepc
);
637 err
= platform_device_add(eeepc
->platform_device
);
639 goto fail_platform_device
;
641 err
= eeepc_wmi_sysfs_init(eeepc
->platform_device
);
647 platform_device_del(eeepc
->platform_device
);
648 fail_platform_device
:
649 platform_device_put(eeepc
->platform_device
);
653 static void eeepc_wmi_platform_exit(struct eeepc_wmi
*eeepc
)
655 eeepc_wmi_sysfs_exit(eeepc
->platform_device
);
656 platform_device_unregister(eeepc
->platform_device
);
662 struct eeepc_wmi_debugfs_node
{
663 struct eeepc_wmi
*eeepc
;
665 int (*show
)(struct seq_file
*m
, void *data
);
668 static int show_dsts(struct seq_file
*m
, void *data
)
670 struct eeepc_wmi
*eeepc
= m
->private;
674 status
= eeepc_wmi_get_devstate(eeepc
->debug
.dev_id
, &retval
);
676 if (ACPI_FAILURE(status
))
679 seq_printf(m
, "DSTS(%x) = %x\n", eeepc
->debug
.dev_id
, retval
);
684 static int show_devs(struct seq_file
*m
, void *data
)
686 struct eeepc_wmi
*eeepc
= m
->private;
690 status
= eeepc_wmi_set_devstate(eeepc
->debug
.dev_id
,
691 eeepc
->debug
.ctrl_param
, &retval
);
692 if (ACPI_FAILURE(status
))
695 seq_printf(m
, "DEVS(%x, %x) = %x\n", eeepc
->debug
.dev_id
,
696 eeepc
->debug
.ctrl_param
, retval
);
701 static struct eeepc_wmi_debugfs_node eeepc_wmi_debug_files
[] = {
702 { NULL
, "devs", show_devs
},
703 { NULL
, "dsts", show_dsts
},
706 static int eeepc_wmi_debugfs_open(struct inode
*inode
, struct file
*file
)
708 struct eeepc_wmi_debugfs_node
*node
= inode
->i_private
;
710 return single_open(file
, node
->show
, node
->eeepc
);
713 static const struct file_operations eeepc_wmi_debugfs_io_ops
= {
714 .owner
= THIS_MODULE
,
715 .open
= eeepc_wmi_debugfs_open
,
718 .release
= single_release
,
721 static void eeepc_wmi_debugfs_exit(struct eeepc_wmi
*eeepc
)
723 debugfs_remove_recursive(eeepc
->debug
.root
);
726 static int eeepc_wmi_debugfs_init(struct eeepc_wmi
*eeepc
)
731 eeepc
->debug
.root
= debugfs_create_dir(EEEPC_WMI_FILE
, NULL
);
732 if (!eeepc
->debug
.root
) {
733 pr_err("failed to create debugfs directory");
737 dent
= debugfs_create_x32("dev_id", S_IRUGO
|S_IWUSR
,
738 eeepc
->debug
.root
, &eeepc
->debug
.dev_id
);
742 dent
= debugfs_create_x32("ctrl_param", S_IRUGO
|S_IWUSR
,
743 eeepc
->debug
.root
, &eeepc
->debug
.ctrl_param
);
747 for (i
= 0; i
< ARRAY_SIZE(eeepc_wmi_debug_files
); i
++) {
748 struct eeepc_wmi_debugfs_node
*node
= &eeepc_wmi_debug_files
[i
];
751 dent
= debugfs_create_file(node
->name
, S_IFREG
| S_IRUGO
,
752 eeepc
->debug
.root
, node
,
753 &eeepc_wmi_debugfs_io_ops
);
755 pr_err("failed to create debug file: %s\n", node
->name
);
763 eeepc_wmi_debugfs_exit(eeepc
);
770 static struct platform_device
* __init
eeepc_wmi_add(void)
772 struct eeepc_wmi
*eeepc
;
776 eeepc
= kzalloc(sizeof(struct eeepc_wmi
), GFP_KERNEL
);
778 return ERR_PTR(-ENOMEM
);
781 * Register the platform device first. It is used as a parent for the
784 err
= eeepc_wmi_platform_init(eeepc
);
788 err
= eeepc_wmi_input_init(eeepc
);
792 err
= eeepc_wmi_led_init(eeepc
);
796 err
= eeepc_wmi_rfkill_init(eeepc
);
800 if (!acpi_video_backlight_support()) {
801 err
= eeepc_wmi_backlight_init(eeepc
);
805 pr_info("Backlight controlled by ACPI video driver\n");
807 status
= wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID
,
808 eeepc_wmi_notify
, eeepc
);
809 if (ACPI_FAILURE(status
)) {
810 pr_err("Unable to register notify handler - %d\n",
813 goto fail_wmi_handler
;
816 err
= eeepc_wmi_debugfs_init(eeepc
);
820 return eeepc
->platform_device
;
823 wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID
);
825 eeepc_wmi_backlight_exit(eeepc
);
827 eeepc_wmi_rfkill_exit(eeepc
);
829 eeepc_wmi_led_exit(eeepc
);
831 eeepc_wmi_input_exit(eeepc
);
833 eeepc_wmi_platform_exit(eeepc
);
839 static int eeepc_wmi_remove(struct platform_device
*device
)
841 struct eeepc_wmi
*eeepc
;
843 eeepc
= platform_get_drvdata(device
);
844 wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID
);
845 eeepc_wmi_backlight_exit(eeepc
);
846 eeepc_wmi_input_exit(eeepc
);
847 eeepc_wmi_led_exit(eeepc
);
848 eeepc_wmi_rfkill_exit(eeepc
);
849 eeepc_wmi_debugfs_exit(eeepc
);
850 eeepc_wmi_platform_exit(eeepc
);
856 static struct platform_driver platform_driver
= {
858 .name
= EEEPC_WMI_FILE
,
859 .owner
= THIS_MODULE
,
863 static int __init
eeepc_wmi_init(void)
867 if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID
) ||
868 !wmi_has_guid(EEEPC_WMI_MGMT_GUID
)) {
869 pr_warning("No known WMI GUID found\n");
873 platform_device
= eeepc_wmi_add();
874 if (IS_ERR(platform_device
)) {
875 err
= PTR_ERR(platform_device
);
879 err
= platform_driver_register(&platform_driver
);
881 pr_warning("Unable to register platform driver\n");
882 goto fail_platform_driver
;
887 fail_platform_driver
:
888 eeepc_wmi_remove(platform_device
);
893 static void __exit
eeepc_wmi_exit(void)
895 eeepc_wmi_remove(platform_device
);
896 platform_driver_unregister(&platform_driver
);
899 module_init(eeepc_wmi_init
);
900 module_exit(eeepc_wmi_exit
);