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