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