1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * HP WMI hotkeys 4 * 5 * Copyright (C) 2008 Red Hat <mjg@redhat.com> 6 * Copyright (C) 2010, 2011 Anssi Hannula <anssi.hannula@iki.fi> 7 * 8 * Portions based on wistron_btns.c: 9 * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz> 10 * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org> 11 * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru> 12 */ 13 14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 15 16 #include <linux/kernel.h> 17 #include <linux/module.h> 18 #include <linux/init.h> 19 #include <linux/slab.h> 20 #include <linux/types.h> 21 #include <linux/input.h> 22 #include <linux/input/sparse-keymap.h> 23 #include <linux/platform_device.h> 24 #include <linux/platform_profile.h> 25 #include <linux/hwmon.h> 26 #include <linux/acpi.h> 27 #include <linux/mutex.h> 28 #include <linux/cleanup.h> 29 #include <linux/power_supply.h> 30 #include <linux/rfkill.h> 31 #include <linux/string.h> 32 #include <linux/dmi.h> 33 34 MODULE_AUTHOR("Matthew Garrett <mjg59@srcf.ucam.org>"); 35 MODULE_DESCRIPTION("HP laptop WMI driver"); 36 MODULE_LICENSE("GPL"); 37 38 MODULE_ALIAS("wmi:95F24279-4D7B-4334-9387-ACCDC67EF61C"); 39 MODULE_ALIAS("wmi:5FB7F034-2C63-45E9-BE91-3D44E2C707E4"); 40 41 #define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C" 42 #define HPWMI_BIOS_GUID "5FB7F034-2C63-45E9-BE91-3D44E2C707E4" 43 44 #define HP_OMEN_EC_THERMAL_PROFILE_FLAGS_OFFSET 0x62 45 #define HP_OMEN_EC_THERMAL_PROFILE_TIMER_OFFSET 0x63 46 #define HP_OMEN_EC_THERMAL_PROFILE_OFFSET 0x95 47 48 #define HP_FAN_SPEED_AUTOMATIC 0x00 49 #define HP_POWER_LIMIT_DEFAULT 0x00 50 #define HP_POWER_LIMIT_NO_CHANGE 0xFF 51 52 #define ACPI_AC_CLASS "ac_adapter" 53 54 #define zero_if_sup(tmp) (zero_insize_support?0:sizeof(tmp)) // use when zero insize is required 55 56 /* DMI board names of devices that should use the omen specific path for 57 * thermal profiles. 58 * This was obtained by taking a look in the windows omen command center 59 * app and parsing a json file that they use to figure out what capabilities 60 * the device should have. 61 * A device is considered an omen if the DisplayName in that list contains 62 * "OMEN", and it can use the thermal profile stuff if the "Feature" array 63 * contains "PerformanceControl". 64 */ 65 static const char * const omen_thermal_profile_boards[] = { 66 "84DA", "84DB", "84DC", "8574", "8575", "860A", "87B5", "8572", "8573", 67 "8600", "8601", "8602", "8605", "8606", "8607", "8746", "8747", "8749", 68 "874A", "8603", "8604", "8748", "886B", "886C", "878A", "878B", "878C", 69 "88C8", "88CB", "8786", "8787", "8788", "88D1", "88D2", "88F4", "88FD", 70 "88F5", "88F6", "88F7", "88FE", "88FF", "8900", "8901", "8902", "8912", 71 "8917", "8918", "8949", "894A", "89EB", "8BAD", "8A42", "8A15" 72 }; 73 74 /* DMI Board names of Omen laptops that are specifically set to be thermal 75 * profile version 0 by the Omen Command Center app, regardless of what 76 * the get system design information WMI call returns 77 */ 78 static const char * const omen_thermal_profile_force_v0_boards[] = { 79 "8607", "8746", "8747", "8749", "874A", "8748" 80 }; 81 82 /* DMI board names of Omen laptops that have a thermal profile timer which will 83 * cause the embedded controller to set the thermal profile back to 84 * "balanced" when reaching zero. 85 */ 86 static const char * const omen_timed_thermal_profile_boards[] = { 87 "8BAD", "8A42", "8A15" 88 }; 89 90 /* DMI Board names of Victus 16-d1xxx laptops */ 91 static const char * const victus_thermal_profile_boards[] = { 92 "8A25" 93 }; 94 95 /* DMI Board names of Victus 16-r and Victus 16-s laptops */ 96 static const char * const victus_s_thermal_profile_boards[] = { 97 "8BBE", "8BD4", "8BD5", 98 "8C78", "8C99", "8C9C", 99 }; 100 101 enum hp_wmi_radio { 102 HPWMI_WIFI = 0x0, 103 HPWMI_BLUETOOTH = 0x1, 104 HPWMI_WWAN = 0x2, 105 HPWMI_GPS = 0x3, 106 }; 107 108 enum hp_wmi_event_ids { 109 HPWMI_DOCK_EVENT = 0x01, 110 HPWMI_PARK_HDD = 0x02, 111 HPWMI_SMART_ADAPTER = 0x03, 112 HPWMI_BEZEL_BUTTON = 0x04, 113 HPWMI_WIRELESS = 0x05, 114 HPWMI_CPU_BATTERY_THROTTLE = 0x06, 115 HPWMI_LOCK_SWITCH = 0x07, 116 HPWMI_LID_SWITCH = 0x08, 117 HPWMI_SCREEN_ROTATION = 0x09, 118 HPWMI_COOLSENSE_SYSTEM_MOBILE = 0x0A, 119 HPWMI_COOLSENSE_SYSTEM_HOT = 0x0B, 120 HPWMI_PROXIMITY_SENSOR = 0x0C, 121 HPWMI_BACKLIT_KB_BRIGHTNESS = 0x0D, 122 HPWMI_PEAKSHIFT_PERIOD = 0x0F, 123 HPWMI_BATTERY_CHARGE_PERIOD = 0x10, 124 HPWMI_SANITIZATION_MODE = 0x17, 125 HPWMI_CAMERA_TOGGLE = 0x1A, 126 HPWMI_FN_P_HOTKEY = 0x1B, 127 HPWMI_OMEN_KEY = 0x1D, 128 HPWMI_SMART_EXPERIENCE_APP = 0x21, 129 }; 130 131 /* 132 * struct bios_args buffer is dynamically allocated. New WMI command types 133 * were introduced that exceeds 128-byte data size. Changes to handle 134 * the data size allocation scheme were kept in hp_wmi_perform_qurey function. 135 */ 136 struct bios_args { 137 u32 signature; 138 u32 command; 139 u32 commandtype; 140 u32 datasize; 141 u8 data[]; 142 }; 143 144 enum hp_wmi_commandtype { 145 HPWMI_DISPLAY_QUERY = 0x01, 146 HPWMI_HDDTEMP_QUERY = 0x02, 147 HPWMI_ALS_QUERY = 0x03, 148 HPWMI_HARDWARE_QUERY = 0x04, 149 HPWMI_WIRELESS_QUERY = 0x05, 150 HPWMI_BATTERY_QUERY = 0x07, 151 HPWMI_BIOS_QUERY = 0x09, 152 HPWMI_FEATURE_QUERY = 0x0b, 153 HPWMI_HOTKEY_QUERY = 0x0c, 154 HPWMI_FEATURE2_QUERY = 0x0d, 155 HPWMI_WIRELESS2_QUERY = 0x1b, 156 HPWMI_POSTCODEERROR_QUERY = 0x2a, 157 HPWMI_SYSTEM_DEVICE_MODE = 0x40, 158 HPWMI_THERMAL_PROFILE_QUERY = 0x4c, 159 }; 160 161 struct victus_power_limits { 162 u8 pl1; 163 u8 pl2; 164 u8 pl4; 165 u8 cpu_gpu_concurrent_limit; 166 }; 167 168 struct victus_gpu_power_modes { 169 u8 ctgp_enable; 170 u8 ppab_enable; 171 u8 dstate; 172 u8 gpu_slowdown_temp; 173 }; 174 175 enum hp_wmi_gm_commandtype { 176 HPWMI_FAN_SPEED_GET_QUERY = 0x11, 177 HPWMI_SET_PERFORMANCE_MODE = 0x1A, 178 HPWMI_FAN_SPEED_MAX_GET_QUERY = 0x26, 179 HPWMI_FAN_SPEED_MAX_SET_QUERY = 0x27, 180 HPWMI_GET_SYSTEM_DESIGN_DATA = 0x28, 181 HPWMI_FAN_COUNT_GET_QUERY = 0x10, 182 HPWMI_GET_GPU_THERMAL_MODES_QUERY = 0x21, 183 HPWMI_SET_GPU_THERMAL_MODES_QUERY = 0x22, 184 HPWMI_SET_POWER_LIMITS_QUERY = 0x29, 185 HPWMI_VICTUS_S_FAN_SPEED_GET_QUERY = 0x2D, 186 HPWMI_FAN_SPEED_SET_QUERY = 0x2E, 187 }; 188 189 enum hp_wmi_command { 190 HPWMI_READ = 0x01, 191 HPWMI_WRITE = 0x02, 192 HPWMI_ODM = 0x03, 193 HPWMI_GM = 0x20008, 194 }; 195 196 enum hp_wmi_hardware_mask { 197 HPWMI_DOCK_MASK = 0x01, 198 HPWMI_TABLET_MASK = 0x04, 199 }; 200 201 struct bios_return { 202 u32 sigpass; 203 u32 return_code; 204 }; 205 206 enum hp_return_value { 207 HPWMI_RET_WRONG_SIGNATURE = 0x02, 208 HPWMI_RET_UNKNOWN_COMMAND = 0x03, 209 HPWMI_RET_UNKNOWN_CMDTYPE = 0x04, 210 HPWMI_RET_INVALID_PARAMETERS = 0x05, 211 }; 212 213 enum hp_wireless2_bits { 214 HPWMI_POWER_STATE = 0x01, 215 HPWMI_POWER_SOFT = 0x02, 216 HPWMI_POWER_BIOS = 0x04, 217 HPWMI_POWER_HARD = 0x08, 218 HPWMI_POWER_FW_OR_HW = HPWMI_POWER_BIOS | HPWMI_POWER_HARD, 219 }; 220 221 enum hp_thermal_profile_omen_v0 { 222 HP_OMEN_V0_THERMAL_PROFILE_DEFAULT = 0x00, 223 HP_OMEN_V0_THERMAL_PROFILE_PERFORMANCE = 0x01, 224 HP_OMEN_V0_THERMAL_PROFILE_COOL = 0x02, 225 }; 226 227 enum hp_thermal_profile_omen_v1 { 228 HP_OMEN_V1_THERMAL_PROFILE_DEFAULT = 0x30, 229 HP_OMEN_V1_THERMAL_PROFILE_PERFORMANCE = 0x31, 230 HP_OMEN_V1_THERMAL_PROFILE_COOL = 0x50, 231 }; 232 233 enum hp_thermal_profile_omen_flags { 234 HP_OMEN_EC_FLAGS_TURBO = 0x04, 235 HP_OMEN_EC_FLAGS_NOTIMER = 0x02, 236 HP_OMEN_EC_FLAGS_JUSTSET = 0x01, 237 }; 238 239 enum hp_thermal_profile_victus { 240 HP_VICTUS_THERMAL_PROFILE_DEFAULT = 0x00, 241 HP_VICTUS_THERMAL_PROFILE_PERFORMANCE = 0x01, 242 HP_VICTUS_THERMAL_PROFILE_QUIET = 0x03, 243 }; 244 245 enum hp_thermal_profile_victus_s { 246 HP_VICTUS_S_THERMAL_PROFILE_DEFAULT = 0x00, 247 HP_VICTUS_S_THERMAL_PROFILE_PERFORMANCE = 0x01, 248 }; 249 250 enum hp_thermal_profile { 251 HP_THERMAL_PROFILE_PERFORMANCE = 0x00, 252 HP_THERMAL_PROFILE_DEFAULT = 0x01, 253 HP_THERMAL_PROFILE_COOL = 0x02, 254 HP_THERMAL_PROFILE_QUIET = 0x03, 255 }; 256 257 #define IS_HWBLOCKED(x) ((x & HPWMI_POWER_FW_OR_HW) != HPWMI_POWER_FW_OR_HW) 258 #define IS_SWBLOCKED(x) !(x & HPWMI_POWER_SOFT) 259 260 struct bios_rfkill2_device_state { 261 u8 radio_type; 262 u8 bus_type; 263 u16 vendor_id; 264 u16 product_id; 265 u16 subsys_vendor_id; 266 u16 subsys_product_id; 267 u8 rfkill_id; 268 u8 power; 269 u8 unknown[4]; 270 }; 271 272 /* 7 devices fit into the 128 byte buffer */ 273 #define HPWMI_MAX_RFKILL2_DEVICES 7 274 275 struct bios_rfkill2_state { 276 u8 unknown[7]; 277 u8 count; 278 u8 pad[8]; 279 struct bios_rfkill2_device_state device[HPWMI_MAX_RFKILL2_DEVICES]; 280 }; 281 282 static const struct key_entry hp_wmi_keymap[] = { 283 { KE_KEY, 0x02, { KEY_BRIGHTNESSUP } }, 284 { KE_KEY, 0x03, { KEY_BRIGHTNESSDOWN } }, 285 { KE_KEY, 0x270, { KEY_MICMUTE } }, 286 { KE_KEY, 0x20e6, { KEY_PROG1 } }, 287 { KE_KEY, 0x20e8, { KEY_MEDIA } }, 288 { KE_KEY, 0x2142, { KEY_MEDIA } }, 289 { KE_KEY, 0x213b, { KEY_INFO } }, 290 { KE_KEY, 0x2169, { KEY_ROTATE_DISPLAY } }, 291 { KE_KEY, 0x216a, { KEY_SETUP } }, 292 { KE_IGNORE, 0x21a4, }, /* Win Lock On */ 293 { KE_IGNORE, 0x121a4, }, /* Win Lock Off */ 294 { KE_KEY, 0x21a5, { KEY_PROG2 } }, /* HP Omen Key */ 295 { KE_KEY, 0x21a7, { KEY_FN_ESC } }, 296 { KE_KEY, 0x21a8, { KEY_PROG2 } }, /* HP Envy x360 programmable key */ 297 { KE_KEY, 0x21a9, { KEY_TOUCHPAD_OFF } }, 298 { KE_KEY, 0x121a9, { KEY_TOUCHPAD_ON } }, 299 { KE_KEY, 0x231b, { KEY_HELP } }, 300 { KE_END, 0 } 301 }; 302 303 /* 304 * Mutex for the active_platform_profile variable, 305 * see omen_powersource_event. 306 */ 307 static DEFINE_MUTEX(active_platform_profile_lock); 308 309 static struct input_dev *hp_wmi_input_dev; 310 static struct input_dev *camera_shutter_input_dev; 311 static struct platform_device *hp_wmi_platform_dev; 312 static struct device *platform_profile_device; 313 static struct notifier_block platform_power_source_nb; 314 static enum platform_profile_option active_platform_profile; 315 static bool platform_profile_support; 316 static bool zero_insize_support; 317 318 static struct rfkill *wifi_rfkill; 319 static struct rfkill *bluetooth_rfkill; 320 static struct rfkill *wwan_rfkill; 321 322 struct rfkill2_device { 323 u8 id; 324 int num; 325 struct rfkill *rfkill; 326 }; 327 328 static int rfkill2_count; 329 static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES]; 330 331 /* 332 * Chassis Types values were obtained from SMBIOS reference 333 * specification version 3.00. A complete list of system enclosures 334 * and chassis types is available on Table 17. 335 */ 336 static const char * const tablet_chassis_types[] = { 337 "30", /* Tablet*/ 338 "31", /* Convertible */ 339 "32" /* Detachable */ 340 }; 341 342 #define DEVICE_MODE_TABLET 0x06 343 344 /* map output size to the corresponding WMI method id */ 345 static inline int encode_outsize_for_pvsz(int outsize) 346 { 347 if (outsize > 4096) 348 return -EINVAL; 349 if (outsize > 1024) 350 return 5; 351 if (outsize > 128) 352 return 4; 353 if (outsize > 4) 354 return 3; 355 if (outsize > 0) 356 return 2; 357 return 1; 358 } 359 360 /* 361 * hp_wmi_perform_query 362 * 363 * query: The commandtype (enum hp_wmi_commandtype) 364 * write: The command (enum hp_wmi_command) 365 * buffer: Buffer used as input and/or output 366 * insize: Size of input buffer 367 * outsize: Size of output buffer 368 * 369 * returns zero on success 370 * an HP WMI query specific error code (which is positive) 371 * -EINVAL if the query was not successful at all 372 * -EINVAL if the output buffer size exceeds buffersize 373 * 374 * Note: The buffersize must at least be the maximum of the input and output 375 * size. E.g. Battery info query is defined to have 1 byte input 376 * and 128 byte output. The caller would do: 377 * buffer = kzalloc(128, GFP_KERNEL); 378 * ret = hp_wmi_perform_query(HPWMI_BATTERY_QUERY, HPWMI_READ, buffer, 1, 128) 379 */ 380 static int hp_wmi_perform_query(int query, enum hp_wmi_command command, 381 void *buffer, int insize, int outsize) 382 { 383 struct acpi_buffer input, output = { ACPI_ALLOCATE_BUFFER, NULL }; 384 struct bios_return *bios_return; 385 union acpi_object *obj = NULL; 386 struct bios_args *args = NULL; 387 int mid, actual_insize, actual_outsize; 388 size_t bios_args_size; 389 int ret; 390 391 mid = encode_outsize_for_pvsz(outsize); 392 if (WARN_ON(mid < 0)) 393 return mid; 394 395 actual_insize = max(insize, 128); 396 bios_args_size = struct_size(args, data, actual_insize); 397 args = kmalloc(bios_args_size, GFP_KERNEL); 398 if (!args) 399 return -ENOMEM; 400 401 input.length = bios_args_size; 402 input.pointer = args; 403 404 args->signature = 0x55434553; 405 args->command = command; 406 args->commandtype = query; 407 args->datasize = insize; 408 memcpy(args->data, buffer, flex_array_size(args, data, insize)); 409 410 ret = wmi_evaluate_method(HPWMI_BIOS_GUID, 0, mid, &input, &output); 411 if (ret) 412 goto out_free; 413 414 obj = output.pointer; 415 if (!obj) { 416 ret = -EINVAL; 417 goto out_free; 418 } 419 420 if (obj->type != ACPI_TYPE_BUFFER) { 421 pr_warn("query 0x%x returned an invalid object 0x%x\n", query, ret); 422 ret = -EINVAL; 423 goto out_free; 424 } 425 426 bios_return = (struct bios_return *)obj->buffer.pointer; 427 ret = bios_return->return_code; 428 429 if (ret) { 430 if (ret != HPWMI_RET_UNKNOWN_COMMAND && 431 ret != HPWMI_RET_UNKNOWN_CMDTYPE) 432 pr_warn("query 0x%x returned error 0x%x\n", query, ret); 433 goto out_free; 434 } 435 436 /* Ignore output data of zero size */ 437 if (!outsize) 438 goto out_free; 439 440 actual_outsize = min(outsize, (int)(obj->buffer.length - sizeof(*bios_return))); 441 memcpy(buffer, obj->buffer.pointer + sizeof(*bios_return), actual_outsize); 442 memset(buffer + actual_outsize, 0, outsize - actual_outsize); 443 444 out_free: 445 kfree(obj); 446 kfree(args); 447 return ret; 448 } 449 450 /* 451 * Calling this hp_wmi_get_fan_count_userdefine_trigger function also enables 452 * and/or maintains the laptop in user defined thermal and fan states, instead 453 * of using a fallback state. After a 120 seconds timeout however, the laptop 454 * goes back to its fallback state. 455 */ 456 static int hp_wmi_get_fan_count_userdefine_trigger(void) 457 { 458 u8 fan_data[4] = {}; 459 int ret; 460 461 ret = hp_wmi_perform_query(HPWMI_FAN_COUNT_GET_QUERY, HPWMI_GM, 462 &fan_data, sizeof(u8), 463 sizeof(fan_data)); 464 if (ret != 0) 465 return -EINVAL; 466 467 return fan_data[0]; /* Others bytes aren't providing fan count */ 468 } 469 470 static int hp_wmi_get_fan_speed(int fan) 471 { 472 u8 fsh, fsl; 473 char fan_data[4] = { fan, 0, 0, 0 }; 474 475 int ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_GET_QUERY, HPWMI_GM, 476 &fan_data, sizeof(char), 477 sizeof(fan_data)); 478 479 if (ret != 0) 480 return -EINVAL; 481 482 fsh = fan_data[2]; 483 fsl = fan_data[3]; 484 485 return (fsh << 8) | fsl; 486 } 487 488 static int hp_wmi_get_fan_speed_victus_s(int fan) 489 { 490 u8 fan_data[128] = {}; 491 int ret; 492 493 if (fan < 0 || fan >= sizeof(fan_data)) 494 return -EINVAL; 495 496 ret = hp_wmi_perform_query(HPWMI_VICTUS_S_FAN_SPEED_GET_QUERY, 497 HPWMI_GM, &fan_data, sizeof(u8), 498 sizeof(fan_data)); 499 if (ret != 0) 500 return -EINVAL; 501 502 return fan_data[fan] * 100; 503 } 504 505 static int hp_wmi_read_int(int query) 506 { 507 int val = 0, ret; 508 509 ret = hp_wmi_perform_query(query, HPWMI_READ, &val, 510 zero_if_sup(val), sizeof(val)); 511 512 if (ret) 513 return ret < 0 ? ret : -EINVAL; 514 515 return val; 516 } 517 518 static int hp_wmi_get_dock_state(void) 519 { 520 int state = hp_wmi_read_int(HPWMI_HARDWARE_QUERY); 521 522 if (state < 0) 523 return state; 524 525 return !!(state & HPWMI_DOCK_MASK); 526 } 527 528 static int hp_wmi_get_tablet_mode(void) 529 { 530 char system_device_mode[4] = { 0 }; 531 const char *chassis_type; 532 bool tablet_found; 533 int ret; 534 535 chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE); 536 if (!chassis_type) 537 return -ENODEV; 538 539 tablet_found = match_string(tablet_chassis_types, 540 ARRAY_SIZE(tablet_chassis_types), 541 chassis_type) >= 0; 542 if (!tablet_found) 543 return -ENODEV; 544 545 ret = hp_wmi_perform_query(HPWMI_SYSTEM_DEVICE_MODE, HPWMI_READ, 546 system_device_mode, zero_if_sup(system_device_mode), 547 sizeof(system_device_mode)); 548 if (ret < 0) 549 return ret; 550 551 return system_device_mode[0] == DEVICE_MODE_TABLET; 552 } 553 554 static int omen_thermal_profile_set(int mode) 555 { 556 /* The Omen Control Center actively sets the first byte of the buffer to 557 * 255, so let's mimic this behaviour to be as close as possible to 558 * the original software. 559 */ 560 char buffer[2] = {-1, mode}; 561 int ret; 562 563 ret = hp_wmi_perform_query(HPWMI_SET_PERFORMANCE_MODE, HPWMI_GM, 564 &buffer, sizeof(buffer), 0); 565 566 if (ret) 567 return ret < 0 ? ret : -EINVAL; 568 569 return mode; 570 } 571 572 static bool is_omen_thermal_profile(void) 573 { 574 const char *board_name = dmi_get_system_info(DMI_BOARD_NAME); 575 576 if (!board_name) 577 return false; 578 579 return match_string(omen_thermal_profile_boards, 580 ARRAY_SIZE(omen_thermal_profile_boards), 581 board_name) >= 0; 582 } 583 584 static int omen_get_thermal_policy_version(void) 585 { 586 unsigned char buffer[8] = { 0 }; 587 int ret; 588 589 const char *board_name = dmi_get_system_info(DMI_BOARD_NAME); 590 591 if (board_name) { 592 int matches = match_string(omen_thermal_profile_force_v0_boards, 593 ARRAY_SIZE(omen_thermal_profile_force_v0_boards), 594 board_name); 595 if (matches >= 0) 596 return 0; 597 } 598 599 ret = hp_wmi_perform_query(HPWMI_GET_SYSTEM_DESIGN_DATA, HPWMI_GM, 600 &buffer, sizeof(buffer), sizeof(buffer)); 601 602 if (ret) 603 return ret < 0 ? ret : -EINVAL; 604 605 return buffer[3]; 606 } 607 608 static int omen_thermal_profile_get(void) 609 { 610 u8 data; 611 612 int ret = ec_read(HP_OMEN_EC_THERMAL_PROFILE_OFFSET, &data); 613 614 if (ret) 615 return ret; 616 617 return data; 618 } 619 620 static int hp_wmi_fan_speed_max_set(int enabled) 621 { 622 int ret; 623 624 ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_MAX_SET_QUERY, HPWMI_GM, 625 &enabled, sizeof(enabled), 0); 626 627 if (ret) 628 return ret < 0 ? ret : -EINVAL; 629 630 return enabled; 631 } 632 633 static int hp_wmi_fan_speed_reset(void) 634 { 635 u8 fan_speed[2] = { HP_FAN_SPEED_AUTOMATIC, HP_FAN_SPEED_AUTOMATIC }; 636 int ret; 637 638 ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_SET_QUERY, HPWMI_GM, 639 &fan_speed, sizeof(fan_speed), 0); 640 641 return ret; 642 } 643 644 static int hp_wmi_fan_speed_max_reset(void) 645 { 646 int ret; 647 648 ret = hp_wmi_fan_speed_max_set(0); 649 if (ret) 650 return ret; 651 652 /* Disabling max fan speed on Victus s1xxx laptops needs a 2nd step: */ 653 ret = hp_wmi_fan_speed_reset(); 654 return ret; 655 } 656 657 static int hp_wmi_fan_speed_max_get(void) 658 { 659 int val = 0, ret; 660 661 ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_MAX_GET_QUERY, HPWMI_GM, 662 &val, zero_if_sup(val), sizeof(val)); 663 664 if (ret) 665 return ret < 0 ? ret : -EINVAL; 666 667 return val; 668 } 669 670 static int __init hp_wmi_bios_2008_later(void) 671 { 672 int state = 0; 673 int ret = hp_wmi_perform_query(HPWMI_FEATURE_QUERY, HPWMI_READ, &state, 674 zero_if_sup(state), sizeof(state)); 675 if (!ret) 676 return 1; 677 678 return (ret == HPWMI_RET_UNKNOWN_CMDTYPE) ? 0 : -ENXIO; 679 } 680 681 static int __init hp_wmi_bios_2009_later(void) 682 { 683 u8 state[128]; 684 int ret = hp_wmi_perform_query(HPWMI_FEATURE2_QUERY, HPWMI_READ, &state, 685 zero_if_sup(state), sizeof(state)); 686 if (!ret) 687 return 1; 688 689 return (ret == HPWMI_RET_UNKNOWN_CMDTYPE) ? 0 : -ENXIO; 690 } 691 692 static int __init hp_wmi_enable_hotkeys(void) 693 { 694 int value = 0x6e; 695 int ret = hp_wmi_perform_query(HPWMI_BIOS_QUERY, HPWMI_WRITE, &value, 696 sizeof(value), 0); 697 698 return ret <= 0 ? ret : -EINVAL; 699 } 700 701 static int hp_wmi_set_block(void *data, bool blocked) 702 { 703 enum hp_wmi_radio r = (long)data; 704 int query = BIT(r + 8) | ((!blocked) << r); 705 int ret; 706 707 ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, HPWMI_WRITE, 708 &query, sizeof(query), 0); 709 710 return ret <= 0 ? ret : -EINVAL; 711 } 712 713 static const struct rfkill_ops hp_wmi_rfkill_ops = { 714 .set_block = hp_wmi_set_block, 715 }; 716 717 static bool hp_wmi_get_sw_state(enum hp_wmi_radio r) 718 { 719 int mask = 0x200 << (r * 8); 720 721 int wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY); 722 723 /* TBD: Pass error */ 724 WARN_ONCE(wireless < 0, "error executing HPWMI_WIRELESS_QUERY"); 725 726 return !(wireless & mask); 727 } 728 729 static bool hp_wmi_get_hw_state(enum hp_wmi_radio r) 730 { 731 int mask = 0x800 << (r * 8); 732 733 int wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY); 734 735 /* TBD: Pass error */ 736 WARN_ONCE(wireless < 0, "error executing HPWMI_WIRELESS_QUERY"); 737 738 return !(wireless & mask); 739 } 740 741 static int hp_wmi_rfkill2_set_block(void *data, bool blocked) 742 { 743 int rfkill_id = (int)(long)data; 744 char buffer[4] = { 0x01, 0x00, rfkill_id, !blocked }; 745 int ret; 746 747 ret = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_WRITE, 748 buffer, sizeof(buffer), 0); 749 750 return ret <= 0 ? ret : -EINVAL; 751 } 752 753 static const struct rfkill_ops hp_wmi_rfkill2_ops = { 754 .set_block = hp_wmi_rfkill2_set_block, 755 }; 756 757 static int hp_wmi_rfkill2_refresh(void) 758 { 759 struct bios_rfkill2_state state; 760 int err, i; 761 762 err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state, 763 zero_if_sup(state), sizeof(state)); 764 if (err) 765 return err; 766 767 for (i = 0; i < rfkill2_count; i++) { 768 int num = rfkill2[i].num; 769 struct bios_rfkill2_device_state *devstate; 770 771 devstate = &state.device[num]; 772 773 if (num >= state.count || 774 devstate->rfkill_id != rfkill2[i].id) { 775 pr_warn("power configuration of the wireless devices unexpectedly changed\n"); 776 continue; 777 } 778 779 rfkill_set_states(rfkill2[i].rfkill, 780 IS_SWBLOCKED(devstate->power), 781 IS_HWBLOCKED(devstate->power)); 782 } 783 784 return 0; 785 } 786 787 static ssize_t display_show(struct device *dev, struct device_attribute *attr, 788 char *buf) 789 { 790 int value = hp_wmi_read_int(HPWMI_DISPLAY_QUERY); 791 792 if (value < 0) 793 return value; 794 return sysfs_emit(buf, "%d\n", value); 795 } 796 797 static ssize_t hddtemp_show(struct device *dev, struct device_attribute *attr, 798 char *buf) 799 { 800 int value = hp_wmi_read_int(HPWMI_HDDTEMP_QUERY); 801 802 if (value < 0) 803 return value; 804 return sysfs_emit(buf, "%d\n", value); 805 } 806 807 static ssize_t als_show(struct device *dev, struct device_attribute *attr, 808 char *buf) 809 { 810 int value = hp_wmi_read_int(HPWMI_ALS_QUERY); 811 812 if (value < 0) 813 return value; 814 return sysfs_emit(buf, "%d\n", value); 815 } 816 817 static ssize_t dock_show(struct device *dev, struct device_attribute *attr, 818 char *buf) 819 { 820 int value = hp_wmi_get_dock_state(); 821 822 if (value < 0) 823 return value; 824 return sysfs_emit(buf, "%d\n", value); 825 } 826 827 static ssize_t tablet_show(struct device *dev, struct device_attribute *attr, 828 char *buf) 829 { 830 int value = hp_wmi_get_tablet_mode(); 831 832 if (value < 0) 833 return value; 834 return sysfs_emit(buf, "%d\n", value); 835 } 836 837 static ssize_t postcode_show(struct device *dev, struct device_attribute *attr, 838 char *buf) 839 { 840 /* Get the POST error code of previous boot failure. */ 841 int value = hp_wmi_read_int(HPWMI_POSTCODEERROR_QUERY); 842 843 if (value < 0) 844 return value; 845 return sysfs_emit(buf, "0x%x\n", value); 846 } 847 848 static ssize_t als_store(struct device *dev, struct device_attribute *attr, 849 const char *buf, size_t count) 850 { 851 u32 tmp; 852 int ret; 853 854 ret = kstrtou32(buf, 10, &tmp); 855 if (ret) 856 return ret; 857 858 ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, HPWMI_WRITE, &tmp, 859 sizeof(tmp), 0); 860 if (ret) 861 return ret < 0 ? ret : -EINVAL; 862 863 return count; 864 } 865 866 static ssize_t postcode_store(struct device *dev, struct device_attribute *attr, 867 const char *buf, size_t count) 868 { 869 u32 tmp = 1; 870 bool clear; 871 int ret; 872 873 ret = kstrtobool(buf, &clear); 874 if (ret) 875 return ret; 876 877 if (clear == false) 878 return -EINVAL; 879 880 /* Clear the POST error code. It is kept until cleared. */ 881 ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, HPWMI_WRITE, &tmp, 882 sizeof(tmp), 0); 883 if (ret) 884 return ret < 0 ? ret : -EINVAL; 885 886 return count; 887 } 888 889 static int camera_shutter_input_setup(void) 890 { 891 int err; 892 893 camera_shutter_input_dev = input_allocate_device(); 894 if (!camera_shutter_input_dev) 895 return -ENOMEM; 896 897 camera_shutter_input_dev->name = "HP WMI camera shutter"; 898 camera_shutter_input_dev->phys = "wmi/input1"; 899 camera_shutter_input_dev->id.bustype = BUS_HOST; 900 901 __set_bit(EV_SW, camera_shutter_input_dev->evbit); 902 __set_bit(SW_CAMERA_LENS_COVER, camera_shutter_input_dev->swbit); 903 904 err = input_register_device(camera_shutter_input_dev); 905 if (err) 906 goto err_free_dev; 907 908 return 0; 909 910 err_free_dev: 911 input_free_device(camera_shutter_input_dev); 912 camera_shutter_input_dev = NULL; 913 return err; 914 } 915 916 static DEVICE_ATTR_RO(display); 917 static DEVICE_ATTR_RO(hddtemp); 918 static DEVICE_ATTR_RW(als); 919 static DEVICE_ATTR_RO(dock); 920 static DEVICE_ATTR_RO(tablet); 921 static DEVICE_ATTR_RW(postcode); 922 923 static struct attribute *hp_wmi_attrs[] = { 924 &dev_attr_display.attr, 925 &dev_attr_hddtemp.attr, 926 &dev_attr_als.attr, 927 &dev_attr_dock.attr, 928 &dev_attr_tablet.attr, 929 &dev_attr_postcode.attr, 930 NULL, 931 }; 932 ATTRIBUTE_GROUPS(hp_wmi); 933 934 static void hp_wmi_notify(union acpi_object *obj, void *context) 935 { 936 u32 event_id, event_data; 937 u32 *location; 938 int key_code; 939 940 if (!obj) 941 return; 942 if (obj->type != ACPI_TYPE_BUFFER) { 943 pr_info("Unknown response received %d\n", obj->type); 944 return; 945 } 946 947 /* 948 * Depending on ACPI version the concatenation of id and event data 949 * inside _WED function will result in a 8 or 16 byte buffer. 950 */ 951 location = (u32 *)obj->buffer.pointer; 952 if (obj->buffer.length == 8) { 953 event_id = *location; 954 event_data = *(location + 1); 955 } else if (obj->buffer.length == 16) { 956 event_id = *location; 957 event_data = *(location + 2); 958 } else { 959 pr_info("Unknown buffer length %d\n", obj->buffer.length); 960 return; 961 } 962 963 switch (event_id) { 964 case HPWMI_DOCK_EVENT: 965 if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit)) 966 input_report_switch(hp_wmi_input_dev, SW_DOCK, 967 hp_wmi_get_dock_state()); 968 if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit)) 969 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, 970 hp_wmi_get_tablet_mode()); 971 input_sync(hp_wmi_input_dev); 972 break; 973 case HPWMI_PARK_HDD: 974 break; 975 case HPWMI_SMART_ADAPTER: 976 break; 977 case HPWMI_BEZEL_BUTTON: 978 key_code = hp_wmi_read_int(HPWMI_HOTKEY_QUERY); 979 if (key_code < 0) 980 break; 981 982 if (!sparse_keymap_report_event(hp_wmi_input_dev, 983 key_code, 1, true)) 984 pr_info("Unknown key code - 0x%x\n", key_code); 985 break; 986 case HPWMI_FN_P_HOTKEY: 987 platform_profile_cycle(); 988 break; 989 case HPWMI_OMEN_KEY: 990 if (event_data) /* Only should be true for HP Omen */ 991 key_code = event_data; 992 else 993 key_code = hp_wmi_read_int(HPWMI_HOTKEY_QUERY); 994 995 if (!sparse_keymap_report_event(hp_wmi_input_dev, 996 key_code, 1, true)) 997 pr_info("Unknown key code - 0x%x\n", key_code); 998 break; 999 case HPWMI_WIRELESS: 1000 if (rfkill2_count) { 1001 hp_wmi_rfkill2_refresh(); 1002 break; 1003 } 1004 1005 if (wifi_rfkill) 1006 rfkill_set_states(wifi_rfkill, 1007 hp_wmi_get_sw_state(HPWMI_WIFI), 1008 hp_wmi_get_hw_state(HPWMI_WIFI)); 1009 if (bluetooth_rfkill) 1010 rfkill_set_states(bluetooth_rfkill, 1011 hp_wmi_get_sw_state(HPWMI_BLUETOOTH), 1012 hp_wmi_get_hw_state(HPWMI_BLUETOOTH)); 1013 if (wwan_rfkill) 1014 rfkill_set_states(wwan_rfkill, 1015 hp_wmi_get_sw_state(HPWMI_WWAN), 1016 hp_wmi_get_hw_state(HPWMI_WWAN)); 1017 break; 1018 case HPWMI_CPU_BATTERY_THROTTLE: 1019 pr_info("Unimplemented CPU throttle because of 3 Cell battery event detected\n"); 1020 break; 1021 case HPWMI_LOCK_SWITCH: 1022 break; 1023 case HPWMI_LID_SWITCH: 1024 break; 1025 case HPWMI_SCREEN_ROTATION: 1026 break; 1027 case HPWMI_COOLSENSE_SYSTEM_MOBILE: 1028 break; 1029 case HPWMI_COOLSENSE_SYSTEM_HOT: 1030 break; 1031 case HPWMI_PROXIMITY_SENSOR: 1032 break; 1033 case HPWMI_BACKLIT_KB_BRIGHTNESS: 1034 break; 1035 case HPWMI_PEAKSHIFT_PERIOD: 1036 break; 1037 case HPWMI_BATTERY_CHARGE_PERIOD: 1038 break; 1039 case HPWMI_SANITIZATION_MODE: 1040 break; 1041 case HPWMI_CAMERA_TOGGLE: 1042 if (!camera_shutter_input_dev) 1043 if (camera_shutter_input_setup()) { 1044 pr_err("Failed to setup camera shutter input device\n"); 1045 break; 1046 } 1047 if (event_data == 0xff) 1048 input_report_switch(camera_shutter_input_dev, SW_CAMERA_LENS_COVER, 1); 1049 else if (event_data == 0xfe) 1050 input_report_switch(camera_shutter_input_dev, SW_CAMERA_LENS_COVER, 0); 1051 else 1052 pr_warn("Unknown camera shutter state - 0x%x\n", event_data); 1053 input_sync(camera_shutter_input_dev); 1054 break; 1055 case HPWMI_SMART_EXPERIENCE_APP: 1056 break; 1057 default: 1058 pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data); 1059 break; 1060 } 1061 } 1062 1063 static int __init hp_wmi_input_setup(void) 1064 { 1065 acpi_status status; 1066 int err, val; 1067 1068 hp_wmi_input_dev = input_allocate_device(); 1069 if (!hp_wmi_input_dev) 1070 return -ENOMEM; 1071 1072 hp_wmi_input_dev->name = "HP WMI hotkeys"; 1073 hp_wmi_input_dev->phys = "wmi/input0"; 1074 hp_wmi_input_dev->id.bustype = BUS_HOST; 1075 1076 __set_bit(EV_SW, hp_wmi_input_dev->evbit); 1077 1078 /* Dock */ 1079 val = hp_wmi_get_dock_state(); 1080 if (!(val < 0)) { 1081 __set_bit(SW_DOCK, hp_wmi_input_dev->swbit); 1082 input_report_switch(hp_wmi_input_dev, SW_DOCK, val); 1083 } 1084 1085 /* Tablet mode */ 1086 val = hp_wmi_get_tablet_mode(); 1087 if (!(val < 0)) { 1088 __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit); 1089 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val); 1090 } 1091 1092 err = sparse_keymap_setup(hp_wmi_input_dev, hp_wmi_keymap, NULL); 1093 if (err) 1094 goto err_free_dev; 1095 1096 /* Set initial hardware state */ 1097 input_sync(hp_wmi_input_dev); 1098 1099 if (!hp_wmi_bios_2009_later() && hp_wmi_bios_2008_later()) 1100 hp_wmi_enable_hotkeys(); 1101 1102 status = wmi_install_notify_handler(HPWMI_EVENT_GUID, hp_wmi_notify, NULL); 1103 if (ACPI_FAILURE(status)) { 1104 err = -EIO; 1105 goto err_free_dev; 1106 } 1107 1108 err = input_register_device(hp_wmi_input_dev); 1109 if (err) 1110 goto err_uninstall_notifier; 1111 1112 return 0; 1113 1114 err_uninstall_notifier: 1115 wmi_remove_notify_handler(HPWMI_EVENT_GUID); 1116 err_free_dev: 1117 input_free_device(hp_wmi_input_dev); 1118 return err; 1119 } 1120 1121 static void hp_wmi_input_destroy(void) 1122 { 1123 wmi_remove_notify_handler(HPWMI_EVENT_GUID); 1124 input_unregister_device(hp_wmi_input_dev); 1125 } 1126 1127 static int __init hp_wmi_rfkill_setup(struct platform_device *device) 1128 { 1129 int err, wireless; 1130 1131 wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY); 1132 if (wireless < 0) 1133 return wireless; 1134 1135 err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, HPWMI_WRITE, &wireless, 1136 sizeof(wireless), 0); 1137 if (err) 1138 return err; 1139 1140 if (wireless & 0x1) { 1141 wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev, 1142 RFKILL_TYPE_WLAN, 1143 &hp_wmi_rfkill_ops, 1144 (void *) HPWMI_WIFI); 1145 if (!wifi_rfkill) 1146 return -ENOMEM; 1147 rfkill_init_sw_state(wifi_rfkill, 1148 hp_wmi_get_sw_state(HPWMI_WIFI)); 1149 rfkill_set_hw_state(wifi_rfkill, 1150 hp_wmi_get_hw_state(HPWMI_WIFI)); 1151 err = rfkill_register(wifi_rfkill); 1152 if (err) 1153 goto register_wifi_error; 1154 } 1155 1156 if (wireless & 0x2) { 1157 bluetooth_rfkill = rfkill_alloc("hp-bluetooth", &device->dev, 1158 RFKILL_TYPE_BLUETOOTH, 1159 &hp_wmi_rfkill_ops, 1160 (void *) HPWMI_BLUETOOTH); 1161 if (!bluetooth_rfkill) { 1162 err = -ENOMEM; 1163 goto register_bluetooth_error; 1164 } 1165 rfkill_init_sw_state(bluetooth_rfkill, 1166 hp_wmi_get_sw_state(HPWMI_BLUETOOTH)); 1167 rfkill_set_hw_state(bluetooth_rfkill, 1168 hp_wmi_get_hw_state(HPWMI_BLUETOOTH)); 1169 err = rfkill_register(bluetooth_rfkill); 1170 if (err) 1171 goto register_bluetooth_error; 1172 } 1173 1174 if (wireless & 0x4) { 1175 wwan_rfkill = rfkill_alloc("hp-wwan", &device->dev, 1176 RFKILL_TYPE_WWAN, 1177 &hp_wmi_rfkill_ops, 1178 (void *) HPWMI_WWAN); 1179 if (!wwan_rfkill) { 1180 err = -ENOMEM; 1181 goto register_wwan_error; 1182 } 1183 rfkill_init_sw_state(wwan_rfkill, 1184 hp_wmi_get_sw_state(HPWMI_WWAN)); 1185 rfkill_set_hw_state(wwan_rfkill, 1186 hp_wmi_get_hw_state(HPWMI_WWAN)); 1187 err = rfkill_register(wwan_rfkill); 1188 if (err) 1189 goto register_wwan_error; 1190 } 1191 1192 return 0; 1193 1194 register_wwan_error: 1195 rfkill_destroy(wwan_rfkill); 1196 wwan_rfkill = NULL; 1197 if (bluetooth_rfkill) 1198 rfkill_unregister(bluetooth_rfkill); 1199 register_bluetooth_error: 1200 rfkill_destroy(bluetooth_rfkill); 1201 bluetooth_rfkill = NULL; 1202 if (wifi_rfkill) 1203 rfkill_unregister(wifi_rfkill); 1204 register_wifi_error: 1205 rfkill_destroy(wifi_rfkill); 1206 wifi_rfkill = NULL; 1207 return err; 1208 } 1209 1210 static int __init hp_wmi_rfkill2_setup(struct platform_device *device) 1211 { 1212 struct bios_rfkill2_state state; 1213 int err, i; 1214 1215 err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state, 1216 zero_if_sup(state), sizeof(state)); 1217 if (err) 1218 return err < 0 ? err : -EINVAL; 1219 1220 if (state.count > HPWMI_MAX_RFKILL2_DEVICES) { 1221 pr_warn("unable to parse 0x1b query output\n"); 1222 return -EINVAL; 1223 } 1224 1225 for (i = 0; i < state.count; i++) { 1226 struct rfkill *rfkill; 1227 enum rfkill_type type; 1228 char *name; 1229 1230 switch (state.device[i].radio_type) { 1231 case HPWMI_WIFI: 1232 type = RFKILL_TYPE_WLAN; 1233 name = "hp-wifi"; 1234 break; 1235 case HPWMI_BLUETOOTH: 1236 type = RFKILL_TYPE_BLUETOOTH; 1237 name = "hp-bluetooth"; 1238 break; 1239 case HPWMI_WWAN: 1240 type = RFKILL_TYPE_WWAN; 1241 name = "hp-wwan"; 1242 break; 1243 case HPWMI_GPS: 1244 type = RFKILL_TYPE_GPS; 1245 name = "hp-gps"; 1246 break; 1247 default: 1248 pr_warn("unknown device type 0x%x\n", 1249 state.device[i].radio_type); 1250 continue; 1251 } 1252 1253 if (!state.device[i].vendor_id) { 1254 pr_warn("zero device %d while %d reported\n", 1255 i, state.count); 1256 continue; 1257 } 1258 1259 rfkill = rfkill_alloc(name, &device->dev, type, 1260 &hp_wmi_rfkill2_ops, (void *)(long)i); 1261 if (!rfkill) { 1262 err = -ENOMEM; 1263 goto fail; 1264 } 1265 1266 rfkill2[rfkill2_count].id = state.device[i].rfkill_id; 1267 rfkill2[rfkill2_count].num = i; 1268 rfkill2[rfkill2_count].rfkill = rfkill; 1269 1270 rfkill_init_sw_state(rfkill, 1271 IS_SWBLOCKED(state.device[i].power)); 1272 rfkill_set_hw_state(rfkill, 1273 IS_HWBLOCKED(state.device[i].power)); 1274 1275 if (!(state.device[i].power & HPWMI_POWER_BIOS)) 1276 pr_info("device %s blocked by BIOS\n", name); 1277 1278 err = rfkill_register(rfkill); 1279 if (err) { 1280 rfkill_destroy(rfkill); 1281 goto fail; 1282 } 1283 1284 rfkill2_count++; 1285 } 1286 1287 return 0; 1288 fail: 1289 for (; rfkill2_count > 0; rfkill2_count--) { 1290 rfkill_unregister(rfkill2[rfkill2_count - 1].rfkill); 1291 rfkill_destroy(rfkill2[rfkill2_count - 1].rfkill); 1292 } 1293 return err; 1294 } 1295 1296 static int platform_profile_omen_get_ec(enum platform_profile_option *profile) 1297 { 1298 int tp; 1299 1300 tp = omen_thermal_profile_get(); 1301 if (tp < 0) 1302 return tp; 1303 1304 switch (tp) { 1305 case HP_OMEN_V0_THERMAL_PROFILE_PERFORMANCE: 1306 case HP_OMEN_V1_THERMAL_PROFILE_PERFORMANCE: 1307 *profile = PLATFORM_PROFILE_PERFORMANCE; 1308 break; 1309 case HP_OMEN_V0_THERMAL_PROFILE_DEFAULT: 1310 case HP_OMEN_V1_THERMAL_PROFILE_DEFAULT: 1311 *profile = PLATFORM_PROFILE_BALANCED; 1312 break; 1313 case HP_OMEN_V0_THERMAL_PROFILE_COOL: 1314 case HP_OMEN_V1_THERMAL_PROFILE_COOL: 1315 *profile = PLATFORM_PROFILE_COOL; 1316 break; 1317 default: 1318 return -EINVAL; 1319 } 1320 1321 return 0; 1322 } 1323 1324 static int platform_profile_omen_get(struct device *dev, 1325 enum platform_profile_option *profile) 1326 { 1327 /* 1328 * We directly return the stored platform profile, as the embedded 1329 * controller will not accept switching to the performance option when 1330 * the conditions are not met (e.g. the laptop is not plugged in). 1331 * 1332 * If we directly return what the EC reports, the platform profile will 1333 * immediately "switch back" to normal mode, which is against the 1334 * expected behaviour from a userspace point of view, as described in 1335 * the Platform Profile Section page of the kernel documentation. 1336 * 1337 * See also omen_powersource_event. 1338 */ 1339 guard(mutex)(&active_platform_profile_lock); 1340 *profile = active_platform_profile; 1341 1342 return 0; 1343 } 1344 1345 static bool has_omen_thermal_profile_ec_timer(void) 1346 { 1347 const char *board_name = dmi_get_system_info(DMI_BOARD_NAME); 1348 1349 if (!board_name) 1350 return false; 1351 1352 return match_string(omen_timed_thermal_profile_boards, 1353 ARRAY_SIZE(omen_timed_thermal_profile_boards), 1354 board_name) >= 0; 1355 } 1356 1357 inline int omen_thermal_profile_ec_flags_set(enum hp_thermal_profile_omen_flags flags) 1358 { 1359 return ec_write(HP_OMEN_EC_THERMAL_PROFILE_FLAGS_OFFSET, flags); 1360 } 1361 1362 inline int omen_thermal_profile_ec_timer_set(u8 value) 1363 { 1364 return ec_write(HP_OMEN_EC_THERMAL_PROFILE_TIMER_OFFSET, value); 1365 } 1366 1367 static int platform_profile_omen_set_ec(enum platform_profile_option profile) 1368 { 1369 int err, tp, tp_version; 1370 enum hp_thermal_profile_omen_flags flags = 0; 1371 1372 tp_version = omen_get_thermal_policy_version(); 1373 1374 if (tp_version < 0 || tp_version > 1) 1375 return -EOPNOTSUPP; 1376 1377 switch (profile) { 1378 case PLATFORM_PROFILE_PERFORMANCE: 1379 if (tp_version == 0) 1380 tp = HP_OMEN_V0_THERMAL_PROFILE_PERFORMANCE; 1381 else 1382 tp = HP_OMEN_V1_THERMAL_PROFILE_PERFORMANCE; 1383 break; 1384 case PLATFORM_PROFILE_BALANCED: 1385 if (tp_version == 0) 1386 tp = HP_OMEN_V0_THERMAL_PROFILE_DEFAULT; 1387 else 1388 tp = HP_OMEN_V1_THERMAL_PROFILE_DEFAULT; 1389 break; 1390 case PLATFORM_PROFILE_COOL: 1391 if (tp_version == 0) 1392 tp = HP_OMEN_V0_THERMAL_PROFILE_COOL; 1393 else 1394 tp = HP_OMEN_V1_THERMAL_PROFILE_COOL; 1395 break; 1396 default: 1397 return -EOPNOTSUPP; 1398 } 1399 1400 err = omen_thermal_profile_set(tp); 1401 if (err < 0) 1402 return err; 1403 1404 if (has_omen_thermal_profile_ec_timer()) { 1405 err = omen_thermal_profile_ec_timer_set(0); 1406 if (err < 0) 1407 return err; 1408 1409 if (profile == PLATFORM_PROFILE_PERFORMANCE) 1410 flags = HP_OMEN_EC_FLAGS_NOTIMER | 1411 HP_OMEN_EC_FLAGS_TURBO; 1412 1413 err = omen_thermal_profile_ec_flags_set(flags); 1414 if (err < 0) 1415 return err; 1416 } 1417 1418 return 0; 1419 } 1420 1421 static int platform_profile_omen_set(struct device *dev, 1422 enum platform_profile_option profile) 1423 { 1424 int err; 1425 1426 guard(mutex)(&active_platform_profile_lock); 1427 1428 err = platform_profile_omen_set_ec(profile); 1429 if (err < 0) 1430 return err; 1431 1432 active_platform_profile = profile; 1433 1434 return 0; 1435 } 1436 1437 static int thermal_profile_get(void) 1438 { 1439 return hp_wmi_read_int(HPWMI_THERMAL_PROFILE_QUERY); 1440 } 1441 1442 static int thermal_profile_set(int thermal_profile) 1443 { 1444 return hp_wmi_perform_query(HPWMI_THERMAL_PROFILE_QUERY, HPWMI_WRITE, &thermal_profile, 1445 sizeof(thermal_profile), 0); 1446 } 1447 1448 static int hp_wmi_platform_profile_get(struct device *dev, 1449 enum platform_profile_option *profile) 1450 { 1451 int tp; 1452 1453 tp = thermal_profile_get(); 1454 if (tp < 0) 1455 return tp; 1456 1457 switch (tp) { 1458 case HP_THERMAL_PROFILE_PERFORMANCE: 1459 *profile = PLATFORM_PROFILE_PERFORMANCE; 1460 break; 1461 case HP_THERMAL_PROFILE_DEFAULT: 1462 *profile = PLATFORM_PROFILE_BALANCED; 1463 break; 1464 case HP_THERMAL_PROFILE_COOL: 1465 *profile = PLATFORM_PROFILE_COOL; 1466 break; 1467 case HP_THERMAL_PROFILE_QUIET: 1468 *profile = PLATFORM_PROFILE_QUIET; 1469 break; 1470 default: 1471 return -EINVAL; 1472 } 1473 1474 return 0; 1475 } 1476 1477 static int hp_wmi_platform_profile_set(struct device *dev, 1478 enum platform_profile_option profile) 1479 { 1480 int err, tp; 1481 1482 switch (profile) { 1483 case PLATFORM_PROFILE_PERFORMANCE: 1484 tp = HP_THERMAL_PROFILE_PERFORMANCE; 1485 break; 1486 case PLATFORM_PROFILE_BALANCED: 1487 tp = HP_THERMAL_PROFILE_DEFAULT; 1488 break; 1489 case PLATFORM_PROFILE_COOL: 1490 tp = HP_THERMAL_PROFILE_COOL; 1491 break; 1492 case PLATFORM_PROFILE_QUIET: 1493 tp = HP_THERMAL_PROFILE_QUIET; 1494 break; 1495 default: 1496 return -EOPNOTSUPP; 1497 } 1498 1499 err = thermal_profile_set(tp); 1500 if (err) 1501 return err; 1502 1503 return 0; 1504 } 1505 1506 static bool is_victus_thermal_profile(void) 1507 { 1508 const char *board_name = dmi_get_system_info(DMI_BOARD_NAME); 1509 1510 if (!board_name) 1511 return false; 1512 1513 return match_string(victus_thermal_profile_boards, 1514 ARRAY_SIZE(victus_thermal_profile_boards), 1515 board_name) >= 0; 1516 } 1517 1518 static int platform_profile_victus_get_ec(enum platform_profile_option *profile) 1519 { 1520 int tp; 1521 1522 tp = omen_thermal_profile_get(); 1523 if (tp < 0) 1524 return tp; 1525 1526 switch (tp) { 1527 case HP_VICTUS_THERMAL_PROFILE_PERFORMANCE: 1528 *profile = PLATFORM_PROFILE_PERFORMANCE; 1529 break; 1530 case HP_VICTUS_THERMAL_PROFILE_DEFAULT: 1531 *profile = PLATFORM_PROFILE_BALANCED; 1532 break; 1533 case HP_VICTUS_THERMAL_PROFILE_QUIET: 1534 *profile = PLATFORM_PROFILE_QUIET; 1535 break; 1536 default: 1537 return -EOPNOTSUPP; 1538 } 1539 1540 return 0; 1541 } 1542 1543 static int platform_profile_victus_get(struct device *dev, 1544 enum platform_profile_option *profile) 1545 { 1546 /* Same behaviour as platform_profile_omen_get */ 1547 return platform_profile_omen_get(dev, profile); 1548 } 1549 1550 static int platform_profile_victus_set_ec(enum platform_profile_option profile) 1551 { 1552 int err, tp; 1553 1554 switch (profile) { 1555 case PLATFORM_PROFILE_PERFORMANCE: 1556 tp = HP_VICTUS_THERMAL_PROFILE_PERFORMANCE; 1557 break; 1558 case PLATFORM_PROFILE_BALANCED: 1559 tp = HP_VICTUS_THERMAL_PROFILE_DEFAULT; 1560 break; 1561 case PLATFORM_PROFILE_QUIET: 1562 tp = HP_VICTUS_THERMAL_PROFILE_QUIET; 1563 break; 1564 default: 1565 return -EOPNOTSUPP; 1566 } 1567 1568 err = omen_thermal_profile_set(tp); 1569 if (err < 0) 1570 return err; 1571 1572 return 0; 1573 } 1574 1575 static bool is_victus_s_thermal_profile(void) 1576 { 1577 const char *board_name; 1578 1579 board_name = dmi_get_system_info(DMI_BOARD_NAME); 1580 if (!board_name) 1581 return false; 1582 1583 return match_string(victus_s_thermal_profile_boards, 1584 ARRAY_SIZE(victus_s_thermal_profile_boards), 1585 board_name) >= 0; 1586 } 1587 1588 static int victus_s_gpu_thermal_profile_get(bool *ctgp_enable, 1589 bool *ppab_enable, 1590 u8 *dstate, 1591 u8 *gpu_slowdown_temp) 1592 { 1593 struct victus_gpu_power_modes gpu_power_modes; 1594 int ret; 1595 1596 ret = hp_wmi_perform_query(HPWMI_GET_GPU_THERMAL_MODES_QUERY, HPWMI_GM, 1597 &gpu_power_modes, sizeof(gpu_power_modes), 1598 sizeof(gpu_power_modes)); 1599 if (ret == 0) { 1600 *ctgp_enable = gpu_power_modes.ctgp_enable ? true : false; 1601 *ppab_enable = gpu_power_modes.ppab_enable ? true : false; 1602 *dstate = gpu_power_modes.dstate; 1603 *gpu_slowdown_temp = gpu_power_modes.gpu_slowdown_temp; 1604 } 1605 1606 return ret; 1607 } 1608 1609 static int victus_s_gpu_thermal_profile_set(bool ctgp_enable, 1610 bool ppab_enable, 1611 u8 dstate) 1612 { 1613 struct victus_gpu_power_modes gpu_power_modes; 1614 int ret; 1615 1616 bool current_ctgp_state, current_ppab_state; 1617 u8 current_dstate, current_gpu_slowdown_temp; 1618 1619 /* Retrieving GPU slowdown temperature, in order to keep it unchanged */ 1620 ret = victus_s_gpu_thermal_profile_get(¤t_ctgp_state, 1621 ¤t_ppab_state, 1622 ¤t_dstate, 1623 ¤t_gpu_slowdown_temp); 1624 if (ret < 0) { 1625 pr_warn("GPU modes not updated, unable to get slowdown temp\n"); 1626 return ret; 1627 } 1628 1629 gpu_power_modes.ctgp_enable = ctgp_enable ? 0x01 : 0x00; 1630 gpu_power_modes.ppab_enable = ppab_enable ? 0x01 : 0x00; 1631 gpu_power_modes.dstate = dstate; 1632 gpu_power_modes.gpu_slowdown_temp = current_gpu_slowdown_temp; 1633 1634 1635 ret = hp_wmi_perform_query(HPWMI_SET_GPU_THERMAL_MODES_QUERY, HPWMI_GM, 1636 &gpu_power_modes, sizeof(gpu_power_modes), 0); 1637 1638 return ret; 1639 } 1640 1641 /* Note: HP_POWER_LIMIT_DEFAULT can be used to restore default PL1 and PL2 */ 1642 static int victus_s_set_cpu_pl1_pl2(u8 pl1, u8 pl2) 1643 { 1644 struct victus_power_limits power_limits; 1645 int ret; 1646 1647 /* We need to know both PL1 and PL2 values in order to check them */ 1648 if (pl1 == HP_POWER_LIMIT_NO_CHANGE || pl2 == HP_POWER_LIMIT_NO_CHANGE) 1649 return -EINVAL; 1650 1651 /* PL2 is not supposed to be lower than PL1 */ 1652 if (pl2 < pl1) 1653 return -EINVAL; 1654 1655 power_limits.pl1 = pl1; 1656 power_limits.pl2 = pl2; 1657 power_limits.pl4 = HP_POWER_LIMIT_NO_CHANGE; 1658 power_limits.cpu_gpu_concurrent_limit = HP_POWER_LIMIT_NO_CHANGE; 1659 1660 ret = hp_wmi_perform_query(HPWMI_SET_POWER_LIMITS_QUERY, HPWMI_GM, 1661 &power_limits, sizeof(power_limits), 0); 1662 1663 return ret; 1664 } 1665 1666 static int platform_profile_victus_s_set_ec(enum platform_profile_option profile) 1667 { 1668 bool gpu_ctgp_enable, gpu_ppab_enable; 1669 u8 gpu_dstate; /* Test shows 1 = 100%, 2 = 50%, 3 = 25%, 4 = 12.5% */ 1670 int err, tp; 1671 1672 switch (profile) { 1673 case PLATFORM_PROFILE_PERFORMANCE: 1674 tp = HP_VICTUS_S_THERMAL_PROFILE_PERFORMANCE; 1675 gpu_ctgp_enable = true; 1676 gpu_ppab_enable = true; 1677 gpu_dstate = 1; 1678 break; 1679 case PLATFORM_PROFILE_BALANCED: 1680 tp = HP_VICTUS_S_THERMAL_PROFILE_DEFAULT; 1681 gpu_ctgp_enable = false; 1682 gpu_ppab_enable = true; 1683 gpu_dstate = 1; 1684 break; 1685 case PLATFORM_PROFILE_LOW_POWER: 1686 tp = HP_VICTUS_S_THERMAL_PROFILE_DEFAULT; 1687 gpu_ctgp_enable = false; 1688 gpu_ppab_enable = false; 1689 gpu_dstate = 1; 1690 break; 1691 default: 1692 return -EOPNOTSUPP; 1693 } 1694 1695 hp_wmi_get_fan_count_userdefine_trigger(); 1696 1697 err = omen_thermal_profile_set(tp); 1698 if (err < 0) { 1699 pr_err("Failed to set platform profile %d: %d\n", profile, err); 1700 return err; 1701 } 1702 1703 err = victus_s_gpu_thermal_profile_set(gpu_ctgp_enable, 1704 gpu_ppab_enable, 1705 gpu_dstate); 1706 if (err < 0) { 1707 pr_err("Failed to set GPU profile %d: %d\n", profile, err); 1708 return err; 1709 } 1710 1711 return 0; 1712 } 1713 1714 static int platform_profile_victus_s_set(struct device *dev, 1715 enum platform_profile_option profile) 1716 { 1717 int err; 1718 1719 guard(mutex)(&active_platform_profile_lock); 1720 1721 err = platform_profile_victus_s_set_ec(profile); 1722 if (err < 0) 1723 return err; 1724 1725 active_platform_profile = profile; 1726 1727 return 0; 1728 } 1729 1730 static int platform_profile_victus_set(struct device *dev, 1731 enum platform_profile_option profile) 1732 { 1733 int err; 1734 1735 guard(mutex)(&active_platform_profile_lock); 1736 1737 err = platform_profile_victus_set_ec(profile); 1738 if (err < 0) 1739 return err; 1740 1741 active_platform_profile = profile; 1742 1743 return 0; 1744 } 1745 1746 static int hp_wmi_platform_profile_probe(void *drvdata, unsigned long *choices) 1747 { 1748 if (is_omen_thermal_profile()) { 1749 set_bit(PLATFORM_PROFILE_COOL, choices); 1750 } else if (is_victus_thermal_profile()) { 1751 set_bit(PLATFORM_PROFILE_QUIET, choices); 1752 } else if (is_victus_s_thermal_profile()) { 1753 /* Adding an equivalent to HP Omen software ECO mode: */ 1754 set_bit(PLATFORM_PROFILE_LOW_POWER, choices); 1755 } else { 1756 set_bit(PLATFORM_PROFILE_QUIET, choices); 1757 set_bit(PLATFORM_PROFILE_COOL, choices); 1758 } 1759 1760 set_bit(PLATFORM_PROFILE_BALANCED, choices); 1761 set_bit(PLATFORM_PROFILE_PERFORMANCE, choices); 1762 1763 return 0; 1764 } 1765 1766 static int omen_powersource_event(struct notifier_block *nb, 1767 unsigned long value, 1768 void *data) 1769 { 1770 struct acpi_bus_event *event_entry = data; 1771 enum platform_profile_option actual_profile; 1772 int err; 1773 1774 if (strcmp(event_entry->device_class, ACPI_AC_CLASS) != 0) 1775 return NOTIFY_DONE; 1776 1777 pr_debug("Received power source device event\n"); 1778 1779 guard(mutex)(&active_platform_profile_lock); 1780 1781 /* 1782 * This handler can only be called on Omen and Victus models, so 1783 * there's no need to call is_victus_thermal_profile() here. 1784 */ 1785 if (is_omen_thermal_profile()) 1786 err = platform_profile_omen_get_ec(&actual_profile); 1787 else 1788 err = platform_profile_victus_get_ec(&actual_profile); 1789 1790 if (err < 0) { 1791 /* 1792 * Although we failed to get the current platform profile, we 1793 * still want the other event consumers to process it. 1794 */ 1795 pr_warn("Failed to read current platform profile (%d)\n", err); 1796 return NOTIFY_DONE; 1797 } 1798 1799 /* 1800 * If we're back on AC and that the user-chosen power profile is 1801 * different from what the EC reports, we restore the user-chosen 1802 * one. 1803 */ 1804 if (power_supply_is_system_supplied() <= 0 || 1805 active_platform_profile == actual_profile) { 1806 pr_debug("Platform profile update skipped, conditions unmet\n"); 1807 return NOTIFY_DONE; 1808 } 1809 1810 if (is_omen_thermal_profile()) 1811 err = platform_profile_omen_set_ec(active_platform_profile); 1812 else 1813 err = platform_profile_victus_set_ec(active_platform_profile); 1814 1815 if (err < 0) { 1816 pr_warn("Failed to restore platform profile (%d)\n", err); 1817 return NOTIFY_DONE; 1818 } 1819 1820 return NOTIFY_OK; 1821 } 1822 1823 static int victus_s_powersource_event(struct notifier_block *nb, 1824 unsigned long value, 1825 void *data) 1826 { 1827 struct acpi_bus_event *event_entry = data; 1828 int err; 1829 1830 if (strcmp(event_entry->device_class, ACPI_AC_CLASS) != 0) 1831 return NOTIFY_DONE; 1832 1833 pr_debug("Received power source device event\n"); 1834 1835 /* 1836 * Switching to battery power source while Performance mode is active 1837 * needs manual triggering of CPU power limits. Same goes when switching 1838 * to AC power source while Performance mode is active. Other modes 1839 * however are automatically behaving without any manual action. 1840 * Seen on HP 16-s1034nf (board 8C9C) with F.11 and F.13 BIOS versions. 1841 */ 1842 1843 if (active_platform_profile == PLATFORM_PROFILE_PERFORMANCE) { 1844 pr_debug("Triggering CPU PL1/PL2 actualization\n"); 1845 err = victus_s_set_cpu_pl1_pl2(HP_POWER_LIMIT_DEFAULT, 1846 HP_POWER_LIMIT_DEFAULT); 1847 if (err) 1848 pr_warn("Failed to actualize power limits: %d\n", err); 1849 1850 return NOTIFY_DONE; 1851 } 1852 1853 return NOTIFY_OK; 1854 } 1855 1856 static int omen_register_powersource_event_handler(void) 1857 { 1858 int err; 1859 1860 platform_power_source_nb.notifier_call = omen_powersource_event; 1861 err = register_acpi_notifier(&platform_power_source_nb); 1862 1863 if (err < 0) { 1864 pr_warn("Failed to install ACPI power source notify handler\n"); 1865 return err; 1866 } 1867 1868 return 0; 1869 } 1870 1871 static int victus_s_register_powersource_event_handler(void) 1872 { 1873 int err; 1874 1875 platform_power_source_nb.notifier_call = victus_s_powersource_event; 1876 err = register_acpi_notifier(&platform_power_source_nb); 1877 if (err < 0) { 1878 pr_warn("Failed to install ACPI power source notify handler\n"); 1879 return err; 1880 } 1881 1882 return 0; 1883 } 1884 1885 static inline void omen_unregister_powersource_event_handler(void) 1886 { 1887 unregister_acpi_notifier(&platform_power_source_nb); 1888 } 1889 1890 static inline void victus_s_unregister_powersource_event_handler(void) 1891 { 1892 unregister_acpi_notifier(&platform_power_source_nb); 1893 } 1894 1895 static const struct platform_profile_ops platform_profile_omen_ops = { 1896 .probe = hp_wmi_platform_profile_probe, 1897 .profile_get = platform_profile_omen_get, 1898 .profile_set = platform_profile_omen_set, 1899 }; 1900 1901 static const struct platform_profile_ops platform_profile_victus_ops = { 1902 .probe = hp_wmi_platform_profile_probe, 1903 .profile_get = platform_profile_victus_get, 1904 .profile_set = platform_profile_victus_set, 1905 }; 1906 1907 static const struct platform_profile_ops platform_profile_victus_s_ops = { 1908 .probe = hp_wmi_platform_profile_probe, 1909 .profile_get = platform_profile_omen_get, 1910 .profile_set = platform_profile_victus_s_set, 1911 }; 1912 1913 static const struct platform_profile_ops hp_wmi_platform_profile_ops = { 1914 .probe = hp_wmi_platform_profile_probe, 1915 .profile_get = hp_wmi_platform_profile_get, 1916 .profile_set = hp_wmi_platform_profile_set, 1917 }; 1918 1919 static int thermal_profile_setup(struct platform_device *device) 1920 { 1921 const struct platform_profile_ops *ops; 1922 int err, tp; 1923 1924 if (is_omen_thermal_profile()) { 1925 err = platform_profile_omen_get_ec(&active_platform_profile); 1926 if (err < 0) 1927 return err; 1928 1929 /* 1930 * call thermal profile write command to ensure that the 1931 * firmware correctly sets the OEM variables 1932 */ 1933 err = platform_profile_omen_set_ec(active_platform_profile); 1934 if (err < 0) 1935 return err; 1936 1937 ops = &platform_profile_omen_ops; 1938 } else if (is_victus_thermal_profile()) { 1939 err = platform_profile_victus_get_ec(&active_platform_profile); 1940 if (err < 0) 1941 return err; 1942 1943 /* 1944 * call thermal profile write command to ensure that the 1945 * firmware correctly sets the OEM variables 1946 */ 1947 err = platform_profile_victus_set_ec(active_platform_profile); 1948 if (err < 0) 1949 return err; 1950 1951 ops = &platform_profile_victus_ops; 1952 } else if (is_victus_s_thermal_profile()) { 1953 /* 1954 * Being unable to retrieve laptop's current thermal profile, 1955 * during this setup, we set it to Balanced by default. 1956 */ 1957 active_platform_profile = PLATFORM_PROFILE_BALANCED; 1958 1959 err = platform_profile_victus_s_set_ec(active_platform_profile); 1960 if (err < 0) 1961 return err; 1962 1963 ops = &platform_profile_victus_s_ops; 1964 } else { 1965 tp = thermal_profile_get(); 1966 1967 if (tp < 0) 1968 return tp; 1969 1970 /* 1971 * call thermal profile write command to ensure that the 1972 * firmware correctly sets the OEM variables for the DPTF 1973 */ 1974 err = thermal_profile_set(tp); 1975 if (err) 1976 return err; 1977 1978 ops = &hp_wmi_platform_profile_ops; 1979 } 1980 1981 platform_profile_device = devm_platform_profile_register(&device->dev, "hp-wmi", 1982 NULL, ops); 1983 if (IS_ERR(platform_profile_device)) 1984 return PTR_ERR(platform_profile_device); 1985 1986 pr_info("Registered as platform profile handler\n"); 1987 platform_profile_support = true; 1988 1989 return 0; 1990 } 1991 1992 static int hp_wmi_hwmon_init(void); 1993 1994 static int __init hp_wmi_bios_setup(struct platform_device *device) 1995 { 1996 int err; 1997 /* clear detected rfkill devices */ 1998 wifi_rfkill = NULL; 1999 bluetooth_rfkill = NULL; 2000 wwan_rfkill = NULL; 2001 rfkill2_count = 0; 2002 2003 /* 2004 * In pre-2009 BIOS, command 1Bh return 0x4 to indicate that 2005 * BIOS no longer controls the power for the wireless 2006 * devices. All features supported by this command will no 2007 * longer be supported. 2008 */ 2009 if (!hp_wmi_bios_2009_later()) { 2010 if (hp_wmi_rfkill_setup(device)) 2011 hp_wmi_rfkill2_setup(device); 2012 } 2013 2014 err = hp_wmi_hwmon_init(); 2015 2016 if (err < 0) 2017 return err; 2018 2019 thermal_profile_setup(device); 2020 2021 return 0; 2022 } 2023 2024 static void __exit hp_wmi_bios_remove(struct platform_device *device) 2025 { 2026 int i; 2027 2028 for (i = 0; i < rfkill2_count; i++) { 2029 rfkill_unregister(rfkill2[i].rfkill); 2030 rfkill_destroy(rfkill2[i].rfkill); 2031 } 2032 2033 if (wifi_rfkill) { 2034 rfkill_unregister(wifi_rfkill); 2035 rfkill_destroy(wifi_rfkill); 2036 } 2037 if (bluetooth_rfkill) { 2038 rfkill_unregister(bluetooth_rfkill); 2039 rfkill_destroy(bluetooth_rfkill); 2040 } 2041 if (wwan_rfkill) { 2042 rfkill_unregister(wwan_rfkill); 2043 rfkill_destroy(wwan_rfkill); 2044 } 2045 } 2046 2047 static int hp_wmi_resume_handler(struct device *device) 2048 { 2049 /* 2050 * Hardware state may have changed while suspended, so trigger 2051 * input events for the current state. As this is a switch, 2052 * the input layer will only actually pass it on if the state 2053 * changed. 2054 */ 2055 if (hp_wmi_input_dev) { 2056 if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit)) 2057 input_report_switch(hp_wmi_input_dev, SW_DOCK, 2058 hp_wmi_get_dock_state()); 2059 if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit)) 2060 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, 2061 hp_wmi_get_tablet_mode()); 2062 input_sync(hp_wmi_input_dev); 2063 } 2064 2065 if (rfkill2_count) 2066 hp_wmi_rfkill2_refresh(); 2067 2068 if (wifi_rfkill) 2069 rfkill_set_states(wifi_rfkill, 2070 hp_wmi_get_sw_state(HPWMI_WIFI), 2071 hp_wmi_get_hw_state(HPWMI_WIFI)); 2072 if (bluetooth_rfkill) 2073 rfkill_set_states(bluetooth_rfkill, 2074 hp_wmi_get_sw_state(HPWMI_BLUETOOTH), 2075 hp_wmi_get_hw_state(HPWMI_BLUETOOTH)); 2076 if (wwan_rfkill) 2077 rfkill_set_states(wwan_rfkill, 2078 hp_wmi_get_sw_state(HPWMI_WWAN), 2079 hp_wmi_get_hw_state(HPWMI_WWAN)); 2080 2081 return 0; 2082 } 2083 2084 static const struct dev_pm_ops hp_wmi_pm_ops = { 2085 .resume = hp_wmi_resume_handler, 2086 .restore = hp_wmi_resume_handler, 2087 }; 2088 2089 /* 2090 * hp_wmi_bios_remove() lives in .exit.text. For drivers registered via 2091 * module_platform_driver_probe() this is ok because they cannot get unbound at 2092 * runtime. So mark the driver struct with __refdata to prevent modpost 2093 * triggering a section mismatch warning. 2094 */ 2095 static struct platform_driver hp_wmi_driver __refdata = { 2096 .driver = { 2097 .name = "hp-wmi", 2098 .pm = &hp_wmi_pm_ops, 2099 .dev_groups = hp_wmi_groups, 2100 }, 2101 .remove = __exit_p(hp_wmi_bios_remove), 2102 }; 2103 2104 static umode_t hp_wmi_hwmon_is_visible(const void *data, 2105 enum hwmon_sensor_types type, 2106 u32 attr, int channel) 2107 { 2108 switch (type) { 2109 case hwmon_pwm: 2110 return 0644; 2111 case hwmon_fan: 2112 if (is_victus_s_thermal_profile()) { 2113 if (hp_wmi_get_fan_speed_victus_s(channel) >= 0) 2114 return 0444; 2115 } else { 2116 if (hp_wmi_get_fan_speed(channel) >= 0) 2117 return 0444; 2118 } 2119 break; 2120 default: 2121 return 0; 2122 } 2123 2124 return 0; 2125 } 2126 2127 static int hp_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type, 2128 u32 attr, int channel, long *val) 2129 { 2130 int ret; 2131 2132 switch (type) { 2133 case hwmon_fan: 2134 if (is_victus_s_thermal_profile()) 2135 ret = hp_wmi_get_fan_speed_victus_s(channel); 2136 else 2137 ret = hp_wmi_get_fan_speed(channel); 2138 if (ret < 0) 2139 return ret; 2140 *val = ret; 2141 return 0; 2142 case hwmon_pwm: 2143 switch (hp_wmi_fan_speed_max_get()) { 2144 case 0: 2145 /* 0 is automatic fan, which is 2 for hwmon */ 2146 *val = 2; 2147 return 0; 2148 case 1: 2149 /* 1 is max fan, which is 0 2150 * (no fan speed control) for hwmon 2151 */ 2152 *val = 0; 2153 return 0; 2154 default: 2155 /* shouldn't happen */ 2156 return -ENODATA; 2157 } 2158 default: 2159 return -EINVAL; 2160 } 2161 } 2162 2163 static int hp_wmi_hwmon_write(struct device *dev, enum hwmon_sensor_types type, 2164 u32 attr, int channel, long val) 2165 { 2166 switch (type) { 2167 case hwmon_pwm: 2168 switch (val) { 2169 case 0: 2170 if (is_victus_s_thermal_profile()) 2171 hp_wmi_get_fan_count_userdefine_trigger(); 2172 /* 0 is no fan speed control (max), which is 1 for us */ 2173 return hp_wmi_fan_speed_max_set(1); 2174 case 2: 2175 /* 2 is automatic speed control, which is 0 for us */ 2176 if (is_victus_s_thermal_profile()) { 2177 hp_wmi_get_fan_count_userdefine_trigger(); 2178 return hp_wmi_fan_speed_max_reset(); 2179 } else 2180 return hp_wmi_fan_speed_max_set(0); 2181 default: 2182 /* we don't support manual fan speed control */ 2183 return -EINVAL; 2184 } 2185 default: 2186 return -EOPNOTSUPP; 2187 } 2188 } 2189 2190 static const struct hwmon_channel_info * const info[] = { 2191 HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT, HWMON_F_INPUT), 2192 HWMON_CHANNEL_INFO(pwm, HWMON_PWM_ENABLE), 2193 NULL 2194 }; 2195 2196 static const struct hwmon_ops ops = { 2197 .is_visible = hp_wmi_hwmon_is_visible, 2198 .read = hp_wmi_hwmon_read, 2199 .write = hp_wmi_hwmon_write, 2200 }; 2201 2202 static const struct hwmon_chip_info chip_info = { 2203 .ops = &ops, 2204 .info = info, 2205 }; 2206 2207 static int hp_wmi_hwmon_init(void) 2208 { 2209 struct device *dev = &hp_wmi_platform_dev->dev; 2210 struct device *hwmon; 2211 2212 hwmon = devm_hwmon_device_register_with_info(dev, "hp", &hp_wmi_driver, 2213 &chip_info, NULL); 2214 2215 if (IS_ERR(hwmon)) { 2216 dev_err(dev, "Could not register hp hwmon device\n"); 2217 return PTR_ERR(hwmon); 2218 } 2219 2220 return 0; 2221 } 2222 2223 static int __init hp_wmi_init(void) 2224 { 2225 int event_capable = wmi_has_guid(HPWMI_EVENT_GUID); 2226 int bios_capable = wmi_has_guid(HPWMI_BIOS_GUID); 2227 int err, tmp = 0; 2228 2229 if (!bios_capable && !event_capable) 2230 return -ENODEV; 2231 2232 if (hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, HPWMI_READ, &tmp, 2233 sizeof(tmp), sizeof(tmp)) == HPWMI_RET_INVALID_PARAMETERS) 2234 zero_insize_support = true; 2235 2236 if (event_capable) { 2237 err = hp_wmi_input_setup(); 2238 if (err) 2239 return err; 2240 } 2241 2242 if (bios_capable) { 2243 hp_wmi_platform_dev = 2244 platform_device_register_simple("hp-wmi", PLATFORM_DEVID_NONE, NULL, 0); 2245 if (IS_ERR(hp_wmi_platform_dev)) { 2246 err = PTR_ERR(hp_wmi_platform_dev); 2247 goto err_destroy_input; 2248 } 2249 2250 err = platform_driver_probe(&hp_wmi_driver, hp_wmi_bios_setup); 2251 if (err) 2252 goto err_unregister_device; 2253 } 2254 2255 if (is_omen_thermal_profile() || is_victus_thermal_profile()) { 2256 err = omen_register_powersource_event_handler(); 2257 if (err) 2258 goto err_unregister_device; 2259 } else if (is_victus_s_thermal_profile()) { 2260 err = victus_s_register_powersource_event_handler(); 2261 if (err) 2262 goto err_unregister_device; 2263 } 2264 2265 return 0; 2266 2267 err_unregister_device: 2268 platform_device_unregister(hp_wmi_platform_dev); 2269 err_destroy_input: 2270 if (event_capable) 2271 hp_wmi_input_destroy(); 2272 2273 return err; 2274 } 2275 module_init(hp_wmi_init); 2276 2277 static void __exit hp_wmi_exit(void) 2278 { 2279 if (is_omen_thermal_profile() || is_victus_thermal_profile()) 2280 omen_unregister_powersource_event_handler(); 2281 2282 if (is_victus_s_thermal_profile()) 2283 victus_s_unregister_powersource_event_handler(); 2284 2285 if (wmi_has_guid(HPWMI_EVENT_GUID)) 2286 hp_wmi_input_destroy(); 2287 2288 if (camera_shutter_input_dev) 2289 input_unregister_device(camera_shutter_input_dev); 2290 2291 if (hp_wmi_platform_dev) { 2292 platform_device_unregister(hp_wmi_platform_dev); 2293 platform_driver_unregister(&hp_wmi_driver); 2294 } 2295 } 2296 module_exit(hp_wmi_exit); 2297