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