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