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