1 /*
2  *  Acer WMI Laptop Extras
3  *
4  *  Copyright (C) 2007-2009	Carlos Corbacho <carlos@strangeworlds.co.uk>
5  *
6  *  Based on acer_acpi:
7  *    Copyright (C) 2005-2007	E.M. Smith
8  *    Copyright (C) 2007-2008	Carlos Corbacho <cathectic@gmail.com>
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  */
24 
25 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
26 
27 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/init.h>
30 #include <linux/types.h>
31 #include <linux/dmi.h>
32 #include <linux/fb.h>
33 #include <linux/backlight.h>
34 #include <linux/leds.h>
35 #include <linux/platform_device.h>
36 #include <linux/acpi.h>
37 #include <linux/i8042.h>
38 #include <linux/rfkill.h>
39 #include <linux/workqueue.h>
40 #include <linux/debugfs.h>
41 #include <linux/slab.h>
42 #include <linux/input.h>
43 #include <linux/input/sparse-keymap.h>
44 
45 #include <acpi/acpi_drivers.h>
46 
47 MODULE_AUTHOR("Carlos Corbacho");
48 MODULE_DESCRIPTION("Acer Laptop WMI Extras Driver");
49 MODULE_LICENSE("GPL");
50 
51 /*
52  * Magic Number
53  * Meaning is unknown - this number is required for writing to ACPI for AMW0
54  * (it's also used in acerhk when directly accessing the BIOS)
55  */
56 #define ACER_AMW0_WRITE	0x9610
57 
58 /*
59  * Bit masks for the AMW0 interface
60  */
61 #define ACER_AMW0_WIRELESS_MASK  0x35
62 #define ACER_AMW0_BLUETOOTH_MASK 0x34
63 #define ACER_AMW0_MAILLED_MASK   0x31
64 
65 /*
66  * Method IDs for WMID interface
67  */
68 #define ACER_WMID_GET_WIRELESS_METHODID		1
69 #define ACER_WMID_GET_BLUETOOTH_METHODID	2
70 #define ACER_WMID_GET_BRIGHTNESS_METHODID	3
71 #define ACER_WMID_SET_WIRELESS_METHODID		4
72 #define ACER_WMID_SET_BLUETOOTH_METHODID	5
73 #define ACER_WMID_SET_BRIGHTNESS_METHODID	6
74 #define ACER_WMID_GET_THREEG_METHODID		10
75 #define ACER_WMID_SET_THREEG_METHODID		11
76 
77 /*
78  * Acer ACPI method GUIDs
79  */
80 #define AMW0_GUID1		"67C3371D-95A3-4C37-BB61-DD47B491DAAB"
81 #define AMW0_GUID2		"431F16ED-0C2B-444C-B267-27DEB140CF9C"
82 #define WMID_GUID1		"6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3"
83 #define WMID_GUID2		"95764E09-FB56-4E83-B31A-37761F60994A"
84 #define WMID_GUID3		"61EF69EA-865C-4BC3-A502-A0DEBA0CB531"
85 
86 /*
87  * Acer ACPI event GUIDs
88  */
89 #define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026"
90 
91 MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
92 MODULE_ALIAS("wmi:6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3");
93 MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
94 
95 enum acer_wmi_event_ids {
96 	WMID_HOTKEY_EVENT = 0x1,
97 };
98 
99 static const struct key_entry acer_wmi_keymap[] = {
100 	{KE_KEY, 0x01, {KEY_WLAN} },     /* WiFi */
101 	{KE_KEY, 0x03, {KEY_WLAN} },     /* WiFi */
102 	{KE_KEY, 0x04, {KEY_WLAN} },     /* WiFi */
103 	{KE_KEY, 0x12, {KEY_BLUETOOTH} },	/* BT */
104 	{KE_KEY, 0x21, {KEY_PROG1} },    /* Backup */
105 	{KE_KEY, 0x22, {KEY_PROG2} },    /* Arcade */
106 	{KE_KEY, 0x23, {KEY_PROG3} },    /* P_Key */
107 	{KE_KEY, 0x24, {KEY_PROG4} },    /* Social networking_Key */
108 	{KE_IGNORE, 0x41, {KEY_MUTE} },
109 	{KE_IGNORE, 0x42, {KEY_PREVIOUSSONG} },
110 	{KE_IGNORE, 0x43, {KEY_NEXTSONG} },
111 	{KE_IGNORE, 0x44, {KEY_PLAYPAUSE} },
112 	{KE_IGNORE, 0x45, {KEY_STOP} },
113 	{KE_IGNORE, 0x48, {KEY_VOLUMEUP} },
114 	{KE_IGNORE, 0x49, {KEY_VOLUMEDOWN} },
115 	{KE_IGNORE, 0x61, {KEY_SWITCHVIDEOMODE} },
116 	{KE_IGNORE, 0x62, {KEY_BRIGHTNESSUP} },
117 	{KE_IGNORE, 0x63, {KEY_BRIGHTNESSDOWN} },
118 	{KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} },	/* Display Switch */
119 	{KE_IGNORE, 0x81, {KEY_SLEEP} },
120 	{KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} },	/* Touch Pad On/Off */
121 	{KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} },
122 	{KE_END, 0}
123 };
124 
125 static struct input_dev *acer_wmi_input_dev;
126 
127 struct event_return_value {
128 	u8 function;
129 	u8 key_num;
130 	u16 device_state;
131 	u32 reserved;
132 } __attribute__((packed));
133 
134 /*
135  * GUID3 Get Device Status device flags
136  */
137 #define ACER_WMID3_GDS_WIRELESS		(1<<0)	/* WiFi */
138 #define ACER_WMID3_GDS_THREEG		(1<<6)	/* 3G */
139 #define ACER_WMID3_GDS_WIMAX		(1<<7)	/* WiMAX */
140 #define ACER_WMID3_GDS_BLUETOOTH	(1<<11)	/* BT */
141 
142 struct lm_input_params {
143 	u8 function_num;        /* Function Number */
144 	u16 commun_devices;     /* Communication type devices default status */
145 	u16 devices;            /* Other type devices default status */
146 	u8 lm_status;           /* Launch Manager Status */
147 	u16 reserved;
148 } __attribute__((packed));
149 
150 struct lm_return_value {
151 	u8 error_code;          /* Error Code */
152 	u8 ec_return_value;     /* EC Return Value */
153 	u16 reserved;
154 } __attribute__((packed));
155 
156 struct wmid3_gds_input_param {	/* Get Device Status input parameter */
157 	u8 function_num;	/* Function Number */
158 	u8 hotkey_number;	/* Hotkey Number */
159 	u16 devices;		/* Get Device */
160 } __attribute__((packed));
161 
162 struct wmid3_gds_return_value {	/* Get Device Status return value*/
163 	u8 error_code;		/* Error Code */
164 	u8 ec_return_value;	/* EC Return Value */
165 	u16 devices;		/* Current Device Status */
166 	u32 reserved;
167 } __attribute__((packed));
168 
169 struct hotkey_function_type_aa {
170 	u8 type;
171 	u8 length;
172 	u16 handle;
173 	u16 commun_func_bitmap;
174 } __attribute__((packed));
175 
176 /*
177  * Interface capability flags
178  */
179 #define ACER_CAP_MAILLED		(1<<0)
180 #define ACER_CAP_WIRELESS		(1<<1)
181 #define ACER_CAP_BLUETOOTH		(1<<2)
182 #define ACER_CAP_BRIGHTNESS		(1<<3)
183 #define ACER_CAP_THREEG			(1<<4)
184 #define ACER_CAP_ANY			(0xFFFFFFFF)
185 
186 /*
187  * Interface type flags
188  */
189 enum interface_flags {
190 	ACER_AMW0,
191 	ACER_AMW0_V2,
192 	ACER_WMID,
193 	ACER_WMID_v2,
194 };
195 
196 #define ACER_DEFAULT_WIRELESS  0
197 #define ACER_DEFAULT_BLUETOOTH 0
198 #define ACER_DEFAULT_MAILLED   0
199 #define ACER_DEFAULT_THREEG    0
200 
201 static int max_brightness = 0xF;
202 
203 static int mailled = -1;
204 static int brightness = -1;
205 static int threeg = -1;
206 static int force_series;
207 static bool ec_raw_mode;
208 static bool has_type_aa;
209 static u16 commun_func_bitmap;
210 
211 module_param(mailled, int, 0444);
212 module_param(brightness, int, 0444);
213 module_param(threeg, int, 0444);
214 module_param(force_series, int, 0444);
215 module_param(ec_raw_mode, bool, 0444);
216 MODULE_PARM_DESC(mailled, "Set initial state of Mail LED");
217 MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness");
218 MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware");
219 MODULE_PARM_DESC(force_series, "Force a different laptop series");
220 MODULE_PARM_DESC(ec_raw_mode, "Enable EC raw mode");
221 
222 struct acer_data {
223 	int mailled;
224 	int threeg;
225 	int brightness;
226 };
227 
228 struct acer_debug {
229 	struct dentry *root;
230 	struct dentry *devices;
231 	u32 wmid_devices;
232 };
233 
234 static struct rfkill *wireless_rfkill;
235 static struct rfkill *bluetooth_rfkill;
236 static struct rfkill *threeg_rfkill;
237 static bool rfkill_inited;
238 
239 /* Each low-level interface must define at least some of the following */
240 struct wmi_interface {
241 	/* The WMI device type */
242 	u32 type;
243 
244 	/* The capabilities this interface provides */
245 	u32 capability;
246 
247 	/* Private data for the current interface */
248 	struct acer_data data;
249 
250 	/* debugfs entries associated with this interface */
251 	struct acer_debug debug;
252 };
253 
254 /* The static interface pointer, points to the currently detected interface */
255 static struct wmi_interface *interface;
256 
257 /*
258  * Embedded Controller quirks
259  * Some laptops require us to directly access the EC to either enable or query
260  * features that are not available through WMI.
261  */
262 
263 struct quirk_entry {
264 	u8 wireless;
265 	u8 mailled;
266 	s8 brightness;
267 	u8 bluetooth;
268 };
269 
270 static struct quirk_entry *quirks;
271 
set_quirks(void)272 static void set_quirks(void)
273 {
274 	if (!interface)
275 		return;
276 
277 	if (quirks->mailled)
278 		interface->capability |= ACER_CAP_MAILLED;
279 
280 	if (quirks->brightness)
281 		interface->capability |= ACER_CAP_BRIGHTNESS;
282 }
283 
dmi_matched(const struct dmi_system_id * dmi)284 static int dmi_matched(const struct dmi_system_id *dmi)
285 {
286 	quirks = dmi->driver_data;
287 	return 1;
288 }
289 
290 static struct quirk_entry quirk_unknown = {
291 };
292 
293 static struct quirk_entry quirk_acer_aspire_1520 = {
294 	.brightness = -1,
295 };
296 
297 static struct quirk_entry quirk_acer_travelmate_2490 = {
298 	.mailled = 1,
299 };
300 
301 /* This AMW0 laptop has no bluetooth */
302 static struct quirk_entry quirk_medion_md_98300 = {
303 	.wireless = 1,
304 };
305 
306 static struct quirk_entry quirk_fujitsu_amilo_li_1718 = {
307 	.wireless = 2,
308 };
309 
310 static struct quirk_entry quirk_lenovo_ideapad_s205 = {
311 	.wireless = 3,
312 };
313 
314 /* The Aspire One has a dummy ACPI-WMI interface - disable it */
315 static struct dmi_system_id __devinitdata acer_blacklist[] = {
316 	{
317 		.ident = "Acer Aspire One (SSD)",
318 		.matches = {
319 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
320 			DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
321 		},
322 	},
323 	{
324 		.ident = "Acer Aspire One (HDD)",
325 		.matches = {
326 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
327 			DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
328 		},
329 	},
330 	{}
331 };
332 
333 static struct dmi_system_id acer_quirks[] = {
334 	{
335 		.callback = dmi_matched,
336 		.ident = "Acer Aspire 1360",
337 		.matches = {
338 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
339 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
340 		},
341 		.driver_data = &quirk_acer_aspire_1520,
342 	},
343 	{
344 		.callback = dmi_matched,
345 		.ident = "Acer Aspire 1520",
346 		.matches = {
347 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
348 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1520"),
349 		},
350 		.driver_data = &quirk_acer_aspire_1520,
351 	},
352 	{
353 		.callback = dmi_matched,
354 		.ident = "Acer Aspire 3100",
355 		.matches = {
356 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
357 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3100"),
358 		},
359 		.driver_data = &quirk_acer_travelmate_2490,
360 	},
361 	{
362 		.callback = dmi_matched,
363 		.ident = "Acer Aspire 3610",
364 		.matches = {
365 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
366 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3610"),
367 		},
368 		.driver_data = &quirk_acer_travelmate_2490,
369 	},
370 	{
371 		.callback = dmi_matched,
372 		.ident = "Acer Aspire 5100",
373 		.matches = {
374 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
375 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
376 		},
377 		.driver_data = &quirk_acer_travelmate_2490,
378 	},
379 	{
380 		.callback = dmi_matched,
381 		.ident = "Acer Aspire 5610",
382 		.matches = {
383 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
384 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
385 		},
386 		.driver_data = &quirk_acer_travelmate_2490,
387 	},
388 	{
389 		.callback = dmi_matched,
390 		.ident = "Acer Aspire 5630",
391 		.matches = {
392 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
393 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"),
394 		},
395 		.driver_data = &quirk_acer_travelmate_2490,
396 	},
397 	{
398 		.callback = dmi_matched,
399 		.ident = "Acer Aspire 5650",
400 		.matches = {
401 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
402 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"),
403 		},
404 		.driver_data = &quirk_acer_travelmate_2490,
405 	},
406 	{
407 		.callback = dmi_matched,
408 		.ident = "Acer Aspire 5680",
409 		.matches = {
410 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
411 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
412 		},
413 		.driver_data = &quirk_acer_travelmate_2490,
414 	},
415 	{
416 		.callback = dmi_matched,
417 		.ident = "Acer Aspire 9110",
418 		.matches = {
419 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
420 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"),
421 		},
422 		.driver_data = &quirk_acer_travelmate_2490,
423 	},
424 	{
425 		.callback = dmi_matched,
426 		.ident = "Acer TravelMate 2490",
427 		.matches = {
428 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
429 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"),
430 		},
431 		.driver_data = &quirk_acer_travelmate_2490,
432 	},
433 	{
434 		.callback = dmi_matched,
435 		.ident = "Acer TravelMate 4200",
436 		.matches = {
437 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
438 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4200"),
439 		},
440 		.driver_data = &quirk_acer_travelmate_2490,
441 	},
442 	{
443 		.callback = dmi_matched,
444 		.ident = "Fujitsu Siemens Amilo Li 1718",
445 		.matches = {
446 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
447 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Li 1718"),
448 		},
449 		.driver_data = &quirk_fujitsu_amilo_li_1718,
450 	},
451 	{
452 		.callback = dmi_matched,
453 		.ident = "Medion MD 98300",
454 		.matches = {
455 			DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
456 			DMI_MATCH(DMI_PRODUCT_NAME, "WAM2030"),
457 		},
458 		.driver_data = &quirk_medion_md_98300,
459 	},
460 	{
461 		.callback = dmi_matched,
462 		.ident = "Lenovo Ideapad S205",
463 		.matches = {
464 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
465 			DMI_MATCH(DMI_PRODUCT_NAME, "10382LG"),
466 		},
467 		.driver_data = &quirk_lenovo_ideapad_s205,
468 	},
469 	{
470 		.callback = dmi_matched,
471 		.ident = "Lenovo 3000 N200",
472 		.matches = {
473 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
474 			DMI_MATCH(DMI_PRODUCT_NAME, "0687A31"),
475 		},
476 		.driver_data = &quirk_fujitsu_amilo_li_1718,
477 	},
478 	{}
479 };
480 
481 /* Find which quirks are needed for a particular vendor/ model pair */
find_quirks(void)482 static void find_quirks(void)
483 {
484 	if (!force_series) {
485 		dmi_check_system(acer_quirks);
486 	} else if (force_series == 2490) {
487 		quirks = &quirk_acer_travelmate_2490;
488 	}
489 
490 	if (quirks == NULL)
491 		quirks = &quirk_unknown;
492 
493 	set_quirks();
494 }
495 
496 /*
497  * General interface convenience methods
498  */
499 
has_cap(u32 cap)500 static bool has_cap(u32 cap)
501 {
502 	if ((interface->capability & cap) != 0)
503 		return 1;
504 
505 	return 0;
506 }
507 
508 /*
509  * AMW0 (V1) interface
510  */
511 struct wmab_args {
512 	u32 eax;
513 	u32 ebx;
514 	u32 ecx;
515 	u32 edx;
516 };
517 
518 struct wmab_ret {
519 	u32 eax;
520 	u32 ebx;
521 	u32 ecx;
522 	u32 edx;
523 	u32 eex;
524 };
525 
wmab_execute(struct wmab_args * regbuf,struct acpi_buffer * result)526 static acpi_status wmab_execute(struct wmab_args *regbuf,
527 struct acpi_buffer *result)
528 {
529 	struct acpi_buffer input;
530 	acpi_status status;
531 	input.length = sizeof(struct wmab_args);
532 	input.pointer = (u8 *)regbuf;
533 
534 	status = wmi_evaluate_method(AMW0_GUID1, 1, 1, &input, result);
535 
536 	return status;
537 }
538 
AMW0_get_u32(u32 * value,u32 cap,struct wmi_interface * iface)539 static acpi_status AMW0_get_u32(u32 *value, u32 cap,
540 struct wmi_interface *iface)
541 {
542 	int err;
543 	u8 result;
544 
545 	switch (cap) {
546 	case ACER_CAP_MAILLED:
547 		switch (quirks->mailled) {
548 		default:
549 			err = ec_read(0xA, &result);
550 			if (err)
551 				return AE_ERROR;
552 			*value = (result >> 7) & 0x1;
553 			return AE_OK;
554 		}
555 		break;
556 	case ACER_CAP_WIRELESS:
557 		switch (quirks->wireless) {
558 		case 1:
559 			err = ec_read(0x7B, &result);
560 			if (err)
561 				return AE_ERROR;
562 			*value = result & 0x1;
563 			return AE_OK;
564 		case 2:
565 			err = ec_read(0x71, &result);
566 			if (err)
567 				return AE_ERROR;
568 			*value = result & 0x1;
569 			return AE_OK;
570 		case 3:
571 			err = ec_read(0x78, &result);
572 			if (err)
573 				return AE_ERROR;
574 			*value = result & 0x1;
575 			return AE_OK;
576 		default:
577 			err = ec_read(0xA, &result);
578 			if (err)
579 				return AE_ERROR;
580 			*value = (result >> 2) & 0x1;
581 			return AE_OK;
582 		}
583 		break;
584 	case ACER_CAP_BLUETOOTH:
585 		switch (quirks->bluetooth) {
586 		default:
587 			err = ec_read(0xA, &result);
588 			if (err)
589 				return AE_ERROR;
590 			*value = (result >> 4) & 0x1;
591 			return AE_OK;
592 		}
593 		break;
594 	case ACER_CAP_BRIGHTNESS:
595 		switch (quirks->brightness) {
596 		default:
597 			err = ec_read(0x83, &result);
598 			if (err)
599 				return AE_ERROR;
600 			*value = result;
601 			return AE_OK;
602 		}
603 		break;
604 	default:
605 		return AE_ERROR;
606 	}
607 	return AE_OK;
608 }
609 
AMW0_set_u32(u32 value,u32 cap,struct wmi_interface * iface)610 static acpi_status AMW0_set_u32(u32 value, u32 cap, struct wmi_interface *iface)
611 {
612 	struct wmab_args args;
613 
614 	args.eax = ACER_AMW0_WRITE;
615 	args.ebx = value ? (1<<8) : 0;
616 	args.ecx = args.edx = 0;
617 
618 	switch (cap) {
619 	case ACER_CAP_MAILLED:
620 		if (value > 1)
621 			return AE_BAD_PARAMETER;
622 		args.ebx |= ACER_AMW0_MAILLED_MASK;
623 		break;
624 	case ACER_CAP_WIRELESS:
625 		if (value > 1)
626 			return AE_BAD_PARAMETER;
627 		args.ebx |= ACER_AMW0_WIRELESS_MASK;
628 		break;
629 	case ACER_CAP_BLUETOOTH:
630 		if (value > 1)
631 			return AE_BAD_PARAMETER;
632 		args.ebx |= ACER_AMW0_BLUETOOTH_MASK;
633 		break;
634 	case ACER_CAP_BRIGHTNESS:
635 		if (value > max_brightness)
636 			return AE_BAD_PARAMETER;
637 		switch (quirks->brightness) {
638 		default:
639 			return ec_write(0x83, value);
640 			break;
641 		}
642 	default:
643 		return AE_ERROR;
644 	}
645 
646 	/* Actually do the set */
647 	return wmab_execute(&args, NULL);
648 }
649 
AMW0_find_mailled(void)650 static acpi_status AMW0_find_mailled(void)
651 {
652 	struct wmab_args args;
653 	struct wmab_ret ret;
654 	acpi_status status = AE_OK;
655 	struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
656 	union acpi_object *obj;
657 
658 	args.eax = 0x86;
659 	args.ebx = args.ecx = args.edx = 0;
660 
661 	status = wmab_execute(&args, &out);
662 	if (ACPI_FAILURE(status))
663 		return status;
664 
665 	obj = (union acpi_object *) out.pointer;
666 	if (obj && obj->type == ACPI_TYPE_BUFFER &&
667 	obj->buffer.length == sizeof(struct wmab_ret)) {
668 		ret = *((struct wmab_ret *) obj->buffer.pointer);
669 	} else {
670 		kfree(out.pointer);
671 		return AE_ERROR;
672 	}
673 
674 	if (ret.eex & 0x1)
675 		interface->capability |= ACER_CAP_MAILLED;
676 
677 	kfree(out.pointer);
678 
679 	return AE_OK;
680 }
681 
682 static int AMW0_set_cap_acpi_check_device_found;
683 
AMW0_set_cap_acpi_check_device_cb(acpi_handle handle,u32 level,void * context,void ** retval)684 static acpi_status AMW0_set_cap_acpi_check_device_cb(acpi_handle handle,
685 	u32 level, void *context, void **retval)
686 {
687 	AMW0_set_cap_acpi_check_device_found = 1;
688 	return AE_OK;
689 }
690 
691 static const struct acpi_device_id norfkill_ids[] = {
692 	{ "VPC2004", 0},
693 	{ "IBM0068", 0},
694 	{ "LEN0068", 0},
695 	{ "", 0},
696 };
697 
AMW0_set_cap_acpi_check_device(void)698 static int AMW0_set_cap_acpi_check_device(void)
699 {
700 	const struct acpi_device_id *id;
701 
702 	for (id = norfkill_ids; id->id[0]; id++)
703 		acpi_get_devices(id->id, AMW0_set_cap_acpi_check_device_cb,
704 				NULL, NULL);
705 	return AMW0_set_cap_acpi_check_device_found;
706 }
707 
AMW0_set_capabilities(void)708 static acpi_status AMW0_set_capabilities(void)
709 {
710 	struct wmab_args args;
711 	struct wmab_ret ret;
712 	acpi_status status;
713 	struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
714 	union acpi_object *obj;
715 
716 	/*
717 	 * On laptops with this strange GUID (non Acer), normal probing doesn't
718 	 * work.
719 	 */
720 	if (wmi_has_guid(AMW0_GUID2)) {
721 		if ((quirks != &quirk_unknown) ||
722 		    !AMW0_set_cap_acpi_check_device())
723 			interface->capability |= ACER_CAP_WIRELESS;
724 		return AE_OK;
725 	}
726 
727 	args.eax = ACER_AMW0_WRITE;
728 	args.ecx = args.edx = 0;
729 
730 	args.ebx = 0xa2 << 8;
731 	args.ebx |= ACER_AMW0_WIRELESS_MASK;
732 
733 	status = wmab_execute(&args, &out);
734 	if (ACPI_FAILURE(status))
735 		return status;
736 
737 	obj = out.pointer;
738 	if (obj && obj->type == ACPI_TYPE_BUFFER &&
739 	obj->buffer.length == sizeof(struct wmab_ret)) {
740 		ret = *((struct wmab_ret *) obj->buffer.pointer);
741 	} else {
742 		status = AE_ERROR;
743 		goto out;
744 	}
745 
746 	if (ret.eax & 0x1)
747 		interface->capability |= ACER_CAP_WIRELESS;
748 
749 	args.ebx = 2 << 8;
750 	args.ebx |= ACER_AMW0_BLUETOOTH_MASK;
751 
752 	/*
753 	 * It's ok to use existing buffer for next wmab_execute call.
754 	 * But we need to kfree(out.pointer) if next wmab_execute fail.
755 	 */
756 	status = wmab_execute(&args, &out);
757 	if (ACPI_FAILURE(status))
758 		goto out;
759 
760 	obj = (union acpi_object *) out.pointer;
761 	if (obj && obj->type == ACPI_TYPE_BUFFER
762 	&& obj->buffer.length == sizeof(struct wmab_ret)) {
763 		ret = *((struct wmab_ret *) obj->buffer.pointer);
764 	} else {
765 		status = AE_ERROR;
766 		goto out;
767 	}
768 
769 	if (ret.eax & 0x1)
770 		interface->capability |= ACER_CAP_BLUETOOTH;
771 
772 	/*
773 	 * This appears to be safe to enable, since all Wistron based laptops
774 	 * appear to use the same EC register for brightness, even if they
775 	 * differ for wireless, etc
776 	 */
777 	if (quirks->brightness >= 0)
778 		interface->capability |= ACER_CAP_BRIGHTNESS;
779 
780 	status = AE_OK;
781 out:
782 	kfree(out.pointer);
783 	return status;
784 }
785 
786 static struct wmi_interface AMW0_interface = {
787 	.type = ACER_AMW0,
788 };
789 
790 static struct wmi_interface AMW0_V2_interface = {
791 	.type = ACER_AMW0_V2,
792 };
793 
794 /*
795  * New interface (The WMID interface)
796  */
797 static acpi_status
WMI_execute_u32(u32 method_id,u32 in,u32 * out)798 WMI_execute_u32(u32 method_id, u32 in, u32 *out)
799 {
800 	struct acpi_buffer input = { (acpi_size) sizeof(u32), (void *)(&in) };
801 	struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL };
802 	union acpi_object *obj;
803 	u32 tmp;
804 	acpi_status status;
805 
806 	status = wmi_evaluate_method(WMID_GUID1, 1, method_id, &input, &result);
807 
808 	if (ACPI_FAILURE(status))
809 		return status;
810 
811 	obj = (union acpi_object *) result.pointer;
812 	if (obj && obj->type == ACPI_TYPE_BUFFER &&
813 		(obj->buffer.length == sizeof(u32) ||
814 		obj->buffer.length == sizeof(u64))) {
815 		tmp = *((u32 *) obj->buffer.pointer);
816 	} else if (obj->type == ACPI_TYPE_INTEGER) {
817 		tmp = (u32) obj->integer.value;
818 	} else {
819 		tmp = 0;
820 	}
821 
822 	if (out)
823 		*out = tmp;
824 
825 	kfree(result.pointer);
826 
827 	return status;
828 }
829 
WMID_get_u32(u32 * value,u32 cap,struct wmi_interface * iface)830 static acpi_status WMID_get_u32(u32 *value, u32 cap,
831 struct wmi_interface *iface)
832 {
833 	acpi_status status;
834 	u8 tmp;
835 	u32 result, method_id = 0;
836 
837 	switch (cap) {
838 	case ACER_CAP_WIRELESS:
839 		method_id = ACER_WMID_GET_WIRELESS_METHODID;
840 		break;
841 	case ACER_CAP_BLUETOOTH:
842 		method_id = ACER_WMID_GET_BLUETOOTH_METHODID;
843 		break;
844 	case ACER_CAP_BRIGHTNESS:
845 		method_id = ACER_WMID_GET_BRIGHTNESS_METHODID;
846 		break;
847 	case ACER_CAP_THREEG:
848 		method_id = ACER_WMID_GET_THREEG_METHODID;
849 		break;
850 	case ACER_CAP_MAILLED:
851 		if (quirks->mailled == 1) {
852 			ec_read(0x9f, &tmp);
853 			*value = tmp & 0x1;
854 			return 0;
855 		}
856 	default:
857 		return AE_ERROR;
858 	}
859 	status = WMI_execute_u32(method_id, 0, &result);
860 
861 	if (ACPI_SUCCESS(status))
862 		*value = (u8)result;
863 
864 	return status;
865 }
866 
WMID_set_u32(u32 value,u32 cap,struct wmi_interface * iface)867 static acpi_status WMID_set_u32(u32 value, u32 cap, struct wmi_interface *iface)
868 {
869 	u32 method_id = 0;
870 	char param;
871 
872 	switch (cap) {
873 	case ACER_CAP_BRIGHTNESS:
874 		if (value > max_brightness)
875 			return AE_BAD_PARAMETER;
876 		method_id = ACER_WMID_SET_BRIGHTNESS_METHODID;
877 		break;
878 	case ACER_CAP_WIRELESS:
879 		if (value > 1)
880 			return AE_BAD_PARAMETER;
881 		method_id = ACER_WMID_SET_WIRELESS_METHODID;
882 		break;
883 	case ACER_CAP_BLUETOOTH:
884 		if (value > 1)
885 			return AE_BAD_PARAMETER;
886 		method_id = ACER_WMID_SET_BLUETOOTH_METHODID;
887 		break;
888 	case ACER_CAP_THREEG:
889 		if (value > 1)
890 			return AE_BAD_PARAMETER;
891 		method_id = ACER_WMID_SET_THREEG_METHODID;
892 		break;
893 	case ACER_CAP_MAILLED:
894 		if (value > 1)
895 			return AE_BAD_PARAMETER;
896 		if (quirks->mailled == 1) {
897 			param = value ? 0x92 : 0x93;
898 			i8042_lock_chip();
899 			i8042_command(&param, 0x1059);
900 			i8042_unlock_chip();
901 			return 0;
902 		}
903 		break;
904 	default:
905 		return AE_ERROR;
906 	}
907 	return WMI_execute_u32(method_id, (u32)value, NULL);
908 }
909 
wmid3_get_device_status(u32 * value,u16 device)910 static acpi_status wmid3_get_device_status(u32 *value, u16 device)
911 {
912 	struct wmid3_gds_return_value return_value;
913 	acpi_status status;
914 	union acpi_object *obj;
915 	struct wmid3_gds_input_param params = {
916 		.function_num = 0x1,
917 		.hotkey_number = 0x01,
918 		.devices = device,
919 	};
920 	struct acpi_buffer input = {
921 		sizeof(struct wmid3_gds_input_param),
922 		&params
923 	};
924 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
925 
926 	status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output);
927 	if (ACPI_FAILURE(status))
928 		return status;
929 
930 	obj = output.pointer;
931 
932 	if (!obj)
933 		return AE_ERROR;
934 	else if (obj->type != ACPI_TYPE_BUFFER) {
935 		kfree(obj);
936 		return AE_ERROR;
937 	}
938 	if (obj->buffer.length != 8) {
939 		pr_warn("Unknown buffer length %d\n", obj->buffer.length);
940 		kfree(obj);
941 		return AE_ERROR;
942 	}
943 
944 	return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
945 	kfree(obj);
946 
947 	if (return_value.error_code || return_value.ec_return_value)
948 		pr_warn("Get 0x%x Device Status failed: 0x%x - 0x%x\n",
949 			device,
950 			return_value.error_code,
951 			return_value.ec_return_value);
952 	else
953 		*value = !!(return_value.devices & device);
954 
955 	return status;
956 }
957 
wmid_v2_get_u32(u32 * value,u32 cap)958 static acpi_status wmid_v2_get_u32(u32 *value, u32 cap)
959 {
960 	u16 device;
961 
962 	switch (cap) {
963 	case ACER_CAP_WIRELESS:
964 		device = ACER_WMID3_GDS_WIRELESS;
965 		break;
966 	case ACER_CAP_BLUETOOTH:
967 		device = ACER_WMID3_GDS_BLUETOOTH;
968 		break;
969 	case ACER_CAP_THREEG:
970 		device = ACER_WMID3_GDS_THREEG;
971 		break;
972 	default:
973 		return AE_ERROR;
974 	}
975 	return wmid3_get_device_status(value, device);
976 }
977 
wmid3_set_device_status(u32 value,u16 device)978 static acpi_status wmid3_set_device_status(u32 value, u16 device)
979 {
980 	struct wmid3_gds_return_value return_value;
981 	acpi_status status;
982 	union acpi_object *obj;
983 	u16 devices;
984 	struct wmid3_gds_input_param params = {
985 		.function_num = 0x1,
986 		.hotkey_number = 0x01,
987 		.devices = commun_func_bitmap,
988 	};
989 	struct acpi_buffer input = {
990 		sizeof(struct wmid3_gds_input_param),
991 		&params
992 	};
993 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
994 	struct acpi_buffer output2 = { ACPI_ALLOCATE_BUFFER, NULL };
995 
996 	status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output);
997 	if (ACPI_FAILURE(status))
998 		return status;
999 
1000 	obj = output.pointer;
1001 
1002 	if (!obj)
1003 		return AE_ERROR;
1004 	else if (obj->type != ACPI_TYPE_BUFFER) {
1005 		kfree(obj);
1006 		return AE_ERROR;
1007 	}
1008 	if (obj->buffer.length != 8) {
1009 		pr_warning("Unknown buffer length %d\n", obj->buffer.length);
1010 		kfree(obj);
1011 		return AE_ERROR;
1012 	}
1013 
1014 	return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
1015 	kfree(obj);
1016 
1017 	if (return_value.error_code || return_value.ec_return_value) {
1018 		pr_warning("Get Current Device Status failed: "
1019 			"0x%x - 0x%x\n", return_value.error_code,
1020 			return_value.ec_return_value);
1021 		return status;
1022 	}
1023 
1024 	devices = return_value.devices;
1025 	params.function_num = 0x2;
1026 	params.hotkey_number = 0x01;
1027 	params.devices = (value) ? (devices | device) : (devices & ~device);
1028 
1029 	status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output2);
1030 	if (ACPI_FAILURE(status))
1031 		return status;
1032 
1033 	obj = output2.pointer;
1034 
1035 	if (!obj)
1036 		return AE_ERROR;
1037 	else if (obj->type != ACPI_TYPE_BUFFER) {
1038 		kfree(obj);
1039 		return AE_ERROR;
1040 	}
1041 	if (obj->buffer.length != 4) {
1042 		pr_warning("Unknown buffer length %d\n", obj->buffer.length);
1043 		kfree(obj);
1044 		return AE_ERROR;
1045 	}
1046 
1047 	return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
1048 	kfree(obj);
1049 
1050 	if (return_value.error_code || return_value.ec_return_value)
1051 		pr_warning("Set Device Status failed: "
1052 			"0x%x - 0x%x\n", return_value.error_code,
1053 			return_value.ec_return_value);
1054 
1055 	return status;
1056 }
1057 
wmid_v2_set_u32(u32 value,u32 cap)1058 static acpi_status wmid_v2_set_u32(u32 value, u32 cap)
1059 {
1060 	u16 device;
1061 
1062 	switch (cap) {
1063 	case ACER_CAP_WIRELESS:
1064 		device = ACER_WMID3_GDS_WIRELESS;
1065 		break;
1066 	case ACER_CAP_BLUETOOTH:
1067 		device = ACER_WMID3_GDS_BLUETOOTH;
1068 		break;
1069 	case ACER_CAP_THREEG:
1070 		device = ACER_WMID3_GDS_THREEG;
1071 		break;
1072 	default:
1073 		return AE_ERROR;
1074 	}
1075 	return wmid3_set_device_status(value, device);
1076 }
1077 
type_aa_dmi_decode(const struct dmi_header * header,void * dummy)1078 static void type_aa_dmi_decode(const struct dmi_header *header, void *dummy)
1079 {
1080 	struct hotkey_function_type_aa *type_aa;
1081 
1082 	/* We are looking for OEM-specific Type AAh */
1083 	if (header->type != 0xAA)
1084 		return;
1085 
1086 	has_type_aa = true;
1087 	type_aa = (struct hotkey_function_type_aa *) header;
1088 
1089 	pr_info("Function bitmap for Communication Button: 0x%x\n",
1090 		type_aa->commun_func_bitmap);
1091 	commun_func_bitmap = type_aa->commun_func_bitmap;
1092 
1093 	if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_WIRELESS)
1094 		interface->capability |= ACER_CAP_WIRELESS;
1095 	if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_THREEG)
1096 		interface->capability |= ACER_CAP_THREEG;
1097 	if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_BLUETOOTH)
1098 		interface->capability |= ACER_CAP_BLUETOOTH;
1099 }
1100 
WMID_set_capabilities(void)1101 static acpi_status WMID_set_capabilities(void)
1102 {
1103 	struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
1104 	union acpi_object *obj;
1105 	acpi_status status;
1106 	u32 devices;
1107 
1108 	status = wmi_query_block(WMID_GUID2, 1, &out);
1109 	if (ACPI_FAILURE(status))
1110 		return status;
1111 
1112 	obj = (union acpi_object *) out.pointer;
1113 	if (obj && obj->type == ACPI_TYPE_BUFFER &&
1114 		(obj->buffer.length == sizeof(u32) ||
1115 		obj->buffer.length == sizeof(u64))) {
1116 		devices = *((u32 *) obj->buffer.pointer);
1117 	} else if (obj->type == ACPI_TYPE_INTEGER) {
1118 		devices = (u32) obj->integer.value;
1119 	} else {
1120 		kfree(out.pointer);
1121 		return AE_ERROR;
1122 	}
1123 
1124 	pr_info("Function bitmap for Communication Device: 0x%x\n", devices);
1125 	if (devices & 0x07)
1126 		interface->capability |= ACER_CAP_WIRELESS;
1127 	if (devices & 0x40)
1128 		interface->capability |= ACER_CAP_THREEG;
1129 	if (devices & 0x10)
1130 		interface->capability |= ACER_CAP_BLUETOOTH;
1131 
1132 	if (!(devices & 0x20))
1133 		max_brightness = 0x9;
1134 
1135 	kfree(out.pointer);
1136 	return status;
1137 }
1138 
1139 static struct wmi_interface wmid_interface = {
1140 	.type = ACER_WMID,
1141 };
1142 
1143 static struct wmi_interface wmid_v2_interface = {
1144 	.type = ACER_WMID_v2,
1145 };
1146 
1147 /*
1148  * Generic Device (interface-independent)
1149  */
1150 
get_u32(u32 * value,u32 cap)1151 static acpi_status get_u32(u32 *value, u32 cap)
1152 {
1153 	acpi_status status = AE_ERROR;
1154 
1155 	switch (interface->type) {
1156 	case ACER_AMW0:
1157 		status = AMW0_get_u32(value, cap, interface);
1158 		break;
1159 	case ACER_AMW0_V2:
1160 		if (cap == ACER_CAP_MAILLED) {
1161 			status = AMW0_get_u32(value, cap, interface);
1162 			break;
1163 		}
1164 	case ACER_WMID:
1165 		status = WMID_get_u32(value, cap, interface);
1166 		break;
1167 	case ACER_WMID_v2:
1168 		if (cap & (ACER_CAP_WIRELESS |
1169 			   ACER_CAP_BLUETOOTH |
1170 			   ACER_CAP_THREEG))
1171 			status = wmid_v2_get_u32(value, cap);
1172 		else if (wmi_has_guid(WMID_GUID2))
1173 			status = WMID_get_u32(value, cap, interface);
1174 		break;
1175 	}
1176 
1177 	return status;
1178 }
1179 
set_u32(u32 value,u32 cap)1180 static acpi_status set_u32(u32 value, u32 cap)
1181 {
1182 	acpi_status status;
1183 
1184 	if (interface->capability & cap) {
1185 		switch (interface->type) {
1186 		case ACER_AMW0:
1187 			return AMW0_set_u32(value, cap, interface);
1188 		case ACER_AMW0_V2:
1189 			if (cap == ACER_CAP_MAILLED)
1190 				return AMW0_set_u32(value, cap, interface);
1191 
1192 			/*
1193 			 * On some models, some WMID methods don't toggle
1194 			 * properly. For those cases, we want to run the AMW0
1195 			 * method afterwards to be certain we've really toggled
1196 			 * the device state.
1197 			 */
1198 			if (cap == ACER_CAP_WIRELESS ||
1199 				cap == ACER_CAP_BLUETOOTH) {
1200 				status = WMID_set_u32(value, cap, interface);
1201 				if (ACPI_FAILURE(status))
1202 					return status;
1203 
1204 				return AMW0_set_u32(value, cap, interface);
1205 			}
1206 		case ACER_WMID:
1207 			return WMID_set_u32(value, cap, interface);
1208 		case ACER_WMID_v2:
1209 			if (cap & (ACER_CAP_WIRELESS |
1210 				   ACER_CAP_BLUETOOTH |
1211 				   ACER_CAP_THREEG))
1212 				return wmid_v2_set_u32(value, cap);
1213 			else if (wmi_has_guid(WMID_GUID2))
1214 				return WMID_set_u32(value, cap, interface);
1215 		default:
1216 			return AE_BAD_PARAMETER;
1217 		}
1218 	}
1219 	return AE_BAD_PARAMETER;
1220 }
1221 
acer_commandline_init(void)1222 static void __init acer_commandline_init(void)
1223 {
1224 	/*
1225 	 * These will all fail silently if the value given is invalid, or the
1226 	 * capability isn't available on the given interface
1227 	 */
1228 	if (mailled >= 0)
1229 		set_u32(mailled, ACER_CAP_MAILLED);
1230 	if (!has_type_aa && threeg >= 0)
1231 		set_u32(threeg, ACER_CAP_THREEG);
1232 	if (brightness >= 0)
1233 		set_u32(brightness, ACER_CAP_BRIGHTNESS);
1234 }
1235 
1236 /*
1237  * LED device (Mail LED only, no other LEDs known yet)
1238  */
mail_led_set(struct led_classdev * led_cdev,enum led_brightness value)1239 static void mail_led_set(struct led_classdev *led_cdev,
1240 enum led_brightness value)
1241 {
1242 	set_u32(value, ACER_CAP_MAILLED);
1243 }
1244 
1245 static struct led_classdev mail_led = {
1246 	.name = "acer-wmi::mail",
1247 	.brightness_set = mail_led_set,
1248 };
1249 
acer_led_init(struct device * dev)1250 static int __devinit acer_led_init(struct device *dev)
1251 {
1252 	return led_classdev_register(dev, &mail_led);
1253 }
1254 
acer_led_exit(void)1255 static void acer_led_exit(void)
1256 {
1257 	set_u32(LED_OFF, ACER_CAP_MAILLED);
1258 	led_classdev_unregister(&mail_led);
1259 }
1260 
1261 /*
1262  * Backlight device
1263  */
1264 static struct backlight_device *acer_backlight_device;
1265 
read_brightness(struct backlight_device * bd)1266 static int read_brightness(struct backlight_device *bd)
1267 {
1268 	u32 value;
1269 	get_u32(&value, ACER_CAP_BRIGHTNESS);
1270 	return value;
1271 }
1272 
update_bl_status(struct backlight_device * bd)1273 static int update_bl_status(struct backlight_device *bd)
1274 {
1275 	int intensity = bd->props.brightness;
1276 
1277 	if (bd->props.power != FB_BLANK_UNBLANK)
1278 		intensity = 0;
1279 	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
1280 		intensity = 0;
1281 
1282 	set_u32(intensity, ACER_CAP_BRIGHTNESS);
1283 
1284 	return 0;
1285 }
1286 
1287 static const struct backlight_ops acer_bl_ops = {
1288 	.get_brightness = read_brightness,
1289 	.update_status = update_bl_status,
1290 };
1291 
acer_backlight_init(struct device * dev)1292 static int __devinit acer_backlight_init(struct device *dev)
1293 {
1294 	struct backlight_properties props;
1295 	struct backlight_device *bd;
1296 
1297 	memset(&props, 0, sizeof(struct backlight_properties));
1298 	props.type = BACKLIGHT_PLATFORM;
1299 	props.max_brightness = max_brightness;
1300 	bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops,
1301 				       &props);
1302 	if (IS_ERR(bd)) {
1303 		pr_err("Could not register Acer backlight device\n");
1304 		acer_backlight_device = NULL;
1305 		return PTR_ERR(bd);
1306 	}
1307 
1308 	acer_backlight_device = bd;
1309 
1310 	bd->props.power = FB_BLANK_UNBLANK;
1311 	bd->props.brightness = read_brightness(bd);
1312 	backlight_update_status(bd);
1313 	return 0;
1314 }
1315 
acer_backlight_exit(void)1316 static void acer_backlight_exit(void)
1317 {
1318 	backlight_device_unregister(acer_backlight_device);
1319 }
1320 
1321 /*
1322  * Rfkill devices
1323  */
1324 static void acer_rfkill_update(struct work_struct *ignored);
1325 static DECLARE_DELAYED_WORK(acer_rfkill_work, acer_rfkill_update);
acer_rfkill_update(struct work_struct * ignored)1326 static void acer_rfkill_update(struct work_struct *ignored)
1327 {
1328 	u32 state;
1329 	acpi_status status;
1330 
1331 	if (has_cap(ACER_CAP_WIRELESS)) {
1332 		status = get_u32(&state, ACER_CAP_WIRELESS);
1333 		if (ACPI_SUCCESS(status)) {
1334 			if (quirks->wireless == 3)
1335 				rfkill_set_hw_state(wireless_rfkill, !state);
1336 			else
1337 				rfkill_set_sw_state(wireless_rfkill, !state);
1338 		}
1339 	}
1340 
1341 	if (has_cap(ACER_CAP_BLUETOOTH)) {
1342 		status = get_u32(&state, ACER_CAP_BLUETOOTH);
1343 		if (ACPI_SUCCESS(status))
1344 			rfkill_set_sw_state(bluetooth_rfkill, !state);
1345 	}
1346 
1347 	if (has_cap(ACER_CAP_THREEG) && wmi_has_guid(WMID_GUID3)) {
1348 		status = get_u32(&state, ACER_WMID3_GDS_THREEG);
1349 		if (ACPI_SUCCESS(status))
1350 			rfkill_set_sw_state(threeg_rfkill, !state);
1351 	}
1352 
1353 	schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
1354 }
1355 
acer_rfkill_set(void * data,bool blocked)1356 static int acer_rfkill_set(void *data, bool blocked)
1357 {
1358 	acpi_status status;
1359 	u32 cap = (unsigned long)data;
1360 
1361 	if (rfkill_inited) {
1362 		status = set_u32(!blocked, cap);
1363 		if (ACPI_FAILURE(status))
1364 			return -ENODEV;
1365 	}
1366 
1367 	return 0;
1368 }
1369 
1370 static const struct rfkill_ops acer_rfkill_ops = {
1371 	.set_block = acer_rfkill_set,
1372 };
1373 
acer_rfkill_register(struct device * dev,enum rfkill_type type,char * name,u32 cap)1374 static struct rfkill *acer_rfkill_register(struct device *dev,
1375 					   enum rfkill_type type,
1376 					   char *name, u32 cap)
1377 {
1378 	int err;
1379 	struct rfkill *rfkill_dev;
1380 	u32 state;
1381 	acpi_status status;
1382 
1383 	rfkill_dev = rfkill_alloc(name, dev, type,
1384 				  &acer_rfkill_ops,
1385 				  (void *)(unsigned long)cap);
1386 	if (!rfkill_dev)
1387 		return ERR_PTR(-ENOMEM);
1388 
1389 	status = get_u32(&state, cap);
1390 
1391 	err = rfkill_register(rfkill_dev);
1392 	if (err) {
1393 		rfkill_destroy(rfkill_dev);
1394 		return ERR_PTR(err);
1395 	}
1396 
1397 	if (ACPI_SUCCESS(status))
1398 		rfkill_set_sw_state(rfkill_dev, !state);
1399 
1400 	return rfkill_dev;
1401 }
1402 
acer_rfkill_init(struct device * dev)1403 static int acer_rfkill_init(struct device *dev)
1404 {
1405 	int err;
1406 
1407 	if (has_cap(ACER_CAP_WIRELESS)) {
1408 		wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN,
1409 			"acer-wireless", ACER_CAP_WIRELESS);
1410 		if (IS_ERR(wireless_rfkill)) {
1411 			err = PTR_ERR(wireless_rfkill);
1412 			goto error_wireless;
1413 		}
1414 	}
1415 
1416 	if (has_cap(ACER_CAP_BLUETOOTH)) {
1417 		bluetooth_rfkill = acer_rfkill_register(dev,
1418 			RFKILL_TYPE_BLUETOOTH, "acer-bluetooth",
1419 			ACER_CAP_BLUETOOTH);
1420 		if (IS_ERR(bluetooth_rfkill)) {
1421 			err = PTR_ERR(bluetooth_rfkill);
1422 			goto error_bluetooth;
1423 		}
1424 	}
1425 
1426 	if (has_cap(ACER_CAP_THREEG)) {
1427 		threeg_rfkill = acer_rfkill_register(dev,
1428 			RFKILL_TYPE_WWAN, "acer-threeg",
1429 			ACER_CAP_THREEG);
1430 		if (IS_ERR(threeg_rfkill)) {
1431 			err = PTR_ERR(threeg_rfkill);
1432 			goto error_threeg;
1433 		}
1434 	}
1435 
1436 	rfkill_inited = true;
1437 
1438 	if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) &&
1439 	    has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG))
1440 		schedule_delayed_work(&acer_rfkill_work,
1441 			round_jiffies_relative(HZ));
1442 
1443 	return 0;
1444 
1445 error_threeg:
1446 	if (has_cap(ACER_CAP_BLUETOOTH)) {
1447 		rfkill_unregister(bluetooth_rfkill);
1448 		rfkill_destroy(bluetooth_rfkill);
1449 	}
1450 error_bluetooth:
1451 	if (has_cap(ACER_CAP_WIRELESS)) {
1452 		rfkill_unregister(wireless_rfkill);
1453 		rfkill_destroy(wireless_rfkill);
1454 	}
1455 error_wireless:
1456 	return err;
1457 }
1458 
acer_rfkill_exit(void)1459 static void acer_rfkill_exit(void)
1460 {
1461 	if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) &&
1462 	    has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG))
1463 		cancel_delayed_work_sync(&acer_rfkill_work);
1464 
1465 	if (has_cap(ACER_CAP_WIRELESS)) {
1466 		rfkill_unregister(wireless_rfkill);
1467 		rfkill_destroy(wireless_rfkill);
1468 	}
1469 
1470 	if (has_cap(ACER_CAP_BLUETOOTH)) {
1471 		rfkill_unregister(bluetooth_rfkill);
1472 		rfkill_destroy(bluetooth_rfkill);
1473 	}
1474 
1475 	if (has_cap(ACER_CAP_THREEG)) {
1476 		rfkill_unregister(threeg_rfkill);
1477 		rfkill_destroy(threeg_rfkill);
1478 	}
1479 	return;
1480 }
1481 
1482 /*
1483  * sysfs interface
1484  */
show_bool_threeg(struct device * dev,struct device_attribute * attr,char * buf)1485 static ssize_t show_bool_threeg(struct device *dev,
1486 	struct device_attribute *attr, char *buf)
1487 {
1488 	u32 result; \
1489 	acpi_status status;
1490 
1491 	pr_info("This threeg sysfs will be removed in 2012"
1492 		" - used by: %s\n", current->comm);
1493 	status = get_u32(&result, ACER_CAP_THREEG);
1494 	if (ACPI_SUCCESS(status))
1495 		return sprintf(buf, "%u\n", result);
1496 	return sprintf(buf, "Read error\n");
1497 }
1498 
set_bool_threeg(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)1499 static ssize_t set_bool_threeg(struct device *dev,
1500 	struct device_attribute *attr, const char *buf, size_t count)
1501 {
1502 	u32 tmp = simple_strtoul(buf, NULL, 10);
1503 	acpi_status status = set_u32(tmp, ACER_CAP_THREEG);
1504 	pr_info("This threeg sysfs will be removed in 2012"
1505 		" - used by: %s\n", current->comm);
1506 	if (ACPI_FAILURE(status))
1507 		return -EINVAL;
1508 	return count;
1509 }
1510 static DEVICE_ATTR(threeg, S_IRUGO | S_IWUSR, show_bool_threeg,
1511 	set_bool_threeg);
1512 
show_interface(struct device * dev,struct device_attribute * attr,char * buf)1513 static ssize_t show_interface(struct device *dev, struct device_attribute *attr,
1514 	char *buf)
1515 {
1516 	pr_info("This interface sysfs will be removed in 2012"
1517 		" - used by: %s\n", current->comm);
1518 	switch (interface->type) {
1519 	case ACER_AMW0:
1520 		return sprintf(buf, "AMW0\n");
1521 	case ACER_AMW0_V2:
1522 		return sprintf(buf, "AMW0 v2\n");
1523 	case ACER_WMID:
1524 		return sprintf(buf, "WMID\n");
1525 	case ACER_WMID_v2:
1526 		return sprintf(buf, "WMID v2\n");
1527 	default:
1528 		return sprintf(buf, "Error!\n");
1529 	}
1530 }
1531 
1532 static DEVICE_ATTR(interface, S_IRUGO, show_interface, NULL);
1533 
acer_wmi_notify(u32 value,void * context)1534 static void acer_wmi_notify(u32 value, void *context)
1535 {
1536 	struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
1537 	union acpi_object *obj;
1538 	struct event_return_value return_value;
1539 	acpi_status status;
1540 	u16 device_state;
1541 	const struct key_entry *key;
1542 
1543 	status = wmi_get_event_data(value, &response);
1544 	if (status != AE_OK) {
1545 		pr_warn("bad event status 0x%x\n", status);
1546 		return;
1547 	}
1548 
1549 	obj = (union acpi_object *)response.pointer;
1550 
1551 	if (!obj)
1552 		return;
1553 	if (obj->type != ACPI_TYPE_BUFFER) {
1554 		pr_warn("Unknown response received %d\n", obj->type);
1555 		kfree(obj);
1556 		return;
1557 	}
1558 	if (obj->buffer.length != 8) {
1559 		pr_warn("Unknown buffer length %d\n", obj->buffer.length);
1560 		kfree(obj);
1561 		return;
1562 	}
1563 
1564 	return_value = *((struct event_return_value *)obj->buffer.pointer);
1565 	kfree(obj);
1566 
1567 	switch (return_value.function) {
1568 	case WMID_HOTKEY_EVENT:
1569 		device_state = return_value.device_state;
1570 		pr_debug("device state: 0x%x\n", device_state);
1571 
1572 		key = sparse_keymap_entry_from_scancode(acer_wmi_input_dev,
1573 							return_value.key_num);
1574 		if (!key) {
1575 			pr_warn("Unknown key number - 0x%x\n",
1576 				return_value.key_num);
1577 		} else {
1578 			switch (key->keycode) {
1579 			case KEY_WLAN:
1580 			case KEY_BLUETOOTH:
1581 				if (has_cap(ACER_CAP_WIRELESS))
1582 					rfkill_set_sw_state(wireless_rfkill,
1583 						!(device_state & ACER_WMID3_GDS_WIRELESS));
1584 				if (has_cap(ACER_CAP_THREEG))
1585 					rfkill_set_sw_state(threeg_rfkill,
1586 						!(device_state & ACER_WMID3_GDS_THREEG));
1587 				if (has_cap(ACER_CAP_BLUETOOTH))
1588 					rfkill_set_sw_state(bluetooth_rfkill,
1589 						!(device_state & ACER_WMID3_GDS_BLUETOOTH));
1590 				break;
1591 			}
1592 			sparse_keymap_report_entry(acer_wmi_input_dev, key,
1593 						   1, true);
1594 		}
1595 		break;
1596 	default:
1597 		pr_warn("Unknown function number - %d - %d\n",
1598 			return_value.function, return_value.key_num);
1599 		break;
1600 	}
1601 }
1602 
1603 static acpi_status
wmid3_set_lm_mode(struct lm_input_params * params,struct lm_return_value * return_value)1604 wmid3_set_lm_mode(struct lm_input_params *params,
1605 		  struct lm_return_value *return_value)
1606 {
1607 	acpi_status status;
1608 	union acpi_object *obj;
1609 
1610 	struct acpi_buffer input = { sizeof(struct lm_input_params), params };
1611 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
1612 
1613 	status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output);
1614 	if (ACPI_FAILURE(status))
1615 		return status;
1616 
1617 	obj = output.pointer;
1618 
1619 	if (!obj)
1620 		return AE_ERROR;
1621 	else if (obj->type != ACPI_TYPE_BUFFER) {
1622 		kfree(obj);
1623 		return AE_ERROR;
1624 	}
1625 	if (obj->buffer.length != 4) {
1626 		pr_warn("Unknown buffer length %d\n", obj->buffer.length);
1627 		kfree(obj);
1628 		return AE_ERROR;
1629 	}
1630 
1631 	*return_value = *((struct lm_return_value *)obj->buffer.pointer);
1632 	kfree(obj);
1633 
1634 	return status;
1635 }
1636 
acer_wmi_enable_ec_raw(void)1637 static int acer_wmi_enable_ec_raw(void)
1638 {
1639 	struct lm_return_value return_value;
1640 	acpi_status status;
1641 	struct lm_input_params params = {
1642 		.function_num = 0x1,
1643 		.commun_devices = 0xFFFF,
1644 		.devices = 0xFFFF,
1645 		.lm_status = 0x00,            /* Launch Manager Deactive */
1646 	};
1647 
1648 	status = wmid3_set_lm_mode(&params, &return_value);
1649 
1650 	if (return_value.error_code || return_value.ec_return_value)
1651 		pr_warn("Enabling EC raw mode failed: 0x%x - 0x%x\n",
1652 			return_value.error_code,
1653 			return_value.ec_return_value);
1654 	else
1655 		pr_info("Enabled EC raw mode\n");
1656 
1657 	return status;
1658 }
1659 
acer_wmi_enable_lm(void)1660 static int acer_wmi_enable_lm(void)
1661 {
1662 	struct lm_return_value return_value;
1663 	acpi_status status;
1664 	struct lm_input_params params = {
1665 		.function_num = 0x1,
1666 		.commun_devices = 0xFFFF,
1667 		.devices = 0xFFFF,
1668 		.lm_status = 0x01,            /* Launch Manager Active */
1669 	};
1670 
1671 	status = wmid3_set_lm_mode(&params, &return_value);
1672 
1673 	if (return_value.error_code || return_value.ec_return_value)
1674 		pr_warn("Enabling Launch Manager failed: 0x%x - 0x%x\n",
1675 			return_value.error_code,
1676 			return_value.ec_return_value);
1677 
1678 	return status;
1679 }
1680 
acer_wmi_input_setup(void)1681 static int __init acer_wmi_input_setup(void)
1682 {
1683 	acpi_status status;
1684 	int err;
1685 
1686 	acer_wmi_input_dev = input_allocate_device();
1687 	if (!acer_wmi_input_dev)
1688 		return -ENOMEM;
1689 
1690 	acer_wmi_input_dev->name = "Acer WMI hotkeys";
1691 	acer_wmi_input_dev->phys = "wmi/input0";
1692 	acer_wmi_input_dev->id.bustype = BUS_HOST;
1693 
1694 	err = sparse_keymap_setup(acer_wmi_input_dev, acer_wmi_keymap, NULL);
1695 	if (err)
1696 		goto err_free_dev;
1697 
1698 	status = wmi_install_notify_handler(ACERWMID_EVENT_GUID,
1699 						acer_wmi_notify, NULL);
1700 	if (ACPI_FAILURE(status)) {
1701 		err = -EIO;
1702 		goto err_free_keymap;
1703 	}
1704 
1705 	err = input_register_device(acer_wmi_input_dev);
1706 	if (err)
1707 		goto err_uninstall_notifier;
1708 
1709 	return 0;
1710 
1711 err_uninstall_notifier:
1712 	wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
1713 err_free_keymap:
1714 	sparse_keymap_free(acer_wmi_input_dev);
1715 err_free_dev:
1716 	input_free_device(acer_wmi_input_dev);
1717 	return err;
1718 }
1719 
acer_wmi_input_destroy(void)1720 static void acer_wmi_input_destroy(void)
1721 {
1722 	wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
1723 	sparse_keymap_free(acer_wmi_input_dev);
1724 	input_unregister_device(acer_wmi_input_dev);
1725 }
1726 
1727 /*
1728  * debugfs functions
1729  */
get_wmid_devices(void)1730 static u32 get_wmid_devices(void)
1731 {
1732 	struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
1733 	union acpi_object *obj;
1734 	acpi_status status;
1735 	u32 devices = 0;
1736 
1737 	status = wmi_query_block(WMID_GUID2, 1, &out);
1738 	if (ACPI_FAILURE(status))
1739 		return 0;
1740 
1741 	obj = (union acpi_object *) out.pointer;
1742 	if (obj && obj->type == ACPI_TYPE_BUFFER &&
1743 		(obj->buffer.length == sizeof(u32) ||
1744 		obj->buffer.length == sizeof(u64))) {
1745 		devices = *((u32 *) obj->buffer.pointer);
1746 	} else if (obj->type == ACPI_TYPE_INTEGER) {
1747 		devices = (u32) obj->integer.value;
1748 	}
1749 
1750 	kfree(out.pointer);
1751 	return devices;
1752 }
1753 
1754 /*
1755  * Platform device
1756  */
acer_platform_probe(struct platform_device * device)1757 static int __devinit acer_platform_probe(struct platform_device *device)
1758 {
1759 	int err;
1760 
1761 	if (has_cap(ACER_CAP_MAILLED)) {
1762 		err = acer_led_init(&device->dev);
1763 		if (err)
1764 			goto error_mailled;
1765 	}
1766 
1767 	if (has_cap(ACER_CAP_BRIGHTNESS)) {
1768 		err = acer_backlight_init(&device->dev);
1769 		if (err)
1770 			goto error_brightness;
1771 	}
1772 
1773 	err = acer_rfkill_init(&device->dev);
1774 	if (err)
1775 		goto error_rfkill;
1776 
1777 	return err;
1778 
1779 error_rfkill:
1780 	if (has_cap(ACER_CAP_BRIGHTNESS))
1781 		acer_backlight_exit();
1782 error_brightness:
1783 	if (has_cap(ACER_CAP_MAILLED))
1784 		acer_led_exit();
1785 error_mailled:
1786 	return err;
1787 }
1788 
acer_platform_remove(struct platform_device * device)1789 static int acer_platform_remove(struct platform_device *device)
1790 {
1791 	if (has_cap(ACER_CAP_MAILLED))
1792 		acer_led_exit();
1793 	if (has_cap(ACER_CAP_BRIGHTNESS))
1794 		acer_backlight_exit();
1795 
1796 	acer_rfkill_exit();
1797 	return 0;
1798 }
1799 
acer_platform_suspend(struct platform_device * dev,pm_message_t state)1800 static int acer_platform_suspend(struct platform_device *dev,
1801 pm_message_t state)
1802 {
1803 	u32 value;
1804 	struct acer_data *data = &interface->data;
1805 
1806 	if (!data)
1807 		return -ENOMEM;
1808 
1809 	if (has_cap(ACER_CAP_MAILLED)) {
1810 		get_u32(&value, ACER_CAP_MAILLED);
1811 		set_u32(LED_OFF, ACER_CAP_MAILLED);
1812 		data->mailled = value;
1813 	}
1814 
1815 	if (has_cap(ACER_CAP_BRIGHTNESS)) {
1816 		get_u32(&value, ACER_CAP_BRIGHTNESS);
1817 		data->brightness = value;
1818 	}
1819 
1820 	return 0;
1821 }
1822 
acer_platform_resume(struct platform_device * device)1823 static int acer_platform_resume(struct platform_device *device)
1824 {
1825 	struct acer_data *data = &interface->data;
1826 
1827 	if (!data)
1828 		return -ENOMEM;
1829 
1830 	if (has_cap(ACER_CAP_MAILLED))
1831 		set_u32(data->mailled, ACER_CAP_MAILLED);
1832 
1833 	if (has_cap(ACER_CAP_BRIGHTNESS))
1834 		set_u32(data->brightness, ACER_CAP_BRIGHTNESS);
1835 
1836 	return 0;
1837 }
1838 
acer_platform_shutdown(struct platform_device * device)1839 static void acer_platform_shutdown(struct platform_device *device)
1840 {
1841 	struct acer_data *data = &interface->data;
1842 
1843 	if (!data)
1844 		return;
1845 
1846 	if (has_cap(ACER_CAP_MAILLED))
1847 		set_u32(LED_OFF, ACER_CAP_MAILLED);
1848 }
1849 
1850 static struct platform_driver acer_platform_driver = {
1851 	.driver = {
1852 		.name = "acer-wmi",
1853 		.owner = THIS_MODULE,
1854 	},
1855 	.probe = acer_platform_probe,
1856 	.remove = acer_platform_remove,
1857 	.suspend = acer_platform_suspend,
1858 	.resume = acer_platform_resume,
1859 	.shutdown = acer_platform_shutdown,
1860 };
1861 
1862 static struct platform_device *acer_platform_device;
1863 
remove_sysfs(struct platform_device * device)1864 static int remove_sysfs(struct platform_device *device)
1865 {
1866 	if (has_cap(ACER_CAP_THREEG))
1867 		device_remove_file(&device->dev, &dev_attr_threeg);
1868 
1869 	device_remove_file(&device->dev, &dev_attr_interface);
1870 
1871 	return 0;
1872 }
1873 
create_sysfs(void)1874 static int create_sysfs(void)
1875 {
1876 	int retval = -ENOMEM;
1877 
1878 	if (has_cap(ACER_CAP_THREEG)) {
1879 		retval = device_create_file(&acer_platform_device->dev,
1880 			&dev_attr_threeg);
1881 		if (retval)
1882 			goto error_sysfs;
1883 	}
1884 
1885 	retval = device_create_file(&acer_platform_device->dev,
1886 		&dev_attr_interface);
1887 	if (retval)
1888 		goto error_sysfs;
1889 
1890 	return 0;
1891 
1892 error_sysfs:
1893 		remove_sysfs(acer_platform_device);
1894 	return retval;
1895 }
1896 
remove_debugfs(void)1897 static void remove_debugfs(void)
1898 {
1899 	debugfs_remove(interface->debug.devices);
1900 	debugfs_remove(interface->debug.root);
1901 }
1902 
create_debugfs(void)1903 static int create_debugfs(void)
1904 {
1905 	interface->debug.root = debugfs_create_dir("acer-wmi", NULL);
1906 	if (!interface->debug.root) {
1907 		pr_err("Failed to create debugfs directory");
1908 		return -ENOMEM;
1909 	}
1910 
1911 	interface->debug.devices = debugfs_create_u32("devices", S_IRUGO,
1912 					interface->debug.root,
1913 					&interface->debug.wmid_devices);
1914 	if (!interface->debug.devices)
1915 		goto error_debugfs;
1916 
1917 	return 0;
1918 
1919 error_debugfs:
1920 	remove_debugfs();
1921 	return -ENOMEM;
1922 }
1923 
acer_wmi_init(void)1924 static int __init acer_wmi_init(void)
1925 {
1926 	int err;
1927 
1928 	pr_info("Acer Laptop ACPI-WMI Extras\n");
1929 
1930 	if (dmi_check_system(acer_blacklist)) {
1931 		pr_info("Blacklisted hardware detected - not loading\n");
1932 		return -ENODEV;
1933 	}
1934 
1935 	find_quirks();
1936 
1937 	/*
1938 	 * Detect which ACPI-WMI interface we're using.
1939 	 */
1940 	if (wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1))
1941 		interface = &AMW0_V2_interface;
1942 
1943 	if (!wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1))
1944 		interface = &wmid_interface;
1945 
1946 	if (wmi_has_guid(WMID_GUID3))
1947 		interface = &wmid_v2_interface;
1948 
1949 	if (interface)
1950 		dmi_walk(type_aa_dmi_decode, NULL);
1951 
1952 	if (wmi_has_guid(WMID_GUID2) && interface) {
1953 		if (!has_type_aa && ACPI_FAILURE(WMID_set_capabilities())) {
1954 			pr_err("Unable to detect available WMID devices\n");
1955 			return -ENODEV;
1956 		}
1957 		/* WMID always provides brightness methods */
1958 		interface->capability |= ACER_CAP_BRIGHTNESS;
1959 	} else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa) {
1960 		pr_err("No WMID device detection method found\n");
1961 		return -ENODEV;
1962 	}
1963 
1964 	if (wmi_has_guid(AMW0_GUID1) && !wmi_has_guid(WMID_GUID1)) {
1965 		interface = &AMW0_interface;
1966 
1967 		if (ACPI_FAILURE(AMW0_set_capabilities())) {
1968 			pr_err("Unable to detect available AMW0 devices\n");
1969 			return -ENODEV;
1970 		}
1971 	}
1972 
1973 	if (wmi_has_guid(AMW0_GUID1))
1974 		AMW0_find_mailled();
1975 
1976 	if (!interface) {
1977 		pr_err("No or unsupported WMI interface, unable to load\n");
1978 		return -ENODEV;
1979 	}
1980 
1981 	set_quirks();
1982 
1983 	if (acpi_video_backlight_support()) {
1984 		interface->capability &= ~ACER_CAP_BRIGHTNESS;
1985 		pr_info("Brightness must be controlled by "
1986 		       "generic video driver\n");
1987 	}
1988 
1989 	if (wmi_has_guid(WMID_GUID3)) {
1990 		if (ec_raw_mode) {
1991 			if (ACPI_FAILURE(acer_wmi_enable_ec_raw())) {
1992 				pr_err("Cannot enable EC raw mode\n");
1993 				return -ENODEV;
1994 			}
1995 		} else if (ACPI_FAILURE(acer_wmi_enable_lm())) {
1996 			pr_err("Cannot enable Launch Manager mode\n");
1997 			return -ENODEV;
1998 		}
1999 	} else if (ec_raw_mode) {
2000 		pr_info("No WMID EC raw mode enable method\n");
2001 	}
2002 
2003 	if (wmi_has_guid(ACERWMID_EVENT_GUID)) {
2004 		err = acer_wmi_input_setup();
2005 		if (err)
2006 			return err;
2007 	}
2008 
2009 	err = platform_driver_register(&acer_platform_driver);
2010 	if (err) {
2011 		pr_err("Unable to register platform driver.\n");
2012 		goto error_platform_register;
2013 	}
2014 
2015 	acer_platform_device = platform_device_alloc("acer-wmi", -1);
2016 	if (!acer_platform_device) {
2017 		err = -ENOMEM;
2018 		goto error_device_alloc;
2019 	}
2020 
2021 	err = platform_device_add(acer_platform_device);
2022 	if (err)
2023 		goto error_device_add;
2024 
2025 	err = create_sysfs();
2026 	if (err)
2027 		goto error_create_sys;
2028 
2029 	if (wmi_has_guid(WMID_GUID2)) {
2030 		interface->debug.wmid_devices = get_wmid_devices();
2031 		err = create_debugfs();
2032 		if (err)
2033 			goto error_create_debugfs;
2034 	}
2035 
2036 	/* Override any initial settings with values from the commandline */
2037 	acer_commandline_init();
2038 
2039 	return 0;
2040 
2041 error_create_debugfs:
2042 	remove_sysfs(acer_platform_device);
2043 error_create_sys:
2044 	platform_device_del(acer_platform_device);
2045 error_device_add:
2046 	platform_device_put(acer_platform_device);
2047 error_device_alloc:
2048 	platform_driver_unregister(&acer_platform_driver);
2049 error_platform_register:
2050 	if (wmi_has_guid(ACERWMID_EVENT_GUID))
2051 		acer_wmi_input_destroy();
2052 
2053 	return err;
2054 }
2055 
acer_wmi_exit(void)2056 static void __exit acer_wmi_exit(void)
2057 {
2058 	if (wmi_has_guid(ACERWMID_EVENT_GUID))
2059 		acer_wmi_input_destroy();
2060 
2061 	remove_sysfs(acer_platform_device);
2062 	remove_debugfs();
2063 	platform_device_unregister(acer_platform_device);
2064 	platform_driver_unregister(&acer_platform_driver);
2065 
2066 	pr_info("Acer Laptop WMI Extras unloaded\n");
2067 	return;
2068 }
2069 
2070 module_init(acer_wmi_init);
2071 module_exit(acer_wmi_exit);
2072