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