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