hp-wmi.c (36602B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * HP WMI hotkeys 4 * 5 * Copyright (C) 2008 Red Hat <mjg@redhat.com> 6 * Copyright (C) 2010, 2011 Anssi Hannula <anssi.hannula@iki.fi> 7 * 8 * Portions based on wistron_btns.c: 9 * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz> 10 * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org> 11 * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru> 12 */ 13 14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 15 16#include <linux/kernel.h> 17#include <linux/module.h> 18#include <linux/init.h> 19#include <linux/slab.h> 20#include <linux/types.h> 21#include <linux/input.h> 22#include <linux/input/sparse-keymap.h> 23#include <linux/platform_device.h> 24#include <linux/platform_profile.h> 25#include <linux/hwmon.h> 26#include <linux/acpi.h> 27#include <linux/rfkill.h> 28#include <linux/string.h> 29#include <linux/dmi.h> 30 31MODULE_AUTHOR("Matthew Garrett <mjg59@srcf.ucam.org>"); 32MODULE_DESCRIPTION("HP laptop WMI hotkeys driver"); 33MODULE_LICENSE("GPL"); 34 35MODULE_ALIAS("wmi:95F24279-4D7B-4334-9387-ACCDC67EF61C"); 36MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4"); 37 38#define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C" 39#define HPWMI_BIOS_GUID "5FB7F034-2C63-45e9-BE91-3D44E2C707E4" 40#define HP_OMEN_EC_THERMAL_PROFILE_OFFSET 0x95 41#define zero_if_sup(tmp) (zero_insize_support?0:sizeof(tmp)) // use when zero insize is required 42 43/* DMI board names of devices that should use the omen specific path for 44 * thermal profiles. 45 * This was obtained by taking a look in the windows omen command center 46 * app and parsing a json file that they use to figure out what capabilities 47 * the device should have. 48 * A device is considered an omen if the DisplayName in that list contains 49 * "OMEN", and it can use the thermal profile stuff if the "Feature" array 50 * contains "PerformanceControl". 51 */ 52static const char * const omen_thermal_profile_boards[] = { 53 "84DA", "84DB", "84DC", "8574", "8575", "860A", "87B5", "8572", "8573", 54 "8600", "8601", "8602", "8605", "8606", "8607", "8746", "8747", "8749", 55 "874A", "8603", "8604", "8748", "886B", "886C", "878A", "878B", "878C", 56 "88C8", "88CB", "8786", "8787", "8788", "88D1", "88D2", "88F4", "88FD", 57 "88F5", "88F6", "88F7", "88FE", "88FF", "8900", "8901", "8902", "8912", 58 "8917", "8918", "8949", "894A", "89EB" 59}; 60 61/* DMI Board names of Omen laptops that are specifically set to be thermal 62 * profile version 0 by the Omen Command Center app, regardless of what 63 * the get system design information WMI call returns 64 */ 65static const char *const omen_thermal_profile_force_v0_boards[] = { 66 "8607", "8746", "8747", "8749", "874A", "8748" 67}; 68 69enum hp_wmi_radio { 70 HPWMI_WIFI = 0x0, 71 HPWMI_BLUETOOTH = 0x1, 72 HPWMI_WWAN = 0x2, 73 HPWMI_GPS = 0x3, 74}; 75 76enum hp_wmi_event_ids { 77 HPWMI_DOCK_EVENT = 0x01, 78 HPWMI_PARK_HDD = 0x02, 79 HPWMI_SMART_ADAPTER = 0x03, 80 HPWMI_BEZEL_BUTTON = 0x04, 81 HPWMI_WIRELESS = 0x05, 82 HPWMI_CPU_BATTERY_THROTTLE = 0x06, 83 HPWMI_LOCK_SWITCH = 0x07, 84 HPWMI_LID_SWITCH = 0x08, 85 HPWMI_SCREEN_ROTATION = 0x09, 86 HPWMI_COOLSENSE_SYSTEM_MOBILE = 0x0A, 87 HPWMI_COOLSENSE_SYSTEM_HOT = 0x0B, 88 HPWMI_PROXIMITY_SENSOR = 0x0C, 89 HPWMI_BACKLIT_KB_BRIGHTNESS = 0x0D, 90 HPWMI_PEAKSHIFT_PERIOD = 0x0F, 91 HPWMI_BATTERY_CHARGE_PERIOD = 0x10, 92 HPWMI_SANITIZATION_MODE = 0x17, 93}; 94 95/* 96 * struct bios_args buffer is dynamically allocated. New WMI command types 97 * were introduced that exceeds 128-byte data size. Changes to handle 98 * the data size allocation scheme were kept in hp_wmi_perform_qurey function. 99 */ 100struct bios_args { 101 u32 signature; 102 u32 command; 103 u32 commandtype; 104 u32 datasize; 105 u8 data[]; 106}; 107 108enum hp_wmi_commandtype { 109 HPWMI_DISPLAY_QUERY = 0x01, 110 HPWMI_HDDTEMP_QUERY = 0x02, 111 HPWMI_ALS_QUERY = 0x03, 112 HPWMI_HARDWARE_QUERY = 0x04, 113 HPWMI_WIRELESS_QUERY = 0x05, 114 HPWMI_BATTERY_QUERY = 0x07, 115 HPWMI_BIOS_QUERY = 0x09, 116 HPWMI_FEATURE_QUERY = 0x0b, 117 HPWMI_HOTKEY_QUERY = 0x0c, 118 HPWMI_FEATURE2_QUERY = 0x0d, 119 HPWMI_WIRELESS2_QUERY = 0x1b, 120 HPWMI_POSTCODEERROR_QUERY = 0x2a, 121 HPWMI_SYSTEM_DEVICE_MODE = 0x40, 122 HPWMI_THERMAL_PROFILE_QUERY = 0x4c, 123}; 124 125enum hp_wmi_gm_commandtype { 126 HPWMI_FAN_SPEED_GET_QUERY = 0x11, 127 HPWMI_SET_PERFORMANCE_MODE = 0x1A, 128 HPWMI_FAN_SPEED_MAX_GET_QUERY = 0x26, 129 HPWMI_FAN_SPEED_MAX_SET_QUERY = 0x27, 130 HPWMI_GET_SYSTEM_DESIGN_DATA = 0x28, 131}; 132 133enum hp_wmi_command { 134 HPWMI_READ = 0x01, 135 HPWMI_WRITE = 0x02, 136 HPWMI_ODM = 0x03, 137 HPWMI_GM = 0x20008, 138}; 139 140enum hp_wmi_hardware_mask { 141 HPWMI_DOCK_MASK = 0x01, 142 HPWMI_TABLET_MASK = 0x04, 143}; 144 145struct bios_return { 146 u32 sigpass; 147 u32 return_code; 148}; 149 150enum hp_return_value { 151 HPWMI_RET_WRONG_SIGNATURE = 0x02, 152 HPWMI_RET_UNKNOWN_COMMAND = 0x03, 153 HPWMI_RET_UNKNOWN_CMDTYPE = 0x04, 154 HPWMI_RET_INVALID_PARAMETERS = 0x05, 155}; 156 157enum hp_wireless2_bits { 158 HPWMI_POWER_STATE = 0x01, 159 HPWMI_POWER_SOFT = 0x02, 160 HPWMI_POWER_BIOS = 0x04, 161 HPWMI_POWER_HARD = 0x08, 162 HPWMI_POWER_FW_OR_HW = HPWMI_POWER_BIOS | HPWMI_POWER_HARD, 163}; 164 165enum hp_thermal_profile_omen_v0 { 166 HP_OMEN_V0_THERMAL_PROFILE_DEFAULT = 0x00, 167 HP_OMEN_V0_THERMAL_PROFILE_PERFORMANCE = 0x01, 168 HP_OMEN_V0_THERMAL_PROFILE_COOL = 0x02, 169}; 170 171enum hp_thermal_profile_omen_v1 { 172 HP_OMEN_V1_THERMAL_PROFILE_DEFAULT = 0x30, 173 HP_OMEN_V1_THERMAL_PROFILE_PERFORMANCE = 0x31, 174 HP_OMEN_V1_THERMAL_PROFILE_COOL = 0x50, 175}; 176 177enum hp_thermal_profile { 178 HP_THERMAL_PROFILE_PERFORMANCE = 0x00, 179 HP_THERMAL_PROFILE_DEFAULT = 0x01, 180 HP_THERMAL_PROFILE_COOL = 0x02 181}; 182 183#define IS_HWBLOCKED(x) ((x & HPWMI_POWER_FW_OR_HW) != HPWMI_POWER_FW_OR_HW) 184#define IS_SWBLOCKED(x) !(x & HPWMI_POWER_SOFT) 185 186struct bios_rfkill2_device_state { 187 u8 radio_type; 188 u8 bus_type; 189 u16 vendor_id; 190 u16 product_id; 191 u16 subsys_vendor_id; 192 u16 subsys_product_id; 193 u8 rfkill_id; 194 u8 power; 195 u8 unknown[4]; 196}; 197 198/* 7 devices fit into the 128 byte buffer */ 199#define HPWMI_MAX_RFKILL2_DEVICES 7 200 201struct bios_rfkill2_state { 202 u8 unknown[7]; 203 u8 count; 204 u8 pad[8]; 205 struct bios_rfkill2_device_state device[HPWMI_MAX_RFKILL2_DEVICES]; 206}; 207 208static const struct key_entry hp_wmi_keymap[] = { 209 { KE_KEY, 0x02, { KEY_BRIGHTNESSUP } }, 210 { KE_KEY, 0x03, { KEY_BRIGHTNESSDOWN } }, 211 { KE_KEY, 0x20e6, { KEY_PROG1 } }, 212 { KE_KEY, 0x20e8, { KEY_MEDIA } }, 213 { KE_KEY, 0x2142, { KEY_MEDIA } }, 214 { KE_KEY, 0x213b, { KEY_INFO } }, 215 { KE_KEY, 0x2169, { KEY_ROTATE_DISPLAY } }, 216 { KE_KEY, 0x216a, { KEY_SETUP } }, 217 { KE_KEY, 0x231b, { KEY_HELP } }, 218 { KE_END, 0 } 219}; 220 221static struct input_dev *hp_wmi_input_dev; 222static struct platform_device *hp_wmi_platform_dev; 223static struct platform_profile_handler platform_profile_handler; 224static bool platform_profile_support; 225static bool zero_insize_support; 226 227static struct rfkill *wifi_rfkill; 228static struct rfkill *bluetooth_rfkill; 229static struct rfkill *wwan_rfkill; 230 231struct rfkill2_device { 232 u8 id; 233 int num; 234 struct rfkill *rfkill; 235}; 236 237static int rfkill2_count; 238static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES]; 239 240/* 241 * Chassis Types values were obtained from SMBIOS reference 242 * specification version 3.00. A complete list of system enclosures 243 * and chassis types is available on Table 17. 244 */ 245static const char * const tablet_chassis_types[] = { 246 "30", /* Tablet*/ 247 "31", /* Convertible */ 248 "32" /* Detachable */ 249}; 250 251#define DEVICE_MODE_TABLET 0x06 252 253/* map output size to the corresponding WMI method id */ 254static inline int encode_outsize_for_pvsz(int outsize) 255{ 256 if (outsize > 4096) 257 return -EINVAL; 258 if (outsize > 1024) 259 return 5; 260 if (outsize > 128) 261 return 4; 262 if (outsize > 4) 263 return 3; 264 if (outsize > 0) 265 return 2; 266 return 1; 267} 268 269/* 270 * hp_wmi_perform_query 271 * 272 * query: The commandtype (enum hp_wmi_commandtype) 273 * write: The command (enum hp_wmi_command) 274 * buffer: Buffer used as input and/or output 275 * insize: Size of input buffer 276 * outsize: Size of output buffer 277 * 278 * returns zero on success 279 * an HP WMI query specific error code (which is positive) 280 * -EINVAL if the query was not successful at all 281 * -EINVAL if the output buffer size exceeds buffersize 282 * 283 * Note: The buffersize must at least be the maximum of the input and output 284 * size. E.g. Battery info query is defined to have 1 byte input 285 * and 128 byte output. The caller would do: 286 * buffer = kzalloc(128, GFP_KERNEL); 287 * ret = hp_wmi_perform_query(HPWMI_BATTERY_QUERY, HPWMI_READ, buffer, 1, 128) 288 */ 289static int hp_wmi_perform_query(int query, enum hp_wmi_command command, 290 void *buffer, int insize, int outsize) 291{ 292 struct acpi_buffer input, output = { ACPI_ALLOCATE_BUFFER, NULL }; 293 struct bios_return *bios_return; 294 union acpi_object *obj = NULL; 295 struct bios_args *args = NULL; 296 int mid, actual_insize, actual_outsize; 297 size_t bios_args_size; 298 int ret; 299 300 mid = encode_outsize_for_pvsz(outsize); 301 if (WARN_ON(mid < 0)) 302 return mid; 303 304 actual_insize = max(insize, 128); 305 bios_args_size = struct_size(args, data, actual_insize); 306 args = kmalloc(bios_args_size, GFP_KERNEL); 307 if (!args) 308 return -ENOMEM; 309 310 input.length = bios_args_size; 311 input.pointer = args; 312 313 args->signature = 0x55434553; 314 args->command = command; 315 args->commandtype = query; 316 args->datasize = insize; 317 memcpy(args->data, buffer, flex_array_size(args, data, insize)); 318 319 ret = wmi_evaluate_method(HPWMI_BIOS_GUID, 0, mid, &input, &output); 320 if (ret) 321 goto out_free; 322 323 obj = output.pointer; 324 if (!obj) { 325 ret = -EINVAL; 326 goto out_free; 327 } 328 329 if (obj->type != ACPI_TYPE_BUFFER) { 330 pr_warn("query 0x%x returned an invalid object 0x%x\n", query, ret); 331 ret = -EINVAL; 332 goto out_free; 333 } 334 335 bios_return = (struct bios_return *)obj->buffer.pointer; 336 ret = bios_return->return_code; 337 338 if (ret) { 339 if (ret != HPWMI_RET_UNKNOWN_COMMAND && 340 ret != HPWMI_RET_UNKNOWN_CMDTYPE) 341 pr_warn("query 0x%x returned error 0x%x\n", query, ret); 342 goto out_free; 343 } 344 345 /* Ignore output data of zero size */ 346 if (!outsize) 347 goto out_free; 348 349 actual_outsize = min(outsize, (int)(obj->buffer.length - sizeof(*bios_return))); 350 memcpy(buffer, obj->buffer.pointer + sizeof(*bios_return), actual_outsize); 351 memset(buffer + actual_outsize, 0, outsize - actual_outsize); 352 353out_free: 354 kfree(obj); 355 kfree(args); 356 return ret; 357} 358 359static int hp_wmi_get_fan_speed(int fan) 360{ 361 u8 fsh, fsl; 362 char fan_data[4] = { fan, 0, 0, 0 }; 363 364 int ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_GET_QUERY, HPWMI_GM, 365 &fan_data, sizeof(char), 366 sizeof(fan_data)); 367 368 if (ret != 0) 369 return -EINVAL; 370 371 fsh = fan_data[2]; 372 fsl = fan_data[3]; 373 374 return (fsh << 8) | fsl; 375} 376 377static int hp_wmi_read_int(int query) 378{ 379 int val = 0, ret; 380 381 ret = hp_wmi_perform_query(query, HPWMI_READ, &val, 382 zero_if_sup(val), sizeof(val)); 383 384 if (ret) 385 return ret < 0 ? ret : -EINVAL; 386 387 return val; 388} 389 390static int hp_wmi_get_dock_state(void) 391{ 392 int state = hp_wmi_read_int(HPWMI_HARDWARE_QUERY); 393 394 if (state < 0) 395 return state; 396 397 return !!(state & HPWMI_DOCK_MASK); 398} 399 400static int hp_wmi_get_tablet_mode(void) 401{ 402 char system_device_mode[4] = { 0 }; 403 const char *chassis_type; 404 bool tablet_found; 405 int ret; 406 407 chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE); 408 if (!chassis_type) 409 return -ENODEV; 410 411 tablet_found = match_string(tablet_chassis_types, 412 ARRAY_SIZE(tablet_chassis_types), 413 chassis_type) >= 0; 414 if (!tablet_found) 415 return -ENODEV; 416 417 ret = hp_wmi_perform_query(HPWMI_SYSTEM_DEVICE_MODE, HPWMI_READ, 418 system_device_mode, zero_if_sup(system_device_mode), 419 sizeof(system_device_mode)); 420 if (ret < 0) 421 return ret; 422 423 return system_device_mode[0] == DEVICE_MODE_TABLET; 424} 425 426static int omen_thermal_profile_set(int mode) 427{ 428 char buffer[2] = {0, mode}; 429 int ret; 430 431 ret = hp_wmi_perform_query(HPWMI_SET_PERFORMANCE_MODE, HPWMI_GM, 432 &buffer, sizeof(buffer), 0); 433 434 if (ret) 435 return ret < 0 ? ret : -EINVAL; 436 437 return mode; 438} 439 440static bool is_omen_thermal_profile(void) 441{ 442 const char *board_name = dmi_get_system_info(DMI_BOARD_NAME); 443 444 if (!board_name) 445 return false; 446 447 return match_string(omen_thermal_profile_boards, 448 ARRAY_SIZE(omen_thermal_profile_boards), 449 board_name) >= 0; 450} 451 452static int omen_get_thermal_policy_version(void) 453{ 454 unsigned char buffer[8] = { 0 }; 455 int ret; 456 457 const char *board_name = dmi_get_system_info(DMI_BOARD_NAME); 458 459 if (board_name) { 460 int matches = match_string(omen_thermal_profile_force_v0_boards, 461 ARRAY_SIZE(omen_thermal_profile_force_v0_boards), 462 board_name); 463 if (matches >= 0) 464 return 0; 465 } 466 467 ret = hp_wmi_perform_query(HPWMI_GET_SYSTEM_DESIGN_DATA, HPWMI_GM, 468 &buffer, sizeof(buffer), sizeof(buffer)); 469 470 if (ret) 471 return ret < 0 ? ret : -EINVAL; 472 473 return buffer[3]; 474} 475 476static int omen_thermal_profile_get(void) 477{ 478 u8 data; 479 480 int ret = ec_read(HP_OMEN_EC_THERMAL_PROFILE_OFFSET, &data); 481 482 if (ret) 483 return ret; 484 485 return data; 486} 487 488static int hp_wmi_fan_speed_max_set(int enabled) 489{ 490 int ret; 491 492 ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_MAX_SET_QUERY, HPWMI_GM, 493 &enabled, sizeof(enabled), 0); 494 495 if (ret) 496 return ret < 0 ? ret : -EINVAL; 497 498 return enabled; 499} 500 501static int hp_wmi_fan_speed_max_get(void) 502{ 503 int val = 0, ret; 504 505 ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_MAX_GET_QUERY, HPWMI_GM, 506 &val, zero_if_sup(val), sizeof(val)); 507 508 if (ret) 509 return ret < 0 ? ret : -EINVAL; 510 511 return val; 512} 513 514static int __init hp_wmi_bios_2008_later(void) 515{ 516 int state = 0; 517 int ret = hp_wmi_perform_query(HPWMI_FEATURE_QUERY, HPWMI_READ, &state, 518 zero_if_sup(state), sizeof(state)); 519 if (!ret) 520 return 1; 521 522 return (ret == HPWMI_RET_UNKNOWN_CMDTYPE) ? 0 : -ENXIO; 523} 524 525static int __init hp_wmi_bios_2009_later(void) 526{ 527 u8 state[128]; 528 int ret = hp_wmi_perform_query(HPWMI_FEATURE2_QUERY, HPWMI_READ, &state, 529 zero_if_sup(state), sizeof(state)); 530 if (!ret) 531 return 1; 532 533 return (ret == HPWMI_RET_UNKNOWN_CMDTYPE) ? 0 : -ENXIO; 534} 535 536static int __init hp_wmi_enable_hotkeys(void) 537{ 538 int value = 0x6e; 539 int ret = hp_wmi_perform_query(HPWMI_BIOS_QUERY, HPWMI_WRITE, &value, 540 sizeof(value), 0); 541 542 return ret <= 0 ? ret : -EINVAL; 543} 544 545static int hp_wmi_set_block(void *data, bool blocked) 546{ 547 enum hp_wmi_radio r = (enum hp_wmi_radio) data; 548 int query = BIT(r + 8) | ((!blocked) << r); 549 int ret; 550 551 ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, HPWMI_WRITE, 552 &query, sizeof(query), 0); 553 554 return ret <= 0 ? ret : -EINVAL; 555} 556 557static const struct rfkill_ops hp_wmi_rfkill_ops = { 558 .set_block = hp_wmi_set_block, 559}; 560 561static bool hp_wmi_get_sw_state(enum hp_wmi_radio r) 562{ 563 int mask = 0x200 << (r * 8); 564 565 int wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY); 566 567 /* TBD: Pass error */ 568 WARN_ONCE(wireless < 0, "error executing HPWMI_WIRELESS_QUERY"); 569 570 return !(wireless & mask); 571} 572 573static bool hp_wmi_get_hw_state(enum hp_wmi_radio r) 574{ 575 int mask = 0x800 << (r * 8); 576 577 int wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY); 578 579 /* TBD: Pass error */ 580 WARN_ONCE(wireless < 0, "error executing HPWMI_WIRELESS_QUERY"); 581 582 return !(wireless & mask); 583} 584 585static int hp_wmi_rfkill2_set_block(void *data, bool blocked) 586{ 587 int rfkill_id = (int)(long)data; 588 char buffer[4] = { 0x01, 0x00, rfkill_id, !blocked }; 589 int ret; 590 591 ret = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_WRITE, 592 buffer, sizeof(buffer), 0); 593 594 return ret <= 0 ? ret : -EINVAL; 595} 596 597static const struct rfkill_ops hp_wmi_rfkill2_ops = { 598 .set_block = hp_wmi_rfkill2_set_block, 599}; 600 601static int hp_wmi_rfkill2_refresh(void) 602{ 603 struct bios_rfkill2_state state; 604 int err, i; 605 606 err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state, 607 zero_if_sup(state), sizeof(state)); 608 if (err) 609 return err; 610 611 for (i = 0; i < rfkill2_count; i++) { 612 int num = rfkill2[i].num; 613 struct bios_rfkill2_device_state *devstate; 614 615 devstate = &state.device[num]; 616 617 if (num >= state.count || 618 devstate->rfkill_id != rfkill2[i].id) { 619 pr_warn("power configuration of the wireless devices unexpectedly changed\n"); 620 continue; 621 } 622 623 rfkill_set_states(rfkill2[i].rfkill, 624 IS_SWBLOCKED(devstate->power), 625 IS_HWBLOCKED(devstate->power)); 626 } 627 628 return 0; 629} 630 631static ssize_t display_show(struct device *dev, struct device_attribute *attr, 632 char *buf) 633{ 634 int value = hp_wmi_read_int(HPWMI_DISPLAY_QUERY); 635 636 if (value < 0) 637 return value; 638 return sprintf(buf, "%d\n", value); 639} 640 641static ssize_t hddtemp_show(struct device *dev, struct device_attribute *attr, 642 char *buf) 643{ 644 int value = hp_wmi_read_int(HPWMI_HDDTEMP_QUERY); 645 646 if (value < 0) 647 return value; 648 return sprintf(buf, "%d\n", value); 649} 650 651static ssize_t als_show(struct device *dev, struct device_attribute *attr, 652 char *buf) 653{ 654 int value = hp_wmi_read_int(HPWMI_ALS_QUERY); 655 656 if (value < 0) 657 return value; 658 return sprintf(buf, "%d\n", value); 659} 660 661static ssize_t dock_show(struct device *dev, struct device_attribute *attr, 662 char *buf) 663{ 664 int value = hp_wmi_get_dock_state(); 665 666 if (value < 0) 667 return value; 668 return sprintf(buf, "%d\n", value); 669} 670 671static ssize_t tablet_show(struct device *dev, struct device_attribute *attr, 672 char *buf) 673{ 674 int value = hp_wmi_get_tablet_mode(); 675 676 if (value < 0) 677 return value; 678 return sprintf(buf, "%d\n", value); 679} 680 681static ssize_t postcode_show(struct device *dev, struct device_attribute *attr, 682 char *buf) 683{ 684 /* Get the POST error code of previous boot failure. */ 685 int value = hp_wmi_read_int(HPWMI_POSTCODEERROR_QUERY); 686 687 if (value < 0) 688 return value; 689 return sprintf(buf, "0x%x\n", value); 690} 691 692static ssize_t als_store(struct device *dev, struct device_attribute *attr, 693 const char *buf, size_t count) 694{ 695 u32 tmp; 696 int ret; 697 698 ret = kstrtou32(buf, 10, &tmp); 699 if (ret) 700 return ret; 701 702 ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, HPWMI_WRITE, &tmp, 703 sizeof(tmp), 0); 704 if (ret) 705 return ret < 0 ? ret : -EINVAL; 706 707 return count; 708} 709 710static ssize_t postcode_store(struct device *dev, struct device_attribute *attr, 711 const char *buf, size_t count) 712{ 713 u32 tmp = 1; 714 bool clear; 715 int ret; 716 717 ret = kstrtobool(buf, &clear); 718 if (ret) 719 return ret; 720 721 if (clear == false) 722 return -EINVAL; 723 724 /* Clear the POST error code. It is kept until cleared. */ 725 ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, HPWMI_WRITE, &tmp, 726 sizeof(tmp), 0); 727 if (ret) 728 return ret < 0 ? ret : -EINVAL; 729 730 return count; 731} 732 733static DEVICE_ATTR_RO(display); 734static DEVICE_ATTR_RO(hddtemp); 735static DEVICE_ATTR_RW(als); 736static DEVICE_ATTR_RO(dock); 737static DEVICE_ATTR_RO(tablet); 738static DEVICE_ATTR_RW(postcode); 739 740static struct attribute *hp_wmi_attrs[] = { 741 &dev_attr_display.attr, 742 &dev_attr_hddtemp.attr, 743 &dev_attr_als.attr, 744 &dev_attr_dock.attr, 745 &dev_attr_tablet.attr, 746 &dev_attr_postcode.attr, 747 NULL, 748}; 749ATTRIBUTE_GROUPS(hp_wmi); 750 751static void hp_wmi_notify(u32 value, void *context) 752{ 753 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; 754 u32 event_id, event_data; 755 union acpi_object *obj; 756 acpi_status status; 757 u32 *location; 758 int key_code; 759 760 status = wmi_get_event_data(value, &response); 761 if (status != AE_OK) { 762 pr_info("bad event status 0x%x\n", status); 763 return; 764 } 765 766 obj = (union acpi_object *)response.pointer; 767 768 if (!obj) 769 return; 770 if (obj->type != ACPI_TYPE_BUFFER) { 771 pr_info("Unknown response received %d\n", obj->type); 772 kfree(obj); 773 return; 774 } 775 776 /* 777 * Depending on ACPI version the concatenation of id and event data 778 * inside _WED function will result in a 8 or 16 byte buffer. 779 */ 780 location = (u32 *)obj->buffer.pointer; 781 if (obj->buffer.length == 8) { 782 event_id = *location; 783 event_data = *(location + 1); 784 } else if (obj->buffer.length == 16) { 785 event_id = *location; 786 event_data = *(location + 2); 787 } else { 788 pr_info("Unknown buffer length %d\n", obj->buffer.length); 789 kfree(obj); 790 return; 791 } 792 kfree(obj); 793 794 switch (event_id) { 795 case HPWMI_DOCK_EVENT: 796 if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit)) 797 input_report_switch(hp_wmi_input_dev, SW_DOCK, 798 hp_wmi_get_dock_state()); 799 if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit)) 800 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, 801 hp_wmi_get_tablet_mode()); 802 input_sync(hp_wmi_input_dev); 803 break; 804 case HPWMI_PARK_HDD: 805 break; 806 case HPWMI_SMART_ADAPTER: 807 break; 808 case HPWMI_BEZEL_BUTTON: 809 key_code = hp_wmi_read_int(HPWMI_HOTKEY_QUERY); 810 if (key_code < 0) 811 break; 812 813 if (!sparse_keymap_report_event(hp_wmi_input_dev, 814 key_code, 1, true)) 815 pr_info("Unknown key code - 0x%x\n", key_code); 816 break; 817 case HPWMI_WIRELESS: 818 if (rfkill2_count) { 819 hp_wmi_rfkill2_refresh(); 820 break; 821 } 822 823 if (wifi_rfkill) 824 rfkill_set_states(wifi_rfkill, 825 hp_wmi_get_sw_state(HPWMI_WIFI), 826 hp_wmi_get_hw_state(HPWMI_WIFI)); 827 if (bluetooth_rfkill) 828 rfkill_set_states(bluetooth_rfkill, 829 hp_wmi_get_sw_state(HPWMI_BLUETOOTH), 830 hp_wmi_get_hw_state(HPWMI_BLUETOOTH)); 831 if (wwan_rfkill) 832 rfkill_set_states(wwan_rfkill, 833 hp_wmi_get_sw_state(HPWMI_WWAN), 834 hp_wmi_get_hw_state(HPWMI_WWAN)); 835 break; 836 case HPWMI_CPU_BATTERY_THROTTLE: 837 pr_info("Unimplemented CPU throttle because of 3 Cell battery event detected\n"); 838 break; 839 case HPWMI_LOCK_SWITCH: 840 break; 841 case HPWMI_LID_SWITCH: 842 break; 843 case HPWMI_SCREEN_ROTATION: 844 break; 845 case HPWMI_COOLSENSE_SYSTEM_MOBILE: 846 break; 847 case HPWMI_COOLSENSE_SYSTEM_HOT: 848 break; 849 case HPWMI_PROXIMITY_SENSOR: 850 break; 851 case HPWMI_BACKLIT_KB_BRIGHTNESS: 852 break; 853 case HPWMI_PEAKSHIFT_PERIOD: 854 break; 855 case HPWMI_BATTERY_CHARGE_PERIOD: 856 break; 857 case HPWMI_SANITIZATION_MODE: 858 break; 859 default: 860 pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data); 861 break; 862 } 863} 864 865static int __init hp_wmi_input_setup(void) 866{ 867 acpi_status status; 868 int err, val; 869 870 hp_wmi_input_dev = input_allocate_device(); 871 if (!hp_wmi_input_dev) 872 return -ENOMEM; 873 874 hp_wmi_input_dev->name = "HP WMI hotkeys"; 875 hp_wmi_input_dev->phys = "wmi/input0"; 876 hp_wmi_input_dev->id.bustype = BUS_HOST; 877 878 __set_bit(EV_SW, hp_wmi_input_dev->evbit); 879 880 /* Dock */ 881 val = hp_wmi_get_dock_state(); 882 if (!(val < 0)) { 883 __set_bit(SW_DOCK, hp_wmi_input_dev->swbit); 884 input_report_switch(hp_wmi_input_dev, SW_DOCK, val); 885 } 886 887 /* Tablet mode */ 888 val = hp_wmi_get_tablet_mode(); 889 if (!(val < 0)) { 890 __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit); 891 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val); 892 } 893 894 err = sparse_keymap_setup(hp_wmi_input_dev, hp_wmi_keymap, NULL); 895 if (err) 896 goto err_free_dev; 897 898 /* Set initial hardware state */ 899 input_sync(hp_wmi_input_dev); 900 901 if (!hp_wmi_bios_2009_later() && hp_wmi_bios_2008_later()) 902 hp_wmi_enable_hotkeys(); 903 904 status = wmi_install_notify_handler(HPWMI_EVENT_GUID, hp_wmi_notify, NULL); 905 if (ACPI_FAILURE(status)) { 906 err = -EIO; 907 goto err_free_dev; 908 } 909 910 err = input_register_device(hp_wmi_input_dev); 911 if (err) 912 goto err_uninstall_notifier; 913 914 return 0; 915 916 err_uninstall_notifier: 917 wmi_remove_notify_handler(HPWMI_EVENT_GUID); 918 err_free_dev: 919 input_free_device(hp_wmi_input_dev); 920 return err; 921} 922 923static void hp_wmi_input_destroy(void) 924{ 925 wmi_remove_notify_handler(HPWMI_EVENT_GUID); 926 input_unregister_device(hp_wmi_input_dev); 927} 928 929static int __init hp_wmi_rfkill_setup(struct platform_device *device) 930{ 931 int err, wireless; 932 933 wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY); 934 if (wireless < 0) 935 return wireless; 936 937 err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, HPWMI_WRITE, &wireless, 938 sizeof(wireless), 0); 939 if (err) 940 return err; 941 942 if (wireless & 0x1) { 943 wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev, 944 RFKILL_TYPE_WLAN, 945 &hp_wmi_rfkill_ops, 946 (void *) HPWMI_WIFI); 947 if (!wifi_rfkill) 948 return -ENOMEM; 949 rfkill_init_sw_state(wifi_rfkill, 950 hp_wmi_get_sw_state(HPWMI_WIFI)); 951 rfkill_set_hw_state(wifi_rfkill, 952 hp_wmi_get_hw_state(HPWMI_WIFI)); 953 err = rfkill_register(wifi_rfkill); 954 if (err) 955 goto register_wifi_error; 956 } 957 958 if (wireless & 0x2) { 959 bluetooth_rfkill = rfkill_alloc("hp-bluetooth", &device->dev, 960 RFKILL_TYPE_BLUETOOTH, 961 &hp_wmi_rfkill_ops, 962 (void *) HPWMI_BLUETOOTH); 963 if (!bluetooth_rfkill) { 964 err = -ENOMEM; 965 goto register_bluetooth_error; 966 } 967 rfkill_init_sw_state(bluetooth_rfkill, 968 hp_wmi_get_sw_state(HPWMI_BLUETOOTH)); 969 rfkill_set_hw_state(bluetooth_rfkill, 970 hp_wmi_get_hw_state(HPWMI_BLUETOOTH)); 971 err = rfkill_register(bluetooth_rfkill); 972 if (err) 973 goto register_bluetooth_error; 974 } 975 976 if (wireless & 0x4) { 977 wwan_rfkill = rfkill_alloc("hp-wwan", &device->dev, 978 RFKILL_TYPE_WWAN, 979 &hp_wmi_rfkill_ops, 980 (void *) HPWMI_WWAN); 981 if (!wwan_rfkill) { 982 err = -ENOMEM; 983 goto register_wwan_error; 984 } 985 rfkill_init_sw_state(wwan_rfkill, 986 hp_wmi_get_sw_state(HPWMI_WWAN)); 987 rfkill_set_hw_state(wwan_rfkill, 988 hp_wmi_get_hw_state(HPWMI_WWAN)); 989 err = rfkill_register(wwan_rfkill); 990 if (err) 991 goto register_wwan_error; 992 } 993 994 return 0; 995 996register_wwan_error: 997 rfkill_destroy(wwan_rfkill); 998 wwan_rfkill = NULL; 999 if (bluetooth_rfkill) 1000 rfkill_unregister(bluetooth_rfkill); 1001register_bluetooth_error: 1002 rfkill_destroy(bluetooth_rfkill); 1003 bluetooth_rfkill = NULL; 1004 if (wifi_rfkill) 1005 rfkill_unregister(wifi_rfkill); 1006register_wifi_error: 1007 rfkill_destroy(wifi_rfkill); 1008 wifi_rfkill = NULL; 1009 return err; 1010} 1011 1012static int __init hp_wmi_rfkill2_setup(struct platform_device *device) 1013{ 1014 struct bios_rfkill2_state state; 1015 int err, i; 1016 1017 err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state, 1018 zero_if_sup(state), sizeof(state)); 1019 if (err) 1020 return err < 0 ? err : -EINVAL; 1021 1022 if (state.count > HPWMI_MAX_RFKILL2_DEVICES) { 1023 pr_warn("unable to parse 0x1b query output\n"); 1024 return -EINVAL; 1025 } 1026 1027 for (i = 0; i < state.count; i++) { 1028 struct rfkill *rfkill; 1029 enum rfkill_type type; 1030 char *name; 1031 1032 switch (state.device[i].radio_type) { 1033 case HPWMI_WIFI: 1034 type = RFKILL_TYPE_WLAN; 1035 name = "hp-wifi"; 1036 break; 1037 case HPWMI_BLUETOOTH: 1038 type = RFKILL_TYPE_BLUETOOTH; 1039 name = "hp-bluetooth"; 1040 break; 1041 case HPWMI_WWAN: 1042 type = RFKILL_TYPE_WWAN; 1043 name = "hp-wwan"; 1044 break; 1045 case HPWMI_GPS: 1046 type = RFKILL_TYPE_GPS; 1047 name = "hp-gps"; 1048 break; 1049 default: 1050 pr_warn("unknown device type 0x%x\n", 1051 state.device[i].radio_type); 1052 continue; 1053 } 1054 1055 if (!state.device[i].vendor_id) { 1056 pr_warn("zero device %d while %d reported\n", 1057 i, state.count); 1058 continue; 1059 } 1060 1061 rfkill = rfkill_alloc(name, &device->dev, type, 1062 &hp_wmi_rfkill2_ops, (void *)(long)i); 1063 if (!rfkill) { 1064 err = -ENOMEM; 1065 goto fail; 1066 } 1067 1068 rfkill2[rfkill2_count].id = state.device[i].rfkill_id; 1069 rfkill2[rfkill2_count].num = i; 1070 rfkill2[rfkill2_count].rfkill = rfkill; 1071 1072 rfkill_init_sw_state(rfkill, 1073 IS_SWBLOCKED(state.device[i].power)); 1074 rfkill_set_hw_state(rfkill, 1075 IS_HWBLOCKED(state.device[i].power)); 1076 1077 if (!(state.device[i].power & HPWMI_POWER_BIOS)) 1078 pr_info("device %s blocked by BIOS\n", name); 1079 1080 err = rfkill_register(rfkill); 1081 if (err) { 1082 rfkill_destroy(rfkill); 1083 goto fail; 1084 } 1085 1086 rfkill2_count++; 1087 } 1088 1089 return 0; 1090fail: 1091 for (; rfkill2_count > 0; rfkill2_count--) { 1092 rfkill_unregister(rfkill2[rfkill2_count - 1].rfkill); 1093 rfkill_destroy(rfkill2[rfkill2_count - 1].rfkill); 1094 } 1095 return err; 1096} 1097 1098static int platform_profile_omen_get(struct platform_profile_handler *pprof, 1099 enum platform_profile_option *profile) 1100{ 1101 int tp; 1102 1103 tp = omen_thermal_profile_get(); 1104 if (tp < 0) 1105 return tp; 1106 1107 switch (tp) { 1108 case HP_OMEN_V0_THERMAL_PROFILE_PERFORMANCE: 1109 case HP_OMEN_V1_THERMAL_PROFILE_PERFORMANCE: 1110 *profile = PLATFORM_PROFILE_PERFORMANCE; 1111 break; 1112 case HP_OMEN_V0_THERMAL_PROFILE_DEFAULT: 1113 case HP_OMEN_V1_THERMAL_PROFILE_DEFAULT: 1114 *profile = PLATFORM_PROFILE_BALANCED; 1115 break; 1116 case HP_OMEN_V0_THERMAL_PROFILE_COOL: 1117 case HP_OMEN_V1_THERMAL_PROFILE_COOL: 1118 *profile = PLATFORM_PROFILE_COOL; 1119 break; 1120 default: 1121 return -EINVAL; 1122 } 1123 1124 return 0; 1125} 1126 1127static int platform_profile_omen_set(struct platform_profile_handler *pprof, 1128 enum platform_profile_option profile) 1129{ 1130 int err, tp, tp_version; 1131 1132 tp_version = omen_get_thermal_policy_version(); 1133 1134 if (tp_version < 0 || tp_version > 1) 1135 return -EOPNOTSUPP; 1136 1137 switch (profile) { 1138 case PLATFORM_PROFILE_PERFORMANCE: 1139 if (tp_version == 0) 1140 tp = HP_OMEN_V0_THERMAL_PROFILE_PERFORMANCE; 1141 else 1142 tp = HP_OMEN_V1_THERMAL_PROFILE_PERFORMANCE; 1143 break; 1144 case PLATFORM_PROFILE_BALANCED: 1145 if (tp_version == 0) 1146 tp = HP_OMEN_V0_THERMAL_PROFILE_DEFAULT; 1147 else 1148 tp = HP_OMEN_V1_THERMAL_PROFILE_DEFAULT; 1149 break; 1150 case PLATFORM_PROFILE_COOL: 1151 if (tp_version == 0) 1152 tp = HP_OMEN_V0_THERMAL_PROFILE_COOL; 1153 else 1154 tp = HP_OMEN_V1_THERMAL_PROFILE_COOL; 1155 break; 1156 default: 1157 return -EOPNOTSUPP; 1158 } 1159 1160 err = omen_thermal_profile_set(tp); 1161 if (err < 0) 1162 return err; 1163 1164 return 0; 1165} 1166 1167static int thermal_profile_get(void) 1168{ 1169 return hp_wmi_read_int(HPWMI_THERMAL_PROFILE_QUERY); 1170} 1171 1172static int thermal_profile_set(int thermal_profile) 1173{ 1174 return hp_wmi_perform_query(HPWMI_THERMAL_PROFILE_QUERY, HPWMI_WRITE, &thermal_profile, 1175 sizeof(thermal_profile), 0); 1176} 1177 1178static int hp_wmi_platform_profile_get(struct platform_profile_handler *pprof, 1179 enum platform_profile_option *profile) 1180{ 1181 int tp; 1182 1183 tp = thermal_profile_get(); 1184 if (tp < 0) 1185 return tp; 1186 1187 switch (tp) { 1188 case HP_THERMAL_PROFILE_PERFORMANCE: 1189 *profile = PLATFORM_PROFILE_PERFORMANCE; 1190 break; 1191 case HP_THERMAL_PROFILE_DEFAULT: 1192 *profile = PLATFORM_PROFILE_BALANCED; 1193 break; 1194 case HP_THERMAL_PROFILE_COOL: 1195 *profile = PLATFORM_PROFILE_COOL; 1196 break; 1197 default: 1198 return -EINVAL; 1199 } 1200 1201 return 0; 1202} 1203 1204static int hp_wmi_platform_profile_set(struct platform_profile_handler *pprof, 1205 enum platform_profile_option profile) 1206{ 1207 int err, tp; 1208 1209 switch (profile) { 1210 case PLATFORM_PROFILE_PERFORMANCE: 1211 tp = HP_THERMAL_PROFILE_PERFORMANCE; 1212 break; 1213 case PLATFORM_PROFILE_BALANCED: 1214 tp = HP_THERMAL_PROFILE_DEFAULT; 1215 break; 1216 case PLATFORM_PROFILE_COOL: 1217 tp = HP_THERMAL_PROFILE_COOL; 1218 break; 1219 default: 1220 return -EOPNOTSUPP; 1221 } 1222 1223 err = thermal_profile_set(tp); 1224 if (err) 1225 return err; 1226 1227 return 0; 1228} 1229 1230static int thermal_profile_setup(void) 1231{ 1232 int err, tp; 1233 1234 if (is_omen_thermal_profile()) { 1235 tp = omen_thermal_profile_get(); 1236 if (tp < 0) 1237 return tp; 1238 1239 /* 1240 * call thermal profile write command to ensure that the 1241 * firmware correctly sets the OEM variables 1242 */ 1243 1244 err = omen_thermal_profile_set(tp); 1245 if (err < 0) 1246 return err; 1247 1248 platform_profile_handler.profile_get = platform_profile_omen_get; 1249 platform_profile_handler.profile_set = platform_profile_omen_set; 1250 } else { 1251 tp = thermal_profile_get(); 1252 1253 if (tp < 0) 1254 return tp; 1255 1256 /* 1257 * call thermal profile write command to ensure that the 1258 * firmware correctly sets the OEM variables for the DPTF 1259 */ 1260 err = thermal_profile_set(tp); 1261 if (err) 1262 return err; 1263 1264 platform_profile_handler.profile_get = hp_wmi_platform_profile_get; 1265 platform_profile_handler.profile_set = hp_wmi_platform_profile_set; 1266 } 1267 1268 set_bit(PLATFORM_PROFILE_COOL, platform_profile_handler.choices); 1269 set_bit(PLATFORM_PROFILE_BALANCED, platform_profile_handler.choices); 1270 set_bit(PLATFORM_PROFILE_PERFORMANCE, platform_profile_handler.choices); 1271 1272 err = platform_profile_register(&platform_profile_handler); 1273 if (err) 1274 return err; 1275 1276 platform_profile_support = true; 1277 1278 return 0; 1279} 1280 1281static int hp_wmi_hwmon_init(void); 1282 1283static int __init hp_wmi_bios_setup(struct platform_device *device) 1284{ 1285 int err; 1286 /* clear detected rfkill devices */ 1287 wifi_rfkill = NULL; 1288 bluetooth_rfkill = NULL; 1289 wwan_rfkill = NULL; 1290 rfkill2_count = 0; 1291 1292 if (hp_wmi_rfkill_setup(device)) 1293 hp_wmi_rfkill2_setup(device); 1294 1295 err = hp_wmi_hwmon_init(); 1296 1297 if (err < 0) 1298 return err; 1299 1300 thermal_profile_setup(); 1301 1302 return 0; 1303} 1304 1305static int __exit hp_wmi_bios_remove(struct platform_device *device) 1306{ 1307 int i; 1308 1309 for (i = 0; i < rfkill2_count; i++) { 1310 rfkill_unregister(rfkill2[i].rfkill); 1311 rfkill_destroy(rfkill2[i].rfkill); 1312 } 1313 1314 if (wifi_rfkill) { 1315 rfkill_unregister(wifi_rfkill); 1316 rfkill_destroy(wifi_rfkill); 1317 } 1318 if (bluetooth_rfkill) { 1319 rfkill_unregister(bluetooth_rfkill); 1320 rfkill_destroy(bluetooth_rfkill); 1321 } 1322 if (wwan_rfkill) { 1323 rfkill_unregister(wwan_rfkill); 1324 rfkill_destroy(wwan_rfkill); 1325 } 1326 1327 if (platform_profile_support) 1328 platform_profile_remove(); 1329 1330 return 0; 1331} 1332 1333static int hp_wmi_resume_handler(struct device *device) 1334{ 1335 /* 1336 * Hardware state may have changed while suspended, so trigger 1337 * input events for the current state. As this is a switch, 1338 * the input layer will only actually pass it on if the state 1339 * changed. 1340 */ 1341 if (hp_wmi_input_dev) { 1342 if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit)) 1343 input_report_switch(hp_wmi_input_dev, SW_DOCK, 1344 hp_wmi_get_dock_state()); 1345 if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit)) 1346 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, 1347 hp_wmi_get_tablet_mode()); 1348 input_sync(hp_wmi_input_dev); 1349 } 1350 1351 if (rfkill2_count) 1352 hp_wmi_rfkill2_refresh(); 1353 1354 if (wifi_rfkill) 1355 rfkill_set_states(wifi_rfkill, 1356 hp_wmi_get_sw_state(HPWMI_WIFI), 1357 hp_wmi_get_hw_state(HPWMI_WIFI)); 1358 if (bluetooth_rfkill) 1359 rfkill_set_states(bluetooth_rfkill, 1360 hp_wmi_get_sw_state(HPWMI_BLUETOOTH), 1361 hp_wmi_get_hw_state(HPWMI_BLUETOOTH)); 1362 if (wwan_rfkill) 1363 rfkill_set_states(wwan_rfkill, 1364 hp_wmi_get_sw_state(HPWMI_WWAN), 1365 hp_wmi_get_hw_state(HPWMI_WWAN)); 1366 1367 return 0; 1368} 1369 1370static const struct dev_pm_ops hp_wmi_pm_ops = { 1371 .resume = hp_wmi_resume_handler, 1372 .restore = hp_wmi_resume_handler, 1373}; 1374 1375static struct platform_driver hp_wmi_driver = { 1376 .driver = { 1377 .name = "hp-wmi", 1378 .pm = &hp_wmi_pm_ops, 1379 .dev_groups = hp_wmi_groups, 1380 }, 1381 .remove = __exit_p(hp_wmi_bios_remove), 1382}; 1383 1384static umode_t hp_wmi_hwmon_is_visible(const void *data, 1385 enum hwmon_sensor_types type, 1386 u32 attr, int channel) 1387{ 1388 switch (type) { 1389 case hwmon_pwm: 1390 return 0644; 1391 case hwmon_fan: 1392 if (hp_wmi_get_fan_speed(channel) >= 0) 1393 return 0444; 1394 break; 1395 default: 1396 return 0; 1397 } 1398 1399 return 0; 1400} 1401 1402static int hp_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type, 1403 u32 attr, int channel, long *val) 1404{ 1405 int ret; 1406 1407 switch (type) { 1408 case hwmon_fan: 1409 ret = hp_wmi_get_fan_speed(channel); 1410 1411 if (ret < 0) 1412 return ret; 1413 *val = ret; 1414 return 0; 1415 case hwmon_pwm: 1416 switch (hp_wmi_fan_speed_max_get()) { 1417 case 0: 1418 /* 0 is automatic fan, which is 2 for hwmon */ 1419 *val = 2; 1420 return 0; 1421 case 1: 1422 /* 1 is max fan, which is 0 1423 * (no fan speed control) for hwmon 1424 */ 1425 *val = 0; 1426 return 0; 1427 default: 1428 /* shouldn't happen */ 1429 return -ENODATA; 1430 } 1431 default: 1432 return -EINVAL; 1433 } 1434} 1435 1436static int hp_wmi_hwmon_write(struct device *dev, enum hwmon_sensor_types type, 1437 u32 attr, int channel, long val) 1438{ 1439 switch (type) { 1440 case hwmon_pwm: 1441 switch (val) { 1442 case 0: 1443 /* 0 is no fan speed control (max), which is 1 for us */ 1444 return hp_wmi_fan_speed_max_set(1); 1445 case 2: 1446 /* 2 is automatic speed control, which is 0 for us */ 1447 return hp_wmi_fan_speed_max_set(0); 1448 default: 1449 /* we don't support manual fan speed control */ 1450 return -EINVAL; 1451 } 1452 default: 1453 return -EOPNOTSUPP; 1454 } 1455} 1456 1457static const struct hwmon_channel_info *info[] = { 1458 HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT, HWMON_F_INPUT), 1459 HWMON_CHANNEL_INFO(pwm, HWMON_PWM_ENABLE), 1460 NULL 1461}; 1462 1463static const struct hwmon_ops ops = { 1464 .is_visible = hp_wmi_hwmon_is_visible, 1465 .read = hp_wmi_hwmon_read, 1466 .write = hp_wmi_hwmon_write, 1467}; 1468 1469static const struct hwmon_chip_info chip_info = { 1470 .ops = &ops, 1471 .info = info, 1472}; 1473 1474static int hp_wmi_hwmon_init(void) 1475{ 1476 struct device *dev = &hp_wmi_platform_dev->dev; 1477 struct device *hwmon; 1478 1479 hwmon = devm_hwmon_device_register_with_info(dev, "hp", &hp_wmi_driver, 1480 &chip_info, NULL); 1481 1482 if (IS_ERR(hwmon)) { 1483 dev_err(dev, "Could not register hp hwmon device\n"); 1484 return PTR_ERR(hwmon); 1485 } 1486 1487 return 0; 1488} 1489 1490static int __init hp_wmi_init(void) 1491{ 1492 int event_capable = wmi_has_guid(HPWMI_EVENT_GUID); 1493 int bios_capable = wmi_has_guid(HPWMI_BIOS_GUID); 1494 int err, tmp = 0; 1495 1496 if (!bios_capable && !event_capable) 1497 return -ENODEV; 1498 1499 if (hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, HPWMI_READ, &tmp, 1500 sizeof(tmp), sizeof(tmp)) == HPWMI_RET_INVALID_PARAMETERS) 1501 zero_insize_support = true; 1502 1503 if (event_capable) { 1504 err = hp_wmi_input_setup(); 1505 if (err) 1506 return err; 1507 } 1508 1509 if (bios_capable) { 1510 hp_wmi_platform_dev = 1511 platform_device_register_simple("hp-wmi", -1, NULL, 0); 1512 if (IS_ERR(hp_wmi_platform_dev)) { 1513 err = PTR_ERR(hp_wmi_platform_dev); 1514 goto err_destroy_input; 1515 } 1516 1517 err = platform_driver_probe(&hp_wmi_driver, hp_wmi_bios_setup); 1518 if (err) 1519 goto err_unregister_device; 1520 } 1521 1522 return 0; 1523 1524err_unregister_device: 1525 platform_device_unregister(hp_wmi_platform_dev); 1526err_destroy_input: 1527 if (event_capable) 1528 hp_wmi_input_destroy(); 1529 1530 return err; 1531} 1532module_init(hp_wmi_init); 1533 1534static void __exit hp_wmi_exit(void) 1535{ 1536 if (wmi_has_guid(HPWMI_EVENT_GUID)) 1537 hp_wmi_input_destroy(); 1538 1539 if (hp_wmi_platform_dev) { 1540 platform_device_unregister(hp_wmi_platform_dev); 1541 platform_driver_unregister(&hp_wmi_driver); 1542 } 1543} 1544module_exit(hp_wmi_exit);