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_unlock;
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_unlock;
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_unlock;
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_unlock;
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_remove_bus_device(dev);
650 				pci_dev_put(dev);
651 			}
652 		}
653 	}
654 
655 out_unlock:
656 	mutex_unlock(&eeepc->hotplug_lock);
657 }
658 
659 static void eeepc_rfkill_hotplug_update(struct eeepc_laptop *eeepc, char *node)
660 {
661 	acpi_status status = AE_OK;
662 	acpi_handle handle;
663 
664 	status = acpi_get_handle(NULL, node, &handle);
665 
666 	if (ACPI_SUCCESS(status))
667 		eeepc_rfkill_hotplug(eeepc, handle);
668 }
669 
670 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
671 {
672 	struct eeepc_laptop *eeepc = data;
673 
674 	if (event != ACPI_NOTIFY_BUS_CHECK)
675 		return;
676 
677 	eeepc_rfkill_hotplug(eeepc, handle);
678 }
679 
680 static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
681 					  char *node)
682 {
683 	acpi_status status;
684 	acpi_handle handle;
685 
686 	status = acpi_get_handle(NULL, node, &handle);
687 
688 	if (ACPI_SUCCESS(status)) {
689 		status = acpi_install_notify_handler(handle,
690 						     ACPI_SYSTEM_NOTIFY,
691 						     eeepc_rfkill_notify,
692 						     eeepc);
693 		if (ACPI_FAILURE(status))
694 			pr_warn("Failed to register notify on %s\n", node);
695 
696 		/*
697 		 * Refresh pci hotplug in case the rfkill state was
698 		 * changed during setup.
699 		 */
700 		eeepc_rfkill_hotplug(eeepc, handle);
701 	} else
702 		return -ENODEV;
703 
704 	return 0;
705 }
706 
707 static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
708 					     char *node)
709 {
710 	acpi_status status = AE_OK;
711 	acpi_handle handle;
712 
713 	status = acpi_get_handle(NULL, node, &handle);
714 
715 	if (ACPI_SUCCESS(status)) {
716 		status = acpi_remove_notify_handler(handle,
717 						     ACPI_SYSTEM_NOTIFY,
718 						     eeepc_rfkill_notify);
719 		if (ACPI_FAILURE(status))
720 			pr_err("Error removing rfkill notify handler %s\n",
721 				node);
722 			/*
723 			 * Refresh pci hotplug in case the rfkill
724 			 * state was changed after
725 			 * eeepc_unregister_rfkill_notifier()
726 			 */
727 		eeepc_rfkill_hotplug(eeepc, handle);
728 	}
729 }
730 
731 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
732 				    u8 *value)
733 {
734 	struct eeepc_laptop *eeepc = hotplug_slot->private;
735 	int val = get_acpi(eeepc, CM_ASL_WLAN);
736 
737 	if (val == 1 || val == 0)
738 		*value = val;
739 	else
740 		return -EINVAL;
741 
742 	return 0;
743 }
744 
745 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
746 {
747 	kfree(hotplug_slot->info);
748 	kfree(hotplug_slot);
749 }
750 
751 static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
752 	.owner = THIS_MODULE,
753 	.get_adapter_status = eeepc_get_adapter_status,
754 	.get_power_status = eeepc_get_adapter_status,
755 };
756 
757 static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
758 {
759 	int ret = -ENOMEM;
760 	struct pci_bus *bus = pci_find_bus(0, 1);
761 
762 	if (!bus) {
763 		pr_err("Unable to find wifi PCI bus\n");
764 		return -ENODEV;
765 	}
766 
767 	eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
768 	if (!eeepc->hotplug_slot)
769 		goto error_slot;
770 
771 	eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
772 					    GFP_KERNEL);
773 	if (!eeepc->hotplug_slot->info)
774 		goto error_info;
775 
776 	eeepc->hotplug_slot->private = eeepc;
777 	eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
778 	eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
779 	eeepc_get_adapter_status(eeepc->hotplug_slot,
780 				 &eeepc->hotplug_slot->info->adapter_status);
781 
782 	ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
783 	if (ret) {
784 		pr_err("Unable to register hotplug slot - %d\n", ret);
785 		goto error_register;
786 	}
787 
788 	return 0;
789 
790 error_register:
791 	kfree(eeepc->hotplug_slot->info);
792 error_info:
793 	kfree(eeepc->hotplug_slot);
794 	eeepc->hotplug_slot = NULL;
795 error_slot:
796 	return ret;
797 }
798 
799 /*
800  * Rfkill devices
801  */
802 static int eeepc_rfkill_set(void *data, bool blocked)
803 {
804 	acpi_handle handle = data;
805 
806 	return write_acpi_int(handle, NULL, !blocked);
807 }
808 
809 static const struct rfkill_ops eeepc_rfkill_ops = {
810 	.set_block = eeepc_rfkill_set,
811 };
812 
813 static int eeepc_new_rfkill(struct eeepc_laptop *eeepc,
814 			    struct rfkill **rfkill,
815 			    const char *name,
816 			    enum rfkill_type type, int cm)
817 {
818 	acpi_handle handle;
819 	int result;
820 
821 	result = acpi_setter_handle(eeepc, cm, &handle);
822 	if (result < 0)
823 		return result;
824 
825 	*rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
826 			       &eeepc_rfkill_ops, handle);
827 
828 	if (!*rfkill)
829 		return -EINVAL;
830 
831 	rfkill_init_sw_state(*rfkill, get_acpi(eeepc, cm) != 1);
832 	result = rfkill_register(*rfkill);
833 	if (result) {
834 		rfkill_destroy(*rfkill);
835 		*rfkill = NULL;
836 		return result;
837 	}
838 	return 0;
839 }
840 
841 static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
842 {
843 	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
844 	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
845 	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
846 	if (eeepc->wlan_rfkill) {
847 		rfkill_unregister(eeepc->wlan_rfkill);
848 		rfkill_destroy(eeepc->wlan_rfkill);
849 		eeepc->wlan_rfkill = NULL;
850 	}
851 
852 	if (eeepc->hotplug_slot)
853 		pci_hp_deregister(eeepc->hotplug_slot);
854 
855 	if (eeepc->bluetooth_rfkill) {
856 		rfkill_unregister(eeepc->bluetooth_rfkill);
857 		rfkill_destroy(eeepc->bluetooth_rfkill);
858 		eeepc->bluetooth_rfkill = NULL;
859 	}
860 	if (eeepc->wwan3g_rfkill) {
861 		rfkill_unregister(eeepc->wwan3g_rfkill);
862 		rfkill_destroy(eeepc->wwan3g_rfkill);
863 		eeepc->wwan3g_rfkill = NULL;
864 	}
865 	if (eeepc->wimax_rfkill) {
866 		rfkill_unregister(eeepc->wimax_rfkill);
867 		rfkill_destroy(eeepc->wimax_rfkill);
868 		eeepc->wimax_rfkill = NULL;
869 	}
870 }
871 
872 static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
873 {
874 	int result = 0;
875 
876 	mutex_init(&eeepc->hotplug_lock);
877 
878 	result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
879 				  "eeepc-wlan", RFKILL_TYPE_WLAN,
880 				  CM_ASL_WLAN);
881 
882 	if (result && result != -ENODEV)
883 		goto exit;
884 
885 	result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
886 				  "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
887 				  CM_ASL_BLUETOOTH);
888 
889 	if (result && result != -ENODEV)
890 		goto exit;
891 
892 	result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
893 				  "eeepc-wwan3g", RFKILL_TYPE_WWAN,
894 				  CM_ASL_3G);
895 
896 	if (result && result != -ENODEV)
897 		goto exit;
898 
899 	result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
900 				  "eeepc-wimax", RFKILL_TYPE_WIMAX,
901 				  CM_ASL_WIMAX);
902 
903 	if (result && result != -ENODEV)
904 		goto exit;
905 
906 	if (eeepc->hotplug_disabled)
907 		return 0;
908 
909 	result = eeepc_setup_pci_hotplug(eeepc);
910 	/*
911 	 * If we get -EBUSY then something else is handling the PCI hotplug -
912 	 * don't fail in this case
913 	 */
914 	if (result == -EBUSY)
915 		result = 0;
916 
917 	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
918 	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
919 	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
920 
921 exit:
922 	if (result && result != -ENODEV)
923 		eeepc_rfkill_exit(eeepc);
924 	return result;
925 }
926 
927 /*
928  * Platform driver - hibernate/resume callbacks
929  */
930 static int eeepc_hotk_thaw(struct device *device)
931 {
932 	struct eeepc_laptop *eeepc = dev_get_drvdata(device);
933 
934 	if (eeepc->wlan_rfkill) {
935 		bool wlan;
936 
937 		/*
938 		 * Work around bios bug - acpi _PTS turns off the wireless led
939 		 * during suspend.  Normally it restores it on resume, but
940 		 * we should kick it ourselves in case hibernation is aborted.
941 		 */
942 		wlan = get_acpi(eeepc, CM_ASL_WLAN);
943 		set_acpi(eeepc, CM_ASL_WLAN, wlan);
944 	}
945 
946 	return 0;
947 }
948 
949 static int eeepc_hotk_restore(struct device *device)
950 {
951 	struct eeepc_laptop *eeepc = dev_get_drvdata(device);
952 
953 	/* Refresh both wlan rfkill state and pci hotplug */
954 	if (eeepc->wlan_rfkill) {
955 		eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P5");
956 		eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P6");
957 		eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P7");
958 	}
959 
960 	if (eeepc->bluetooth_rfkill)
961 		rfkill_set_sw_state(eeepc->bluetooth_rfkill,
962 				    get_acpi(eeepc, CM_ASL_BLUETOOTH) != 1);
963 	if (eeepc->wwan3g_rfkill)
964 		rfkill_set_sw_state(eeepc->wwan3g_rfkill,
965 				    get_acpi(eeepc, CM_ASL_3G) != 1);
966 	if (eeepc->wimax_rfkill)
967 		rfkill_set_sw_state(eeepc->wimax_rfkill,
968 				    get_acpi(eeepc, CM_ASL_WIMAX) != 1);
969 
970 	return 0;
971 }
972 
973 static const struct dev_pm_ops eeepc_pm_ops = {
974 	.thaw = eeepc_hotk_thaw,
975 	.restore = eeepc_hotk_restore,
976 };
977 
978 static struct platform_driver platform_driver = {
979 	.driver = {
980 		.name = EEEPC_LAPTOP_FILE,
981 		.owner = THIS_MODULE,
982 		.pm = &eeepc_pm_ops,
983 	}
984 };
985 
986 /*
987  * Hwmon device
988  */
989 
990 #define EEEPC_EC_SC00      0x61
991 #define EEEPC_EC_FAN_PWM   (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */
992 #define EEEPC_EC_FAN_HRPM  (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */
993 #define EEEPC_EC_FAN_LRPM  (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */
994 
995 #define EEEPC_EC_SFB0      0xD0
996 #define EEEPC_EC_FAN_CTRL  (EEEPC_EC_SFB0 + 3) /* Byte containing SF25  */
997 
998 static int eeepc_get_fan_pwm(void)
999 {
1000 	u8 value = 0;
1001 
1002 	ec_read(EEEPC_EC_FAN_PWM, &value);
1003 	return value * 255 / 100;
1004 }
1005 
1006 static void eeepc_set_fan_pwm(int value)
1007 {
1008 	value = SENSORS_LIMIT(value, 0, 255);
1009 	value = value * 100 / 255;
1010 	ec_write(EEEPC_EC_FAN_PWM, value);
1011 }
1012 
1013 static int eeepc_get_fan_rpm(void)
1014 {
1015 	u8 high = 0;
1016 	u8 low = 0;
1017 
1018 	ec_read(EEEPC_EC_FAN_HRPM, &high);
1019 	ec_read(EEEPC_EC_FAN_LRPM, &low);
1020 	return high << 8 | low;
1021 }
1022 
1023 static int eeepc_get_fan_ctrl(void)
1024 {
1025 	u8 value = 0;
1026 
1027 	ec_read(EEEPC_EC_FAN_CTRL, &value);
1028 	if (value & 0x02)
1029 		return 1; /* manual */
1030 	else
1031 		return 2; /* automatic */
1032 }
1033 
1034 static void eeepc_set_fan_ctrl(int manual)
1035 {
1036 	u8 value = 0;
1037 
1038 	ec_read(EEEPC_EC_FAN_CTRL, &value);
1039 	if (manual == 1)
1040 		value |= 0x02;
1041 	else
1042 		value &= ~0x02;
1043 	ec_write(EEEPC_EC_FAN_CTRL, value);
1044 }
1045 
1046 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
1047 {
1048 	int rv, value;
1049 
1050 	rv = parse_arg(buf, count, &value);
1051 	if (rv > 0)
1052 		set(value);
1053 	return rv;
1054 }
1055 
1056 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
1057 {
1058 	return sprintf(buf, "%d\n", get());
1059 }
1060 
1061 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get)		\
1062 	static ssize_t show_##_name(struct device *dev,			\
1063 				    struct device_attribute *attr,	\
1064 				    char *buf)				\
1065 	{								\
1066 		return show_sys_hwmon(_set, buf);			\
1067 	}								\
1068 	static ssize_t store_##_name(struct device *dev,		\
1069 				     struct device_attribute *attr,	\
1070 				     const char *buf, size_t count)	\
1071 	{								\
1072 		return store_sys_hwmon(_get, buf, count);		\
1073 	}								\
1074 	static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
1075 
1076 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
1077 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
1078 			 eeepc_get_fan_pwm, eeepc_set_fan_pwm);
1079 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
1080 			 eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
1081 
1082 static ssize_t
1083 show_name(struct device *dev, struct device_attribute *attr, char *buf)
1084 {
1085 	return sprintf(buf, "eeepc\n");
1086 }
1087 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
1088 
1089 static struct attribute *hwmon_attributes[] = {
1090 	&sensor_dev_attr_pwm1.dev_attr.attr,
1091 	&sensor_dev_attr_fan1_input.dev_attr.attr,
1092 	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
1093 	&sensor_dev_attr_name.dev_attr.attr,
1094 	NULL
1095 };
1096 
1097 static struct attribute_group hwmon_attribute_group = {
1098 	.attrs = hwmon_attributes
1099 };
1100 
1101 static void eeepc_hwmon_exit(struct eeepc_laptop *eeepc)
1102 {
1103 	struct device *hwmon;
1104 
1105 	hwmon = eeepc->hwmon_device;
1106 	if (!hwmon)
1107 		return;
1108 	sysfs_remove_group(&hwmon->kobj,
1109 			   &hwmon_attribute_group);
1110 	hwmon_device_unregister(hwmon);
1111 	eeepc->hwmon_device = NULL;
1112 }
1113 
1114 static int eeepc_hwmon_init(struct eeepc_laptop *eeepc)
1115 {
1116 	struct device *hwmon;
1117 	int result;
1118 
1119 	hwmon = hwmon_device_register(&eeepc->platform_device->dev);
1120 	if (IS_ERR(hwmon)) {
1121 		pr_err("Could not register eeepc hwmon device\n");
1122 		eeepc->hwmon_device = NULL;
1123 		return PTR_ERR(hwmon);
1124 	}
1125 	eeepc->hwmon_device = hwmon;
1126 	result = sysfs_create_group(&hwmon->kobj,
1127 				    &hwmon_attribute_group);
1128 	if (result)
1129 		eeepc_hwmon_exit(eeepc);
1130 	return result;
1131 }
1132 
1133 /*
1134  * Backlight device
1135  */
1136 static int read_brightness(struct backlight_device *bd)
1137 {
1138 	struct eeepc_laptop *eeepc = bl_get_data(bd);
1139 
1140 	return get_acpi(eeepc, CM_ASL_PANELBRIGHT);
1141 }
1142 
1143 static int set_brightness(struct backlight_device *bd, int value)
1144 {
1145 	struct eeepc_laptop *eeepc = bl_get_data(bd);
1146 
1147 	return set_acpi(eeepc, CM_ASL_PANELBRIGHT, value);
1148 }
1149 
1150 static int update_bl_status(struct backlight_device *bd)
1151 {
1152 	return set_brightness(bd, bd->props.brightness);
1153 }
1154 
1155 static const struct backlight_ops eeepcbl_ops = {
1156 	.get_brightness = read_brightness,
1157 	.update_status = update_bl_status,
1158 };
1159 
1160 static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
1161 {
1162 	struct backlight_device *bd = eeepc->backlight_device;
1163 	int old = bd->props.brightness;
1164 
1165 	backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
1166 
1167 	return old;
1168 }
1169 
1170 static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
1171 {
1172 	struct backlight_properties props;
1173 	struct backlight_device *bd;
1174 
1175 	memset(&props, 0, sizeof(struct backlight_properties));
1176 	props.type = BACKLIGHT_PLATFORM;
1177 	props.max_brightness = 15;
1178 	bd = backlight_device_register(EEEPC_LAPTOP_FILE,
1179 				       &eeepc->platform_device->dev, eeepc,
1180 				       &eeepcbl_ops, &props);
1181 	if (IS_ERR(bd)) {
1182 		pr_err("Could not register eeepc backlight device\n");
1183 		eeepc->backlight_device = NULL;
1184 		return PTR_ERR(bd);
1185 	}
1186 	eeepc->backlight_device = bd;
1187 	bd->props.brightness = read_brightness(bd);
1188 	bd->props.power = FB_BLANK_UNBLANK;
1189 	backlight_update_status(bd);
1190 	return 0;
1191 }
1192 
1193 static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
1194 {
1195 	if (eeepc->backlight_device)
1196 		backlight_device_unregister(eeepc->backlight_device);
1197 	eeepc->backlight_device = NULL;
1198 }
1199 
1200 
1201 /*
1202  * Input device (i.e. hotkeys)
1203  */
1204 static int eeepc_input_init(struct eeepc_laptop *eeepc)
1205 {
1206 	struct input_dev *input;
1207 	int error;
1208 
1209 	input = input_allocate_device();
1210 	if (!input) {
1211 		pr_info("Unable to allocate input device\n");
1212 		return -ENOMEM;
1213 	}
1214 
1215 	input->name = "Asus EeePC extra buttons";
1216 	input->phys = EEEPC_LAPTOP_FILE "/input0";
1217 	input->id.bustype = BUS_HOST;
1218 	input->dev.parent = &eeepc->platform_device->dev;
1219 
1220 	error = sparse_keymap_setup(input, eeepc_keymap, NULL);
1221 	if (error) {
1222 		pr_err("Unable to setup input device keymap\n");
1223 		goto err_free_dev;
1224 	}
1225 
1226 	error = input_register_device(input);
1227 	if (error) {
1228 		pr_err("Unable to register input device\n");
1229 		goto err_free_keymap;
1230 	}
1231 
1232 	eeepc->inputdev = input;
1233 	return 0;
1234 
1235 err_free_keymap:
1236 	sparse_keymap_free(input);
1237 err_free_dev:
1238 	input_free_device(input);
1239 	return error;
1240 }
1241 
1242 static void eeepc_input_exit(struct eeepc_laptop *eeepc)
1243 {
1244 	if (eeepc->inputdev) {
1245 		sparse_keymap_free(eeepc->inputdev);
1246 		input_unregister_device(eeepc->inputdev);
1247 	}
1248 	eeepc->inputdev = NULL;
1249 }
1250 
1251 /*
1252  * ACPI driver
1253  */
1254 static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
1255 {
1256 	struct eeepc_laptop *eeepc = acpi_driver_data(device);
1257 	u16 count;
1258 
1259 	if (event > ACPI_MAX_SYS_NOTIFY)
1260 		return;
1261 	count = eeepc->event_count[event % 128]++;
1262 	acpi_bus_generate_proc_event(device, event, count);
1263 	acpi_bus_generate_netlink_event(device->pnp.device_class,
1264 					dev_name(&device->dev), event,
1265 					count);
1266 
1267 	/* Brightness events are special */
1268 	if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) {
1269 
1270 		/* Ignore them completely if the acpi video driver is used */
1271 		if (eeepc->backlight_device != NULL) {
1272 			int old_brightness, new_brightness;
1273 
1274 			/* Update the backlight device. */
1275 			old_brightness = eeepc_backlight_notify(eeepc);
1276 
1277 			/* Convert event to keypress (obsolescent hack) */
1278 			new_brightness = event - NOTIFY_BRN_MIN;
1279 
1280 			if (new_brightness < old_brightness) {
1281 				event = NOTIFY_BRN_MIN; /* brightness down */
1282 			} else if (new_brightness > old_brightness) {
1283 				event = NOTIFY_BRN_MAX; /* brightness up */
1284 			} else {
1285 				/*
1286 				* no change in brightness - already at min/max,
1287 				* event will be desired value (or else ignored)
1288 				*/
1289 			}
1290 			sparse_keymap_report_event(eeepc->inputdev, event,
1291 						   1, true);
1292 		}
1293 	} else {
1294 		/* Everything else is a bona-fide keypress event */
1295 		sparse_keymap_report_event(eeepc->inputdev, event, 1, true);
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 __devinit 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 __devinit 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 __devinit 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, int type)
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