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