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