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