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