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