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