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