xref: /openbmc/linux/drivers/platform/x86/eeepc-laptop.c (revision baa7eb025ab14f3cba2e35c0a8648f9c9f01d24f)
1 /*
2  *  eeepc-laptop.c - Asus Eee PC extras
3  *
4  *  Based on asus_acpi.c as patched for the Eee PC by Asus:
5  *  ftp://ftp.asus.com/pub/ASUS/EeePC/701/ASUS_ACPI_071126.rar
6  *  Based on eee.c from eeepc-linux
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  */
18 
19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20 
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/init.h>
24 #include <linux/types.h>
25 #include <linux/platform_device.h>
26 #include <linux/backlight.h>
27 #include <linux/fb.h>
28 #include <linux/hwmon.h>
29 #include <linux/hwmon-sysfs.h>
30 #include <linux/slab.h>
31 #include <acpi/acpi_drivers.h>
32 #include <acpi/acpi_bus.h>
33 #include <linux/uaccess.h>
34 #include <linux/input.h>
35 #include <linux/input/sparse-keymap.h>
36 #include <linux/rfkill.h>
37 #include <linux/pci.h>
38 #include <linux/pci_hotplug.h>
39 #include <linux/leds.h>
40 #include <linux/dmi.h>
41 
42 #define EEEPC_LAPTOP_VERSION	"0.1"
43 #define EEEPC_LAPTOP_NAME	"Eee PC Hotkey Driver"
44 #define EEEPC_LAPTOP_FILE	"eeepc"
45 
46 #define EEEPC_ACPI_CLASS	"hotkey"
47 #define EEEPC_ACPI_DEVICE_NAME	"Hotkey"
48 #define EEEPC_ACPI_HID		"ASUS010"
49 
50 MODULE_AUTHOR("Corentin Chary, Eric Cooper");
51 MODULE_DESCRIPTION(EEEPC_LAPTOP_NAME);
52 MODULE_LICENSE("GPL");
53 
54 static bool hotplug_disabled;
55 
56 module_param(hotplug_disabled, bool, 0444);
57 MODULE_PARM_DESC(hotplug_disabled,
58 		 "Disable hotplug for wireless device. "
59 		 "If your laptop need that, please report to "
60 		 "acpi4asus-user@lists.sourceforge.net.");
61 
62 /*
63  * Definitions for Asus EeePC
64  */
65 #define NOTIFY_BRN_MIN	0x20
66 #define NOTIFY_BRN_MAX	0x2f
67 
68 enum {
69 	DISABLE_ASL_WLAN = 0x0001,
70 	DISABLE_ASL_BLUETOOTH = 0x0002,
71 	DISABLE_ASL_IRDA = 0x0004,
72 	DISABLE_ASL_CAMERA = 0x0008,
73 	DISABLE_ASL_TV = 0x0010,
74 	DISABLE_ASL_GPS = 0x0020,
75 	DISABLE_ASL_DISPLAYSWITCH = 0x0040,
76 	DISABLE_ASL_MODEM = 0x0080,
77 	DISABLE_ASL_CARDREADER = 0x0100,
78 	DISABLE_ASL_3G = 0x0200,
79 	DISABLE_ASL_WIMAX = 0x0400,
80 	DISABLE_ASL_HWCF = 0x0800
81 };
82 
83 enum {
84 	CM_ASL_WLAN = 0,
85 	CM_ASL_BLUETOOTH,
86 	CM_ASL_IRDA,
87 	CM_ASL_1394,
88 	CM_ASL_CAMERA,
89 	CM_ASL_TV,
90 	CM_ASL_GPS,
91 	CM_ASL_DVDROM,
92 	CM_ASL_DISPLAYSWITCH,
93 	CM_ASL_PANELBRIGHT,
94 	CM_ASL_BIOSFLASH,
95 	CM_ASL_ACPIFLASH,
96 	CM_ASL_CPUFV,
97 	CM_ASL_CPUTEMPERATURE,
98 	CM_ASL_FANCPU,
99 	CM_ASL_FANCHASSIS,
100 	CM_ASL_USBPORT1,
101 	CM_ASL_USBPORT2,
102 	CM_ASL_USBPORT3,
103 	CM_ASL_MODEM,
104 	CM_ASL_CARDREADER,
105 	CM_ASL_3G,
106 	CM_ASL_WIMAX,
107 	CM_ASL_HWCF,
108 	CM_ASL_LID,
109 	CM_ASL_TYPE,
110 	CM_ASL_PANELPOWER,	/*P901*/
111 	CM_ASL_TPD
112 };
113 
114 static const char *cm_getv[] = {
115 	"WLDG", "BTHG", NULL, NULL,
116 	"CAMG", NULL, NULL, NULL,
117 	NULL, "PBLG", NULL, NULL,
118 	"CFVG", NULL, NULL, NULL,
119 	"USBG", NULL, NULL, "MODG",
120 	"CRDG", "M3GG", "WIMG", "HWCF",
121 	"LIDG",	"TYPE", "PBPG",	"TPDG"
122 };
123 
124 static const char *cm_setv[] = {
125 	"WLDS", "BTHS", NULL, NULL,
126 	"CAMS", NULL, NULL, NULL,
127 	"SDSP", "PBLS", "HDPS", NULL,
128 	"CFVS", NULL, NULL, NULL,
129 	"USBG", NULL, NULL, "MODS",
130 	"CRDS", "M3GS", "WIMS", NULL,
131 	NULL, NULL, "PBPS", "TPDS"
132 };
133 
134 static const struct key_entry eeepc_keymap[] = {
135 	{ KE_KEY, 0x10, { KEY_WLAN } },
136 	{ KE_KEY, 0x11, { KEY_WLAN } },
137 	{ KE_KEY, 0x12, { KEY_PROG1 } },
138 	{ KE_KEY, 0x13, { KEY_MUTE } },
139 	{ KE_KEY, 0x14, { KEY_VOLUMEDOWN } },
140 	{ KE_KEY, 0x15, { KEY_VOLUMEUP } },
141 	{ KE_KEY, 0x16, { KEY_DISPLAY_OFF } },
142 	{ KE_KEY, 0x1a, { KEY_COFFEE } },
143 	{ KE_KEY, 0x1b, { KEY_ZOOM } },
144 	{ KE_KEY, 0x1c, { KEY_PROG2 } },
145 	{ KE_KEY, 0x1d, { KEY_PROG3 } },
146 	{ KE_KEY, NOTIFY_BRN_MIN, { KEY_BRIGHTNESSDOWN } },
147 	{ KE_KEY, NOTIFY_BRN_MAX, { KEY_BRIGHTNESSUP } },
148 	{ KE_KEY, 0x30, { KEY_SWITCHVIDEOMODE } },
149 	{ KE_KEY, 0x31, { KEY_SWITCHVIDEOMODE } },
150 	{ KE_KEY, 0x32, { KEY_SWITCHVIDEOMODE } },
151 	{ KE_KEY, 0x37, { KEY_F13 } }, /* Disable Touchpad */
152 	{ KE_KEY, 0x38, { KEY_F14 } },
153 	{ KE_END, 0 },
154 };
155 
156 /*
157  * This is the main structure, we can use it to store useful information
158  */
159 struct eeepc_laptop {
160 	acpi_handle handle;		/* the handle of the acpi device */
161 	u32 cm_supported;		/* the control methods supported
162 					   by this BIOS */
163 	bool cpufv_disabled;
164 	bool hotplug_disabled;
165 	u16 event_count[128];		/* count for each event */
166 
167 	struct platform_device *platform_device;
168 	struct acpi_device *device;		/* the device we are in */
169 	struct device *hwmon_device;
170 	struct backlight_device *backlight_device;
171 
172 	struct input_dev *inputdev;
173 
174 	struct rfkill *wlan_rfkill;
175 	struct rfkill *bluetooth_rfkill;
176 	struct rfkill *wwan3g_rfkill;
177 	struct rfkill *wimax_rfkill;
178 
179 	struct hotplug_slot *hotplug_slot;
180 	struct mutex hotplug_lock;
181 
182 	struct led_classdev tpd_led;
183 	int tpd_led_wk;
184 	struct workqueue_struct *led_workqueue;
185 	struct work_struct tpd_led_work;
186 };
187 
188 /*
189  * ACPI Helpers
190  */
191 static int write_acpi_int(acpi_handle handle, const char *method, int val)
192 {
193 	struct acpi_object_list params;
194 	union acpi_object in_obj;
195 	acpi_status status;
196 
197 	params.count = 1;
198 	params.pointer = &in_obj;
199 	in_obj.type = ACPI_TYPE_INTEGER;
200 	in_obj.integer.value = val;
201 
202 	status = acpi_evaluate_object(handle, (char *)method, &params, NULL);
203 	return (status == AE_OK ? 0 : -1);
204 }
205 
206 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
207 {
208 	acpi_status status;
209 	unsigned long long result;
210 
211 	status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
212 	if (ACPI_FAILURE(status)) {
213 		*val = -1;
214 		return -1;
215 	} else {
216 		*val = result;
217 		return 0;
218 	}
219 }
220 
221 static int set_acpi(struct eeepc_laptop *eeepc, int cm, int value)
222 {
223 	const char *method = cm_setv[cm];
224 
225 	if (method == NULL)
226 		return -ENODEV;
227 	if ((eeepc->cm_supported & (0x1 << cm)) == 0)
228 		return -ENODEV;
229 
230 	if (write_acpi_int(eeepc->handle, method, value))
231 		pr_warning("Error writing %s\n", method);
232 	return 0;
233 }
234 
235 static int get_acpi(struct eeepc_laptop *eeepc, int cm)
236 {
237 	const char *method = cm_getv[cm];
238 	int value;
239 
240 	if (method == NULL)
241 		return -ENODEV;
242 	if ((eeepc->cm_supported & (0x1 << cm)) == 0)
243 		return -ENODEV;
244 
245 	if (read_acpi_int(eeepc->handle, method, &value))
246 		pr_warning("Error reading %s\n", method);
247 	return value;
248 }
249 
250 static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm,
251 			      acpi_handle *handle)
252 {
253 	const char *method = cm_setv[cm];
254 	acpi_status status;
255 
256 	if (method == NULL)
257 		return -ENODEV;
258 	if ((eeepc->cm_supported & (0x1 << cm)) == 0)
259 		return -ENODEV;
260 
261 	status = acpi_get_handle(eeepc->handle, (char *)method,
262 				 handle);
263 	if (status != AE_OK) {
264 		pr_warning("Error finding %s\n", method);
265 		return -ENODEV;
266 	}
267 	return 0;
268 }
269 
270 
271 /*
272  * Sys helpers
273  */
274 static int parse_arg(const char *buf, unsigned long count, int *val)
275 {
276 	if (!count)
277 		return 0;
278 	if (sscanf(buf, "%i", val) != 1)
279 		return -EINVAL;
280 	return count;
281 }
282 
283 static ssize_t store_sys_acpi(struct device *dev, int cm,
284 			      const char *buf, size_t count)
285 {
286 	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
287 	int rv, value;
288 
289 	rv = parse_arg(buf, count, &value);
290 	if (rv > 0)
291 		value = set_acpi(eeepc, cm, value);
292 	if (value < 0)
293 		return -EIO;
294 	return rv;
295 }
296 
297 static ssize_t show_sys_acpi(struct device *dev, int cm, char *buf)
298 {
299 	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
300 	int value = get_acpi(eeepc, cm);
301 
302 	if (value < 0)
303 		return -EIO;
304 	return sprintf(buf, "%d\n", value);
305 }
306 
307 #define EEEPC_CREATE_DEVICE_ATTR(_name, _mode, _cm)			\
308 	static ssize_t show_##_name(struct device *dev,			\
309 				    struct device_attribute *attr,	\
310 				    char *buf)				\
311 	{								\
312 		return show_sys_acpi(dev, _cm, buf);			\
313 	}								\
314 	static ssize_t store_##_name(struct device *dev,		\
315 				     struct device_attribute *attr,	\
316 				     const char *buf, size_t count)	\
317 	{								\
318 		return store_sys_acpi(dev, _cm, buf, count);		\
319 	}								\
320 	static struct device_attribute dev_attr_##_name = {		\
321 		.attr = {						\
322 			.name = __stringify(_name),			\
323 			.mode = _mode },				\
324 		.show   = show_##_name,					\
325 		.store  = store_##_name,				\
326 	}
327 
328 EEEPC_CREATE_DEVICE_ATTR(camera, 0644, CM_ASL_CAMERA);
329 EEEPC_CREATE_DEVICE_ATTR(cardr, 0644, CM_ASL_CARDREADER);
330 EEEPC_CREATE_DEVICE_ATTR(disp, 0200, CM_ASL_DISPLAYSWITCH);
331 
332 struct eeepc_cpufv {
333 	int num;
334 	int cur;
335 };
336 
337 static int get_cpufv(struct eeepc_laptop *eeepc, struct eeepc_cpufv *c)
338 {
339 	c->cur = get_acpi(eeepc, CM_ASL_CPUFV);
340 	c->num = (c->cur >> 8) & 0xff;
341 	c->cur &= 0xff;
342 	if (c->cur < 0 || c->num <= 0 || c->num > 12)
343 		return -ENODEV;
344 	return 0;
345 }
346 
347 static ssize_t show_available_cpufv(struct device *dev,
348 				    struct device_attribute *attr,
349 				    char *buf)
350 {
351 	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
352 	struct eeepc_cpufv c;
353 	int i;
354 	ssize_t len = 0;
355 
356 	if (get_cpufv(eeepc, &c))
357 		return -ENODEV;
358 	for (i = 0; i < c.num; i++)
359 		len += sprintf(buf + len, "%d ", i);
360 	len += sprintf(buf + len, "\n");
361 	return len;
362 }
363 
364 static ssize_t show_cpufv(struct device *dev,
365 			  struct device_attribute *attr,
366 			  char *buf)
367 {
368 	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
369 	struct eeepc_cpufv c;
370 
371 	if (get_cpufv(eeepc, &c))
372 		return -ENODEV;
373 	return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
374 }
375 
376 static ssize_t store_cpufv(struct device *dev,
377 			   struct device_attribute *attr,
378 			   const char *buf, size_t count)
379 {
380 	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
381 	struct eeepc_cpufv c;
382 	int rv, value;
383 
384 	if (eeepc->cpufv_disabled)
385 		return -EPERM;
386 	if (get_cpufv(eeepc, &c))
387 		return -ENODEV;
388 	rv = parse_arg(buf, count, &value);
389 	if (rv < 0)
390 		return rv;
391 	if (!rv || value < 0 || value >= c.num)
392 		return -EINVAL;
393 	set_acpi(eeepc, CM_ASL_CPUFV, value);
394 	return rv;
395 }
396 
397 static ssize_t show_cpufv_disabled(struct device *dev,
398 			  struct device_attribute *attr,
399 			  char *buf)
400 {
401 	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
402 
403 	return sprintf(buf, "%d\n", eeepc->cpufv_disabled);
404 }
405 
406 static ssize_t store_cpufv_disabled(struct device *dev,
407 			   struct device_attribute *attr,
408 			   const char *buf, size_t count)
409 {
410 	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
411 	int rv, value;
412 
413 	rv = parse_arg(buf, count, &value);
414 	if (rv < 0)
415 		return rv;
416 
417 	switch (value) {
418 	case 0:
419 		if (eeepc->cpufv_disabled)
420 			pr_warning("cpufv enabled (not officially supported "
421 				"on this model)\n");
422 		eeepc->cpufv_disabled = false;
423 		return rv;
424 	case 1:
425 		return -EPERM;
426 	default:
427 		return -EINVAL;
428 	}
429 }
430 
431 
432 static struct device_attribute dev_attr_cpufv = {
433 	.attr = {
434 		.name = "cpufv",
435 		.mode = 0644 },
436 	.show   = show_cpufv,
437 	.store  = store_cpufv
438 };
439 
440 static struct device_attribute dev_attr_available_cpufv = {
441 	.attr = {
442 		.name = "available_cpufv",
443 		.mode = 0444 },
444 	.show   = show_available_cpufv
445 };
446 
447 static struct device_attribute dev_attr_cpufv_disabled = {
448 	.attr = {
449 		.name = "cpufv_disabled",
450 		.mode = 0644 },
451 	.show   = show_cpufv_disabled,
452 	.store  = store_cpufv_disabled
453 };
454 
455 
456 static struct attribute *platform_attributes[] = {
457 	&dev_attr_camera.attr,
458 	&dev_attr_cardr.attr,
459 	&dev_attr_disp.attr,
460 	&dev_attr_cpufv.attr,
461 	&dev_attr_available_cpufv.attr,
462 	&dev_attr_cpufv_disabled.attr,
463 	NULL
464 };
465 
466 static struct attribute_group platform_attribute_group = {
467 	.attrs = platform_attributes
468 };
469 
470 static int eeepc_platform_init(struct eeepc_laptop *eeepc)
471 {
472 	int result;
473 
474 	eeepc->platform_device = platform_device_alloc(EEEPC_LAPTOP_FILE, -1);
475 	if (!eeepc->platform_device)
476 		return -ENOMEM;
477 	platform_set_drvdata(eeepc->platform_device, eeepc);
478 
479 	result = platform_device_add(eeepc->platform_device);
480 	if (result)
481 		goto fail_platform_device;
482 
483 	result = sysfs_create_group(&eeepc->platform_device->dev.kobj,
484 				    &platform_attribute_group);
485 	if (result)
486 		goto fail_sysfs;
487 	return 0;
488 
489 fail_sysfs:
490 	platform_device_del(eeepc->platform_device);
491 fail_platform_device:
492 	platform_device_put(eeepc->platform_device);
493 	return result;
494 }
495 
496 static void eeepc_platform_exit(struct eeepc_laptop *eeepc)
497 {
498 	sysfs_remove_group(&eeepc->platform_device->dev.kobj,
499 			   &platform_attribute_group);
500 	platform_device_unregister(eeepc->platform_device);
501 }
502 
503 /*
504  * LEDs
505  */
506 /*
507  * These functions actually update the LED's, and are called from a
508  * workqueue. By doing this as separate work rather than when the LED
509  * subsystem asks, we avoid messing with the Asus ACPI stuff during a
510  * potentially bad time, such as a timer interrupt.
511  */
512 static void tpd_led_update(struct work_struct *work)
513  {
514 	struct eeepc_laptop *eeepc;
515 
516 	eeepc = container_of(work, struct eeepc_laptop, tpd_led_work);
517 
518 	set_acpi(eeepc, CM_ASL_TPD, eeepc->tpd_led_wk);
519 }
520 
521 static void tpd_led_set(struct led_classdev *led_cdev,
522 			enum led_brightness value)
523 {
524 	struct eeepc_laptop *eeepc;
525 
526 	eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
527 
528 	eeepc->tpd_led_wk = (value > 0) ? 1 : 0;
529 	queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
530 }
531 
532 static int eeepc_led_init(struct eeepc_laptop *eeepc)
533 {
534 	int rv;
535 
536 	if (get_acpi(eeepc, CM_ASL_TPD) == -ENODEV)
537 		return 0;
538 
539 	eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
540 	if (!eeepc->led_workqueue)
541 		return -ENOMEM;
542 	INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);
543 
544 	eeepc->tpd_led.name = "eeepc::touchpad";
545 	eeepc->tpd_led.brightness_set = tpd_led_set;
546 	eeepc->tpd_led.max_brightness = 1;
547 
548 	rv = led_classdev_register(&eeepc->platform_device->dev,
549 				   &eeepc->tpd_led);
550 	if (rv) {
551 		destroy_workqueue(eeepc->led_workqueue);
552 		return rv;
553 	}
554 
555 	return 0;
556 }
557 
558 static void eeepc_led_exit(struct eeepc_laptop *eeepc)
559 {
560 	if (eeepc->tpd_led.dev)
561 		led_classdev_unregister(&eeepc->tpd_led);
562 	if (eeepc->led_workqueue)
563 		destroy_workqueue(eeepc->led_workqueue);
564 }
565 
566 
567 /*
568  * PCI hotplug (for wlan rfkill)
569  */
570 static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc)
571 {
572 	if (get_acpi(eeepc, CM_ASL_WLAN) == 1)
573 		return false;
574 	return true;
575 }
576 
577 static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc)
578 {
579 	struct pci_dev *dev;
580 	struct pci_bus *bus;
581 	bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
582 	bool absent;
583 	u32 l;
584 
585 	if (eeepc->wlan_rfkill)
586 		rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
587 
588 	mutex_lock(&eeepc->hotplug_lock);
589 
590 	if (eeepc->hotplug_slot) {
591 		bus = pci_find_bus(0, 1);
592 		if (!bus) {
593 			pr_warning("Unable to find PCI bus 1?\n");
594 			goto out_unlock;
595 		}
596 
597 		if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
598 			pr_err("Unable to read PCI config space?\n");
599 			goto out_unlock;
600 		}
601 		absent = (l == 0xffffffff);
602 
603 		if (blocked != absent) {
604 			pr_warning("BIOS says wireless lan is %s, "
605 					"but the pci device is %s\n",
606 				blocked ? "blocked" : "unblocked",
607 				absent ? "absent" : "present");
608 			pr_warning("skipped wireless hotplug as probably "
609 					"inappropriate for this model\n");
610 			goto out_unlock;
611 		}
612 
613 		if (!blocked) {
614 			dev = pci_get_slot(bus, 0);
615 			if (dev) {
616 				/* Device already present */
617 				pci_dev_put(dev);
618 				goto out_unlock;
619 			}
620 			dev = pci_scan_single_device(bus, 0);
621 			if (dev) {
622 				pci_bus_assign_resources(bus);
623 				if (pci_bus_add_device(dev))
624 					pr_err("Unable to hotplug wifi\n");
625 			}
626 		} else {
627 			dev = pci_get_slot(bus, 0);
628 			if (dev) {
629 				pci_remove_bus_device(dev);
630 				pci_dev_put(dev);
631 			}
632 		}
633 	}
634 
635 out_unlock:
636 	mutex_unlock(&eeepc->hotplug_lock);
637 }
638 
639 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
640 {
641 	struct eeepc_laptop *eeepc = data;
642 
643 	if (event != ACPI_NOTIFY_BUS_CHECK)
644 		return;
645 
646 	eeepc_rfkill_hotplug(eeepc);
647 }
648 
649 static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
650 					  char *node)
651 {
652 	acpi_status status;
653 	acpi_handle handle;
654 
655 	status = acpi_get_handle(NULL, node, &handle);
656 
657 	if (ACPI_SUCCESS(status)) {
658 		status = acpi_install_notify_handler(handle,
659 						     ACPI_SYSTEM_NOTIFY,
660 						     eeepc_rfkill_notify,
661 						     eeepc);
662 		if (ACPI_FAILURE(status))
663 			pr_warning("Failed to register notify on %s\n", node);
664 	} else
665 		return -ENODEV;
666 
667 	return 0;
668 }
669 
670 static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
671 					     char *node)
672 {
673 	acpi_status status = AE_OK;
674 	acpi_handle handle;
675 
676 	status = acpi_get_handle(NULL, node, &handle);
677 
678 	if (ACPI_SUCCESS(status)) {
679 		status = acpi_remove_notify_handler(handle,
680 						     ACPI_SYSTEM_NOTIFY,
681 						     eeepc_rfkill_notify);
682 		if (ACPI_FAILURE(status))
683 			pr_err("Error removing rfkill notify handler %s\n",
684 				node);
685 	}
686 }
687 
688 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
689 				    u8 *value)
690 {
691 	struct eeepc_laptop *eeepc = hotplug_slot->private;
692 	int val = get_acpi(eeepc, CM_ASL_WLAN);
693 
694 	if (val == 1 || val == 0)
695 		*value = val;
696 	else
697 		return -EINVAL;
698 
699 	return 0;
700 }
701 
702 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
703 {
704 	kfree(hotplug_slot->info);
705 	kfree(hotplug_slot);
706 }
707 
708 static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
709 	.owner = THIS_MODULE,
710 	.get_adapter_status = eeepc_get_adapter_status,
711 	.get_power_status = eeepc_get_adapter_status,
712 };
713 
714 static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
715 {
716 	int ret = -ENOMEM;
717 	struct pci_bus *bus = pci_find_bus(0, 1);
718 
719 	if (!bus) {
720 		pr_err("Unable to find wifi PCI bus\n");
721 		return -ENODEV;
722 	}
723 
724 	eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
725 	if (!eeepc->hotplug_slot)
726 		goto error_slot;
727 
728 	eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
729 					    GFP_KERNEL);
730 	if (!eeepc->hotplug_slot->info)
731 		goto error_info;
732 
733 	eeepc->hotplug_slot->private = eeepc;
734 	eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
735 	eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
736 	eeepc_get_adapter_status(eeepc->hotplug_slot,
737 				 &eeepc->hotplug_slot->info->adapter_status);
738 
739 	ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
740 	if (ret) {
741 		pr_err("Unable to register hotplug slot - %d\n", ret);
742 		goto error_register;
743 	}
744 
745 	return 0;
746 
747 error_register:
748 	kfree(eeepc->hotplug_slot->info);
749 error_info:
750 	kfree(eeepc->hotplug_slot);
751 	eeepc->hotplug_slot = NULL;
752 error_slot:
753 	return ret;
754 }
755 
756 /*
757  * Rfkill devices
758  */
759 static int eeepc_rfkill_set(void *data, bool blocked)
760 {
761 	acpi_handle handle = data;
762 
763 	return write_acpi_int(handle, NULL, !blocked);
764 }
765 
766 static const struct rfkill_ops eeepc_rfkill_ops = {
767 	.set_block = eeepc_rfkill_set,
768 };
769 
770 static int eeepc_new_rfkill(struct eeepc_laptop *eeepc,
771 			    struct rfkill **rfkill,
772 			    const char *name,
773 			    enum rfkill_type type, int cm)
774 {
775 	acpi_handle handle;
776 	int result;
777 
778 	result = acpi_setter_handle(eeepc, cm, &handle);
779 	if (result < 0)
780 		return result;
781 
782 	*rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
783 			       &eeepc_rfkill_ops, handle);
784 
785 	if (!*rfkill)
786 		return -EINVAL;
787 
788 	rfkill_init_sw_state(*rfkill, get_acpi(eeepc, cm) != 1);
789 	result = rfkill_register(*rfkill);
790 	if (result) {
791 		rfkill_destroy(*rfkill);
792 		*rfkill = NULL;
793 		return result;
794 	}
795 	return 0;
796 }
797 
798 static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
799 {
800 	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
801 	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
802 	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
803 	if (eeepc->wlan_rfkill) {
804 		rfkill_unregister(eeepc->wlan_rfkill);
805 		rfkill_destroy(eeepc->wlan_rfkill);
806 		eeepc->wlan_rfkill = NULL;
807 	}
808 	/*
809 	 * Refresh pci hotplug in case the rfkill state was changed after
810 	 * eeepc_unregister_rfkill_notifier()
811 	 */
812 	eeepc_rfkill_hotplug(eeepc);
813 	if (eeepc->hotplug_slot)
814 		pci_hp_deregister(eeepc->hotplug_slot);
815 
816 	if (eeepc->bluetooth_rfkill) {
817 		rfkill_unregister(eeepc->bluetooth_rfkill);
818 		rfkill_destroy(eeepc->bluetooth_rfkill);
819 		eeepc->bluetooth_rfkill = NULL;
820 	}
821 	if (eeepc->wwan3g_rfkill) {
822 		rfkill_unregister(eeepc->wwan3g_rfkill);
823 		rfkill_destroy(eeepc->wwan3g_rfkill);
824 		eeepc->wwan3g_rfkill = NULL;
825 	}
826 	if (eeepc->wimax_rfkill) {
827 		rfkill_unregister(eeepc->wimax_rfkill);
828 		rfkill_destroy(eeepc->wimax_rfkill);
829 		eeepc->wimax_rfkill = NULL;
830 	}
831 }
832 
833 static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
834 {
835 	int result = 0;
836 
837 	mutex_init(&eeepc->hotplug_lock);
838 
839 	result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
840 				  "eeepc-wlan", RFKILL_TYPE_WLAN,
841 				  CM_ASL_WLAN);
842 
843 	if (result && result != -ENODEV)
844 		goto exit;
845 
846 	result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
847 				  "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
848 				  CM_ASL_BLUETOOTH);
849 
850 	if (result && result != -ENODEV)
851 		goto exit;
852 
853 	result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
854 				  "eeepc-wwan3g", RFKILL_TYPE_WWAN,
855 				  CM_ASL_3G);
856 
857 	if (result && result != -ENODEV)
858 		goto exit;
859 
860 	result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
861 				  "eeepc-wimax", RFKILL_TYPE_WIMAX,
862 				  CM_ASL_WIMAX);
863 
864 	if (result && result != -ENODEV)
865 		goto exit;
866 
867 	if (eeepc->hotplug_disabled)
868 		return 0;
869 
870 	result = eeepc_setup_pci_hotplug(eeepc);
871 	/*
872 	 * If we get -EBUSY then something else is handling the PCI hotplug -
873 	 * don't fail in this case
874 	 */
875 	if (result == -EBUSY)
876 		result = 0;
877 
878 	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
879 	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
880 	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
881 	/*
882 	 * Refresh pci hotplug in case the rfkill state was changed during
883 	 * setup.
884 	 */
885 	eeepc_rfkill_hotplug(eeepc);
886 
887 exit:
888 	if (result && result != -ENODEV)
889 		eeepc_rfkill_exit(eeepc);
890 	return result;
891 }
892 
893 /*
894  * Platform driver - hibernate/resume callbacks
895  */
896 static int eeepc_hotk_thaw(struct device *device)
897 {
898 	struct eeepc_laptop *eeepc = dev_get_drvdata(device);
899 
900 	if (eeepc->wlan_rfkill) {
901 		bool wlan;
902 
903 		/*
904 		 * Work around bios bug - acpi _PTS turns off the wireless led
905 		 * during suspend.  Normally it restores it on resume, but
906 		 * we should kick it ourselves in case hibernation is aborted.
907 		 */
908 		wlan = get_acpi(eeepc, CM_ASL_WLAN);
909 		set_acpi(eeepc, CM_ASL_WLAN, wlan);
910 	}
911 
912 	return 0;
913 }
914 
915 static int eeepc_hotk_restore(struct device *device)
916 {
917 	struct eeepc_laptop *eeepc = dev_get_drvdata(device);
918 
919 	/* Refresh both wlan rfkill state and pci hotplug */
920 	if (eeepc->wlan_rfkill)
921 		eeepc_rfkill_hotplug(eeepc);
922 
923 	if (eeepc->bluetooth_rfkill)
924 		rfkill_set_sw_state(eeepc->bluetooth_rfkill,
925 				    get_acpi(eeepc, CM_ASL_BLUETOOTH) != 1);
926 	if (eeepc->wwan3g_rfkill)
927 		rfkill_set_sw_state(eeepc->wwan3g_rfkill,
928 				    get_acpi(eeepc, CM_ASL_3G) != 1);
929 	if (eeepc->wimax_rfkill)
930 		rfkill_set_sw_state(eeepc->wimax_rfkill,
931 				    get_acpi(eeepc, CM_ASL_WIMAX) != 1);
932 
933 	return 0;
934 }
935 
936 static const struct dev_pm_ops eeepc_pm_ops = {
937 	.thaw = eeepc_hotk_thaw,
938 	.restore = eeepc_hotk_restore,
939 };
940 
941 static struct platform_driver platform_driver = {
942 	.driver = {
943 		.name = EEEPC_LAPTOP_FILE,
944 		.owner = THIS_MODULE,
945 		.pm = &eeepc_pm_ops,
946 	}
947 };
948 
949 /*
950  * Hwmon device
951  */
952 
953 #define EEEPC_EC_SC00      0x61
954 #define EEEPC_EC_FAN_PWM   (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */
955 #define EEEPC_EC_FAN_HRPM  (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */
956 #define EEEPC_EC_FAN_LRPM  (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */
957 
958 #define EEEPC_EC_SFB0      0xD0
959 #define EEEPC_EC_FAN_CTRL  (EEEPC_EC_SFB0 + 3) /* Byte containing SF25  */
960 
961 static int eeepc_get_fan_pwm(void)
962 {
963 	u8 value = 0;
964 
965 	ec_read(EEEPC_EC_FAN_PWM, &value);
966 	return value * 255 / 100;
967 }
968 
969 static void eeepc_set_fan_pwm(int value)
970 {
971 	value = SENSORS_LIMIT(value, 0, 255);
972 	value = value * 100 / 255;
973 	ec_write(EEEPC_EC_FAN_PWM, value);
974 }
975 
976 static int eeepc_get_fan_rpm(void)
977 {
978 	u8 high = 0;
979 	u8 low = 0;
980 
981 	ec_read(EEEPC_EC_FAN_HRPM, &high);
982 	ec_read(EEEPC_EC_FAN_LRPM, &low);
983 	return high << 8 | low;
984 }
985 
986 static int eeepc_get_fan_ctrl(void)
987 {
988 	u8 value = 0;
989 
990 	ec_read(EEEPC_EC_FAN_CTRL, &value);
991 	if (value & 0x02)
992 		return 1; /* manual */
993 	else
994 		return 2; /* automatic */
995 }
996 
997 static void eeepc_set_fan_ctrl(int manual)
998 {
999 	u8 value = 0;
1000 
1001 	ec_read(EEEPC_EC_FAN_CTRL, &value);
1002 	if (manual == 1)
1003 		value |= 0x02;
1004 	else
1005 		value &= ~0x02;
1006 	ec_write(EEEPC_EC_FAN_CTRL, value);
1007 }
1008 
1009 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
1010 {
1011 	int rv, value;
1012 
1013 	rv = parse_arg(buf, count, &value);
1014 	if (rv > 0)
1015 		set(value);
1016 	return rv;
1017 }
1018 
1019 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
1020 {
1021 	return sprintf(buf, "%d\n", get());
1022 }
1023 
1024 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get)		\
1025 	static ssize_t show_##_name(struct device *dev,			\
1026 				    struct device_attribute *attr,	\
1027 				    char *buf)				\
1028 	{								\
1029 		return show_sys_hwmon(_set, buf);			\
1030 	}								\
1031 	static ssize_t store_##_name(struct device *dev,		\
1032 				     struct device_attribute *attr,	\
1033 				     const char *buf, size_t count)	\
1034 	{								\
1035 		return store_sys_hwmon(_get, buf, count);		\
1036 	}								\
1037 	static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
1038 
1039 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
1040 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
1041 			 eeepc_get_fan_pwm, eeepc_set_fan_pwm);
1042 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
1043 			 eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
1044 
1045 static ssize_t
1046 show_name(struct device *dev, struct device_attribute *attr, char *buf)
1047 {
1048 	return sprintf(buf, "eeepc\n");
1049 }
1050 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
1051 
1052 static struct attribute *hwmon_attributes[] = {
1053 	&sensor_dev_attr_pwm1.dev_attr.attr,
1054 	&sensor_dev_attr_fan1_input.dev_attr.attr,
1055 	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
1056 	&sensor_dev_attr_name.dev_attr.attr,
1057 	NULL
1058 };
1059 
1060 static struct attribute_group hwmon_attribute_group = {
1061 	.attrs = hwmon_attributes
1062 };
1063 
1064 static void eeepc_hwmon_exit(struct eeepc_laptop *eeepc)
1065 {
1066 	struct device *hwmon;
1067 
1068 	hwmon = eeepc->hwmon_device;
1069 	if (!hwmon)
1070 		return;
1071 	sysfs_remove_group(&hwmon->kobj,
1072 			   &hwmon_attribute_group);
1073 	hwmon_device_unregister(hwmon);
1074 	eeepc->hwmon_device = NULL;
1075 }
1076 
1077 static int eeepc_hwmon_init(struct eeepc_laptop *eeepc)
1078 {
1079 	struct device *hwmon;
1080 	int result;
1081 
1082 	hwmon = hwmon_device_register(&eeepc->platform_device->dev);
1083 	if (IS_ERR(hwmon)) {
1084 		pr_err("Could not register eeepc hwmon device\n");
1085 		eeepc->hwmon_device = NULL;
1086 		return PTR_ERR(hwmon);
1087 	}
1088 	eeepc->hwmon_device = hwmon;
1089 	result = sysfs_create_group(&hwmon->kobj,
1090 				    &hwmon_attribute_group);
1091 	if (result)
1092 		eeepc_hwmon_exit(eeepc);
1093 	return result;
1094 }
1095 
1096 /*
1097  * Backlight device
1098  */
1099 static int read_brightness(struct backlight_device *bd)
1100 {
1101 	struct eeepc_laptop *eeepc = bl_get_data(bd);
1102 
1103 	return get_acpi(eeepc, CM_ASL_PANELBRIGHT);
1104 }
1105 
1106 static int set_brightness(struct backlight_device *bd, int value)
1107 {
1108 	struct eeepc_laptop *eeepc = bl_get_data(bd);
1109 
1110 	return set_acpi(eeepc, CM_ASL_PANELBRIGHT, value);
1111 }
1112 
1113 static int update_bl_status(struct backlight_device *bd)
1114 {
1115 	return set_brightness(bd, bd->props.brightness);
1116 }
1117 
1118 static struct backlight_ops eeepcbl_ops = {
1119 	.get_brightness = read_brightness,
1120 	.update_status = update_bl_status,
1121 };
1122 
1123 static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
1124 {
1125 	struct backlight_device *bd = eeepc->backlight_device;
1126 	int old = bd->props.brightness;
1127 
1128 	backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
1129 
1130 	return old;
1131 }
1132 
1133 static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
1134 {
1135 	struct backlight_properties props;
1136 	struct backlight_device *bd;
1137 
1138 	memset(&props, 0, sizeof(struct backlight_properties));
1139 	props.max_brightness = 15;
1140 	bd = backlight_device_register(EEEPC_LAPTOP_FILE,
1141 				       &eeepc->platform_device->dev, eeepc,
1142 				       &eeepcbl_ops, &props);
1143 	if (IS_ERR(bd)) {
1144 		pr_err("Could not register eeepc backlight device\n");
1145 		eeepc->backlight_device = NULL;
1146 		return PTR_ERR(bd);
1147 	}
1148 	eeepc->backlight_device = bd;
1149 	bd->props.brightness = read_brightness(bd);
1150 	bd->props.power = FB_BLANK_UNBLANK;
1151 	backlight_update_status(bd);
1152 	return 0;
1153 }
1154 
1155 static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
1156 {
1157 	if (eeepc->backlight_device)
1158 		backlight_device_unregister(eeepc->backlight_device);
1159 	eeepc->backlight_device = NULL;
1160 }
1161 
1162 
1163 /*
1164  * Input device (i.e. hotkeys)
1165  */
1166 static int eeepc_input_init(struct eeepc_laptop *eeepc)
1167 {
1168 	struct input_dev *input;
1169 	int error;
1170 
1171 	input = input_allocate_device();
1172 	if (!input) {
1173 		pr_info("Unable to allocate input device\n");
1174 		return -ENOMEM;
1175 	}
1176 
1177 	input->name = "Asus EeePC extra buttons";
1178 	input->phys = EEEPC_LAPTOP_FILE "/input0";
1179 	input->id.bustype = BUS_HOST;
1180 	input->dev.parent = &eeepc->platform_device->dev;
1181 
1182 	error = sparse_keymap_setup(input, eeepc_keymap, NULL);
1183 	if (error) {
1184 		pr_err("Unable to setup input device keymap\n");
1185 		goto err_free_dev;
1186 	}
1187 
1188 	error = input_register_device(input);
1189 	if (error) {
1190 		pr_err("Unable to register input device\n");
1191 		goto err_free_keymap;
1192 	}
1193 
1194 	eeepc->inputdev = input;
1195 	return 0;
1196 
1197 err_free_keymap:
1198 	sparse_keymap_free(input);
1199 err_free_dev:
1200 	input_free_device(input);
1201 	return error;
1202 }
1203 
1204 static void eeepc_input_exit(struct eeepc_laptop *eeepc)
1205 {
1206 	if (eeepc->inputdev) {
1207 		sparse_keymap_free(eeepc->inputdev);
1208 		input_unregister_device(eeepc->inputdev);
1209 	}
1210 	eeepc->inputdev = NULL;
1211 }
1212 
1213 /*
1214  * ACPI driver
1215  */
1216 static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
1217 {
1218 	struct eeepc_laptop *eeepc = acpi_driver_data(device);
1219 	u16 count;
1220 
1221 	if (event > ACPI_MAX_SYS_NOTIFY)
1222 		return;
1223 	count = eeepc->event_count[event % 128]++;
1224 	acpi_bus_generate_proc_event(device, event, count);
1225 	acpi_bus_generate_netlink_event(device->pnp.device_class,
1226 					dev_name(&device->dev), event,
1227 					count);
1228 
1229 	/* Brightness events are special */
1230 	if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) {
1231 
1232 		/* Ignore them completely if the acpi video driver is used */
1233 		if (eeepc->backlight_device != NULL) {
1234 			int old_brightness, new_brightness;
1235 
1236 			/* Update the backlight device. */
1237 			old_brightness = eeepc_backlight_notify(eeepc);
1238 
1239 			/* Convert event to keypress (obsolescent hack) */
1240 			new_brightness = event - NOTIFY_BRN_MIN;
1241 
1242 			if (new_brightness < old_brightness) {
1243 				event = NOTIFY_BRN_MIN; /* brightness down */
1244 			} else if (new_brightness > old_brightness) {
1245 				event = NOTIFY_BRN_MAX; /* brightness up */
1246 			} else {
1247 				/*
1248 				* no change in brightness - already at min/max,
1249 				* event will be desired value (or else ignored)
1250 				*/
1251 			}
1252 			sparse_keymap_report_event(eeepc->inputdev, event,
1253 						   1, true);
1254 		}
1255 	} else {
1256 		/* Everything else is a bona-fide keypress event */
1257 		sparse_keymap_report_event(eeepc->inputdev, event, 1, true);
1258 	}
1259 }
1260 
1261 static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
1262 {
1263 	const char *model;
1264 
1265 	model = dmi_get_system_info(DMI_PRODUCT_NAME);
1266 	if (!model)
1267 		return;
1268 
1269 	/*
1270 	 * Blacklist for setting cpufv (cpu speed).
1271 	 *
1272 	 * EeePC 4G ("701") implements CFVS, but it is not supported
1273 	 * by the pre-installed OS, and the original option to change it
1274 	 * in the BIOS setup screen was removed in later versions.
1275 	 *
1276 	 * Judging by the lack of "Super Hybrid Engine" on Asus product pages,
1277 	 * this applies to all "701" models (4G/4G Surf/2G Surf).
1278 	 *
1279 	 * So Asus made a deliberate decision not to support it on this model.
1280 	 * We have several reports that using it can cause the system to hang
1281 	 *
1282 	 * The hang has also been reported on a "702" (Model name "8G"?).
1283 	 *
1284 	 * We avoid dmi_check_system() / dmi_match(), because they use
1285 	 * substring matching.  We don't want to affect the "701SD"
1286 	 * and "701SDX" models, because they do support S.H.E.
1287 	 */
1288 	if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) {
1289 		eeepc->cpufv_disabled = true;
1290 		pr_info("model %s does not officially support setting cpu "
1291 			"speed\n", model);
1292 		pr_info("cpufv disabled to avoid instability\n");
1293 	}
1294 
1295 	/*
1296 	 * Blacklist for wlan hotplug
1297 	 *
1298 	 * Eeepc 1005HA doesn't work like others models and don't need the
1299 	 * hotplug code. In fact, current hotplug code seems to unplug another
1300 	 * device...
1301 	 */
1302 	if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0 ||
1303 	    strcmp(model, "1005PE") == 0) {
1304 		eeepc->hotplug_disabled = true;
1305 		pr_info("wlan hotplug disabled\n");
1306 	}
1307 }
1308 
1309 static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
1310 {
1311 	int dummy;
1312 
1313 	/* Some BIOSes do not report cm although it is avaliable.
1314 	   Check if cm_getv[cm] works and, if yes, assume cm should be set. */
1315 	if (!(eeepc->cm_supported & (1 << cm))
1316 	    && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
1317 		pr_info("%s (%x) not reported by BIOS,"
1318 			" enabling anyway\n", name, 1 << cm);
1319 		eeepc->cm_supported |= 1 << cm;
1320 	}
1321 }
1322 
1323 static void cmsg_quirks(struct eeepc_laptop *eeepc)
1324 {
1325 	cmsg_quirk(eeepc, CM_ASL_LID, "LID");
1326 	cmsg_quirk(eeepc, CM_ASL_TYPE, "TYPE");
1327 	cmsg_quirk(eeepc, CM_ASL_PANELPOWER, "PANELPOWER");
1328 	cmsg_quirk(eeepc, CM_ASL_TPD, "TPD");
1329 }
1330 
1331 static int __devinit eeepc_acpi_init(struct eeepc_laptop *eeepc)
1332 {
1333 	unsigned int init_flags;
1334 	int result;
1335 
1336 	result = acpi_bus_get_status(eeepc->device);
1337 	if (result)
1338 		return result;
1339 	if (!eeepc->device->status.present) {
1340 		pr_err("Hotkey device not present, aborting\n");
1341 		return -ENODEV;
1342 	}
1343 
1344 	init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
1345 	pr_notice("Hotkey init flags 0x%x\n", init_flags);
1346 
1347 	if (write_acpi_int(eeepc->handle, "INIT", init_flags)) {
1348 		pr_err("Hotkey initialization failed\n");
1349 		return -ENODEV;
1350 	}
1351 
1352 	/* get control methods supported */
1353 	if (read_acpi_int(eeepc->handle, "CMSG", &eeepc->cm_supported)) {
1354 		pr_err("Get control methods supported failed\n");
1355 		return -ENODEV;
1356 	}
1357 	cmsg_quirks(eeepc);
1358 	pr_info("Get control methods supported: 0x%x\n", eeepc->cm_supported);
1359 
1360 	return 0;
1361 }
1362 
1363 static void __devinit eeepc_enable_camera(struct eeepc_laptop *eeepc)
1364 {
1365 	/*
1366 	 * If the following call to set_acpi() fails, it's because there's no
1367 	 * camera so we can ignore the error.
1368 	 */
1369 	if (get_acpi(eeepc, CM_ASL_CAMERA) == 0)
1370 		set_acpi(eeepc, CM_ASL_CAMERA, 1);
1371 }
1372 
1373 static bool eeepc_device_present;
1374 
1375 static int __devinit eeepc_acpi_add(struct acpi_device *device)
1376 {
1377 	struct eeepc_laptop *eeepc;
1378 	int result;
1379 
1380 	pr_notice(EEEPC_LAPTOP_NAME "\n");
1381 	eeepc = kzalloc(sizeof(struct eeepc_laptop), GFP_KERNEL);
1382 	if (!eeepc)
1383 		return -ENOMEM;
1384 	eeepc->handle = device->handle;
1385 	strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME);
1386 	strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
1387 	device->driver_data = eeepc;
1388 	eeepc->device = device;
1389 
1390 	eeepc->hotplug_disabled = hotplug_disabled;
1391 
1392 	eeepc_dmi_check(eeepc);
1393 
1394 	result = eeepc_acpi_init(eeepc);
1395 	if (result)
1396 		goto fail_platform;
1397 	eeepc_enable_camera(eeepc);
1398 
1399 	/*
1400 	 * Register the platform device first.  It is used as a parent for the
1401 	 * sub-devices below.
1402 	 *
1403 	 * Note that if there are multiple instances of this ACPI device it
1404 	 * will bail out, because the platform device is registered with a
1405 	 * fixed name.  Of course it doesn't make sense to have more than one,
1406 	 * and machine-specific scripts find the fixed name convenient.  But
1407 	 * It's also good for us to exclude multiple instances because both
1408 	 * our hwmon and our wlan rfkill subdevice use global ACPI objects
1409 	 * (the EC and the wlan PCI slot respectively).
1410 	 */
1411 	result = eeepc_platform_init(eeepc);
1412 	if (result)
1413 		goto fail_platform;
1414 
1415 	if (!acpi_video_backlight_support()) {
1416 		result = eeepc_backlight_init(eeepc);
1417 		if (result)
1418 			goto fail_backlight;
1419 	} else
1420 		pr_info("Backlight controlled by ACPI video driver\n");
1421 
1422 	result = eeepc_input_init(eeepc);
1423 	if (result)
1424 		goto fail_input;
1425 
1426 	result = eeepc_hwmon_init(eeepc);
1427 	if (result)
1428 		goto fail_hwmon;
1429 
1430 	result = eeepc_led_init(eeepc);
1431 	if (result)
1432 		goto fail_led;
1433 
1434 	result = eeepc_rfkill_init(eeepc);
1435 	if (result)
1436 		goto fail_rfkill;
1437 
1438 	eeepc_device_present = true;
1439 	return 0;
1440 
1441 fail_rfkill:
1442 	eeepc_led_exit(eeepc);
1443 fail_led:
1444 	eeepc_hwmon_exit(eeepc);
1445 fail_hwmon:
1446 	eeepc_input_exit(eeepc);
1447 fail_input:
1448 	eeepc_backlight_exit(eeepc);
1449 fail_backlight:
1450 	eeepc_platform_exit(eeepc);
1451 fail_platform:
1452 	kfree(eeepc);
1453 
1454 	return result;
1455 }
1456 
1457 static int eeepc_acpi_remove(struct acpi_device *device, int type)
1458 {
1459 	struct eeepc_laptop *eeepc = acpi_driver_data(device);
1460 
1461 	eeepc_backlight_exit(eeepc);
1462 	eeepc_rfkill_exit(eeepc);
1463 	eeepc_input_exit(eeepc);
1464 	eeepc_hwmon_exit(eeepc);
1465 	eeepc_led_exit(eeepc);
1466 	eeepc_platform_exit(eeepc);
1467 
1468 	kfree(eeepc);
1469 	return 0;
1470 }
1471 
1472 
1473 static const struct acpi_device_id eeepc_device_ids[] = {
1474 	{EEEPC_ACPI_HID, 0},
1475 	{"", 0},
1476 };
1477 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
1478 
1479 static struct acpi_driver eeepc_acpi_driver = {
1480 	.name = EEEPC_LAPTOP_NAME,
1481 	.class = EEEPC_ACPI_CLASS,
1482 	.owner = THIS_MODULE,
1483 	.ids = eeepc_device_ids,
1484 	.flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
1485 	.ops = {
1486 		.add = eeepc_acpi_add,
1487 		.remove = eeepc_acpi_remove,
1488 		.notify = eeepc_acpi_notify,
1489 	},
1490 };
1491 
1492 
1493 static int __init eeepc_laptop_init(void)
1494 {
1495 	int result;
1496 
1497 	result = platform_driver_register(&platform_driver);
1498 	if (result < 0)
1499 		return result;
1500 
1501 	result = acpi_bus_register_driver(&eeepc_acpi_driver);
1502 	if (result < 0)
1503 		goto fail_acpi_driver;
1504 
1505 	if (!eeepc_device_present) {
1506 		result = -ENODEV;
1507 		goto fail_no_device;
1508 	}
1509 
1510 	return 0;
1511 
1512 fail_no_device:
1513 	acpi_bus_unregister_driver(&eeepc_acpi_driver);
1514 fail_acpi_driver:
1515 	platform_driver_unregister(&platform_driver);
1516 	return result;
1517 }
1518 
1519 static void __exit eeepc_laptop_exit(void)
1520 {
1521 	acpi_bus_unregister_driver(&eeepc_acpi_driver);
1522 	platform_driver_unregister(&platform_driver);
1523 }
1524 
1525 module_init(eeepc_laptop_init);
1526 module_exit(eeepc_laptop_exit);
1527