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