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