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