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