Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Acer WMI Laptop Extras
0004  *
0005  *  Copyright (C) 2007-2009 Carlos Corbacho <carlos@strangeworlds.co.uk>
0006  *
0007  *  Based on acer_acpi:
0008  *    Copyright (C) 2005-2007   E.M. Smith
0009  *    Copyright (C) 2007-2008   Carlos Corbacho <cathectic@gmail.com>
0010  */
0011 
0012 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0013 
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/init.h>
0017 #include <linux/types.h>
0018 #include <linux/dmi.h>
0019 #include <linux/fb.h>
0020 #include <linux/backlight.h>
0021 #include <linux/leds.h>
0022 #include <linux/platform_device.h>
0023 #include <linux/acpi.h>
0024 #include <linux/i8042.h>
0025 #include <linux/rfkill.h>
0026 #include <linux/workqueue.h>
0027 #include <linux/debugfs.h>
0028 #include <linux/slab.h>
0029 #include <linux/input.h>
0030 #include <linux/input/sparse-keymap.h>
0031 #include <acpi/video.h>
0032 
0033 MODULE_AUTHOR("Carlos Corbacho");
0034 MODULE_DESCRIPTION("Acer Laptop WMI Extras Driver");
0035 MODULE_LICENSE("GPL");
0036 
0037 /*
0038  * Magic Number
0039  * Meaning is unknown - this number is required for writing to ACPI for AMW0
0040  * (it's also used in acerhk when directly accessing the BIOS)
0041  */
0042 #define ACER_AMW0_WRITE 0x9610
0043 
0044 /*
0045  * Bit masks for the AMW0 interface
0046  */
0047 #define ACER_AMW0_WIRELESS_MASK  0x35
0048 #define ACER_AMW0_BLUETOOTH_MASK 0x34
0049 #define ACER_AMW0_MAILLED_MASK   0x31
0050 
0051 /*
0052  * Method IDs for WMID interface
0053  */
0054 #define ACER_WMID_GET_WIRELESS_METHODID     1
0055 #define ACER_WMID_GET_BLUETOOTH_METHODID    2
0056 #define ACER_WMID_GET_BRIGHTNESS_METHODID   3
0057 #define ACER_WMID_SET_WIRELESS_METHODID     4
0058 #define ACER_WMID_SET_BLUETOOTH_METHODID    5
0059 #define ACER_WMID_SET_BRIGHTNESS_METHODID   6
0060 #define ACER_WMID_GET_THREEG_METHODID       10
0061 #define ACER_WMID_SET_THREEG_METHODID       11
0062 
0063 #define ACER_WMID_SET_GAMING_LED_METHODID 2
0064 #define ACER_WMID_GET_GAMING_LED_METHODID 4
0065 #define ACER_WMID_SET_GAMING_FAN_BEHAVIOR 14
0066 #define ACER_WMID_SET_GAMING_MISC_SETTING_METHODID 22
0067 
0068 /*
0069  * Acer ACPI method GUIDs
0070  */
0071 #define AMW0_GUID1      "67C3371D-95A3-4C37-BB61-DD47B491DAAB"
0072 #define AMW0_GUID2      "431F16ED-0C2B-444C-B267-27DEB140CF9C"
0073 #define WMID_GUID1      "6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3"
0074 #define WMID_GUID2      "95764E09-FB56-4E83-B31A-37761F60994A"
0075 #define WMID_GUID3      "61EF69EA-865C-4BC3-A502-A0DEBA0CB531"
0076 #define WMID_GUID4      "7A4DDFE7-5B5D-40B4-8595-4408E0CC7F56"
0077 
0078 /*
0079  * Acer ACPI event GUIDs
0080  */
0081 #define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026"
0082 
0083 MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
0084 MODULE_ALIAS("wmi:6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3");
0085 MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
0086 
0087 enum acer_wmi_event_ids {
0088     WMID_HOTKEY_EVENT = 0x1,
0089     WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5,
0090     WMID_GAMING_TURBO_KEY_EVENT = 0x7,
0091 };
0092 
0093 static const struct key_entry acer_wmi_keymap[] __initconst = {
0094     {KE_KEY, 0x01, {KEY_WLAN} },     /* WiFi */
0095     {KE_KEY, 0x03, {KEY_WLAN} },     /* WiFi */
0096     {KE_KEY, 0x04, {KEY_WLAN} },     /* WiFi */
0097     {KE_KEY, 0x12, {KEY_BLUETOOTH} },   /* BT */
0098     {KE_KEY, 0x21, {KEY_PROG1} },    /* Backup */
0099     {KE_KEY, 0x22, {KEY_PROG2} },    /* Arcade */
0100     {KE_KEY, 0x23, {KEY_PROG3} },    /* P_Key */
0101     {KE_KEY, 0x24, {KEY_PROG4} },    /* Social networking_Key */
0102     {KE_KEY, 0x27, {KEY_HELP} },
0103     {KE_KEY, 0x29, {KEY_PROG3} },    /* P_Key for TM8372 */
0104     {KE_IGNORE, 0x41, {KEY_MUTE} },
0105     {KE_IGNORE, 0x42, {KEY_PREVIOUSSONG} },
0106     {KE_IGNORE, 0x4d, {KEY_PREVIOUSSONG} },
0107     {KE_IGNORE, 0x43, {KEY_NEXTSONG} },
0108     {KE_IGNORE, 0x4e, {KEY_NEXTSONG} },
0109     {KE_IGNORE, 0x44, {KEY_PLAYPAUSE} },
0110     {KE_IGNORE, 0x4f, {KEY_PLAYPAUSE} },
0111     {KE_IGNORE, 0x45, {KEY_STOP} },
0112     {KE_IGNORE, 0x50, {KEY_STOP} },
0113     {KE_IGNORE, 0x48, {KEY_VOLUMEUP} },
0114     {KE_IGNORE, 0x49, {KEY_VOLUMEDOWN} },
0115     {KE_IGNORE, 0x4a, {KEY_VOLUMEDOWN} },
0116     /*
0117      * 0x61 is KEY_SWITCHVIDEOMODE. Usually this is a duplicate input event
0118      * with the "Video Bus" input device events. But sometimes it is not
0119      * a dup. Map it to KEY_UNKNOWN instead of using KE_IGNORE so that
0120      * udev/hwdb can override it on systems where it is not a dup.
0121      */
0122     {KE_KEY, 0x61, {KEY_UNKNOWN} },
0123     {KE_IGNORE, 0x62, {KEY_BRIGHTNESSUP} },
0124     {KE_IGNORE, 0x63, {KEY_BRIGHTNESSDOWN} },
0125     {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */
0126     {KE_IGNORE, 0x81, {KEY_SLEEP} },
0127     {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad Toggle */
0128     {KE_IGNORE, 0x84, {KEY_KBDILLUMTOGGLE} }, /* Automatic Keyboard background light toggle */
0129     {KE_KEY, KEY_TOUCHPAD_ON, {KEY_TOUCHPAD_ON} },
0130     {KE_KEY, KEY_TOUCHPAD_OFF, {KEY_TOUCHPAD_OFF} },
0131     {KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} },
0132     {KE_KEY, 0x85, {KEY_TOUCHPAD_TOGGLE} },
0133     {KE_KEY, 0x86, {KEY_WLAN} },
0134     {KE_KEY, 0x87, {KEY_POWER} },
0135     {KE_END, 0}
0136 };
0137 
0138 static struct input_dev *acer_wmi_input_dev;
0139 static struct input_dev *acer_wmi_accel_dev;
0140 
0141 struct event_return_value {
0142     u8 function;
0143     u8 key_num;
0144     u16 device_state;
0145     u16 reserved1;
0146     u8 kbd_dock_state;
0147     u8 reserved2;
0148 } __packed;
0149 
0150 /*
0151  * GUID3 Get Device Status device flags
0152  */
0153 #define ACER_WMID3_GDS_WIRELESS     (1<<0)  /* WiFi */
0154 #define ACER_WMID3_GDS_THREEG       (1<<6)  /* 3G */
0155 #define ACER_WMID3_GDS_WIMAX        (1<<7)  /* WiMAX */
0156 #define ACER_WMID3_GDS_BLUETOOTH    (1<<11) /* BT */
0157 #define ACER_WMID3_GDS_RFBTN        (1<<14) /* RF Button */
0158 
0159 #define ACER_WMID3_GDS_TOUCHPAD     (1<<1)  /* Touchpad */
0160 
0161 /* Hotkey Customized Setting and Acer Application Status.
0162  * Set Device Default Value and Report Acer Application Status.
0163  * When Acer Application starts, it will run this method to inform
0164  * BIOS/EC that Acer Application is on.
0165  * App Status
0166  *  Bit[0]: Launch Manager Status
0167  *  Bit[1]: ePM Status
0168  *  Bit[2]: Device Control Status
0169  *  Bit[3]: Acer Power Button Utility Status
0170  *  Bit[4]: RF Button Status
0171  *  Bit[5]: ODD PM Status
0172  *  Bit[6]: Device Default Value Control
0173  *  Bit[7]: Hall Sensor Application Status
0174  */
0175 struct func_input_params {
0176     u8 function_num;        /* Function Number */
0177     u16 commun_devices;     /* Communication type devices default status */
0178     u16 devices;            /* Other type devices default status */
0179     u8 app_status;          /* Acer Device Status. LM, ePM, RF Button... */
0180     u8 app_mask;        /* Bit mask to app_status */
0181     u8 reserved;
0182 } __packed;
0183 
0184 struct func_return_value {
0185     u8 error_code;          /* Error Code */
0186     u8 ec_return_value;     /* EC Return Value */
0187     u16 reserved;
0188 } __packed;
0189 
0190 struct wmid3_gds_set_input_param {     /* Set Device Status input parameter */
0191     u8 function_num;        /* Function Number */
0192     u8 hotkey_number;       /* Hotkey Number */
0193     u16 devices;            /* Set Device */
0194     u8 volume_value;        /* Volume Value */
0195 } __packed;
0196 
0197 struct wmid3_gds_get_input_param {     /* Get Device Status input parameter */
0198     u8 function_num;    /* Function Number */
0199     u8 hotkey_number;   /* Hotkey Number */
0200     u16 devices;        /* Get Device */
0201 } __packed;
0202 
0203 struct wmid3_gds_return_value { /* Get Device Status return value*/
0204     u8 error_code;      /* Error Code */
0205     u8 ec_return_value; /* EC Return Value */
0206     u16 devices;        /* Current Device Status */
0207     u32 reserved;
0208 } __packed;
0209 
0210 struct hotkey_function_type_aa {
0211     u8 type;
0212     u8 length;
0213     u16 handle;
0214     u16 commun_func_bitmap;
0215     u16 application_func_bitmap;
0216     u16 media_func_bitmap;
0217     u16 display_func_bitmap;
0218     u16 others_func_bitmap;
0219     u8 commun_fn_key_number;
0220 } __packed;
0221 
0222 /*
0223  * Interface capability flags
0224  */
0225 #define ACER_CAP_MAILLED        BIT(0)
0226 #define ACER_CAP_WIRELESS       BIT(1)
0227 #define ACER_CAP_BLUETOOTH      BIT(2)
0228 #define ACER_CAP_BRIGHTNESS     BIT(3)
0229 #define ACER_CAP_THREEG         BIT(4)
0230 #define ACER_CAP_SET_FUNCTION_MODE  BIT(5)
0231 #define ACER_CAP_KBD_DOCK       BIT(6)
0232 #define ACER_CAP_TURBO_OC     BIT(7)
0233 #define ACER_CAP_TURBO_LED     BIT(8)
0234 #define ACER_CAP_TURBO_FAN     BIT(9)
0235 
0236 /*
0237  * Interface type flags
0238  */
0239 enum interface_flags {
0240     ACER_AMW0,
0241     ACER_AMW0_V2,
0242     ACER_WMID,
0243     ACER_WMID_v2,
0244 };
0245 
0246 #define ACER_DEFAULT_WIRELESS  0
0247 #define ACER_DEFAULT_BLUETOOTH 0
0248 #define ACER_DEFAULT_MAILLED   0
0249 #define ACER_DEFAULT_THREEG    0
0250 
0251 static int max_brightness = 0xF;
0252 
0253 static int mailled = -1;
0254 static int brightness = -1;
0255 static int threeg = -1;
0256 static int force_series;
0257 static int force_caps = -1;
0258 static bool ec_raw_mode;
0259 static bool has_type_aa;
0260 static u16 commun_func_bitmap;
0261 static u8 commun_fn_key_number;
0262 
0263 module_param(mailled, int, 0444);
0264 module_param(brightness, int, 0444);
0265 module_param(threeg, int, 0444);
0266 module_param(force_series, int, 0444);
0267 module_param(force_caps, int, 0444);
0268 module_param(ec_raw_mode, bool, 0444);
0269 MODULE_PARM_DESC(mailled, "Set initial state of Mail LED");
0270 MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness");
0271 MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware");
0272 MODULE_PARM_DESC(force_series, "Force a different laptop series");
0273 MODULE_PARM_DESC(force_caps, "Force the capability bitmask to this value");
0274 MODULE_PARM_DESC(ec_raw_mode, "Enable EC raw mode");
0275 
0276 struct acer_data {
0277     int mailled;
0278     int threeg;
0279     int brightness;
0280 };
0281 
0282 struct acer_debug {
0283     struct dentry *root;
0284     u32 wmid_devices;
0285 };
0286 
0287 static struct rfkill *wireless_rfkill;
0288 static struct rfkill *bluetooth_rfkill;
0289 static struct rfkill *threeg_rfkill;
0290 static bool rfkill_inited;
0291 
0292 /* Each low-level interface must define at least some of the following */
0293 struct wmi_interface {
0294     /* The WMI device type */
0295     u32 type;
0296 
0297     /* The capabilities this interface provides */
0298     u32 capability;
0299 
0300     /* Private data for the current interface */
0301     struct acer_data data;
0302 
0303     /* debugfs entries associated with this interface */
0304     struct acer_debug debug;
0305 };
0306 
0307 /* The static interface pointer, points to the currently detected interface */
0308 static struct wmi_interface *interface;
0309 
0310 /*
0311  * Embedded Controller quirks
0312  * Some laptops require us to directly access the EC to either enable or query
0313  * features that are not available through WMI.
0314  */
0315 
0316 struct quirk_entry {
0317     u8 wireless;
0318     u8 mailled;
0319     s8 brightness;
0320     u8 bluetooth;
0321     u8 turbo;
0322     u8 cpu_fans;
0323     u8 gpu_fans;
0324 };
0325 
0326 static struct quirk_entry *quirks;
0327 
0328 static void __init set_quirks(void)
0329 {
0330     if (quirks->mailled)
0331         interface->capability |= ACER_CAP_MAILLED;
0332 
0333     if (quirks->brightness)
0334         interface->capability |= ACER_CAP_BRIGHTNESS;
0335 
0336     if (quirks->turbo)
0337         interface->capability |= ACER_CAP_TURBO_OC | ACER_CAP_TURBO_LED
0338                      | ACER_CAP_TURBO_FAN;
0339 }
0340 
0341 static int __init dmi_matched(const struct dmi_system_id *dmi)
0342 {
0343     quirks = dmi->driver_data;
0344     return 1;
0345 }
0346 
0347 static int __init set_force_caps(const struct dmi_system_id *dmi)
0348 {
0349     if (force_caps == -1) {
0350         force_caps = (uintptr_t)dmi->driver_data;
0351         pr_info("Found %s, set force_caps to 0x%x\n", dmi->ident, force_caps);
0352     }
0353     return 1;
0354 }
0355 
0356 static struct quirk_entry quirk_unknown = {
0357 };
0358 
0359 static struct quirk_entry quirk_acer_aspire_1520 = {
0360     .brightness = -1,
0361 };
0362 
0363 static struct quirk_entry quirk_acer_travelmate_2490 = {
0364     .mailled = 1,
0365 };
0366 
0367 static struct quirk_entry quirk_acer_predator_ph315_53 = {
0368     .turbo = 1,
0369     .cpu_fans = 1,
0370     .gpu_fans = 1,
0371 };
0372 
0373 /* This AMW0 laptop has no bluetooth */
0374 static struct quirk_entry quirk_medion_md_98300 = {
0375     .wireless = 1,
0376 };
0377 
0378 static struct quirk_entry quirk_fujitsu_amilo_li_1718 = {
0379     .wireless = 2,
0380 };
0381 
0382 static struct quirk_entry quirk_lenovo_ideapad_s205 = {
0383     .wireless = 3,
0384 };
0385 
0386 /* The Aspire One has a dummy ACPI-WMI interface - disable it */
0387 static const struct dmi_system_id acer_blacklist[] __initconst = {
0388     {
0389         .ident = "Acer Aspire One (SSD)",
0390         .matches = {
0391             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0392             DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
0393         },
0394     },
0395     {
0396         .ident = "Acer Aspire One (HDD)",
0397         .matches = {
0398             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0399             DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
0400         },
0401     },
0402     {}
0403 };
0404 
0405 static const struct dmi_system_id amw0_whitelist[] __initconst = {
0406     {
0407         .ident = "Acer",
0408         .matches = {
0409             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0410         },
0411     },
0412     {
0413         .ident = "Gateway",
0414         .matches = {
0415             DMI_MATCH(DMI_SYS_VENDOR, "Gateway"),
0416         },
0417     },
0418     {
0419         .ident = "Packard Bell",
0420         .matches = {
0421             DMI_MATCH(DMI_SYS_VENDOR, "Packard Bell"),
0422         },
0423     },
0424     {}
0425 };
0426 
0427 /*
0428  * This quirk table is only for Acer/Gateway/Packard Bell family
0429  * that those machines are supported by acer-wmi driver.
0430  */
0431 static const struct dmi_system_id acer_quirks[] __initconst = {
0432     {
0433         .callback = dmi_matched,
0434         .ident = "Acer Aspire 1360",
0435         .matches = {
0436             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0437             DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
0438         },
0439         .driver_data = &quirk_acer_aspire_1520,
0440     },
0441     {
0442         .callback = dmi_matched,
0443         .ident = "Acer Aspire 1520",
0444         .matches = {
0445             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0446             DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1520"),
0447         },
0448         .driver_data = &quirk_acer_aspire_1520,
0449     },
0450     {
0451         .callback = dmi_matched,
0452         .ident = "Acer Aspire 3100",
0453         .matches = {
0454             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0455             DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3100"),
0456         },
0457         .driver_data = &quirk_acer_travelmate_2490,
0458     },
0459     {
0460         .callback = dmi_matched,
0461         .ident = "Acer Aspire 3610",
0462         .matches = {
0463             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0464             DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3610"),
0465         },
0466         .driver_data = &quirk_acer_travelmate_2490,
0467     },
0468     {
0469         .callback = dmi_matched,
0470         .ident = "Acer Aspire 5100",
0471         .matches = {
0472             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0473             DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
0474         },
0475         .driver_data = &quirk_acer_travelmate_2490,
0476     },
0477     {
0478         .callback = dmi_matched,
0479         .ident = "Acer Aspire 5610",
0480         .matches = {
0481             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0482             DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
0483         },
0484         .driver_data = &quirk_acer_travelmate_2490,
0485     },
0486     {
0487         .callback = dmi_matched,
0488         .ident = "Acer Aspire 5630",
0489         .matches = {
0490             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0491             DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"),
0492         },
0493         .driver_data = &quirk_acer_travelmate_2490,
0494     },
0495     {
0496         .callback = dmi_matched,
0497         .ident = "Acer Aspire 5650",
0498         .matches = {
0499             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0500             DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"),
0501         },
0502         .driver_data = &quirk_acer_travelmate_2490,
0503     },
0504     {
0505         .callback = dmi_matched,
0506         .ident = "Acer Aspire 5680",
0507         .matches = {
0508             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0509             DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
0510         },
0511         .driver_data = &quirk_acer_travelmate_2490,
0512     },
0513     {
0514         .callback = dmi_matched,
0515         .ident = "Acer Aspire 9110",
0516         .matches = {
0517             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0518             DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"),
0519         },
0520         .driver_data = &quirk_acer_travelmate_2490,
0521     },
0522     {
0523         .callback = dmi_matched,
0524         .ident = "Acer TravelMate 2490",
0525         .matches = {
0526             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0527             DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"),
0528         },
0529         .driver_data = &quirk_acer_travelmate_2490,
0530     },
0531     {
0532         .callback = dmi_matched,
0533         .ident = "Acer TravelMate 4200",
0534         .matches = {
0535             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0536             DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4200"),
0537         },
0538         .driver_data = &quirk_acer_travelmate_2490,
0539     },
0540     {
0541         .callback = dmi_matched,
0542         .ident = "Acer Predator PH315-53",
0543         .matches = {
0544             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0545             DMI_MATCH(DMI_PRODUCT_NAME, "Predator PH315-53"),
0546         },
0547         .driver_data = &quirk_acer_predator_ph315_53,
0548     },
0549     {
0550         .callback = set_force_caps,
0551         .ident = "Acer Aspire Switch 10E SW3-016",
0552         .matches = {
0553             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0554             DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW3-016"),
0555         },
0556         .driver_data = (void *)ACER_CAP_KBD_DOCK,
0557     },
0558     {
0559         .callback = set_force_caps,
0560         .ident = "Acer Aspire Switch 10 SW5-012",
0561         .matches = {
0562             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0563             DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
0564         },
0565         .driver_data = (void *)ACER_CAP_KBD_DOCK,
0566     },
0567     {
0568         .callback = set_force_caps,
0569         .ident = "Acer One 10 (S1003)",
0570         .matches = {
0571             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
0572             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"),
0573         },
0574         .driver_data = (void *)ACER_CAP_KBD_DOCK,
0575     },
0576     {}
0577 };
0578 
0579 /*
0580  * This quirk list is for those non-acer machines that have AMW0_GUID1
0581  * but supported by acer-wmi in past days. Keeping this quirk list here
0582  * is only for backward compatible. Please do not add new machine to
0583  * here anymore. Those non-acer machines should be supported by
0584  * appropriate wmi drivers.
0585  */
0586 static const struct dmi_system_id non_acer_quirks[] __initconst = {
0587     {
0588         .callback = dmi_matched,
0589         .ident = "Fujitsu Siemens Amilo Li 1718",
0590         .matches = {
0591             DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
0592             DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Li 1718"),
0593         },
0594         .driver_data = &quirk_fujitsu_amilo_li_1718,
0595     },
0596     {
0597         .callback = dmi_matched,
0598         .ident = "Medion MD 98300",
0599         .matches = {
0600             DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
0601             DMI_MATCH(DMI_PRODUCT_NAME, "WAM2030"),
0602         },
0603         .driver_data = &quirk_medion_md_98300,
0604     },
0605     {
0606         .callback = dmi_matched,
0607         .ident = "Lenovo Ideapad S205",
0608         .matches = {
0609             DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
0610             DMI_MATCH(DMI_PRODUCT_NAME, "10382LG"),
0611         },
0612         .driver_data = &quirk_lenovo_ideapad_s205,
0613     },
0614     {
0615         .callback = dmi_matched,
0616         .ident = "Lenovo Ideapad S205 (Brazos)",
0617         .matches = {
0618             DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
0619             DMI_MATCH(DMI_PRODUCT_NAME, "Brazos"),
0620         },
0621         .driver_data = &quirk_lenovo_ideapad_s205,
0622     },
0623     {
0624         .callback = dmi_matched,
0625         .ident = "Lenovo 3000 N200",
0626         .matches = {
0627             DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
0628             DMI_MATCH(DMI_PRODUCT_NAME, "0687A31"),
0629         },
0630         .driver_data = &quirk_fujitsu_amilo_li_1718,
0631     },
0632     {
0633         .callback = dmi_matched,
0634         .ident = "Lenovo Ideapad S205-10382JG",
0635         .matches = {
0636             DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
0637             DMI_MATCH(DMI_PRODUCT_NAME, "10382JG"),
0638         },
0639         .driver_data = &quirk_lenovo_ideapad_s205,
0640     },
0641     {
0642         .callback = dmi_matched,
0643         .ident = "Lenovo Ideapad S205-1038DPG",
0644         .matches = {
0645             DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
0646             DMI_MATCH(DMI_PRODUCT_NAME, "1038DPG"),
0647         },
0648         .driver_data = &quirk_lenovo_ideapad_s205,
0649     },
0650     {}
0651 };
0652 
0653 static int __init
0654 video_set_backlight_video_vendor(const struct dmi_system_id *d)
0655 {
0656     interface->capability &= ~ACER_CAP_BRIGHTNESS;
0657     pr_info("Brightness must be controlled by generic video driver\n");
0658     return 0;
0659 }
0660 
0661 static const struct dmi_system_id video_vendor_dmi_table[] __initconst = {
0662     {
0663         .callback = video_set_backlight_video_vendor,
0664         .ident = "Acer TravelMate 4750",
0665         .matches = {
0666             DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
0667             DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4750"),
0668         },
0669     },
0670     {
0671         .callback = video_set_backlight_video_vendor,
0672         .ident = "Acer Extensa 5235",
0673         .matches = {
0674             DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
0675             DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5235"),
0676         },
0677     },
0678     {
0679         .callback = video_set_backlight_video_vendor,
0680         .ident = "Acer TravelMate 5760",
0681         .matches = {
0682             DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
0683             DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5760"),
0684         },
0685     },
0686     {
0687         .callback = video_set_backlight_video_vendor,
0688         .ident = "Acer Aspire 5750",
0689         .matches = {
0690             DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
0691             DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5750"),
0692         },
0693     },
0694     {
0695         .callback = video_set_backlight_video_vendor,
0696         .ident = "Acer Aspire 5741",
0697         .matches = {
0698             DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
0699             DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5741"),
0700         },
0701     },
0702     {
0703         /*
0704          * Note no video_set_backlight_video_vendor, we must use the
0705          * acer interface, as there is no native backlight interface.
0706          */
0707         .ident = "Acer KAV80",
0708         .matches = {
0709             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0710             DMI_MATCH(DMI_PRODUCT_NAME, "KAV80"),
0711         },
0712     },
0713     {}
0714 };
0715 
0716 /* Find which quirks are needed for a particular vendor/ model pair */
0717 static void __init find_quirks(void)
0718 {
0719     if (!force_series) {
0720         dmi_check_system(acer_quirks);
0721         dmi_check_system(non_acer_quirks);
0722     } else if (force_series == 2490) {
0723         quirks = &quirk_acer_travelmate_2490;
0724     }
0725 
0726     if (quirks == NULL)
0727         quirks = &quirk_unknown;
0728 }
0729 
0730 /*
0731  * General interface convenience methods
0732  */
0733 
0734 static bool has_cap(u32 cap)
0735 {
0736     return interface->capability & cap;
0737 }
0738 
0739 /*
0740  * AMW0 (V1) interface
0741  */
0742 struct wmab_args {
0743     u32 eax;
0744     u32 ebx;
0745     u32 ecx;
0746     u32 edx;
0747 };
0748 
0749 struct wmab_ret {
0750     u32 eax;
0751     u32 ebx;
0752     u32 ecx;
0753     u32 edx;
0754     u32 eex;
0755 };
0756 
0757 static acpi_status wmab_execute(struct wmab_args *regbuf,
0758 struct acpi_buffer *result)
0759 {
0760     struct acpi_buffer input;
0761     acpi_status status;
0762     input.length = sizeof(struct wmab_args);
0763     input.pointer = (u8 *)regbuf;
0764 
0765     status = wmi_evaluate_method(AMW0_GUID1, 0, 1, &input, result);
0766 
0767     return status;
0768 }
0769 
0770 static acpi_status AMW0_get_u32(u32 *value, u32 cap)
0771 {
0772     int err;
0773     u8 result;
0774 
0775     switch (cap) {
0776     case ACER_CAP_MAILLED:
0777         switch (quirks->mailled) {
0778         default:
0779             err = ec_read(0xA, &result);
0780             if (err)
0781                 return AE_ERROR;
0782             *value = (result >> 7) & 0x1;
0783             return AE_OK;
0784         }
0785         break;
0786     case ACER_CAP_WIRELESS:
0787         switch (quirks->wireless) {
0788         case 1:
0789             err = ec_read(0x7B, &result);
0790             if (err)
0791                 return AE_ERROR;
0792             *value = result & 0x1;
0793             return AE_OK;
0794         case 2:
0795             err = ec_read(0x71, &result);
0796             if (err)
0797                 return AE_ERROR;
0798             *value = result & 0x1;
0799             return AE_OK;
0800         case 3:
0801             err = ec_read(0x78, &result);
0802             if (err)
0803                 return AE_ERROR;
0804             *value = result & 0x1;
0805             return AE_OK;
0806         default:
0807             err = ec_read(0xA, &result);
0808             if (err)
0809                 return AE_ERROR;
0810             *value = (result >> 2) & 0x1;
0811             return AE_OK;
0812         }
0813         break;
0814     case ACER_CAP_BLUETOOTH:
0815         switch (quirks->bluetooth) {
0816         default:
0817             err = ec_read(0xA, &result);
0818             if (err)
0819                 return AE_ERROR;
0820             *value = (result >> 4) & 0x1;
0821             return AE_OK;
0822         }
0823         break;
0824     case ACER_CAP_BRIGHTNESS:
0825         switch (quirks->brightness) {
0826         default:
0827             err = ec_read(0x83, &result);
0828             if (err)
0829                 return AE_ERROR;
0830             *value = result;
0831             return AE_OK;
0832         }
0833         break;
0834     default:
0835         return AE_ERROR;
0836     }
0837     return AE_OK;
0838 }
0839 
0840 static acpi_status AMW0_set_u32(u32 value, u32 cap)
0841 {
0842     struct wmab_args args;
0843 
0844     args.eax = ACER_AMW0_WRITE;
0845     args.ebx = value ? (1<<8) : 0;
0846     args.ecx = args.edx = 0;
0847 
0848     switch (cap) {
0849     case ACER_CAP_MAILLED:
0850         if (value > 1)
0851             return AE_BAD_PARAMETER;
0852         args.ebx |= ACER_AMW0_MAILLED_MASK;
0853         break;
0854     case ACER_CAP_WIRELESS:
0855         if (value > 1)
0856             return AE_BAD_PARAMETER;
0857         args.ebx |= ACER_AMW0_WIRELESS_MASK;
0858         break;
0859     case ACER_CAP_BLUETOOTH:
0860         if (value > 1)
0861             return AE_BAD_PARAMETER;
0862         args.ebx |= ACER_AMW0_BLUETOOTH_MASK;
0863         break;
0864     case ACER_CAP_BRIGHTNESS:
0865         if (value > max_brightness)
0866             return AE_BAD_PARAMETER;
0867         switch (quirks->brightness) {
0868         default:
0869             return ec_write(0x83, value);
0870         }
0871     default:
0872         return AE_ERROR;
0873     }
0874 
0875     /* Actually do the set */
0876     return wmab_execute(&args, NULL);
0877 }
0878 
0879 static acpi_status __init AMW0_find_mailled(void)
0880 {
0881     struct wmab_args args;
0882     struct wmab_ret ret;
0883     acpi_status status = AE_OK;
0884     struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
0885     union acpi_object *obj;
0886 
0887     args.eax = 0x86;
0888     args.ebx = args.ecx = args.edx = 0;
0889 
0890     status = wmab_execute(&args, &out);
0891     if (ACPI_FAILURE(status))
0892         return status;
0893 
0894     obj = (union acpi_object *) out.pointer;
0895     if (obj && obj->type == ACPI_TYPE_BUFFER &&
0896     obj->buffer.length == sizeof(struct wmab_ret)) {
0897         ret = *((struct wmab_ret *) obj->buffer.pointer);
0898     } else {
0899         kfree(out.pointer);
0900         return AE_ERROR;
0901     }
0902 
0903     if (ret.eex & 0x1)
0904         interface->capability |= ACER_CAP_MAILLED;
0905 
0906     kfree(out.pointer);
0907 
0908     return AE_OK;
0909 }
0910 
0911 static const struct acpi_device_id norfkill_ids[] __initconst = {
0912     { "VPC2004", 0},
0913     { "IBM0068", 0},
0914     { "LEN0068", 0},
0915     { "SNY5001", 0},    /* sony-laptop in charge */
0916     { "HPQ6601", 0},
0917     { "", 0},
0918 };
0919 
0920 static int __init AMW0_set_cap_acpi_check_device(void)
0921 {
0922     const struct acpi_device_id *id;
0923 
0924     for (id = norfkill_ids; id->id[0]; id++)
0925         if (acpi_dev_found(id->id))
0926             return true;
0927 
0928     return false;
0929 }
0930 
0931 static acpi_status __init AMW0_set_capabilities(void)
0932 {
0933     struct wmab_args args;
0934     struct wmab_ret ret;
0935     acpi_status status;
0936     struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
0937     union acpi_object *obj;
0938 
0939     /*
0940      * On laptops with this strange GUID (non Acer), normal probing doesn't
0941      * work.
0942      */
0943     if (wmi_has_guid(AMW0_GUID2)) {
0944         if ((quirks != &quirk_unknown) ||
0945             !AMW0_set_cap_acpi_check_device())
0946             interface->capability |= ACER_CAP_WIRELESS;
0947         return AE_OK;
0948     }
0949 
0950     args.eax = ACER_AMW0_WRITE;
0951     args.ecx = args.edx = 0;
0952 
0953     args.ebx = 0xa2 << 8;
0954     args.ebx |= ACER_AMW0_WIRELESS_MASK;
0955 
0956     status = wmab_execute(&args, &out);
0957     if (ACPI_FAILURE(status))
0958         return status;
0959 
0960     obj = out.pointer;
0961     if (obj && obj->type == ACPI_TYPE_BUFFER &&
0962     obj->buffer.length == sizeof(struct wmab_ret)) {
0963         ret = *((struct wmab_ret *) obj->buffer.pointer);
0964     } else {
0965         status = AE_ERROR;
0966         goto out;
0967     }
0968 
0969     if (ret.eax & 0x1)
0970         interface->capability |= ACER_CAP_WIRELESS;
0971 
0972     args.ebx = 2 << 8;
0973     args.ebx |= ACER_AMW0_BLUETOOTH_MASK;
0974 
0975     /*
0976      * It's ok to use existing buffer for next wmab_execute call.
0977      * But we need to kfree(out.pointer) if next wmab_execute fail.
0978      */
0979     status = wmab_execute(&args, &out);
0980     if (ACPI_FAILURE(status))
0981         goto out;
0982 
0983     obj = (union acpi_object *) out.pointer;
0984     if (obj && obj->type == ACPI_TYPE_BUFFER
0985     && obj->buffer.length == sizeof(struct wmab_ret)) {
0986         ret = *((struct wmab_ret *) obj->buffer.pointer);
0987     } else {
0988         status = AE_ERROR;
0989         goto out;
0990     }
0991 
0992     if (ret.eax & 0x1)
0993         interface->capability |= ACER_CAP_BLUETOOTH;
0994 
0995     /*
0996      * This appears to be safe to enable, since all Wistron based laptops
0997      * appear to use the same EC register for brightness, even if they
0998      * differ for wireless, etc
0999      */
1000     if (quirks->brightness >= 0)
1001         interface->capability |= ACER_CAP_BRIGHTNESS;
1002 
1003     status = AE_OK;
1004 out:
1005     kfree(out.pointer);
1006     return status;
1007 }
1008 
1009 static struct wmi_interface AMW0_interface = {
1010     .type = ACER_AMW0,
1011 };
1012 
1013 static struct wmi_interface AMW0_V2_interface = {
1014     .type = ACER_AMW0_V2,
1015 };
1016 
1017 /*
1018  * New interface (The WMID interface)
1019  */
1020 static acpi_status
1021 WMI_execute_u32(u32 method_id, u32 in, u32 *out)
1022 {
1023     struct acpi_buffer input = { (acpi_size) sizeof(u32), (void *)(&in) };
1024     struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL };
1025     union acpi_object *obj;
1026     u32 tmp = 0;
1027     acpi_status status;
1028 
1029     status = wmi_evaluate_method(WMID_GUID1, 0, method_id, &input, &result);
1030 
1031     if (ACPI_FAILURE(status))
1032         return status;
1033 
1034     obj = (union acpi_object *) result.pointer;
1035     if (obj) {
1036         if (obj->type == ACPI_TYPE_BUFFER &&
1037             (obj->buffer.length == sizeof(u32) ||
1038             obj->buffer.length == sizeof(u64))) {
1039             tmp = *((u32 *) obj->buffer.pointer);
1040         } else if (obj->type == ACPI_TYPE_INTEGER) {
1041             tmp = (u32) obj->integer.value;
1042         }
1043     }
1044 
1045     if (out)
1046         *out = tmp;
1047 
1048     kfree(result.pointer);
1049 
1050     return status;
1051 }
1052 
1053 static acpi_status WMID_get_u32(u32 *value, u32 cap)
1054 {
1055     acpi_status status;
1056     u8 tmp;
1057     u32 result, method_id = 0;
1058 
1059     switch (cap) {
1060     case ACER_CAP_WIRELESS:
1061         method_id = ACER_WMID_GET_WIRELESS_METHODID;
1062         break;
1063     case ACER_CAP_BLUETOOTH:
1064         method_id = ACER_WMID_GET_BLUETOOTH_METHODID;
1065         break;
1066     case ACER_CAP_BRIGHTNESS:
1067         method_id = ACER_WMID_GET_BRIGHTNESS_METHODID;
1068         break;
1069     case ACER_CAP_THREEG:
1070         method_id = ACER_WMID_GET_THREEG_METHODID;
1071         break;
1072     case ACER_CAP_MAILLED:
1073         if (quirks->mailled == 1) {
1074             ec_read(0x9f, &tmp);
1075             *value = tmp & 0x1;
1076             return 0;
1077         }
1078         fallthrough;
1079     default:
1080         return AE_ERROR;
1081     }
1082     status = WMI_execute_u32(method_id, 0, &result);
1083 
1084     if (ACPI_SUCCESS(status))
1085         *value = (u8)result;
1086 
1087     return status;
1088 }
1089 
1090 static acpi_status WMID_set_u32(u32 value, u32 cap)
1091 {
1092     u32 method_id = 0;
1093     char param;
1094 
1095     switch (cap) {
1096     case ACER_CAP_BRIGHTNESS:
1097         if (value > max_brightness)
1098             return AE_BAD_PARAMETER;
1099         method_id = ACER_WMID_SET_BRIGHTNESS_METHODID;
1100         break;
1101     case ACER_CAP_WIRELESS:
1102         if (value > 1)
1103             return AE_BAD_PARAMETER;
1104         method_id = ACER_WMID_SET_WIRELESS_METHODID;
1105         break;
1106     case ACER_CAP_BLUETOOTH:
1107         if (value > 1)
1108             return AE_BAD_PARAMETER;
1109         method_id = ACER_WMID_SET_BLUETOOTH_METHODID;
1110         break;
1111     case ACER_CAP_THREEG:
1112         if (value > 1)
1113             return AE_BAD_PARAMETER;
1114         method_id = ACER_WMID_SET_THREEG_METHODID;
1115         break;
1116     case ACER_CAP_MAILLED:
1117         if (value > 1)
1118             return AE_BAD_PARAMETER;
1119         if (quirks->mailled == 1) {
1120             param = value ? 0x92 : 0x93;
1121             i8042_lock_chip();
1122             i8042_command(&param, 0x1059);
1123             i8042_unlock_chip();
1124             return 0;
1125         }
1126         break;
1127     default:
1128         return AE_ERROR;
1129     }
1130     return WMI_execute_u32(method_id, (u32)value, NULL);
1131 }
1132 
1133 static acpi_status wmid3_get_device_status(u32 *value, u16 device)
1134 {
1135     struct wmid3_gds_return_value return_value;
1136     acpi_status status;
1137     union acpi_object *obj;
1138     struct wmid3_gds_get_input_param params = {
1139         .function_num = 0x1,
1140         .hotkey_number = commun_fn_key_number,
1141         .devices = device,
1142     };
1143     struct acpi_buffer input = {
1144         sizeof(struct wmid3_gds_get_input_param),
1145         &params
1146     };
1147     struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
1148 
1149     status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output);
1150     if (ACPI_FAILURE(status))
1151         return status;
1152 
1153     obj = output.pointer;
1154 
1155     if (!obj)
1156         return AE_ERROR;
1157     else if (obj->type != ACPI_TYPE_BUFFER) {
1158         kfree(obj);
1159         return AE_ERROR;
1160     }
1161     if (obj->buffer.length != 8) {
1162         pr_warn("Unknown buffer length %d\n", obj->buffer.length);
1163         kfree(obj);
1164         return AE_ERROR;
1165     }
1166 
1167     return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
1168     kfree(obj);
1169 
1170     if (return_value.error_code || return_value.ec_return_value)
1171         pr_warn("Get 0x%x Device Status failed: 0x%x - 0x%x\n",
1172             device,
1173             return_value.error_code,
1174             return_value.ec_return_value);
1175     else
1176         *value = !!(return_value.devices & device);
1177 
1178     return status;
1179 }
1180 
1181 static acpi_status wmid_v2_get_u32(u32 *value, u32 cap)
1182 {
1183     u16 device;
1184 
1185     switch (cap) {
1186     case ACER_CAP_WIRELESS:
1187         device = ACER_WMID3_GDS_WIRELESS;
1188         break;
1189     case ACER_CAP_BLUETOOTH:
1190         device = ACER_WMID3_GDS_BLUETOOTH;
1191         break;
1192     case ACER_CAP_THREEG:
1193         device = ACER_WMID3_GDS_THREEG;
1194         break;
1195     default:
1196         return AE_ERROR;
1197     }
1198     return wmid3_get_device_status(value, device);
1199 }
1200 
1201 static acpi_status wmid3_set_device_status(u32 value, u16 device)
1202 {
1203     struct wmid3_gds_return_value return_value;
1204     acpi_status status;
1205     union acpi_object *obj;
1206     u16 devices;
1207     struct wmid3_gds_get_input_param get_params = {
1208         .function_num = 0x1,
1209         .hotkey_number = commun_fn_key_number,
1210         .devices = commun_func_bitmap,
1211     };
1212     struct acpi_buffer get_input = {
1213         sizeof(struct wmid3_gds_get_input_param),
1214         &get_params
1215     };
1216     struct wmid3_gds_set_input_param set_params = {
1217         .function_num = 0x2,
1218         .hotkey_number = commun_fn_key_number,
1219         .devices = commun_func_bitmap,
1220     };
1221     struct acpi_buffer set_input = {
1222         sizeof(struct wmid3_gds_set_input_param),
1223         &set_params
1224     };
1225     struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
1226     struct acpi_buffer output2 = { ACPI_ALLOCATE_BUFFER, NULL };
1227 
1228     status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &get_input, &output);
1229     if (ACPI_FAILURE(status))
1230         return status;
1231 
1232     obj = output.pointer;
1233 
1234     if (!obj)
1235         return AE_ERROR;
1236     else if (obj->type != ACPI_TYPE_BUFFER) {
1237         kfree(obj);
1238         return AE_ERROR;
1239     }
1240     if (obj->buffer.length != 8) {
1241         pr_warn("Unknown buffer length %d\n", obj->buffer.length);
1242         kfree(obj);
1243         return AE_ERROR;
1244     }
1245 
1246     return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
1247     kfree(obj);
1248 
1249     if (return_value.error_code || return_value.ec_return_value) {
1250         pr_warn("Get Current Device Status failed: 0x%x - 0x%x\n",
1251             return_value.error_code,
1252             return_value.ec_return_value);
1253         return status;
1254     }
1255 
1256     devices = return_value.devices;
1257     set_params.devices = (value) ? (devices | device) : (devices & ~device);
1258 
1259     status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &set_input, &output2);
1260     if (ACPI_FAILURE(status))
1261         return status;
1262 
1263     obj = output2.pointer;
1264 
1265     if (!obj)
1266         return AE_ERROR;
1267     else if (obj->type != ACPI_TYPE_BUFFER) {
1268         kfree(obj);
1269         return AE_ERROR;
1270     }
1271     if (obj->buffer.length != 4) {
1272         pr_warn("Unknown buffer length %d\n", obj->buffer.length);
1273         kfree(obj);
1274         return AE_ERROR;
1275     }
1276 
1277     return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
1278     kfree(obj);
1279 
1280     if (return_value.error_code || return_value.ec_return_value)
1281         pr_warn("Set Device Status failed: 0x%x - 0x%x\n",
1282             return_value.error_code,
1283             return_value.ec_return_value);
1284 
1285     return status;
1286 }
1287 
1288 static acpi_status wmid_v2_set_u32(u32 value, u32 cap)
1289 {
1290     u16 device;
1291 
1292     switch (cap) {
1293     case ACER_CAP_WIRELESS:
1294         device = ACER_WMID3_GDS_WIRELESS;
1295         break;
1296     case ACER_CAP_BLUETOOTH:
1297         device = ACER_WMID3_GDS_BLUETOOTH;
1298         break;
1299     case ACER_CAP_THREEG:
1300         device = ACER_WMID3_GDS_THREEG;
1301         break;
1302     default:
1303         return AE_ERROR;
1304     }
1305     return wmid3_set_device_status(value, device);
1306 }
1307 
1308 static void __init type_aa_dmi_decode(const struct dmi_header *header, void *d)
1309 {
1310     struct hotkey_function_type_aa *type_aa;
1311 
1312     /* We are looking for OEM-specific Type AAh */
1313     if (header->type != 0xAA)
1314         return;
1315 
1316     has_type_aa = true;
1317     type_aa = (struct hotkey_function_type_aa *) header;
1318 
1319     pr_info("Function bitmap for Communication Button: 0x%x\n",
1320         type_aa->commun_func_bitmap);
1321     commun_func_bitmap = type_aa->commun_func_bitmap;
1322 
1323     if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_WIRELESS)
1324         interface->capability |= ACER_CAP_WIRELESS;
1325     if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_THREEG)
1326         interface->capability |= ACER_CAP_THREEG;
1327     if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_BLUETOOTH)
1328         interface->capability |= ACER_CAP_BLUETOOTH;
1329     if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN)
1330         commun_func_bitmap &= ~ACER_WMID3_GDS_RFBTN;
1331 
1332     commun_fn_key_number = type_aa->commun_fn_key_number;
1333 }
1334 
1335 static acpi_status __init WMID_set_capabilities(void)
1336 {
1337     struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
1338     union acpi_object *obj;
1339     acpi_status status;
1340     u32 devices;
1341 
1342     status = wmi_query_block(WMID_GUID2, 0, &out);
1343     if (ACPI_FAILURE(status))
1344         return status;
1345 
1346     obj = (union acpi_object *) out.pointer;
1347     if (obj) {
1348         if (obj->type == ACPI_TYPE_BUFFER &&
1349             (obj->buffer.length == sizeof(u32) ||
1350             obj->buffer.length == sizeof(u64))) {
1351             devices = *((u32 *) obj->buffer.pointer);
1352         } else if (obj->type == ACPI_TYPE_INTEGER) {
1353             devices = (u32) obj->integer.value;
1354         } else {
1355             kfree(out.pointer);
1356             return AE_ERROR;
1357         }
1358     } else {
1359         kfree(out.pointer);
1360         return AE_ERROR;
1361     }
1362 
1363     pr_info("Function bitmap for Communication Device: 0x%x\n", devices);
1364     if (devices & 0x07)
1365         interface->capability |= ACER_CAP_WIRELESS;
1366     if (devices & 0x40)
1367         interface->capability |= ACER_CAP_THREEG;
1368     if (devices & 0x10)
1369         interface->capability |= ACER_CAP_BLUETOOTH;
1370 
1371     if (!(devices & 0x20))
1372         max_brightness = 0x9;
1373 
1374     kfree(out.pointer);
1375     return status;
1376 }
1377 
1378 static struct wmi_interface wmid_interface = {
1379     .type = ACER_WMID,
1380 };
1381 
1382 static struct wmi_interface wmid_v2_interface = {
1383     .type = ACER_WMID_v2,
1384 };
1385 
1386 /*
1387  * WMID Gaming interface
1388  */
1389 
1390 static acpi_status
1391 WMI_gaming_execute_u64(u32 method_id, u64 in, u64 *out)
1392 {
1393     struct acpi_buffer input = { (acpi_size) sizeof(u64), (void *)(&in) };
1394     struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL };
1395     union acpi_object *obj;
1396     u32 tmp = 0;
1397     acpi_status status;
1398 
1399     status = wmi_evaluate_method(WMID_GUID4, 0, method_id, &input, &result);
1400 
1401     if (ACPI_FAILURE(status))
1402         return status;
1403     obj = (union acpi_object *) result.pointer;
1404 
1405     if (obj) {
1406         if (obj->type == ACPI_TYPE_BUFFER) {
1407             if (obj->buffer.length == sizeof(u32))
1408                 tmp = *((u32 *) obj->buffer.pointer);
1409             else if (obj->buffer.length == sizeof(u64))
1410                 tmp = *((u64 *) obj->buffer.pointer);
1411         } else if (obj->type == ACPI_TYPE_INTEGER) {
1412             tmp = (u64) obj->integer.value;
1413         }
1414     }
1415 
1416     if (out)
1417         *out = tmp;
1418 
1419     kfree(result.pointer);
1420 
1421     return status;
1422 }
1423 
1424 static acpi_status WMID_gaming_set_u64(u64 value, u32 cap)
1425 {
1426     u32 method_id = 0;
1427 
1428     if (!(interface->capability & cap))
1429         return AE_BAD_PARAMETER;
1430 
1431     switch (cap) {
1432     case ACER_CAP_TURBO_LED:
1433         method_id = ACER_WMID_SET_GAMING_LED_METHODID;
1434         break;
1435     case ACER_CAP_TURBO_FAN:
1436         method_id = ACER_WMID_SET_GAMING_FAN_BEHAVIOR;
1437         break;
1438     case ACER_CAP_TURBO_OC:
1439         method_id = ACER_WMID_SET_GAMING_MISC_SETTING_METHODID;
1440         break;
1441     default:
1442         return AE_BAD_PARAMETER;
1443     }
1444 
1445     return WMI_gaming_execute_u64(method_id, value, NULL);
1446 }
1447 
1448 static acpi_status WMID_gaming_get_u64(u64 *value, u32 cap)
1449 {
1450     acpi_status status;
1451     u64 result;
1452     u64 input;
1453     u32 method_id;
1454 
1455     if (!(interface->capability & cap))
1456         return AE_BAD_PARAMETER;
1457 
1458     switch (cap) {
1459     case ACER_CAP_TURBO_LED:
1460         method_id = ACER_WMID_GET_GAMING_LED_METHODID;
1461         input = 0x1;
1462         break;
1463     default:
1464         return AE_BAD_PARAMETER;
1465     }
1466     status = WMI_gaming_execute_u64(method_id, input, &result);
1467     if (ACPI_SUCCESS(status))
1468         *value = (u64) result;
1469 
1470     return status;
1471 }
1472 
1473 static void WMID_gaming_set_fan_mode(u8 fan_mode)
1474 {
1475     /* fan_mode = 1 is used for auto, fan_mode = 2 used for turbo*/
1476     u64 gpu_fan_config1 = 0, gpu_fan_config2 = 0;
1477     int i;
1478 
1479     if (quirks->cpu_fans > 0)
1480         gpu_fan_config2 |= 1;
1481     for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
1482         gpu_fan_config2 |= 1 << (i + 1);
1483     for (i = 0; i < quirks->gpu_fans; ++i)
1484         gpu_fan_config2 |= 1 << (i + 3);
1485     if (quirks->cpu_fans > 0)
1486         gpu_fan_config1 |= fan_mode;
1487     for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
1488         gpu_fan_config1 |= fan_mode << (2 * i + 2);
1489     for (i = 0; i < quirks->gpu_fans; ++i)
1490         gpu_fan_config1 |= fan_mode << (2 * i + 6);
1491     WMID_gaming_set_u64(gpu_fan_config2 | gpu_fan_config1 << 16, ACER_CAP_TURBO_FAN);
1492 }
1493 
1494 /*
1495  * Generic Device (interface-independent)
1496  */
1497 
1498 static acpi_status get_u32(u32 *value, u32 cap)
1499 {
1500     acpi_status status = AE_ERROR;
1501 
1502     switch (interface->type) {
1503     case ACER_AMW0:
1504         status = AMW0_get_u32(value, cap);
1505         break;
1506     case ACER_AMW0_V2:
1507         if (cap == ACER_CAP_MAILLED) {
1508             status = AMW0_get_u32(value, cap);
1509             break;
1510         }
1511         fallthrough;
1512     case ACER_WMID:
1513         status = WMID_get_u32(value, cap);
1514         break;
1515     case ACER_WMID_v2:
1516         if (cap & (ACER_CAP_WIRELESS |
1517                ACER_CAP_BLUETOOTH |
1518                ACER_CAP_THREEG))
1519             status = wmid_v2_get_u32(value, cap);
1520         else if (wmi_has_guid(WMID_GUID2))
1521             status = WMID_get_u32(value, cap);
1522         break;
1523     }
1524 
1525     return status;
1526 }
1527 
1528 static acpi_status set_u32(u32 value, u32 cap)
1529 {
1530     acpi_status status;
1531 
1532     if (interface->capability & cap) {
1533         switch (interface->type) {
1534         case ACER_AMW0:
1535             return AMW0_set_u32(value, cap);
1536         case ACER_AMW0_V2:
1537             if (cap == ACER_CAP_MAILLED)
1538                 return AMW0_set_u32(value, cap);
1539 
1540             /*
1541              * On some models, some WMID methods don't toggle
1542              * properly. For those cases, we want to run the AMW0
1543              * method afterwards to be certain we've really toggled
1544              * the device state.
1545              */
1546             if (cap == ACER_CAP_WIRELESS ||
1547                 cap == ACER_CAP_BLUETOOTH) {
1548                 status = WMID_set_u32(value, cap);
1549                 if (ACPI_FAILURE(status))
1550                     return status;
1551 
1552                 return AMW0_set_u32(value, cap);
1553             }
1554             fallthrough;
1555         case ACER_WMID:
1556             return WMID_set_u32(value, cap);
1557         case ACER_WMID_v2:
1558             if (cap & (ACER_CAP_WIRELESS |
1559                    ACER_CAP_BLUETOOTH |
1560                    ACER_CAP_THREEG))
1561                 return wmid_v2_set_u32(value, cap);
1562             else if (wmi_has_guid(WMID_GUID2))
1563                 return WMID_set_u32(value, cap);
1564             fallthrough;
1565         default:
1566             return AE_BAD_PARAMETER;
1567         }
1568     }
1569     return AE_BAD_PARAMETER;
1570 }
1571 
1572 static void __init acer_commandline_init(void)
1573 {
1574     /*
1575      * These will all fail silently if the value given is invalid, or the
1576      * capability isn't available on the given interface
1577      */
1578     if (mailled >= 0)
1579         set_u32(mailled, ACER_CAP_MAILLED);
1580     if (!has_type_aa && threeg >= 0)
1581         set_u32(threeg, ACER_CAP_THREEG);
1582     if (brightness >= 0)
1583         set_u32(brightness, ACER_CAP_BRIGHTNESS);
1584 }
1585 
1586 /*
1587  * LED device (Mail LED only, no other LEDs known yet)
1588  */
1589 static void mail_led_set(struct led_classdev *led_cdev,
1590 enum led_brightness value)
1591 {
1592     set_u32(value, ACER_CAP_MAILLED);
1593 }
1594 
1595 static struct led_classdev mail_led = {
1596     .name = "acer-wmi::mail",
1597     .brightness_set = mail_led_set,
1598 };
1599 
1600 static int acer_led_init(struct device *dev)
1601 {
1602     return led_classdev_register(dev, &mail_led);
1603 }
1604 
1605 static void acer_led_exit(void)
1606 {
1607     set_u32(LED_OFF, ACER_CAP_MAILLED);
1608     led_classdev_unregister(&mail_led);
1609 }
1610 
1611 /*
1612  * Backlight device
1613  */
1614 static struct backlight_device *acer_backlight_device;
1615 
1616 static int read_brightness(struct backlight_device *bd)
1617 {
1618     u32 value;
1619     get_u32(&value, ACER_CAP_BRIGHTNESS);
1620     return value;
1621 }
1622 
1623 static int update_bl_status(struct backlight_device *bd)
1624 {
1625     int intensity = backlight_get_brightness(bd);
1626 
1627     set_u32(intensity, ACER_CAP_BRIGHTNESS);
1628 
1629     return 0;
1630 }
1631 
1632 static const struct backlight_ops acer_bl_ops = {
1633     .get_brightness = read_brightness,
1634     .update_status = update_bl_status,
1635 };
1636 
1637 static int acer_backlight_init(struct device *dev)
1638 {
1639     struct backlight_properties props;
1640     struct backlight_device *bd;
1641 
1642     memset(&props, 0, sizeof(struct backlight_properties));
1643     props.type = BACKLIGHT_PLATFORM;
1644     props.max_brightness = max_brightness;
1645     bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops,
1646                        &props);
1647     if (IS_ERR(bd)) {
1648         pr_err("Could not register Acer backlight device\n");
1649         acer_backlight_device = NULL;
1650         return PTR_ERR(bd);
1651     }
1652 
1653     acer_backlight_device = bd;
1654 
1655     bd->props.power = FB_BLANK_UNBLANK;
1656     bd->props.brightness = read_brightness(bd);
1657     backlight_update_status(bd);
1658     return 0;
1659 }
1660 
1661 static void acer_backlight_exit(void)
1662 {
1663     backlight_device_unregister(acer_backlight_device);
1664 }
1665 
1666 /*
1667  * Accelerometer device
1668  */
1669 static acpi_handle gsensor_handle;
1670 
1671 static int acer_gsensor_init(void)
1672 {
1673     acpi_status status;
1674     struct acpi_buffer output;
1675     union acpi_object out_obj;
1676 
1677     output.length = sizeof(out_obj);
1678     output.pointer = &out_obj;
1679     status = acpi_evaluate_object(gsensor_handle, "_INI", NULL, &output);
1680     if (ACPI_FAILURE(status))
1681         return -1;
1682 
1683     return 0;
1684 }
1685 
1686 static int acer_gsensor_open(struct input_dev *input)
1687 {
1688     return acer_gsensor_init();
1689 }
1690 
1691 static int acer_gsensor_event(void)
1692 {
1693     acpi_status status;
1694     struct acpi_buffer output;
1695     union acpi_object out_obj[5];
1696 
1697     if (!acer_wmi_accel_dev)
1698         return -1;
1699 
1700     output.length = sizeof(out_obj);
1701     output.pointer = out_obj;
1702 
1703     status = acpi_evaluate_object(gsensor_handle, "RDVL", NULL, &output);
1704     if (ACPI_FAILURE(status))
1705         return -1;
1706 
1707     if (out_obj->package.count != 4)
1708         return -1;
1709 
1710     input_report_abs(acer_wmi_accel_dev, ABS_X,
1711         (s16)out_obj->package.elements[0].integer.value);
1712     input_report_abs(acer_wmi_accel_dev, ABS_Y,
1713         (s16)out_obj->package.elements[1].integer.value);
1714     input_report_abs(acer_wmi_accel_dev, ABS_Z,
1715         (s16)out_obj->package.elements[2].integer.value);
1716     input_sync(acer_wmi_accel_dev);
1717     return 0;
1718 }
1719 
1720 /*
1721  *  Predator series turbo button
1722  */
1723 static int acer_toggle_turbo(void)
1724 {
1725     u64 turbo_led_state;
1726 
1727     /* Get current state from turbo button */
1728     if (ACPI_FAILURE(WMID_gaming_get_u64(&turbo_led_state, ACER_CAP_TURBO_LED)))
1729         return -1;
1730 
1731     if (turbo_led_state) {
1732         /* Turn off turbo led */
1733         WMID_gaming_set_u64(0x1, ACER_CAP_TURBO_LED);
1734 
1735         /* Set FAN mode to auto */
1736         WMID_gaming_set_fan_mode(0x1);
1737 
1738         /* Set OC to normal */
1739         WMID_gaming_set_u64(0x5, ACER_CAP_TURBO_OC);
1740         WMID_gaming_set_u64(0x7, ACER_CAP_TURBO_OC);
1741     } else {
1742         /* Turn on turbo led */
1743         WMID_gaming_set_u64(0x10001, ACER_CAP_TURBO_LED);
1744 
1745         /* Set FAN mode to turbo */
1746         WMID_gaming_set_fan_mode(0x2);
1747 
1748         /* Set OC to turbo mode */
1749         WMID_gaming_set_u64(0x205, ACER_CAP_TURBO_OC);
1750         WMID_gaming_set_u64(0x207, ACER_CAP_TURBO_OC);
1751     }
1752     return turbo_led_state;
1753 }
1754 
1755 /*
1756  * Switch series keyboard dock status
1757  */
1758 static int acer_kbd_dock_state_to_sw_tablet_mode(u8 kbd_dock_state)
1759 {
1760     switch (kbd_dock_state) {
1761     case 0x01: /* Docked, traditional clamshell laptop mode */
1762         return 0;
1763     case 0x04: /* Stand-alone tablet */
1764     case 0x40: /* Docked, tent mode, keyboard not usable */
1765         return 1;
1766     default:
1767         pr_warn("Unknown kbd_dock_state 0x%02x\n", kbd_dock_state);
1768     }
1769 
1770     return 0;
1771 }
1772 
1773 static void acer_kbd_dock_get_initial_state(void)
1774 {
1775     u8 *output, input[8] = { 0x05, 0x00, };
1776     struct acpi_buffer input_buf = { sizeof(input), input };
1777     struct acpi_buffer output_buf = { ACPI_ALLOCATE_BUFFER, NULL };
1778     union acpi_object *obj;
1779     acpi_status status;
1780     int sw_tablet_mode;
1781 
1782     status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input_buf, &output_buf);
1783     if (ACPI_FAILURE(status)) {
1784         pr_err("Error getting keyboard-dock initial status: %s\n",
1785                acpi_format_exception(status));
1786         return;
1787     }
1788 
1789     obj = output_buf.pointer;
1790     if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) {
1791         pr_err("Unexpected output format getting keyboard-dock initial status\n");
1792         goto out_free_obj;
1793     }
1794 
1795     output = obj->buffer.pointer;
1796     if (output[0] != 0x00 || (output[3] != 0x05 && output[3] != 0x45)) {
1797         pr_err("Unexpected output [0]=0x%02x [3]=0x%02x getting keyboard-dock initial status\n",
1798                output[0], output[3]);
1799         goto out_free_obj;
1800     }
1801 
1802     sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(output[4]);
1803     input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode);
1804 
1805 out_free_obj:
1806     kfree(obj);
1807 }
1808 
1809 static void acer_kbd_dock_event(const struct event_return_value *event)
1810 {
1811     int sw_tablet_mode;
1812 
1813     if (!has_cap(ACER_CAP_KBD_DOCK))
1814         return;
1815 
1816     sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(event->kbd_dock_state);
1817     input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode);
1818     input_sync(acer_wmi_input_dev);
1819 }
1820 
1821 /*
1822  * Rfkill devices
1823  */
1824 static void acer_rfkill_update(struct work_struct *ignored);
1825 static DECLARE_DELAYED_WORK(acer_rfkill_work, acer_rfkill_update);
1826 static void acer_rfkill_update(struct work_struct *ignored)
1827 {
1828     u32 state;
1829     acpi_status status;
1830 
1831     if (has_cap(ACER_CAP_WIRELESS)) {
1832         status = get_u32(&state, ACER_CAP_WIRELESS);
1833         if (ACPI_SUCCESS(status)) {
1834             if (quirks->wireless == 3)
1835                 rfkill_set_hw_state(wireless_rfkill, !state);
1836             else
1837                 rfkill_set_sw_state(wireless_rfkill, !state);
1838         }
1839     }
1840 
1841     if (has_cap(ACER_CAP_BLUETOOTH)) {
1842         status = get_u32(&state, ACER_CAP_BLUETOOTH);
1843         if (ACPI_SUCCESS(status))
1844             rfkill_set_sw_state(bluetooth_rfkill, !state);
1845     }
1846 
1847     if (has_cap(ACER_CAP_THREEG) && wmi_has_guid(WMID_GUID3)) {
1848         status = get_u32(&state, ACER_WMID3_GDS_THREEG);
1849         if (ACPI_SUCCESS(status))
1850             rfkill_set_sw_state(threeg_rfkill, !state);
1851     }
1852 
1853     schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
1854 }
1855 
1856 static int acer_rfkill_set(void *data, bool blocked)
1857 {
1858     acpi_status status;
1859     u32 cap = (unsigned long)data;
1860 
1861     if (rfkill_inited) {
1862         status = set_u32(!blocked, cap);
1863         if (ACPI_FAILURE(status))
1864             return -ENODEV;
1865     }
1866 
1867     return 0;
1868 }
1869 
1870 static const struct rfkill_ops acer_rfkill_ops = {
1871     .set_block = acer_rfkill_set,
1872 };
1873 
1874 static struct rfkill *acer_rfkill_register(struct device *dev,
1875                        enum rfkill_type type,
1876                        char *name, u32 cap)
1877 {
1878     int err;
1879     struct rfkill *rfkill_dev;
1880     u32 state;
1881     acpi_status status;
1882 
1883     rfkill_dev = rfkill_alloc(name, dev, type,
1884                   &acer_rfkill_ops,
1885                   (void *)(unsigned long)cap);
1886     if (!rfkill_dev)
1887         return ERR_PTR(-ENOMEM);
1888 
1889     status = get_u32(&state, cap);
1890 
1891     err = rfkill_register(rfkill_dev);
1892     if (err) {
1893         rfkill_destroy(rfkill_dev);
1894         return ERR_PTR(err);
1895     }
1896 
1897     if (ACPI_SUCCESS(status))
1898         rfkill_set_sw_state(rfkill_dev, !state);
1899 
1900     return rfkill_dev;
1901 }
1902 
1903 static int acer_rfkill_init(struct device *dev)
1904 {
1905     int err;
1906 
1907     if (has_cap(ACER_CAP_WIRELESS)) {
1908         wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN,
1909             "acer-wireless", ACER_CAP_WIRELESS);
1910         if (IS_ERR(wireless_rfkill)) {
1911             err = PTR_ERR(wireless_rfkill);
1912             goto error_wireless;
1913         }
1914     }
1915 
1916     if (has_cap(ACER_CAP_BLUETOOTH)) {
1917         bluetooth_rfkill = acer_rfkill_register(dev,
1918             RFKILL_TYPE_BLUETOOTH, "acer-bluetooth",
1919             ACER_CAP_BLUETOOTH);
1920         if (IS_ERR(bluetooth_rfkill)) {
1921             err = PTR_ERR(bluetooth_rfkill);
1922             goto error_bluetooth;
1923         }
1924     }
1925 
1926     if (has_cap(ACER_CAP_THREEG)) {
1927         threeg_rfkill = acer_rfkill_register(dev,
1928             RFKILL_TYPE_WWAN, "acer-threeg",
1929             ACER_CAP_THREEG);
1930         if (IS_ERR(threeg_rfkill)) {
1931             err = PTR_ERR(threeg_rfkill);
1932             goto error_threeg;
1933         }
1934     }
1935 
1936     rfkill_inited = true;
1937 
1938     if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) &&
1939         has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG))
1940         schedule_delayed_work(&acer_rfkill_work,
1941             round_jiffies_relative(HZ));
1942 
1943     return 0;
1944 
1945 error_threeg:
1946     if (has_cap(ACER_CAP_BLUETOOTH)) {
1947         rfkill_unregister(bluetooth_rfkill);
1948         rfkill_destroy(bluetooth_rfkill);
1949     }
1950 error_bluetooth:
1951     if (has_cap(ACER_CAP_WIRELESS)) {
1952         rfkill_unregister(wireless_rfkill);
1953         rfkill_destroy(wireless_rfkill);
1954     }
1955 error_wireless:
1956     return err;
1957 }
1958 
1959 static void acer_rfkill_exit(void)
1960 {
1961     if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) &&
1962         has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG))
1963         cancel_delayed_work_sync(&acer_rfkill_work);
1964 
1965     if (has_cap(ACER_CAP_WIRELESS)) {
1966         rfkill_unregister(wireless_rfkill);
1967         rfkill_destroy(wireless_rfkill);
1968     }
1969 
1970     if (has_cap(ACER_CAP_BLUETOOTH)) {
1971         rfkill_unregister(bluetooth_rfkill);
1972         rfkill_destroy(bluetooth_rfkill);
1973     }
1974 
1975     if (has_cap(ACER_CAP_THREEG)) {
1976         rfkill_unregister(threeg_rfkill);
1977         rfkill_destroy(threeg_rfkill);
1978     }
1979     return;
1980 }
1981 
1982 static void acer_wmi_notify(u32 value, void *context)
1983 {
1984     struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
1985     union acpi_object *obj;
1986     struct event_return_value return_value;
1987     acpi_status status;
1988     u16 device_state;
1989     const struct key_entry *key;
1990     u32 scancode;
1991 
1992     status = wmi_get_event_data(value, &response);
1993     if (status != AE_OK) {
1994         pr_warn("bad event status 0x%x\n", status);
1995         return;
1996     }
1997 
1998     obj = (union acpi_object *)response.pointer;
1999 
2000     if (!obj)
2001         return;
2002     if (obj->type != ACPI_TYPE_BUFFER) {
2003         pr_warn("Unknown response received %d\n", obj->type);
2004         kfree(obj);
2005         return;
2006     }
2007     if (obj->buffer.length != 8) {
2008         pr_warn("Unknown buffer length %d\n", obj->buffer.length);
2009         kfree(obj);
2010         return;
2011     }
2012 
2013     return_value = *((struct event_return_value *)obj->buffer.pointer);
2014     kfree(obj);
2015 
2016     switch (return_value.function) {
2017     case WMID_HOTKEY_EVENT:
2018         device_state = return_value.device_state;
2019         pr_debug("device state: 0x%x\n", device_state);
2020 
2021         key = sparse_keymap_entry_from_scancode(acer_wmi_input_dev,
2022                             return_value.key_num);
2023         if (!key) {
2024             pr_warn("Unknown key number - 0x%x\n",
2025                 return_value.key_num);
2026         } else {
2027             scancode = return_value.key_num;
2028             switch (key->keycode) {
2029             case KEY_WLAN:
2030             case KEY_BLUETOOTH:
2031                 if (has_cap(ACER_CAP_WIRELESS))
2032                     rfkill_set_sw_state(wireless_rfkill,
2033                         !(device_state & ACER_WMID3_GDS_WIRELESS));
2034                 if (has_cap(ACER_CAP_THREEG))
2035                     rfkill_set_sw_state(threeg_rfkill,
2036                         !(device_state & ACER_WMID3_GDS_THREEG));
2037                 if (has_cap(ACER_CAP_BLUETOOTH))
2038                     rfkill_set_sw_state(bluetooth_rfkill,
2039                         !(device_state & ACER_WMID3_GDS_BLUETOOTH));
2040                 break;
2041             case KEY_TOUCHPAD_TOGGLE:
2042                 scancode = (device_state & ACER_WMID3_GDS_TOUCHPAD) ?
2043                         KEY_TOUCHPAD_ON : KEY_TOUCHPAD_OFF;
2044             }
2045             sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true);
2046         }
2047         break;
2048     case WMID_ACCEL_OR_KBD_DOCK_EVENT:
2049         acer_gsensor_event();
2050         acer_kbd_dock_event(&return_value);
2051         break;
2052     case WMID_GAMING_TURBO_KEY_EVENT:
2053         if (return_value.key_num == 0x4)
2054             acer_toggle_turbo();
2055         break;
2056     default:
2057         pr_warn("Unknown function number - %d - %d\n",
2058             return_value.function, return_value.key_num);
2059         break;
2060     }
2061 }
2062 
2063 static acpi_status __init
2064 wmid3_set_function_mode(struct func_input_params *params,
2065             struct func_return_value *return_value)
2066 {
2067     acpi_status status;
2068     union acpi_object *obj;
2069 
2070     struct acpi_buffer input = { sizeof(struct func_input_params), params };
2071     struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
2072 
2073     status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output);
2074     if (ACPI_FAILURE(status))
2075         return status;
2076 
2077     obj = output.pointer;
2078 
2079     if (!obj)
2080         return AE_ERROR;
2081     else if (obj->type != ACPI_TYPE_BUFFER) {
2082         kfree(obj);
2083         return AE_ERROR;
2084     }
2085     if (obj->buffer.length != 4) {
2086         pr_warn("Unknown buffer length %d\n", obj->buffer.length);
2087         kfree(obj);
2088         return AE_ERROR;
2089     }
2090 
2091     *return_value = *((struct func_return_value *)obj->buffer.pointer);
2092     kfree(obj);
2093 
2094     return status;
2095 }
2096 
2097 static int __init acer_wmi_enable_ec_raw(void)
2098 {
2099     struct func_return_value return_value;
2100     acpi_status status;
2101     struct func_input_params params = {
2102         .function_num = 0x1,
2103         .commun_devices = 0xFFFF,
2104         .devices = 0xFFFF,
2105         .app_status = 0x00,     /* Launch Manager Deactive */
2106         .app_mask = 0x01,
2107     };
2108 
2109     status = wmid3_set_function_mode(&params, &return_value);
2110 
2111     if (return_value.error_code || return_value.ec_return_value)
2112         pr_warn("Enabling EC raw mode failed: 0x%x - 0x%x\n",
2113             return_value.error_code,
2114             return_value.ec_return_value);
2115     else
2116         pr_info("Enabled EC raw mode\n");
2117 
2118     return status;
2119 }
2120 
2121 static int __init acer_wmi_enable_lm(void)
2122 {
2123     struct func_return_value return_value;
2124     acpi_status status;
2125     struct func_input_params params = {
2126         .function_num = 0x1,
2127         .commun_devices = 0xFFFF,
2128         .devices = 0xFFFF,
2129         .app_status = 0x01,            /* Launch Manager Active */
2130         .app_mask = 0x01,
2131     };
2132 
2133     status = wmid3_set_function_mode(&params, &return_value);
2134 
2135     if (return_value.error_code || return_value.ec_return_value)
2136         pr_warn("Enabling Launch Manager failed: 0x%x - 0x%x\n",
2137             return_value.error_code,
2138             return_value.ec_return_value);
2139 
2140     return status;
2141 }
2142 
2143 static int __init acer_wmi_enable_rf_button(void)
2144 {
2145     struct func_return_value return_value;
2146     acpi_status status;
2147     struct func_input_params params = {
2148         .function_num = 0x1,
2149         .commun_devices = 0xFFFF,
2150         .devices = 0xFFFF,
2151         .app_status = 0x10,            /* RF Button Active */
2152         .app_mask = 0x10,
2153     };
2154 
2155     status = wmid3_set_function_mode(&params, &return_value);
2156 
2157     if (return_value.error_code || return_value.ec_return_value)
2158         pr_warn("Enabling RF Button failed: 0x%x - 0x%x\n",
2159             return_value.error_code,
2160             return_value.ec_return_value);
2161 
2162     return status;
2163 }
2164 
2165 static int __init acer_wmi_accel_setup(void)
2166 {
2167     struct acpi_device *adev;
2168     int err;
2169 
2170     adev = acpi_dev_get_first_match_dev("BST0001", NULL, -1);
2171     if (!adev)
2172         return -ENODEV;
2173 
2174     gsensor_handle = acpi_device_handle(adev);
2175     acpi_dev_put(adev);
2176 
2177     acer_wmi_accel_dev = input_allocate_device();
2178     if (!acer_wmi_accel_dev)
2179         return -ENOMEM;
2180 
2181     acer_wmi_accel_dev->open = acer_gsensor_open;
2182 
2183     acer_wmi_accel_dev->name = "Acer BMA150 accelerometer";
2184     acer_wmi_accel_dev->phys = "wmi/input1";
2185     acer_wmi_accel_dev->id.bustype = BUS_HOST;
2186     acer_wmi_accel_dev->evbit[0] = BIT_MASK(EV_ABS);
2187     input_set_abs_params(acer_wmi_accel_dev, ABS_X, -16384, 16384, 0, 0);
2188     input_set_abs_params(acer_wmi_accel_dev, ABS_Y, -16384, 16384, 0, 0);
2189     input_set_abs_params(acer_wmi_accel_dev, ABS_Z, -16384, 16384, 0, 0);
2190 
2191     err = input_register_device(acer_wmi_accel_dev);
2192     if (err)
2193         goto err_free_dev;
2194 
2195     return 0;
2196 
2197 err_free_dev:
2198     input_free_device(acer_wmi_accel_dev);
2199     return err;
2200 }
2201 
2202 static int __init acer_wmi_input_setup(void)
2203 {
2204     acpi_status status;
2205     int err;
2206 
2207     acer_wmi_input_dev = input_allocate_device();
2208     if (!acer_wmi_input_dev)
2209         return -ENOMEM;
2210 
2211     acer_wmi_input_dev->name = "Acer WMI hotkeys";
2212     acer_wmi_input_dev->phys = "wmi/input0";
2213     acer_wmi_input_dev->id.bustype = BUS_HOST;
2214 
2215     err = sparse_keymap_setup(acer_wmi_input_dev, acer_wmi_keymap, NULL);
2216     if (err)
2217         goto err_free_dev;
2218 
2219     if (has_cap(ACER_CAP_KBD_DOCK))
2220         input_set_capability(acer_wmi_input_dev, EV_SW, SW_TABLET_MODE);
2221 
2222     status = wmi_install_notify_handler(ACERWMID_EVENT_GUID,
2223                         acer_wmi_notify, NULL);
2224     if (ACPI_FAILURE(status)) {
2225         err = -EIO;
2226         goto err_free_dev;
2227     }
2228 
2229     if (has_cap(ACER_CAP_KBD_DOCK))
2230         acer_kbd_dock_get_initial_state();
2231 
2232     err = input_register_device(acer_wmi_input_dev);
2233     if (err)
2234         goto err_uninstall_notifier;
2235 
2236     return 0;
2237 
2238 err_uninstall_notifier:
2239     wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
2240 err_free_dev:
2241     input_free_device(acer_wmi_input_dev);
2242     return err;
2243 }
2244 
2245 static void acer_wmi_input_destroy(void)
2246 {
2247     wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
2248     input_unregister_device(acer_wmi_input_dev);
2249 }
2250 
2251 /*
2252  * debugfs functions
2253  */
2254 static u32 get_wmid_devices(void)
2255 {
2256     struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
2257     union acpi_object *obj;
2258     acpi_status status;
2259     u32 devices = 0;
2260 
2261     status = wmi_query_block(WMID_GUID2, 0, &out);
2262     if (ACPI_FAILURE(status))
2263         return 0;
2264 
2265     obj = (union acpi_object *) out.pointer;
2266     if (obj) {
2267         if (obj->type == ACPI_TYPE_BUFFER &&
2268             (obj->buffer.length == sizeof(u32) ||
2269             obj->buffer.length == sizeof(u64))) {
2270             devices = *((u32 *) obj->buffer.pointer);
2271         } else if (obj->type == ACPI_TYPE_INTEGER) {
2272             devices = (u32) obj->integer.value;
2273         }
2274     }
2275 
2276     kfree(out.pointer);
2277     return devices;
2278 }
2279 
2280 /*
2281  * Platform device
2282  */
2283 static int acer_platform_probe(struct platform_device *device)
2284 {
2285     int err;
2286 
2287     if (has_cap(ACER_CAP_MAILLED)) {
2288         err = acer_led_init(&device->dev);
2289         if (err)
2290             goto error_mailled;
2291     }
2292 
2293     if (has_cap(ACER_CAP_BRIGHTNESS)) {
2294         err = acer_backlight_init(&device->dev);
2295         if (err)
2296             goto error_brightness;
2297     }
2298 
2299     err = acer_rfkill_init(&device->dev);
2300     if (err)
2301         goto error_rfkill;
2302 
2303     return err;
2304 
2305 error_rfkill:
2306     if (has_cap(ACER_CAP_BRIGHTNESS))
2307         acer_backlight_exit();
2308 error_brightness:
2309     if (has_cap(ACER_CAP_MAILLED))
2310         acer_led_exit();
2311 error_mailled:
2312     return err;
2313 }
2314 
2315 static int acer_platform_remove(struct platform_device *device)
2316 {
2317     if (has_cap(ACER_CAP_MAILLED))
2318         acer_led_exit();
2319     if (has_cap(ACER_CAP_BRIGHTNESS))
2320         acer_backlight_exit();
2321 
2322     acer_rfkill_exit();
2323     return 0;
2324 }
2325 
2326 #ifdef CONFIG_PM_SLEEP
2327 static int acer_suspend(struct device *dev)
2328 {
2329     u32 value;
2330     struct acer_data *data = &interface->data;
2331 
2332     if (!data)
2333         return -ENOMEM;
2334 
2335     if (has_cap(ACER_CAP_MAILLED)) {
2336         get_u32(&value, ACER_CAP_MAILLED);
2337         set_u32(LED_OFF, ACER_CAP_MAILLED);
2338         data->mailled = value;
2339     }
2340 
2341     if (has_cap(ACER_CAP_BRIGHTNESS)) {
2342         get_u32(&value, ACER_CAP_BRIGHTNESS);
2343         data->brightness = value;
2344     }
2345 
2346     return 0;
2347 }
2348 
2349 static int acer_resume(struct device *dev)
2350 {
2351     struct acer_data *data = &interface->data;
2352 
2353     if (!data)
2354         return -ENOMEM;
2355 
2356     if (has_cap(ACER_CAP_MAILLED))
2357         set_u32(data->mailled, ACER_CAP_MAILLED);
2358 
2359     if (has_cap(ACER_CAP_BRIGHTNESS))
2360         set_u32(data->brightness, ACER_CAP_BRIGHTNESS);
2361 
2362     if (acer_wmi_accel_dev)
2363         acer_gsensor_init();
2364 
2365     return 0;
2366 }
2367 #else
2368 #define acer_suspend    NULL
2369 #define acer_resume NULL
2370 #endif
2371 
2372 static SIMPLE_DEV_PM_OPS(acer_pm, acer_suspend, acer_resume);
2373 
2374 static void acer_platform_shutdown(struct platform_device *device)
2375 {
2376     struct acer_data *data = &interface->data;
2377 
2378     if (!data)
2379         return;
2380 
2381     if (has_cap(ACER_CAP_MAILLED))
2382         set_u32(LED_OFF, ACER_CAP_MAILLED);
2383 }
2384 
2385 static struct platform_driver acer_platform_driver = {
2386     .driver = {
2387         .name = "acer-wmi",
2388         .pm = &acer_pm,
2389     },
2390     .probe = acer_platform_probe,
2391     .remove = acer_platform_remove,
2392     .shutdown = acer_platform_shutdown,
2393 };
2394 
2395 static struct platform_device *acer_platform_device;
2396 
2397 static void remove_debugfs(void)
2398 {
2399     debugfs_remove_recursive(interface->debug.root);
2400 }
2401 
2402 static void __init create_debugfs(void)
2403 {
2404     interface->debug.root = debugfs_create_dir("acer-wmi", NULL);
2405 
2406     debugfs_create_u32("devices", S_IRUGO, interface->debug.root,
2407                &interface->debug.wmid_devices);
2408 }
2409 
2410 static int __init acer_wmi_init(void)
2411 {
2412     int err;
2413 
2414     pr_info("Acer Laptop ACPI-WMI Extras\n");
2415 
2416     if (dmi_check_system(acer_blacklist)) {
2417         pr_info("Blacklisted hardware detected - not loading\n");
2418         return -ENODEV;
2419     }
2420 
2421     find_quirks();
2422 
2423     /*
2424      * The AMW0_GUID1 wmi is not only found on Acer family but also other
2425      * machines like Lenovo, Fujitsu and Medion. In the past days,
2426      * acer-wmi driver handled those non-Acer machines by quirks list.
2427      * But actually acer-wmi driver was loaded on any machines that have
2428      * AMW0_GUID1. This behavior is strange because those machines should
2429      * be supported by appropriate wmi drivers. e.g. fujitsu-laptop,
2430      * ideapad-laptop. So, here checks the machine that has AMW0_GUID1
2431      * should be in Acer/Gateway/Packard Bell white list, or it's already
2432      * in the past quirk list.
2433      */
2434     if (wmi_has_guid(AMW0_GUID1) &&
2435         !dmi_check_system(amw0_whitelist) &&
2436         quirks == &quirk_unknown) {
2437         pr_debug("Unsupported machine has AMW0_GUID1, unable to load\n");
2438         return -ENODEV;
2439     }
2440 
2441     /*
2442      * Detect which ACPI-WMI interface we're using.
2443      */
2444     if (wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1))
2445         interface = &AMW0_V2_interface;
2446 
2447     if (!wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1))
2448         interface = &wmid_interface;
2449 
2450     if (wmi_has_guid(WMID_GUID3))
2451         interface = &wmid_v2_interface;
2452 
2453     if (interface)
2454         dmi_walk(type_aa_dmi_decode, NULL);
2455 
2456     if (wmi_has_guid(WMID_GUID2) && interface) {
2457         if (!has_type_aa && ACPI_FAILURE(WMID_set_capabilities())) {
2458             pr_err("Unable to detect available WMID devices\n");
2459             return -ENODEV;
2460         }
2461         /* WMID always provides brightness methods */
2462         interface->capability |= ACER_CAP_BRIGHTNESS;
2463     } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa && force_caps == -1) {
2464         pr_err("No WMID device detection method found\n");
2465         return -ENODEV;
2466     }
2467 
2468     if (wmi_has_guid(AMW0_GUID1) && !wmi_has_guid(WMID_GUID1)) {
2469         interface = &AMW0_interface;
2470 
2471         if (ACPI_FAILURE(AMW0_set_capabilities())) {
2472             pr_err("Unable to detect available AMW0 devices\n");
2473             return -ENODEV;
2474         }
2475     }
2476 
2477     if (wmi_has_guid(AMW0_GUID1))
2478         AMW0_find_mailled();
2479 
2480     if (!interface) {
2481         pr_err("No or unsupported WMI interface, unable to load\n");
2482         return -ENODEV;
2483     }
2484 
2485     set_quirks();
2486 
2487     if (dmi_check_system(video_vendor_dmi_table))
2488         acpi_video_set_dmi_backlight_type(acpi_backlight_vendor);
2489 
2490     if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
2491         interface->capability &= ~ACER_CAP_BRIGHTNESS;
2492 
2493     if (wmi_has_guid(WMID_GUID3))
2494         interface->capability |= ACER_CAP_SET_FUNCTION_MODE;
2495 
2496     if (force_caps != -1)
2497         interface->capability = force_caps;
2498 
2499     if (wmi_has_guid(WMID_GUID3) &&
2500         (interface->capability & ACER_CAP_SET_FUNCTION_MODE)) {
2501         if (ACPI_FAILURE(acer_wmi_enable_rf_button()))
2502             pr_warn("Cannot enable RF Button Driver\n");
2503 
2504         if (ec_raw_mode) {
2505             if (ACPI_FAILURE(acer_wmi_enable_ec_raw())) {
2506                 pr_err("Cannot enable EC raw mode\n");
2507                 return -ENODEV;
2508             }
2509         } else if (ACPI_FAILURE(acer_wmi_enable_lm())) {
2510             pr_err("Cannot enable Launch Manager mode\n");
2511             return -ENODEV;
2512         }
2513     } else if (ec_raw_mode) {
2514         pr_info("No WMID EC raw mode enable method\n");
2515     }
2516 
2517     if (wmi_has_guid(ACERWMID_EVENT_GUID)) {
2518         err = acer_wmi_input_setup();
2519         if (err)
2520             return err;
2521         err = acer_wmi_accel_setup();
2522         if (err && err != -ENODEV)
2523             pr_warn("Cannot enable accelerometer\n");
2524     }
2525 
2526     err = platform_driver_register(&acer_platform_driver);
2527     if (err) {
2528         pr_err("Unable to register platform driver\n");
2529         goto error_platform_register;
2530     }
2531 
2532     acer_platform_device = platform_device_alloc("acer-wmi", -1);
2533     if (!acer_platform_device) {
2534         err = -ENOMEM;
2535         goto error_device_alloc;
2536     }
2537 
2538     err = platform_device_add(acer_platform_device);
2539     if (err)
2540         goto error_device_add;
2541 
2542     if (wmi_has_guid(WMID_GUID2)) {
2543         interface->debug.wmid_devices = get_wmid_devices();
2544         create_debugfs();
2545     }
2546 
2547     /* Override any initial settings with values from the commandline */
2548     acer_commandline_init();
2549 
2550     return 0;
2551 
2552 error_device_add:
2553     platform_device_put(acer_platform_device);
2554 error_device_alloc:
2555     platform_driver_unregister(&acer_platform_driver);
2556 error_platform_register:
2557     if (wmi_has_guid(ACERWMID_EVENT_GUID))
2558         acer_wmi_input_destroy();
2559     if (acer_wmi_accel_dev)
2560         input_unregister_device(acer_wmi_accel_dev);
2561 
2562     return err;
2563 }
2564 
2565 static void __exit acer_wmi_exit(void)
2566 {
2567     if (wmi_has_guid(ACERWMID_EVENT_GUID))
2568         acer_wmi_input_destroy();
2569 
2570     if (acer_wmi_accel_dev)
2571         input_unregister_device(acer_wmi_accel_dev);
2572 
2573     remove_debugfs();
2574     platform_device_unregister(acer_platform_device);
2575     platform_driver_unregister(&acer_platform_driver);
2576 
2577     pr_info("Acer Laptop WMI Extras unloaded\n");
2578     return;
2579 }
2580 
2581 module_init(acer_wmi_init);
2582 module_exit(acer_wmi_exit);