1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  Acer WMI Laptop Extras
4  *
5  *  Copyright (C) 2007-2009	Carlos Corbacho <carlos@strangeworlds.co.uk>
6  *
7  *  Based on acer_acpi:
8  *    Copyright (C) 2005-2007	E.M. Smith
9  *    Copyright (C) 2007-2008	Carlos Corbacho <cathectic@gmail.com>
10  */
11 
12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13 
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/types.h>
18 #include <linux/dmi.h>
19 #include <linux/fb.h>
20 #include <linux/backlight.h>
21 #include <linux/leds.h>
22 #include <linux/platform_device.h>
23 #include <linux/acpi.h>
24 #include <linux/i8042.h>
25 #include <linux/rfkill.h>
26 #include <linux/workqueue.h>
27 #include <linux/debugfs.h>
28 #include <linux/slab.h>
29 #include <linux/input.h>
30 #include <linux/input/sparse-keymap.h>
31 #include <acpi/video.h>
32 
33 MODULE_AUTHOR("Carlos Corbacho");
34 MODULE_DESCRIPTION("Acer Laptop WMI Extras Driver");
35 MODULE_LICENSE("GPL");
36 
37 /*
38  * Magic Number
39  * Meaning is unknown - this number is required for writing to ACPI for AMW0
40  * (it's also used in acerhk when directly accessing the BIOS)
41  */
42 #define ACER_AMW0_WRITE	0x9610
43 
44 /*
45  * Bit masks for the AMW0 interface
46  */
47 #define ACER_AMW0_WIRELESS_MASK  0x35
48 #define ACER_AMW0_BLUETOOTH_MASK 0x34
49 #define ACER_AMW0_MAILLED_MASK   0x31
50 
51 /*
52  * Method IDs for WMID interface
53  */
54 #define ACER_WMID_GET_WIRELESS_METHODID		1
55 #define ACER_WMID_GET_BLUETOOTH_METHODID	2
56 #define ACER_WMID_GET_BRIGHTNESS_METHODID	3
57 #define ACER_WMID_SET_WIRELESS_METHODID		4
58 #define ACER_WMID_SET_BLUETOOTH_METHODID	5
59 #define ACER_WMID_SET_BRIGHTNESS_METHODID	6
60 #define ACER_WMID_GET_THREEG_METHODID		10
61 #define ACER_WMID_SET_THREEG_METHODID		11
62 
63 #define ACER_WMID_SET_GAMING_LED_METHODID 2
64 #define ACER_WMID_GET_GAMING_LED_METHODID 4
65 #define ACER_WMID_SET_GAMING_FAN_BEHAVIOR 14
66 #define ACER_WMID_SET_GAMING_MISC_SETTING_METHODID 22
67 
68 /*
69  * Acer ACPI method GUIDs
70  */
71 #define AMW0_GUID1		"67C3371D-95A3-4C37-BB61-DD47B491DAAB"
72 #define AMW0_GUID2		"431F16ED-0C2B-444C-B267-27DEB140CF9C"
73 #define WMID_GUID1		"6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3"
74 #define WMID_GUID2		"95764E09-FB56-4E83-B31A-37761F60994A"
75 #define WMID_GUID3		"61EF69EA-865C-4BC3-A502-A0DEBA0CB531"
76 #define WMID_GUID4		"7A4DDFE7-5B5D-40B4-8595-4408E0CC7F56"
77 
78 /*
79  * Acer ACPI event GUIDs
80  */
81 #define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026"
82 
83 MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
84 MODULE_ALIAS("wmi:6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3");
85 MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
86 
87 enum acer_wmi_event_ids {
88 	WMID_HOTKEY_EVENT = 0x1,
89 	WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5,
90 	WMID_GAMING_TURBO_KEY_EVENT = 0x7,
91 };
92 
93 static const struct key_entry acer_wmi_keymap[] __initconst = {
94 	{KE_KEY, 0x01, {KEY_WLAN} },     /* WiFi */
95 	{KE_KEY, 0x03, {KEY_WLAN} },     /* WiFi */
96 	{KE_KEY, 0x04, {KEY_WLAN} },     /* WiFi */
97 	{KE_KEY, 0x12, {KEY_BLUETOOTH} },	/* BT */
98 	{KE_KEY, 0x21, {KEY_PROG1} },    /* Backup */
99 	{KE_KEY, 0x22, {KEY_PROG2} },    /* Arcade */
100 	{KE_KEY, 0x23, {KEY_PROG3} },    /* P_Key */
101 	{KE_KEY, 0x24, {KEY_PROG4} },    /* Social networking_Key */
102 	{KE_KEY, 0x27, {KEY_HELP} },
103 	{KE_KEY, 0x29, {KEY_PROG3} },    /* P_Key for TM8372 */
104 	{KE_IGNORE, 0x41, {KEY_MUTE} },
105 	{KE_IGNORE, 0x42, {KEY_PREVIOUSSONG} },
106 	{KE_IGNORE, 0x4d, {KEY_PREVIOUSSONG} },
107 	{KE_IGNORE, 0x43, {KEY_NEXTSONG} },
108 	{KE_IGNORE, 0x4e, {KEY_NEXTSONG} },
109 	{KE_IGNORE, 0x44, {KEY_PLAYPAUSE} },
110 	{KE_IGNORE, 0x4f, {KEY_PLAYPAUSE} },
111 	{KE_IGNORE, 0x45, {KEY_STOP} },
112 	{KE_IGNORE, 0x50, {KEY_STOP} },
113 	{KE_IGNORE, 0x48, {KEY_VOLUMEUP} },
114 	{KE_IGNORE, 0x49, {KEY_VOLUMEDOWN} },
115 	{KE_IGNORE, 0x4a, {KEY_VOLUMEDOWN} },
116 	/*
117 	 * 0x61 is KEY_SWITCHVIDEOMODE. Usually this is a duplicate input event
118 	 * with the "Video Bus" input device events. But sometimes it is not
119 	 * a dup. Map it to KEY_UNKNOWN instead of using KE_IGNORE so that
120 	 * udev/hwdb can override it on systems where it is not a dup.
121 	 */
122 	{KE_KEY, 0x61, {KEY_UNKNOWN} },
123 	{KE_IGNORE, 0x62, {KEY_BRIGHTNESSUP} },
124 	{KE_IGNORE, 0x63, {KEY_BRIGHTNESSDOWN} },
125 	{KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} },	/* Display Switch */
126 	{KE_IGNORE, 0x81, {KEY_SLEEP} },
127 	{KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} },	/* Touch Pad Toggle */
128 	{KE_IGNORE, 0x84, {KEY_KBDILLUMTOGGLE} }, /* Automatic Keyboard background light toggle */
129 	{KE_KEY, KEY_TOUCHPAD_ON, {KEY_TOUCHPAD_ON} },
130 	{KE_KEY, KEY_TOUCHPAD_OFF, {KEY_TOUCHPAD_OFF} },
131 	{KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} },
132 	{KE_KEY, 0x85, {KEY_TOUCHPAD_TOGGLE} },
133 	{KE_KEY, 0x86, {KEY_WLAN} },
134 	{KE_KEY, 0x87, {KEY_POWER} },
135 	{KE_END, 0}
136 };
137 
138 static struct input_dev *acer_wmi_input_dev;
139 static struct input_dev *acer_wmi_accel_dev;
140 
141 struct event_return_value {
142 	u8 function;
143 	u8 key_num;
144 	u16 device_state;
145 	u16 reserved1;
146 	u8 kbd_dock_state;
147 	u8 reserved2;
148 } __packed;
149 
150 /*
151  * GUID3 Get Device Status device flags
152  */
153 #define ACER_WMID3_GDS_WIRELESS		(1<<0)	/* WiFi */
154 #define ACER_WMID3_GDS_THREEG		(1<<6)	/* 3G */
155 #define ACER_WMID3_GDS_WIMAX		(1<<7)	/* WiMAX */
156 #define ACER_WMID3_GDS_BLUETOOTH	(1<<11)	/* BT */
157 #define ACER_WMID3_GDS_RFBTN		(1<<14)	/* RF Button */
158 
159 #define ACER_WMID3_GDS_TOUCHPAD		(1<<1)	/* Touchpad */
160 
161 /* Hotkey Customized Setting and Acer Application Status.
162  * Set Device Default Value and Report Acer Application Status.
163  * When Acer Application starts, it will run this method to inform
164  * BIOS/EC that Acer Application is on.
165  * App Status
166  *	Bit[0]: Launch Manager Status
167  *	Bit[1]: ePM Status
168  *	Bit[2]: Device Control Status
169  *	Bit[3]: Acer Power Button Utility Status
170  *	Bit[4]: RF Button Status
171  *	Bit[5]: ODD PM Status
172  *	Bit[6]: Device Default Value Control
173  *	Bit[7]: Hall Sensor Application Status
174  */
175 struct func_input_params {
176 	u8 function_num;        /* Function Number */
177 	u16 commun_devices;     /* Communication type devices default status */
178 	u16 devices;            /* Other type devices default status */
179 	u8 app_status;          /* Acer Device Status. LM, ePM, RF Button... */
180 	u8 app_mask;		/* Bit mask to app_status */
181 	u8 reserved;
182 } __packed;
183 
184 struct func_return_value {
185 	u8 error_code;          /* Error Code */
186 	u8 ec_return_value;     /* EC Return Value */
187 	u16 reserved;
188 } __packed;
189 
190 struct wmid3_gds_set_input_param {     /* Set Device Status input parameter */
191 	u8 function_num;        /* Function Number */
192 	u8 hotkey_number;       /* Hotkey Number */
193 	u16 devices;            /* Set Device */
194 	u8 volume_value;        /* Volume Value */
195 } __packed;
196 
197 struct wmid3_gds_get_input_param {     /* Get Device Status input parameter */
198 	u8 function_num;	/* Function Number */
199 	u8 hotkey_number;	/* Hotkey Number */
200 	u16 devices;		/* Get Device */
201 } __packed;
202 
203 struct wmid3_gds_return_value {	/* Get Device Status return value*/
204 	u8 error_code;		/* Error Code */
205 	u8 ec_return_value;	/* EC Return Value */
206 	u16 devices;		/* Current Device Status */
207 	u32 reserved;
208 } __packed;
209 
210 struct hotkey_function_type_aa {
211 	u8 type;
212 	u8 length;
213 	u16 handle;
214 	u16 commun_func_bitmap;
215 	u16 application_func_bitmap;
216 	u16 media_func_bitmap;
217 	u16 display_func_bitmap;
218 	u16 others_func_bitmap;
219 	u8 commun_fn_key_number;
220 } __packed;
221 
222 /*
223  * Interface capability flags
224  */
225 #define ACER_CAP_MAILLED		BIT(0)
226 #define ACER_CAP_WIRELESS		BIT(1)
227 #define ACER_CAP_BLUETOOTH		BIT(2)
228 #define ACER_CAP_BRIGHTNESS		BIT(3)
229 #define ACER_CAP_THREEG			BIT(4)
230 #define ACER_CAP_SET_FUNCTION_MODE	BIT(5)
231 #define ACER_CAP_KBD_DOCK		BIT(6)
232 #define ACER_CAP_TURBO_OC     BIT(7)
233 #define ACER_CAP_TURBO_LED     BIT(8)
234 #define ACER_CAP_TURBO_FAN     BIT(9)
235 
236 /*
237  * Interface type flags
238  */
239 enum interface_flags {
240 	ACER_AMW0,
241 	ACER_AMW0_V2,
242 	ACER_WMID,
243 	ACER_WMID_v2,
244 };
245 
246 #define ACER_DEFAULT_WIRELESS  0
247 #define ACER_DEFAULT_BLUETOOTH 0
248 #define ACER_DEFAULT_MAILLED   0
249 #define ACER_DEFAULT_THREEG    0
250 
251 static int max_brightness = 0xF;
252 
253 static int mailled = -1;
254 static int brightness = -1;
255 static int threeg = -1;
256 static int force_series;
257 static int force_caps = -1;
258 static bool ec_raw_mode;
259 static bool has_type_aa;
260 static u16 commun_func_bitmap;
261 static u8 commun_fn_key_number;
262 
263 module_param(mailled, int, 0444);
264 module_param(brightness, int, 0444);
265 module_param(threeg, int, 0444);
266 module_param(force_series, int, 0444);
267 module_param(force_caps, int, 0444);
268 module_param(ec_raw_mode, bool, 0444);
269 MODULE_PARM_DESC(mailled, "Set initial state of Mail LED");
270 MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness");
271 MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware");
272 MODULE_PARM_DESC(force_series, "Force a different laptop series");
273 MODULE_PARM_DESC(force_caps, "Force the capability bitmask to this value");
274 MODULE_PARM_DESC(ec_raw_mode, "Enable EC raw mode");
275 
276 struct acer_data {
277 	int mailled;
278 	int threeg;
279 	int brightness;
280 };
281 
282 struct acer_debug {
283 	struct dentry *root;
284 	u32 wmid_devices;
285 };
286 
287 static struct rfkill *wireless_rfkill;
288 static struct rfkill *bluetooth_rfkill;
289 static struct rfkill *threeg_rfkill;
290 static bool rfkill_inited;
291 
292 /* Each low-level interface must define at least some of the following */
293 struct wmi_interface {
294 	/* The WMI device type */
295 	u32 type;
296 
297 	/* The capabilities this interface provides */
298 	u32 capability;
299 
300 	/* Private data for the current interface */
301 	struct acer_data data;
302 
303 	/* debugfs entries associated with this interface */
304 	struct acer_debug debug;
305 };
306 
307 /* The static interface pointer, points to the currently detected interface */
308 static struct wmi_interface *interface;
309 
310 /*
311  * Embedded Controller quirks
312  * Some laptops require us to directly access the EC to either enable or query
313  * features that are not available through WMI.
314  */
315 
316 struct quirk_entry {
317 	u8 wireless;
318 	u8 mailled;
319 	s8 brightness;
320 	u8 bluetooth;
321 	u8 turbo;
322 	u8 cpu_fans;
323 	u8 gpu_fans;
324 };
325 
326 static struct quirk_entry *quirks;
327 
set_quirks(void)328 static void __init set_quirks(void)
329 {
330 	if (quirks->mailled)
331 		interface->capability |= ACER_CAP_MAILLED;
332 
333 	if (quirks->brightness)
334 		interface->capability |= ACER_CAP_BRIGHTNESS;
335 
336 	if (quirks->turbo)
337 		interface->capability |= ACER_CAP_TURBO_OC | ACER_CAP_TURBO_LED
338 					 | ACER_CAP_TURBO_FAN;
339 }
340 
dmi_matched(const struct dmi_system_id * dmi)341 static int __init dmi_matched(const struct dmi_system_id *dmi)
342 {
343 	quirks = dmi->driver_data;
344 	return 1;
345 }
346 
set_force_caps(const struct dmi_system_id * dmi)347 static int __init set_force_caps(const struct dmi_system_id *dmi)
348 {
349 	if (force_caps == -1) {
350 		force_caps = (uintptr_t)dmi->driver_data;
351 		pr_info("Found %s, set force_caps to 0x%x\n", dmi->ident, force_caps);
352 	}
353 	return 1;
354 }
355 
356 static struct quirk_entry quirk_unknown = {
357 };
358 
359 static struct quirk_entry quirk_acer_aspire_1520 = {
360 	.brightness = -1,
361 };
362 
363 static struct quirk_entry quirk_acer_travelmate_2490 = {
364 	.mailled = 1,
365 };
366 
367 static struct quirk_entry quirk_acer_predator_ph315_53 = {
368 	.turbo = 1,
369 	.cpu_fans = 1,
370 	.gpu_fans = 1,
371 };
372 
373 /* This AMW0 laptop has no bluetooth */
374 static struct quirk_entry quirk_medion_md_98300 = {
375 	.wireless = 1,
376 };
377 
378 static struct quirk_entry quirk_fujitsu_amilo_li_1718 = {
379 	.wireless = 2,
380 };
381 
382 static struct quirk_entry quirk_lenovo_ideapad_s205 = {
383 	.wireless = 3,
384 };
385 
386 /* The Aspire One has a dummy ACPI-WMI interface - disable it */
387 static const struct dmi_system_id acer_blacklist[] __initconst = {
388 	{
389 		.ident = "Acer Aspire One (SSD)",
390 		.matches = {
391 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
392 			DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
393 		},
394 	},
395 	{
396 		.ident = "Acer Aspire One (HDD)",
397 		.matches = {
398 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
399 			DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
400 		},
401 	},
402 	{}
403 };
404 
405 static const struct dmi_system_id amw0_whitelist[] __initconst = {
406 	{
407 		.ident = "Acer",
408 		.matches = {
409 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
410 		},
411 	},
412 	{
413 		.ident = "Gateway",
414 		.matches = {
415 			DMI_MATCH(DMI_SYS_VENDOR, "Gateway"),
416 		},
417 	},
418 	{
419 		.ident = "Packard Bell",
420 		.matches = {
421 			DMI_MATCH(DMI_SYS_VENDOR, "Packard Bell"),
422 		},
423 	},
424 	{}
425 };
426 
427 /*
428  * This quirk table is only for Acer/Gateway/Packard Bell family
429  * that those machines are supported by acer-wmi driver.
430  */
431 static const struct dmi_system_id acer_quirks[] __initconst = {
432 	{
433 		.callback = dmi_matched,
434 		.ident = "Acer Aspire 1360",
435 		.matches = {
436 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
437 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
438 		},
439 		.driver_data = &quirk_acer_aspire_1520,
440 	},
441 	{
442 		.callback = dmi_matched,
443 		.ident = "Acer Aspire 1520",
444 		.matches = {
445 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
446 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1520"),
447 		},
448 		.driver_data = &quirk_acer_aspire_1520,
449 	},
450 	{
451 		.callback = dmi_matched,
452 		.ident = "Acer Aspire 3100",
453 		.matches = {
454 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
455 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3100"),
456 		},
457 		.driver_data = &quirk_acer_travelmate_2490,
458 	},
459 	{
460 		.callback = dmi_matched,
461 		.ident = "Acer Aspire 3610",
462 		.matches = {
463 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
464 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3610"),
465 		},
466 		.driver_data = &quirk_acer_travelmate_2490,
467 	},
468 	{
469 		.callback = dmi_matched,
470 		.ident = "Acer Aspire 5100",
471 		.matches = {
472 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
473 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
474 		},
475 		.driver_data = &quirk_acer_travelmate_2490,
476 	},
477 	{
478 		.callback = dmi_matched,
479 		.ident = "Acer Aspire 5610",
480 		.matches = {
481 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
482 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
483 		},
484 		.driver_data = &quirk_acer_travelmate_2490,
485 	},
486 	{
487 		.callback = dmi_matched,
488 		.ident = "Acer Aspire 5630",
489 		.matches = {
490 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
491 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"),
492 		},
493 		.driver_data = &quirk_acer_travelmate_2490,
494 	},
495 	{
496 		.callback = dmi_matched,
497 		.ident = "Acer Aspire 5650",
498 		.matches = {
499 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
500 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"),
501 		},
502 		.driver_data = &quirk_acer_travelmate_2490,
503 	},
504 	{
505 		.callback = dmi_matched,
506 		.ident = "Acer Aspire 5680",
507 		.matches = {
508 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
509 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
510 		},
511 		.driver_data = &quirk_acer_travelmate_2490,
512 	},
513 	{
514 		.callback = dmi_matched,
515 		.ident = "Acer Aspire 9110",
516 		.matches = {
517 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
518 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"),
519 		},
520 		.driver_data = &quirk_acer_travelmate_2490,
521 	},
522 	{
523 		.callback = dmi_matched,
524 		.ident = "Acer TravelMate 2490",
525 		.matches = {
526 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
527 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"),
528 		},
529 		.driver_data = &quirk_acer_travelmate_2490,
530 	},
531 	{
532 		.callback = dmi_matched,
533 		.ident = "Acer TravelMate 4200",
534 		.matches = {
535 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
536 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4200"),
537 		},
538 		.driver_data = &quirk_acer_travelmate_2490,
539 	},
540 	{
541 		.callback = dmi_matched,
542 		.ident = "Acer Predator PH315-53",
543 		.matches = {
544 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
545 			DMI_MATCH(DMI_PRODUCT_NAME, "Predator PH315-53"),
546 		},
547 		.driver_data = &quirk_acer_predator_ph315_53,
548 	},
549 	{
550 		.callback = set_force_caps,
551 		.ident = "Acer Aspire Switch 10E SW3-016",
552 		.matches = {
553 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
554 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW3-016"),
555 		},
556 		.driver_data = (void *)ACER_CAP_KBD_DOCK,
557 	},
558 	{
559 		.callback = set_force_caps,
560 		.ident = "Acer Aspire Switch 10 SW5-012",
561 		.matches = {
562 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
563 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
564 		},
565 		.driver_data = (void *)ACER_CAP_KBD_DOCK,
566 	},
567 	{
568 		.callback = set_force_caps,
569 		.ident = "Acer Aspire Switch V 10 SW5-017",
570 		.matches = {
571 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
572 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"),
573 		},
574 		.driver_data = (void *)ACER_CAP_KBD_DOCK,
575 	},
576 	{
577 		.callback = set_force_caps,
578 		.ident = "Acer One 10 (S1003)",
579 		.matches = {
580 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
581 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"),
582 		},
583 		.driver_data = (void *)ACER_CAP_KBD_DOCK,
584 	},
585 	{}
586 };
587 
588 /*
589  * This quirk list is for those non-acer machines that have AMW0_GUID1
590  * but supported by acer-wmi in past days. Keeping this quirk list here
591  * is only for backward compatible. Please do not add new machine to
592  * here anymore. Those non-acer machines should be supported by
593  * appropriate wmi drivers.
594  */
595 static const struct dmi_system_id non_acer_quirks[] __initconst = {
596 	{
597 		.callback = dmi_matched,
598 		.ident = "Fujitsu Siemens Amilo Li 1718",
599 		.matches = {
600 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
601 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Li 1718"),
602 		},
603 		.driver_data = &quirk_fujitsu_amilo_li_1718,
604 	},
605 	{
606 		.callback = dmi_matched,
607 		.ident = "Medion MD 98300",
608 		.matches = {
609 			DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
610 			DMI_MATCH(DMI_PRODUCT_NAME, "WAM2030"),
611 		},
612 		.driver_data = &quirk_medion_md_98300,
613 	},
614 	{
615 		.callback = dmi_matched,
616 		.ident = "Lenovo Ideapad S205",
617 		.matches = {
618 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
619 			DMI_MATCH(DMI_PRODUCT_NAME, "10382LG"),
620 		},
621 		.driver_data = &quirk_lenovo_ideapad_s205,
622 	},
623 	{
624 		.callback = dmi_matched,
625 		.ident = "Lenovo Ideapad S205 (Brazos)",
626 		.matches = {
627 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
628 			DMI_MATCH(DMI_PRODUCT_NAME, "Brazos"),
629 		},
630 		.driver_data = &quirk_lenovo_ideapad_s205,
631 	},
632 	{
633 		.callback = dmi_matched,
634 		.ident = "Lenovo 3000 N200",
635 		.matches = {
636 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
637 			DMI_MATCH(DMI_PRODUCT_NAME, "0687A31"),
638 		},
639 		.driver_data = &quirk_fujitsu_amilo_li_1718,
640 	},
641 	{
642 		.callback = dmi_matched,
643 		.ident = "Lenovo Ideapad S205-10382JG",
644 		.matches = {
645 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
646 			DMI_MATCH(DMI_PRODUCT_NAME, "10382JG"),
647 		},
648 		.driver_data = &quirk_lenovo_ideapad_s205,
649 	},
650 	{
651 		.callback = dmi_matched,
652 		.ident = "Lenovo Ideapad S205-1038DPG",
653 		.matches = {
654 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
655 			DMI_MATCH(DMI_PRODUCT_NAME, "1038DPG"),
656 		},
657 		.driver_data = &quirk_lenovo_ideapad_s205,
658 	},
659 	{}
660 };
661 
662 /* Find which quirks are needed for a particular vendor/ model pair */
find_quirks(void)663 static void __init find_quirks(void)
664 {
665 	if (!force_series) {
666 		dmi_check_system(acer_quirks);
667 		dmi_check_system(non_acer_quirks);
668 	} else if (force_series == 2490) {
669 		quirks = &quirk_acer_travelmate_2490;
670 	}
671 
672 	if (quirks == NULL)
673 		quirks = &quirk_unknown;
674 }
675 
676 /*
677  * General interface convenience methods
678  */
679 
has_cap(u32 cap)680 static bool has_cap(u32 cap)
681 {
682 	return interface->capability & cap;
683 }
684 
685 /*
686  * AMW0 (V1) interface
687  */
688 struct wmab_args {
689 	u32 eax;
690 	u32 ebx;
691 	u32 ecx;
692 	u32 edx;
693 };
694 
695 struct wmab_ret {
696 	u32 eax;
697 	u32 ebx;
698 	u32 ecx;
699 	u32 edx;
700 	u32 eex;
701 };
702 
wmab_execute(struct wmab_args * regbuf,struct acpi_buffer * result)703 static acpi_status wmab_execute(struct wmab_args *regbuf,
704 struct acpi_buffer *result)
705 {
706 	struct acpi_buffer input;
707 	acpi_status status;
708 	input.length = sizeof(struct wmab_args);
709 	input.pointer = (u8 *)regbuf;
710 
711 	status = wmi_evaluate_method(AMW0_GUID1, 0, 1, &input, result);
712 
713 	return status;
714 }
715 
AMW0_get_u32(u32 * value,u32 cap)716 static acpi_status AMW0_get_u32(u32 *value, u32 cap)
717 {
718 	int err;
719 	u8 result;
720 
721 	switch (cap) {
722 	case ACER_CAP_MAILLED:
723 		switch (quirks->mailled) {
724 		default:
725 			err = ec_read(0xA, &result);
726 			if (err)
727 				return AE_ERROR;
728 			*value = (result >> 7) & 0x1;
729 			return AE_OK;
730 		}
731 		break;
732 	case ACER_CAP_WIRELESS:
733 		switch (quirks->wireless) {
734 		case 1:
735 			err = ec_read(0x7B, &result);
736 			if (err)
737 				return AE_ERROR;
738 			*value = result & 0x1;
739 			return AE_OK;
740 		case 2:
741 			err = ec_read(0x71, &result);
742 			if (err)
743 				return AE_ERROR;
744 			*value = result & 0x1;
745 			return AE_OK;
746 		case 3:
747 			err = ec_read(0x78, &result);
748 			if (err)
749 				return AE_ERROR;
750 			*value = result & 0x1;
751 			return AE_OK;
752 		default:
753 			err = ec_read(0xA, &result);
754 			if (err)
755 				return AE_ERROR;
756 			*value = (result >> 2) & 0x1;
757 			return AE_OK;
758 		}
759 		break;
760 	case ACER_CAP_BLUETOOTH:
761 		switch (quirks->bluetooth) {
762 		default:
763 			err = ec_read(0xA, &result);
764 			if (err)
765 				return AE_ERROR;
766 			*value = (result >> 4) & 0x1;
767 			return AE_OK;
768 		}
769 		break;
770 	case ACER_CAP_BRIGHTNESS:
771 		switch (quirks->brightness) {
772 		default:
773 			err = ec_read(0x83, &result);
774 			if (err)
775 				return AE_ERROR;
776 			*value = result;
777 			return AE_OK;
778 		}
779 		break;
780 	default:
781 		return AE_ERROR;
782 	}
783 	return AE_OK;
784 }
785 
AMW0_set_u32(u32 value,u32 cap)786 static acpi_status AMW0_set_u32(u32 value, u32 cap)
787 {
788 	struct wmab_args args;
789 
790 	args.eax = ACER_AMW0_WRITE;
791 	args.ebx = value ? (1<<8) : 0;
792 	args.ecx = args.edx = 0;
793 
794 	switch (cap) {
795 	case ACER_CAP_MAILLED:
796 		if (value > 1)
797 			return AE_BAD_PARAMETER;
798 		args.ebx |= ACER_AMW0_MAILLED_MASK;
799 		break;
800 	case ACER_CAP_WIRELESS:
801 		if (value > 1)
802 			return AE_BAD_PARAMETER;
803 		args.ebx |= ACER_AMW0_WIRELESS_MASK;
804 		break;
805 	case ACER_CAP_BLUETOOTH:
806 		if (value > 1)
807 			return AE_BAD_PARAMETER;
808 		args.ebx |= ACER_AMW0_BLUETOOTH_MASK;
809 		break;
810 	case ACER_CAP_BRIGHTNESS:
811 		if (value > max_brightness)
812 			return AE_BAD_PARAMETER;
813 		switch (quirks->brightness) {
814 		default:
815 			return ec_write(0x83, value);
816 		}
817 	default:
818 		return AE_ERROR;
819 	}
820 
821 	/* Actually do the set */
822 	return wmab_execute(&args, NULL);
823 }
824 
AMW0_find_mailled(void)825 static acpi_status __init AMW0_find_mailled(void)
826 {
827 	struct wmab_args args;
828 	struct wmab_ret ret;
829 	acpi_status status = AE_OK;
830 	struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
831 	union acpi_object *obj;
832 
833 	args.eax = 0x86;
834 	args.ebx = args.ecx = args.edx = 0;
835 
836 	status = wmab_execute(&args, &out);
837 	if (ACPI_FAILURE(status))
838 		return status;
839 
840 	obj = (union acpi_object *) out.pointer;
841 	if (obj && obj->type == ACPI_TYPE_BUFFER &&
842 	obj->buffer.length == sizeof(struct wmab_ret)) {
843 		ret = *((struct wmab_ret *) obj->buffer.pointer);
844 	} else {
845 		kfree(out.pointer);
846 		return AE_ERROR;
847 	}
848 
849 	if (ret.eex & 0x1)
850 		interface->capability |= ACER_CAP_MAILLED;
851 
852 	kfree(out.pointer);
853 
854 	return AE_OK;
855 }
856 
857 static const struct acpi_device_id norfkill_ids[] __initconst = {
858 	{ "VPC2004", 0},
859 	{ "IBM0068", 0},
860 	{ "LEN0068", 0},
861 	{ "SNY5001", 0},	/* sony-laptop in charge */
862 	{ "HPQ6601", 0},
863 	{ "", 0},
864 };
865 
AMW0_set_cap_acpi_check_device(void)866 static int __init AMW0_set_cap_acpi_check_device(void)
867 {
868 	const struct acpi_device_id *id;
869 
870 	for (id = norfkill_ids; id->id[0]; id++)
871 		if (acpi_dev_found(id->id))
872 			return true;
873 
874 	return false;
875 }
876 
AMW0_set_capabilities(void)877 static acpi_status __init AMW0_set_capabilities(void)
878 {
879 	struct wmab_args args;
880 	struct wmab_ret ret;
881 	acpi_status status;
882 	struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
883 	union acpi_object *obj;
884 
885 	/*
886 	 * On laptops with this strange GUID (non Acer), normal probing doesn't
887 	 * work.
888 	 */
889 	if (wmi_has_guid(AMW0_GUID2)) {
890 		if ((quirks != &quirk_unknown) ||
891 		    !AMW0_set_cap_acpi_check_device())
892 			interface->capability |= ACER_CAP_WIRELESS;
893 		return AE_OK;
894 	}
895 
896 	args.eax = ACER_AMW0_WRITE;
897 	args.ecx = args.edx = 0;
898 
899 	args.ebx = 0xa2 << 8;
900 	args.ebx |= ACER_AMW0_WIRELESS_MASK;
901 
902 	status = wmab_execute(&args, &out);
903 	if (ACPI_FAILURE(status))
904 		return status;
905 
906 	obj = out.pointer;
907 	if (obj && obj->type == ACPI_TYPE_BUFFER &&
908 	obj->buffer.length == sizeof(struct wmab_ret)) {
909 		ret = *((struct wmab_ret *) obj->buffer.pointer);
910 	} else {
911 		status = AE_ERROR;
912 		goto out;
913 	}
914 
915 	if (ret.eax & 0x1)
916 		interface->capability |= ACER_CAP_WIRELESS;
917 
918 	args.ebx = 2 << 8;
919 	args.ebx |= ACER_AMW0_BLUETOOTH_MASK;
920 
921 	/*
922 	 * It's ok to use existing buffer for next wmab_execute call.
923 	 * But we need to kfree(out.pointer) if next wmab_execute fail.
924 	 */
925 	status = wmab_execute(&args, &out);
926 	if (ACPI_FAILURE(status))
927 		goto out;
928 
929 	obj = (union acpi_object *) out.pointer;
930 	if (obj && obj->type == ACPI_TYPE_BUFFER
931 	&& obj->buffer.length == sizeof(struct wmab_ret)) {
932 		ret = *((struct wmab_ret *) obj->buffer.pointer);
933 	} else {
934 		status = AE_ERROR;
935 		goto out;
936 	}
937 
938 	if (ret.eax & 0x1)
939 		interface->capability |= ACER_CAP_BLUETOOTH;
940 
941 	/*
942 	 * This appears to be safe to enable, since all Wistron based laptops
943 	 * appear to use the same EC register for brightness, even if they
944 	 * differ for wireless, etc
945 	 */
946 	if (quirks->brightness >= 0)
947 		interface->capability |= ACER_CAP_BRIGHTNESS;
948 
949 	status = AE_OK;
950 out:
951 	kfree(out.pointer);
952 	return status;
953 }
954 
955 static struct wmi_interface AMW0_interface = {
956 	.type = ACER_AMW0,
957 };
958 
959 static struct wmi_interface AMW0_V2_interface = {
960 	.type = ACER_AMW0_V2,
961 };
962 
963 /*
964  * New interface (The WMID interface)
965  */
966 static acpi_status
WMI_execute_u32(u32 method_id,u32 in,u32 * out)967 WMI_execute_u32(u32 method_id, u32 in, u32 *out)
968 {
969 	struct acpi_buffer input = { (acpi_size) sizeof(u32), (void *)(&in) };
970 	struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL };
971 	union acpi_object *obj;
972 	u32 tmp = 0;
973 	acpi_status status;
974 
975 	status = wmi_evaluate_method(WMID_GUID1, 0, method_id, &input, &result);
976 
977 	if (ACPI_FAILURE(status))
978 		return status;
979 
980 	obj = (union acpi_object *) result.pointer;
981 	if (obj) {
982 		if (obj->type == ACPI_TYPE_BUFFER &&
983 			(obj->buffer.length == sizeof(u32) ||
984 			obj->buffer.length == sizeof(u64))) {
985 			tmp = *((u32 *) obj->buffer.pointer);
986 		} else if (obj->type == ACPI_TYPE_INTEGER) {
987 			tmp = (u32) obj->integer.value;
988 		}
989 	}
990 
991 	if (out)
992 		*out = tmp;
993 
994 	kfree(result.pointer);
995 
996 	return status;
997 }
998 
WMID_get_u32(u32 * value,u32 cap)999 static acpi_status WMID_get_u32(u32 *value, u32 cap)
1000 {
1001 	acpi_status status;
1002 	u8 tmp;
1003 	u32 result, method_id = 0;
1004 
1005 	switch (cap) {
1006 	case ACER_CAP_WIRELESS:
1007 		method_id = ACER_WMID_GET_WIRELESS_METHODID;
1008 		break;
1009 	case ACER_CAP_BLUETOOTH:
1010 		method_id = ACER_WMID_GET_BLUETOOTH_METHODID;
1011 		break;
1012 	case ACER_CAP_BRIGHTNESS:
1013 		method_id = ACER_WMID_GET_BRIGHTNESS_METHODID;
1014 		break;
1015 	case ACER_CAP_THREEG:
1016 		method_id = ACER_WMID_GET_THREEG_METHODID;
1017 		break;
1018 	case ACER_CAP_MAILLED:
1019 		if (quirks->mailled == 1) {
1020 			ec_read(0x9f, &tmp);
1021 			*value = tmp & 0x1;
1022 			return 0;
1023 		}
1024 		fallthrough;
1025 	default:
1026 		return AE_ERROR;
1027 	}
1028 	status = WMI_execute_u32(method_id, 0, &result);
1029 
1030 	if (ACPI_SUCCESS(status))
1031 		*value = (u8)result;
1032 
1033 	return status;
1034 }
1035 
WMID_set_u32(u32 value,u32 cap)1036 static acpi_status WMID_set_u32(u32 value, u32 cap)
1037 {
1038 	u32 method_id = 0;
1039 	char param;
1040 
1041 	switch (cap) {
1042 	case ACER_CAP_BRIGHTNESS:
1043 		if (value > max_brightness)
1044 			return AE_BAD_PARAMETER;
1045 		method_id = ACER_WMID_SET_BRIGHTNESS_METHODID;
1046 		break;
1047 	case ACER_CAP_WIRELESS:
1048 		if (value > 1)
1049 			return AE_BAD_PARAMETER;
1050 		method_id = ACER_WMID_SET_WIRELESS_METHODID;
1051 		break;
1052 	case ACER_CAP_BLUETOOTH:
1053 		if (value > 1)
1054 			return AE_BAD_PARAMETER;
1055 		method_id = ACER_WMID_SET_BLUETOOTH_METHODID;
1056 		break;
1057 	case ACER_CAP_THREEG:
1058 		if (value > 1)
1059 			return AE_BAD_PARAMETER;
1060 		method_id = ACER_WMID_SET_THREEG_METHODID;
1061 		break;
1062 	case ACER_CAP_MAILLED:
1063 		if (value > 1)
1064 			return AE_BAD_PARAMETER;
1065 		if (quirks->mailled == 1) {
1066 			param = value ? 0x92 : 0x93;
1067 			i8042_lock_chip();
1068 			i8042_command(&param, 0x1059);
1069 			i8042_unlock_chip();
1070 			return 0;
1071 		}
1072 		break;
1073 	default:
1074 		return AE_ERROR;
1075 	}
1076 	return WMI_execute_u32(method_id, (u32)value, NULL);
1077 }
1078 
wmid3_get_device_status(u32 * value,u16 device)1079 static acpi_status wmid3_get_device_status(u32 *value, u16 device)
1080 {
1081 	struct wmid3_gds_return_value return_value;
1082 	acpi_status status;
1083 	union acpi_object *obj;
1084 	struct wmid3_gds_get_input_param params = {
1085 		.function_num = 0x1,
1086 		.hotkey_number = commun_fn_key_number,
1087 		.devices = device,
1088 	};
1089 	struct acpi_buffer input = {
1090 		sizeof(struct wmid3_gds_get_input_param),
1091 		&params
1092 	};
1093 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
1094 
1095 	status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output);
1096 	if (ACPI_FAILURE(status))
1097 		return status;
1098 
1099 	obj = output.pointer;
1100 
1101 	if (!obj)
1102 		return AE_ERROR;
1103 	else if (obj->type != ACPI_TYPE_BUFFER) {
1104 		kfree(obj);
1105 		return AE_ERROR;
1106 	}
1107 	if (obj->buffer.length != 8) {
1108 		pr_warn("Unknown buffer length %d\n", obj->buffer.length);
1109 		kfree(obj);
1110 		return AE_ERROR;
1111 	}
1112 
1113 	return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
1114 	kfree(obj);
1115 
1116 	if (return_value.error_code || return_value.ec_return_value)
1117 		pr_warn("Get 0x%x Device Status failed: 0x%x - 0x%x\n",
1118 			device,
1119 			return_value.error_code,
1120 			return_value.ec_return_value);
1121 	else
1122 		*value = !!(return_value.devices & device);
1123 
1124 	return status;
1125 }
1126 
wmid_v2_get_u32(u32 * value,u32 cap)1127 static acpi_status wmid_v2_get_u32(u32 *value, u32 cap)
1128 {
1129 	u16 device;
1130 
1131 	switch (cap) {
1132 	case ACER_CAP_WIRELESS:
1133 		device = ACER_WMID3_GDS_WIRELESS;
1134 		break;
1135 	case ACER_CAP_BLUETOOTH:
1136 		device = ACER_WMID3_GDS_BLUETOOTH;
1137 		break;
1138 	case ACER_CAP_THREEG:
1139 		device = ACER_WMID3_GDS_THREEG;
1140 		break;
1141 	default:
1142 		return AE_ERROR;
1143 	}
1144 	return wmid3_get_device_status(value, device);
1145 }
1146 
wmid3_set_device_status(u32 value,u16 device)1147 static acpi_status wmid3_set_device_status(u32 value, u16 device)
1148 {
1149 	struct wmid3_gds_return_value return_value;
1150 	acpi_status status;
1151 	union acpi_object *obj;
1152 	u16 devices;
1153 	struct wmid3_gds_get_input_param get_params = {
1154 		.function_num = 0x1,
1155 		.hotkey_number = commun_fn_key_number,
1156 		.devices = commun_func_bitmap,
1157 	};
1158 	struct acpi_buffer get_input = {
1159 		sizeof(struct wmid3_gds_get_input_param),
1160 		&get_params
1161 	};
1162 	struct wmid3_gds_set_input_param set_params = {
1163 		.function_num = 0x2,
1164 		.hotkey_number = commun_fn_key_number,
1165 		.devices = commun_func_bitmap,
1166 	};
1167 	struct acpi_buffer set_input = {
1168 		sizeof(struct wmid3_gds_set_input_param),
1169 		&set_params
1170 	};
1171 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
1172 	struct acpi_buffer output2 = { ACPI_ALLOCATE_BUFFER, NULL };
1173 
1174 	status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &get_input, &output);
1175 	if (ACPI_FAILURE(status))
1176 		return status;
1177 
1178 	obj = output.pointer;
1179 
1180 	if (!obj)
1181 		return AE_ERROR;
1182 	else if (obj->type != ACPI_TYPE_BUFFER) {
1183 		kfree(obj);
1184 		return AE_ERROR;
1185 	}
1186 	if (obj->buffer.length != 8) {
1187 		pr_warn("Unknown buffer length %d\n", obj->buffer.length);
1188 		kfree(obj);
1189 		return AE_ERROR;
1190 	}
1191 
1192 	return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
1193 	kfree(obj);
1194 
1195 	if (return_value.error_code || return_value.ec_return_value) {
1196 		pr_warn("Get Current Device Status failed: 0x%x - 0x%x\n",
1197 			return_value.error_code,
1198 			return_value.ec_return_value);
1199 		return status;
1200 	}
1201 
1202 	devices = return_value.devices;
1203 	set_params.devices = (value) ? (devices | device) : (devices & ~device);
1204 
1205 	status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &set_input, &output2);
1206 	if (ACPI_FAILURE(status))
1207 		return status;
1208 
1209 	obj = output2.pointer;
1210 
1211 	if (!obj)
1212 		return AE_ERROR;
1213 	else if (obj->type != ACPI_TYPE_BUFFER) {
1214 		kfree(obj);
1215 		return AE_ERROR;
1216 	}
1217 	if (obj->buffer.length != 4) {
1218 		pr_warn("Unknown buffer length %d\n", obj->buffer.length);
1219 		kfree(obj);
1220 		return AE_ERROR;
1221 	}
1222 
1223 	return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
1224 	kfree(obj);
1225 
1226 	if (return_value.error_code || return_value.ec_return_value)
1227 		pr_warn("Set Device Status failed: 0x%x - 0x%x\n",
1228 			return_value.error_code,
1229 			return_value.ec_return_value);
1230 
1231 	return status;
1232 }
1233 
wmid_v2_set_u32(u32 value,u32 cap)1234 static acpi_status wmid_v2_set_u32(u32 value, u32 cap)
1235 {
1236 	u16 device;
1237 
1238 	switch (cap) {
1239 	case ACER_CAP_WIRELESS:
1240 		device = ACER_WMID3_GDS_WIRELESS;
1241 		break;
1242 	case ACER_CAP_BLUETOOTH:
1243 		device = ACER_WMID3_GDS_BLUETOOTH;
1244 		break;
1245 	case ACER_CAP_THREEG:
1246 		device = ACER_WMID3_GDS_THREEG;
1247 		break;
1248 	default:
1249 		return AE_ERROR;
1250 	}
1251 	return wmid3_set_device_status(value, device);
1252 }
1253 
type_aa_dmi_decode(const struct dmi_header * header,void * d)1254 static void __init type_aa_dmi_decode(const struct dmi_header *header, void *d)
1255 {
1256 	struct hotkey_function_type_aa *type_aa;
1257 
1258 	/* We are looking for OEM-specific Type AAh */
1259 	if (header->type != 0xAA)
1260 		return;
1261 
1262 	has_type_aa = true;
1263 	type_aa = (struct hotkey_function_type_aa *) header;
1264 
1265 	pr_info("Function bitmap for Communication Button: 0x%x\n",
1266 		type_aa->commun_func_bitmap);
1267 	commun_func_bitmap = type_aa->commun_func_bitmap;
1268 
1269 	if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_WIRELESS)
1270 		interface->capability |= ACER_CAP_WIRELESS;
1271 	if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_THREEG)
1272 		interface->capability |= ACER_CAP_THREEG;
1273 	if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_BLUETOOTH)
1274 		interface->capability |= ACER_CAP_BLUETOOTH;
1275 	if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN)
1276 		commun_func_bitmap &= ~ACER_WMID3_GDS_RFBTN;
1277 
1278 	commun_fn_key_number = type_aa->commun_fn_key_number;
1279 }
1280 
WMID_set_capabilities(void)1281 static acpi_status __init WMID_set_capabilities(void)
1282 {
1283 	struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
1284 	union acpi_object *obj;
1285 	acpi_status status;
1286 	u32 devices;
1287 
1288 	status = wmi_query_block(WMID_GUID2, 0, &out);
1289 	if (ACPI_FAILURE(status))
1290 		return status;
1291 
1292 	obj = (union acpi_object *) out.pointer;
1293 	if (obj) {
1294 		if (obj->type == ACPI_TYPE_BUFFER &&
1295 			(obj->buffer.length == sizeof(u32) ||
1296 			obj->buffer.length == sizeof(u64))) {
1297 			devices = *((u32 *) obj->buffer.pointer);
1298 		} else if (obj->type == ACPI_TYPE_INTEGER) {
1299 			devices = (u32) obj->integer.value;
1300 		} else {
1301 			kfree(out.pointer);
1302 			return AE_ERROR;
1303 		}
1304 	} else {
1305 		kfree(out.pointer);
1306 		return AE_ERROR;
1307 	}
1308 
1309 	pr_info("Function bitmap for Communication Device: 0x%x\n", devices);
1310 	if (devices & 0x07)
1311 		interface->capability |= ACER_CAP_WIRELESS;
1312 	if (devices & 0x40)
1313 		interface->capability |= ACER_CAP_THREEG;
1314 	if (devices & 0x10)
1315 		interface->capability |= ACER_CAP_BLUETOOTH;
1316 
1317 	if (!(devices & 0x20))
1318 		max_brightness = 0x9;
1319 
1320 	kfree(out.pointer);
1321 	return status;
1322 }
1323 
1324 static struct wmi_interface wmid_interface = {
1325 	.type = ACER_WMID,
1326 };
1327 
1328 static struct wmi_interface wmid_v2_interface = {
1329 	.type = ACER_WMID_v2,
1330 };
1331 
1332 /*
1333  * WMID Gaming interface
1334  */
1335 
1336 static acpi_status
WMI_gaming_execute_u64(u32 method_id,u64 in,u64 * out)1337 WMI_gaming_execute_u64(u32 method_id, u64 in, u64 *out)
1338 {
1339 	struct acpi_buffer input = { (acpi_size) sizeof(u64), (void *)(&in) };
1340 	struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL };
1341 	union acpi_object *obj;
1342 	u32 tmp = 0;
1343 	acpi_status status;
1344 
1345 	status = wmi_evaluate_method(WMID_GUID4, 0, method_id, &input, &result);
1346 
1347 	if (ACPI_FAILURE(status))
1348 		return status;
1349 	obj = (union acpi_object *) result.pointer;
1350 
1351 	if (obj) {
1352 		if (obj->type == ACPI_TYPE_BUFFER) {
1353 			if (obj->buffer.length == sizeof(u32))
1354 				tmp = *((u32 *) obj->buffer.pointer);
1355 			else if (obj->buffer.length == sizeof(u64))
1356 				tmp = *((u64 *) obj->buffer.pointer);
1357 		} else if (obj->type == ACPI_TYPE_INTEGER) {
1358 			tmp = (u64) obj->integer.value;
1359 		}
1360 	}
1361 
1362 	if (out)
1363 		*out = tmp;
1364 
1365 	kfree(result.pointer);
1366 
1367 	return status;
1368 }
1369 
WMID_gaming_set_u64(u64 value,u32 cap)1370 static acpi_status WMID_gaming_set_u64(u64 value, u32 cap)
1371 {
1372 	u32 method_id = 0;
1373 
1374 	if (!(interface->capability & cap))
1375 		return AE_BAD_PARAMETER;
1376 
1377 	switch (cap) {
1378 	case ACER_CAP_TURBO_LED:
1379 		method_id = ACER_WMID_SET_GAMING_LED_METHODID;
1380 		break;
1381 	case ACER_CAP_TURBO_FAN:
1382 		method_id = ACER_WMID_SET_GAMING_FAN_BEHAVIOR;
1383 		break;
1384 	case ACER_CAP_TURBO_OC:
1385 		method_id = ACER_WMID_SET_GAMING_MISC_SETTING_METHODID;
1386 		break;
1387 	default:
1388 		return AE_BAD_PARAMETER;
1389 	}
1390 
1391 	return WMI_gaming_execute_u64(method_id, value, NULL);
1392 }
1393 
WMID_gaming_get_u64(u64 * value,u32 cap)1394 static acpi_status WMID_gaming_get_u64(u64 *value, u32 cap)
1395 {
1396 	acpi_status status;
1397 	u64 result;
1398 	u64 input;
1399 	u32 method_id;
1400 
1401 	if (!(interface->capability & cap))
1402 		return AE_BAD_PARAMETER;
1403 
1404 	switch (cap) {
1405 	case ACER_CAP_TURBO_LED:
1406 		method_id = ACER_WMID_GET_GAMING_LED_METHODID;
1407 		input = 0x1;
1408 		break;
1409 	default:
1410 		return AE_BAD_PARAMETER;
1411 	}
1412 	status = WMI_gaming_execute_u64(method_id, input, &result);
1413 	if (ACPI_SUCCESS(status))
1414 		*value = (u64) result;
1415 
1416 	return status;
1417 }
1418 
WMID_gaming_set_fan_mode(u8 fan_mode)1419 static void WMID_gaming_set_fan_mode(u8 fan_mode)
1420 {
1421 	/* fan_mode = 1 is used for auto, fan_mode = 2 used for turbo*/
1422 	u64 gpu_fan_config1 = 0, gpu_fan_config2 = 0;
1423 	int i;
1424 
1425 	if (quirks->cpu_fans > 0)
1426 		gpu_fan_config2 |= 1;
1427 	for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
1428 		gpu_fan_config2 |= 1 << (i + 1);
1429 	for (i = 0; i < quirks->gpu_fans; ++i)
1430 		gpu_fan_config2 |= 1 << (i + 3);
1431 	if (quirks->cpu_fans > 0)
1432 		gpu_fan_config1 |= fan_mode;
1433 	for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
1434 		gpu_fan_config1 |= fan_mode << (2 * i + 2);
1435 	for (i = 0; i < quirks->gpu_fans; ++i)
1436 		gpu_fan_config1 |= fan_mode << (2 * i + 6);
1437 	WMID_gaming_set_u64(gpu_fan_config2 | gpu_fan_config1 << 16, ACER_CAP_TURBO_FAN);
1438 }
1439 
1440 /*
1441  * Generic Device (interface-independent)
1442  */
1443 
get_u32(u32 * value,u32 cap)1444 static acpi_status get_u32(u32 *value, u32 cap)
1445 {
1446 	acpi_status status = AE_ERROR;
1447 
1448 	switch (interface->type) {
1449 	case ACER_AMW0:
1450 		status = AMW0_get_u32(value, cap);
1451 		break;
1452 	case ACER_AMW0_V2:
1453 		if (cap == ACER_CAP_MAILLED) {
1454 			status = AMW0_get_u32(value, cap);
1455 			break;
1456 		}
1457 		fallthrough;
1458 	case ACER_WMID:
1459 		status = WMID_get_u32(value, cap);
1460 		break;
1461 	case ACER_WMID_v2:
1462 		if (cap & (ACER_CAP_WIRELESS |
1463 			   ACER_CAP_BLUETOOTH |
1464 			   ACER_CAP_THREEG))
1465 			status = wmid_v2_get_u32(value, cap);
1466 		else if (wmi_has_guid(WMID_GUID2))
1467 			status = WMID_get_u32(value, cap);
1468 		break;
1469 	}
1470 
1471 	return status;
1472 }
1473 
set_u32(u32 value,u32 cap)1474 static acpi_status set_u32(u32 value, u32 cap)
1475 {
1476 	acpi_status status;
1477 
1478 	if (interface->capability & cap) {
1479 		switch (interface->type) {
1480 		case ACER_AMW0:
1481 			return AMW0_set_u32(value, cap);
1482 		case ACER_AMW0_V2:
1483 			if (cap == ACER_CAP_MAILLED)
1484 				return AMW0_set_u32(value, cap);
1485 
1486 			/*
1487 			 * On some models, some WMID methods don't toggle
1488 			 * properly. For those cases, we want to run the AMW0
1489 			 * method afterwards to be certain we've really toggled
1490 			 * the device state.
1491 			 */
1492 			if (cap == ACER_CAP_WIRELESS ||
1493 				cap == ACER_CAP_BLUETOOTH) {
1494 				status = WMID_set_u32(value, cap);
1495 				if (ACPI_FAILURE(status))
1496 					return status;
1497 
1498 				return AMW0_set_u32(value, cap);
1499 			}
1500 			fallthrough;
1501 		case ACER_WMID:
1502 			return WMID_set_u32(value, cap);
1503 		case ACER_WMID_v2:
1504 			if (cap & (ACER_CAP_WIRELESS |
1505 				   ACER_CAP_BLUETOOTH |
1506 				   ACER_CAP_THREEG))
1507 				return wmid_v2_set_u32(value, cap);
1508 			else if (wmi_has_guid(WMID_GUID2))
1509 				return WMID_set_u32(value, cap);
1510 			fallthrough;
1511 		default:
1512 			return AE_BAD_PARAMETER;
1513 		}
1514 	}
1515 	return AE_BAD_PARAMETER;
1516 }
1517 
acer_commandline_init(void)1518 static void __init acer_commandline_init(void)
1519 {
1520 	/*
1521 	 * These will all fail silently if the value given is invalid, or the
1522 	 * capability isn't available on the given interface
1523 	 */
1524 	if (mailled >= 0)
1525 		set_u32(mailled, ACER_CAP_MAILLED);
1526 	if (!has_type_aa && threeg >= 0)
1527 		set_u32(threeg, ACER_CAP_THREEG);
1528 	if (brightness >= 0)
1529 		set_u32(brightness, ACER_CAP_BRIGHTNESS);
1530 }
1531 
1532 /*
1533  * LED device (Mail LED only, no other LEDs known yet)
1534  */
mail_led_set(struct led_classdev * led_cdev,enum led_brightness value)1535 static void mail_led_set(struct led_classdev *led_cdev,
1536 enum led_brightness value)
1537 {
1538 	set_u32(value, ACER_CAP_MAILLED);
1539 }
1540 
1541 static struct led_classdev mail_led = {
1542 	.name = "acer-wmi::mail",
1543 	.brightness_set = mail_led_set,
1544 };
1545 
acer_led_init(struct device * dev)1546 static int acer_led_init(struct device *dev)
1547 {
1548 	return led_classdev_register(dev, &mail_led);
1549 }
1550 
acer_led_exit(void)1551 static void acer_led_exit(void)
1552 {
1553 	set_u32(LED_OFF, ACER_CAP_MAILLED);
1554 	led_classdev_unregister(&mail_led);
1555 }
1556 
1557 /*
1558  * Backlight device
1559  */
1560 static struct backlight_device *acer_backlight_device;
1561 
read_brightness(struct backlight_device * bd)1562 static int read_brightness(struct backlight_device *bd)
1563 {
1564 	u32 value;
1565 	get_u32(&value, ACER_CAP_BRIGHTNESS);
1566 	return value;
1567 }
1568 
update_bl_status(struct backlight_device * bd)1569 static int update_bl_status(struct backlight_device *bd)
1570 {
1571 	int intensity = backlight_get_brightness(bd);
1572 
1573 	set_u32(intensity, ACER_CAP_BRIGHTNESS);
1574 
1575 	return 0;
1576 }
1577 
1578 static const struct backlight_ops acer_bl_ops = {
1579 	.get_brightness = read_brightness,
1580 	.update_status = update_bl_status,
1581 };
1582 
acer_backlight_init(struct device * dev)1583 static int acer_backlight_init(struct device *dev)
1584 {
1585 	struct backlight_properties props;
1586 	struct backlight_device *bd;
1587 
1588 	memset(&props, 0, sizeof(struct backlight_properties));
1589 	props.type = BACKLIGHT_PLATFORM;
1590 	props.max_brightness = max_brightness;
1591 	bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops,
1592 				       &props);
1593 	if (IS_ERR(bd)) {
1594 		pr_err("Could not register Acer backlight device\n");
1595 		acer_backlight_device = NULL;
1596 		return PTR_ERR(bd);
1597 	}
1598 
1599 	acer_backlight_device = bd;
1600 
1601 	bd->props.power = FB_BLANK_UNBLANK;
1602 	bd->props.brightness = read_brightness(bd);
1603 	backlight_update_status(bd);
1604 	return 0;
1605 }
1606 
acer_backlight_exit(void)1607 static void acer_backlight_exit(void)
1608 {
1609 	backlight_device_unregister(acer_backlight_device);
1610 }
1611 
1612 /*
1613  * Accelerometer device
1614  */
1615 static acpi_handle gsensor_handle;
1616 
acer_gsensor_init(void)1617 static int acer_gsensor_init(void)
1618 {
1619 	acpi_status status;
1620 	struct acpi_buffer output;
1621 	union acpi_object out_obj;
1622 
1623 	output.length = sizeof(out_obj);
1624 	output.pointer = &out_obj;
1625 	status = acpi_evaluate_object(gsensor_handle, "_INI", NULL, &output);
1626 	if (ACPI_FAILURE(status))
1627 		return -1;
1628 
1629 	return 0;
1630 }
1631 
acer_gsensor_open(struct input_dev * input)1632 static int acer_gsensor_open(struct input_dev *input)
1633 {
1634 	return acer_gsensor_init();
1635 }
1636 
acer_gsensor_event(void)1637 static int acer_gsensor_event(void)
1638 {
1639 	acpi_status status;
1640 	struct acpi_buffer output;
1641 	union acpi_object out_obj[5];
1642 
1643 	if (!acer_wmi_accel_dev)
1644 		return -1;
1645 
1646 	output.length = sizeof(out_obj);
1647 	output.pointer = out_obj;
1648 
1649 	status = acpi_evaluate_object(gsensor_handle, "RDVL", NULL, &output);
1650 	if (ACPI_FAILURE(status))
1651 		return -1;
1652 
1653 	if (out_obj->package.count != 4)
1654 		return -1;
1655 
1656 	input_report_abs(acer_wmi_accel_dev, ABS_X,
1657 		(s16)out_obj->package.elements[0].integer.value);
1658 	input_report_abs(acer_wmi_accel_dev, ABS_Y,
1659 		(s16)out_obj->package.elements[1].integer.value);
1660 	input_report_abs(acer_wmi_accel_dev, ABS_Z,
1661 		(s16)out_obj->package.elements[2].integer.value);
1662 	input_sync(acer_wmi_accel_dev);
1663 	return 0;
1664 }
1665 
1666 /*
1667  *  Predator series turbo button
1668  */
acer_toggle_turbo(void)1669 static int acer_toggle_turbo(void)
1670 {
1671 	u64 turbo_led_state;
1672 
1673 	/* Get current state from turbo button */
1674 	if (ACPI_FAILURE(WMID_gaming_get_u64(&turbo_led_state, ACER_CAP_TURBO_LED)))
1675 		return -1;
1676 
1677 	if (turbo_led_state) {
1678 		/* Turn off turbo led */
1679 		WMID_gaming_set_u64(0x1, ACER_CAP_TURBO_LED);
1680 
1681 		/* Set FAN mode to auto */
1682 		WMID_gaming_set_fan_mode(0x1);
1683 
1684 		/* Set OC to normal */
1685 		WMID_gaming_set_u64(0x5, ACER_CAP_TURBO_OC);
1686 		WMID_gaming_set_u64(0x7, ACER_CAP_TURBO_OC);
1687 	} else {
1688 		/* Turn on turbo led */
1689 		WMID_gaming_set_u64(0x10001, ACER_CAP_TURBO_LED);
1690 
1691 		/* Set FAN mode to turbo */
1692 		WMID_gaming_set_fan_mode(0x2);
1693 
1694 		/* Set OC to turbo mode */
1695 		WMID_gaming_set_u64(0x205, ACER_CAP_TURBO_OC);
1696 		WMID_gaming_set_u64(0x207, ACER_CAP_TURBO_OC);
1697 	}
1698 	return turbo_led_state;
1699 }
1700 
1701 /*
1702  * Switch series keyboard dock status
1703  */
acer_kbd_dock_state_to_sw_tablet_mode(u8 kbd_dock_state)1704 static int acer_kbd_dock_state_to_sw_tablet_mode(u8 kbd_dock_state)
1705 {
1706 	switch (kbd_dock_state) {
1707 	case 0x01: /* Docked, traditional clamshell laptop mode */
1708 		return 0;
1709 	case 0x04: /* Stand-alone tablet */
1710 	case 0x40: /* Docked, tent mode, keyboard not usable */
1711 		return 1;
1712 	default:
1713 		pr_warn("Unknown kbd_dock_state 0x%02x\n", kbd_dock_state);
1714 	}
1715 
1716 	return 0;
1717 }
1718 
acer_kbd_dock_get_initial_state(void)1719 static void acer_kbd_dock_get_initial_state(void)
1720 {
1721 	u8 *output, input[8] = { 0x05, 0x00, };
1722 	struct acpi_buffer input_buf = { sizeof(input), input };
1723 	struct acpi_buffer output_buf = { ACPI_ALLOCATE_BUFFER, NULL };
1724 	union acpi_object *obj;
1725 	acpi_status status;
1726 	int sw_tablet_mode;
1727 
1728 	status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input_buf, &output_buf);
1729 	if (ACPI_FAILURE(status)) {
1730 		pr_err("Error getting keyboard-dock initial status: %s\n",
1731 		       acpi_format_exception(status));
1732 		return;
1733 	}
1734 
1735 	obj = output_buf.pointer;
1736 	if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) {
1737 		pr_err("Unexpected output format getting keyboard-dock initial status\n");
1738 		goto out_free_obj;
1739 	}
1740 
1741 	output = obj->buffer.pointer;
1742 	if (output[0] != 0x00 || (output[3] != 0x05 && output[3] != 0x45)) {
1743 		pr_err("Unexpected output [0]=0x%02x [3]=0x%02x getting keyboard-dock initial status\n",
1744 		       output[0], output[3]);
1745 		goto out_free_obj;
1746 	}
1747 
1748 	sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(output[4]);
1749 	input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode);
1750 
1751 out_free_obj:
1752 	kfree(obj);
1753 }
1754 
acer_kbd_dock_event(const struct event_return_value * event)1755 static void acer_kbd_dock_event(const struct event_return_value *event)
1756 {
1757 	int sw_tablet_mode;
1758 
1759 	if (!has_cap(ACER_CAP_KBD_DOCK))
1760 		return;
1761 
1762 	sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(event->kbd_dock_state);
1763 	input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode);
1764 	input_sync(acer_wmi_input_dev);
1765 }
1766 
1767 /*
1768  * Rfkill devices
1769  */
1770 static void acer_rfkill_update(struct work_struct *ignored);
1771 static DECLARE_DELAYED_WORK(acer_rfkill_work, acer_rfkill_update);
acer_rfkill_update(struct work_struct * ignored)1772 static void acer_rfkill_update(struct work_struct *ignored)
1773 {
1774 	u32 state;
1775 	acpi_status status;
1776 
1777 	if (has_cap(ACER_CAP_WIRELESS)) {
1778 		status = get_u32(&state, ACER_CAP_WIRELESS);
1779 		if (ACPI_SUCCESS(status)) {
1780 			if (quirks->wireless == 3)
1781 				rfkill_set_hw_state(wireless_rfkill, !state);
1782 			else
1783 				rfkill_set_sw_state(wireless_rfkill, !state);
1784 		}
1785 	}
1786 
1787 	if (has_cap(ACER_CAP_BLUETOOTH)) {
1788 		status = get_u32(&state, ACER_CAP_BLUETOOTH);
1789 		if (ACPI_SUCCESS(status))
1790 			rfkill_set_sw_state(bluetooth_rfkill, !state);
1791 	}
1792 
1793 	if (has_cap(ACER_CAP_THREEG) && wmi_has_guid(WMID_GUID3)) {
1794 		status = get_u32(&state, ACER_WMID3_GDS_THREEG);
1795 		if (ACPI_SUCCESS(status))
1796 			rfkill_set_sw_state(threeg_rfkill, !state);
1797 	}
1798 
1799 	schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
1800 }
1801 
acer_rfkill_set(void * data,bool blocked)1802 static int acer_rfkill_set(void *data, bool blocked)
1803 {
1804 	acpi_status status;
1805 	u32 cap = (unsigned long)data;
1806 
1807 	if (rfkill_inited) {
1808 		status = set_u32(!blocked, cap);
1809 		if (ACPI_FAILURE(status))
1810 			return -ENODEV;
1811 	}
1812 
1813 	return 0;
1814 }
1815 
1816 static const struct rfkill_ops acer_rfkill_ops = {
1817 	.set_block = acer_rfkill_set,
1818 };
1819 
acer_rfkill_register(struct device * dev,enum rfkill_type type,char * name,u32 cap)1820 static struct rfkill *acer_rfkill_register(struct device *dev,
1821 					   enum rfkill_type type,
1822 					   char *name, u32 cap)
1823 {
1824 	int err;
1825 	struct rfkill *rfkill_dev;
1826 	u32 state;
1827 	acpi_status status;
1828 
1829 	rfkill_dev = rfkill_alloc(name, dev, type,
1830 				  &acer_rfkill_ops,
1831 				  (void *)(unsigned long)cap);
1832 	if (!rfkill_dev)
1833 		return ERR_PTR(-ENOMEM);
1834 
1835 	status = get_u32(&state, cap);
1836 
1837 	err = rfkill_register(rfkill_dev);
1838 	if (err) {
1839 		rfkill_destroy(rfkill_dev);
1840 		return ERR_PTR(err);
1841 	}
1842 
1843 	if (ACPI_SUCCESS(status))
1844 		rfkill_set_sw_state(rfkill_dev, !state);
1845 
1846 	return rfkill_dev;
1847 }
1848 
acer_rfkill_init(struct device * dev)1849 static int acer_rfkill_init(struct device *dev)
1850 {
1851 	int err;
1852 
1853 	if (has_cap(ACER_CAP_WIRELESS)) {
1854 		wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN,
1855 			"acer-wireless", ACER_CAP_WIRELESS);
1856 		if (IS_ERR(wireless_rfkill)) {
1857 			err = PTR_ERR(wireless_rfkill);
1858 			goto error_wireless;
1859 		}
1860 	}
1861 
1862 	if (has_cap(ACER_CAP_BLUETOOTH)) {
1863 		bluetooth_rfkill = acer_rfkill_register(dev,
1864 			RFKILL_TYPE_BLUETOOTH, "acer-bluetooth",
1865 			ACER_CAP_BLUETOOTH);
1866 		if (IS_ERR(bluetooth_rfkill)) {
1867 			err = PTR_ERR(bluetooth_rfkill);
1868 			goto error_bluetooth;
1869 		}
1870 	}
1871 
1872 	if (has_cap(ACER_CAP_THREEG)) {
1873 		threeg_rfkill = acer_rfkill_register(dev,
1874 			RFKILL_TYPE_WWAN, "acer-threeg",
1875 			ACER_CAP_THREEG);
1876 		if (IS_ERR(threeg_rfkill)) {
1877 			err = PTR_ERR(threeg_rfkill);
1878 			goto error_threeg;
1879 		}
1880 	}
1881 
1882 	rfkill_inited = true;
1883 
1884 	if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) &&
1885 	    has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG))
1886 		schedule_delayed_work(&acer_rfkill_work,
1887 			round_jiffies_relative(HZ));
1888 
1889 	return 0;
1890 
1891 error_threeg:
1892 	if (has_cap(ACER_CAP_BLUETOOTH)) {
1893 		rfkill_unregister(bluetooth_rfkill);
1894 		rfkill_destroy(bluetooth_rfkill);
1895 	}
1896 error_bluetooth:
1897 	if (has_cap(ACER_CAP_WIRELESS)) {
1898 		rfkill_unregister(wireless_rfkill);
1899 		rfkill_destroy(wireless_rfkill);
1900 	}
1901 error_wireless:
1902 	return err;
1903 }
1904 
acer_rfkill_exit(void)1905 static void acer_rfkill_exit(void)
1906 {
1907 	if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) &&
1908 	    has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG))
1909 		cancel_delayed_work_sync(&acer_rfkill_work);
1910 
1911 	if (has_cap(ACER_CAP_WIRELESS)) {
1912 		rfkill_unregister(wireless_rfkill);
1913 		rfkill_destroy(wireless_rfkill);
1914 	}
1915 
1916 	if (has_cap(ACER_CAP_BLUETOOTH)) {
1917 		rfkill_unregister(bluetooth_rfkill);
1918 		rfkill_destroy(bluetooth_rfkill);
1919 	}
1920 
1921 	if (has_cap(ACER_CAP_THREEG)) {
1922 		rfkill_unregister(threeg_rfkill);
1923 		rfkill_destroy(threeg_rfkill);
1924 	}
1925 	return;
1926 }
1927 
acer_wmi_notify(u32 value,void * context)1928 static void acer_wmi_notify(u32 value, void *context)
1929 {
1930 	struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
1931 	union acpi_object *obj;
1932 	struct event_return_value return_value;
1933 	acpi_status status;
1934 	u16 device_state;
1935 	const struct key_entry *key;
1936 	u32 scancode;
1937 
1938 	status = wmi_get_event_data(value, &response);
1939 	if (status != AE_OK) {
1940 		pr_warn("bad event status 0x%x\n", status);
1941 		return;
1942 	}
1943 
1944 	obj = (union acpi_object *)response.pointer;
1945 
1946 	if (!obj)
1947 		return;
1948 	if (obj->type != ACPI_TYPE_BUFFER) {
1949 		pr_warn("Unknown response received %d\n", obj->type);
1950 		kfree(obj);
1951 		return;
1952 	}
1953 	if (obj->buffer.length != 8) {
1954 		pr_warn("Unknown buffer length %d\n", obj->buffer.length);
1955 		kfree(obj);
1956 		return;
1957 	}
1958 
1959 	return_value = *((struct event_return_value *)obj->buffer.pointer);
1960 	kfree(obj);
1961 
1962 	switch (return_value.function) {
1963 	case WMID_HOTKEY_EVENT:
1964 		device_state = return_value.device_state;
1965 		pr_debug("device state: 0x%x\n", device_state);
1966 
1967 		key = sparse_keymap_entry_from_scancode(acer_wmi_input_dev,
1968 							return_value.key_num);
1969 		if (!key) {
1970 			pr_warn("Unknown key number - 0x%x\n",
1971 				return_value.key_num);
1972 		} else {
1973 			scancode = return_value.key_num;
1974 			switch (key->keycode) {
1975 			case KEY_WLAN:
1976 			case KEY_BLUETOOTH:
1977 				if (has_cap(ACER_CAP_WIRELESS))
1978 					rfkill_set_sw_state(wireless_rfkill,
1979 						!(device_state & ACER_WMID3_GDS_WIRELESS));
1980 				if (has_cap(ACER_CAP_THREEG))
1981 					rfkill_set_sw_state(threeg_rfkill,
1982 						!(device_state & ACER_WMID3_GDS_THREEG));
1983 				if (has_cap(ACER_CAP_BLUETOOTH))
1984 					rfkill_set_sw_state(bluetooth_rfkill,
1985 						!(device_state & ACER_WMID3_GDS_BLUETOOTH));
1986 				break;
1987 			case KEY_TOUCHPAD_TOGGLE:
1988 				scancode = (device_state & ACER_WMID3_GDS_TOUCHPAD) ?
1989 						KEY_TOUCHPAD_ON : KEY_TOUCHPAD_OFF;
1990 			}
1991 			sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true);
1992 		}
1993 		break;
1994 	case WMID_ACCEL_OR_KBD_DOCK_EVENT:
1995 		acer_gsensor_event();
1996 		acer_kbd_dock_event(&return_value);
1997 		break;
1998 	case WMID_GAMING_TURBO_KEY_EVENT:
1999 		if (return_value.key_num == 0x4)
2000 			acer_toggle_turbo();
2001 		break;
2002 	default:
2003 		pr_warn("Unknown function number - %d - %d\n",
2004 			return_value.function, return_value.key_num);
2005 		break;
2006 	}
2007 }
2008 
2009 static acpi_status __init
wmid3_set_function_mode(struct func_input_params * params,struct func_return_value * return_value)2010 wmid3_set_function_mode(struct func_input_params *params,
2011 			struct func_return_value *return_value)
2012 {
2013 	acpi_status status;
2014 	union acpi_object *obj;
2015 
2016 	struct acpi_buffer input = { sizeof(struct func_input_params), params };
2017 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
2018 
2019 	status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output);
2020 	if (ACPI_FAILURE(status))
2021 		return status;
2022 
2023 	obj = output.pointer;
2024 
2025 	if (!obj)
2026 		return AE_ERROR;
2027 	else if (obj->type != ACPI_TYPE_BUFFER) {
2028 		kfree(obj);
2029 		return AE_ERROR;
2030 	}
2031 	if (obj->buffer.length != 4) {
2032 		pr_warn("Unknown buffer length %d\n", obj->buffer.length);
2033 		kfree(obj);
2034 		return AE_ERROR;
2035 	}
2036 
2037 	*return_value = *((struct func_return_value *)obj->buffer.pointer);
2038 	kfree(obj);
2039 
2040 	return status;
2041 }
2042 
acer_wmi_enable_ec_raw(void)2043 static int __init acer_wmi_enable_ec_raw(void)
2044 {
2045 	struct func_return_value return_value;
2046 	acpi_status status;
2047 	struct func_input_params params = {
2048 		.function_num = 0x1,
2049 		.commun_devices = 0xFFFF,
2050 		.devices = 0xFFFF,
2051 		.app_status = 0x00,		/* Launch Manager Deactive */
2052 		.app_mask = 0x01,
2053 	};
2054 
2055 	status = wmid3_set_function_mode(&params, &return_value);
2056 
2057 	if (return_value.error_code || return_value.ec_return_value)
2058 		pr_warn("Enabling EC raw mode failed: 0x%x - 0x%x\n",
2059 			return_value.error_code,
2060 			return_value.ec_return_value);
2061 	else
2062 		pr_info("Enabled EC raw mode\n");
2063 
2064 	return status;
2065 }
2066 
acer_wmi_enable_lm(void)2067 static int __init acer_wmi_enable_lm(void)
2068 {
2069 	struct func_return_value return_value;
2070 	acpi_status status;
2071 	struct func_input_params params = {
2072 		.function_num = 0x1,
2073 		.commun_devices = 0xFFFF,
2074 		.devices = 0xFFFF,
2075 		.app_status = 0x01,            /* Launch Manager Active */
2076 		.app_mask = 0x01,
2077 	};
2078 
2079 	status = wmid3_set_function_mode(&params, &return_value);
2080 
2081 	if (return_value.error_code || return_value.ec_return_value)
2082 		pr_warn("Enabling Launch Manager failed: 0x%x - 0x%x\n",
2083 			return_value.error_code,
2084 			return_value.ec_return_value);
2085 
2086 	return status;
2087 }
2088 
acer_wmi_enable_rf_button(void)2089 static int __init acer_wmi_enable_rf_button(void)
2090 {
2091 	struct func_return_value return_value;
2092 	acpi_status status;
2093 	struct func_input_params params = {
2094 		.function_num = 0x1,
2095 		.commun_devices = 0xFFFF,
2096 		.devices = 0xFFFF,
2097 		.app_status = 0x10,            /* RF Button Active */
2098 		.app_mask = 0x10,
2099 	};
2100 
2101 	status = wmid3_set_function_mode(&params, &return_value);
2102 
2103 	if (return_value.error_code || return_value.ec_return_value)
2104 		pr_warn("Enabling RF Button failed: 0x%x - 0x%x\n",
2105 			return_value.error_code,
2106 			return_value.ec_return_value);
2107 
2108 	return status;
2109 }
2110 
acer_wmi_accel_setup(void)2111 static int __init acer_wmi_accel_setup(void)
2112 {
2113 	struct acpi_device *adev;
2114 	int err;
2115 
2116 	adev = acpi_dev_get_first_match_dev("BST0001", NULL, -1);
2117 	if (!adev)
2118 		return -ENODEV;
2119 
2120 	gsensor_handle = acpi_device_handle(adev);
2121 	acpi_dev_put(adev);
2122 
2123 	acer_wmi_accel_dev = input_allocate_device();
2124 	if (!acer_wmi_accel_dev)
2125 		return -ENOMEM;
2126 
2127 	acer_wmi_accel_dev->open = acer_gsensor_open;
2128 
2129 	acer_wmi_accel_dev->name = "Acer BMA150 accelerometer";
2130 	acer_wmi_accel_dev->phys = "wmi/input1";
2131 	acer_wmi_accel_dev->id.bustype = BUS_HOST;
2132 	acer_wmi_accel_dev->evbit[0] = BIT_MASK(EV_ABS);
2133 	input_set_abs_params(acer_wmi_accel_dev, ABS_X, -16384, 16384, 0, 0);
2134 	input_set_abs_params(acer_wmi_accel_dev, ABS_Y, -16384, 16384, 0, 0);
2135 	input_set_abs_params(acer_wmi_accel_dev, ABS_Z, -16384, 16384, 0, 0);
2136 
2137 	err = input_register_device(acer_wmi_accel_dev);
2138 	if (err)
2139 		goto err_free_dev;
2140 
2141 	return 0;
2142 
2143 err_free_dev:
2144 	input_free_device(acer_wmi_accel_dev);
2145 	return err;
2146 }
2147 
acer_wmi_input_setup(void)2148 static int __init acer_wmi_input_setup(void)
2149 {
2150 	acpi_status status;
2151 	int err;
2152 
2153 	acer_wmi_input_dev = input_allocate_device();
2154 	if (!acer_wmi_input_dev)
2155 		return -ENOMEM;
2156 
2157 	acer_wmi_input_dev->name = "Acer WMI hotkeys";
2158 	acer_wmi_input_dev->phys = "wmi/input0";
2159 	acer_wmi_input_dev->id.bustype = BUS_HOST;
2160 
2161 	err = sparse_keymap_setup(acer_wmi_input_dev, acer_wmi_keymap, NULL);
2162 	if (err)
2163 		goto err_free_dev;
2164 
2165 	if (has_cap(ACER_CAP_KBD_DOCK))
2166 		input_set_capability(acer_wmi_input_dev, EV_SW, SW_TABLET_MODE);
2167 
2168 	status = wmi_install_notify_handler(ACERWMID_EVENT_GUID,
2169 						acer_wmi_notify, NULL);
2170 	if (ACPI_FAILURE(status)) {
2171 		err = -EIO;
2172 		goto err_free_dev;
2173 	}
2174 
2175 	if (has_cap(ACER_CAP_KBD_DOCK))
2176 		acer_kbd_dock_get_initial_state();
2177 
2178 	err = input_register_device(acer_wmi_input_dev);
2179 	if (err)
2180 		goto err_uninstall_notifier;
2181 
2182 	return 0;
2183 
2184 err_uninstall_notifier:
2185 	wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
2186 err_free_dev:
2187 	input_free_device(acer_wmi_input_dev);
2188 	return err;
2189 }
2190 
acer_wmi_input_destroy(void)2191 static void acer_wmi_input_destroy(void)
2192 {
2193 	wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
2194 	input_unregister_device(acer_wmi_input_dev);
2195 }
2196 
2197 /*
2198  * debugfs functions
2199  */
get_wmid_devices(void)2200 static u32 get_wmid_devices(void)
2201 {
2202 	struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
2203 	union acpi_object *obj;
2204 	acpi_status status;
2205 	u32 devices = 0;
2206 
2207 	status = wmi_query_block(WMID_GUID2, 0, &out);
2208 	if (ACPI_FAILURE(status))
2209 		return 0;
2210 
2211 	obj = (union acpi_object *) out.pointer;
2212 	if (obj) {
2213 		if (obj->type == ACPI_TYPE_BUFFER &&
2214 			(obj->buffer.length == sizeof(u32) ||
2215 			obj->buffer.length == sizeof(u64))) {
2216 			devices = *((u32 *) obj->buffer.pointer);
2217 		} else if (obj->type == ACPI_TYPE_INTEGER) {
2218 			devices = (u32) obj->integer.value;
2219 		}
2220 	}
2221 
2222 	kfree(out.pointer);
2223 	return devices;
2224 }
2225 
2226 /*
2227  * Platform device
2228  */
acer_platform_probe(struct platform_device * device)2229 static int acer_platform_probe(struct platform_device *device)
2230 {
2231 	int err;
2232 
2233 	if (has_cap(ACER_CAP_MAILLED)) {
2234 		err = acer_led_init(&device->dev);
2235 		if (err)
2236 			goto error_mailled;
2237 	}
2238 
2239 	if (has_cap(ACER_CAP_BRIGHTNESS)) {
2240 		err = acer_backlight_init(&device->dev);
2241 		if (err)
2242 			goto error_brightness;
2243 	}
2244 
2245 	err = acer_rfkill_init(&device->dev);
2246 	if (err)
2247 		goto error_rfkill;
2248 
2249 	return err;
2250 
2251 error_rfkill:
2252 	if (has_cap(ACER_CAP_BRIGHTNESS))
2253 		acer_backlight_exit();
2254 error_brightness:
2255 	if (has_cap(ACER_CAP_MAILLED))
2256 		acer_led_exit();
2257 error_mailled:
2258 	return err;
2259 }
2260 
acer_platform_remove(struct platform_device * device)2261 static void acer_platform_remove(struct platform_device *device)
2262 {
2263 	if (has_cap(ACER_CAP_MAILLED))
2264 		acer_led_exit();
2265 	if (has_cap(ACER_CAP_BRIGHTNESS))
2266 		acer_backlight_exit();
2267 
2268 	acer_rfkill_exit();
2269 }
2270 
2271 #ifdef CONFIG_PM_SLEEP
acer_suspend(struct device * dev)2272 static int acer_suspend(struct device *dev)
2273 {
2274 	u32 value;
2275 	struct acer_data *data = &interface->data;
2276 
2277 	if (!data)
2278 		return -ENOMEM;
2279 
2280 	if (has_cap(ACER_CAP_MAILLED)) {
2281 		get_u32(&value, ACER_CAP_MAILLED);
2282 		set_u32(LED_OFF, ACER_CAP_MAILLED);
2283 		data->mailled = value;
2284 	}
2285 
2286 	if (has_cap(ACER_CAP_BRIGHTNESS)) {
2287 		get_u32(&value, ACER_CAP_BRIGHTNESS);
2288 		data->brightness = value;
2289 	}
2290 
2291 	return 0;
2292 }
2293 
acer_resume(struct device * dev)2294 static int acer_resume(struct device *dev)
2295 {
2296 	struct acer_data *data = &interface->data;
2297 
2298 	if (!data)
2299 		return -ENOMEM;
2300 
2301 	if (has_cap(ACER_CAP_MAILLED))
2302 		set_u32(data->mailled, ACER_CAP_MAILLED);
2303 
2304 	if (has_cap(ACER_CAP_BRIGHTNESS))
2305 		set_u32(data->brightness, ACER_CAP_BRIGHTNESS);
2306 
2307 	if (acer_wmi_accel_dev)
2308 		acer_gsensor_init();
2309 
2310 	return 0;
2311 }
2312 #else
2313 #define acer_suspend	NULL
2314 #define acer_resume	NULL
2315 #endif
2316 
2317 static SIMPLE_DEV_PM_OPS(acer_pm, acer_suspend, acer_resume);
2318 
acer_platform_shutdown(struct platform_device * device)2319 static void acer_platform_shutdown(struct platform_device *device)
2320 {
2321 	struct acer_data *data = &interface->data;
2322 
2323 	if (!data)
2324 		return;
2325 
2326 	if (has_cap(ACER_CAP_MAILLED))
2327 		set_u32(LED_OFF, ACER_CAP_MAILLED);
2328 }
2329 
2330 static struct platform_driver acer_platform_driver = {
2331 	.driver = {
2332 		.name = "acer-wmi",
2333 		.pm = &acer_pm,
2334 	},
2335 	.probe = acer_platform_probe,
2336 	.remove_new = acer_platform_remove,
2337 	.shutdown = acer_platform_shutdown,
2338 };
2339 
2340 static struct platform_device *acer_platform_device;
2341 
remove_debugfs(void)2342 static void remove_debugfs(void)
2343 {
2344 	debugfs_remove_recursive(interface->debug.root);
2345 }
2346 
create_debugfs(void)2347 static void __init create_debugfs(void)
2348 {
2349 	interface->debug.root = debugfs_create_dir("acer-wmi", NULL);
2350 
2351 	debugfs_create_u32("devices", S_IRUGO, interface->debug.root,
2352 			   &interface->debug.wmid_devices);
2353 }
2354 
acer_wmi_init(void)2355 static int __init acer_wmi_init(void)
2356 {
2357 	int err;
2358 
2359 	pr_info("Acer Laptop ACPI-WMI Extras\n");
2360 
2361 	if (dmi_check_system(acer_blacklist)) {
2362 		pr_info("Blacklisted hardware detected - not loading\n");
2363 		return -ENODEV;
2364 	}
2365 
2366 	find_quirks();
2367 
2368 	/*
2369 	 * The AMW0_GUID1 wmi is not only found on Acer family but also other
2370 	 * machines like Lenovo, Fujitsu and Medion. In the past days,
2371 	 * acer-wmi driver handled those non-Acer machines by quirks list.
2372 	 * But actually acer-wmi driver was loaded on any machines that have
2373 	 * AMW0_GUID1. This behavior is strange because those machines should
2374 	 * be supported by appropriate wmi drivers. e.g. fujitsu-laptop,
2375 	 * ideapad-laptop. So, here checks the machine that has AMW0_GUID1
2376 	 * should be in Acer/Gateway/Packard Bell white list, or it's already
2377 	 * in the past quirk list.
2378 	 */
2379 	if (wmi_has_guid(AMW0_GUID1) &&
2380 	    !dmi_check_system(amw0_whitelist) &&
2381 	    quirks == &quirk_unknown) {
2382 		pr_debug("Unsupported machine has AMW0_GUID1, unable to load\n");
2383 		return -ENODEV;
2384 	}
2385 
2386 	/*
2387 	 * Detect which ACPI-WMI interface we're using.
2388 	 */
2389 	if (wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1))
2390 		interface = &AMW0_V2_interface;
2391 
2392 	if (!wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1))
2393 		interface = &wmid_interface;
2394 
2395 	if (wmi_has_guid(WMID_GUID3))
2396 		interface = &wmid_v2_interface;
2397 
2398 	if (interface)
2399 		dmi_walk(type_aa_dmi_decode, NULL);
2400 
2401 	if (wmi_has_guid(WMID_GUID2) && interface) {
2402 		if (!has_type_aa && ACPI_FAILURE(WMID_set_capabilities())) {
2403 			pr_err("Unable to detect available WMID devices\n");
2404 			return -ENODEV;
2405 		}
2406 		/* WMID always provides brightness methods */
2407 		interface->capability |= ACER_CAP_BRIGHTNESS;
2408 	} else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa && force_caps == -1) {
2409 		pr_err("No WMID device detection method found\n");
2410 		return -ENODEV;
2411 	}
2412 
2413 	if (wmi_has_guid(AMW0_GUID1) && !wmi_has_guid(WMID_GUID1)) {
2414 		interface = &AMW0_interface;
2415 
2416 		if (ACPI_FAILURE(AMW0_set_capabilities())) {
2417 			pr_err("Unable to detect available AMW0 devices\n");
2418 			return -ENODEV;
2419 		}
2420 	}
2421 
2422 	if (wmi_has_guid(AMW0_GUID1))
2423 		AMW0_find_mailled();
2424 
2425 	if (!interface) {
2426 		pr_err("No or unsupported WMI interface, unable to load\n");
2427 		return -ENODEV;
2428 	}
2429 
2430 	set_quirks();
2431 
2432 	if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
2433 		interface->capability &= ~ACER_CAP_BRIGHTNESS;
2434 
2435 	if (wmi_has_guid(WMID_GUID3))
2436 		interface->capability |= ACER_CAP_SET_FUNCTION_MODE;
2437 
2438 	if (force_caps != -1)
2439 		interface->capability = force_caps;
2440 
2441 	if (wmi_has_guid(WMID_GUID3) &&
2442 	    (interface->capability & ACER_CAP_SET_FUNCTION_MODE)) {
2443 		if (ACPI_FAILURE(acer_wmi_enable_rf_button()))
2444 			pr_warn("Cannot enable RF Button Driver\n");
2445 
2446 		if (ec_raw_mode) {
2447 			if (ACPI_FAILURE(acer_wmi_enable_ec_raw())) {
2448 				pr_err("Cannot enable EC raw mode\n");
2449 				return -ENODEV;
2450 			}
2451 		} else if (ACPI_FAILURE(acer_wmi_enable_lm())) {
2452 			pr_err("Cannot enable Launch Manager mode\n");
2453 			return -ENODEV;
2454 		}
2455 	} else if (ec_raw_mode) {
2456 		pr_info("No WMID EC raw mode enable method\n");
2457 	}
2458 
2459 	if (wmi_has_guid(ACERWMID_EVENT_GUID)) {
2460 		err = acer_wmi_input_setup();
2461 		if (err)
2462 			return err;
2463 		err = acer_wmi_accel_setup();
2464 		if (err && err != -ENODEV)
2465 			pr_warn("Cannot enable accelerometer\n");
2466 	}
2467 
2468 	err = platform_driver_register(&acer_platform_driver);
2469 	if (err) {
2470 		pr_err("Unable to register platform driver\n");
2471 		goto error_platform_register;
2472 	}
2473 
2474 	acer_platform_device = platform_device_alloc("acer-wmi", PLATFORM_DEVID_NONE);
2475 	if (!acer_platform_device) {
2476 		err = -ENOMEM;
2477 		goto error_device_alloc;
2478 	}
2479 
2480 	err = platform_device_add(acer_platform_device);
2481 	if (err)
2482 		goto error_device_add;
2483 
2484 	if (wmi_has_guid(WMID_GUID2)) {
2485 		interface->debug.wmid_devices = get_wmid_devices();
2486 		create_debugfs();
2487 	}
2488 
2489 	/* Override any initial settings with values from the commandline */
2490 	acer_commandline_init();
2491 
2492 	return 0;
2493 
2494 error_device_add:
2495 	platform_device_put(acer_platform_device);
2496 error_device_alloc:
2497 	platform_driver_unregister(&acer_platform_driver);
2498 error_platform_register:
2499 	if (wmi_has_guid(ACERWMID_EVENT_GUID))
2500 		acer_wmi_input_destroy();
2501 	if (acer_wmi_accel_dev)
2502 		input_unregister_device(acer_wmi_accel_dev);
2503 
2504 	return err;
2505 }
2506 
acer_wmi_exit(void)2507 static void __exit acer_wmi_exit(void)
2508 {
2509 	if (wmi_has_guid(ACERWMID_EVENT_GUID))
2510 		acer_wmi_input_destroy();
2511 
2512 	if (acer_wmi_accel_dev)
2513 		input_unregister_device(acer_wmi_accel_dev);
2514 
2515 	remove_debugfs();
2516 	platform_device_unregister(acer_platform_device);
2517 	platform_driver_unregister(&acer_platform_driver);
2518 
2519 	pr_info("Acer Laptop WMI Extras unloaded\n");
2520 	return;
2521 }
2522 
2523 module_init(acer_wmi_init);
2524 module_exit(acer_wmi_exit);
2525