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