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