1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Acer WMI Laptop Extras 4 * 5 * Copyright (C) 2007-2009 Carlos Corbacho <carlos@strangeworlds.co.uk> 6 * 7 * Based on acer_acpi: 8 * Copyright (C) 2005-2007 E.M. Smith 9 * Copyright (C) 2007-2008 Carlos Corbacho <cathectic@gmail.com> 10 */ 11 12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 13 14 #include <linux/kernel.h> 15 #include <linux/minmax.h> 16 #include <linux/module.h> 17 #include <linux/init.h> 18 #include <linux/types.h> 19 #include <linux/dmi.h> 20 #include <linux/fixp-arith.h> 21 #include <linux/backlight.h> 22 #include <linux/leds.h> 23 #include <linux/platform_device.h> 24 #include <linux/platform_profile.h> 25 #include <linux/acpi.h> 26 #include <linux/i8042.h> 27 #include <linux/rfkill.h> 28 #include <linux/workqueue.h> 29 #include <linux/debugfs.h> 30 #include <linux/slab.h> 31 #include <linux/input.h> 32 #include <linux/input/sparse-keymap.h> 33 #include <acpi/video.h> 34 #include <linux/hwmon.h> 35 #include <linux/units.h> 36 #include <linux/unaligned.h> 37 #include <linux/bitfield.h> 38 #include <linux/bitmap.h> 39 40 MODULE_AUTHOR("Carlos Corbacho"); 41 MODULE_DESCRIPTION("Acer Laptop WMI Extras Driver"); 42 MODULE_LICENSE("GPL"); 43 44 /* 45 * Magic Number 46 * Meaning is unknown - this number is required for writing to ACPI for AMW0 47 * (it's also used in acerhk when directly accessing the BIOS) 48 */ 49 #define ACER_AMW0_WRITE 0x9610 50 51 /* 52 * Bit masks for the AMW0 interface 53 */ 54 #define ACER_AMW0_WIRELESS_MASK 0x35 55 #define ACER_AMW0_BLUETOOTH_MASK 0x34 56 #define ACER_AMW0_MAILLED_MASK 0x31 57 58 /* 59 * Method IDs for WMID interface 60 */ 61 #define ACER_WMID_GET_WIRELESS_METHODID 1 62 #define ACER_WMID_GET_BLUETOOTH_METHODID 2 63 #define ACER_WMID_GET_BRIGHTNESS_METHODID 3 64 #define ACER_WMID_SET_WIRELESS_METHODID 4 65 #define ACER_WMID_SET_BLUETOOTH_METHODID 5 66 #define ACER_WMID_SET_BRIGHTNESS_METHODID 6 67 #define ACER_WMID_GET_THREEG_METHODID 10 68 #define ACER_WMID_SET_THREEG_METHODID 11 69 70 #define ACER_WMID_SET_GAMING_LED_METHODID 2 71 #define ACER_WMID_GET_GAMING_LED_METHODID 4 72 #define ACER_WMID_GET_GAMING_SYS_INFO_METHODID 5 73 #define ACER_WMID_SET_GAMING_FAN_BEHAVIOR_METHODID 14 74 #define ACER_WMID_GET_GAMING_FAN_BEHAVIOR_METHODID 15 75 #define ACER_WMID_SET_GAMING_FAN_SPEED_METHODID 16 76 #define ACER_WMID_GET_GAMING_FAN_SPEED_METHODID 17 77 #define ACER_WMID_SET_GAMING_MISC_SETTING_METHODID 22 78 #define ACER_WMID_GET_GAMING_MISC_SETTING_METHODID 23 79 80 #define ACER_GAMING_FAN_BEHAVIOR_CPU BIT(0) 81 #define ACER_GAMING_FAN_BEHAVIOR_GPU BIT(3) 82 83 #define ACER_GAMING_FAN_BEHAVIOR_STATUS_MASK GENMASK_ULL(7, 0) 84 #define ACER_GAMING_FAN_BEHAVIOR_ID_MASK GENMASK_ULL(15, 0) 85 #define ACER_GAMING_FAN_BEHAVIOR_SET_CPU_MODE_MASK GENMASK(17, 16) 86 #define ACER_GAMING_FAN_BEHAVIOR_SET_GPU_MODE_MASK GENMASK(23, 22) 87 #define ACER_GAMING_FAN_BEHAVIOR_GET_CPU_MODE_MASK GENMASK(9, 8) 88 #define ACER_GAMING_FAN_BEHAVIOR_GET_GPU_MODE_MASK GENMASK(15, 14) 89 90 #define ACER_GAMING_FAN_SPEED_STATUS_MASK GENMASK_ULL(7, 0) 91 #define ACER_GAMING_FAN_SPEED_ID_MASK GENMASK_ULL(7, 0) 92 #define ACER_GAMING_FAN_SPEED_VALUE_MASK GENMASK_ULL(15, 8) 93 94 #define ACER_GAMING_MISC_SETTING_STATUS_MASK GENMASK_ULL(7, 0) 95 #define ACER_GAMING_MISC_SETTING_INDEX_MASK GENMASK_ULL(7, 0) 96 #define ACER_GAMING_MISC_SETTING_VALUE_MASK GENMASK_ULL(15, 8) 97 98 #define ACER_PREDATOR_V4_RETURN_STATUS_BIT_MASK GENMASK_ULL(7, 0) 99 #define ACER_PREDATOR_V4_SENSOR_INDEX_BIT_MASK GENMASK_ULL(15, 8) 100 #define ACER_PREDATOR_V4_SENSOR_READING_BIT_MASK GENMASK_ULL(23, 8) 101 #define ACER_PREDATOR_V4_SUPPORTED_SENSORS_BIT_MASK GENMASK_ULL(39, 24) 102 103 /* 104 * Acer ACPI method GUIDs 105 */ 106 #define AMW0_GUID1 "67C3371D-95A3-4C37-BB61-DD47B491DAAB" 107 #define AMW0_GUID2 "431F16ED-0C2B-444C-B267-27DEB140CF9C" 108 #define WMID_GUID1 "6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3" 109 #define WMID_GUID2 "95764E09-FB56-4E83-B31A-37761F60994A" 110 #define WMID_GUID3 "61EF69EA-865C-4BC3-A502-A0DEBA0CB531" 111 #define WMID_GUID4 "7A4DDFE7-5B5D-40B4-8595-4408E0CC7F56" 112 113 /* 114 * Acer ACPI event GUIDs 115 */ 116 #define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026" 117 118 MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB"); 119 MODULE_ALIAS("wmi:6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3"); 120 MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026"); 121 122 enum acer_wmi_event_ids { 123 WMID_HOTKEY_EVENT = 0x1, 124 WMID_BACKLIGHT_EVENT = 0x4, 125 WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5, 126 WMID_GAMING_TURBO_KEY_EVENT = 0x7, 127 WMID_AC_EVENT = 0x8, 128 }; 129 130 enum acer_wmi_predator_v4_sys_info_command { 131 ACER_WMID_CMD_GET_PREDATOR_V4_SUPPORTED_SENSORS = 0x0000, 132 ACER_WMID_CMD_GET_PREDATOR_V4_SENSOR_READING = 0x0001, 133 ACER_WMID_CMD_GET_PREDATOR_V4_BAT_STATUS = 0x0002, 134 }; 135 136 enum acer_wmi_predator_v4_sensor_id { 137 ACER_WMID_SENSOR_CPU_TEMPERATURE = 0x01, 138 ACER_WMID_SENSOR_CPU_FAN_SPEED = 0x02, 139 ACER_WMID_SENSOR_EXTERNAL_TEMPERATURE_2 = 0x03, 140 ACER_WMID_SENSOR_GPU_FAN_SPEED = 0x06, 141 ACER_WMID_SENSOR_GPU_TEMPERATURE = 0x0A, 142 }; 143 144 enum acer_wmi_gaming_fan_id { 145 ACER_WMID_CPU_FAN = 0x01, 146 ACER_WMID_GPU_FAN = 0x04, 147 }; 148 149 enum acer_wmi_gaming_fan_mode { 150 ACER_WMID_FAN_MODE_AUTO = 0x01, 151 ACER_WMID_FAN_MODE_TURBO = 0x02, 152 ACER_WMID_FAN_MODE_CUSTOM = 0x03, 153 }; 154 155 enum acer_wmi_predator_v4_oc { 156 ACER_WMID_OC_NORMAL = 0x0000, 157 ACER_WMID_OC_TURBO = 0x0002, 158 }; 159 160 enum acer_wmi_gaming_misc_setting { 161 ACER_WMID_MISC_SETTING_OC_1 = 0x0005, 162 ACER_WMID_MISC_SETTING_OC_2 = 0x0007, 163 /* Unreliable on some models */ 164 ACER_WMID_MISC_SETTING_SUPPORTED_PROFILES = 0x000A, 165 ACER_WMID_MISC_SETTING_PLATFORM_PROFILE = 0x000B, 166 }; 167 168 static const struct key_entry acer_wmi_keymap[] __initconst = { 169 {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */ 170 {KE_KEY, 0x03, {KEY_WLAN} }, /* WiFi */ 171 {KE_KEY, 0x04, {KEY_WLAN} }, /* WiFi */ 172 {KE_KEY, 0x12, {KEY_BLUETOOTH} }, /* BT */ 173 {KE_KEY, 0x21, {KEY_PROG1} }, /* Backup */ 174 {KE_KEY, 0x22, {KEY_PROG2} }, /* Arcade */ 175 {KE_KEY, 0x23, {KEY_PROG3} }, /* P_Key */ 176 {KE_KEY, 0x24, {KEY_PROG4} }, /* Social networking_Key */ 177 {KE_KEY, 0x27, {KEY_HELP} }, 178 {KE_KEY, 0x29, {KEY_PROG3} }, /* P_Key for TM8372 */ 179 {KE_IGNORE, 0x41, {KEY_MUTE} }, 180 {KE_IGNORE, 0x42, {KEY_PREVIOUSSONG} }, 181 {KE_IGNORE, 0x4d, {KEY_PREVIOUSSONG} }, 182 {KE_IGNORE, 0x43, {KEY_NEXTSONG} }, 183 {KE_IGNORE, 0x4e, {KEY_NEXTSONG} }, 184 {KE_IGNORE, 0x44, {KEY_PLAYPAUSE} }, 185 {KE_IGNORE, 0x4f, {KEY_PLAYPAUSE} }, 186 {KE_IGNORE, 0x45, {KEY_STOP} }, 187 {KE_IGNORE, 0x50, {KEY_STOP} }, 188 {KE_IGNORE, 0x48, {KEY_VOLUMEUP} }, 189 {KE_IGNORE, 0x49, {KEY_VOLUMEDOWN} }, 190 {KE_IGNORE, 0x4a, {KEY_VOLUMEDOWN} }, 191 /* 192 * 0x61 is KEY_SWITCHVIDEOMODE. Usually this is a duplicate input event 193 * with the "Video Bus" input device events. But sometimes it is not 194 * a dup. Map it to KEY_UNKNOWN instead of using KE_IGNORE so that 195 * udev/hwdb can override it on systems where it is not a dup. 196 */ 197 {KE_KEY, 0x61, {KEY_UNKNOWN} }, 198 {KE_IGNORE, 0x62, {KEY_BRIGHTNESSUP} }, 199 {KE_IGNORE, 0x63, {KEY_BRIGHTNESSDOWN} }, 200 {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */ 201 {KE_IGNORE, 0x81, {KEY_SLEEP} }, 202 {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad Toggle */ 203 {KE_IGNORE, 0x84, {KEY_KBDILLUMTOGGLE} }, /* Automatic Keyboard background light toggle */ 204 {KE_KEY, KEY_TOUCHPAD_ON, {KEY_TOUCHPAD_ON} }, 205 {KE_KEY, KEY_TOUCHPAD_OFF, {KEY_TOUCHPAD_OFF} }, 206 {KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} }, 207 {KE_KEY, 0x85, {KEY_TOUCHPAD_TOGGLE} }, 208 {KE_KEY, 0x86, {KEY_WLAN} }, 209 {KE_KEY, 0x87, {KEY_POWER} }, 210 {KE_END, 0} 211 }; 212 213 static struct input_dev *acer_wmi_input_dev; 214 static struct input_dev *acer_wmi_accel_dev; 215 216 struct event_return_value { 217 u8 function; 218 u8 key_num; 219 u16 device_state; 220 u16 reserved1; 221 u8 kbd_dock_state; 222 u8 reserved2; 223 } __packed; 224 225 /* 226 * GUID3 Get Device Status device flags 227 */ 228 #define ACER_WMID3_GDS_WIRELESS (1<<0) /* WiFi */ 229 #define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */ 230 #define ACER_WMID3_GDS_WIMAX (1<<7) /* WiMAX */ 231 #define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */ 232 #define ACER_WMID3_GDS_RFBTN (1<<14) /* RF Button */ 233 234 #define ACER_WMID3_GDS_TOUCHPAD (1<<1) /* Touchpad */ 235 236 /* Hotkey Customized Setting and Acer Application Status. 237 * Set Device Default Value and Report Acer Application Status. 238 * When Acer Application starts, it will run this method to inform 239 * BIOS/EC that Acer Application is on. 240 * App Status 241 * Bit[0]: Launch Manager Status 242 * Bit[1]: ePM Status 243 * Bit[2]: Device Control Status 244 * Bit[3]: Acer Power Button Utility Status 245 * Bit[4]: RF Button Status 246 * Bit[5]: ODD PM Status 247 * Bit[6]: Device Default Value Control 248 * Bit[7]: Hall Sensor Application Status 249 */ 250 struct func_input_params { 251 u8 function_num; /* Function Number */ 252 u16 commun_devices; /* Communication type devices default status */ 253 u16 devices; /* Other type devices default status */ 254 u8 app_status; /* Acer Device Status. LM, ePM, RF Button... */ 255 u8 app_mask; /* Bit mask to app_status */ 256 u8 reserved; 257 } __packed; 258 259 struct func_return_value { 260 u8 error_code; /* Error Code */ 261 u8 ec_return_value; /* EC Return Value */ 262 u16 reserved; 263 } __packed; 264 265 struct wmid3_gds_set_input_param { /* Set Device Status input parameter */ 266 u8 function_num; /* Function Number */ 267 u8 hotkey_number; /* Hotkey Number */ 268 u16 devices; /* Set Device */ 269 u8 volume_value; /* Volume Value */ 270 } __packed; 271 272 struct wmid3_gds_get_input_param { /* Get Device Status input parameter */ 273 u8 function_num; /* Function Number */ 274 u8 hotkey_number; /* Hotkey Number */ 275 u16 devices; /* Get Device */ 276 } __packed; 277 278 struct wmid3_gds_return_value { /* Get Device Status return value*/ 279 u8 error_code; /* Error Code */ 280 u8 ec_return_value; /* EC Return Value */ 281 u16 devices; /* Current Device Status */ 282 u32 reserved; 283 } __packed; 284 285 struct hotkey_function_type_aa { 286 u8 type; 287 u8 length; 288 u16 handle; 289 u16 commun_func_bitmap; 290 u16 application_func_bitmap; 291 u16 media_func_bitmap; 292 u16 display_func_bitmap; 293 u16 others_func_bitmap; 294 u8 commun_fn_key_number; 295 } __packed; 296 297 /* 298 * Interface capability flags 299 */ 300 #define ACER_CAP_MAILLED BIT(0) 301 #define ACER_CAP_WIRELESS BIT(1) 302 #define ACER_CAP_BLUETOOTH BIT(2) 303 #define ACER_CAP_BRIGHTNESS BIT(3) 304 #define ACER_CAP_THREEG BIT(4) 305 #define ACER_CAP_SET_FUNCTION_MODE BIT(5) 306 #define ACER_CAP_KBD_DOCK BIT(6) 307 #define ACER_CAP_TURBO_OC BIT(7) 308 #define ACER_CAP_TURBO_LED BIT(8) 309 #define ACER_CAP_TURBO_FAN BIT(9) 310 #define ACER_CAP_PLATFORM_PROFILE BIT(10) 311 #define ACER_CAP_HWMON BIT(11) 312 #define ACER_CAP_PWM BIT(12) 313 314 /* 315 * Interface type flags 316 */ 317 enum interface_flags { 318 ACER_AMW0, 319 ACER_AMW0_V2, 320 ACER_WMID, 321 ACER_WMID_v2, 322 }; 323 324 static int max_brightness = 0xF; 325 326 static int mailled = -1; 327 static int brightness = -1; 328 static int threeg = -1; 329 static int force_series; 330 static int force_caps = -1; 331 static bool ec_raw_mode; 332 static bool has_type_aa; 333 static u16 commun_func_bitmap; 334 static u8 commun_fn_key_number; 335 static bool cycle_gaming_thermal_profile = true; 336 static bool predator_v4; 337 static u64 supported_sensors; 338 339 module_param(mailled, int, 0444); 340 module_param(brightness, int, 0444); 341 module_param(threeg, int, 0444); 342 module_param(force_series, int, 0444); 343 module_param(force_caps, int, 0444); 344 module_param(ec_raw_mode, bool, 0444); 345 module_param(cycle_gaming_thermal_profile, bool, 0644); 346 module_param(predator_v4, bool, 0444); 347 MODULE_PARM_DESC(mailled, "Set initial state of Mail LED"); 348 MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness"); 349 MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware"); 350 MODULE_PARM_DESC(force_series, "Force a different laptop series"); 351 MODULE_PARM_DESC(force_caps, "Force the capability bitmask to this value"); 352 MODULE_PARM_DESC(ec_raw_mode, "Enable EC raw mode"); 353 MODULE_PARM_DESC(cycle_gaming_thermal_profile, 354 "Set thermal mode key in cycle mode. Disabling it sets the mode key in turbo toggle mode"); 355 MODULE_PARM_DESC(predator_v4, 356 "Enable features for predator laptops that use predator sense v4"); 357 358 struct acer_data { 359 int mailled; 360 int threeg; 361 int brightness; 362 }; 363 364 struct acer_debug { 365 struct dentry *root; 366 u32 wmid_devices; 367 }; 368 369 static struct rfkill *wireless_rfkill; 370 static struct rfkill *bluetooth_rfkill; 371 static struct rfkill *threeg_rfkill; 372 static bool rfkill_inited; 373 374 /* Each low-level interface must define at least some of the following */ 375 struct wmi_interface { 376 /* The WMI device type */ 377 u32 type; 378 379 /* The capabilities this interface provides */ 380 u32 capability; 381 382 /* Private data for the current interface */ 383 struct acer_data data; 384 385 /* debugfs entries associated with this interface */ 386 struct acer_debug debug; 387 }; 388 389 /* The static interface pointer, points to the currently detected interface */ 390 static struct wmi_interface *interface; 391 392 /* 393 * Embedded Controller quirks 394 * Some laptops require us to directly access the EC to either enable or query 395 * features that are not available through WMI. 396 */ 397 398 struct quirk_entry { 399 u8 wireless; 400 u8 mailled; 401 s8 brightness; 402 u8 bluetooth; 403 u8 turbo; 404 u8 cpu_fans; 405 u8 gpu_fans; 406 u8 predator_v4; 407 u8 pwm; 408 }; 409 410 static struct quirk_entry *quirks; 411 412 static void __init set_quirks(void) 413 { 414 if (quirks->mailled) 415 interface->capability |= ACER_CAP_MAILLED; 416 417 if (quirks->brightness) 418 interface->capability |= ACER_CAP_BRIGHTNESS; 419 420 if (quirks->turbo) 421 interface->capability |= ACER_CAP_TURBO_OC | ACER_CAP_TURBO_LED 422 | ACER_CAP_TURBO_FAN; 423 424 if (quirks->predator_v4) 425 interface->capability |= ACER_CAP_PLATFORM_PROFILE | 426 ACER_CAP_HWMON; 427 428 if (quirks->pwm) 429 interface->capability |= ACER_CAP_PWM; 430 } 431 432 static int __init dmi_matched(const struct dmi_system_id *dmi) 433 { 434 quirks = dmi->driver_data; 435 return 1; 436 } 437 438 static int __init set_force_caps(const struct dmi_system_id *dmi) 439 { 440 if (force_caps == -1) { 441 force_caps = (uintptr_t)dmi->driver_data; 442 pr_info("Found %s, set force_caps to 0x%x\n", dmi->ident, force_caps); 443 } 444 return 1; 445 } 446 447 static struct quirk_entry quirk_unknown = { 448 }; 449 450 static struct quirk_entry quirk_acer_aspire_1520 = { 451 .brightness = -1, 452 }; 453 454 static struct quirk_entry quirk_acer_travelmate_2490 = { 455 .mailled = 1, 456 }; 457 458 static struct quirk_entry quirk_acer_nitro_an515_58 = { 459 .predator_v4 = 1, 460 .pwm = 1, 461 }; 462 463 static struct quirk_entry quirk_acer_predator_ph315_53 = { 464 .turbo = 1, 465 .cpu_fans = 1, 466 .gpu_fans = 1, 467 }; 468 469 static struct quirk_entry quirk_acer_predator_ph16_72 = { 470 .turbo = 1, 471 .cpu_fans = 1, 472 .gpu_fans = 1, 473 .predator_v4 = 1, 474 .pwm = 1, 475 }; 476 477 static struct quirk_entry quirk_acer_predator_pt14_51 = { 478 .turbo = 1, 479 .cpu_fans = 1, 480 .gpu_fans = 1, 481 .predator_v4 = 1, 482 .pwm = 1, 483 }; 484 485 static struct quirk_entry quirk_acer_predator_v4 = { 486 .predator_v4 = 1, 487 }; 488 489 /* This AMW0 laptop has no bluetooth */ 490 static struct quirk_entry quirk_medion_md_98300 = { 491 .wireless = 1, 492 }; 493 494 static struct quirk_entry quirk_fujitsu_amilo_li_1718 = { 495 .wireless = 2, 496 }; 497 498 static struct quirk_entry quirk_lenovo_ideapad_s205 = { 499 .wireless = 3, 500 }; 501 502 /* The Aspire One has a dummy ACPI-WMI interface - disable it */ 503 static const struct dmi_system_id acer_blacklist[] __initconst = { 504 { 505 .ident = "Acer Aspire One (SSD)", 506 .matches = { 507 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 508 DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"), 509 }, 510 }, 511 { 512 .ident = "Acer Aspire One (HDD)", 513 .matches = { 514 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 515 DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"), 516 }, 517 }, 518 {} 519 }; 520 521 static const struct dmi_system_id amw0_whitelist[] __initconst = { 522 { 523 .ident = "Acer", 524 .matches = { 525 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 526 }, 527 }, 528 { 529 .ident = "Gateway", 530 .matches = { 531 DMI_MATCH(DMI_SYS_VENDOR, "Gateway"), 532 }, 533 }, 534 { 535 .ident = "Packard Bell", 536 .matches = { 537 DMI_MATCH(DMI_SYS_VENDOR, "Packard Bell"), 538 }, 539 }, 540 {} 541 }; 542 543 /* 544 * This quirk table is only for Acer/Gateway/Packard Bell family 545 * that those machines are supported by acer-wmi driver. 546 */ 547 static const struct dmi_system_id acer_quirks[] __initconst = { 548 { 549 .callback = dmi_matched, 550 .ident = "Acer Aspire 1360", 551 .matches = { 552 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 553 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), 554 }, 555 .driver_data = &quirk_acer_aspire_1520, 556 }, 557 { 558 .callback = dmi_matched, 559 .ident = "Acer Aspire 1520", 560 .matches = { 561 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 562 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1520"), 563 }, 564 .driver_data = &quirk_acer_aspire_1520, 565 }, 566 { 567 .callback = dmi_matched, 568 .ident = "Acer Aspire 3100", 569 .matches = { 570 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 571 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3100"), 572 }, 573 .driver_data = &quirk_acer_travelmate_2490, 574 }, 575 { 576 .callback = dmi_matched, 577 .ident = "Acer Aspire 3610", 578 .matches = { 579 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 580 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3610"), 581 }, 582 .driver_data = &quirk_acer_travelmate_2490, 583 }, 584 { 585 .callback = dmi_matched, 586 .ident = "Acer Aspire 5100", 587 .matches = { 588 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 589 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"), 590 }, 591 .driver_data = &quirk_acer_travelmate_2490, 592 }, 593 { 594 .callback = dmi_matched, 595 .ident = "Acer Aspire 5610", 596 .matches = { 597 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 598 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), 599 }, 600 .driver_data = &quirk_acer_travelmate_2490, 601 }, 602 { 603 .callback = dmi_matched, 604 .ident = "Acer Aspire 5630", 605 .matches = { 606 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 607 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"), 608 }, 609 .driver_data = &quirk_acer_travelmate_2490, 610 }, 611 { 612 .callback = dmi_matched, 613 .ident = "Acer Aspire 5650", 614 .matches = { 615 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 616 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"), 617 }, 618 .driver_data = &quirk_acer_travelmate_2490, 619 }, 620 { 621 .callback = dmi_matched, 622 .ident = "Acer Aspire 5680", 623 .matches = { 624 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 625 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"), 626 }, 627 .driver_data = &quirk_acer_travelmate_2490, 628 }, 629 { 630 .callback = dmi_matched, 631 .ident = "Acer Aspire 9110", 632 .matches = { 633 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 634 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"), 635 }, 636 .driver_data = &quirk_acer_travelmate_2490, 637 }, 638 { 639 .callback = dmi_matched, 640 .ident = "Acer TravelMate 2490", 641 .matches = { 642 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 643 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), 644 }, 645 .driver_data = &quirk_acer_travelmate_2490, 646 }, 647 { 648 .callback = dmi_matched, 649 .ident = "Acer TravelMate 4200", 650 .matches = { 651 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 652 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4200"), 653 }, 654 .driver_data = &quirk_acer_travelmate_2490, 655 }, 656 { 657 .callback = dmi_matched, 658 .ident = "Acer Nitro AN515-58", 659 .matches = { 660 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 661 DMI_MATCH(DMI_PRODUCT_NAME, "Nitro AN515-58"), 662 }, 663 .driver_data = &quirk_acer_nitro_an515_58, 664 }, 665 { 666 .callback = dmi_matched, 667 .ident = "Acer Predator PH315-53", 668 .matches = { 669 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 670 DMI_MATCH(DMI_PRODUCT_NAME, "Predator PH315-53"), 671 }, 672 .driver_data = &quirk_acer_predator_ph315_53, 673 }, 674 { 675 .callback = dmi_matched, 676 .ident = "Acer Predator PHN16-71", 677 .matches = { 678 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 679 DMI_MATCH(DMI_PRODUCT_NAME, "Predator PHN16-71"), 680 }, 681 .driver_data = &quirk_acer_predator_v4, 682 }, 683 { 684 .callback = dmi_matched, 685 .ident = "Acer Predator PH16-71", 686 .matches = { 687 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 688 DMI_MATCH(DMI_PRODUCT_NAME, "Predator PH16-71"), 689 }, 690 .driver_data = &quirk_acer_predator_v4, 691 }, 692 { 693 .callback = dmi_matched, 694 .ident = "Acer Predator PH16-72", 695 .matches = { 696 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 697 DMI_MATCH(DMI_PRODUCT_NAME, "Predator PH16-72"), 698 }, 699 .driver_data = &quirk_acer_predator_ph16_72, 700 }, 701 { 702 .callback = dmi_matched, 703 .ident = "Acer Predator Helios Neo 16", 704 .matches = { 705 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 706 DMI_MATCH(DMI_PRODUCT_NAME, "Predator PHN16-72"), 707 }, 708 .driver_data = &quirk_acer_predator_ph16_72, 709 }, 710 { 711 .callback = dmi_matched, 712 .ident = "Acer Predator PH18-71", 713 .matches = { 714 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 715 DMI_MATCH(DMI_PRODUCT_NAME, "Predator PH18-71"), 716 }, 717 .driver_data = &quirk_acer_predator_v4, 718 }, 719 { 720 .callback = dmi_matched, 721 .ident = "Acer Predator PT14-51", 722 .matches = { 723 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 724 DMI_MATCH(DMI_PRODUCT_NAME, "Predator PT14-51"), 725 }, 726 .driver_data = &quirk_acer_predator_pt14_51, 727 }, 728 { 729 .callback = set_force_caps, 730 .ident = "Acer Aspire Switch 10E SW3-016", 731 .matches = { 732 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 733 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW3-016"), 734 }, 735 .driver_data = (void *)ACER_CAP_KBD_DOCK, 736 }, 737 { 738 .callback = set_force_caps, 739 .ident = "Acer Aspire Switch 10 SW5-012", 740 .matches = { 741 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 742 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"), 743 }, 744 .driver_data = (void *)ACER_CAP_KBD_DOCK, 745 }, 746 { 747 .callback = set_force_caps, 748 .ident = "Acer Aspire Switch V 10 SW5-017", 749 .matches = { 750 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), 751 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"), 752 }, 753 .driver_data = (void *)ACER_CAP_KBD_DOCK, 754 }, 755 { 756 .callback = set_force_caps, 757 .ident = "Acer One 10 (S1003)", 758 .matches = { 759 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), 760 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"), 761 }, 762 .driver_data = (void *)ACER_CAP_KBD_DOCK, 763 }, 764 {} 765 }; 766 767 /* 768 * This quirk list is for those non-acer machines that have AMW0_GUID1 769 * but supported by acer-wmi in past days. Keeping this quirk list here 770 * is only for backward compatible. Please do not add new machine to 771 * here anymore. Those non-acer machines should be supported by 772 * appropriate wmi drivers. 773 */ 774 static const struct dmi_system_id non_acer_quirks[] __initconst = { 775 { 776 .callback = dmi_matched, 777 .ident = "Fujitsu Siemens Amilo Li 1718", 778 .matches = { 779 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 780 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Li 1718"), 781 }, 782 .driver_data = &quirk_fujitsu_amilo_li_1718, 783 }, 784 { 785 .callback = dmi_matched, 786 .ident = "Medion MD 98300", 787 .matches = { 788 DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), 789 DMI_MATCH(DMI_PRODUCT_NAME, "WAM2030"), 790 }, 791 .driver_data = &quirk_medion_md_98300, 792 }, 793 { 794 .callback = dmi_matched, 795 .ident = "Lenovo Ideapad S205", 796 .matches = { 797 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 798 DMI_MATCH(DMI_PRODUCT_NAME, "10382LG"), 799 }, 800 .driver_data = &quirk_lenovo_ideapad_s205, 801 }, 802 { 803 .callback = dmi_matched, 804 .ident = "Lenovo Ideapad S205 (Brazos)", 805 .matches = { 806 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 807 DMI_MATCH(DMI_PRODUCT_NAME, "Brazos"), 808 }, 809 .driver_data = &quirk_lenovo_ideapad_s205, 810 }, 811 { 812 .callback = dmi_matched, 813 .ident = "Lenovo 3000 N200", 814 .matches = { 815 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 816 DMI_MATCH(DMI_PRODUCT_NAME, "0687A31"), 817 }, 818 .driver_data = &quirk_fujitsu_amilo_li_1718, 819 }, 820 { 821 .callback = dmi_matched, 822 .ident = "Lenovo Ideapad S205-10382JG", 823 .matches = { 824 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 825 DMI_MATCH(DMI_PRODUCT_NAME, "10382JG"), 826 }, 827 .driver_data = &quirk_lenovo_ideapad_s205, 828 }, 829 { 830 .callback = dmi_matched, 831 .ident = "Lenovo Ideapad S205-1038DPG", 832 .matches = { 833 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 834 DMI_MATCH(DMI_PRODUCT_NAME, "1038DPG"), 835 }, 836 .driver_data = &quirk_lenovo_ideapad_s205, 837 }, 838 {} 839 }; 840 841 static struct device *platform_profile_device; 842 static bool platform_profile_support; 843 844 /* 845 * The profile used before turbo mode. This variable is needed for 846 * returning from turbo mode when the mode key is in toggle mode. 847 */ 848 static int last_non_turbo_profile = INT_MIN; 849 850 enum acer_predator_v4_thermal_profile { 851 ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET = 0x00, 852 ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED = 0x01, 853 ACER_PREDATOR_V4_THERMAL_PROFILE_PERFORMANCE = 0x04, 854 ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO = 0x05, 855 ACER_PREDATOR_V4_THERMAL_PROFILE_ECO = 0x06, 856 }; 857 858 /* Find which quirks are needed for a particular vendor/ model pair */ 859 static void __init find_quirks(void) 860 { 861 if (predator_v4) { 862 quirks = &quirk_acer_predator_v4; 863 } else if (!force_series) { 864 dmi_check_system(acer_quirks); 865 dmi_check_system(non_acer_quirks); 866 } else if (force_series == 2490) { 867 quirks = &quirk_acer_travelmate_2490; 868 } 869 870 if (quirks == NULL) 871 quirks = &quirk_unknown; 872 } 873 874 /* 875 * General interface convenience methods 876 */ 877 878 static bool has_cap(u32 cap) 879 { 880 return interface->capability & cap; 881 } 882 883 /* 884 * AMW0 (V1) interface 885 */ 886 struct wmab_args { 887 u32 eax; 888 u32 ebx; 889 u32 ecx; 890 u32 edx; 891 }; 892 893 struct wmab_ret { 894 u32 eax; 895 u32 ebx; 896 u32 ecx; 897 u32 edx; 898 u32 eex; 899 }; 900 901 static acpi_status wmab_execute(struct wmab_args *regbuf, 902 struct acpi_buffer *result) 903 { 904 struct acpi_buffer input; 905 acpi_status status; 906 input.length = sizeof(struct wmab_args); 907 input.pointer = (u8 *)regbuf; 908 909 status = wmi_evaluate_method(AMW0_GUID1, 0, 1, &input, result); 910 911 return status; 912 } 913 914 static acpi_status AMW0_get_u32(u32 *value, u32 cap) 915 { 916 int err; 917 u8 result; 918 919 switch (cap) { 920 case ACER_CAP_MAILLED: 921 switch (quirks->mailled) { 922 default: 923 err = ec_read(0xA, &result); 924 if (err) 925 return AE_ERROR; 926 *value = (result >> 7) & 0x1; 927 return AE_OK; 928 } 929 break; 930 case ACER_CAP_WIRELESS: 931 switch (quirks->wireless) { 932 case 1: 933 err = ec_read(0x7B, &result); 934 if (err) 935 return AE_ERROR; 936 *value = result & 0x1; 937 return AE_OK; 938 case 2: 939 err = ec_read(0x71, &result); 940 if (err) 941 return AE_ERROR; 942 *value = result & 0x1; 943 return AE_OK; 944 case 3: 945 err = ec_read(0x78, &result); 946 if (err) 947 return AE_ERROR; 948 *value = result & 0x1; 949 return AE_OK; 950 default: 951 err = ec_read(0xA, &result); 952 if (err) 953 return AE_ERROR; 954 *value = (result >> 2) & 0x1; 955 return AE_OK; 956 } 957 break; 958 case ACER_CAP_BLUETOOTH: 959 switch (quirks->bluetooth) { 960 default: 961 err = ec_read(0xA, &result); 962 if (err) 963 return AE_ERROR; 964 *value = (result >> 4) & 0x1; 965 return AE_OK; 966 } 967 break; 968 case ACER_CAP_BRIGHTNESS: 969 switch (quirks->brightness) { 970 default: 971 err = ec_read(0x83, &result); 972 if (err) 973 return AE_ERROR; 974 *value = result; 975 return AE_OK; 976 } 977 break; 978 default: 979 return AE_ERROR; 980 } 981 return AE_OK; 982 } 983 984 static acpi_status AMW0_set_u32(u32 value, u32 cap) 985 { 986 struct wmab_args args; 987 988 args.eax = ACER_AMW0_WRITE; 989 args.ebx = value ? (1<<8) : 0; 990 args.ecx = args.edx = 0; 991 992 switch (cap) { 993 case ACER_CAP_MAILLED: 994 if (value > 1) 995 return AE_BAD_PARAMETER; 996 args.ebx |= ACER_AMW0_MAILLED_MASK; 997 break; 998 case ACER_CAP_WIRELESS: 999 if (value > 1) 1000 return AE_BAD_PARAMETER; 1001 args.ebx |= ACER_AMW0_WIRELESS_MASK; 1002 break; 1003 case ACER_CAP_BLUETOOTH: 1004 if (value > 1) 1005 return AE_BAD_PARAMETER; 1006 args.ebx |= ACER_AMW0_BLUETOOTH_MASK; 1007 break; 1008 case ACER_CAP_BRIGHTNESS: 1009 if (value > max_brightness) 1010 return AE_BAD_PARAMETER; 1011 switch (quirks->brightness) { 1012 default: 1013 return ec_write(0x83, value); 1014 } 1015 default: 1016 return AE_ERROR; 1017 } 1018 1019 /* Actually do the set */ 1020 return wmab_execute(&args, NULL); 1021 } 1022 1023 static acpi_status __init AMW0_find_mailled(void) 1024 { 1025 struct wmab_args args; 1026 struct wmab_ret ret; 1027 acpi_status status = AE_OK; 1028 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; 1029 union acpi_object *obj; 1030 1031 args.eax = 0x86; 1032 args.ebx = args.ecx = args.edx = 0; 1033 1034 status = wmab_execute(&args, &out); 1035 if (ACPI_FAILURE(status)) 1036 return status; 1037 1038 obj = (union acpi_object *) out.pointer; 1039 if (obj && obj->type == ACPI_TYPE_BUFFER && 1040 obj->buffer.length == sizeof(struct wmab_ret)) { 1041 ret = *((struct wmab_ret *) obj->buffer.pointer); 1042 } else { 1043 kfree(out.pointer); 1044 return AE_ERROR; 1045 } 1046 1047 if (ret.eex & 0x1) 1048 interface->capability |= ACER_CAP_MAILLED; 1049 1050 kfree(out.pointer); 1051 1052 return AE_OK; 1053 } 1054 1055 static const struct acpi_device_id norfkill_ids[] __initconst = { 1056 { "VPC2004", 0}, 1057 { "IBM0068", 0}, 1058 { "LEN0068", 0}, 1059 { "SNY5001", 0}, /* sony-laptop in charge */ 1060 { "HPQ6601", 0}, 1061 { "", 0}, 1062 }; 1063 1064 static int __init AMW0_set_cap_acpi_check_device(void) 1065 { 1066 const struct acpi_device_id *id; 1067 1068 for (id = norfkill_ids; id->id[0]; id++) 1069 if (acpi_dev_found(id->id)) 1070 return true; 1071 1072 return false; 1073 } 1074 1075 static acpi_status __init AMW0_set_capabilities(void) 1076 { 1077 struct wmab_args args; 1078 struct wmab_ret ret; 1079 acpi_status status; 1080 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; 1081 union acpi_object *obj; 1082 1083 /* 1084 * On laptops with this strange GUID (non Acer), normal probing doesn't 1085 * work. 1086 */ 1087 if (wmi_has_guid(AMW0_GUID2)) { 1088 if ((quirks != &quirk_unknown) || 1089 !AMW0_set_cap_acpi_check_device()) 1090 interface->capability |= ACER_CAP_WIRELESS; 1091 return AE_OK; 1092 } 1093 1094 args.eax = ACER_AMW0_WRITE; 1095 args.ecx = args.edx = 0; 1096 1097 args.ebx = 0xa2 << 8; 1098 args.ebx |= ACER_AMW0_WIRELESS_MASK; 1099 1100 status = wmab_execute(&args, &out); 1101 if (ACPI_FAILURE(status)) 1102 return status; 1103 1104 obj = out.pointer; 1105 if (obj && obj->type == ACPI_TYPE_BUFFER && 1106 obj->buffer.length == sizeof(struct wmab_ret)) { 1107 ret = *((struct wmab_ret *) obj->buffer.pointer); 1108 } else { 1109 status = AE_ERROR; 1110 goto out; 1111 } 1112 1113 if (ret.eax & 0x1) 1114 interface->capability |= ACER_CAP_WIRELESS; 1115 1116 args.ebx = 2 << 8; 1117 args.ebx |= ACER_AMW0_BLUETOOTH_MASK; 1118 1119 /* 1120 * It's ok to use existing buffer for next wmab_execute call. 1121 * But we need to kfree(out.pointer) if next wmab_execute fail. 1122 */ 1123 status = wmab_execute(&args, &out); 1124 if (ACPI_FAILURE(status)) 1125 goto out; 1126 1127 obj = (union acpi_object *) out.pointer; 1128 if (obj && obj->type == ACPI_TYPE_BUFFER 1129 && obj->buffer.length == sizeof(struct wmab_ret)) { 1130 ret = *((struct wmab_ret *) obj->buffer.pointer); 1131 } else { 1132 status = AE_ERROR; 1133 goto out; 1134 } 1135 1136 if (ret.eax & 0x1) 1137 interface->capability |= ACER_CAP_BLUETOOTH; 1138 1139 /* 1140 * This appears to be safe to enable, since all Wistron based laptops 1141 * appear to use the same EC register for brightness, even if they 1142 * differ for wireless, etc 1143 */ 1144 if (quirks->brightness >= 0) 1145 interface->capability |= ACER_CAP_BRIGHTNESS; 1146 1147 status = AE_OK; 1148 out: 1149 kfree(out.pointer); 1150 return status; 1151 } 1152 1153 static struct wmi_interface AMW0_interface = { 1154 .type = ACER_AMW0, 1155 }; 1156 1157 static struct wmi_interface AMW0_V2_interface = { 1158 .type = ACER_AMW0_V2, 1159 }; 1160 1161 /* 1162 * New interface (The WMID interface) 1163 */ 1164 static acpi_status 1165 WMI_execute_u32(u32 method_id, u32 in, u32 *out) 1166 { 1167 struct acpi_buffer input = { (acpi_size) sizeof(u32), (void *)(&in) }; 1168 struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL }; 1169 union acpi_object *obj; 1170 u32 tmp = 0; 1171 acpi_status status; 1172 1173 status = wmi_evaluate_method(WMID_GUID1, 0, method_id, &input, &result); 1174 1175 if (ACPI_FAILURE(status)) 1176 return status; 1177 1178 obj = (union acpi_object *) result.pointer; 1179 if (obj) { 1180 if (obj->type == ACPI_TYPE_BUFFER && 1181 (obj->buffer.length == sizeof(u32) || 1182 obj->buffer.length == sizeof(u64))) { 1183 tmp = *((u32 *) obj->buffer.pointer); 1184 } else if (obj->type == ACPI_TYPE_INTEGER) { 1185 tmp = (u32) obj->integer.value; 1186 } 1187 } 1188 1189 if (out) 1190 *out = tmp; 1191 1192 kfree(result.pointer); 1193 1194 return status; 1195 } 1196 1197 static acpi_status WMID_get_u32(u32 *value, u32 cap) 1198 { 1199 acpi_status status; 1200 u8 tmp; 1201 u32 result, method_id = 0; 1202 1203 switch (cap) { 1204 case ACER_CAP_WIRELESS: 1205 method_id = ACER_WMID_GET_WIRELESS_METHODID; 1206 break; 1207 case ACER_CAP_BLUETOOTH: 1208 method_id = ACER_WMID_GET_BLUETOOTH_METHODID; 1209 break; 1210 case ACER_CAP_BRIGHTNESS: 1211 method_id = ACER_WMID_GET_BRIGHTNESS_METHODID; 1212 break; 1213 case ACER_CAP_THREEG: 1214 method_id = ACER_WMID_GET_THREEG_METHODID; 1215 break; 1216 case ACER_CAP_MAILLED: 1217 if (quirks->mailled == 1) { 1218 ec_read(0x9f, &tmp); 1219 *value = tmp & 0x1; 1220 return 0; 1221 } 1222 fallthrough; 1223 default: 1224 return AE_ERROR; 1225 } 1226 status = WMI_execute_u32(method_id, 0, &result); 1227 1228 if (ACPI_SUCCESS(status)) 1229 *value = (u8)result; 1230 1231 return status; 1232 } 1233 1234 static acpi_status WMID_set_u32(u32 value, u32 cap) 1235 { 1236 u32 method_id = 0; 1237 char param; 1238 1239 switch (cap) { 1240 case ACER_CAP_BRIGHTNESS: 1241 if (value > max_brightness) 1242 return AE_BAD_PARAMETER; 1243 method_id = ACER_WMID_SET_BRIGHTNESS_METHODID; 1244 break; 1245 case ACER_CAP_WIRELESS: 1246 if (value > 1) 1247 return AE_BAD_PARAMETER; 1248 method_id = ACER_WMID_SET_WIRELESS_METHODID; 1249 break; 1250 case ACER_CAP_BLUETOOTH: 1251 if (value > 1) 1252 return AE_BAD_PARAMETER; 1253 method_id = ACER_WMID_SET_BLUETOOTH_METHODID; 1254 break; 1255 case ACER_CAP_THREEG: 1256 if (value > 1) 1257 return AE_BAD_PARAMETER; 1258 method_id = ACER_WMID_SET_THREEG_METHODID; 1259 break; 1260 case ACER_CAP_MAILLED: 1261 if (value > 1) 1262 return AE_BAD_PARAMETER; 1263 if (quirks->mailled == 1) { 1264 param = value ? 0x92 : 0x93; 1265 i8042_lock_chip(); 1266 i8042_command(¶m, 0x1059); 1267 i8042_unlock_chip(); 1268 return 0; 1269 } 1270 break; 1271 default: 1272 return AE_ERROR; 1273 } 1274 return WMI_execute_u32(method_id, (u32)value, NULL); 1275 } 1276 1277 static acpi_status wmid3_get_device_status(u32 *value, u16 device) 1278 { 1279 struct wmid3_gds_return_value return_value; 1280 acpi_status status; 1281 union acpi_object *obj; 1282 struct wmid3_gds_get_input_param params = { 1283 .function_num = 0x1, 1284 .hotkey_number = commun_fn_key_number, 1285 .devices = device, 1286 }; 1287 struct acpi_buffer input = { 1288 sizeof(struct wmid3_gds_get_input_param), 1289 ¶ms 1290 }; 1291 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 1292 1293 status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output); 1294 if (ACPI_FAILURE(status)) 1295 return status; 1296 1297 obj = output.pointer; 1298 1299 if (!obj) 1300 return AE_ERROR; 1301 else if (obj->type != ACPI_TYPE_BUFFER) { 1302 kfree(obj); 1303 return AE_ERROR; 1304 } 1305 if (obj->buffer.length != 8) { 1306 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 1307 kfree(obj); 1308 return AE_ERROR; 1309 } 1310 1311 return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); 1312 kfree(obj); 1313 1314 if (return_value.error_code || return_value.ec_return_value) 1315 pr_warn("Get 0x%x Device Status failed: 0x%x - 0x%x\n", 1316 device, 1317 return_value.error_code, 1318 return_value.ec_return_value); 1319 else 1320 *value = !!(return_value.devices & device); 1321 1322 return status; 1323 } 1324 1325 static acpi_status wmid_v2_get_u32(u32 *value, u32 cap) 1326 { 1327 u16 device; 1328 1329 switch (cap) { 1330 case ACER_CAP_WIRELESS: 1331 device = ACER_WMID3_GDS_WIRELESS; 1332 break; 1333 case ACER_CAP_BLUETOOTH: 1334 device = ACER_WMID3_GDS_BLUETOOTH; 1335 break; 1336 case ACER_CAP_THREEG: 1337 device = ACER_WMID3_GDS_THREEG; 1338 break; 1339 default: 1340 return AE_ERROR; 1341 } 1342 return wmid3_get_device_status(value, device); 1343 } 1344 1345 static acpi_status wmid3_set_device_status(u32 value, u16 device) 1346 { 1347 struct wmid3_gds_return_value return_value; 1348 acpi_status status; 1349 union acpi_object *obj; 1350 u16 devices; 1351 struct wmid3_gds_get_input_param get_params = { 1352 .function_num = 0x1, 1353 .hotkey_number = commun_fn_key_number, 1354 .devices = commun_func_bitmap, 1355 }; 1356 struct acpi_buffer get_input = { 1357 sizeof(struct wmid3_gds_get_input_param), 1358 &get_params 1359 }; 1360 struct wmid3_gds_set_input_param set_params = { 1361 .function_num = 0x2, 1362 .hotkey_number = commun_fn_key_number, 1363 .devices = commun_func_bitmap, 1364 }; 1365 struct acpi_buffer set_input = { 1366 sizeof(struct wmid3_gds_set_input_param), 1367 &set_params 1368 }; 1369 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 1370 struct acpi_buffer output2 = { ACPI_ALLOCATE_BUFFER, NULL }; 1371 1372 status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &get_input, &output); 1373 if (ACPI_FAILURE(status)) 1374 return status; 1375 1376 obj = output.pointer; 1377 1378 if (!obj) 1379 return AE_ERROR; 1380 else if (obj->type != ACPI_TYPE_BUFFER) { 1381 kfree(obj); 1382 return AE_ERROR; 1383 } 1384 if (obj->buffer.length != 8) { 1385 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 1386 kfree(obj); 1387 return AE_ERROR; 1388 } 1389 1390 return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); 1391 kfree(obj); 1392 1393 if (return_value.error_code || return_value.ec_return_value) { 1394 pr_warn("Get Current Device Status failed: 0x%x - 0x%x\n", 1395 return_value.error_code, 1396 return_value.ec_return_value); 1397 return status; 1398 } 1399 1400 devices = return_value.devices; 1401 set_params.devices = (value) ? (devices | device) : (devices & ~device); 1402 1403 status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &set_input, &output2); 1404 if (ACPI_FAILURE(status)) 1405 return status; 1406 1407 obj = output2.pointer; 1408 1409 if (!obj) 1410 return AE_ERROR; 1411 else if (obj->type != ACPI_TYPE_BUFFER) { 1412 kfree(obj); 1413 return AE_ERROR; 1414 } 1415 if (obj->buffer.length != 4) { 1416 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 1417 kfree(obj); 1418 return AE_ERROR; 1419 } 1420 1421 return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); 1422 kfree(obj); 1423 1424 if (return_value.error_code || return_value.ec_return_value) 1425 pr_warn("Set Device Status failed: 0x%x - 0x%x\n", 1426 return_value.error_code, 1427 return_value.ec_return_value); 1428 1429 return status; 1430 } 1431 1432 static acpi_status wmid_v2_set_u32(u32 value, u32 cap) 1433 { 1434 u16 device; 1435 1436 switch (cap) { 1437 case ACER_CAP_WIRELESS: 1438 device = ACER_WMID3_GDS_WIRELESS; 1439 break; 1440 case ACER_CAP_BLUETOOTH: 1441 device = ACER_WMID3_GDS_BLUETOOTH; 1442 break; 1443 case ACER_CAP_THREEG: 1444 device = ACER_WMID3_GDS_THREEG; 1445 break; 1446 default: 1447 return AE_ERROR; 1448 } 1449 return wmid3_set_device_status(value, device); 1450 } 1451 1452 static void __init type_aa_dmi_decode(const struct dmi_header *header, void *d) 1453 { 1454 struct hotkey_function_type_aa *type_aa; 1455 1456 /* We are looking for OEM-specific Type AAh */ 1457 if (header->type != 0xAA) 1458 return; 1459 1460 has_type_aa = true; 1461 type_aa = (struct hotkey_function_type_aa *) header; 1462 1463 pr_info("Function bitmap for Communication Button: 0x%x\n", 1464 type_aa->commun_func_bitmap); 1465 commun_func_bitmap = type_aa->commun_func_bitmap; 1466 1467 if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_WIRELESS) 1468 interface->capability |= ACER_CAP_WIRELESS; 1469 if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_THREEG) 1470 interface->capability |= ACER_CAP_THREEG; 1471 if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_BLUETOOTH) 1472 interface->capability |= ACER_CAP_BLUETOOTH; 1473 if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN) 1474 commun_func_bitmap &= ~ACER_WMID3_GDS_RFBTN; 1475 1476 commun_fn_key_number = type_aa->commun_fn_key_number; 1477 } 1478 1479 static acpi_status __init WMID_set_capabilities(void) 1480 { 1481 struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL}; 1482 union acpi_object *obj; 1483 acpi_status status; 1484 u32 devices; 1485 1486 status = wmi_query_block(WMID_GUID2, 0, &out); 1487 if (ACPI_FAILURE(status)) 1488 return status; 1489 1490 obj = (union acpi_object *) out.pointer; 1491 if (obj) { 1492 if (obj->type == ACPI_TYPE_BUFFER && 1493 (obj->buffer.length == sizeof(u32) || 1494 obj->buffer.length == sizeof(u64))) { 1495 devices = *((u32 *) obj->buffer.pointer); 1496 } else if (obj->type == ACPI_TYPE_INTEGER) { 1497 devices = (u32) obj->integer.value; 1498 } else { 1499 kfree(out.pointer); 1500 return AE_ERROR; 1501 } 1502 } else { 1503 kfree(out.pointer); 1504 return AE_ERROR; 1505 } 1506 1507 pr_info("Function bitmap for Communication Device: 0x%x\n", devices); 1508 if (devices & 0x07) 1509 interface->capability |= ACER_CAP_WIRELESS; 1510 if (devices & 0x40) 1511 interface->capability |= ACER_CAP_THREEG; 1512 if (devices & 0x10) 1513 interface->capability |= ACER_CAP_BLUETOOTH; 1514 1515 if (!(devices & 0x20)) 1516 max_brightness = 0x9; 1517 1518 kfree(out.pointer); 1519 return status; 1520 } 1521 1522 static struct wmi_interface wmid_interface = { 1523 .type = ACER_WMID, 1524 }; 1525 1526 static struct wmi_interface wmid_v2_interface = { 1527 .type = ACER_WMID_v2, 1528 }; 1529 1530 /* 1531 * WMID Gaming interface 1532 */ 1533 1534 static acpi_status 1535 WMI_gaming_execute_u64(u32 method_id, u64 in, u64 *out) 1536 { 1537 struct acpi_buffer input = { (acpi_size) sizeof(u64), (void *)(&in) }; 1538 struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL }; 1539 union acpi_object *obj; 1540 u64 tmp = 0; 1541 acpi_status status; 1542 1543 status = wmi_evaluate_method(WMID_GUID4, 0, method_id, &input, &result); 1544 1545 if (ACPI_FAILURE(status)) 1546 return status; 1547 obj = (union acpi_object *) result.pointer; 1548 1549 if (obj) { 1550 if (obj->type == ACPI_TYPE_BUFFER) { 1551 if (obj->buffer.length == sizeof(u32)) 1552 tmp = *((u32 *) obj->buffer.pointer); 1553 else if (obj->buffer.length == sizeof(u64)) 1554 tmp = *((u64 *) obj->buffer.pointer); 1555 } else if (obj->type == ACPI_TYPE_INTEGER) { 1556 tmp = (u64) obj->integer.value; 1557 } 1558 } 1559 1560 if (out) 1561 *out = tmp; 1562 1563 kfree(result.pointer); 1564 1565 return status; 1566 } 1567 1568 static int WMI_gaming_execute_u32_u64(u32 method_id, u32 in, u64 *out) 1569 { 1570 struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL }; 1571 struct acpi_buffer input = { 1572 .length = sizeof(in), 1573 .pointer = &in, 1574 }; 1575 union acpi_object *obj; 1576 acpi_status status; 1577 int ret = 0; 1578 1579 status = wmi_evaluate_method(WMID_GUID4, 0, method_id, &input, &result); 1580 if (ACPI_FAILURE(status)) 1581 return -EIO; 1582 1583 obj = result.pointer; 1584 if (obj && out) { 1585 switch (obj->type) { 1586 case ACPI_TYPE_INTEGER: 1587 *out = obj->integer.value; 1588 break; 1589 case ACPI_TYPE_BUFFER: 1590 if (obj->buffer.length < sizeof(*out)) 1591 ret = -ENOMSG; 1592 else 1593 *out = get_unaligned_le64(obj->buffer.pointer); 1594 1595 break; 1596 default: 1597 ret = -ENOMSG; 1598 break; 1599 } 1600 } 1601 1602 kfree(obj); 1603 1604 return ret; 1605 } 1606 1607 static acpi_status WMID_gaming_set_u64(u64 value, u32 cap) 1608 { 1609 u32 method_id = 0; 1610 1611 if (!(interface->capability & cap)) 1612 return AE_BAD_PARAMETER; 1613 1614 switch (cap) { 1615 case ACER_CAP_TURBO_LED: 1616 method_id = ACER_WMID_SET_GAMING_LED_METHODID; 1617 break; 1618 default: 1619 return AE_BAD_PARAMETER; 1620 } 1621 1622 return WMI_gaming_execute_u64(method_id, value, NULL); 1623 } 1624 1625 static acpi_status WMID_gaming_get_u64(u64 *value, u32 cap) 1626 { 1627 acpi_status status; 1628 u64 result; 1629 u64 input; 1630 u32 method_id; 1631 1632 if (!(interface->capability & cap)) 1633 return AE_BAD_PARAMETER; 1634 1635 switch (cap) { 1636 case ACER_CAP_TURBO_LED: 1637 method_id = ACER_WMID_GET_GAMING_LED_METHODID; 1638 input = 0x1; 1639 break; 1640 default: 1641 return AE_BAD_PARAMETER; 1642 } 1643 status = WMI_gaming_execute_u64(method_id, input, &result); 1644 if (ACPI_SUCCESS(status)) 1645 *value = (u64) result; 1646 1647 return status; 1648 } 1649 1650 static int WMID_gaming_get_sys_info(u32 command, u64 *out) 1651 { 1652 acpi_status status; 1653 u64 result; 1654 1655 status = WMI_gaming_execute_u64(ACER_WMID_GET_GAMING_SYS_INFO_METHODID, command, &result); 1656 if (ACPI_FAILURE(status)) 1657 return -EIO; 1658 1659 /* The return status must be zero for the operation to have succeeded */ 1660 if (FIELD_GET(ACER_PREDATOR_V4_RETURN_STATUS_BIT_MASK, result)) 1661 return -EIO; 1662 1663 *out = result; 1664 1665 return 0; 1666 } 1667 1668 static int WMID_gaming_set_fan_behavior(u16 fan_bitmap, enum acer_wmi_gaming_fan_mode mode) 1669 { 1670 acpi_status status; 1671 u64 input = 0; 1672 u64 result; 1673 1674 input |= FIELD_PREP(ACER_GAMING_FAN_BEHAVIOR_ID_MASK, fan_bitmap); 1675 1676 if (fan_bitmap & ACER_GAMING_FAN_BEHAVIOR_CPU) 1677 input |= FIELD_PREP(ACER_GAMING_FAN_BEHAVIOR_SET_CPU_MODE_MASK, mode); 1678 1679 if (fan_bitmap & ACER_GAMING_FAN_BEHAVIOR_GPU) 1680 input |= FIELD_PREP(ACER_GAMING_FAN_BEHAVIOR_SET_GPU_MODE_MASK, mode); 1681 1682 status = WMI_gaming_execute_u64(ACER_WMID_SET_GAMING_FAN_BEHAVIOR_METHODID, input, 1683 &result); 1684 if (ACPI_FAILURE(status)) 1685 return -EIO; 1686 1687 /* The return status must be zero for the operation to have succeeded */ 1688 if (FIELD_GET(ACER_GAMING_FAN_BEHAVIOR_STATUS_MASK, result)) 1689 return -EIO; 1690 1691 return 0; 1692 } 1693 1694 static int WMID_gaming_get_fan_behavior(u16 fan_bitmap, enum acer_wmi_gaming_fan_mode *mode) 1695 { 1696 acpi_status status; 1697 u32 input = 0; 1698 u64 result; 1699 int value; 1700 1701 input |= FIELD_PREP(ACER_GAMING_FAN_BEHAVIOR_ID_MASK, fan_bitmap); 1702 status = WMI_gaming_execute_u32_u64(ACER_WMID_GET_GAMING_FAN_BEHAVIOR_METHODID, input, 1703 &result); 1704 if (ACPI_FAILURE(status)) 1705 return -EIO; 1706 1707 /* The return status must be zero for the operation to have succeeded */ 1708 if (FIELD_GET(ACER_GAMING_FAN_BEHAVIOR_STATUS_MASK, result)) 1709 return -EIO; 1710 1711 /* Theoretically multiple fans can be specified, but this is currently unused */ 1712 if (fan_bitmap & ACER_GAMING_FAN_BEHAVIOR_CPU) 1713 value = FIELD_GET(ACER_GAMING_FAN_BEHAVIOR_GET_CPU_MODE_MASK, result); 1714 else if (fan_bitmap & ACER_GAMING_FAN_BEHAVIOR_GPU) 1715 value = FIELD_GET(ACER_GAMING_FAN_BEHAVIOR_GET_GPU_MODE_MASK, result); 1716 else 1717 return -EINVAL; 1718 1719 if (value < ACER_WMID_FAN_MODE_AUTO || value > ACER_WMID_FAN_MODE_CUSTOM) 1720 return -ENXIO; 1721 1722 *mode = value; 1723 1724 return 0; 1725 } 1726 1727 static void WMID_gaming_set_fan_mode(enum acer_wmi_gaming_fan_mode mode) 1728 { 1729 u16 fan_bitmap = 0; 1730 1731 if (quirks->cpu_fans > 0) 1732 fan_bitmap |= ACER_GAMING_FAN_BEHAVIOR_CPU; 1733 1734 if (quirks->gpu_fans > 0) 1735 fan_bitmap |= ACER_GAMING_FAN_BEHAVIOR_GPU; 1736 1737 WMID_gaming_set_fan_behavior(fan_bitmap, mode); 1738 } 1739 1740 static int WMID_gaming_set_gaming_fan_speed(u8 fan, u8 speed) 1741 { 1742 acpi_status status; 1743 u64 input = 0; 1744 u64 result; 1745 1746 if (speed > 100) 1747 return -EINVAL; 1748 1749 input |= FIELD_PREP(ACER_GAMING_FAN_SPEED_ID_MASK, fan); 1750 input |= FIELD_PREP(ACER_GAMING_FAN_SPEED_VALUE_MASK, speed); 1751 1752 status = WMI_gaming_execute_u64(ACER_WMID_SET_GAMING_FAN_SPEED_METHODID, input, &result); 1753 if (ACPI_FAILURE(status)) 1754 return -EIO; 1755 1756 switch (FIELD_GET(ACER_GAMING_FAN_SPEED_STATUS_MASK, result)) { 1757 case 0x00: 1758 return 0; 1759 case 0x01: 1760 return -ENODEV; 1761 case 0x02: 1762 return -EINVAL; 1763 default: 1764 return -ENXIO; 1765 } 1766 } 1767 1768 static int WMID_gaming_get_gaming_fan_speed(u8 fan, u8 *speed) 1769 { 1770 acpi_status status; 1771 u32 input = 0; 1772 u64 result; 1773 1774 input |= FIELD_PREP(ACER_GAMING_FAN_SPEED_ID_MASK, fan); 1775 1776 status = WMI_gaming_execute_u32_u64(ACER_WMID_GET_GAMING_FAN_SPEED_METHODID, input, 1777 &result); 1778 if (ACPI_FAILURE(status)) 1779 return -EIO; 1780 1781 if (FIELD_GET(ACER_GAMING_FAN_SPEED_STATUS_MASK, result)) 1782 return -ENODEV; 1783 1784 *speed = FIELD_GET(ACER_GAMING_FAN_SPEED_VALUE_MASK, result); 1785 1786 return 0; 1787 } 1788 1789 static int WMID_gaming_set_misc_setting(enum acer_wmi_gaming_misc_setting setting, u8 value) 1790 { 1791 acpi_status status; 1792 u64 input = 0; 1793 u64 result; 1794 1795 input |= FIELD_PREP(ACER_GAMING_MISC_SETTING_INDEX_MASK, setting); 1796 input |= FIELD_PREP(ACER_GAMING_MISC_SETTING_VALUE_MASK, value); 1797 1798 status = WMI_gaming_execute_u64(ACER_WMID_SET_GAMING_MISC_SETTING_METHODID, input, &result); 1799 if (ACPI_FAILURE(status)) 1800 return -EIO; 1801 1802 /* The return status must be zero for the operation to have succeeded */ 1803 if (FIELD_GET(ACER_GAMING_MISC_SETTING_STATUS_MASK, result)) 1804 return -EIO; 1805 1806 return 0; 1807 } 1808 1809 static int WMID_gaming_get_misc_setting(enum acer_wmi_gaming_misc_setting setting, u8 *value) 1810 { 1811 u64 input = 0; 1812 u64 result; 1813 int ret; 1814 1815 input |= FIELD_PREP(ACER_GAMING_MISC_SETTING_INDEX_MASK, setting); 1816 1817 ret = WMI_gaming_execute_u32_u64(ACER_WMID_GET_GAMING_MISC_SETTING_METHODID, input, 1818 &result); 1819 if (ret < 0) 1820 return ret; 1821 1822 /* The return status must be zero for the operation to have succeeded */ 1823 if (FIELD_GET(ACER_GAMING_MISC_SETTING_STATUS_MASK, result)) 1824 return -EIO; 1825 1826 *value = FIELD_GET(ACER_GAMING_MISC_SETTING_VALUE_MASK, result); 1827 1828 return 0; 1829 } 1830 1831 /* 1832 * Generic Device (interface-independent) 1833 */ 1834 1835 static acpi_status get_u32(u32 *value, u32 cap) 1836 { 1837 acpi_status status = AE_ERROR; 1838 1839 switch (interface->type) { 1840 case ACER_AMW0: 1841 status = AMW0_get_u32(value, cap); 1842 break; 1843 case ACER_AMW0_V2: 1844 if (cap == ACER_CAP_MAILLED) { 1845 status = AMW0_get_u32(value, cap); 1846 break; 1847 } 1848 fallthrough; 1849 case ACER_WMID: 1850 status = WMID_get_u32(value, cap); 1851 break; 1852 case ACER_WMID_v2: 1853 if (cap & (ACER_CAP_WIRELESS | 1854 ACER_CAP_BLUETOOTH | 1855 ACER_CAP_THREEG)) 1856 status = wmid_v2_get_u32(value, cap); 1857 else if (wmi_has_guid(WMID_GUID2)) 1858 status = WMID_get_u32(value, cap); 1859 break; 1860 } 1861 1862 return status; 1863 } 1864 1865 static acpi_status set_u32(u32 value, u32 cap) 1866 { 1867 acpi_status status; 1868 1869 if (interface->capability & cap) { 1870 switch (interface->type) { 1871 case ACER_AMW0: 1872 return AMW0_set_u32(value, cap); 1873 case ACER_AMW0_V2: 1874 if (cap == ACER_CAP_MAILLED) 1875 return AMW0_set_u32(value, cap); 1876 1877 /* 1878 * On some models, some WMID methods don't toggle 1879 * properly. For those cases, we want to run the AMW0 1880 * method afterwards to be certain we've really toggled 1881 * the device state. 1882 */ 1883 if (cap == ACER_CAP_WIRELESS || 1884 cap == ACER_CAP_BLUETOOTH) { 1885 status = WMID_set_u32(value, cap); 1886 if (ACPI_FAILURE(status)) 1887 return status; 1888 1889 return AMW0_set_u32(value, cap); 1890 } 1891 fallthrough; 1892 case ACER_WMID: 1893 return WMID_set_u32(value, cap); 1894 case ACER_WMID_v2: 1895 if (cap & (ACER_CAP_WIRELESS | 1896 ACER_CAP_BLUETOOTH | 1897 ACER_CAP_THREEG)) 1898 return wmid_v2_set_u32(value, cap); 1899 else if (wmi_has_guid(WMID_GUID2)) 1900 return WMID_set_u32(value, cap); 1901 fallthrough; 1902 default: 1903 return AE_BAD_PARAMETER; 1904 } 1905 } 1906 return AE_BAD_PARAMETER; 1907 } 1908 1909 static void __init acer_commandline_init(void) 1910 { 1911 /* 1912 * These will all fail silently if the value given is invalid, or the 1913 * capability isn't available on the given interface 1914 */ 1915 if (mailled >= 0) 1916 set_u32(mailled, ACER_CAP_MAILLED); 1917 if (!has_type_aa && threeg >= 0) 1918 set_u32(threeg, ACER_CAP_THREEG); 1919 if (brightness >= 0) 1920 set_u32(brightness, ACER_CAP_BRIGHTNESS); 1921 } 1922 1923 /* 1924 * LED device (Mail LED only, no other LEDs known yet) 1925 */ 1926 static void mail_led_set(struct led_classdev *led_cdev, 1927 enum led_brightness value) 1928 { 1929 set_u32(value, ACER_CAP_MAILLED); 1930 } 1931 1932 static struct led_classdev mail_led = { 1933 .name = "acer-wmi::mail", 1934 .brightness_set = mail_led_set, 1935 }; 1936 1937 static int acer_led_init(struct device *dev) 1938 { 1939 return led_classdev_register(dev, &mail_led); 1940 } 1941 1942 static void acer_led_exit(void) 1943 { 1944 set_u32(LED_OFF, ACER_CAP_MAILLED); 1945 led_classdev_unregister(&mail_led); 1946 } 1947 1948 /* 1949 * Backlight device 1950 */ 1951 static struct backlight_device *acer_backlight_device; 1952 1953 static int read_brightness(struct backlight_device *bd) 1954 { 1955 u32 value; 1956 get_u32(&value, ACER_CAP_BRIGHTNESS); 1957 return value; 1958 } 1959 1960 static int update_bl_status(struct backlight_device *bd) 1961 { 1962 int intensity = backlight_get_brightness(bd); 1963 1964 set_u32(intensity, ACER_CAP_BRIGHTNESS); 1965 1966 return 0; 1967 } 1968 1969 static const struct backlight_ops acer_bl_ops = { 1970 .get_brightness = read_brightness, 1971 .update_status = update_bl_status, 1972 }; 1973 1974 static int acer_backlight_init(struct device *dev) 1975 { 1976 struct backlight_properties props; 1977 struct backlight_device *bd; 1978 1979 memset(&props, 0, sizeof(struct backlight_properties)); 1980 props.type = BACKLIGHT_PLATFORM; 1981 props.max_brightness = max_brightness; 1982 bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops, 1983 &props); 1984 if (IS_ERR(bd)) { 1985 pr_err("Could not register Acer backlight device\n"); 1986 acer_backlight_device = NULL; 1987 return PTR_ERR(bd); 1988 } 1989 1990 acer_backlight_device = bd; 1991 1992 bd->props.power = BACKLIGHT_POWER_ON; 1993 bd->props.brightness = read_brightness(bd); 1994 backlight_update_status(bd); 1995 return 0; 1996 } 1997 1998 static void acer_backlight_exit(void) 1999 { 2000 backlight_device_unregister(acer_backlight_device); 2001 } 2002 2003 /* 2004 * Accelerometer device 2005 */ 2006 static acpi_handle gsensor_handle; 2007 2008 static int acer_gsensor_init(void) 2009 { 2010 acpi_status status; 2011 struct acpi_buffer output; 2012 union acpi_object out_obj; 2013 2014 output.length = sizeof(out_obj); 2015 output.pointer = &out_obj; 2016 status = acpi_evaluate_object(gsensor_handle, "_INI", NULL, &output); 2017 if (ACPI_FAILURE(status)) 2018 return -1; 2019 2020 return 0; 2021 } 2022 2023 static int acer_gsensor_open(struct input_dev *input) 2024 { 2025 return acer_gsensor_init(); 2026 } 2027 2028 static int acer_gsensor_event(void) 2029 { 2030 acpi_status status; 2031 struct acpi_buffer output; 2032 union acpi_object out_obj[5]; 2033 2034 if (!acer_wmi_accel_dev) 2035 return -1; 2036 2037 output.length = sizeof(out_obj); 2038 output.pointer = out_obj; 2039 2040 status = acpi_evaluate_object(gsensor_handle, "RDVL", NULL, &output); 2041 if (ACPI_FAILURE(status)) 2042 return -1; 2043 2044 if (out_obj->package.count != 4) 2045 return -1; 2046 2047 input_report_abs(acer_wmi_accel_dev, ABS_X, 2048 (s16)out_obj->package.elements[0].integer.value); 2049 input_report_abs(acer_wmi_accel_dev, ABS_Y, 2050 (s16)out_obj->package.elements[1].integer.value); 2051 input_report_abs(acer_wmi_accel_dev, ABS_Z, 2052 (s16)out_obj->package.elements[2].integer.value); 2053 input_sync(acer_wmi_accel_dev); 2054 return 0; 2055 } 2056 2057 /* 2058 * Predator series turbo button 2059 */ 2060 static int acer_toggle_turbo(void) 2061 { 2062 u64 turbo_led_state; 2063 2064 /* Get current state from turbo button */ 2065 if (ACPI_FAILURE(WMID_gaming_get_u64(&turbo_led_state, ACER_CAP_TURBO_LED))) 2066 return -1; 2067 2068 if (turbo_led_state) { 2069 /* Turn off turbo led */ 2070 WMID_gaming_set_u64(0x1, ACER_CAP_TURBO_LED); 2071 2072 /* Set FAN mode to auto */ 2073 if (has_cap(ACER_CAP_TURBO_FAN)) 2074 WMID_gaming_set_fan_mode(ACER_WMID_FAN_MODE_AUTO); 2075 2076 /* Set OC to normal */ 2077 if (has_cap(ACER_CAP_TURBO_OC)) { 2078 WMID_gaming_set_misc_setting(ACER_WMID_MISC_SETTING_OC_1, 2079 ACER_WMID_OC_NORMAL); 2080 WMID_gaming_set_misc_setting(ACER_WMID_MISC_SETTING_OC_2, 2081 ACER_WMID_OC_NORMAL); 2082 } 2083 } else { 2084 /* Turn on turbo led */ 2085 WMID_gaming_set_u64(0x10001, ACER_CAP_TURBO_LED); 2086 2087 /* Set FAN mode to turbo */ 2088 if (has_cap(ACER_CAP_TURBO_FAN)) 2089 WMID_gaming_set_fan_mode(ACER_WMID_FAN_MODE_TURBO); 2090 2091 /* Set OC to turbo mode */ 2092 if (has_cap(ACER_CAP_TURBO_OC)) { 2093 WMID_gaming_set_misc_setting(ACER_WMID_MISC_SETTING_OC_1, 2094 ACER_WMID_OC_TURBO); 2095 WMID_gaming_set_misc_setting(ACER_WMID_MISC_SETTING_OC_2, 2096 ACER_WMID_OC_TURBO); 2097 } 2098 } 2099 return turbo_led_state; 2100 } 2101 2102 static int 2103 acer_predator_v4_platform_profile_get(struct device *dev, 2104 enum platform_profile_option *profile) 2105 { 2106 u8 tp; 2107 int err; 2108 2109 err = WMID_gaming_get_misc_setting(ACER_WMID_MISC_SETTING_PLATFORM_PROFILE, &tp); 2110 if (err) 2111 return err; 2112 2113 switch (tp) { 2114 case ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO: 2115 *profile = PLATFORM_PROFILE_PERFORMANCE; 2116 break; 2117 case ACER_PREDATOR_V4_THERMAL_PROFILE_PERFORMANCE: 2118 *profile = PLATFORM_PROFILE_BALANCED_PERFORMANCE; 2119 break; 2120 case ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED: 2121 *profile = PLATFORM_PROFILE_BALANCED; 2122 break; 2123 case ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET: 2124 *profile = PLATFORM_PROFILE_QUIET; 2125 break; 2126 case ACER_PREDATOR_V4_THERMAL_PROFILE_ECO: 2127 *profile = PLATFORM_PROFILE_LOW_POWER; 2128 break; 2129 default: 2130 return -EOPNOTSUPP; 2131 } 2132 2133 return 0; 2134 } 2135 2136 static int 2137 acer_predator_v4_platform_profile_set(struct device *dev, 2138 enum platform_profile_option profile) 2139 { 2140 int err, tp; 2141 2142 switch (profile) { 2143 case PLATFORM_PROFILE_PERFORMANCE: 2144 tp = ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO; 2145 break; 2146 case PLATFORM_PROFILE_BALANCED_PERFORMANCE: 2147 tp = ACER_PREDATOR_V4_THERMAL_PROFILE_PERFORMANCE; 2148 break; 2149 case PLATFORM_PROFILE_BALANCED: 2150 tp = ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED; 2151 break; 2152 case PLATFORM_PROFILE_QUIET: 2153 tp = ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET; 2154 break; 2155 case PLATFORM_PROFILE_LOW_POWER: 2156 tp = ACER_PREDATOR_V4_THERMAL_PROFILE_ECO; 2157 break; 2158 default: 2159 return -EOPNOTSUPP; 2160 } 2161 2162 err = WMID_gaming_set_misc_setting(ACER_WMID_MISC_SETTING_PLATFORM_PROFILE, tp); 2163 if (err) 2164 return err; 2165 2166 if (tp != ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO) 2167 last_non_turbo_profile = tp; 2168 2169 return 0; 2170 } 2171 2172 static int 2173 acer_predator_v4_platform_profile_probe(void *drvdata, unsigned long *choices) 2174 { 2175 set_bit(PLATFORM_PROFILE_PERFORMANCE, choices); 2176 set_bit(PLATFORM_PROFILE_BALANCED_PERFORMANCE, choices); 2177 set_bit(PLATFORM_PROFILE_BALANCED, choices); 2178 set_bit(PLATFORM_PROFILE_QUIET, choices); 2179 set_bit(PLATFORM_PROFILE_LOW_POWER, choices); 2180 2181 /* Set default non-turbo profile */ 2182 last_non_turbo_profile = ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED; 2183 2184 return 0; 2185 } 2186 2187 static const struct platform_profile_ops acer_predator_v4_platform_profile_ops = { 2188 .probe = acer_predator_v4_platform_profile_probe, 2189 .profile_get = acer_predator_v4_platform_profile_get, 2190 .profile_set = acer_predator_v4_platform_profile_set, 2191 }; 2192 2193 static int acer_platform_profile_setup(struct platform_device *device) 2194 { 2195 if (quirks->predator_v4) { 2196 platform_profile_device = devm_platform_profile_register( 2197 &device->dev, "acer-wmi", NULL, &acer_predator_v4_platform_profile_ops); 2198 if (IS_ERR(platform_profile_device)) 2199 return PTR_ERR(platform_profile_device); 2200 2201 platform_profile_support = true; 2202 } 2203 return 0; 2204 } 2205 2206 static int acer_thermal_profile_change(void) 2207 { 2208 /* 2209 * This mode key will either cycle through each mode or toggle the 2210 * most performant profile. 2211 */ 2212 if (quirks->predator_v4) { 2213 u8 current_tp; 2214 int err, tp; 2215 2216 if (cycle_gaming_thermal_profile) { 2217 platform_profile_cycle(); 2218 } else { 2219 err = WMID_gaming_get_misc_setting( 2220 ACER_WMID_MISC_SETTING_PLATFORM_PROFILE, ¤t_tp); 2221 if (err) 2222 return err; 2223 2224 if (current_tp == ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO) 2225 tp = last_non_turbo_profile; 2226 else 2227 tp = ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO; 2228 2229 err = WMID_gaming_set_misc_setting( 2230 ACER_WMID_MISC_SETTING_PLATFORM_PROFILE, tp); 2231 if (err) 2232 return err; 2233 2234 /* Store last profile for toggle */ 2235 if (current_tp != ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO) 2236 last_non_turbo_profile = current_tp; 2237 2238 platform_profile_notify(platform_profile_device); 2239 } 2240 } 2241 2242 return 0; 2243 } 2244 2245 /* 2246 * Switch series keyboard dock status 2247 */ 2248 static int acer_kbd_dock_state_to_sw_tablet_mode(u8 kbd_dock_state) 2249 { 2250 switch (kbd_dock_state) { 2251 case 0x01: /* Docked, traditional clamshell laptop mode */ 2252 return 0; 2253 case 0x04: /* Stand-alone tablet */ 2254 case 0x40: /* Docked, tent mode, keyboard not usable */ 2255 return 1; 2256 default: 2257 pr_warn("Unknown kbd_dock_state 0x%02x\n", kbd_dock_state); 2258 } 2259 2260 return 0; 2261 } 2262 2263 static void acer_kbd_dock_get_initial_state(void) 2264 { 2265 u8 *output, input[8] = { 0x05, 0x00, }; 2266 struct acpi_buffer input_buf = { sizeof(input), input }; 2267 struct acpi_buffer output_buf = { ACPI_ALLOCATE_BUFFER, NULL }; 2268 union acpi_object *obj; 2269 acpi_status status; 2270 int sw_tablet_mode; 2271 2272 status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input_buf, &output_buf); 2273 if (ACPI_FAILURE(status)) { 2274 pr_err("Error getting keyboard-dock initial status: %s\n", 2275 acpi_format_exception(status)); 2276 return; 2277 } 2278 2279 obj = output_buf.pointer; 2280 if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) { 2281 pr_err("Unexpected output format getting keyboard-dock initial status\n"); 2282 goto out_free_obj; 2283 } 2284 2285 output = obj->buffer.pointer; 2286 if (output[0] != 0x00 || (output[3] != 0x05 && output[3] != 0x45)) { 2287 pr_err("Unexpected output [0]=0x%02x [3]=0x%02x getting keyboard-dock initial status\n", 2288 output[0], output[3]); 2289 goto out_free_obj; 2290 } 2291 2292 sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(output[4]); 2293 input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode); 2294 2295 out_free_obj: 2296 kfree(obj); 2297 } 2298 2299 static void acer_kbd_dock_event(const struct event_return_value *event) 2300 { 2301 int sw_tablet_mode; 2302 2303 if (!has_cap(ACER_CAP_KBD_DOCK)) 2304 return; 2305 2306 sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(event->kbd_dock_state); 2307 input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode); 2308 input_sync(acer_wmi_input_dev); 2309 } 2310 2311 /* 2312 * Rfkill devices 2313 */ 2314 static void acer_rfkill_update(struct work_struct *ignored); 2315 static DECLARE_DELAYED_WORK(acer_rfkill_work, acer_rfkill_update); 2316 static void acer_rfkill_update(struct work_struct *ignored) 2317 { 2318 u32 state; 2319 acpi_status status; 2320 2321 if (has_cap(ACER_CAP_WIRELESS)) { 2322 status = get_u32(&state, ACER_CAP_WIRELESS); 2323 if (ACPI_SUCCESS(status)) { 2324 if (quirks->wireless == 3) 2325 rfkill_set_hw_state(wireless_rfkill, !state); 2326 else 2327 rfkill_set_sw_state(wireless_rfkill, !state); 2328 } 2329 } 2330 2331 if (has_cap(ACER_CAP_BLUETOOTH)) { 2332 status = get_u32(&state, ACER_CAP_BLUETOOTH); 2333 if (ACPI_SUCCESS(status)) 2334 rfkill_set_sw_state(bluetooth_rfkill, !state); 2335 } 2336 2337 if (has_cap(ACER_CAP_THREEG) && wmi_has_guid(WMID_GUID3)) { 2338 status = get_u32(&state, ACER_WMID3_GDS_THREEG); 2339 if (ACPI_SUCCESS(status)) 2340 rfkill_set_sw_state(threeg_rfkill, !state); 2341 } 2342 2343 schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ)); 2344 } 2345 2346 static int acer_rfkill_set(void *data, bool blocked) 2347 { 2348 acpi_status status; 2349 u32 cap = (unsigned long)data; 2350 2351 if (rfkill_inited) { 2352 status = set_u32(!blocked, cap); 2353 if (ACPI_FAILURE(status)) 2354 return -ENODEV; 2355 } 2356 2357 return 0; 2358 } 2359 2360 static const struct rfkill_ops acer_rfkill_ops = { 2361 .set_block = acer_rfkill_set, 2362 }; 2363 2364 static struct rfkill *acer_rfkill_register(struct device *dev, 2365 enum rfkill_type type, 2366 char *name, u32 cap) 2367 { 2368 int err; 2369 struct rfkill *rfkill_dev; 2370 u32 state; 2371 acpi_status status; 2372 2373 rfkill_dev = rfkill_alloc(name, dev, type, 2374 &acer_rfkill_ops, 2375 (void *)(unsigned long)cap); 2376 if (!rfkill_dev) 2377 return ERR_PTR(-ENOMEM); 2378 2379 status = get_u32(&state, cap); 2380 2381 err = rfkill_register(rfkill_dev); 2382 if (err) { 2383 rfkill_destroy(rfkill_dev); 2384 return ERR_PTR(err); 2385 } 2386 2387 if (ACPI_SUCCESS(status)) 2388 rfkill_set_sw_state(rfkill_dev, !state); 2389 2390 return rfkill_dev; 2391 } 2392 2393 static int acer_rfkill_init(struct device *dev) 2394 { 2395 int err; 2396 2397 if (has_cap(ACER_CAP_WIRELESS)) { 2398 wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN, 2399 "acer-wireless", ACER_CAP_WIRELESS); 2400 if (IS_ERR(wireless_rfkill)) { 2401 err = PTR_ERR(wireless_rfkill); 2402 goto error_wireless; 2403 } 2404 } 2405 2406 if (has_cap(ACER_CAP_BLUETOOTH)) { 2407 bluetooth_rfkill = acer_rfkill_register(dev, 2408 RFKILL_TYPE_BLUETOOTH, "acer-bluetooth", 2409 ACER_CAP_BLUETOOTH); 2410 if (IS_ERR(bluetooth_rfkill)) { 2411 err = PTR_ERR(bluetooth_rfkill); 2412 goto error_bluetooth; 2413 } 2414 } 2415 2416 if (has_cap(ACER_CAP_THREEG)) { 2417 threeg_rfkill = acer_rfkill_register(dev, 2418 RFKILL_TYPE_WWAN, "acer-threeg", 2419 ACER_CAP_THREEG); 2420 if (IS_ERR(threeg_rfkill)) { 2421 err = PTR_ERR(threeg_rfkill); 2422 goto error_threeg; 2423 } 2424 } 2425 2426 rfkill_inited = true; 2427 2428 if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) && 2429 has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG)) 2430 schedule_delayed_work(&acer_rfkill_work, 2431 round_jiffies_relative(HZ)); 2432 2433 return 0; 2434 2435 error_threeg: 2436 if (has_cap(ACER_CAP_BLUETOOTH)) { 2437 rfkill_unregister(bluetooth_rfkill); 2438 rfkill_destroy(bluetooth_rfkill); 2439 } 2440 error_bluetooth: 2441 if (has_cap(ACER_CAP_WIRELESS)) { 2442 rfkill_unregister(wireless_rfkill); 2443 rfkill_destroy(wireless_rfkill); 2444 } 2445 error_wireless: 2446 return err; 2447 } 2448 2449 static void acer_rfkill_exit(void) 2450 { 2451 if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) && 2452 has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG)) 2453 cancel_delayed_work_sync(&acer_rfkill_work); 2454 2455 if (has_cap(ACER_CAP_WIRELESS)) { 2456 rfkill_unregister(wireless_rfkill); 2457 rfkill_destroy(wireless_rfkill); 2458 } 2459 2460 if (has_cap(ACER_CAP_BLUETOOTH)) { 2461 rfkill_unregister(bluetooth_rfkill); 2462 rfkill_destroy(bluetooth_rfkill); 2463 } 2464 2465 if (has_cap(ACER_CAP_THREEG)) { 2466 rfkill_unregister(threeg_rfkill); 2467 rfkill_destroy(threeg_rfkill); 2468 } 2469 } 2470 2471 static void acer_wmi_notify(union acpi_object *obj, void *context) 2472 { 2473 struct event_return_value return_value; 2474 u16 device_state; 2475 const struct key_entry *key; 2476 u32 scancode; 2477 2478 if (!obj) 2479 return; 2480 if (obj->type != ACPI_TYPE_BUFFER) { 2481 pr_warn("Unknown response received %d\n", obj->type); 2482 return; 2483 } 2484 if (obj->buffer.length != 8) { 2485 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 2486 return; 2487 } 2488 2489 return_value = *((struct event_return_value *)obj->buffer.pointer); 2490 2491 switch (return_value.function) { 2492 case WMID_HOTKEY_EVENT: 2493 device_state = return_value.device_state; 2494 pr_debug("device state: 0x%x\n", device_state); 2495 2496 key = sparse_keymap_entry_from_scancode(acer_wmi_input_dev, 2497 return_value.key_num); 2498 if (!key) { 2499 pr_warn("Unknown key number - 0x%x\n", 2500 return_value.key_num); 2501 } else { 2502 scancode = return_value.key_num; 2503 switch (key->keycode) { 2504 case KEY_WLAN: 2505 case KEY_BLUETOOTH: 2506 if (has_cap(ACER_CAP_WIRELESS)) 2507 rfkill_set_sw_state(wireless_rfkill, 2508 !(device_state & ACER_WMID3_GDS_WIRELESS)); 2509 if (has_cap(ACER_CAP_THREEG)) 2510 rfkill_set_sw_state(threeg_rfkill, 2511 !(device_state & ACER_WMID3_GDS_THREEG)); 2512 if (has_cap(ACER_CAP_BLUETOOTH)) 2513 rfkill_set_sw_state(bluetooth_rfkill, 2514 !(device_state & ACER_WMID3_GDS_BLUETOOTH)); 2515 break; 2516 case KEY_TOUCHPAD_TOGGLE: 2517 scancode = (device_state & ACER_WMID3_GDS_TOUCHPAD) ? 2518 KEY_TOUCHPAD_ON : KEY_TOUCHPAD_OFF; 2519 } 2520 sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true); 2521 } 2522 break; 2523 case WMID_BACKLIGHT_EVENT: 2524 /* Already handled by acpi-video */ 2525 break; 2526 case WMID_ACCEL_OR_KBD_DOCK_EVENT: 2527 acer_gsensor_event(); 2528 acer_kbd_dock_event(&return_value); 2529 break; 2530 case WMID_GAMING_TURBO_KEY_EVENT: 2531 if (return_value.key_num == 0x4) 2532 acer_toggle_turbo(); 2533 if (return_value.key_num == 0x5 && has_cap(ACER_CAP_PLATFORM_PROFILE)) 2534 acer_thermal_profile_change(); 2535 break; 2536 case WMID_AC_EVENT: 2537 /* We ignore AC events here */ 2538 break; 2539 default: 2540 pr_warn("Unknown function number - %d - %d\n", 2541 return_value.function, return_value.key_num); 2542 break; 2543 } 2544 } 2545 2546 static acpi_status __init 2547 wmid3_set_function_mode(struct func_input_params *params, 2548 struct func_return_value *return_value) 2549 { 2550 acpi_status status; 2551 union acpi_object *obj; 2552 2553 struct acpi_buffer input = { sizeof(struct func_input_params), params }; 2554 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 2555 2556 status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output); 2557 if (ACPI_FAILURE(status)) 2558 return status; 2559 2560 obj = output.pointer; 2561 2562 if (!obj) 2563 return AE_ERROR; 2564 else if (obj->type != ACPI_TYPE_BUFFER) { 2565 kfree(obj); 2566 return AE_ERROR; 2567 } 2568 if (obj->buffer.length != 4) { 2569 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 2570 kfree(obj); 2571 return AE_ERROR; 2572 } 2573 2574 *return_value = *((struct func_return_value *)obj->buffer.pointer); 2575 kfree(obj); 2576 2577 return status; 2578 } 2579 2580 static int __init acer_wmi_enable_ec_raw(void) 2581 { 2582 struct func_return_value return_value; 2583 acpi_status status; 2584 struct func_input_params params = { 2585 .function_num = 0x1, 2586 .commun_devices = 0xFFFF, 2587 .devices = 0xFFFF, 2588 .app_status = 0x00, /* Launch Manager Deactive */ 2589 .app_mask = 0x01, 2590 }; 2591 2592 status = wmid3_set_function_mode(¶ms, &return_value); 2593 2594 if (return_value.error_code || return_value.ec_return_value) 2595 pr_warn("Enabling EC raw mode failed: 0x%x - 0x%x\n", 2596 return_value.error_code, 2597 return_value.ec_return_value); 2598 else 2599 pr_info("Enabled EC raw mode\n"); 2600 2601 return status; 2602 } 2603 2604 static int __init acer_wmi_enable_lm(void) 2605 { 2606 struct func_return_value return_value; 2607 acpi_status status; 2608 struct func_input_params params = { 2609 .function_num = 0x1, 2610 .commun_devices = 0xFFFF, 2611 .devices = 0xFFFF, 2612 .app_status = 0x01, /* Launch Manager Active */ 2613 .app_mask = 0x01, 2614 }; 2615 2616 status = wmid3_set_function_mode(¶ms, &return_value); 2617 2618 if (return_value.error_code || return_value.ec_return_value) 2619 pr_warn("Enabling Launch Manager failed: 0x%x - 0x%x\n", 2620 return_value.error_code, 2621 return_value.ec_return_value); 2622 2623 return status; 2624 } 2625 2626 static int __init acer_wmi_enable_rf_button(void) 2627 { 2628 struct func_return_value return_value; 2629 acpi_status status; 2630 struct func_input_params params = { 2631 .function_num = 0x1, 2632 .commun_devices = 0xFFFF, 2633 .devices = 0xFFFF, 2634 .app_status = 0x10, /* RF Button Active */ 2635 .app_mask = 0x10, 2636 }; 2637 2638 status = wmid3_set_function_mode(¶ms, &return_value); 2639 2640 if (return_value.error_code || return_value.ec_return_value) 2641 pr_warn("Enabling RF Button failed: 0x%x - 0x%x\n", 2642 return_value.error_code, 2643 return_value.ec_return_value); 2644 2645 return status; 2646 } 2647 2648 static int __init acer_wmi_accel_setup(void) 2649 { 2650 struct acpi_device *adev; 2651 int err; 2652 2653 adev = acpi_dev_get_first_match_dev("BST0001", NULL, -1); 2654 if (!adev) 2655 return -ENODEV; 2656 2657 gsensor_handle = acpi_device_handle(adev); 2658 acpi_dev_put(adev); 2659 2660 acer_wmi_accel_dev = input_allocate_device(); 2661 if (!acer_wmi_accel_dev) 2662 return -ENOMEM; 2663 2664 acer_wmi_accel_dev->open = acer_gsensor_open; 2665 2666 acer_wmi_accel_dev->name = "Acer BMA150 accelerometer"; 2667 acer_wmi_accel_dev->phys = "wmi/input1"; 2668 acer_wmi_accel_dev->id.bustype = BUS_HOST; 2669 acer_wmi_accel_dev->evbit[0] = BIT_MASK(EV_ABS); 2670 input_set_abs_params(acer_wmi_accel_dev, ABS_X, -16384, 16384, 0, 0); 2671 input_set_abs_params(acer_wmi_accel_dev, ABS_Y, -16384, 16384, 0, 0); 2672 input_set_abs_params(acer_wmi_accel_dev, ABS_Z, -16384, 16384, 0, 0); 2673 2674 err = input_register_device(acer_wmi_accel_dev); 2675 if (err) 2676 goto err_free_dev; 2677 2678 return 0; 2679 2680 err_free_dev: 2681 input_free_device(acer_wmi_accel_dev); 2682 return err; 2683 } 2684 2685 static int __init acer_wmi_input_setup(void) 2686 { 2687 acpi_status status; 2688 int err; 2689 2690 acer_wmi_input_dev = input_allocate_device(); 2691 if (!acer_wmi_input_dev) 2692 return -ENOMEM; 2693 2694 acer_wmi_input_dev->name = "Acer WMI hotkeys"; 2695 acer_wmi_input_dev->phys = "wmi/input0"; 2696 acer_wmi_input_dev->id.bustype = BUS_HOST; 2697 2698 err = sparse_keymap_setup(acer_wmi_input_dev, acer_wmi_keymap, NULL); 2699 if (err) 2700 goto err_free_dev; 2701 2702 if (has_cap(ACER_CAP_KBD_DOCK)) 2703 input_set_capability(acer_wmi_input_dev, EV_SW, SW_TABLET_MODE); 2704 2705 status = wmi_install_notify_handler(ACERWMID_EVENT_GUID, 2706 acer_wmi_notify, NULL); 2707 if (ACPI_FAILURE(status)) { 2708 err = -EIO; 2709 goto err_free_dev; 2710 } 2711 2712 if (has_cap(ACER_CAP_KBD_DOCK)) 2713 acer_kbd_dock_get_initial_state(); 2714 2715 err = input_register_device(acer_wmi_input_dev); 2716 if (err) 2717 goto err_uninstall_notifier; 2718 2719 return 0; 2720 2721 err_uninstall_notifier: 2722 wmi_remove_notify_handler(ACERWMID_EVENT_GUID); 2723 err_free_dev: 2724 input_free_device(acer_wmi_input_dev); 2725 return err; 2726 } 2727 2728 static void acer_wmi_input_destroy(void) 2729 { 2730 wmi_remove_notify_handler(ACERWMID_EVENT_GUID); 2731 input_unregister_device(acer_wmi_input_dev); 2732 } 2733 2734 /* 2735 * debugfs functions 2736 */ 2737 static u32 get_wmid_devices(void) 2738 { 2739 struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL}; 2740 union acpi_object *obj; 2741 acpi_status status; 2742 u32 devices = 0; 2743 2744 status = wmi_query_block(WMID_GUID2, 0, &out); 2745 if (ACPI_FAILURE(status)) 2746 return 0; 2747 2748 obj = (union acpi_object *) out.pointer; 2749 if (obj) { 2750 if (obj->type == ACPI_TYPE_BUFFER && 2751 (obj->buffer.length == sizeof(u32) || 2752 obj->buffer.length == sizeof(u64))) { 2753 devices = *((u32 *) obj->buffer.pointer); 2754 } else if (obj->type == ACPI_TYPE_INTEGER) { 2755 devices = (u32) obj->integer.value; 2756 } 2757 } 2758 2759 kfree(out.pointer); 2760 return devices; 2761 } 2762 2763 static int acer_wmi_hwmon_init(void); 2764 2765 /* 2766 * Platform device 2767 */ 2768 static int acer_platform_probe(struct platform_device *device) 2769 { 2770 int err; 2771 2772 if (has_cap(ACER_CAP_MAILLED)) { 2773 err = acer_led_init(&device->dev); 2774 if (err) 2775 goto error_mailled; 2776 } 2777 2778 if (has_cap(ACER_CAP_BRIGHTNESS)) { 2779 err = acer_backlight_init(&device->dev); 2780 if (err) 2781 goto error_brightness; 2782 } 2783 2784 err = acer_rfkill_init(&device->dev); 2785 if (err) 2786 goto error_rfkill; 2787 2788 if (has_cap(ACER_CAP_PLATFORM_PROFILE)) { 2789 err = acer_platform_profile_setup(device); 2790 if (err) 2791 goto error_platform_profile; 2792 } 2793 2794 if (has_cap(ACER_CAP_HWMON)) { 2795 err = acer_wmi_hwmon_init(); 2796 if (err) 2797 goto error_hwmon; 2798 } 2799 2800 return 0; 2801 2802 error_hwmon: 2803 error_platform_profile: 2804 acer_rfkill_exit(); 2805 error_rfkill: 2806 if (has_cap(ACER_CAP_BRIGHTNESS)) 2807 acer_backlight_exit(); 2808 error_brightness: 2809 if (has_cap(ACER_CAP_MAILLED)) 2810 acer_led_exit(); 2811 error_mailled: 2812 return err; 2813 } 2814 2815 static void acer_platform_remove(struct platform_device *device) 2816 { 2817 if (has_cap(ACER_CAP_MAILLED)) 2818 acer_led_exit(); 2819 if (has_cap(ACER_CAP_BRIGHTNESS)) 2820 acer_backlight_exit(); 2821 2822 acer_rfkill_exit(); 2823 } 2824 2825 #ifdef CONFIG_PM_SLEEP 2826 static int acer_suspend(struct device *dev) 2827 { 2828 u32 value; 2829 struct acer_data *data = &interface->data; 2830 2831 if (!data) 2832 return -ENOMEM; 2833 2834 if (has_cap(ACER_CAP_MAILLED)) { 2835 get_u32(&value, ACER_CAP_MAILLED); 2836 set_u32(LED_OFF, ACER_CAP_MAILLED); 2837 data->mailled = value; 2838 } 2839 2840 if (has_cap(ACER_CAP_BRIGHTNESS)) { 2841 get_u32(&value, ACER_CAP_BRIGHTNESS); 2842 data->brightness = value; 2843 } 2844 2845 return 0; 2846 } 2847 2848 static int acer_resume(struct device *dev) 2849 { 2850 struct acer_data *data = &interface->data; 2851 2852 if (!data) 2853 return -ENOMEM; 2854 2855 if (has_cap(ACER_CAP_MAILLED)) 2856 set_u32(data->mailled, ACER_CAP_MAILLED); 2857 2858 if (has_cap(ACER_CAP_BRIGHTNESS)) 2859 set_u32(data->brightness, ACER_CAP_BRIGHTNESS); 2860 2861 if (acer_wmi_accel_dev) 2862 acer_gsensor_init(); 2863 2864 return 0; 2865 } 2866 #else 2867 #define acer_suspend NULL 2868 #define acer_resume NULL 2869 #endif 2870 2871 static SIMPLE_DEV_PM_OPS(acer_pm, acer_suspend, acer_resume); 2872 2873 static void acer_platform_shutdown(struct platform_device *device) 2874 { 2875 struct acer_data *data = &interface->data; 2876 2877 if (!data) 2878 return; 2879 2880 if (has_cap(ACER_CAP_MAILLED)) 2881 set_u32(LED_OFF, ACER_CAP_MAILLED); 2882 } 2883 2884 static struct platform_driver acer_platform_driver = { 2885 .driver = { 2886 .name = "acer-wmi", 2887 .pm = &acer_pm, 2888 }, 2889 .probe = acer_platform_probe, 2890 .remove = acer_platform_remove, 2891 .shutdown = acer_platform_shutdown, 2892 }; 2893 2894 static struct platform_device *acer_platform_device; 2895 2896 static void remove_debugfs(void) 2897 { 2898 debugfs_remove_recursive(interface->debug.root); 2899 } 2900 2901 static void __init create_debugfs(void) 2902 { 2903 interface->debug.root = debugfs_create_dir("acer-wmi", NULL); 2904 2905 debugfs_create_u32("devices", S_IRUGO, interface->debug.root, 2906 &interface->debug.wmid_devices); 2907 } 2908 2909 static const enum acer_wmi_predator_v4_sensor_id acer_wmi_temp_channel_to_sensor_id[] = { 2910 [0] = ACER_WMID_SENSOR_CPU_TEMPERATURE, 2911 [1] = ACER_WMID_SENSOR_GPU_TEMPERATURE, 2912 [2] = ACER_WMID_SENSOR_EXTERNAL_TEMPERATURE_2, 2913 }; 2914 2915 static const enum acer_wmi_predator_v4_sensor_id acer_wmi_fan_channel_to_sensor_id[] = { 2916 [0] = ACER_WMID_SENSOR_CPU_FAN_SPEED, 2917 [1] = ACER_WMID_SENSOR_GPU_FAN_SPEED, 2918 }; 2919 2920 static const enum acer_wmi_gaming_fan_id acer_wmi_fan_channel_to_fan_id[] = { 2921 [0] = ACER_WMID_CPU_FAN, 2922 [1] = ACER_WMID_GPU_FAN, 2923 }; 2924 2925 static const u16 acer_wmi_fan_channel_to_fan_bitmap[] = { 2926 [0] = ACER_GAMING_FAN_BEHAVIOR_CPU, 2927 [1] = ACER_GAMING_FAN_BEHAVIOR_GPU, 2928 }; 2929 2930 static umode_t acer_wmi_hwmon_is_visible(const void *data, 2931 enum hwmon_sensor_types type, u32 attr, 2932 int channel) 2933 { 2934 enum acer_wmi_predator_v4_sensor_id sensor_id; 2935 const u64 *supported_sensors = data; 2936 2937 switch (type) { 2938 case hwmon_temp: 2939 sensor_id = acer_wmi_temp_channel_to_sensor_id[channel]; 2940 break; 2941 case hwmon_pwm: 2942 if (!has_cap(ACER_CAP_PWM)) 2943 return 0; 2944 2945 fallthrough; 2946 case hwmon_fan: 2947 sensor_id = acer_wmi_fan_channel_to_sensor_id[channel]; 2948 break; 2949 default: 2950 return 0; 2951 } 2952 2953 if (*supported_sensors & BIT(sensor_id - 1)) { 2954 if (type == hwmon_pwm) 2955 return 0644; 2956 2957 return 0444; 2958 } 2959 2960 return 0; 2961 } 2962 2963 static int acer_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type, 2964 u32 attr, int channel, long *val) 2965 { 2966 u64 command = ACER_WMID_CMD_GET_PREDATOR_V4_SENSOR_READING; 2967 enum acer_wmi_gaming_fan_mode mode; 2968 u16 fan_bitmap; 2969 u8 fan, speed; 2970 u64 result; 2971 int ret; 2972 2973 switch (type) { 2974 case hwmon_temp: 2975 command |= FIELD_PREP(ACER_PREDATOR_V4_SENSOR_INDEX_BIT_MASK, 2976 acer_wmi_temp_channel_to_sensor_id[channel]); 2977 2978 ret = WMID_gaming_get_sys_info(command, &result); 2979 if (ret < 0) 2980 return ret; 2981 2982 result = FIELD_GET(ACER_PREDATOR_V4_SENSOR_READING_BIT_MASK, result); 2983 *val = result * MILLIDEGREE_PER_DEGREE; 2984 return 0; 2985 case hwmon_fan: 2986 command |= FIELD_PREP(ACER_PREDATOR_V4_SENSOR_INDEX_BIT_MASK, 2987 acer_wmi_fan_channel_to_sensor_id[channel]); 2988 2989 ret = WMID_gaming_get_sys_info(command, &result); 2990 if (ret < 0) 2991 return ret; 2992 2993 *val = FIELD_GET(ACER_PREDATOR_V4_SENSOR_READING_BIT_MASK, result); 2994 return 0; 2995 case hwmon_pwm: 2996 switch (attr) { 2997 case hwmon_pwm_input: 2998 fan = acer_wmi_fan_channel_to_fan_id[channel]; 2999 ret = WMID_gaming_get_gaming_fan_speed(fan, &speed); 3000 if (ret < 0) 3001 return ret; 3002 3003 *val = fixp_linear_interpolate(0, 0, 100, U8_MAX, speed); 3004 return 0; 3005 case hwmon_pwm_enable: 3006 fan_bitmap = acer_wmi_fan_channel_to_fan_bitmap[channel]; 3007 ret = WMID_gaming_get_fan_behavior(fan_bitmap, &mode); 3008 if (ret < 0) 3009 return ret; 3010 3011 switch (mode) { 3012 case ACER_WMID_FAN_MODE_AUTO: 3013 *val = 2; 3014 return 0; 3015 case ACER_WMID_FAN_MODE_TURBO: 3016 *val = 0; 3017 return 0; 3018 case ACER_WMID_FAN_MODE_CUSTOM: 3019 *val = 1; 3020 return 0; 3021 default: 3022 return -ENXIO; 3023 } 3024 default: 3025 return -EOPNOTSUPP; 3026 } 3027 default: 3028 return -EOPNOTSUPP; 3029 } 3030 } 3031 3032 static int acer_wmi_hwmon_write(struct device *dev, enum hwmon_sensor_types type, 3033 u32 attr, int channel, long val) 3034 { 3035 enum acer_wmi_gaming_fan_mode mode; 3036 u16 fan_bitmap; 3037 u8 fan, speed; 3038 3039 switch (type) { 3040 case hwmon_pwm: 3041 switch (attr) { 3042 case hwmon_pwm_input: 3043 fan = acer_wmi_fan_channel_to_fan_id[channel]; 3044 speed = fixp_linear_interpolate(0, 0, U8_MAX, 100, 3045 clamp_val(val, 0, U8_MAX)); 3046 3047 return WMID_gaming_set_gaming_fan_speed(fan, speed); 3048 case hwmon_pwm_enable: 3049 fan_bitmap = acer_wmi_fan_channel_to_fan_bitmap[channel]; 3050 3051 switch (val) { 3052 case 0: 3053 mode = ACER_WMID_FAN_MODE_TURBO; 3054 break; 3055 case 1: 3056 mode = ACER_WMID_FAN_MODE_CUSTOM; 3057 break; 3058 case 2: 3059 mode = ACER_WMID_FAN_MODE_AUTO; 3060 break; 3061 default: 3062 return -EINVAL; 3063 } 3064 3065 return WMID_gaming_set_fan_behavior(fan_bitmap, mode); 3066 default: 3067 return -EOPNOTSUPP; 3068 } 3069 default: 3070 return -EOPNOTSUPP; 3071 } 3072 } 3073 3074 static const struct hwmon_channel_info *const acer_wmi_hwmon_info[] = { 3075 HWMON_CHANNEL_INFO(temp, 3076 HWMON_T_INPUT, 3077 HWMON_T_INPUT, 3078 HWMON_T_INPUT 3079 ), 3080 HWMON_CHANNEL_INFO(fan, 3081 HWMON_F_INPUT, 3082 HWMON_F_INPUT 3083 ), 3084 HWMON_CHANNEL_INFO(pwm, 3085 HWMON_PWM_INPUT | HWMON_PWM_ENABLE, 3086 HWMON_PWM_INPUT | HWMON_PWM_ENABLE 3087 ), 3088 NULL 3089 }; 3090 3091 static const struct hwmon_ops acer_wmi_hwmon_ops = { 3092 .read = acer_wmi_hwmon_read, 3093 .write = acer_wmi_hwmon_write, 3094 .is_visible = acer_wmi_hwmon_is_visible, 3095 }; 3096 3097 static const struct hwmon_chip_info acer_wmi_hwmon_chip_info = { 3098 .ops = &acer_wmi_hwmon_ops, 3099 .info = acer_wmi_hwmon_info, 3100 }; 3101 3102 static int acer_wmi_hwmon_init(void) 3103 { 3104 struct device *dev = &acer_platform_device->dev; 3105 struct device *hwmon; 3106 u64 result; 3107 int ret; 3108 3109 ret = WMID_gaming_get_sys_info(ACER_WMID_CMD_GET_PREDATOR_V4_SUPPORTED_SENSORS, &result); 3110 if (ret < 0) 3111 return ret; 3112 3113 /* Return early if no sensors are available */ 3114 supported_sensors = FIELD_GET(ACER_PREDATOR_V4_SUPPORTED_SENSORS_BIT_MASK, result); 3115 if (!supported_sensors) 3116 return 0; 3117 3118 hwmon = devm_hwmon_device_register_with_info(dev, "acer", 3119 &supported_sensors, 3120 &acer_wmi_hwmon_chip_info, 3121 NULL); 3122 3123 if (IS_ERR(hwmon)) { 3124 dev_err(dev, "Could not register acer hwmon device\n"); 3125 return PTR_ERR(hwmon); 3126 } 3127 3128 return 0; 3129 } 3130 3131 static int __init acer_wmi_init(void) 3132 { 3133 int err; 3134 3135 pr_info("Acer Laptop ACPI-WMI Extras\n"); 3136 3137 if (dmi_check_system(acer_blacklist)) { 3138 pr_info("Blacklisted hardware detected - not loading\n"); 3139 return -ENODEV; 3140 } 3141 3142 find_quirks(); 3143 3144 /* 3145 * The AMW0_GUID1 wmi is not only found on Acer family but also other 3146 * machines like Lenovo, Fujitsu and Medion. In the past days, 3147 * acer-wmi driver handled those non-Acer machines by quirks list. 3148 * But actually acer-wmi driver was loaded on any machines that have 3149 * AMW0_GUID1. This behavior is strange because those machines should 3150 * be supported by appropriate wmi drivers. e.g. fujitsu-laptop, 3151 * ideapad-laptop. So, here checks the machine that has AMW0_GUID1 3152 * should be in Acer/Gateway/Packard Bell white list, or it's already 3153 * in the past quirk list. 3154 */ 3155 if (wmi_has_guid(AMW0_GUID1) && 3156 !dmi_check_system(amw0_whitelist) && 3157 quirks == &quirk_unknown) { 3158 pr_debug("Unsupported machine has AMW0_GUID1, unable to load\n"); 3159 return -ENODEV; 3160 } 3161 3162 /* 3163 * Detect which ACPI-WMI interface we're using. 3164 */ 3165 if (wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1)) 3166 interface = &AMW0_V2_interface; 3167 3168 if (!wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1)) 3169 interface = &wmid_interface; 3170 3171 if (wmi_has_guid(WMID_GUID3)) 3172 interface = &wmid_v2_interface; 3173 3174 if (interface) 3175 dmi_walk(type_aa_dmi_decode, NULL); 3176 3177 if (wmi_has_guid(WMID_GUID2) && interface) { 3178 if (!has_type_aa && ACPI_FAILURE(WMID_set_capabilities())) { 3179 pr_err("Unable to detect available WMID devices\n"); 3180 return -ENODEV; 3181 } 3182 /* WMID always provides brightness methods */ 3183 interface->capability |= ACER_CAP_BRIGHTNESS; 3184 } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa && force_caps == -1) { 3185 pr_err("No WMID device detection method found\n"); 3186 return -ENODEV; 3187 } 3188 3189 if (wmi_has_guid(AMW0_GUID1) && !wmi_has_guid(WMID_GUID1)) { 3190 interface = &AMW0_interface; 3191 3192 if (ACPI_FAILURE(AMW0_set_capabilities())) { 3193 pr_err("Unable to detect available AMW0 devices\n"); 3194 return -ENODEV; 3195 } 3196 } 3197 3198 if (wmi_has_guid(AMW0_GUID1)) 3199 AMW0_find_mailled(); 3200 3201 if (!interface) { 3202 pr_err("No or unsupported WMI interface, unable to load\n"); 3203 return -ENODEV; 3204 } 3205 3206 set_quirks(); 3207 3208 if (acpi_video_get_backlight_type() != acpi_backlight_vendor) 3209 interface->capability &= ~ACER_CAP_BRIGHTNESS; 3210 3211 if (wmi_has_guid(WMID_GUID3)) 3212 interface->capability |= ACER_CAP_SET_FUNCTION_MODE; 3213 3214 if (force_caps != -1) 3215 interface->capability = force_caps; 3216 3217 if (wmi_has_guid(WMID_GUID3) && 3218 (interface->capability & ACER_CAP_SET_FUNCTION_MODE)) { 3219 if (ACPI_FAILURE(acer_wmi_enable_rf_button())) 3220 pr_warn("Cannot enable RF Button Driver\n"); 3221 3222 if (ec_raw_mode) { 3223 if (ACPI_FAILURE(acer_wmi_enable_ec_raw())) { 3224 pr_err("Cannot enable EC raw mode\n"); 3225 return -ENODEV; 3226 } 3227 } else if (ACPI_FAILURE(acer_wmi_enable_lm())) { 3228 pr_err("Cannot enable Launch Manager mode\n"); 3229 return -ENODEV; 3230 } 3231 } else if (ec_raw_mode) { 3232 pr_info("No WMID EC raw mode enable method\n"); 3233 } 3234 3235 if (wmi_has_guid(ACERWMID_EVENT_GUID)) { 3236 err = acer_wmi_input_setup(); 3237 if (err) 3238 return err; 3239 err = acer_wmi_accel_setup(); 3240 if (err && err != -ENODEV) 3241 pr_warn("Cannot enable accelerometer\n"); 3242 } 3243 3244 err = platform_driver_register(&acer_platform_driver); 3245 if (err) { 3246 pr_err("Unable to register platform driver\n"); 3247 goto error_platform_register; 3248 } 3249 3250 acer_platform_device = platform_device_alloc("acer-wmi", PLATFORM_DEVID_NONE); 3251 if (!acer_platform_device) { 3252 err = -ENOMEM; 3253 goto error_device_alloc; 3254 } 3255 3256 err = platform_device_add(acer_platform_device); 3257 if (err) 3258 goto error_device_add; 3259 3260 if (wmi_has_guid(WMID_GUID2)) { 3261 interface->debug.wmid_devices = get_wmid_devices(); 3262 create_debugfs(); 3263 } 3264 3265 /* Override any initial settings with values from the commandline */ 3266 acer_commandline_init(); 3267 3268 return 0; 3269 3270 error_device_add: 3271 platform_device_put(acer_platform_device); 3272 error_device_alloc: 3273 platform_driver_unregister(&acer_platform_driver); 3274 error_platform_register: 3275 if (wmi_has_guid(ACERWMID_EVENT_GUID)) 3276 acer_wmi_input_destroy(); 3277 if (acer_wmi_accel_dev) 3278 input_unregister_device(acer_wmi_accel_dev); 3279 3280 return err; 3281 } 3282 3283 static void __exit acer_wmi_exit(void) 3284 { 3285 if (wmi_has_guid(ACERWMID_EVENT_GUID)) 3286 acer_wmi_input_destroy(); 3287 3288 if (acer_wmi_accel_dev) 3289 input_unregister_device(acer_wmi_accel_dev); 3290 3291 remove_debugfs(); 3292 platform_device_unregister(acer_platform_device); 3293 platform_driver_unregister(&acer_platform_driver); 3294 3295 pr_info("Acer Laptop WMI Extras unloaded\n"); 3296 } 3297 3298 module_init(acer_wmi_init); 3299 module_exit(acer_wmi_exit); 3300