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