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