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