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