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