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