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