1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Alienware WMAX WMI device driver 4 * 5 * Copyright (C) 2014 Dell Inc <Dell.Client.Kernel@dell.com> 6 * Copyright (C) 2025 Kurt Borja <kuurtb@gmail.com> 7 */ 8 9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 10 11 #include <linux/array_size.h> 12 #include <linux/bitfield.h> 13 #include <linux/bitmap.h> 14 #include <linux/bits.h> 15 #include <linux/debugfs.h> 16 #include <linux/dmi.h> 17 #include <linux/hwmon.h> 18 #include <linux/hwmon-sysfs.h> 19 #include <linux/kstrtox.h> 20 #include <linux/minmax.h> 21 #include <linux/moduleparam.h> 22 #include <linux/platform_profile.h> 23 #include <linux/pm.h> 24 #include <linux/seq_file.h> 25 #include <linux/units.h> 26 #include <linux/wmi.h> 27 #include "alienware-wmi.h" 28 29 #define WMAX_METHOD_HDMI_SOURCE 0x1 30 #define WMAX_METHOD_HDMI_STATUS 0x2 31 #define WMAX_METHOD_HDMI_CABLE 0x5 32 #define WMAX_METHOD_AMPLIFIER_CABLE 0x6 33 #define WMAX_METHOD_DEEP_SLEEP_CONTROL 0x0B 34 #define WMAX_METHOD_DEEP_SLEEP_STATUS 0x0C 35 #define WMAX_METHOD_BRIGHTNESS 0x3 36 #define WMAX_METHOD_ZONE_CONTROL 0x4 37 38 #define AWCC_METHOD_GET_FAN_SENSORS 0x13 39 #define AWCC_METHOD_THERMAL_INFORMATION 0x14 40 #define AWCC_METHOD_THERMAL_CONTROL 0x15 41 #define AWCC_METHOD_FWUP_GPIO_CONTROL 0x20 42 #define AWCC_METHOD_READ_TOTAL_GPIOS 0x21 43 #define AWCC_METHOD_READ_GPIO_STATUS 0x22 44 #define AWCC_METHOD_GAME_SHIFT_STATUS 0x25 45 46 #define AWCC_FAILURE_CODE 0xFFFFFFFF 47 #define AWCC_FAILURE_CODE_2 0xFFFFFFFE 48 49 #define AWCC_SENSOR_ID_FLAG BIT(8) 50 #define AWCC_THERMAL_MODE_MASK GENMASK(3, 0) 51 #define AWCC_THERMAL_TABLE_MASK GENMASK(7, 4) 52 #define AWCC_RESOURCE_ID_MASK GENMASK(7, 0) 53 54 /* Arbitrary limit based on supported models */ 55 #define AWCC_MAX_RES_COUNT 16 56 #define AWCC_ID_BITMAP_SIZE (U8_MAX + 1) 57 #define AWCC_ID_BITMAP_LONGS BITS_TO_LONGS(AWCC_ID_BITMAP_SIZE) 58 59 static bool force_hwmon; 60 module_param_unsafe(force_hwmon, bool, 0); 61 MODULE_PARM_DESC(force_hwmon, "Force probing for HWMON support without checking if the WMI backend is available"); 62 63 static bool force_platform_profile; 64 module_param_unsafe(force_platform_profile, bool, 0); 65 MODULE_PARM_DESC(force_platform_profile, "Forces auto-detecting thermal profiles without checking if WMI thermal backend is available"); 66 67 static bool force_gmode; 68 module_param_unsafe(force_gmode, bool, 0); 69 MODULE_PARM_DESC(force_gmode, "Forces G-Mode when performance profile is selected"); 70 71 struct awcc_quirks { 72 bool hwmon; 73 bool pprof; 74 bool gmode; 75 }; 76 77 static struct awcc_quirks g_series_quirks = { 78 .hwmon = true, 79 .pprof = true, 80 .gmode = true, 81 }; 82 83 static struct awcc_quirks generic_quirks = { 84 .hwmon = true, 85 .pprof = true, 86 .gmode = false, 87 }; 88 89 static struct awcc_quirks empty_quirks; 90 91 static const struct dmi_system_id awcc_dmi_table[] __initconst = { 92 { 93 .ident = "Alienware Area-51m R2", 94 .matches = { 95 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), 96 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware Area-51m R2"), 97 }, 98 .driver_data = &generic_quirks, 99 }, 100 { 101 .ident = "Alienware m15 R7", 102 .matches = { 103 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), 104 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m15 R7"), 105 }, 106 .driver_data = &generic_quirks, 107 }, 108 { 109 .ident = "Alienware m16 R1", 110 .matches = { 111 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), 112 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R1"), 113 }, 114 .driver_data = &g_series_quirks, 115 }, 116 { 117 .ident = "Alienware m16 R1 AMD", 118 .matches = { 119 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), 120 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R1 AMD"), 121 }, 122 .driver_data = &generic_quirks, 123 }, 124 { 125 .ident = "Alienware m16 R2", 126 .matches = { 127 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), 128 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R2"), 129 }, 130 .driver_data = &generic_quirks, 131 }, 132 { 133 .ident = "Alienware m17 R5", 134 .matches = { 135 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), 136 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"), 137 }, 138 .driver_data = &generic_quirks, 139 }, 140 { 141 .ident = "Alienware m18 R2", 142 .matches = { 143 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), 144 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18 R2"), 145 }, 146 .driver_data = &generic_quirks, 147 }, 148 { 149 .ident = "Alienware x15 R1", 150 .matches = { 151 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), 152 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R1"), 153 }, 154 .driver_data = &generic_quirks, 155 }, 156 { 157 .ident = "Alienware x15 R2", 158 .matches = { 159 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), 160 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R2"), 161 }, 162 .driver_data = &generic_quirks, 163 }, 164 { 165 .ident = "Alienware x17 R2", 166 .matches = { 167 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), 168 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17 R2"), 169 }, 170 .driver_data = &generic_quirks, 171 }, 172 { 173 .ident = "Dell Inc. G15 5510", 174 .matches = { 175 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 176 DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5510"), 177 }, 178 .driver_data = &g_series_quirks, 179 }, 180 { 181 .ident = "Dell Inc. G15 5511", 182 .matches = { 183 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 184 DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5511"), 185 }, 186 .driver_data = &g_series_quirks, 187 }, 188 { 189 .ident = "Dell Inc. G15 5515", 190 .matches = { 191 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 192 DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"), 193 }, 194 .driver_data = &g_series_quirks, 195 }, 196 { 197 .ident = "Dell Inc. G16 7630", 198 .matches = { 199 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 200 DMI_MATCH(DMI_PRODUCT_NAME, "Dell G16 7630"), 201 }, 202 .driver_data = &g_series_quirks, 203 }, 204 { 205 .ident = "Dell Inc. G3 3500", 206 .matches = { 207 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 208 DMI_MATCH(DMI_PRODUCT_NAME, "G3 3500"), 209 }, 210 .driver_data = &g_series_quirks, 211 }, 212 { 213 .ident = "Dell Inc. G3 3590", 214 .matches = { 215 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 216 DMI_MATCH(DMI_PRODUCT_NAME, "G3 3590"), 217 }, 218 .driver_data = &g_series_quirks, 219 }, 220 { 221 .ident = "Dell Inc. G5 5500", 222 .matches = { 223 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 224 DMI_MATCH(DMI_PRODUCT_NAME, "G5 5500"), 225 }, 226 .driver_data = &g_series_quirks, 227 }, 228 { 229 .ident = "Dell Inc. G5 5505", 230 .matches = { 231 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 232 DMI_MATCH(DMI_PRODUCT_NAME, "G5 5505"), 233 }, 234 .driver_data = &g_series_quirks, 235 }, 236 }; 237 238 enum AWCC_GET_FAN_SENSORS_OPERATIONS { 239 AWCC_OP_GET_TOTAL_FAN_TEMPS = 0x01, 240 AWCC_OP_GET_FAN_TEMP_ID = 0x02, 241 }; 242 243 enum AWCC_THERMAL_INFORMATION_OPERATIONS { 244 AWCC_OP_GET_SYSTEM_DESCRIPTION = 0x02, 245 AWCC_OP_GET_RESOURCE_ID = 0x03, 246 AWCC_OP_GET_TEMPERATURE = 0x04, 247 AWCC_OP_GET_FAN_RPM = 0x05, 248 AWCC_OP_GET_FAN_MIN_RPM = 0x08, 249 AWCC_OP_GET_FAN_MAX_RPM = 0x09, 250 AWCC_OP_GET_CURRENT_PROFILE = 0x0B, 251 AWCC_OP_GET_FAN_BOOST = 0x0C, 252 }; 253 254 enum AWCC_THERMAL_CONTROL_OPERATIONS { 255 AWCC_OP_ACTIVATE_PROFILE = 0x01, 256 AWCC_OP_SET_FAN_BOOST = 0x02, 257 }; 258 259 enum AWCC_GAME_SHIFT_STATUS_OPERATIONS { 260 AWCC_OP_TOGGLE_GAME_SHIFT = 0x01, 261 AWCC_OP_GET_GAME_SHIFT_STATUS = 0x02, 262 }; 263 264 enum AWCC_THERMAL_TABLES { 265 AWCC_THERMAL_TABLE_LEGACY = 0x9, 266 AWCC_THERMAL_TABLE_USTT = 0xA, 267 }; 268 269 enum AWCC_SPECIAL_THERMAL_CODES { 270 AWCC_SPECIAL_PROFILE_CUSTOM = 0x00, 271 AWCC_SPECIAL_PROFILE_GMODE = 0xAB, 272 }; 273 274 enum AWCC_TEMP_SENSOR_TYPES { 275 AWCC_TEMP_SENSOR_CPU = 0x01, 276 AWCC_TEMP_SENSOR_GPU = 0x06, 277 }; 278 279 enum awcc_thermal_profile { 280 AWCC_PROFILE_USTT_BALANCED, 281 AWCC_PROFILE_USTT_BALANCED_PERFORMANCE, 282 AWCC_PROFILE_USTT_COOL, 283 AWCC_PROFILE_USTT_QUIET, 284 AWCC_PROFILE_USTT_PERFORMANCE, 285 AWCC_PROFILE_USTT_LOW_POWER, 286 AWCC_PROFILE_LEGACY_QUIET, 287 AWCC_PROFILE_LEGACY_BALANCED, 288 AWCC_PROFILE_LEGACY_BALANCED_PERFORMANCE, 289 AWCC_PROFILE_LEGACY_PERFORMANCE, 290 AWCC_PROFILE_LAST, 291 }; 292 293 struct wmax_led_args { 294 u32 led_mask; 295 struct color_platform colors; 296 u8 state; 297 } __packed; 298 299 struct wmax_brightness_args { 300 u32 led_mask; 301 u32 percentage; 302 }; 303 304 struct wmax_basic_args { 305 u8 arg; 306 }; 307 308 struct wmax_u32_args { 309 u8 operation; 310 u8 arg1; 311 u8 arg2; 312 u8 arg3; 313 }; 314 315 struct awcc_fan_data { 316 unsigned long auto_channels_temp; 317 const char *label; 318 u32 min_rpm; 319 u32 max_rpm; 320 u8 suspend_cache; 321 u8 id; 322 }; 323 324 struct awcc_priv { 325 struct wmi_device *wdev; 326 union { 327 u32 system_description; 328 struct { 329 u8 fan_count; 330 u8 temp_count; 331 u8 unknown_count; 332 u8 profile_count; 333 }; 334 u8 res_count[4]; 335 }; 336 337 struct device *ppdev; 338 u8 supported_profiles[PLATFORM_PROFILE_LAST]; 339 340 struct device *hwdev; 341 struct awcc_fan_data **fan_data; 342 unsigned long temp_sensors[AWCC_ID_BITMAP_LONGS]; 343 344 u32 gpio_count; 345 }; 346 347 static const enum platform_profile_option awcc_mode_to_platform_profile[AWCC_PROFILE_LAST] = { 348 [AWCC_PROFILE_USTT_BALANCED] = PLATFORM_PROFILE_BALANCED, 349 [AWCC_PROFILE_USTT_BALANCED_PERFORMANCE] = PLATFORM_PROFILE_BALANCED_PERFORMANCE, 350 [AWCC_PROFILE_USTT_COOL] = PLATFORM_PROFILE_COOL, 351 [AWCC_PROFILE_USTT_QUIET] = PLATFORM_PROFILE_QUIET, 352 [AWCC_PROFILE_USTT_PERFORMANCE] = PLATFORM_PROFILE_PERFORMANCE, 353 [AWCC_PROFILE_USTT_LOW_POWER] = PLATFORM_PROFILE_LOW_POWER, 354 [AWCC_PROFILE_LEGACY_QUIET] = PLATFORM_PROFILE_QUIET, 355 [AWCC_PROFILE_LEGACY_BALANCED] = PLATFORM_PROFILE_BALANCED, 356 [AWCC_PROFILE_LEGACY_BALANCED_PERFORMANCE] = PLATFORM_PROFILE_BALANCED_PERFORMANCE, 357 [AWCC_PROFILE_LEGACY_PERFORMANCE] = PLATFORM_PROFILE_PERFORMANCE, 358 }; 359 360 static struct awcc_quirks *awcc; 361 362 /* 363 * The HDMI mux sysfs node indicates the status of the HDMI input mux. 364 * It can toggle between standard system GPU output and HDMI input. 365 */ 366 static ssize_t cable_show(struct device *dev, struct device_attribute *attr, 367 char *buf) 368 { 369 struct alienfx_platdata *pdata = dev_get_platdata(dev); 370 struct wmax_basic_args in_args = { 371 .arg = 0, 372 }; 373 u32 out_data; 374 int ret; 375 376 ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_HDMI_CABLE, 377 &in_args, sizeof(in_args), &out_data); 378 if (!ret) { 379 if (out_data == 0) 380 return sysfs_emit(buf, "[unconnected] connected unknown\n"); 381 else if (out_data == 1) 382 return sysfs_emit(buf, "unconnected [connected] unknown\n"); 383 } 384 385 pr_err("alienware-wmi: unknown HDMI cable status: %d\n", ret); 386 return sysfs_emit(buf, "unconnected connected [unknown]\n"); 387 } 388 389 static ssize_t source_show(struct device *dev, struct device_attribute *attr, 390 char *buf) 391 { 392 struct alienfx_platdata *pdata = dev_get_platdata(dev); 393 struct wmax_basic_args in_args = { 394 .arg = 0, 395 }; 396 u32 out_data; 397 int ret; 398 399 ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_HDMI_STATUS, 400 &in_args, sizeof(in_args), &out_data); 401 if (!ret) { 402 if (out_data == 1) 403 return sysfs_emit(buf, "[input] gpu unknown\n"); 404 else if (out_data == 2) 405 return sysfs_emit(buf, "input [gpu] unknown\n"); 406 } 407 408 pr_err("alienware-wmi: unknown HDMI source status: %u\n", ret); 409 return sysfs_emit(buf, "input gpu [unknown]\n"); 410 } 411 412 static ssize_t source_store(struct device *dev, struct device_attribute *attr, 413 const char *buf, size_t count) 414 { 415 struct alienfx_platdata *pdata = dev_get_platdata(dev); 416 struct wmax_basic_args args; 417 int ret; 418 419 if (strcmp(buf, "gpu\n") == 0) 420 args.arg = 1; 421 else if (strcmp(buf, "input\n") == 0) 422 args.arg = 2; 423 else 424 args.arg = 3; 425 pr_debug("alienware-wmi: setting hdmi to %d : %s", args.arg, buf); 426 427 ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_HDMI_SOURCE, &args, 428 sizeof(args), NULL); 429 if (ret < 0) 430 pr_err("alienware-wmi: HDMI toggle failed: results: %u\n", ret); 431 432 return count; 433 } 434 435 static DEVICE_ATTR_RO(cable); 436 static DEVICE_ATTR_RW(source); 437 438 static bool hdmi_group_visible(struct kobject *kobj) 439 { 440 return alienware_interface == WMAX && alienfx->hdmi_mux; 441 } 442 DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(hdmi); 443 444 static struct attribute *hdmi_attrs[] = { 445 &dev_attr_cable.attr, 446 &dev_attr_source.attr, 447 NULL, 448 }; 449 450 const struct attribute_group wmax_hdmi_attribute_group = { 451 .name = "hdmi", 452 .is_visible = SYSFS_GROUP_VISIBLE(hdmi), 453 .attrs = hdmi_attrs, 454 }; 455 456 /* 457 * Alienware GFX amplifier support 458 * - Currently supports reading cable status 459 * - Leaving expansion room to possibly support dock/undock events later 460 */ 461 static ssize_t status_show(struct device *dev, struct device_attribute *attr, 462 char *buf) 463 { 464 struct alienfx_platdata *pdata = dev_get_platdata(dev); 465 struct wmax_basic_args in_args = { 466 .arg = 0, 467 }; 468 u32 out_data; 469 int ret; 470 471 ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_AMPLIFIER_CABLE, 472 &in_args, sizeof(in_args), &out_data); 473 if (!ret) { 474 if (out_data == 0) 475 return sysfs_emit(buf, "[unconnected] connected unknown\n"); 476 else if (out_data == 1) 477 return sysfs_emit(buf, "unconnected [connected] unknown\n"); 478 } 479 480 pr_err("alienware-wmi: unknown amplifier cable status: %d\n", ret); 481 return sysfs_emit(buf, "unconnected connected [unknown]\n"); 482 } 483 484 static DEVICE_ATTR_RO(status); 485 486 static bool amplifier_group_visible(struct kobject *kobj) 487 { 488 return alienware_interface == WMAX && alienfx->amplifier; 489 } 490 DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(amplifier); 491 492 static struct attribute *amplifier_attrs[] = { 493 &dev_attr_status.attr, 494 NULL, 495 }; 496 497 const struct attribute_group wmax_amplifier_attribute_group = { 498 .name = "amplifier", 499 .is_visible = SYSFS_GROUP_VISIBLE(amplifier), 500 .attrs = amplifier_attrs, 501 }; 502 503 /* 504 * Deep Sleep Control support 505 * - Modifies BIOS setting for deep sleep control allowing extra wakeup events 506 */ 507 static ssize_t deepsleep_show(struct device *dev, struct device_attribute *attr, 508 char *buf) 509 { 510 struct alienfx_platdata *pdata = dev_get_platdata(dev); 511 struct wmax_basic_args in_args = { 512 .arg = 0, 513 }; 514 u32 out_data; 515 int ret; 516 517 ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_DEEP_SLEEP_STATUS, 518 &in_args, sizeof(in_args), &out_data); 519 if (!ret) { 520 if (out_data == 0) 521 return sysfs_emit(buf, "[disabled] s5 s5_s4\n"); 522 else if (out_data == 1) 523 return sysfs_emit(buf, "disabled [s5] s5_s4\n"); 524 else if (out_data == 2) 525 return sysfs_emit(buf, "disabled s5 [s5_s4]\n"); 526 } 527 528 pr_err("alienware-wmi: unknown deep sleep status: %d\n", ret); 529 return sysfs_emit(buf, "disabled s5 s5_s4 [unknown]\n"); 530 } 531 532 static ssize_t deepsleep_store(struct device *dev, struct device_attribute *attr, 533 const char *buf, size_t count) 534 { 535 struct alienfx_platdata *pdata = dev_get_platdata(dev); 536 struct wmax_basic_args args; 537 int ret; 538 539 if (strcmp(buf, "disabled\n") == 0) 540 args.arg = 0; 541 else if (strcmp(buf, "s5\n") == 0) 542 args.arg = 1; 543 else 544 args.arg = 2; 545 pr_debug("alienware-wmi: setting deep sleep to %d : %s", args.arg, buf); 546 547 ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_DEEP_SLEEP_CONTROL, 548 &args, sizeof(args), NULL); 549 if (!ret) 550 pr_err("alienware-wmi: deep sleep control failed: results: %u\n", ret); 551 552 return count; 553 } 554 555 static DEVICE_ATTR_RW(deepsleep); 556 557 static bool deepsleep_group_visible(struct kobject *kobj) 558 { 559 return alienware_interface == WMAX && alienfx->deepslp; 560 } 561 DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(deepsleep); 562 563 static struct attribute *deepsleep_attrs[] = { 564 &dev_attr_deepsleep.attr, 565 NULL, 566 }; 567 568 const struct attribute_group wmax_deepsleep_attribute_group = { 569 .name = "deepsleep", 570 .is_visible = SYSFS_GROUP_VISIBLE(deepsleep), 571 .attrs = deepsleep_attrs, 572 }; 573 574 /* 575 * AWCC Helpers 576 */ 577 static bool is_awcc_thermal_profile_id(u8 code) 578 { 579 u8 table = FIELD_GET(AWCC_THERMAL_TABLE_MASK, code); 580 u8 mode = FIELD_GET(AWCC_THERMAL_MODE_MASK, code); 581 582 if (mode >= AWCC_PROFILE_LAST) 583 return false; 584 585 if (table == AWCC_THERMAL_TABLE_LEGACY && mode >= AWCC_PROFILE_LEGACY_QUIET) 586 return true; 587 588 if (table == AWCC_THERMAL_TABLE_USTT && mode <= AWCC_PROFILE_USTT_LOW_POWER) 589 return true; 590 591 return false; 592 } 593 594 static int awcc_wmi_command(struct wmi_device *wdev, u32 method_id, 595 struct wmax_u32_args *args, u32 *out) 596 { 597 int ret; 598 599 ret = alienware_wmi_command(wdev, method_id, args, sizeof(*args), out); 600 if (ret) 601 return ret; 602 603 if (*out == AWCC_FAILURE_CODE || *out == AWCC_FAILURE_CODE_2) 604 return -EBADRQC; 605 606 return 0; 607 } 608 609 static int awcc_get_fan_sensors(struct wmi_device *wdev, u8 operation, 610 u8 fan_id, u8 index, u32 *out) 611 { 612 struct wmax_u32_args args = { 613 .operation = operation, 614 .arg1 = fan_id, 615 .arg2 = index, 616 .arg3 = 0, 617 }; 618 619 return awcc_wmi_command(wdev, AWCC_METHOD_GET_FAN_SENSORS, &args, out); 620 } 621 622 static int awcc_thermal_information(struct wmi_device *wdev, u8 operation, u8 arg, 623 u32 *out) 624 { 625 struct wmax_u32_args args = { 626 .operation = operation, 627 .arg1 = arg, 628 .arg2 = 0, 629 .arg3 = 0, 630 }; 631 632 return awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, out); 633 } 634 635 static int awcc_fwup_gpio_control(struct wmi_device *wdev, u8 pin, u8 status) 636 { 637 struct wmax_u32_args args = { 638 .operation = pin, 639 .arg1 = status, 640 .arg2 = 0, 641 .arg3 = 0, 642 }; 643 u32 out; 644 645 return awcc_wmi_command(wdev, AWCC_METHOD_FWUP_GPIO_CONTROL, &args, &out); 646 } 647 648 static int awcc_read_total_gpios(struct wmi_device *wdev, u32 *count) 649 { 650 struct wmax_u32_args args = {}; 651 652 return awcc_wmi_command(wdev, AWCC_METHOD_READ_TOTAL_GPIOS, &args, count); 653 } 654 655 static int awcc_read_gpio_status(struct wmi_device *wdev, u8 pin, u32 *status) 656 { 657 struct wmax_u32_args args = { 658 .operation = pin, 659 .arg1 = 0, 660 .arg2 = 0, 661 .arg3 = 0, 662 }; 663 664 return awcc_wmi_command(wdev, AWCC_METHOD_READ_GPIO_STATUS, &args, status); 665 } 666 667 static int awcc_game_shift_status(struct wmi_device *wdev, u8 operation, 668 u32 *out) 669 { 670 struct wmax_u32_args args = { 671 .operation = operation, 672 .arg1 = 0, 673 .arg2 = 0, 674 .arg3 = 0, 675 }; 676 677 return awcc_wmi_command(wdev, AWCC_METHOD_GAME_SHIFT_STATUS, &args, out); 678 } 679 680 /** 681 * awcc_op_get_resource_id - Get the resource ID at a given index 682 * @wdev: AWCC WMI device 683 * @index: Index 684 * @out: Value returned by the WMI call 685 * 686 * Get the resource ID at a given @index. Resource IDs are listed in the 687 * following order: 688 * 689 * - Fan IDs 690 * - Sensor IDs 691 * - Unknown IDs 692 * - Thermal Profile IDs 693 * 694 * The total number of IDs of a given type can be obtained with 695 * AWCC_OP_GET_SYSTEM_DESCRIPTION. 696 * 697 * Return: 0 on success, -errno on failure 698 */ 699 static int awcc_op_get_resource_id(struct wmi_device *wdev, u8 index, u8 *out) 700 { 701 struct wmax_u32_args args = { 702 .operation = AWCC_OP_GET_RESOURCE_ID, 703 .arg1 = index, 704 .arg2 = 0, 705 .arg3 = 0, 706 }; 707 u32 out_data; 708 int ret; 709 710 ret = awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, &out_data); 711 if (ret) 712 return ret; 713 714 *out = FIELD_GET(AWCC_RESOURCE_ID_MASK, out_data); 715 716 return 0; 717 } 718 719 static int awcc_op_get_fan_rpm(struct wmi_device *wdev, u8 fan_id, u32 *out) 720 { 721 struct wmax_u32_args args = { 722 .operation = AWCC_OP_GET_FAN_RPM, 723 .arg1 = fan_id, 724 .arg2 = 0, 725 .arg3 = 0, 726 }; 727 728 return awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, out); 729 } 730 731 static int awcc_op_get_temperature(struct wmi_device *wdev, u8 temp_id, u32 *out) 732 { 733 struct wmax_u32_args args = { 734 .operation = AWCC_OP_GET_TEMPERATURE, 735 .arg1 = temp_id, 736 .arg2 = 0, 737 .arg3 = 0, 738 }; 739 740 return awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, out); 741 } 742 743 static int awcc_op_get_fan_boost(struct wmi_device *wdev, u8 fan_id, u32 *out) 744 { 745 struct wmax_u32_args args = { 746 .operation = AWCC_OP_GET_FAN_BOOST, 747 .arg1 = fan_id, 748 .arg2 = 0, 749 .arg3 = 0, 750 }; 751 752 return awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, out); 753 } 754 755 static int awcc_op_get_current_profile(struct wmi_device *wdev, u32 *out) 756 { 757 struct wmax_u32_args args = { 758 .operation = AWCC_OP_GET_CURRENT_PROFILE, 759 .arg1 = 0, 760 .arg2 = 0, 761 .arg3 = 0, 762 }; 763 764 return awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, out); 765 } 766 767 static int awcc_op_activate_profile(struct wmi_device *wdev, u8 profile) 768 { 769 struct wmax_u32_args args = { 770 .operation = AWCC_OP_ACTIVATE_PROFILE, 771 .arg1 = profile, 772 .arg2 = 0, 773 .arg3 = 0, 774 }; 775 u32 out; 776 777 return awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_CONTROL, &args, &out); 778 } 779 780 static int awcc_op_set_fan_boost(struct wmi_device *wdev, u8 fan_id, u8 boost) 781 { 782 struct wmax_u32_args args = { 783 .operation = AWCC_OP_SET_FAN_BOOST, 784 .arg1 = fan_id, 785 .arg2 = boost, 786 .arg3 = 0, 787 }; 788 u32 out; 789 790 return awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_CONTROL, &args, &out); 791 } 792 793 /* 794 * HWMON 795 * - Provides temperature and fan speed monitoring as well as manual fan 796 * control 797 */ 798 static umode_t awcc_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_types type, 799 u32 attr, int channel) 800 { 801 const struct awcc_priv *priv = drvdata; 802 unsigned int temp_count; 803 804 switch (type) { 805 case hwmon_temp: 806 temp_count = bitmap_weight(priv->temp_sensors, AWCC_ID_BITMAP_SIZE); 807 808 return channel < temp_count ? 0444 : 0; 809 case hwmon_fan: 810 return channel < priv->fan_count ? 0444 : 0; 811 case hwmon_pwm: 812 return channel < priv->fan_count ? 0444 : 0; 813 default: 814 return 0; 815 } 816 } 817 818 static int awcc_hwmon_read(struct device *dev, enum hwmon_sensor_types type, 819 u32 attr, int channel, long *val) 820 { 821 struct awcc_priv *priv = dev_get_drvdata(dev); 822 const struct awcc_fan_data *fan; 823 u32 state; 824 int ret; 825 u8 temp; 826 827 switch (type) { 828 case hwmon_temp: 829 temp = find_nth_bit(priv->temp_sensors, AWCC_ID_BITMAP_SIZE, channel); 830 831 switch (attr) { 832 case hwmon_temp_input: 833 ret = awcc_op_get_temperature(priv->wdev, temp, &state); 834 if (ret) 835 return ret; 836 837 *val = state * MILLIDEGREE_PER_DEGREE; 838 break; 839 default: 840 return -EOPNOTSUPP; 841 } 842 843 break; 844 case hwmon_fan: 845 fan = priv->fan_data[channel]; 846 847 switch (attr) { 848 case hwmon_fan_input: 849 ret = awcc_op_get_fan_rpm(priv->wdev, fan->id, &state); 850 if (ret) 851 return ret; 852 853 *val = state; 854 break; 855 case hwmon_fan_min: 856 *val = fan->min_rpm; 857 break; 858 case hwmon_fan_max: 859 *val = fan->max_rpm; 860 break; 861 default: 862 return -EOPNOTSUPP; 863 } 864 865 break; 866 case hwmon_pwm: 867 fan = priv->fan_data[channel]; 868 869 switch (attr) { 870 case hwmon_pwm_auto_channels_temp: 871 *val = fan->auto_channels_temp; 872 break; 873 default: 874 return -EOPNOTSUPP; 875 } 876 877 break; 878 default: 879 return -EOPNOTSUPP; 880 } 881 882 return 0; 883 } 884 885 static int awcc_hwmon_read_string(struct device *dev, enum hwmon_sensor_types type, 886 u32 attr, int channel, const char **str) 887 { 888 struct awcc_priv *priv = dev_get_drvdata(dev); 889 u8 temp; 890 891 switch (type) { 892 case hwmon_temp: 893 temp = find_nth_bit(priv->temp_sensors, AWCC_ID_BITMAP_SIZE, channel); 894 895 switch (temp) { 896 case AWCC_TEMP_SENSOR_CPU: 897 *str = "CPU"; 898 break; 899 case AWCC_TEMP_SENSOR_GPU: 900 *str = "GPU"; 901 break; 902 default: 903 *str = "Unknown"; 904 break; 905 } 906 907 break; 908 case hwmon_fan: 909 *str = priv->fan_data[channel]->label; 910 break; 911 default: 912 return -EOPNOTSUPP; 913 } 914 915 return 0; 916 } 917 918 static const struct hwmon_ops awcc_hwmon_ops = { 919 .is_visible = awcc_hwmon_is_visible, 920 .read = awcc_hwmon_read, 921 .read_string = awcc_hwmon_read_string, 922 }; 923 924 static const struct hwmon_channel_info * const awcc_hwmon_info[] = { 925 HWMON_CHANNEL_INFO(temp, 926 HWMON_T_LABEL | HWMON_T_INPUT, 927 HWMON_T_LABEL | HWMON_T_INPUT, 928 HWMON_T_LABEL | HWMON_T_INPUT, 929 HWMON_T_LABEL | HWMON_T_INPUT, 930 HWMON_T_LABEL | HWMON_T_INPUT, 931 HWMON_T_LABEL | HWMON_T_INPUT 932 ), 933 HWMON_CHANNEL_INFO(fan, 934 HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX, 935 HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX, 936 HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX, 937 HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX, 938 HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX, 939 HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX 940 ), 941 HWMON_CHANNEL_INFO(pwm, 942 HWMON_PWM_AUTO_CHANNELS_TEMP, 943 HWMON_PWM_AUTO_CHANNELS_TEMP, 944 HWMON_PWM_AUTO_CHANNELS_TEMP, 945 HWMON_PWM_AUTO_CHANNELS_TEMP, 946 HWMON_PWM_AUTO_CHANNELS_TEMP, 947 HWMON_PWM_AUTO_CHANNELS_TEMP 948 ), 949 NULL 950 }; 951 952 static const struct hwmon_chip_info awcc_hwmon_chip_info = { 953 .ops = &awcc_hwmon_ops, 954 .info = awcc_hwmon_info, 955 }; 956 957 static ssize_t fan_boost_show(struct device *dev, struct device_attribute *attr, 958 char *buf) 959 { 960 struct awcc_priv *priv = dev_get_drvdata(dev); 961 int index = to_sensor_dev_attr(attr)->index; 962 struct awcc_fan_data *fan = priv->fan_data[index]; 963 u32 boost; 964 int ret; 965 966 ret = awcc_op_get_fan_boost(priv->wdev, fan->id, &boost); 967 if (ret) 968 return ret; 969 970 return sysfs_emit(buf, "%u\n", boost); 971 } 972 973 static ssize_t fan_boost_store(struct device *dev, struct device_attribute *attr, 974 const char *buf, size_t count) 975 { 976 struct awcc_priv *priv = dev_get_drvdata(dev); 977 int index = to_sensor_dev_attr(attr)->index; 978 struct awcc_fan_data *fan = priv->fan_data[index]; 979 unsigned long val; 980 int ret; 981 982 ret = kstrtoul(buf, 0, &val); 983 if (ret) 984 return ret; 985 986 ret = awcc_op_set_fan_boost(priv->wdev, fan->id, clamp_val(val, 0, 255)); 987 988 return ret ? ret : count; 989 } 990 991 static SENSOR_DEVICE_ATTR_RW(fan1_boost, fan_boost, 0); 992 static SENSOR_DEVICE_ATTR_RW(fan2_boost, fan_boost, 1); 993 static SENSOR_DEVICE_ATTR_RW(fan3_boost, fan_boost, 2); 994 static SENSOR_DEVICE_ATTR_RW(fan4_boost, fan_boost, 3); 995 static SENSOR_DEVICE_ATTR_RW(fan5_boost, fan_boost, 4); 996 static SENSOR_DEVICE_ATTR_RW(fan6_boost, fan_boost, 5); 997 998 static umode_t fan_boost_attr_visible(struct kobject *kobj, struct attribute *attr, int n) 999 { 1000 struct awcc_priv *priv = dev_get_drvdata(kobj_to_dev(kobj)); 1001 1002 return n < priv->fan_count ? attr->mode : 0; 1003 } 1004 1005 static bool fan_boost_group_visible(struct kobject *kobj) 1006 { 1007 return true; 1008 } 1009 1010 DEFINE_SYSFS_GROUP_VISIBLE(fan_boost); 1011 1012 static struct attribute *fan_boost_attrs[] = { 1013 &sensor_dev_attr_fan1_boost.dev_attr.attr, 1014 &sensor_dev_attr_fan2_boost.dev_attr.attr, 1015 &sensor_dev_attr_fan3_boost.dev_attr.attr, 1016 &sensor_dev_attr_fan4_boost.dev_attr.attr, 1017 &sensor_dev_attr_fan5_boost.dev_attr.attr, 1018 &sensor_dev_attr_fan6_boost.dev_attr.attr, 1019 NULL 1020 }; 1021 1022 static const struct attribute_group fan_boost_group = { 1023 .attrs = fan_boost_attrs, 1024 .is_visible = SYSFS_GROUP_VISIBLE(fan_boost), 1025 }; 1026 1027 static const struct attribute_group *awcc_hwmon_groups[] = { 1028 &fan_boost_group, 1029 NULL 1030 }; 1031 1032 static int awcc_hwmon_temps_init(struct wmi_device *wdev) 1033 { 1034 struct awcc_priv *priv = dev_get_drvdata(&wdev->dev); 1035 unsigned int i; 1036 int ret; 1037 u8 id; 1038 1039 for (i = 0; i < priv->temp_count; i++) { 1040 /* 1041 * Temperature sensors IDs are listed after the fan IDs at 1042 * offset `fan_count` 1043 */ 1044 ret = awcc_op_get_resource_id(wdev, i + priv->fan_count, &id); 1045 if (ret) 1046 return ret; 1047 1048 __set_bit(id, priv->temp_sensors); 1049 } 1050 1051 return 0; 1052 } 1053 1054 static char *awcc_get_fan_label(unsigned long *fan_temps) 1055 { 1056 unsigned int temp_count = bitmap_weight(fan_temps, AWCC_ID_BITMAP_SIZE); 1057 char *label; 1058 u8 temp_id; 1059 1060 switch (temp_count) { 1061 case 0: 1062 label = "Independent Fan"; 1063 break; 1064 case 1: 1065 temp_id = find_first_bit(fan_temps, AWCC_ID_BITMAP_SIZE); 1066 1067 switch (temp_id) { 1068 case AWCC_TEMP_SENSOR_CPU: 1069 label = "Processor Fan"; 1070 break; 1071 case AWCC_TEMP_SENSOR_GPU: 1072 label = "Video Fan"; 1073 break; 1074 default: 1075 label = "Unknown Fan"; 1076 break; 1077 } 1078 1079 break; 1080 default: 1081 label = "Shared Fan"; 1082 break; 1083 } 1084 1085 return label; 1086 } 1087 1088 static int awcc_hwmon_fans_init(struct wmi_device *wdev) 1089 { 1090 struct awcc_priv *priv = dev_get_drvdata(&wdev->dev); 1091 unsigned long fan_temps[AWCC_ID_BITMAP_LONGS]; 1092 unsigned long gather[AWCC_ID_BITMAP_LONGS]; 1093 u32 min_rpm, max_rpm, temp_count, temp_id; 1094 struct awcc_fan_data *fan_data; 1095 unsigned int i, j; 1096 int ret; 1097 u8 id; 1098 1099 for (i = 0; i < priv->fan_count; i++) { 1100 fan_data = devm_kzalloc(&wdev->dev, sizeof(*fan_data), GFP_KERNEL); 1101 if (!fan_data) 1102 return -ENOMEM; 1103 1104 /* 1105 * Fan IDs are listed first at offset 0 1106 */ 1107 ret = awcc_op_get_resource_id(wdev, i, &id); 1108 if (ret) 1109 return ret; 1110 1111 ret = awcc_thermal_information(wdev, AWCC_OP_GET_FAN_MIN_RPM, id, 1112 &min_rpm); 1113 if (ret) 1114 return ret; 1115 1116 ret = awcc_thermal_information(wdev, AWCC_OP_GET_FAN_MAX_RPM, id, 1117 &max_rpm); 1118 if (ret) 1119 return ret; 1120 1121 ret = awcc_get_fan_sensors(wdev, AWCC_OP_GET_TOTAL_FAN_TEMPS, id, 1122 0, &temp_count); 1123 if (ret) 1124 return ret; 1125 1126 bitmap_zero(fan_temps, AWCC_ID_BITMAP_SIZE); 1127 1128 for (j = 0; j < temp_count; j++) { 1129 ret = awcc_get_fan_sensors(wdev, AWCC_OP_GET_FAN_TEMP_ID, 1130 id, j, &temp_id); 1131 if (ret) 1132 break; 1133 1134 temp_id = FIELD_GET(AWCC_RESOURCE_ID_MASK, temp_id); 1135 __set_bit(temp_id, fan_temps); 1136 } 1137 1138 fan_data->id = id; 1139 fan_data->min_rpm = min_rpm; 1140 fan_data->max_rpm = max_rpm; 1141 fan_data->label = awcc_get_fan_label(fan_temps); 1142 bitmap_gather(gather, fan_temps, priv->temp_sensors, AWCC_ID_BITMAP_SIZE); 1143 bitmap_copy(&fan_data->auto_channels_temp, gather, BITS_PER_LONG); 1144 priv->fan_data[i] = fan_data; 1145 } 1146 1147 return 0; 1148 } 1149 1150 static int awcc_hwmon_init(struct wmi_device *wdev) 1151 { 1152 struct awcc_priv *priv = dev_get_drvdata(&wdev->dev); 1153 int ret; 1154 1155 priv->fan_data = devm_kcalloc(&wdev->dev, priv->fan_count, 1156 sizeof(*priv->fan_data), GFP_KERNEL); 1157 if (!priv->fan_data) 1158 return -ENOMEM; 1159 1160 ret = awcc_hwmon_temps_init(wdev); 1161 if (ret) 1162 return ret; 1163 1164 ret = awcc_hwmon_fans_init(wdev); 1165 if (ret) 1166 return ret; 1167 1168 priv->hwdev = devm_hwmon_device_register_with_info(&wdev->dev, "alienware_wmi", 1169 priv, &awcc_hwmon_chip_info, 1170 awcc_hwmon_groups); 1171 1172 return PTR_ERR_OR_ZERO(priv->hwdev); 1173 } 1174 1175 static void awcc_hwmon_suspend(struct device *dev) 1176 { 1177 struct awcc_priv *priv = dev_get_drvdata(dev); 1178 struct awcc_fan_data *fan; 1179 unsigned int i; 1180 u32 boost; 1181 int ret; 1182 1183 for (i = 0; i < priv->fan_count; i++) { 1184 fan = priv->fan_data[i]; 1185 1186 ret = awcc_thermal_information(priv->wdev, AWCC_OP_GET_FAN_BOOST, 1187 fan->id, &boost); 1188 if (ret) 1189 dev_err(dev, "Failed to store Fan %u boost while suspending\n", i); 1190 1191 fan->suspend_cache = ret ? 0 : clamp_val(boost, 0, 255); 1192 1193 awcc_op_set_fan_boost(priv->wdev, fan->id, 0); 1194 if (ret) 1195 dev_err(dev, "Failed to set Fan %u boost to 0 while suspending\n", i); 1196 } 1197 } 1198 1199 static void awcc_hwmon_resume(struct device *dev) 1200 { 1201 struct awcc_priv *priv = dev_get_drvdata(dev); 1202 struct awcc_fan_data *fan; 1203 unsigned int i; 1204 int ret; 1205 1206 for (i = 0; i < priv->fan_count; i++) { 1207 fan = priv->fan_data[i]; 1208 1209 if (!fan->suspend_cache) 1210 continue; 1211 1212 ret = awcc_op_set_fan_boost(priv->wdev, fan->id, fan->suspend_cache); 1213 if (ret) 1214 dev_err(dev, "Failed to restore Fan %u boost while resuming\n", i); 1215 } 1216 } 1217 1218 /* 1219 * Thermal Profile control 1220 * - Provides thermal profile control through the Platform Profile API 1221 */ 1222 static int awcc_platform_profile_get(struct device *dev, 1223 enum platform_profile_option *profile) 1224 { 1225 struct awcc_priv *priv = dev_get_drvdata(dev); 1226 u32 out_data; 1227 int ret; 1228 1229 ret = awcc_op_get_current_profile(priv->wdev, &out_data); 1230 if (ret) 1231 return ret; 1232 1233 switch (out_data) { 1234 case AWCC_SPECIAL_PROFILE_CUSTOM: 1235 *profile = PLATFORM_PROFILE_CUSTOM; 1236 return 0; 1237 case AWCC_SPECIAL_PROFILE_GMODE: 1238 *profile = PLATFORM_PROFILE_PERFORMANCE; 1239 return 0; 1240 default: 1241 break; 1242 } 1243 1244 if (!is_awcc_thermal_profile_id(out_data)) 1245 return -ENODATA; 1246 1247 out_data = FIELD_GET(AWCC_THERMAL_MODE_MASK, out_data); 1248 *profile = awcc_mode_to_platform_profile[out_data]; 1249 1250 return 0; 1251 } 1252 1253 static int awcc_platform_profile_set(struct device *dev, 1254 enum platform_profile_option profile) 1255 { 1256 struct awcc_priv *priv = dev_get_drvdata(dev); 1257 1258 if (awcc->gmode) { 1259 u32 gmode_status; 1260 int ret; 1261 1262 ret = awcc_game_shift_status(priv->wdev, 1263 AWCC_OP_GET_GAME_SHIFT_STATUS, 1264 &gmode_status); 1265 1266 if (ret < 0) 1267 return ret; 1268 1269 if ((profile == PLATFORM_PROFILE_PERFORMANCE && !gmode_status) || 1270 (profile != PLATFORM_PROFILE_PERFORMANCE && gmode_status)) { 1271 ret = awcc_game_shift_status(priv->wdev, 1272 AWCC_OP_TOGGLE_GAME_SHIFT, 1273 &gmode_status); 1274 1275 if (ret < 0) 1276 return ret; 1277 } 1278 } 1279 1280 return awcc_op_activate_profile(priv->wdev, priv->supported_profiles[profile]); 1281 } 1282 1283 static int awcc_platform_profile_probe(void *drvdata, unsigned long *choices) 1284 { 1285 enum platform_profile_option profile; 1286 struct awcc_priv *priv = drvdata; 1287 enum awcc_thermal_profile mode; 1288 u8 id, offset = 0; 1289 int ret; 1290 1291 /* 1292 * Thermal profile IDs are listed last at offset 1293 * fan_count + temp_count + unknown_count 1294 */ 1295 for (unsigned int i = 0; i < ARRAY_SIZE(priv->res_count) - 1; i++) 1296 offset += priv->res_count[i]; 1297 1298 for (unsigned int i = 0; i < priv->profile_count; i++) { 1299 ret = awcc_op_get_resource_id(priv->wdev, i + offset, &id); 1300 /* 1301 * Some devices report an incorrect number of thermal profiles 1302 * so the resource ID list may end prematurely 1303 */ 1304 if (ret == -EBADRQC) 1305 break; 1306 if (ret) 1307 return ret; 1308 1309 if (!is_awcc_thermal_profile_id(id)) { 1310 dev_dbg(&priv->wdev->dev, "Unmapped thermal profile ID 0x%02x\n", id); 1311 continue; 1312 } 1313 1314 mode = FIELD_GET(AWCC_THERMAL_MODE_MASK, id); 1315 profile = awcc_mode_to_platform_profile[mode]; 1316 priv->supported_profiles[profile] = id; 1317 1318 __set_bit(profile, choices); 1319 } 1320 1321 if (bitmap_empty(choices, PLATFORM_PROFILE_LAST)) 1322 return -ENODEV; 1323 1324 if (awcc->gmode) { 1325 priv->supported_profiles[PLATFORM_PROFILE_PERFORMANCE] = 1326 AWCC_SPECIAL_PROFILE_GMODE; 1327 1328 __set_bit(PLATFORM_PROFILE_PERFORMANCE, choices); 1329 } 1330 1331 /* Every model supports the "custom" profile */ 1332 priv->supported_profiles[PLATFORM_PROFILE_CUSTOM] = 1333 AWCC_SPECIAL_PROFILE_CUSTOM; 1334 1335 __set_bit(PLATFORM_PROFILE_CUSTOM, choices); 1336 1337 return 0; 1338 } 1339 1340 static const struct platform_profile_ops awcc_platform_profile_ops = { 1341 .probe = awcc_platform_profile_probe, 1342 .profile_get = awcc_platform_profile_get, 1343 .profile_set = awcc_platform_profile_set, 1344 }; 1345 1346 static int awcc_platform_profile_init(struct wmi_device *wdev) 1347 { 1348 struct awcc_priv *priv = dev_get_drvdata(&wdev->dev); 1349 1350 priv->ppdev = devm_platform_profile_register(&wdev->dev, "alienware-wmi", 1351 priv, &awcc_platform_profile_ops); 1352 1353 return PTR_ERR_OR_ZERO(priv->ppdev); 1354 } 1355 1356 /* 1357 * DebugFS 1358 */ 1359 static int awcc_debugfs_system_description_read(struct seq_file *seq, void *data) 1360 { 1361 struct device *dev = seq->private; 1362 struct awcc_priv *priv = dev_get_drvdata(dev); 1363 1364 seq_printf(seq, "0x%08x\n", priv->system_description); 1365 1366 return 0; 1367 } 1368 1369 static int awcc_debugfs_hwmon_data_read(struct seq_file *seq, void *data) 1370 { 1371 struct device *dev = seq->private; 1372 struct awcc_priv *priv = dev_get_drvdata(dev); 1373 const struct awcc_fan_data *fan; 1374 unsigned int bit; 1375 1376 seq_printf(seq, "Number of fans: %u\n", priv->fan_count); 1377 seq_printf(seq, "Number of temperature sensors: %u\n\n", priv->temp_count); 1378 1379 for (u32 i = 0; i < priv->fan_count; i++) { 1380 fan = priv->fan_data[i]; 1381 1382 seq_printf(seq, "Fan %u:\n", i); 1383 seq_printf(seq, " ID: 0x%02x\n", fan->id); 1384 seq_printf(seq, " Related temperature sensors bitmap: %lu\n", 1385 fan->auto_channels_temp); 1386 } 1387 1388 seq_puts(seq, "\nTemperature sensor IDs:\n"); 1389 for_each_set_bit(bit, priv->temp_sensors, AWCC_ID_BITMAP_SIZE) 1390 seq_printf(seq, " 0x%02x\n", bit); 1391 1392 return 0; 1393 } 1394 1395 static int awcc_debugfs_pprof_data_read(struct seq_file *seq, void *data) 1396 { 1397 struct device *dev = seq->private; 1398 struct awcc_priv *priv = dev_get_drvdata(dev); 1399 1400 seq_printf(seq, "Number of thermal profiles: %u\n\n", priv->profile_count); 1401 1402 for (u32 i = 0; i < PLATFORM_PROFILE_LAST; i++) { 1403 if (!priv->supported_profiles[i]) 1404 continue; 1405 1406 seq_printf(seq, "Platform profile %u:\n", i); 1407 seq_printf(seq, " ID: 0x%02x\n", priv->supported_profiles[i]); 1408 } 1409 1410 return 0; 1411 } 1412 1413 static int awcc_gpio_pin_show(struct seq_file *seq, void *data) 1414 { 1415 unsigned long pin = debugfs_get_aux_num(seq->file); 1416 struct wmi_device *wdev = seq->private; 1417 u32 status; 1418 int ret; 1419 1420 ret = awcc_read_gpio_status(wdev, pin, &status); 1421 if (ret) 1422 return ret; 1423 1424 seq_printf(seq, "%u\n", status); 1425 1426 return 0; 1427 } 1428 1429 static ssize_t awcc_gpio_pin_write(struct file *file, const char __user *buf, 1430 size_t count, loff_t *ppos) 1431 { 1432 unsigned long pin = debugfs_get_aux_num(file); 1433 struct seq_file *seq = file->private_data; 1434 struct wmi_device *wdev = seq->private; 1435 bool status; 1436 int ret; 1437 1438 if (!ppos || *ppos) 1439 return -EINVAL; 1440 1441 ret = kstrtobool_from_user(buf, count, &status); 1442 if (ret) 1443 return ret; 1444 1445 ret = awcc_fwup_gpio_control(wdev, pin, status); 1446 if (ret) 1447 return ret; 1448 1449 return count; 1450 } 1451 1452 DEFINE_SHOW_STORE_ATTRIBUTE(awcc_gpio_pin); 1453 1454 static void awcc_debugfs_remove(void *data) 1455 { 1456 struct dentry *root = data; 1457 1458 debugfs_remove(root); 1459 } 1460 1461 static void awcc_debugfs_init(struct wmi_device *wdev) 1462 { 1463 struct awcc_priv *priv = dev_get_drvdata(&wdev->dev); 1464 struct dentry *root, *gpio_ctl; 1465 u32 gpio_count; 1466 char name[64]; 1467 int ret; 1468 1469 scnprintf(name, sizeof(name), "%s-%s", "alienware-wmi", dev_name(&wdev->dev)); 1470 root = debugfs_create_dir(name, NULL); 1471 1472 debugfs_create_devm_seqfile(&wdev->dev, "system_description", root, 1473 awcc_debugfs_system_description_read); 1474 1475 if (awcc->hwmon) 1476 debugfs_create_devm_seqfile(&wdev->dev, "hwmon_data", root, 1477 awcc_debugfs_hwmon_data_read); 1478 1479 if (awcc->pprof) 1480 debugfs_create_devm_seqfile(&wdev->dev, "pprof_data", root, 1481 awcc_debugfs_pprof_data_read); 1482 1483 ret = awcc_read_total_gpios(wdev, &gpio_count); 1484 if (ret) { 1485 dev_dbg(&wdev->dev, "Failed to get total GPIO Pin count\n"); 1486 goto out_add_action; 1487 } else if (gpio_count > AWCC_MAX_RES_COUNT) { 1488 dev_dbg(&wdev->dev, "Reported GPIO Pin count may be incorrect: %u\n", gpio_count); 1489 goto out_add_action; 1490 } 1491 1492 gpio_ctl = debugfs_create_dir("gpio_ctl", root); 1493 1494 priv->gpio_count = gpio_count; 1495 debugfs_create_u32("total_gpios", 0444, gpio_ctl, &priv->gpio_count); 1496 1497 for (unsigned int i = 0; i < gpio_count; i++) { 1498 scnprintf(name, sizeof(name), "pin%u", i); 1499 debugfs_create_file_aux_num(name, 0644, gpio_ctl, wdev, i, 1500 &awcc_gpio_pin_fops); 1501 } 1502 1503 out_add_action: 1504 devm_add_action_or_reset(&wdev->dev, awcc_debugfs_remove, root); 1505 } 1506 1507 static int alienware_awcc_setup(struct wmi_device *wdev) 1508 { 1509 struct awcc_priv *priv; 1510 int ret; 1511 1512 priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL); 1513 if (!priv) 1514 return -ENOMEM; 1515 1516 ret = awcc_thermal_information(wdev, AWCC_OP_GET_SYSTEM_DESCRIPTION, 1517 0, &priv->system_description); 1518 if (ret < 0) 1519 return ret; 1520 1521 /* Sanity check */ 1522 for (unsigned int i = 0; i < ARRAY_SIZE(priv->res_count); i++) { 1523 if (priv->res_count[i] > AWCC_MAX_RES_COUNT) { 1524 dev_err(&wdev->dev, "Malformed system description: 0x%08x\n", 1525 priv->system_description); 1526 return -ENXIO; 1527 } 1528 } 1529 1530 priv->wdev = wdev; 1531 dev_set_drvdata(&wdev->dev, priv); 1532 1533 if (awcc->hwmon) { 1534 ret = awcc_hwmon_init(wdev); 1535 if (ret) 1536 return ret; 1537 } 1538 1539 if (awcc->pprof) { 1540 ret = awcc_platform_profile_init(wdev); 1541 if (ret) 1542 return ret; 1543 } 1544 1545 awcc_debugfs_init(wdev); 1546 1547 return 0; 1548 } 1549 1550 /* 1551 * WMAX WMI driver 1552 */ 1553 static int wmax_wmi_update_led(struct alienfx_priv *priv, 1554 struct wmi_device *wdev, u8 location) 1555 { 1556 struct wmax_led_args in_args = { 1557 .led_mask = 1 << location, 1558 .colors = priv->colors[location], 1559 .state = priv->lighting_control_state, 1560 }; 1561 1562 return alienware_wmi_command(wdev, WMAX_METHOD_ZONE_CONTROL, &in_args, 1563 sizeof(in_args), NULL); 1564 } 1565 1566 static int wmax_wmi_update_brightness(struct alienfx_priv *priv, 1567 struct wmi_device *wdev, u8 brightness) 1568 { 1569 struct wmax_brightness_args in_args = { 1570 .led_mask = 0xFF, 1571 .percentage = brightness, 1572 }; 1573 1574 return alienware_wmi_command(wdev, WMAX_METHOD_BRIGHTNESS, &in_args, 1575 sizeof(in_args), NULL); 1576 } 1577 1578 static int wmax_wmi_probe(struct wmi_device *wdev, const void *context) 1579 { 1580 struct alienfx_platdata pdata = { 1581 .wdev = wdev, 1582 .ops = { 1583 .upd_led = wmax_wmi_update_led, 1584 .upd_brightness = wmax_wmi_update_brightness, 1585 }, 1586 }; 1587 int ret; 1588 1589 if (awcc) 1590 ret = alienware_awcc_setup(wdev); 1591 else 1592 ret = alienware_alienfx_setup(&pdata); 1593 1594 return ret; 1595 } 1596 1597 static int wmax_wmi_suspend(struct device *dev) 1598 { 1599 if (awcc->hwmon) 1600 awcc_hwmon_suspend(dev); 1601 1602 return 0; 1603 } 1604 1605 static int wmax_wmi_resume(struct device *dev) 1606 { 1607 if (awcc->hwmon) 1608 awcc_hwmon_resume(dev); 1609 1610 return 0; 1611 } 1612 1613 static DEFINE_SIMPLE_DEV_PM_OPS(wmax_wmi_pm_ops, wmax_wmi_suspend, wmax_wmi_resume); 1614 1615 static const struct wmi_device_id alienware_wmax_device_id_table[] = { 1616 { WMAX_CONTROL_GUID, NULL }, 1617 { }, 1618 }; 1619 MODULE_DEVICE_TABLE(wmi, alienware_wmax_device_id_table); 1620 1621 static struct wmi_driver alienware_wmax_wmi_driver = { 1622 .driver = { 1623 .name = "alienware-wmi-wmax", 1624 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 1625 .pm = pm_sleep_ptr(&wmax_wmi_pm_ops), 1626 }, 1627 .id_table = alienware_wmax_device_id_table, 1628 .probe = wmax_wmi_probe, 1629 .no_singleton = true, 1630 }; 1631 1632 int __init alienware_wmax_wmi_init(void) 1633 { 1634 const struct dmi_system_id *id; 1635 1636 id = dmi_first_match(awcc_dmi_table); 1637 if (id) 1638 awcc = id->driver_data; 1639 1640 if (force_hwmon) { 1641 if (!awcc) 1642 awcc = &empty_quirks; 1643 1644 awcc->hwmon = true; 1645 } 1646 1647 if (force_platform_profile) { 1648 if (!awcc) 1649 awcc = &empty_quirks; 1650 1651 awcc->pprof = true; 1652 } 1653 1654 if (force_gmode) { 1655 if (awcc) 1656 awcc->gmode = true; 1657 else 1658 pr_warn("force_gmode requires platform profile support\n"); 1659 } 1660 1661 return wmi_driver_register(&alienware_wmax_wmi_driver); 1662 } 1663 1664 void __exit alienware_wmax_wmi_exit(void) 1665 { 1666 wmi_driver_unregister(&alienware_wmax_wmi_driver); 1667 } 1668