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