xref: /openbmc/linux/drivers/platform/x86/eeepc-wmi.c (revision afa7c886578ce264d9b66d4bcb1fea51fac47925)
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 
141 	struct eeepc_wmi_debug debug;
142 };
143 
144 /* Only used in eeepc_wmi_init() and eeepc_wmi_exit() */
145 static struct platform_device *platform_device;
146 
147 static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc)
148 {
149 	int err;
150 
151 	eeepc->inputdev = input_allocate_device();
152 	if (!eeepc->inputdev)
153 		return -ENOMEM;
154 
155 	eeepc->inputdev->name = "Eee PC WMI hotkeys";
156 	eeepc->inputdev->phys = EEEPC_WMI_FILE "/input0";
157 	eeepc->inputdev->id.bustype = BUS_HOST;
158 	eeepc->inputdev->dev.parent = &eeepc->platform_device->dev;
159 
160 	err = sparse_keymap_setup(eeepc->inputdev, eeepc_wmi_keymap, NULL);
161 	if (err)
162 		goto err_free_dev;
163 
164 	err = input_register_device(eeepc->inputdev);
165 	if (err)
166 		goto err_free_keymap;
167 
168 	return 0;
169 
170 err_free_keymap:
171 	sparse_keymap_free(eeepc->inputdev);
172 err_free_dev:
173 	input_free_device(eeepc->inputdev);
174 	return err;
175 }
176 
177 static void eeepc_wmi_input_exit(struct eeepc_wmi *eeepc)
178 {
179 	if (eeepc->inputdev) {
180 		sparse_keymap_free(eeepc->inputdev);
181 		input_unregister_device(eeepc->inputdev);
182 	}
183 
184 	eeepc->inputdev = NULL;
185 }
186 
187 static acpi_status eeepc_wmi_get_devstate(u32 dev_id, u32 *retval)
188 {
189 	struct acpi_buffer input = { (acpi_size)sizeof(u32), &dev_id };
190 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
191 	union acpi_object *obj;
192 	acpi_status status;
193 	u32 tmp;
194 
195 	status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
196 				     1, EEEPC_WMI_METHODID_DSTS,
197 				     &input, &output);
198 
199 	if (ACPI_FAILURE(status))
200 		return status;
201 
202 	obj = (union acpi_object *)output.pointer;
203 	if (obj && obj->type == ACPI_TYPE_INTEGER)
204 		tmp = (u32)obj->integer.value;
205 	else
206 		tmp = 0;
207 
208 	if (retval)
209 		*retval = tmp;
210 
211 	kfree(obj);
212 
213 	return status;
214 
215 }
216 
217 static acpi_status eeepc_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
218 					  u32 *retval)
219 {
220 	struct bios_args args = {
221 		.dev_id = dev_id,
222 		.ctrl_param = ctrl_param,
223 	};
224 	struct acpi_buffer input = { (acpi_size)sizeof(args), &args };
225 	acpi_status status;
226 
227 	if (!retval) {
228 		status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID, 1,
229 					     EEEPC_WMI_METHODID_DEVS,
230 					     &input, NULL);
231 	} else {
232 		struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
233 		union acpi_object *obj;
234 		u32 tmp;
235 
236 		status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID, 1,
237 					     EEEPC_WMI_METHODID_DEVS,
238 					     &input, &output);
239 
240 		if (ACPI_FAILURE(status))
241 			return status;
242 
243 		obj = (union acpi_object *)output.pointer;
244 		if (obj && obj->type == ACPI_TYPE_INTEGER)
245 			tmp = (u32)obj->integer.value;
246 		else
247 			tmp = 0;
248 
249 		*retval = tmp;
250 
251 		kfree(obj);
252 	}
253 
254 	return status;
255 }
256 
257 /*
258  * LEDs
259  */
260 /*
261  * These functions actually update the LED's, and are called from a
262  * workqueue. By doing this as separate work rather than when the LED
263  * subsystem asks, we avoid messing with the Eeepc ACPI stuff during a
264  * potentially bad time, such as a timer interrupt.
265  */
266 static void tpd_led_update(struct work_struct *work)
267 {
268 	int ctrl_param;
269 	struct eeepc_wmi *eeepc;
270 
271 	eeepc = container_of(work, struct eeepc_wmi, tpd_led_work);
272 
273 	ctrl_param = eeepc->tpd_led_wk;
274 	eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_TPDLED, ctrl_param, NULL);
275 }
276 
277 static void tpd_led_set(struct led_classdev *led_cdev,
278 			enum led_brightness value)
279 {
280 	struct eeepc_wmi *eeepc;
281 
282 	eeepc = container_of(led_cdev, struct eeepc_wmi, tpd_led);
283 
284 	eeepc->tpd_led_wk = !!value;
285 	queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
286 }
287 
288 static int read_tpd_state(struct eeepc_wmi *eeepc)
289 {
290 	u32 retval;
291 	acpi_status status;
292 
293 	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_TPDLED, &retval);
294 
295 	if (ACPI_FAILURE(status))
296 		return -1;
297 	else if (!retval || retval == 0x00060000)
298 		/*
299 		 * if touchpad led is present, DSTS will set some bits,
300 		 * usually 0x00020000.
301 		 * 0x00060000 means that the device is not supported
302 		 */
303 		return -ENODEV;
304 	else
305 		/* Status is stored in the first bit */
306 		return retval & 0x1;
307 }
308 
309 static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
310 {
311 	struct eeepc_wmi *eeepc;
312 
313 	eeepc = container_of(led_cdev, struct eeepc_wmi, tpd_led);
314 
315 	return read_tpd_state(eeepc);
316 }
317 
318 static int eeepc_wmi_led_init(struct eeepc_wmi *eeepc)
319 {
320 	int rv;
321 
322 	if (read_tpd_state(eeepc) < 0)
323 		return 0;
324 
325 	eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
326 	if (!eeepc->led_workqueue)
327 		return -ENOMEM;
328 	INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);
329 
330 	eeepc->tpd_led.name = "eeepc::touchpad";
331 	eeepc->tpd_led.brightness_set = tpd_led_set;
332 	eeepc->tpd_led.brightness_get = tpd_led_get;
333 	eeepc->tpd_led.max_brightness = 1;
334 
335 	rv = led_classdev_register(&eeepc->platform_device->dev,
336 				   &eeepc->tpd_led);
337 	if (rv) {
338 		destroy_workqueue(eeepc->led_workqueue);
339 		return rv;
340 	}
341 
342 	return 0;
343 }
344 
345 static void eeepc_wmi_led_exit(struct eeepc_wmi *eeepc)
346 {
347 	if (eeepc->tpd_led.dev)
348 		led_classdev_unregister(&eeepc->tpd_led);
349 	if (eeepc->led_workqueue)
350 		destroy_workqueue(eeepc->led_workqueue);
351 }
352 
353 /*
354  * PCI hotplug (for wlan rfkill)
355  */
356 static bool eeepc_wlan_rfkill_blocked(struct eeepc_wmi *eeepc)
357 {
358 	u32 retval;
359 	acpi_status status;
360 
361 	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_WLAN, &retval);
362 
363 	if (ACPI_FAILURE(status))
364 		return false;
365 
366 	return !(retval & 0x1);
367 }
368 
369 static void eeepc_rfkill_hotplug(struct eeepc_wmi *eeepc)
370 {
371 	struct pci_dev *dev;
372 	struct pci_bus *bus;
373 	bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
374 	bool absent;
375 	u32 l;
376 
377 	if (eeepc->wlan_rfkill)
378 		rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
379 
380 	mutex_lock(&eeepc->hotplug_lock);
381 
382 	if (eeepc->hotplug_slot) {
383 		bus = pci_find_bus(0, 1);
384 		if (!bus) {
385 			pr_warning("Unable to find PCI bus 1?\n");
386 			goto out_unlock;
387 		}
388 
389 		if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
390 			pr_err("Unable to read PCI config space?\n");
391 			goto out_unlock;
392 		}
393 		absent = (l == 0xffffffff);
394 
395 		if (blocked != absent) {
396 			pr_warning("BIOS says wireless lan is %s, "
397 					"but the pci device is %s\n",
398 				blocked ? "blocked" : "unblocked",
399 				absent ? "absent" : "present");
400 			pr_warning("skipped wireless hotplug as probably "
401 					"inappropriate for this model\n");
402 			goto out_unlock;
403 		}
404 
405 		if (!blocked) {
406 			dev = pci_get_slot(bus, 0);
407 			if (dev) {
408 				/* Device already present */
409 				pci_dev_put(dev);
410 				goto out_unlock;
411 			}
412 			dev = pci_scan_single_device(bus, 0);
413 			if (dev) {
414 				pci_bus_assign_resources(bus);
415 				if (pci_bus_add_device(dev))
416 					pr_err("Unable to hotplug wifi\n");
417 			}
418 		} else {
419 			dev = pci_get_slot(bus, 0);
420 			if (dev) {
421 				pci_remove_bus_device(dev);
422 				pci_dev_put(dev);
423 			}
424 		}
425 	}
426 
427 out_unlock:
428 	mutex_unlock(&eeepc->hotplug_lock);
429 }
430 
431 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
432 {
433 	struct eeepc_wmi *eeepc = data;
434 
435 	if (event != ACPI_NOTIFY_BUS_CHECK)
436 		return;
437 
438 	eeepc_rfkill_hotplug(eeepc);
439 }
440 
441 static int eeepc_register_rfkill_notifier(struct eeepc_wmi *eeepc,
442 					  char *node)
443 {
444 	acpi_status status;
445 	acpi_handle handle;
446 
447 	status = acpi_get_handle(NULL, node, &handle);
448 
449 	if (ACPI_SUCCESS(status)) {
450 		status = acpi_install_notify_handler(handle,
451 						     ACPI_SYSTEM_NOTIFY,
452 						     eeepc_rfkill_notify,
453 						     eeepc);
454 		if (ACPI_FAILURE(status))
455 			pr_warning("Failed to register notify on %s\n", node);
456 	} else
457 		return -ENODEV;
458 
459 	return 0;
460 }
461 
462 static void eeepc_unregister_rfkill_notifier(struct eeepc_wmi *eeepc,
463 					     char *node)
464 {
465 	acpi_status status = AE_OK;
466 	acpi_handle handle;
467 
468 	status = acpi_get_handle(NULL, node, &handle);
469 
470 	if (ACPI_SUCCESS(status)) {
471 		status = acpi_remove_notify_handler(handle,
472 						     ACPI_SYSTEM_NOTIFY,
473 						     eeepc_rfkill_notify);
474 		if (ACPI_FAILURE(status))
475 			pr_err("Error removing rfkill notify handler %s\n",
476 				node);
477 	}
478 }
479 
480 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
481 				    u8 *value)
482 {
483 	u32 retval;
484 	acpi_status status;
485 
486 	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_WLAN, &retval);
487 
488 	if (ACPI_FAILURE(status))
489 		return -EIO;
490 
491 	if (!retval || retval == 0x00060000)
492 		return -ENODEV;
493 	else
494 		*value = (retval & 0x1);
495 
496 	return 0;
497 }
498 
499 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
500 {
501 	kfree(hotplug_slot->info);
502 	kfree(hotplug_slot);
503 }
504 
505 static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
506 	.owner = THIS_MODULE,
507 	.get_adapter_status = eeepc_get_adapter_status,
508 	.get_power_status = eeepc_get_adapter_status,
509 };
510 
511 static int eeepc_setup_pci_hotplug(struct eeepc_wmi *eeepc)
512 {
513 	int ret = -ENOMEM;
514 	struct pci_bus *bus = pci_find_bus(0, 1);
515 
516 	if (!bus) {
517 		pr_err("Unable to find wifi PCI bus\n");
518 		return -ENODEV;
519 	}
520 
521 	eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
522 	if (!eeepc->hotplug_slot)
523 		goto error_slot;
524 
525 	eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
526 					    GFP_KERNEL);
527 	if (!eeepc->hotplug_slot->info)
528 		goto error_info;
529 
530 	eeepc->hotplug_slot->private = eeepc;
531 	eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
532 	eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
533 	eeepc_get_adapter_status(eeepc->hotplug_slot,
534 				 &eeepc->hotplug_slot->info->adapter_status);
535 
536 	ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
537 	if (ret) {
538 		pr_err("Unable to register hotplug slot - %d\n", ret);
539 		goto error_register;
540 	}
541 
542 	return 0;
543 
544 error_register:
545 	kfree(eeepc->hotplug_slot->info);
546 error_info:
547 	kfree(eeepc->hotplug_slot);
548 	eeepc->hotplug_slot = NULL;
549 error_slot:
550 	return ret;
551 }
552 
553 /*
554  * Rfkill devices
555  */
556 static int eeepc_rfkill_set(void *data, bool blocked)
557 {
558 	int dev_id = (unsigned long)data;
559 	u32 ctrl_param = !blocked;
560 
561 	return eeepc_wmi_set_devstate(dev_id, ctrl_param, NULL);
562 }
563 
564 static void eeepc_rfkill_query(struct rfkill *rfkill, void *data)
565 {
566 	int dev_id = (unsigned long)data;
567 	u32 retval;
568 	acpi_status status;
569 
570 	status = eeepc_wmi_get_devstate(dev_id, &retval);
571 
572 	if (ACPI_FAILURE(status))
573 		return ;
574 
575 	rfkill_set_sw_state(rfkill, !(retval & 0x1));
576 }
577 
578 static const struct rfkill_ops eeepc_rfkill_ops = {
579 	.set_block = eeepc_rfkill_set,
580 	.query = eeepc_rfkill_query,
581 };
582 
583 static int eeepc_new_rfkill(struct eeepc_wmi *eeepc,
584 			    struct rfkill **rfkill,
585 			    const char *name,
586 			    enum rfkill_type type, int dev_id)
587 {
588 	int result;
589 	u32 retval;
590 	acpi_status status;
591 
592 	status = eeepc_wmi_get_devstate(dev_id, &retval);
593 
594 	if (ACPI_FAILURE(status))
595 		return -1;
596 
597 	/* If the device is present, DSTS will always set some bits
598 	 * 0x00070000 - 1110000000000000000 - device supported
599 	 * 0x00060000 - 1100000000000000000 - not supported
600 	 * 0x00020000 - 0100000000000000000 - device supported
601 	 * 0x00010000 - 0010000000000000000 - not supported / special mode ?
602 	 */
603 	if (!retval || retval == 0x00060000)
604 		return -ENODEV;
605 
606 	*rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
607 			       &eeepc_rfkill_ops, (void *)(long)dev_id);
608 
609 	if (!*rfkill)
610 		return -EINVAL;
611 
612 	rfkill_init_sw_state(*rfkill, !(retval & 0x1));
613 	result = rfkill_register(*rfkill);
614 	if (result) {
615 		rfkill_destroy(*rfkill);
616 		*rfkill = NULL;
617 		return result;
618 	}
619 	return 0;
620 }
621 
622 static void eeepc_wmi_rfkill_exit(struct eeepc_wmi *eeepc)
623 {
624 	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
625 	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
626 	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
627 	if (eeepc->wlan_rfkill) {
628 		rfkill_unregister(eeepc->wlan_rfkill);
629 		rfkill_destroy(eeepc->wlan_rfkill);
630 		eeepc->wlan_rfkill = NULL;
631 	}
632 	/*
633 	 * Refresh pci hotplug in case the rfkill state was changed after
634 	 * eeepc_unregister_rfkill_notifier()
635 	 */
636 	eeepc_rfkill_hotplug(eeepc);
637 	if (eeepc->hotplug_slot)
638 		pci_hp_deregister(eeepc->hotplug_slot);
639 
640 	if (eeepc->bluetooth_rfkill) {
641 		rfkill_unregister(eeepc->bluetooth_rfkill);
642 		rfkill_destroy(eeepc->bluetooth_rfkill);
643 		eeepc->bluetooth_rfkill = NULL;
644 	}
645 	if (eeepc->wwan3g_rfkill) {
646 		rfkill_unregister(eeepc->wwan3g_rfkill);
647 		rfkill_destroy(eeepc->wwan3g_rfkill);
648 		eeepc->wwan3g_rfkill = NULL;
649 	}
650 }
651 
652 static int eeepc_wmi_rfkill_init(struct eeepc_wmi *eeepc)
653 {
654 	int result = 0;
655 
656 	mutex_init(&eeepc->hotplug_lock);
657 
658 	result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
659 				  "eeepc-wlan", RFKILL_TYPE_WLAN,
660 				  EEEPC_WMI_DEVID_WLAN);
661 
662 	if (result && result != -ENODEV)
663 		goto exit;
664 
665 	result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
666 				  "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
667 				  EEEPC_WMI_DEVID_BLUETOOTH);
668 
669 	if (result && result != -ENODEV)
670 		goto exit;
671 
672 	result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
673 				  "eeepc-wwan3g", RFKILL_TYPE_WWAN,
674 				  EEEPC_WMI_DEVID_WWAN3G);
675 
676 	if (result && result != -ENODEV)
677 		goto exit;
678 
679 	result = eeepc_setup_pci_hotplug(eeepc);
680 	/*
681 	 * If we get -EBUSY then something else is handling the PCI hotplug -
682 	 * don't fail in this case
683 	 */
684 	if (result == -EBUSY)
685 		result = 0;
686 
687 	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
688 	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
689 	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
690 	/*
691 	 * Refresh pci hotplug in case the rfkill state was changed during
692 	 * setup.
693 	 */
694 	eeepc_rfkill_hotplug(eeepc);
695 
696 exit:
697 	if (result && result != -ENODEV)
698 		eeepc_wmi_rfkill_exit(eeepc);
699 
700 	if (result == -ENODEV)
701 		result = 0;
702 
703 	return result;
704 }
705 
706 /*
707  * Backlight
708  */
709 static int read_brightness(struct backlight_device *bd)
710 {
711 	u32 retval;
712 	acpi_status status;
713 
714 	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT, &retval);
715 
716 	if (ACPI_FAILURE(status))
717 		return -1;
718 	else
719 		return retval & 0xFF;
720 }
721 
722 static int update_bl_status(struct backlight_device *bd)
723 {
724 
725 	u32 ctrl_param;
726 	acpi_status status;
727 
728 	ctrl_param = bd->props.brightness;
729 
730 	status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT,
731 					ctrl_param, NULL);
732 
733 	if (ACPI_FAILURE(status))
734 		return -1;
735 	else
736 		return 0;
737 }
738 
739 static const struct backlight_ops eeepc_wmi_bl_ops = {
740 	.get_brightness = read_brightness,
741 	.update_status = update_bl_status,
742 };
743 
744 static int eeepc_wmi_backlight_notify(struct eeepc_wmi *eeepc, int code)
745 {
746 	struct backlight_device *bd = eeepc->backlight_device;
747 	int old = bd->props.brightness;
748 	int new = old;
749 
750 	if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
751 		new = code - NOTIFY_BRNUP_MIN + 1;
752 	else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
753 		new = code - NOTIFY_BRNDOWN_MIN;
754 
755 	bd->props.brightness = new;
756 	backlight_update_status(bd);
757 	backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
758 
759 	return old;
760 }
761 
762 static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
763 {
764 	struct backlight_device *bd;
765 	struct backlight_properties props;
766 
767 	memset(&props, 0, sizeof(struct backlight_properties));
768 	props.max_brightness = 15;
769 	bd = backlight_device_register(EEEPC_WMI_FILE,
770 				       &eeepc->platform_device->dev, eeepc,
771 				       &eeepc_wmi_bl_ops, &props);
772 	if (IS_ERR(bd)) {
773 		pr_err("Could not register backlight device\n");
774 		return PTR_ERR(bd);
775 	}
776 
777 	eeepc->backlight_device = bd;
778 
779 	bd->props.brightness = read_brightness(bd);
780 	bd->props.power = FB_BLANK_UNBLANK;
781 	backlight_update_status(bd);
782 
783 	return 0;
784 }
785 
786 static void eeepc_wmi_backlight_exit(struct eeepc_wmi *eeepc)
787 {
788 	if (eeepc->backlight_device)
789 		backlight_device_unregister(eeepc->backlight_device);
790 
791 	eeepc->backlight_device = NULL;
792 }
793 
794 static void eeepc_wmi_notify(u32 value, void *context)
795 {
796 	struct eeepc_wmi *eeepc = context;
797 	struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
798 	union acpi_object *obj;
799 	acpi_status status;
800 	int code;
801 	int orig_code;
802 
803 	status = wmi_get_event_data(value, &response);
804 	if (status != AE_OK) {
805 		pr_err("bad event status 0x%x\n", status);
806 		return;
807 	}
808 
809 	obj = (union acpi_object *)response.pointer;
810 
811 	if (obj && obj->type == ACPI_TYPE_INTEGER) {
812 		code = obj->integer.value;
813 		orig_code = code;
814 
815 		if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
816 			code = NOTIFY_BRNUP_MIN;
817 		else if (code >= NOTIFY_BRNDOWN_MIN &&
818 			 code <= NOTIFY_BRNDOWN_MAX)
819 			code = NOTIFY_BRNDOWN_MIN;
820 
821 		if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) {
822 			if (!acpi_video_backlight_support())
823 				eeepc_wmi_backlight_notify(eeepc, orig_code);
824 		}
825 
826 		if (!sparse_keymap_report_event(eeepc->inputdev,
827 						code, 1, true))
828 			pr_info("Unknown key %x pressed\n", code);
829 	}
830 
831 	kfree(obj);
832 }
833 
834 static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr,
835 			   const char *buf, size_t count)
836 {
837 	int value;
838 	struct acpi_buffer input = { (acpi_size)sizeof(value), &value };
839 	acpi_status status;
840 
841 	if (!count || sscanf(buf, "%i", &value) != 1)
842 		return -EINVAL;
843 	if (value < 0 || value > 2)
844 		return -EINVAL;
845 
846 	status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
847 				     1, EEEPC_WMI_METHODID_CFVS, &input, NULL);
848 
849 	if (ACPI_FAILURE(status))
850 		return -EIO;
851 	else
852 		return count;
853 }
854 
855 static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv);
856 
857 static struct attribute *platform_attributes[] = {
858 	&dev_attr_cpufv.attr,
859 	NULL
860 };
861 
862 static struct attribute_group platform_attribute_group = {
863 	.attrs = platform_attributes
864 };
865 
866 static void eeepc_wmi_sysfs_exit(struct platform_device *device)
867 {
868 	sysfs_remove_group(&device->dev.kobj, &platform_attribute_group);
869 }
870 
871 static int eeepc_wmi_sysfs_init(struct platform_device *device)
872 {
873 	return sysfs_create_group(&device->dev.kobj, &platform_attribute_group);
874 }
875 
876 /*
877  * Platform device
878  */
879 static int __init eeepc_wmi_platform_init(struct eeepc_wmi *eeepc)
880 {
881 	int err;
882 
883 	eeepc->platform_device = platform_device_alloc(EEEPC_WMI_FILE, -1);
884 	if (!eeepc->platform_device)
885 		return -ENOMEM;
886 	platform_set_drvdata(eeepc->platform_device, eeepc);
887 
888 	err = platform_device_add(eeepc->platform_device);
889 	if (err)
890 		goto fail_platform_device;
891 
892 	err = eeepc_wmi_sysfs_init(eeepc->platform_device);
893 	if (err)
894 		goto fail_sysfs;
895 	return 0;
896 
897 fail_sysfs:
898 	platform_device_del(eeepc->platform_device);
899 fail_platform_device:
900 	platform_device_put(eeepc->platform_device);
901 	return err;
902 }
903 
904 static void eeepc_wmi_platform_exit(struct eeepc_wmi *eeepc)
905 {
906 	eeepc_wmi_sysfs_exit(eeepc->platform_device);
907 	platform_device_unregister(eeepc->platform_device);
908 }
909 
910 /*
911  * debugfs
912  */
913 struct eeepc_wmi_debugfs_node {
914 	struct eeepc_wmi *eeepc;
915 	char *name;
916 	int (*show)(struct seq_file *m, void *data);
917 };
918 
919 static int show_dsts(struct seq_file *m, void *data)
920 {
921 	struct eeepc_wmi *eeepc = m->private;
922 	acpi_status status;
923 	u32 retval = -1;
924 
925 	status = eeepc_wmi_get_devstate(eeepc->debug.dev_id, &retval);
926 
927 	if (ACPI_FAILURE(status))
928 		return -EIO;
929 
930 	seq_printf(m, "DSTS(%x) = %x\n", eeepc->debug.dev_id, retval);
931 
932 	return 0;
933 }
934 
935 static int show_devs(struct seq_file *m, void *data)
936 {
937 	struct eeepc_wmi *eeepc = m->private;
938 	acpi_status status;
939 	u32 retval = -1;
940 
941 	status = eeepc_wmi_set_devstate(eeepc->debug.dev_id,
942 					eeepc->debug.ctrl_param, &retval);
943 	if (ACPI_FAILURE(status))
944 		return -EIO;
945 
946 	seq_printf(m, "DEVS(%x, %x) = %x\n", eeepc->debug.dev_id,
947 		   eeepc->debug.ctrl_param, retval);
948 
949 	return 0;
950 }
951 
952 static struct eeepc_wmi_debugfs_node eeepc_wmi_debug_files[] = {
953 	{ NULL, "devs", show_devs },
954 	{ NULL, "dsts", show_dsts },
955 };
956 
957 static int eeepc_wmi_debugfs_open(struct inode *inode, struct file *file)
958 {
959 	struct eeepc_wmi_debugfs_node *node = inode->i_private;
960 
961 	return single_open(file, node->show, node->eeepc);
962 }
963 
964 static const struct file_operations eeepc_wmi_debugfs_io_ops = {
965 	.owner = THIS_MODULE,
966 	.open  = eeepc_wmi_debugfs_open,
967 	.read = seq_read,
968 	.llseek = seq_lseek,
969 	.release = single_release,
970 };
971 
972 static void eeepc_wmi_debugfs_exit(struct eeepc_wmi *eeepc)
973 {
974 	debugfs_remove_recursive(eeepc->debug.root);
975 }
976 
977 static int eeepc_wmi_debugfs_init(struct eeepc_wmi *eeepc)
978 {
979 	struct dentry *dent;
980 	int i;
981 
982 	eeepc->debug.root = debugfs_create_dir(EEEPC_WMI_FILE, NULL);
983 	if (!eeepc->debug.root) {
984 		pr_err("failed to create debugfs directory");
985 		goto error_debugfs;
986 	}
987 
988 	dent = debugfs_create_x32("dev_id", S_IRUGO|S_IWUSR,
989 				  eeepc->debug.root, &eeepc->debug.dev_id);
990 	if (!dent)
991 		goto error_debugfs;
992 
993 	dent = debugfs_create_x32("ctrl_param", S_IRUGO|S_IWUSR,
994 				  eeepc->debug.root, &eeepc->debug.ctrl_param);
995 	if (!dent)
996 		goto error_debugfs;
997 
998 	for (i = 0; i < ARRAY_SIZE(eeepc_wmi_debug_files); i++) {
999 		struct eeepc_wmi_debugfs_node *node = &eeepc_wmi_debug_files[i];
1000 
1001 		node->eeepc = eeepc;
1002 		dent = debugfs_create_file(node->name, S_IFREG | S_IRUGO,
1003 					   eeepc->debug.root, node,
1004 					   &eeepc_wmi_debugfs_io_ops);
1005 		if (!dent) {
1006 			pr_err("failed to create debug file: %s\n", node->name);
1007 			goto error_debugfs;
1008 		}
1009 	}
1010 
1011 	return 0;
1012 
1013 error_debugfs:
1014 	eeepc_wmi_debugfs_exit(eeepc);
1015 	return -ENOMEM;
1016 }
1017 
1018 /*
1019  * WMI Driver
1020  */
1021 static void eeepc_dmi_check(struct eeepc_wmi *eeepc)
1022 {
1023 	const char *model;
1024 
1025 	model = dmi_get_system_info(DMI_PRODUCT_NAME);
1026 	if (!model)
1027 		return;
1028 
1029 	/*
1030 	 * Whitelist for wlan hotplug
1031 	 *
1032 	 * Eeepc 1000H needs the current hotplug code to handle
1033 	 * Fn+F2 correctly. We may add other Eeepc here later, but
1034 	 * it seems that most of the laptops supported by eeepc-wmi
1035 	 * don't need to be on this list
1036 	 */
1037 	if (strcmp(model, "1000H") == 0) {
1038 		eeepc->hotplug_wireless = true;
1039 		pr_info("wlan hotplug enabled\n");
1040 	}
1041 }
1042 
1043 static struct platform_device * __init eeepc_wmi_add(void)
1044 {
1045 	struct eeepc_wmi *eeepc;
1046 	acpi_status status;
1047 	int err;
1048 
1049 	eeepc = kzalloc(sizeof(struct eeepc_wmi), GFP_KERNEL);
1050 	if (!eeepc)
1051 		return ERR_PTR(-ENOMEM);
1052 
1053 	eeepc->hotplug_wireless = hotplug_wireless;
1054 	eeepc_dmi_check(eeepc);
1055 
1056 	/*
1057 	 * Register the platform device first.  It is used as a parent for the
1058 	 * sub-devices below.
1059 	 */
1060 	err = eeepc_wmi_platform_init(eeepc);
1061 	if (err)
1062 		goto fail_platform;
1063 
1064 	err = eeepc_wmi_input_init(eeepc);
1065 	if (err)
1066 		goto fail_input;
1067 
1068 	err = eeepc_wmi_led_init(eeepc);
1069 	if (err)
1070 		goto fail_leds;
1071 
1072 	err = eeepc_wmi_rfkill_init(eeepc);
1073 	if (err)
1074 		goto fail_rfkill;
1075 
1076 	if (!acpi_video_backlight_support()) {
1077 		err = eeepc_wmi_backlight_init(eeepc);
1078 		if (err)
1079 			goto fail_backlight;
1080 	} else
1081 		pr_info("Backlight controlled by ACPI video driver\n");
1082 
1083 	status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID,
1084 					    eeepc_wmi_notify, eeepc);
1085 	if (ACPI_FAILURE(status)) {
1086 		pr_err("Unable to register notify handler - %d\n",
1087 			status);
1088 		err = -ENODEV;
1089 		goto fail_wmi_handler;
1090 	}
1091 
1092 	err = eeepc_wmi_debugfs_init(eeepc);
1093 	if (err)
1094 		goto fail_debugfs;
1095 
1096 	return eeepc->platform_device;
1097 
1098 fail_debugfs:
1099 	wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
1100 fail_wmi_handler:
1101 	eeepc_wmi_backlight_exit(eeepc);
1102 fail_backlight:
1103 	eeepc_wmi_rfkill_exit(eeepc);
1104 fail_rfkill:
1105 	eeepc_wmi_led_exit(eeepc);
1106 fail_leds:
1107 	eeepc_wmi_input_exit(eeepc);
1108 fail_input:
1109 	eeepc_wmi_platform_exit(eeepc);
1110 fail_platform:
1111 	kfree(eeepc);
1112 	return ERR_PTR(err);
1113 }
1114 
1115 static int eeepc_wmi_remove(struct platform_device *device)
1116 {
1117 	struct eeepc_wmi *eeepc;
1118 
1119 	eeepc = platform_get_drvdata(device);
1120 	wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
1121 	eeepc_wmi_backlight_exit(eeepc);
1122 	eeepc_wmi_input_exit(eeepc);
1123 	eeepc_wmi_led_exit(eeepc);
1124 	eeepc_wmi_rfkill_exit(eeepc);
1125 	eeepc_wmi_debugfs_exit(eeepc);
1126 	eeepc_wmi_platform_exit(eeepc);
1127 
1128 	kfree(eeepc);
1129 	return 0;
1130 }
1131 
1132 static struct platform_driver platform_driver = {
1133 	.driver = {
1134 		.name = EEEPC_WMI_FILE,
1135 		.owner = THIS_MODULE,
1136 	},
1137 };
1138 
1139 static acpi_status __init eeepc_wmi_parse_device(acpi_handle handle, u32 level,
1140 						 void *context, void **retval)
1141 {
1142 	pr_warning("Found legacy ATKD device (%s)", EEEPC_ACPI_HID);
1143 	*(bool *)context = true;
1144 	return AE_CTRL_TERMINATE;
1145 }
1146 
1147 static int __init eeepc_wmi_check_atkd(void)
1148 {
1149 	acpi_status status;
1150 	bool found = false;
1151 
1152 	status = acpi_get_devices(EEEPC_ACPI_HID, eeepc_wmi_parse_device,
1153 				  &found, NULL);
1154 
1155 	if (ACPI_FAILURE(status) || !found)
1156 		return 0;
1157 	return -1;
1158 }
1159 
1160 static int __init eeepc_wmi_init(void)
1161 {
1162 	int err;
1163 
1164 	if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID) ||
1165 	    !wmi_has_guid(EEEPC_WMI_MGMT_GUID)) {
1166 		pr_warning("No known WMI GUID found\n");
1167 		return -ENODEV;
1168 	}
1169 
1170 	if (eeepc_wmi_check_atkd()) {
1171 		pr_warning("WMI device present, but legacy ATKD device is also "
1172 			   "present and enabled.");
1173 		pr_warning("You probably booted with acpi_osi=\"Linux\" or "
1174 			   "acpi_osi=\"!Windows 2009\"");
1175 		pr_warning("Can't load eeepc-wmi, use default acpi_osi "
1176 			   "(preferred) or eeepc-laptop");
1177 		return -ENODEV;
1178 	}
1179 
1180 	platform_device = eeepc_wmi_add();
1181 	if (IS_ERR(platform_device)) {
1182 		err = PTR_ERR(platform_device);
1183 		goto fail_eeepc_wmi;
1184 	}
1185 
1186 	err = platform_driver_register(&platform_driver);
1187 	if (err) {
1188 		pr_warning("Unable to register platform driver\n");
1189 		goto fail_platform_driver;
1190 	}
1191 
1192 	return 0;
1193 
1194 fail_platform_driver:
1195 	eeepc_wmi_remove(platform_device);
1196 fail_eeepc_wmi:
1197 	return err;
1198 }
1199 
1200 static void __exit eeepc_wmi_exit(void)
1201 {
1202 	eeepc_wmi_remove(platform_device);
1203 	platform_driver_unregister(&platform_driver);
1204 }
1205 
1206 module_init(eeepc_wmi_init);
1207 module_exit(eeepc_wmi_exit);
1208