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