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