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