xref: /linux/drivers/platform/x86/acer-wmi.c (revision c02ce1735b150cf7c3b43790b48e23dcd17c0d46)
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 = set_force_caps,
602 		.ident = "Acer Aspire Switch 10E SW3-016",
603 		.matches = {
604 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
605 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW3-016"),
606 		},
607 		.driver_data = (void *)ACER_CAP_KBD_DOCK,
608 	},
609 	{
610 		.callback = set_force_caps,
611 		.ident = "Acer Aspire Switch 10 SW5-012",
612 		.matches = {
613 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
614 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
615 		},
616 		.driver_data = (void *)ACER_CAP_KBD_DOCK,
617 	},
618 	{
619 		.callback = set_force_caps,
620 		.ident = "Acer Aspire Switch V 10 SW5-017",
621 		.matches = {
622 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
623 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"),
624 		},
625 		.driver_data = (void *)ACER_CAP_KBD_DOCK,
626 	},
627 	{
628 		.callback = set_force_caps,
629 		.ident = "Acer One 10 (S1003)",
630 		.matches = {
631 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
632 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"),
633 		},
634 		.driver_data = (void *)ACER_CAP_KBD_DOCK,
635 	},
636 	{}
637 };
638 
639 /*
640  * This quirk list is for those non-acer machines that have AMW0_GUID1
641  * but supported by acer-wmi in past days. Keeping this quirk list here
642  * is only for backward compatible. Please do not add new machine to
643  * here anymore. Those non-acer machines should be supported by
644  * appropriate wmi drivers.
645  */
646 static const struct dmi_system_id non_acer_quirks[] __initconst = {
647 	{
648 		.callback = dmi_matched,
649 		.ident = "Fujitsu Siemens Amilo Li 1718",
650 		.matches = {
651 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
652 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Li 1718"),
653 		},
654 		.driver_data = &quirk_fujitsu_amilo_li_1718,
655 	},
656 	{
657 		.callback = dmi_matched,
658 		.ident = "Medion MD 98300",
659 		.matches = {
660 			DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
661 			DMI_MATCH(DMI_PRODUCT_NAME, "WAM2030"),
662 		},
663 		.driver_data = &quirk_medion_md_98300,
664 	},
665 	{
666 		.callback = dmi_matched,
667 		.ident = "Lenovo Ideapad S205",
668 		.matches = {
669 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
670 			DMI_MATCH(DMI_PRODUCT_NAME, "10382LG"),
671 		},
672 		.driver_data = &quirk_lenovo_ideapad_s205,
673 	},
674 	{
675 		.callback = dmi_matched,
676 		.ident = "Lenovo Ideapad S205 (Brazos)",
677 		.matches = {
678 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
679 			DMI_MATCH(DMI_PRODUCT_NAME, "Brazos"),
680 		},
681 		.driver_data = &quirk_lenovo_ideapad_s205,
682 	},
683 	{
684 		.callback = dmi_matched,
685 		.ident = "Lenovo 3000 N200",
686 		.matches = {
687 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
688 			DMI_MATCH(DMI_PRODUCT_NAME, "0687A31"),
689 		},
690 		.driver_data = &quirk_fujitsu_amilo_li_1718,
691 	},
692 	{
693 		.callback = dmi_matched,
694 		.ident = "Lenovo Ideapad S205-10382JG",
695 		.matches = {
696 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
697 			DMI_MATCH(DMI_PRODUCT_NAME, "10382JG"),
698 		},
699 		.driver_data = &quirk_lenovo_ideapad_s205,
700 	},
701 	{
702 		.callback = dmi_matched,
703 		.ident = "Lenovo Ideapad S205-1038DPG",
704 		.matches = {
705 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
706 			DMI_MATCH(DMI_PRODUCT_NAME, "1038DPG"),
707 		},
708 		.driver_data = &quirk_lenovo_ideapad_s205,
709 	},
710 	{}
711 };
712 
713 static struct platform_profile_handler platform_profile_handler;
714 static bool platform_profile_support;
715 
716 /*
717  * The profile used before turbo mode. This variable is needed for
718  * returning from turbo mode when the mode key is in toggle mode.
719  */
720 static int last_non_turbo_profile;
721 
722 enum acer_predator_v4_thermal_profile_ec {
723 	ACER_PREDATOR_V4_THERMAL_PROFILE_ECO = 0x04,
724 	ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO = 0x03,
725 	ACER_PREDATOR_V4_THERMAL_PROFILE_PERFORMANCE = 0x02,
726 	ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET = 0x01,
727 	ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED = 0x00,
728 };
729 
730 enum acer_predator_v4_thermal_profile_wmi {
731 	ACER_PREDATOR_V4_THERMAL_PROFILE_ECO_WMI = 0x060B,
732 	ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO_WMI = 0x050B,
733 	ACER_PREDATOR_V4_THERMAL_PROFILE_PERFORMANCE_WMI = 0x040B,
734 	ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET_WMI = 0x0B,
735 	ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED_WMI = 0x010B,
736 };
737 
738 /* Find which quirks are needed for a particular vendor/ model pair */
739 static void __init find_quirks(void)
740 {
741 	if (predator_v4) {
742 		quirks = &quirk_acer_predator_v4;
743 	} else if (!force_series) {
744 		dmi_check_system(acer_quirks);
745 		dmi_check_system(non_acer_quirks);
746 	} else if (force_series == 2490) {
747 		quirks = &quirk_acer_travelmate_2490;
748 	}
749 
750 	if (quirks == NULL)
751 		quirks = &quirk_unknown;
752 }
753 
754 /*
755  * General interface convenience methods
756  */
757 
758 static bool has_cap(u32 cap)
759 {
760 	return interface->capability & cap;
761 }
762 
763 /*
764  * AMW0 (V1) interface
765  */
766 struct wmab_args {
767 	u32 eax;
768 	u32 ebx;
769 	u32 ecx;
770 	u32 edx;
771 };
772 
773 struct wmab_ret {
774 	u32 eax;
775 	u32 ebx;
776 	u32 ecx;
777 	u32 edx;
778 	u32 eex;
779 };
780 
781 static acpi_status wmab_execute(struct wmab_args *regbuf,
782 struct acpi_buffer *result)
783 {
784 	struct acpi_buffer input;
785 	acpi_status status;
786 	input.length = sizeof(struct wmab_args);
787 	input.pointer = (u8 *)regbuf;
788 
789 	status = wmi_evaluate_method(AMW0_GUID1, 0, 1, &input, result);
790 
791 	return status;
792 }
793 
794 static acpi_status AMW0_get_u32(u32 *value, u32 cap)
795 {
796 	int err;
797 	u8 result;
798 
799 	switch (cap) {
800 	case ACER_CAP_MAILLED:
801 		switch (quirks->mailled) {
802 		default:
803 			err = ec_read(0xA, &result);
804 			if (err)
805 				return AE_ERROR;
806 			*value = (result >> 7) & 0x1;
807 			return AE_OK;
808 		}
809 		break;
810 	case ACER_CAP_WIRELESS:
811 		switch (quirks->wireless) {
812 		case 1:
813 			err = ec_read(0x7B, &result);
814 			if (err)
815 				return AE_ERROR;
816 			*value = result & 0x1;
817 			return AE_OK;
818 		case 2:
819 			err = ec_read(0x71, &result);
820 			if (err)
821 				return AE_ERROR;
822 			*value = result & 0x1;
823 			return AE_OK;
824 		case 3:
825 			err = ec_read(0x78, &result);
826 			if (err)
827 				return AE_ERROR;
828 			*value = result & 0x1;
829 			return AE_OK;
830 		default:
831 			err = ec_read(0xA, &result);
832 			if (err)
833 				return AE_ERROR;
834 			*value = (result >> 2) & 0x1;
835 			return AE_OK;
836 		}
837 		break;
838 	case ACER_CAP_BLUETOOTH:
839 		switch (quirks->bluetooth) {
840 		default:
841 			err = ec_read(0xA, &result);
842 			if (err)
843 				return AE_ERROR;
844 			*value = (result >> 4) & 0x1;
845 			return AE_OK;
846 		}
847 		break;
848 	case ACER_CAP_BRIGHTNESS:
849 		switch (quirks->brightness) {
850 		default:
851 			err = ec_read(0x83, &result);
852 			if (err)
853 				return AE_ERROR;
854 			*value = result;
855 			return AE_OK;
856 		}
857 		break;
858 	default:
859 		return AE_ERROR;
860 	}
861 	return AE_OK;
862 }
863 
864 static acpi_status AMW0_set_u32(u32 value, u32 cap)
865 {
866 	struct wmab_args args;
867 
868 	args.eax = ACER_AMW0_WRITE;
869 	args.ebx = value ? (1<<8) : 0;
870 	args.ecx = args.edx = 0;
871 
872 	switch (cap) {
873 	case ACER_CAP_MAILLED:
874 		if (value > 1)
875 			return AE_BAD_PARAMETER;
876 		args.ebx |= ACER_AMW0_MAILLED_MASK;
877 		break;
878 	case ACER_CAP_WIRELESS:
879 		if (value > 1)
880 			return AE_BAD_PARAMETER;
881 		args.ebx |= ACER_AMW0_WIRELESS_MASK;
882 		break;
883 	case ACER_CAP_BLUETOOTH:
884 		if (value > 1)
885 			return AE_BAD_PARAMETER;
886 		args.ebx |= ACER_AMW0_BLUETOOTH_MASK;
887 		break;
888 	case ACER_CAP_BRIGHTNESS:
889 		if (value > max_brightness)
890 			return AE_BAD_PARAMETER;
891 		switch (quirks->brightness) {
892 		default:
893 			return ec_write(0x83, value);
894 		}
895 	default:
896 		return AE_ERROR;
897 	}
898 
899 	/* Actually do the set */
900 	return wmab_execute(&args, NULL);
901 }
902 
903 static acpi_status __init AMW0_find_mailled(void)
904 {
905 	struct wmab_args args;
906 	struct wmab_ret ret;
907 	acpi_status status = AE_OK;
908 	struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
909 	union acpi_object *obj;
910 
911 	args.eax = 0x86;
912 	args.ebx = args.ecx = args.edx = 0;
913 
914 	status = wmab_execute(&args, &out);
915 	if (ACPI_FAILURE(status))
916 		return status;
917 
918 	obj = (union acpi_object *) out.pointer;
919 	if (obj && obj->type == ACPI_TYPE_BUFFER &&
920 	obj->buffer.length == sizeof(struct wmab_ret)) {
921 		ret = *((struct wmab_ret *) obj->buffer.pointer);
922 	} else {
923 		kfree(out.pointer);
924 		return AE_ERROR;
925 	}
926 
927 	if (ret.eex & 0x1)
928 		interface->capability |= ACER_CAP_MAILLED;
929 
930 	kfree(out.pointer);
931 
932 	return AE_OK;
933 }
934 
935 static const struct acpi_device_id norfkill_ids[] __initconst = {
936 	{ "VPC2004", 0},
937 	{ "IBM0068", 0},
938 	{ "LEN0068", 0},
939 	{ "SNY5001", 0},	/* sony-laptop in charge */
940 	{ "HPQ6601", 0},
941 	{ "", 0},
942 };
943 
944 static int __init AMW0_set_cap_acpi_check_device(void)
945 {
946 	const struct acpi_device_id *id;
947 
948 	for (id = norfkill_ids; id->id[0]; id++)
949 		if (acpi_dev_found(id->id))
950 			return true;
951 
952 	return false;
953 }
954 
955 static acpi_status __init AMW0_set_capabilities(void)
956 {
957 	struct wmab_args args;
958 	struct wmab_ret ret;
959 	acpi_status status;
960 	struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
961 	union acpi_object *obj;
962 
963 	/*
964 	 * On laptops with this strange GUID (non Acer), normal probing doesn't
965 	 * work.
966 	 */
967 	if (wmi_has_guid(AMW0_GUID2)) {
968 		if ((quirks != &quirk_unknown) ||
969 		    !AMW0_set_cap_acpi_check_device())
970 			interface->capability |= ACER_CAP_WIRELESS;
971 		return AE_OK;
972 	}
973 
974 	args.eax = ACER_AMW0_WRITE;
975 	args.ecx = args.edx = 0;
976 
977 	args.ebx = 0xa2 << 8;
978 	args.ebx |= ACER_AMW0_WIRELESS_MASK;
979 
980 	status = wmab_execute(&args, &out);
981 	if (ACPI_FAILURE(status))
982 		return status;
983 
984 	obj = out.pointer;
985 	if (obj && obj->type == ACPI_TYPE_BUFFER &&
986 	obj->buffer.length == sizeof(struct wmab_ret)) {
987 		ret = *((struct wmab_ret *) obj->buffer.pointer);
988 	} else {
989 		status = AE_ERROR;
990 		goto out;
991 	}
992 
993 	if (ret.eax & 0x1)
994 		interface->capability |= ACER_CAP_WIRELESS;
995 
996 	args.ebx = 2 << 8;
997 	args.ebx |= ACER_AMW0_BLUETOOTH_MASK;
998 
999 	/*
1000 	 * It's ok to use existing buffer for next wmab_execute call.
1001 	 * But we need to kfree(out.pointer) if next wmab_execute fail.
1002 	 */
1003 	status = wmab_execute(&args, &out);
1004 	if (ACPI_FAILURE(status))
1005 		goto out;
1006 
1007 	obj = (union acpi_object *) out.pointer;
1008 	if (obj && obj->type == ACPI_TYPE_BUFFER
1009 	&& obj->buffer.length == sizeof(struct wmab_ret)) {
1010 		ret = *((struct wmab_ret *) obj->buffer.pointer);
1011 	} else {
1012 		status = AE_ERROR;
1013 		goto out;
1014 	}
1015 
1016 	if (ret.eax & 0x1)
1017 		interface->capability |= ACER_CAP_BLUETOOTH;
1018 
1019 	/*
1020 	 * This appears to be safe to enable, since all Wistron based laptops
1021 	 * appear to use the same EC register for brightness, even if they
1022 	 * differ for wireless, etc
1023 	 */
1024 	if (quirks->brightness >= 0)
1025 		interface->capability |= ACER_CAP_BRIGHTNESS;
1026 
1027 	status = AE_OK;
1028 out:
1029 	kfree(out.pointer);
1030 	return status;
1031 }
1032 
1033 static struct wmi_interface AMW0_interface = {
1034 	.type = ACER_AMW0,
1035 };
1036 
1037 static struct wmi_interface AMW0_V2_interface = {
1038 	.type = ACER_AMW0_V2,
1039 };
1040 
1041 /*
1042  * New interface (The WMID interface)
1043  */
1044 static acpi_status
1045 WMI_execute_u32(u32 method_id, u32 in, u32 *out)
1046 {
1047 	struct acpi_buffer input = { (acpi_size) sizeof(u32), (void *)(&in) };
1048 	struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL };
1049 	union acpi_object *obj;
1050 	u32 tmp = 0;
1051 	acpi_status status;
1052 
1053 	status = wmi_evaluate_method(WMID_GUID1, 0, method_id, &input, &result);
1054 
1055 	if (ACPI_FAILURE(status))
1056 		return status;
1057 
1058 	obj = (union acpi_object *) result.pointer;
1059 	if (obj) {
1060 		if (obj->type == ACPI_TYPE_BUFFER &&
1061 			(obj->buffer.length == sizeof(u32) ||
1062 			obj->buffer.length == sizeof(u64))) {
1063 			tmp = *((u32 *) obj->buffer.pointer);
1064 		} else if (obj->type == ACPI_TYPE_INTEGER) {
1065 			tmp = (u32) obj->integer.value;
1066 		}
1067 	}
1068 
1069 	if (out)
1070 		*out = tmp;
1071 
1072 	kfree(result.pointer);
1073 
1074 	return status;
1075 }
1076 
1077 static acpi_status WMID_get_u32(u32 *value, u32 cap)
1078 {
1079 	acpi_status status;
1080 	u8 tmp;
1081 	u32 result, method_id = 0;
1082 
1083 	switch (cap) {
1084 	case ACER_CAP_WIRELESS:
1085 		method_id = ACER_WMID_GET_WIRELESS_METHODID;
1086 		break;
1087 	case ACER_CAP_BLUETOOTH:
1088 		method_id = ACER_WMID_GET_BLUETOOTH_METHODID;
1089 		break;
1090 	case ACER_CAP_BRIGHTNESS:
1091 		method_id = ACER_WMID_GET_BRIGHTNESS_METHODID;
1092 		break;
1093 	case ACER_CAP_THREEG:
1094 		method_id = ACER_WMID_GET_THREEG_METHODID;
1095 		break;
1096 	case ACER_CAP_MAILLED:
1097 		if (quirks->mailled == 1) {
1098 			ec_read(0x9f, &tmp);
1099 			*value = tmp & 0x1;
1100 			return 0;
1101 		}
1102 		fallthrough;
1103 	default:
1104 		return AE_ERROR;
1105 	}
1106 	status = WMI_execute_u32(method_id, 0, &result);
1107 
1108 	if (ACPI_SUCCESS(status))
1109 		*value = (u8)result;
1110 
1111 	return status;
1112 }
1113 
1114 static acpi_status WMID_set_u32(u32 value, u32 cap)
1115 {
1116 	u32 method_id = 0;
1117 	char param;
1118 
1119 	switch (cap) {
1120 	case ACER_CAP_BRIGHTNESS:
1121 		if (value > max_brightness)
1122 			return AE_BAD_PARAMETER;
1123 		method_id = ACER_WMID_SET_BRIGHTNESS_METHODID;
1124 		break;
1125 	case ACER_CAP_WIRELESS:
1126 		if (value > 1)
1127 			return AE_BAD_PARAMETER;
1128 		method_id = ACER_WMID_SET_WIRELESS_METHODID;
1129 		break;
1130 	case ACER_CAP_BLUETOOTH:
1131 		if (value > 1)
1132 			return AE_BAD_PARAMETER;
1133 		method_id = ACER_WMID_SET_BLUETOOTH_METHODID;
1134 		break;
1135 	case ACER_CAP_THREEG:
1136 		if (value > 1)
1137 			return AE_BAD_PARAMETER;
1138 		method_id = ACER_WMID_SET_THREEG_METHODID;
1139 		break;
1140 	case ACER_CAP_MAILLED:
1141 		if (value > 1)
1142 			return AE_BAD_PARAMETER;
1143 		if (quirks->mailled == 1) {
1144 			param = value ? 0x92 : 0x93;
1145 			i8042_lock_chip();
1146 			i8042_command(&param, 0x1059);
1147 			i8042_unlock_chip();
1148 			return 0;
1149 		}
1150 		break;
1151 	default:
1152 		return AE_ERROR;
1153 	}
1154 	return WMI_execute_u32(method_id, (u32)value, NULL);
1155 }
1156 
1157 static acpi_status wmid3_get_device_status(u32 *value, u16 device)
1158 {
1159 	struct wmid3_gds_return_value return_value;
1160 	acpi_status status;
1161 	union acpi_object *obj;
1162 	struct wmid3_gds_get_input_param params = {
1163 		.function_num = 0x1,
1164 		.hotkey_number = commun_fn_key_number,
1165 		.devices = device,
1166 	};
1167 	struct acpi_buffer input = {
1168 		sizeof(struct wmid3_gds_get_input_param),
1169 		&params
1170 	};
1171 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
1172 
1173 	status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output);
1174 	if (ACPI_FAILURE(status))
1175 		return status;
1176 
1177 	obj = output.pointer;
1178 
1179 	if (!obj)
1180 		return AE_ERROR;
1181 	else if (obj->type != ACPI_TYPE_BUFFER) {
1182 		kfree(obj);
1183 		return AE_ERROR;
1184 	}
1185 	if (obj->buffer.length != 8) {
1186 		pr_warn("Unknown buffer length %d\n", obj->buffer.length);
1187 		kfree(obj);
1188 		return AE_ERROR;
1189 	}
1190 
1191 	return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
1192 	kfree(obj);
1193 
1194 	if (return_value.error_code || return_value.ec_return_value)
1195 		pr_warn("Get 0x%x Device Status failed: 0x%x - 0x%x\n",
1196 			device,
1197 			return_value.error_code,
1198 			return_value.ec_return_value);
1199 	else
1200 		*value = !!(return_value.devices & device);
1201 
1202 	return status;
1203 }
1204 
1205 static acpi_status wmid_v2_get_u32(u32 *value, u32 cap)
1206 {
1207 	u16 device;
1208 
1209 	switch (cap) {
1210 	case ACER_CAP_WIRELESS:
1211 		device = ACER_WMID3_GDS_WIRELESS;
1212 		break;
1213 	case ACER_CAP_BLUETOOTH:
1214 		device = ACER_WMID3_GDS_BLUETOOTH;
1215 		break;
1216 	case ACER_CAP_THREEG:
1217 		device = ACER_WMID3_GDS_THREEG;
1218 		break;
1219 	default:
1220 		return AE_ERROR;
1221 	}
1222 	return wmid3_get_device_status(value, device);
1223 }
1224 
1225 static acpi_status wmid3_set_device_status(u32 value, u16 device)
1226 {
1227 	struct wmid3_gds_return_value return_value;
1228 	acpi_status status;
1229 	union acpi_object *obj;
1230 	u16 devices;
1231 	struct wmid3_gds_get_input_param get_params = {
1232 		.function_num = 0x1,
1233 		.hotkey_number = commun_fn_key_number,
1234 		.devices = commun_func_bitmap,
1235 	};
1236 	struct acpi_buffer get_input = {
1237 		sizeof(struct wmid3_gds_get_input_param),
1238 		&get_params
1239 	};
1240 	struct wmid3_gds_set_input_param set_params = {
1241 		.function_num = 0x2,
1242 		.hotkey_number = commun_fn_key_number,
1243 		.devices = commun_func_bitmap,
1244 	};
1245 	struct acpi_buffer set_input = {
1246 		sizeof(struct wmid3_gds_set_input_param),
1247 		&set_params
1248 	};
1249 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
1250 	struct acpi_buffer output2 = { ACPI_ALLOCATE_BUFFER, NULL };
1251 
1252 	status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &get_input, &output);
1253 	if (ACPI_FAILURE(status))
1254 		return status;
1255 
1256 	obj = output.pointer;
1257 
1258 	if (!obj)
1259 		return AE_ERROR;
1260 	else if (obj->type != ACPI_TYPE_BUFFER) {
1261 		kfree(obj);
1262 		return AE_ERROR;
1263 	}
1264 	if (obj->buffer.length != 8) {
1265 		pr_warn("Unknown buffer length %d\n", obj->buffer.length);
1266 		kfree(obj);
1267 		return AE_ERROR;
1268 	}
1269 
1270 	return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
1271 	kfree(obj);
1272 
1273 	if (return_value.error_code || return_value.ec_return_value) {
1274 		pr_warn("Get Current Device Status failed: 0x%x - 0x%x\n",
1275 			return_value.error_code,
1276 			return_value.ec_return_value);
1277 		return status;
1278 	}
1279 
1280 	devices = return_value.devices;
1281 	set_params.devices = (value) ? (devices | device) : (devices & ~device);
1282 
1283 	status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &set_input, &output2);
1284 	if (ACPI_FAILURE(status))
1285 		return status;
1286 
1287 	obj = output2.pointer;
1288 
1289 	if (!obj)
1290 		return AE_ERROR;
1291 	else if (obj->type != ACPI_TYPE_BUFFER) {
1292 		kfree(obj);
1293 		return AE_ERROR;
1294 	}
1295 	if (obj->buffer.length != 4) {
1296 		pr_warn("Unknown buffer length %d\n", obj->buffer.length);
1297 		kfree(obj);
1298 		return AE_ERROR;
1299 	}
1300 
1301 	return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
1302 	kfree(obj);
1303 
1304 	if (return_value.error_code || return_value.ec_return_value)
1305 		pr_warn("Set Device Status failed: 0x%x - 0x%x\n",
1306 			return_value.error_code,
1307 			return_value.ec_return_value);
1308 
1309 	return status;
1310 }
1311 
1312 static acpi_status wmid_v2_set_u32(u32 value, u32 cap)
1313 {
1314 	u16 device;
1315 
1316 	switch (cap) {
1317 	case ACER_CAP_WIRELESS:
1318 		device = ACER_WMID3_GDS_WIRELESS;
1319 		break;
1320 	case ACER_CAP_BLUETOOTH:
1321 		device = ACER_WMID3_GDS_BLUETOOTH;
1322 		break;
1323 	case ACER_CAP_THREEG:
1324 		device = ACER_WMID3_GDS_THREEG;
1325 		break;
1326 	default:
1327 		return AE_ERROR;
1328 	}
1329 	return wmid3_set_device_status(value, device);
1330 }
1331 
1332 static void __init type_aa_dmi_decode(const struct dmi_header *header, void *d)
1333 {
1334 	struct hotkey_function_type_aa *type_aa;
1335 
1336 	/* We are looking for OEM-specific Type AAh */
1337 	if (header->type != 0xAA)
1338 		return;
1339 
1340 	has_type_aa = true;
1341 	type_aa = (struct hotkey_function_type_aa *) header;
1342 
1343 	pr_info("Function bitmap for Communication Button: 0x%x\n",
1344 		type_aa->commun_func_bitmap);
1345 	commun_func_bitmap = type_aa->commun_func_bitmap;
1346 
1347 	if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_WIRELESS)
1348 		interface->capability |= ACER_CAP_WIRELESS;
1349 	if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_THREEG)
1350 		interface->capability |= ACER_CAP_THREEG;
1351 	if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_BLUETOOTH)
1352 		interface->capability |= ACER_CAP_BLUETOOTH;
1353 	if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN)
1354 		commun_func_bitmap &= ~ACER_WMID3_GDS_RFBTN;
1355 
1356 	commun_fn_key_number = type_aa->commun_fn_key_number;
1357 }
1358 
1359 static acpi_status __init WMID_set_capabilities(void)
1360 {
1361 	struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
1362 	union acpi_object *obj;
1363 	acpi_status status;
1364 	u32 devices;
1365 
1366 	status = wmi_query_block(WMID_GUID2, 0, &out);
1367 	if (ACPI_FAILURE(status))
1368 		return status;
1369 
1370 	obj = (union acpi_object *) out.pointer;
1371 	if (obj) {
1372 		if (obj->type == ACPI_TYPE_BUFFER &&
1373 			(obj->buffer.length == sizeof(u32) ||
1374 			obj->buffer.length == sizeof(u64))) {
1375 			devices = *((u32 *) obj->buffer.pointer);
1376 		} else if (obj->type == ACPI_TYPE_INTEGER) {
1377 			devices = (u32) obj->integer.value;
1378 		} else {
1379 			kfree(out.pointer);
1380 			return AE_ERROR;
1381 		}
1382 	} else {
1383 		kfree(out.pointer);
1384 		return AE_ERROR;
1385 	}
1386 
1387 	pr_info("Function bitmap for Communication Device: 0x%x\n", devices);
1388 	if (devices & 0x07)
1389 		interface->capability |= ACER_CAP_WIRELESS;
1390 	if (devices & 0x40)
1391 		interface->capability |= ACER_CAP_THREEG;
1392 	if (devices & 0x10)
1393 		interface->capability |= ACER_CAP_BLUETOOTH;
1394 
1395 	if (!(devices & 0x20))
1396 		max_brightness = 0x9;
1397 
1398 	kfree(out.pointer);
1399 	return status;
1400 }
1401 
1402 static struct wmi_interface wmid_interface = {
1403 	.type = ACER_WMID,
1404 };
1405 
1406 static struct wmi_interface wmid_v2_interface = {
1407 	.type = ACER_WMID_v2,
1408 };
1409 
1410 /*
1411  * WMID Gaming interface
1412  */
1413 
1414 static acpi_status
1415 WMI_gaming_execute_u64(u32 method_id, u64 in, u64 *out)
1416 {
1417 	struct acpi_buffer input = { (acpi_size) sizeof(u64), (void *)(&in) };
1418 	struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL };
1419 	union acpi_object *obj;
1420 	u64 tmp = 0;
1421 	acpi_status status;
1422 
1423 	status = wmi_evaluate_method(WMID_GUID4, 0, method_id, &input, &result);
1424 
1425 	if (ACPI_FAILURE(status))
1426 		return status;
1427 	obj = (union acpi_object *) result.pointer;
1428 
1429 	if (obj) {
1430 		if (obj->type == ACPI_TYPE_BUFFER) {
1431 			if (obj->buffer.length == sizeof(u32))
1432 				tmp = *((u32 *) obj->buffer.pointer);
1433 			else if (obj->buffer.length == sizeof(u64))
1434 				tmp = *((u64 *) obj->buffer.pointer);
1435 		} else if (obj->type == ACPI_TYPE_INTEGER) {
1436 			tmp = (u64) obj->integer.value;
1437 		}
1438 	}
1439 
1440 	if (out)
1441 		*out = tmp;
1442 
1443 	kfree(result.pointer);
1444 
1445 	return status;
1446 }
1447 
1448 static acpi_status WMID_gaming_set_u64(u64 value, u32 cap)
1449 {
1450 	u32 method_id = 0;
1451 
1452 	if (!(interface->capability & cap))
1453 		return AE_BAD_PARAMETER;
1454 
1455 	switch (cap) {
1456 	case ACER_CAP_TURBO_LED:
1457 		method_id = ACER_WMID_SET_GAMING_LED_METHODID;
1458 		break;
1459 	case ACER_CAP_TURBO_FAN:
1460 		method_id = ACER_WMID_SET_GAMING_FAN_BEHAVIOR;
1461 		break;
1462 	case ACER_CAP_TURBO_OC:
1463 		method_id = ACER_WMID_SET_GAMING_MISC_SETTING_METHODID;
1464 		break;
1465 	default:
1466 		return AE_BAD_PARAMETER;
1467 	}
1468 
1469 	return WMI_gaming_execute_u64(method_id, value, NULL);
1470 }
1471 
1472 static acpi_status WMID_gaming_get_u64(u64 *value, u32 cap)
1473 {
1474 	acpi_status status;
1475 	u64 result;
1476 	u64 input;
1477 	u32 method_id;
1478 
1479 	if (!(interface->capability & cap))
1480 		return AE_BAD_PARAMETER;
1481 
1482 	switch (cap) {
1483 	case ACER_CAP_TURBO_LED:
1484 		method_id = ACER_WMID_GET_GAMING_LED_METHODID;
1485 		input = 0x1;
1486 		break;
1487 	default:
1488 		return AE_BAD_PARAMETER;
1489 	}
1490 	status = WMI_gaming_execute_u64(method_id, input, &result);
1491 	if (ACPI_SUCCESS(status))
1492 		*value = (u64) result;
1493 
1494 	return status;
1495 }
1496 
1497 static void WMID_gaming_set_fan_mode(u8 fan_mode)
1498 {
1499 	/* fan_mode = 1 is used for auto, fan_mode = 2 used for turbo*/
1500 	u64 gpu_fan_config1 = 0, gpu_fan_config2 = 0;
1501 	int i;
1502 
1503 	if (quirks->cpu_fans > 0)
1504 		gpu_fan_config2 |= 1;
1505 	for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
1506 		gpu_fan_config2 |= 1 << (i + 1);
1507 	for (i = 0; i < quirks->gpu_fans; ++i)
1508 		gpu_fan_config2 |= 1 << (i + 3);
1509 	if (quirks->cpu_fans > 0)
1510 		gpu_fan_config1 |= fan_mode;
1511 	for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
1512 		gpu_fan_config1 |= fan_mode << (2 * i + 2);
1513 	for (i = 0; i < quirks->gpu_fans; ++i)
1514 		gpu_fan_config1 |= fan_mode << (2 * i + 6);
1515 	WMID_gaming_set_u64(gpu_fan_config2 | gpu_fan_config1 << 16, ACER_CAP_TURBO_FAN);
1516 }
1517 
1518 /*
1519  * Generic Device (interface-independent)
1520  */
1521 
1522 static acpi_status get_u32(u32 *value, u32 cap)
1523 {
1524 	acpi_status status = AE_ERROR;
1525 
1526 	switch (interface->type) {
1527 	case ACER_AMW0:
1528 		status = AMW0_get_u32(value, cap);
1529 		break;
1530 	case ACER_AMW0_V2:
1531 		if (cap == ACER_CAP_MAILLED) {
1532 			status = AMW0_get_u32(value, cap);
1533 			break;
1534 		}
1535 		fallthrough;
1536 	case ACER_WMID:
1537 		status = WMID_get_u32(value, cap);
1538 		break;
1539 	case ACER_WMID_v2:
1540 		if (cap & (ACER_CAP_WIRELESS |
1541 			   ACER_CAP_BLUETOOTH |
1542 			   ACER_CAP_THREEG))
1543 			status = wmid_v2_get_u32(value, cap);
1544 		else if (wmi_has_guid(WMID_GUID2))
1545 			status = WMID_get_u32(value, cap);
1546 		break;
1547 	}
1548 
1549 	return status;
1550 }
1551 
1552 static acpi_status set_u32(u32 value, u32 cap)
1553 {
1554 	acpi_status status;
1555 
1556 	if (interface->capability & cap) {
1557 		switch (interface->type) {
1558 		case ACER_AMW0:
1559 			return AMW0_set_u32(value, cap);
1560 		case ACER_AMW0_V2:
1561 			if (cap == ACER_CAP_MAILLED)
1562 				return AMW0_set_u32(value, cap);
1563 
1564 			/*
1565 			 * On some models, some WMID methods don't toggle
1566 			 * properly. For those cases, we want to run the AMW0
1567 			 * method afterwards to be certain we've really toggled
1568 			 * the device state.
1569 			 */
1570 			if (cap == ACER_CAP_WIRELESS ||
1571 				cap == ACER_CAP_BLUETOOTH) {
1572 				status = WMID_set_u32(value, cap);
1573 				if (ACPI_FAILURE(status))
1574 					return status;
1575 
1576 				return AMW0_set_u32(value, cap);
1577 			}
1578 			fallthrough;
1579 		case ACER_WMID:
1580 			return WMID_set_u32(value, cap);
1581 		case ACER_WMID_v2:
1582 			if (cap & (ACER_CAP_WIRELESS |
1583 				   ACER_CAP_BLUETOOTH |
1584 				   ACER_CAP_THREEG))
1585 				return wmid_v2_set_u32(value, cap);
1586 			else if (wmi_has_guid(WMID_GUID2))
1587 				return WMID_set_u32(value, cap);
1588 			fallthrough;
1589 		default:
1590 			return AE_BAD_PARAMETER;
1591 		}
1592 	}
1593 	return AE_BAD_PARAMETER;
1594 }
1595 
1596 static void __init acer_commandline_init(void)
1597 {
1598 	/*
1599 	 * These will all fail silently if the value given is invalid, or the
1600 	 * capability isn't available on the given interface
1601 	 */
1602 	if (mailled >= 0)
1603 		set_u32(mailled, ACER_CAP_MAILLED);
1604 	if (!has_type_aa && threeg >= 0)
1605 		set_u32(threeg, ACER_CAP_THREEG);
1606 	if (brightness >= 0)
1607 		set_u32(brightness, ACER_CAP_BRIGHTNESS);
1608 }
1609 
1610 /*
1611  * LED device (Mail LED only, no other LEDs known yet)
1612  */
1613 static void mail_led_set(struct led_classdev *led_cdev,
1614 enum led_brightness value)
1615 {
1616 	set_u32(value, ACER_CAP_MAILLED);
1617 }
1618 
1619 static struct led_classdev mail_led = {
1620 	.name = "acer-wmi::mail",
1621 	.brightness_set = mail_led_set,
1622 };
1623 
1624 static int acer_led_init(struct device *dev)
1625 {
1626 	return led_classdev_register(dev, &mail_led);
1627 }
1628 
1629 static void acer_led_exit(void)
1630 {
1631 	set_u32(LED_OFF, ACER_CAP_MAILLED);
1632 	led_classdev_unregister(&mail_led);
1633 }
1634 
1635 /*
1636  * Backlight device
1637  */
1638 static struct backlight_device *acer_backlight_device;
1639 
1640 static int read_brightness(struct backlight_device *bd)
1641 {
1642 	u32 value;
1643 	get_u32(&value, ACER_CAP_BRIGHTNESS);
1644 	return value;
1645 }
1646 
1647 static int update_bl_status(struct backlight_device *bd)
1648 {
1649 	int intensity = backlight_get_brightness(bd);
1650 
1651 	set_u32(intensity, ACER_CAP_BRIGHTNESS);
1652 
1653 	return 0;
1654 }
1655 
1656 static const struct backlight_ops acer_bl_ops = {
1657 	.get_brightness = read_brightness,
1658 	.update_status = update_bl_status,
1659 };
1660 
1661 static int acer_backlight_init(struct device *dev)
1662 {
1663 	struct backlight_properties props;
1664 	struct backlight_device *bd;
1665 
1666 	memset(&props, 0, sizeof(struct backlight_properties));
1667 	props.type = BACKLIGHT_PLATFORM;
1668 	props.max_brightness = max_brightness;
1669 	bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops,
1670 				       &props);
1671 	if (IS_ERR(bd)) {
1672 		pr_err("Could not register Acer backlight device\n");
1673 		acer_backlight_device = NULL;
1674 		return PTR_ERR(bd);
1675 	}
1676 
1677 	acer_backlight_device = bd;
1678 
1679 	bd->props.power = FB_BLANK_UNBLANK;
1680 	bd->props.brightness = read_brightness(bd);
1681 	backlight_update_status(bd);
1682 	return 0;
1683 }
1684 
1685 static void acer_backlight_exit(void)
1686 {
1687 	backlight_device_unregister(acer_backlight_device);
1688 }
1689 
1690 /*
1691  * Accelerometer device
1692  */
1693 static acpi_handle gsensor_handle;
1694 
1695 static int acer_gsensor_init(void)
1696 {
1697 	acpi_status status;
1698 	struct acpi_buffer output;
1699 	union acpi_object out_obj;
1700 
1701 	output.length = sizeof(out_obj);
1702 	output.pointer = &out_obj;
1703 	status = acpi_evaluate_object(gsensor_handle, "_INI", NULL, &output);
1704 	if (ACPI_FAILURE(status))
1705 		return -1;
1706 
1707 	return 0;
1708 }
1709 
1710 static int acer_gsensor_open(struct input_dev *input)
1711 {
1712 	return acer_gsensor_init();
1713 }
1714 
1715 static int acer_gsensor_event(void)
1716 {
1717 	acpi_status status;
1718 	struct acpi_buffer output;
1719 	union acpi_object out_obj[5];
1720 
1721 	if (!acer_wmi_accel_dev)
1722 		return -1;
1723 
1724 	output.length = sizeof(out_obj);
1725 	output.pointer = out_obj;
1726 
1727 	status = acpi_evaluate_object(gsensor_handle, "RDVL", NULL, &output);
1728 	if (ACPI_FAILURE(status))
1729 		return -1;
1730 
1731 	if (out_obj->package.count != 4)
1732 		return -1;
1733 
1734 	input_report_abs(acer_wmi_accel_dev, ABS_X,
1735 		(s16)out_obj->package.elements[0].integer.value);
1736 	input_report_abs(acer_wmi_accel_dev, ABS_Y,
1737 		(s16)out_obj->package.elements[1].integer.value);
1738 	input_report_abs(acer_wmi_accel_dev, ABS_Z,
1739 		(s16)out_obj->package.elements[2].integer.value);
1740 	input_sync(acer_wmi_accel_dev);
1741 	return 0;
1742 }
1743 
1744 static int acer_get_fan_speed(int fan)
1745 {
1746 	if (quirks->predator_v4) {
1747 		acpi_status status;
1748 		u64 fanspeed;
1749 
1750 		status = WMI_gaming_execute_u64(
1751 			ACER_WMID_GET_GAMING_SYS_INFO_METHODID,
1752 			fan == 0 ? ACER_WMID_CMD_GET_PREDATOR_V4_CPU_FAN_SPEED :
1753 				   ACER_WMID_CMD_GET_PREDATOR_V4_GPU_FAN_SPEED,
1754 			&fanspeed);
1755 
1756 		if (ACPI_FAILURE(status))
1757 			return -EIO;
1758 
1759 		return FIELD_GET(ACER_PREDATOR_V4_FAN_SPEED_READ_BIT_MASK, fanspeed);
1760 	}
1761 	return -EOPNOTSUPP;
1762 }
1763 
1764 /*
1765  *  Predator series turbo button
1766  */
1767 static int acer_toggle_turbo(void)
1768 {
1769 	u64 turbo_led_state;
1770 
1771 	/* Get current state from turbo button */
1772 	if (ACPI_FAILURE(WMID_gaming_get_u64(&turbo_led_state, ACER_CAP_TURBO_LED)))
1773 		return -1;
1774 
1775 	if (turbo_led_state) {
1776 		/* Turn off turbo led */
1777 		WMID_gaming_set_u64(0x1, ACER_CAP_TURBO_LED);
1778 
1779 		/* Set FAN mode to auto */
1780 		WMID_gaming_set_fan_mode(0x1);
1781 
1782 		/* Set OC to normal */
1783 		WMID_gaming_set_u64(0x5, ACER_CAP_TURBO_OC);
1784 		WMID_gaming_set_u64(0x7, ACER_CAP_TURBO_OC);
1785 	} else {
1786 		/* Turn on turbo led */
1787 		WMID_gaming_set_u64(0x10001, ACER_CAP_TURBO_LED);
1788 
1789 		/* Set FAN mode to turbo */
1790 		WMID_gaming_set_fan_mode(0x2);
1791 
1792 		/* Set OC to turbo mode */
1793 		WMID_gaming_set_u64(0x205, ACER_CAP_TURBO_OC);
1794 		WMID_gaming_set_u64(0x207, ACER_CAP_TURBO_OC);
1795 	}
1796 	return turbo_led_state;
1797 }
1798 
1799 static int
1800 acer_predator_v4_platform_profile_get(struct platform_profile_handler *pprof,
1801 				      enum platform_profile_option *profile)
1802 {
1803 	u8 tp;
1804 	int err;
1805 
1806 	err = ec_read(ACER_PREDATOR_V4_THERMAL_PROFILE_EC_OFFSET, &tp);
1807 
1808 	if (err < 0)
1809 		return err;
1810 
1811 	switch (tp) {
1812 	case ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO:
1813 		*profile = PLATFORM_PROFILE_PERFORMANCE;
1814 		break;
1815 	case ACER_PREDATOR_V4_THERMAL_PROFILE_PERFORMANCE:
1816 		*profile = PLATFORM_PROFILE_BALANCED_PERFORMANCE;
1817 		break;
1818 	case ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED:
1819 		*profile = PLATFORM_PROFILE_BALANCED;
1820 		break;
1821 	case ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET:
1822 		*profile = PLATFORM_PROFILE_QUIET;
1823 		break;
1824 	case ACER_PREDATOR_V4_THERMAL_PROFILE_ECO:
1825 		*profile = PLATFORM_PROFILE_LOW_POWER;
1826 		break;
1827 	default:
1828 		return -EOPNOTSUPP;
1829 	}
1830 
1831 	return 0;
1832 }
1833 
1834 static int
1835 acer_predator_v4_platform_profile_set(struct platform_profile_handler *pprof,
1836 				      enum platform_profile_option profile)
1837 {
1838 	int tp;
1839 	acpi_status status;
1840 
1841 	switch (profile) {
1842 	case PLATFORM_PROFILE_PERFORMANCE:
1843 		tp = ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO_WMI;
1844 		break;
1845 	case PLATFORM_PROFILE_BALANCED_PERFORMANCE:
1846 		tp = ACER_PREDATOR_V4_THERMAL_PROFILE_PERFORMANCE_WMI;
1847 		break;
1848 	case PLATFORM_PROFILE_BALANCED:
1849 		tp = ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED_WMI;
1850 		break;
1851 	case PLATFORM_PROFILE_QUIET:
1852 		tp = ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET_WMI;
1853 		break;
1854 	case PLATFORM_PROFILE_LOW_POWER:
1855 		tp = ACER_PREDATOR_V4_THERMAL_PROFILE_ECO_WMI;
1856 		break;
1857 	default:
1858 		return -EOPNOTSUPP;
1859 	}
1860 
1861 	status = WMI_gaming_execute_u64(
1862 		ACER_WMID_SET_GAMING_MISC_SETTING_METHODID, tp, NULL);
1863 
1864 	if (ACPI_FAILURE(status))
1865 		return -EIO;
1866 
1867 	if (tp != ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO_WMI)
1868 		last_non_turbo_profile = tp;
1869 
1870 	return 0;
1871 }
1872 
1873 static int acer_platform_profile_setup(void)
1874 {
1875 	if (quirks->predator_v4) {
1876 		int err;
1877 
1878 		platform_profile_handler.profile_get =
1879 			acer_predator_v4_platform_profile_get;
1880 		platform_profile_handler.profile_set =
1881 			acer_predator_v4_platform_profile_set;
1882 
1883 		set_bit(PLATFORM_PROFILE_PERFORMANCE,
1884 			platform_profile_handler.choices);
1885 		set_bit(PLATFORM_PROFILE_BALANCED_PERFORMANCE,
1886 			platform_profile_handler.choices);
1887 		set_bit(PLATFORM_PROFILE_BALANCED,
1888 			platform_profile_handler.choices);
1889 		set_bit(PLATFORM_PROFILE_QUIET,
1890 			platform_profile_handler.choices);
1891 		set_bit(PLATFORM_PROFILE_LOW_POWER,
1892 			platform_profile_handler.choices);
1893 
1894 		err = platform_profile_register(&platform_profile_handler);
1895 		if (err)
1896 			return err;
1897 
1898 		platform_profile_support = true;
1899 
1900 		/* Set default non-turbo profile  */
1901 		last_non_turbo_profile =
1902 			ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED_WMI;
1903 	}
1904 	return 0;
1905 }
1906 
1907 static int acer_thermal_profile_change(void)
1908 {
1909 	/*
1910 	 * This mode key can rotate each mode or toggle turbo mode.
1911 	 * On battery, only ECO and BALANCED mode are available.
1912 	 */
1913 	if (quirks->predator_v4) {
1914 		u8 current_tp;
1915 		int tp, err;
1916 		u64 on_AC;
1917 		acpi_status status;
1918 
1919 		err = ec_read(ACER_PREDATOR_V4_THERMAL_PROFILE_EC_OFFSET,
1920 			      &current_tp);
1921 
1922 		if (err < 0)
1923 			return err;
1924 
1925 		/* Check power source */
1926 		status = WMI_gaming_execute_u64(
1927 			ACER_WMID_GET_GAMING_SYS_INFO_METHODID,
1928 			ACER_WMID_CMD_GET_PREDATOR_V4_BAT_STATUS, &on_AC);
1929 
1930 		if (ACPI_FAILURE(status))
1931 			return -EIO;
1932 
1933 		switch (current_tp) {
1934 		case ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO:
1935 			if (!on_AC)
1936 				tp = ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED_WMI;
1937 			else if (cycle_gaming_thermal_profile)
1938 				tp = ACER_PREDATOR_V4_THERMAL_PROFILE_ECO_WMI;
1939 			else
1940 				tp = last_non_turbo_profile;
1941 			break;
1942 		case ACER_PREDATOR_V4_THERMAL_PROFILE_PERFORMANCE:
1943 			if (!on_AC)
1944 				tp = ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED_WMI;
1945 			else
1946 				tp = ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO_WMI;
1947 			break;
1948 		case ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED:
1949 			if (!on_AC)
1950 				tp = ACER_PREDATOR_V4_THERMAL_PROFILE_ECO_WMI;
1951 			else if (cycle_gaming_thermal_profile)
1952 				tp = ACER_PREDATOR_V4_THERMAL_PROFILE_PERFORMANCE_WMI;
1953 			else
1954 				tp = ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO_WMI;
1955 			break;
1956 		case ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET:
1957 			if (!on_AC)
1958 				tp = ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED_WMI;
1959 			else if (cycle_gaming_thermal_profile)
1960 				tp = ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED_WMI;
1961 			else
1962 				tp = ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO_WMI;
1963 			break;
1964 		case ACER_PREDATOR_V4_THERMAL_PROFILE_ECO:
1965 			if (!on_AC)
1966 				tp = ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED_WMI;
1967 			else if (cycle_gaming_thermal_profile)
1968 				tp = ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET_WMI;
1969 			else
1970 				tp = ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO_WMI;
1971 			break;
1972 		default:
1973 			return -EOPNOTSUPP;
1974 		}
1975 
1976 		status = WMI_gaming_execute_u64(
1977 			ACER_WMID_SET_GAMING_MISC_SETTING_METHODID, tp, NULL);
1978 
1979 		if (ACPI_FAILURE(status))
1980 			return -EIO;
1981 
1982 		/* Store non-turbo profile for turbo mode toggle*/
1983 		if (tp != ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO_WMI)
1984 			last_non_turbo_profile = tp;
1985 
1986 		platform_profile_notify();
1987 	}
1988 
1989 	return 0;
1990 }
1991 
1992 /*
1993  * Switch series keyboard dock status
1994  */
1995 static int acer_kbd_dock_state_to_sw_tablet_mode(u8 kbd_dock_state)
1996 {
1997 	switch (kbd_dock_state) {
1998 	case 0x01: /* Docked, traditional clamshell laptop mode */
1999 		return 0;
2000 	case 0x04: /* Stand-alone tablet */
2001 	case 0x40: /* Docked, tent mode, keyboard not usable */
2002 		return 1;
2003 	default:
2004 		pr_warn("Unknown kbd_dock_state 0x%02x\n", kbd_dock_state);
2005 	}
2006 
2007 	return 0;
2008 }
2009 
2010 static void acer_kbd_dock_get_initial_state(void)
2011 {
2012 	u8 *output, input[8] = { 0x05, 0x00, };
2013 	struct acpi_buffer input_buf = { sizeof(input), input };
2014 	struct acpi_buffer output_buf = { ACPI_ALLOCATE_BUFFER, NULL };
2015 	union acpi_object *obj;
2016 	acpi_status status;
2017 	int sw_tablet_mode;
2018 
2019 	status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input_buf, &output_buf);
2020 	if (ACPI_FAILURE(status)) {
2021 		pr_err("Error getting keyboard-dock initial status: %s\n",
2022 		       acpi_format_exception(status));
2023 		return;
2024 	}
2025 
2026 	obj = output_buf.pointer;
2027 	if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) {
2028 		pr_err("Unexpected output format getting keyboard-dock initial status\n");
2029 		goto out_free_obj;
2030 	}
2031 
2032 	output = obj->buffer.pointer;
2033 	if (output[0] != 0x00 || (output[3] != 0x05 && output[3] != 0x45)) {
2034 		pr_err("Unexpected output [0]=0x%02x [3]=0x%02x getting keyboard-dock initial status\n",
2035 		       output[0], output[3]);
2036 		goto out_free_obj;
2037 	}
2038 
2039 	sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(output[4]);
2040 	input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode);
2041 
2042 out_free_obj:
2043 	kfree(obj);
2044 }
2045 
2046 static void acer_kbd_dock_event(const struct event_return_value *event)
2047 {
2048 	int sw_tablet_mode;
2049 
2050 	if (!has_cap(ACER_CAP_KBD_DOCK))
2051 		return;
2052 
2053 	sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(event->kbd_dock_state);
2054 	input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode);
2055 	input_sync(acer_wmi_input_dev);
2056 }
2057 
2058 /*
2059  * Rfkill devices
2060  */
2061 static void acer_rfkill_update(struct work_struct *ignored);
2062 static DECLARE_DELAYED_WORK(acer_rfkill_work, acer_rfkill_update);
2063 static void acer_rfkill_update(struct work_struct *ignored)
2064 {
2065 	u32 state;
2066 	acpi_status status;
2067 
2068 	if (has_cap(ACER_CAP_WIRELESS)) {
2069 		status = get_u32(&state, ACER_CAP_WIRELESS);
2070 		if (ACPI_SUCCESS(status)) {
2071 			if (quirks->wireless == 3)
2072 				rfkill_set_hw_state(wireless_rfkill, !state);
2073 			else
2074 				rfkill_set_sw_state(wireless_rfkill, !state);
2075 		}
2076 	}
2077 
2078 	if (has_cap(ACER_CAP_BLUETOOTH)) {
2079 		status = get_u32(&state, ACER_CAP_BLUETOOTH);
2080 		if (ACPI_SUCCESS(status))
2081 			rfkill_set_sw_state(bluetooth_rfkill, !state);
2082 	}
2083 
2084 	if (has_cap(ACER_CAP_THREEG) && wmi_has_guid(WMID_GUID3)) {
2085 		status = get_u32(&state, ACER_WMID3_GDS_THREEG);
2086 		if (ACPI_SUCCESS(status))
2087 			rfkill_set_sw_state(threeg_rfkill, !state);
2088 	}
2089 
2090 	schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
2091 }
2092 
2093 static int acer_rfkill_set(void *data, bool blocked)
2094 {
2095 	acpi_status status;
2096 	u32 cap = (unsigned long)data;
2097 
2098 	if (rfkill_inited) {
2099 		status = set_u32(!blocked, cap);
2100 		if (ACPI_FAILURE(status))
2101 			return -ENODEV;
2102 	}
2103 
2104 	return 0;
2105 }
2106 
2107 static const struct rfkill_ops acer_rfkill_ops = {
2108 	.set_block = acer_rfkill_set,
2109 };
2110 
2111 static struct rfkill *acer_rfkill_register(struct device *dev,
2112 					   enum rfkill_type type,
2113 					   char *name, u32 cap)
2114 {
2115 	int err;
2116 	struct rfkill *rfkill_dev;
2117 	u32 state;
2118 	acpi_status status;
2119 
2120 	rfkill_dev = rfkill_alloc(name, dev, type,
2121 				  &acer_rfkill_ops,
2122 				  (void *)(unsigned long)cap);
2123 	if (!rfkill_dev)
2124 		return ERR_PTR(-ENOMEM);
2125 
2126 	status = get_u32(&state, cap);
2127 
2128 	err = rfkill_register(rfkill_dev);
2129 	if (err) {
2130 		rfkill_destroy(rfkill_dev);
2131 		return ERR_PTR(err);
2132 	}
2133 
2134 	if (ACPI_SUCCESS(status))
2135 		rfkill_set_sw_state(rfkill_dev, !state);
2136 
2137 	return rfkill_dev;
2138 }
2139 
2140 static int acer_rfkill_init(struct device *dev)
2141 {
2142 	int err;
2143 
2144 	if (has_cap(ACER_CAP_WIRELESS)) {
2145 		wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN,
2146 			"acer-wireless", ACER_CAP_WIRELESS);
2147 		if (IS_ERR(wireless_rfkill)) {
2148 			err = PTR_ERR(wireless_rfkill);
2149 			goto error_wireless;
2150 		}
2151 	}
2152 
2153 	if (has_cap(ACER_CAP_BLUETOOTH)) {
2154 		bluetooth_rfkill = acer_rfkill_register(dev,
2155 			RFKILL_TYPE_BLUETOOTH, "acer-bluetooth",
2156 			ACER_CAP_BLUETOOTH);
2157 		if (IS_ERR(bluetooth_rfkill)) {
2158 			err = PTR_ERR(bluetooth_rfkill);
2159 			goto error_bluetooth;
2160 		}
2161 	}
2162 
2163 	if (has_cap(ACER_CAP_THREEG)) {
2164 		threeg_rfkill = acer_rfkill_register(dev,
2165 			RFKILL_TYPE_WWAN, "acer-threeg",
2166 			ACER_CAP_THREEG);
2167 		if (IS_ERR(threeg_rfkill)) {
2168 			err = PTR_ERR(threeg_rfkill);
2169 			goto error_threeg;
2170 		}
2171 	}
2172 
2173 	rfkill_inited = true;
2174 
2175 	if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) &&
2176 	    has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG))
2177 		schedule_delayed_work(&acer_rfkill_work,
2178 			round_jiffies_relative(HZ));
2179 
2180 	return 0;
2181 
2182 error_threeg:
2183 	if (has_cap(ACER_CAP_BLUETOOTH)) {
2184 		rfkill_unregister(bluetooth_rfkill);
2185 		rfkill_destroy(bluetooth_rfkill);
2186 	}
2187 error_bluetooth:
2188 	if (has_cap(ACER_CAP_WIRELESS)) {
2189 		rfkill_unregister(wireless_rfkill);
2190 		rfkill_destroy(wireless_rfkill);
2191 	}
2192 error_wireless:
2193 	return err;
2194 }
2195 
2196 static void acer_rfkill_exit(void)
2197 {
2198 	if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) &&
2199 	    has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG))
2200 		cancel_delayed_work_sync(&acer_rfkill_work);
2201 
2202 	if (has_cap(ACER_CAP_WIRELESS)) {
2203 		rfkill_unregister(wireless_rfkill);
2204 		rfkill_destroy(wireless_rfkill);
2205 	}
2206 
2207 	if (has_cap(ACER_CAP_BLUETOOTH)) {
2208 		rfkill_unregister(bluetooth_rfkill);
2209 		rfkill_destroy(bluetooth_rfkill);
2210 	}
2211 
2212 	if (has_cap(ACER_CAP_THREEG)) {
2213 		rfkill_unregister(threeg_rfkill);
2214 		rfkill_destroy(threeg_rfkill);
2215 	}
2216 }
2217 
2218 static void acer_wmi_notify(u32 value, void *context)
2219 {
2220 	struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
2221 	union acpi_object *obj;
2222 	struct event_return_value return_value;
2223 	acpi_status status;
2224 	u16 device_state;
2225 	const struct key_entry *key;
2226 	u32 scancode;
2227 
2228 	status = wmi_get_event_data(value, &response);
2229 	if (status != AE_OK) {
2230 		pr_warn("bad event status 0x%x\n", status);
2231 		return;
2232 	}
2233 
2234 	obj = (union acpi_object *)response.pointer;
2235 
2236 	if (!obj)
2237 		return;
2238 	if (obj->type != ACPI_TYPE_BUFFER) {
2239 		pr_warn("Unknown response received %d\n", obj->type);
2240 		kfree(obj);
2241 		return;
2242 	}
2243 	if (obj->buffer.length != 8) {
2244 		pr_warn("Unknown buffer length %d\n", obj->buffer.length);
2245 		kfree(obj);
2246 		return;
2247 	}
2248 
2249 	return_value = *((struct event_return_value *)obj->buffer.pointer);
2250 	kfree(obj);
2251 
2252 	switch (return_value.function) {
2253 	case WMID_HOTKEY_EVENT:
2254 		device_state = return_value.device_state;
2255 		pr_debug("device state: 0x%x\n", device_state);
2256 
2257 		key = sparse_keymap_entry_from_scancode(acer_wmi_input_dev,
2258 							return_value.key_num);
2259 		if (!key) {
2260 			pr_warn("Unknown key number - 0x%x\n",
2261 				return_value.key_num);
2262 		} else {
2263 			scancode = return_value.key_num;
2264 			switch (key->keycode) {
2265 			case KEY_WLAN:
2266 			case KEY_BLUETOOTH:
2267 				if (has_cap(ACER_CAP_WIRELESS))
2268 					rfkill_set_sw_state(wireless_rfkill,
2269 						!(device_state & ACER_WMID3_GDS_WIRELESS));
2270 				if (has_cap(ACER_CAP_THREEG))
2271 					rfkill_set_sw_state(threeg_rfkill,
2272 						!(device_state & ACER_WMID3_GDS_THREEG));
2273 				if (has_cap(ACER_CAP_BLUETOOTH))
2274 					rfkill_set_sw_state(bluetooth_rfkill,
2275 						!(device_state & ACER_WMID3_GDS_BLUETOOTH));
2276 				break;
2277 			case KEY_TOUCHPAD_TOGGLE:
2278 				scancode = (device_state & ACER_WMID3_GDS_TOUCHPAD) ?
2279 						KEY_TOUCHPAD_ON : KEY_TOUCHPAD_OFF;
2280 			}
2281 			sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true);
2282 		}
2283 		break;
2284 	case WMID_ACCEL_OR_KBD_DOCK_EVENT:
2285 		acer_gsensor_event();
2286 		acer_kbd_dock_event(&return_value);
2287 		break;
2288 	case WMID_GAMING_TURBO_KEY_EVENT:
2289 		if (return_value.key_num == 0x4)
2290 			acer_toggle_turbo();
2291 		if (return_value.key_num == 0x5 && has_cap(ACER_CAP_PLATFORM_PROFILE))
2292 			acer_thermal_profile_change();
2293 		break;
2294 	default:
2295 		pr_warn("Unknown function number - %d - %d\n",
2296 			return_value.function, return_value.key_num);
2297 		break;
2298 	}
2299 }
2300 
2301 static acpi_status __init
2302 wmid3_set_function_mode(struct func_input_params *params,
2303 			struct func_return_value *return_value)
2304 {
2305 	acpi_status status;
2306 	union acpi_object *obj;
2307 
2308 	struct acpi_buffer input = { sizeof(struct func_input_params), params };
2309 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
2310 
2311 	status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output);
2312 	if (ACPI_FAILURE(status))
2313 		return status;
2314 
2315 	obj = output.pointer;
2316 
2317 	if (!obj)
2318 		return AE_ERROR;
2319 	else if (obj->type != ACPI_TYPE_BUFFER) {
2320 		kfree(obj);
2321 		return AE_ERROR;
2322 	}
2323 	if (obj->buffer.length != 4) {
2324 		pr_warn("Unknown buffer length %d\n", obj->buffer.length);
2325 		kfree(obj);
2326 		return AE_ERROR;
2327 	}
2328 
2329 	*return_value = *((struct func_return_value *)obj->buffer.pointer);
2330 	kfree(obj);
2331 
2332 	return status;
2333 }
2334 
2335 static int __init acer_wmi_enable_ec_raw(void)
2336 {
2337 	struct func_return_value return_value;
2338 	acpi_status status;
2339 	struct func_input_params params = {
2340 		.function_num = 0x1,
2341 		.commun_devices = 0xFFFF,
2342 		.devices = 0xFFFF,
2343 		.app_status = 0x00,		/* Launch Manager Deactive */
2344 		.app_mask = 0x01,
2345 	};
2346 
2347 	status = wmid3_set_function_mode(&params, &return_value);
2348 
2349 	if (return_value.error_code || return_value.ec_return_value)
2350 		pr_warn("Enabling EC raw mode failed: 0x%x - 0x%x\n",
2351 			return_value.error_code,
2352 			return_value.ec_return_value);
2353 	else
2354 		pr_info("Enabled EC raw mode\n");
2355 
2356 	return status;
2357 }
2358 
2359 static int __init acer_wmi_enable_lm(void)
2360 {
2361 	struct func_return_value return_value;
2362 	acpi_status status;
2363 	struct func_input_params params = {
2364 		.function_num = 0x1,
2365 		.commun_devices = 0xFFFF,
2366 		.devices = 0xFFFF,
2367 		.app_status = 0x01,            /* Launch Manager Active */
2368 		.app_mask = 0x01,
2369 	};
2370 
2371 	status = wmid3_set_function_mode(&params, &return_value);
2372 
2373 	if (return_value.error_code || return_value.ec_return_value)
2374 		pr_warn("Enabling Launch Manager failed: 0x%x - 0x%x\n",
2375 			return_value.error_code,
2376 			return_value.ec_return_value);
2377 
2378 	return status;
2379 }
2380 
2381 static int __init acer_wmi_enable_rf_button(void)
2382 {
2383 	struct func_return_value return_value;
2384 	acpi_status status;
2385 	struct func_input_params params = {
2386 		.function_num = 0x1,
2387 		.commun_devices = 0xFFFF,
2388 		.devices = 0xFFFF,
2389 		.app_status = 0x10,            /* RF Button Active */
2390 		.app_mask = 0x10,
2391 	};
2392 
2393 	status = wmid3_set_function_mode(&params, &return_value);
2394 
2395 	if (return_value.error_code || return_value.ec_return_value)
2396 		pr_warn("Enabling RF Button failed: 0x%x - 0x%x\n",
2397 			return_value.error_code,
2398 			return_value.ec_return_value);
2399 
2400 	return status;
2401 }
2402 
2403 static int __init acer_wmi_accel_setup(void)
2404 {
2405 	struct acpi_device *adev;
2406 	int err;
2407 
2408 	adev = acpi_dev_get_first_match_dev("BST0001", NULL, -1);
2409 	if (!adev)
2410 		return -ENODEV;
2411 
2412 	gsensor_handle = acpi_device_handle(adev);
2413 	acpi_dev_put(adev);
2414 
2415 	acer_wmi_accel_dev = input_allocate_device();
2416 	if (!acer_wmi_accel_dev)
2417 		return -ENOMEM;
2418 
2419 	acer_wmi_accel_dev->open = acer_gsensor_open;
2420 
2421 	acer_wmi_accel_dev->name = "Acer BMA150 accelerometer";
2422 	acer_wmi_accel_dev->phys = "wmi/input1";
2423 	acer_wmi_accel_dev->id.bustype = BUS_HOST;
2424 	acer_wmi_accel_dev->evbit[0] = BIT_MASK(EV_ABS);
2425 	input_set_abs_params(acer_wmi_accel_dev, ABS_X, -16384, 16384, 0, 0);
2426 	input_set_abs_params(acer_wmi_accel_dev, ABS_Y, -16384, 16384, 0, 0);
2427 	input_set_abs_params(acer_wmi_accel_dev, ABS_Z, -16384, 16384, 0, 0);
2428 
2429 	err = input_register_device(acer_wmi_accel_dev);
2430 	if (err)
2431 		goto err_free_dev;
2432 
2433 	return 0;
2434 
2435 err_free_dev:
2436 	input_free_device(acer_wmi_accel_dev);
2437 	return err;
2438 }
2439 
2440 static int __init acer_wmi_input_setup(void)
2441 {
2442 	acpi_status status;
2443 	int err;
2444 
2445 	acer_wmi_input_dev = input_allocate_device();
2446 	if (!acer_wmi_input_dev)
2447 		return -ENOMEM;
2448 
2449 	acer_wmi_input_dev->name = "Acer WMI hotkeys";
2450 	acer_wmi_input_dev->phys = "wmi/input0";
2451 	acer_wmi_input_dev->id.bustype = BUS_HOST;
2452 
2453 	err = sparse_keymap_setup(acer_wmi_input_dev, acer_wmi_keymap, NULL);
2454 	if (err)
2455 		goto err_free_dev;
2456 
2457 	if (has_cap(ACER_CAP_KBD_DOCK))
2458 		input_set_capability(acer_wmi_input_dev, EV_SW, SW_TABLET_MODE);
2459 
2460 	status = wmi_install_notify_handler(ACERWMID_EVENT_GUID,
2461 						acer_wmi_notify, NULL);
2462 	if (ACPI_FAILURE(status)) {
2463 		err = -EIO;
2464 		goto err_free_dev;
2465 	}
2466 
2467 	if (has_cap(ACER_CAP_KBD_DOCK))
2468 		acer_kbd_dock_get_initial_state();
2469 
2470 	err = input_register_device(acer_wmi_input_dev);
2471 	if (err)
2472 		goto err_uninstall_notifier;
2473 
2474 	return 0;
2475 
2476 err_uninstall_notifier:
2477 	wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
2478 err_free_dev:
2479 	input_free_device(acer_wmi_input_dev);
2480 	return err;
2481 }
2482 
2483 static void acer_wmi_input_destroy(void)
2484 {
2485 	wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
2486 	input_unregister_device(acer_wmi_input_dev);
2487 }
2488 
2489 /*
2490  * debugfs functions
2491  */
2492 static u32 get_wmid_devices(void)
2493 {
2494 	struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
2495 	union acpi_object *obj;
2496 	acpi_status status;
2497 	u32 devices = 0;
2498 
2499 	status = wmi_query_block(WMID_GUID2, 0, &out);
2500 	if (ACPI_FAILURE(status))
2501 		return 0;
2502 
2503 	obj = (union acpi_object *) out.pointer;
2504 	if (obj) {
2505 		if (obj->type == ACPI_TYPE_BUFFER &&
2506 			(obj->buffer.length == sizeof(u32) ||
2507 			obj->buffer.length == sizeof(u64))) {
2508 			devices = *((u32 *) obj->buffer.pointer);
2509 		} else if (obj->type == ACPI_TYPE_INTEGER) {
2510 			devices = (u32) obj->integer.value;
2511 		}
2512 	}
2513 
2514 	kfree(out.pointer);
2515 	return devices;
2516 }
2517 
2518 static int acer_wmi_hwmon_init(void);
2519 
2520 /*
2521  * Platform device
2522  */
2523 static int acer_platform_probe(struct platform_device *device)
2524 {
2525 	int err;
2526 
2527 	if (has_cap(ACER_CAP_MAILLED)) {
2528 		err = acer_led_init(&device->dev);
2529 		if (err)
2530 			goto error_mailled;
2531 	}
2532 
2533 	if (has_cap(ACER_CAP_BRIGHTNESS)) {
2534 		err = acer_backlight_init(&device->dev);
2535 		if (err)
2536 			goto error_brightness;
2537 	}
2538 
2539 	err = acer_rfkill_init(&device->dev);
2540 	if (err)
2541 		goto error_rfkill;
2542 
2543 	if (has_cap(ACER_CAP_PLATFORM_PROFILE)) {
2544 		err = acer_platform_profile_setup();
2545 		if (err)
2546 			goto error_platform_profile;
2547 	}
2548 
2549 	if (has_cap(ACER_CAP_FAN_SPEED_READ)) {
2550 		err = acer_wmi_hwmon_init();
2551 		if (err)
2552 			goto error_hwmon;
2553 	}
2554 
2555 	return 0;
2556 
2557 error_hwmon:
2558 	if (platform_profile_support)
2559 		platform_profile_remove();
2560 error_platform_profile:
2561 	acer_rfkill_exit();
2562 error_rfkill:
2563 	if (has_cap(ACER_CAP_BRIGHTNESS))
2564 		acer_backlight_exit();
2565 error_brightness:
2566 	if (has_cap(ACER_CAP_MAILLED))
2567 		acer_led_exit();
2568 error_mailled:
2569 	return err;
2570 }
2571 
2572 static void acer_platform_remove(struct platform_device *device)
2573 {
2574 	if (has_cap(ACER_CAP_MAILLED))
2575 		acer_led_exit();
2576 	if (has_cap(ACER_CAP_BRIGHTNESS))
2577 		acer_backlight_exit();
2578 
2579 	acer_rfkill_exit();
2580 
2581 	if (platform_profile_support)
2582 		platform_profile_remove();
2583 }
2584 
2585 #ifdef CONFIG_PM_SLEEP
2586 static int acer_suspend(struct device *dev)
2587 {
2588 	u32 value;
2589 	struct acer_data *data = &interface->data;
2590 
2591 	if (!data)
2592 		return -ENOMEM;
2593 
2594 	if (has_cap(ACER_CAP_MAILLED)) {
2595 		get_u32(&value, ACER_CAP_MAILLED);
2596 		set_u32(LED_OFF, ACER_CAP_MAILLED);
2597 		data->mailled = value;
2598 	}
2599 
2600 	if (has_cap(ACER_CAP_BRIGHTNESS)) {
2601 		get_u32(&value, ACER_CAP_BRIGHTNESS);
2602 		data->brightness = value;
2603 	}
2604 
2605 	return 0;
2606 }
2607 
2608 static int acer_resume(struct device *dev)
2609 {
2610 	struct acer_data *data = &interface->data;
2611 
2612 	if (!data)
2613 		return -ENOMEM;
2614 
2615 	if (has_cap(ACER_CAP_MAILLED))
2616 		set_u32(data->mailled, ACER_CAP_MAILLED);
2617 
2618 	if (has_cap(ACER_CAP_BRIGHTNESS))
2619 		set_u32(data->brightness, ACER_CAP_BRIGHTNESS);
2620 
2621 	if (acer_wmi_accel_dev)
2622 		acer_gsensor_init();
2623 
2624 	return 0;
2625 }
2626 #else
2627 #define acer_suspend	NULL
2628 #define acer_resume	NULL
2629 #endif
2630 
2631 static SIMPLE_DEV_PM_OPS(acer_pm, acer_suspend, acer_resume);
2632 
2633 static void acer_platform_shutdown(struct platform_device *device)
2634 {
2635 	struct acer_data *data = &interface->data;
2636 
2637 	if (!data)
2638 		return;
2639 
2640 	if (has_cap(ACER_CAP_MAILLED))
2641 		set_u32(LED_OFF, ACER_CAP_MAILLED);
2642 }
2643 
2644 static struct platform_driver acer_platform_driver = {
2645 	.driver = {
2646 		.name = "acer-wmi",
2647 		.pm = &acer_pm,
2648 	},
2649 	.probe = acer_platform_probe,
2650 	.remove_new = acer_platform_remove,
2651 	.shutdown = acer_platform_shutdown,
2652 };
2653 
2654 static struct platform_device *acer_platform_device;
2655 
2656 static void remove_debugfs(void)
2657 {
2658 	debugfs_remove_recursive(interface->debug.root);
2659 }
2660 
2661 static void __init create_debugfs(void)
2662 {
2663 	interface->debug.root = debugfs_create_dir("acer-wmi", NULL);
2664 
2665 	debugfs_create_u32("devices", S_IRUGO, interface->debug.root,
2666 			   &interface->debug.wmid_devices);
2667 }
2668 
2669 static umode_t acer_wmi_hwmon_is_visible(const void *data,
2670 					 enum hwmon_sensor_types type, u32 attr,
2671 					 int channel)
2672 {
2673 	switch (type) {
2674 	case hwmon_fan:
2675 		if (acer_get_fan_speed(channel) >= 0)
2676 			return 0444;
2677 		break;
2678 	default:
2679 		return 0;
2680 	}
2681 
2682 	return 0;
2683 }
2684 
2685 static int acer_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
2686 			       u32 attr, int channel, long *val)
2687 {
2688 	int ret;
2689 
2690 	switch (type) {
2691 	case hwmon_fan:
2692 		ret = acer_get_fan_speed(channel);
2693 		if (ret < 0)
2694 			return ret;
2695 		*val = ret;
2696 		break;
2697 	default:
2698 		return -EOPNOTSUPP;
2699 	}
2700 
2701 	return 0;
2702 }
2703 
2704 static const struct hwmon_channel_info *const acer_wmi_hwmon_info[] = {
2705 	HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT, HWMON_F_INPUT), NULL
2706 };
2707 
2708 static const struct hwmon_ops acer_wmi_hwmon_ops = {
2709 	.read = acer_wmi_hwmon_read,
2710 	.is_visible = acer_wmi_hwmon_is_visible,
2711 };
2712 
2713 static const struct hwmon_chip_info acer_wmi_hwmon_chip_info = {
2714 	.ops = &acer_wmi_hwmon_ops,
2715 	.info = acer_wmi_hwmon_info,
2716 };
2717 
2718 static int acer_wmi_hwmon_init(void)
2719 {
2720 	struct device *dev = &acer_platform_device->dev;
2721 	struct device *hwmon;
2722 
2723 	hwmon = devm_hwmon_device_register_with_info(dev, "acer",
2724 						     &acer_platform_driver,
2725 						     &acer_wmi_hwmon_chip_info,
2726 						     NULL);
2727 
2728 	if (IS_ERR(hwmon)) {
2729 		dev_err(dev, "Could not register acer hwmon device\n");
2730 		return PTR_ERR(hwmon);
2731 	}
2732 
2733 	return 0;
2734 }
2735 
2736 static int __init acer_wmi_init(void)
2737 {
2738 	int err;
2739 
2740 	pr_info("Acer Laptop ACPI-WMI Extras\n");
2741 
2742 	if (dmi_check_system(acer_blacklist)) {
2743 		pr_info("Blacklisted hardware detected - not loading\n");
2744 		return -ENODEV;
2745 	}
2746 
2747 	find_quirks();
2748 
2749 	/*
2750 	 * The AMW0_GUID1 wmi is not only found on Acer family but also other
2751 	 * machines like Lenovo, Fujitsu and Medion. In the past days,
2752 	 * acer-wmi driver handled those non-Acer machines by quirks list.
2753 	 * But actually acer-wmi driver was loaded on any machines that have
2754 	 * AMW0_GUID1. This behavior is strange because those machines should
2755 	 * be supported by appropriate wmi drivers. e.g. fujitsu-laptop,
2756 	 * ideapad-laptop. So, here checks the machine that has AMW0_GUID1
2757 	 * should be in Acer/Gateway/Packard Bell white list, or it's already
2758 	 * in the past quirk list.
2759 	 */
2760 	if (wmi_has_guid(AMW0_GUID1) &&
2761 	    !dmi_check_system(amw0_whitelist) &&
2762 	    quirks == &quirk_unknown) {
2763 		pr_debug("Unsupported machine has AMW0_GUID1, unable to load\n");
2764 		return -ENODEV;
2765 	}
2766 
2767 	/*
2768 	 * Detect which ACPI-WMI interface we're using.
2769 	 */
2770 	if (wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1))
2771 		interface = &AMW0_V2_interface;
2772 
2773 	if (!wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1))
2774 		interface = &wmid_interface;
2775 
2776 	if (wmi_has_guid(WMID_GUID3))
2777 		interface = &wmid_v2_interface;
2778 
2779 	if (interface)
2780 		dmi_walk(type_aa_dmi_decode, NULL);
2781 
2782 	if (wmi_has_guid(WMID_GUID2) && interface) {
2783 		if (!has_type_aa && ACPI_FAILURE(WMID_set_capabilities())) {
2784 			pr_err("Unable to detect available WMID devices\n");
2785 			return -ENODEV;
2786 		}
2787 		/* WMID always provides brightness methods */
2788 		interface->capability |= ACER_CAP_BRIGHTNESS;
2789 	} else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa && force_caps == -1) {
2790 		pr_err("No WMID device detection method found\n");
2791 		return -ENODEV;
2792 	}
2793 
2794 	if (wmi_has_guid(AMW0_GUID1) && !wmi_has_guid(WMID_GUID1)) {
2795 		interface = &AMW0_interface;
2796 
2797 		if (ACPI_FAILURE(AMW0_set_capabilities())) {
2798 			pr_err("Unable to detect available AMW0 devices\n");
2799 			return -ENODEV;
2800 		}
2801 	}
2802 
2803 	if (wmi_has_guid(AMW0_GUID1))
2804 		AMW0_find_mailled();
2805 
2806 	if (!interface) {
2807 		pr_err("No or unsupported WMI interface, unable to load\n");
2808 		return -ENODEV;
2809 	}
2810 
2811 	set_quirks();
2812 
2813 	if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
2814 		interface->capability &= ~ACER_CAP_BRIGHTNESS;
2815 
2816 	if (wmi_has_guid(WMID_GUID3))
2817 		interface->capability |= ACER_CAP_SET_FUNCTION_MODE;
2818 
2819 	if (force_caps != -1)
2820 		interface->capability = force_caps;
2821 
2822 	if (wmi_has_guid(WMID_GUID3) &&
2823 	    (interface->capability & ACER_CAP_SET_FUNCTION_MODE)) {
2824 		if (ACPI_FAILURE(acer_wmi_enable_rf_button()))
2825 			pr_warn("Cannot enable RF Button Driver\n");
2826 
2827 		if (ec_raw_mode) {
2828 			if (ACPI_FAILURE(acer_wmi_enable_ec_raw())) {
2829 				pr_err("Cannot enable EC raw mode\n");
2830 				return -ENODEV;
2831 			}
2832 		} else if (ACPI_FAILURE(acer_wmi_enable_lm())) {
2833 			pr_err("Cannot enable Launch Manager mode\n");
2834 			return -ENODEV;
2835 		}
2836 	} else if (ec_raw_mode) {
2837 		pr_info("No WMID EC raw mode enable method\n");
2838 	}
2839 
2840 	if (wmi_has_guid(ACERWMID_EVENT_GUID)) {
2841 		err = acer_wmi_input_setup();
2842 		if (err)
2843 			return err;
2844 		err = acer_wmi_accel_setup();
2845 		if (err && err != -ENODEV)
2846 			pr_warn("Cannot enable accelerometer\n");
2847 	}
2848 
2849 	err = platform_driver_register(&acer_platform_driver);
2850 	if (err) {
2851 		pr_err("Unable to register platform driver\n");
2852 		goto error_platform_register;
2853 	}
2854 
2855 	acer_platform_device = platform_device_alloc("acer-wmi", PLATFORM_DEVID_NONE);
2856 	if (!acer_platform_device) {
2857 		err = -ENOMEM;
2858 		goto error_device_alloc;
2859 	}
2860 
2861 	err = platform_device_add(acer_platform_device);
2862 	if (err)
2863 		goto error_device_add;
2864 
2865 	if (wmi_has_guid(WMID_GUID2)) {
2866 		interface->debug.wmid_devices = get_wmid_devices();
2867 		create_debugfs();
2868 	}
2869 
2870 	/* Override any initial settings with values from the commandline */
2871 	acer_commandline_init();
2872 
2873 	return 0;
2874 
2875 error_device_add:
2876 	platform_device_put(acer_platform_device);
2877 error_device_alloc:
2878 	platform_driver_unregister(&acer_platform_driver);
2879 error_platform_register:
2880 	if (wmi_has_guid(ACERWMID_EVENT_GUID))
2881 		acer_wmi_input_destroy();
2882 	if (acer_wmi_accel_dev)
2883 		input_unregister_device(acer_wmi_accel_dev);
2884 
2885 	return err;
2886 }
2887 
2888 static void __exit acer_wmi_exit(void)
2889 {
2890 	if (wmi_has_guid(ACERWMID_EVENT_GUID))
2891 		acer_wmi_input_destroy();
2892 
2893 	if (acer_wmi_accel_dev)
2894 		input_unregister_device(acer_wmi_accel_dev);
2895 
2896 	remove_debugfs();
2897 	platform_device_unregister(acer_platform_device);
2898 	platform_driver_unregister(&acer_platform_driver);
2899 
2900 	pr_info("Acer Laptop WMI Extras unloaded\n");
2901 }
2902 
2903 module_init(acer_wmi_init);
2904 module_exit(acer_wmi_exit);
2905