1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Linux driver for Uniwill notebooks. 4 * 5 * Special thanks go to Pőcze Barnabás, Christoffer Sandberg and Werner Sembach 6 * for supporting the development of this driver either through prior work or 7 * by answering questions regarding the underlying ACPI and WMI interfaces. 8 * 9 * Copyright (C) 2025 Armin Wolf <W_Armin@gmx.de> 10 */ 11 12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 13 14 #include <linux/acpi.h> 15 #include <linux/array_size.h> 16 #include <linux/bits.h> 17 #include <linux/bitfield.h> 18 #include <linux/cleanup.h> 19 #include <linux/debugfs.h> 20 #include <linux/delay.h> 21 #include <linux/device.h> 22 #include <linux/device/driver.h> 23 #include <linux/dmi.h> 24 #include <linux/errno.h> 25 #include <linux/fixp-arith.h> 26 #include <linux/hwmon.h> 27 #include <linux/hwmon-sysfs.h> 28 #include <linux/init.h> 29 #include <linux/input.h> 30 #include <linux/input/sparse-keymap.h> 31 #include <linux/kernel.h> 32 #include <linux/kstrtox.h> 33 #include <linux/leds.h> 34 #include <linux/led-class-multicolor.h> 35 #include <linux/limits.h> 36 #include <linux/list.h> 37 #include <linux/minmax.h> 38 #include <linux/module.h> 39 #include <linux/mutex.h> 40 #include <linux/notifier.h> 41 #include <linux/platform_device.h> 42 #include <linux/pm.h> 43 #include <linux/printk.h> 44 #include <linux/regmap.h> 45 #include <linux/string.h> 46 #include <linux/sysfs.h> 47 #include <linux/types.h> 48 #include <linux/units.h> 49 50 #include <acpi/battery.h> 51 52 #include "uniwill-wmi.h" 53 54 #define EC_ADDR_BAT_POWER_UNIT_1 0x0400 55 56 #define EC_ADDR_BAT_POWER_UNIT_2 0x0401 57 58 #define EC_ADDR_BAT_DESIGN_CAPACITY_1 0x0402 59 60 #define EC_ADDR_BAT_DESIGN_CAPACITY_2 0x0403 61 62 #define EC_ADDR_BAT_FULL_CAPACITY_1 0x0404 63 64 #define EC_ADDR_BAT_FULL_CAPACITY_2 0x0405 65 66 #define EC_ADDR_BAT_DESIGN_VOLTAGE_1 0x0408 67 68 #define EC_ADDR_BAT_DESIGN_VOLTAGE_2 0x0409 69 70 #define EC_ADDR_BAT_STATUS_1 0x0432 71 #define BAT_DISCHARGING BIT(0) 72 73 #define EC_ADDR_BAT_STATUS_2 0x0433 74 75 #define EC_ADDR_BAT_CURRENT_1 0x0434 76 77 #define EC_ADDR_BAT_CURRENT_2 0x0435 78 79 #define EC_ADDR_BAT_REMAIN_CAPACITY_1 0x0436 80 81 #define EC_ADDR_BAT_REMAIN_CAPACITY_2 0x0437 82 83 #define EC_ADDR_BAT_VOLTAGE_1 0x0438 84 85 #define EC_ADDR_BAT_VOLTAGE_2 0x0439 86 87 #define EC_ADDR_CPU_TEMP 0x043E 88 89 #define EC_ADDR_GPU_TEMP 0x044F 90 91 #define EC_ADDR_SYSTEM_ID 0x0456 92 #define HAS_GPU BIT(7) 93 94 #define EC_ADDR_MAIN_FAN_RPM_1 0x0464 95 96 #define EC_ADDR_MAIN_FAN_RPM_2 0x0465 97 98 #define EC_ADDR_SECOND_FAN_RPM_1 0x046C 99 100 #define EC_ADDR_SECOND_FAN_RPM_2 0x046D 101 102 #define EC_ADDR_DEVICE_STATUS 0x047B 103 #define WIFI_STATUS_ON BIT(7) 104 /* BIT(5) is also unset depending on the rfkill state (bluetooth?) */ 105 106 #define EC_ADDR_BAT_ALERT 0x0494 107 108 #define EC_ADDR_BAT_CYCLE_COUNT_1 0x04A6 109 110 #define EC_ADDR_BAT_CYCLE_COUNT_2 0x04A7 111 112 #define EC_ADDR_PROJECT_ID 0x0740 113 #define PROJECT_ID_PH4TRX1 0x12 114 #define PROJECT_ID_PH6TRX1 0x15 115 116 #define EC_ADDR_AP_OEM 0x0741 117 #define ENABLE_MANUAL_CTRL BIT(0) 118 #define ITE_KBD_EFFECT_REACTIVE BIT(3) 119 #define FAN_ABNORMAL BIT(5) 120 121 #define EC_ADDR_SUPPORT_5 0x0742 122 #define FAN_TURBO_SUPPORTED BIT(4) 123 #define FAN_SUPPORT BIT(5) 124 125 #define EC_ADDR_CTGP_DB_CTRL 0x0743 126 #define CTGP_DB_GENERAL_ENABLE BIT(0) 127 #define CTGP_DB_DB_ENABLE BIT(1) 128 #define CTGP_DB_CTGP_ENABLE BIT(2) 129 130 #define EC_ADDR_CTGP_DB_CTGP_OFFSET 0x0744 131 132 #define EC_ADDR_CTGP_DB_TPP_OFFSET 0x0745 133 134 #define EC_ADDR_CTGP_DB_DB_OFFSET 0x0746 135 136 #define EC_ADDR_LIGHTBAR_AC_CTRL 0x0748 137 #define LIGHTBAR_APP_EXISTS BIT(0) 138 #define LIGHTBAR_POWER_SAVE BIT(1) 139 #define LIGHTBAR_S0_OFF BIT(2) 140 #define LIGHTBAR_S3_OFF BIT(3) // Breathing animation when suspended 141 #define LIGHTBAR_WELCOME BIT(7) // Rainbow animation 142 143 #define EC_ADDR_LIGHTBAR_AC_RED 0x0749 144 145 #define EC_ADDR_LIGHTBAR_AC_GREEN 0x074A 146 147 #define EC_ADDR_LIGHTBAR_AC_BLUE 0x074B 148 149 #define EC_ADDR_BIOS_OEM 0x074E 150 #define FN_LOCK_STATUS BIT(4) 151 152 #define EC_ADDR_MANUAL_FAN_CTRL 0x0751 153 #define FAN_LEVEL_MASK GENMASK(2, 0) 154 #define FAN_MODE_TURBO BIT(4) 155 #define FAN_MODE_HIGH BIT(5) 156 #define FAN_MODE_BOOST BIT(6) 157 #define FAN_MODE_USER BIT(7) 158 159 #define EC_ADDR_PWM_1 0x075B 160 161 #define EC_ADDR_PWM_2 0x075C 162 163 /* Unreliable */ 164 #define EC_ADDR_SUPPORT_1 0x0765 165 #define AIRPLANE_MODE BIT(0) 166 #define GPS_SWITCH BIT(1) 167 #define OVERCLOCK BIT(2) 168 #define MACRO_KEY BIT(3) 169 #define SHORTCUT_KEY BIT(4) 170 #define SUPER_KEY_LOCK BIT(5) 171 #define LIGHTBAR BIT(6) 172 #define FAN_BOOST BIT(7) 173 174 #define EC_ADDR_SUPPORT_2 0x0766 175 #define SILENT_MODE BIT(0) 176 #define USB_CHARGING BIT(1) 177 #define RGB_KEYBOARD BIT(2) 178 #define CHINA_MODE BIT(5) 179 #define MY_BATTERY BIT(6) 180 181 #define EC_ADDR_TRIGGER 0x0767 182 #define TRIGGER_SUPER_KEY_LOCK BIT(0) 183 #define TRIGGER_LIGHTBAR BIT(1) 184 #define TRIGGER_FAN_BOOST BIT(2) 185 #define TRIGGER_SILENT_MODE BIT(3) 186 #define TRIGGER_USB_CHARGING BIT(4) 187 #define RGB_APPLY_COLOR BIT(5) 188 #define RGB_LOGO_EFFECT BIT(6) 189 #define RGB_RAINBOW_EFFECT BIT(7) 190 191 #define EC_ADDR_SWITCH_STATUS 0x0768 192 #define SUPER_KEY_LOCK_STATUS BIT(0) 193 #define LIGHTBAR_STATUS BIT(1) 194 #define FAN_BOOST_STATUS BIT(2) 195 #define MACRO_KEY_STATUS BIT(3) 196 #define MY_BAT_POWER_BAT_STATUS BIT(4) 197 198 #define EC_ADDR_RGB_RED 0x0769 199 200 #define EC_ADDR_RGB_GREEN 0x076A 201 202 #define EC_ADDR_RGB_BLUE 0x076B 203 204 #define EC_ADDR_ROMID_START 0x0770 205 #define ROMID_LENGTH 14 206 207 #define EC_ADDR_ROMID_EXTRA_1 0x077E 208 209 #define EC_ADDR_ROMID_EXTRA_2 0x077F 210 211 #define EC_ADDR_BIOS_OEM_2 0x0782 212 #define FAN_V2_NEW BIT(0) 213 #define FAN_QKEY BIT(1) 214 #define FAN_TABLE_OFFICE_MODE BIT(2) 215 #define FAN_V3 BIT(3) 216 #define DEFAULT_MODE BIT(4) 217 218 #define EC_ADDR_PL1_SETTING 0x0783 219 220 #define EC_ADDR_PL2_SETTING 0x0784 221 222 #define EC_ADDR_PL4_SETTING 0x0785 223 224 #define EC_ADDR_FAN_DEFAULT 0x0786 225 #define FAN_CURVE_LENGTH 5 226 227 #define EC_ADDR_KBD_STATUS 0x078C 228 #define KBD_WHITE_ONLY BIT(0) // ~single color 229 #define KBD_SINGLE_COLOR_OFF BIT(1) 230 #define KBD_TURBO_LEVEL_MASK GENMASK(3, 2) 231 #define KBD_APPLY BIT(4) 232 #define KBD_BRIGHTNESS GENMASK(7, 5) 233 234 #define EC_ADDR_FAN_CTRL 0x078E 235 #define FAN3P5 BIT(1) 236 #define CHARGING_PROFILE BIT(3) 237 #define UNIVERSAL_FAN_CTRL BIT(6) 238 239 #define EC_ADDR_BIOS_OEM_3 0x07A3 240 #define FAN_REDUCED_DURY_CYCLE BIT(5) 241 #define FAN_ALWAYS_ON BIT(6) 242 243 #define EC_ADDR_BIOS_BYTE 0x07A4 244 #define FN_LOCK_SWITCH BIT(3) 245 246 #define EC_ADDR_OEM_3 0x07A5 247 #define POWER_LED_MASK GENMASK(1, 0) 248 #define POWER_LED_LEFT 0x00 249 #define POWER_LED_BOTH 0x01 250 #define POWER_LED_NONE 0x02 251 #define FAN_QUIET BIT(2) 252 #define OVERBOOST BIT(4) 253 #define HIGH_POWER BIT(7) 254 255 #define EC_ADDR_OEM_4 0x07A6 256 #define OVERBOOST_DYN_TEMP_OFF BIT(1) 257 #define TOUCHPAD_TOGGLE_OFF BIT(6) 258 259 #define EC_ADDR_CHARGE_CTRL 0x07B9 260 #define CHARGE_CTRL_MASK GENMASK(6, 0) 261 #define CHARGE_CTRL_REACHED BIT(7) 262 263 #define EC_ADDR_UNIVERSAL_FAN_CTRL 0x07C5 264 #define SPLIT_TABLES BIT(7) 265 266 #define EC_ADDR_AP_OEM_6 0x07C6 267 #define ENABLE_UNIVERSAL_FAN_CTRL BIT(2) 268 #define BATTERY_CHARGE_FULL_OVER_24H BIT(3) 269 #define BATTERY_ERM_STATUS_REACHED BIT(4) 270 271 #define EC_ADDR_USB_C_POWER_PRIORITY 0x07CC 272 #define USB_C_POWER_PRIORITY BIT(7) 273 274 /* Same bits as EC_ADDR_LIGHTBAR_AC_CTRL except LIGHTBAR_S3_OFF */ 275 #define EC_ADDR_LIGHTBAR_BAT_CTRL 0x07E2 276 277 #define EC_ADDR_LIGHTBAR_BAT_RED 0x07E3 278 279 #define EC_ADDR_LIGHTBAR_BAT_GREEN 0x07E4 280 281 #define EC_ADDR_LIGHTBAR_BAT_BLUE 0x07E5 282 283 #define EC_ADDR_CPU_TEMP_END_TABLE 0x0F00 284 285 #define EC_ADDR_CPU_TEMP_START_TABLE 0x0F10 286 287 #define EC_ADDR_CPU_FAN_SPEED_TABLE 0x0F20 288 289 #define EC_ADDR_GPU_TEMP_END_TABLE 0x0F30 290 291 #define EC_ADDR_GPU_TEMP_START_TABLE 0x0F40 292 293 #define EC_ADDR_GPU_FAN_SPEED_TABLE 0x0F50 294 295 /* 296 * Those two registers technically allow for manual fan control, 297 * but are unstable on some models and are likely not meant to 298 * be used by applications as they are only accessible when using 299 * the WMI interface. 300 */ 301 #define EC_ADDR_PWM_1_WRITEABLE 0x1804 302 303 #define EC_ADDR_PWM_2_WRITEABLE 0x1809 304 305 #define DRIVER_NAME "uniwill" 306 307 /* 308 * The OEM software always sleeps up to 6 ms after reading/writing EC 309 * registers, so we emulate this behaviour for maximum compatibility. 310 */ 311 #define UNIWILL_EC_DELAY_US 6000 312 313 #define PWM_MAX 200 314 #define FAN_TABLE_LENGTH 16 315 316 #define LED_CHANNELS 3 317 #define LED_MAX_BRIGHTNESS 200 318 319 #define UNIWILL_FEATURE_FN_LOCK BIT(0) 320 #define UNIWILL_FEATURE_SUPER_KEY BIT(1) 321 #define UNIWILL_FEATURE_TOUCHPAD_TOGGLE BIT(2) 322 #define UNIWILL_FEATURE_LIGHTBAR BIT(3) 323 #define UNIWILL_FEATURE_BATTERY BIT(4) 324 #define UNIWILL_FEATURE_CPU_TEMP BIT(5) 325 #define UNIWILL_FEATURE_GPU_TEMP BIT(6) 326 #define UNIWILL_FEATURE_PRIMARY_FAN BIT(7) 327 #define UNIWILL_FEATURE_SECONDARY_FAN BIT(8) 328 #define UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL BIT(9) 329 #define UNIWILL_FEATURE_USB_C_POWER_PRIORITY BIT(10) 330 331 enum usb_c_power_priority_options { 332 USB_C_POWER_PRIORITY_CHARGING = 0, 333 USB_C_POWER_PRIORITY_PERFORMANCE, 334 }; 335 336 struct uniwill_data { 337 struct device *dev; 338 acpi_handle handle; 339 struct regmap *regmap; 340 unsigned int features; 341 struct acpi_battery_hook hook; 342 unsigned int last_charge_ctrl; 343 struct mutex battery_lock; /* Protects the list of currently registered batteries */ 344 unsigned int last_status; 345 unsigned int last_switch_status; 346 struct mutex super_key_lock; /* Protects the toggling of the super key lock state */ 347 struct list_head batteries; 348 struct mutex led_lock; /* Protects writes to the lightbar registers */ 349 struct led_classdev_mc led_mc_cdev; 350 struct mc_subled led_mc_subled_info[LED_CHANNELS]; 351 struct mutex input_lock; /* Protects input sequence during notify */ 352 struct input_dev *input_device; 353 struct notifier_block nb; 354 struct mutex usb_c_power_priority_lock; /* Protects dependent bit write and state safe */ 355 enum usb_c_power_priority_options last_usb_c_power_priority_option; 356 }; 357 358 struct uniwill_battery_entry { 359 struct list_head head; 360 struct power_supply *battery; 361 }; 362 363 struct uniwill_device_descriptor { 364 unsigned int features; 365 /* Executed during driver probing */ 366 int (*probe)(struct uniwill_data *data); 367 }; 368 369 static bool force; 370 module_param_unsafe(force, bool, 0); 371 MODULE_PARM_DESC(force, "Force loading without checking for supported devices\n"); 372 373 /* 374 * Contains device specific data like the feature bitmap since 375 * the associated registers are not always reliable. 376 */ 377 static struct uniwill_device_descriptor device_descriptor __ro_after_init; 378 379 static const char * const uniwill_temp_labels[] = { 380 "CPU", 381 "GPU", 382 }; 383 384 static const char * const uniwill_fan_labels[] = { 385 "Main", 386 "Secondary", 387 }; 388 389 static const struct key_entry uniwill_keymap[] = { 390 /* Reported via keyboard controller */ 391 { KE_IGNORE, UNIWILL_OSD_CAPSLOCK, { KEY_CAPSLOCK }}, 392 { KE_IGNORE, UNIWILL_OSD_NUMLOCK, { KEY_NUMLOCK }}, 393 394 /* 395 * Reported when the user enables/disables the super key. 396 * Those events might even be reported when the change was done 397 * using the sysfs attribute! 398 */ 399 { KE_IGNORE, UNIWILL_OSD_SUPER_KEY_DISABLE, { KEY_UNKNOWN }}, 400 { KE_IGNORE, UNIWILL_OSD_SUPER_KEY_ENABLE, { KEY_UNKNOWN }}, 401 /* Optional, might not be reported by all devices */ 402 { KE_IGNORE, UNIWILL_OSD_SUPER_KEY_STATE_CHANGED, { KEY_UNKNOWN }}, 403 404 /* Reported in manual mode when toggling the airplane mode status */ 405 { KE_KEY, UNIWILL_OSD_RFKILL, { KEY_RFKILL }}, 406 { KE_IGNORE, UNIWILL_OSD_RADIOON, { KEY_UNKNOWN }}, 407 { KE_IGNORE, UNIWILL_OSD_RADIOOFF, { KEY_UNKNOWN }}, 408 409 /* Reported when user wants to cycle the platform profile */ 410 { KE_KEY, UNIWILL_OSD_PERFORMANCE_MODE_TOGGLE, { KEY_F14 }}, 411 412 /* Reported when the user wants to adjust the brightness of the keyboard */ 413 { KE_KEY, UNIWILL_OSD_KBDILLUMDOWN, { KEY_KBDILLUMDOWN }}, 414 { KE_KEY, UNIWILL_OSD_KBDILLUMUP, { KEY_KBDILLUMUP }}, 415 416 /* Reported when the user wants to toggle the microphone mute status */ 417 { KE_KEY, UNIWILL_OSD_MIC_MUTE, { KEY_MICMUTE }}, 418 419 /* Reported when the user wants to toggle the mute status */ 420 { KE_IGNORE, UNIWILL_OSD_MUTE, { KEY_MUTE }}, 421 422 /* Reported when the user wants to toggle the brightness of the keyboard */ 423 { KE_KEY, UNIWILL_OSD_KBDILLUMTOGGLE, { KEY_KBDILLUMTOGGLE }}, 424 { KE_KEY, UNIWILL_OSD_KB_LED_LEVEL0, { KEY_KBDILLUMTOGGLE }}, 425 { KE_KEY, UNIWILL_OSD_KB_LED_LEVEL1, { KEY_KBDILLUMTOGGLE }}, 426 { KE_KEY, UNIWILL_OSD_KB_LED_LEVEL2, { KEY_KBDILLUMTOGGLE }}, 427 { KE_KEY, UNIWILL_OSD_KB_LED_LEVEL3, { KEY_KBDILLUMTOGGLE }}, 428 { KE_KEY, UNIWILL_OSD_KB_LED_LEVEL4, { KEY_KBDILLUMTOGGLE }}, 429 430 /* FIXME: find out the exact meaning of those events */ 431 { KE_IGNORE, UNIWILL_OSD_BAT_CHARGE_FULL_24_H, { KEY_UNKNOWN }}, 432 { KE_IGNORE, UNIWILL_OSD_BAT_ERM_UPDATE, { KEY_UNKNOWN }}, 433 434 /* Reported when the user wants to toggle the benchmark mode status */ 435 { KE_IGNORE, UNIWILL_OSD_BENCHMARK_MODE_TOGGLE, { KEY_UNKNOWN }}, 436 437 /* Reported when the user wants to toggle the webcam */ 438 { KE_IGNORE, UNIWILL_OSD_WEBCAM_TOGGLE, { KEY_UNKNOWN }}, 439 440 { KE_END } 441 }; 442 443 static inline bool uniwill_device_supports(const struct uniwill_data *data, 444 unsigned int features) 445 { 446 return (data->features & features) == features; 447 } 448 449 static int uniwill_ec_reg_write(void *context, unsigned int reg, unsigned int val) 450 { 451 union acpi_object params[2] = { 452 { 453 .integer = { 454 .type = ACPI_TYPE_INTEGER, 455 .value = reg, 456 }, 457 }, 458 { 459 .integer = { 460 .type = ACPI_TYPE_INTEGER, 461 .value = val, 462 }, 463 }, 464 }; 465 struct uniwill_data *data = context; 466 struct acpi_object_list input = { 467 .count = ARRAY_SIZE(params), 468 .pointer = params, 469 }; 470 acpi_status status; 471 472 status = acpi_evaluate_object(data->handle, "ECRW", &input, NULL); 473 if (ACPI_FAILURE(status)) 474 return -EIO; 475 476 usleep_range(UNIWILL_EC_DELAY_US, UNIWILL_EC_DELAY_US * 2); 477 478 return 0; 479 } 480 481 static int uniwill_ec_reg_read(void *context, unsigned int reg, unsigned int *val) 482 { 483 union acpi_object params[1] = { 484 { 485 .integer = { 486 .type = ACPI_TYPE_INTEGER, 487 .value = reg, 488 }, 489 }, 490 }; 491 struct uniwill_data *data = context; 492 struct acpi_object_list input = { 493 .count = ARRAY_SIZE(params), 494 .pointer = params, 495 }; 496 unsigned long long output; 497 acpi_status status; 498 499 status = acpi_evaluate_integer(data->handle, "ECRR", &input, &output); 500 if (ACPI_FAILURE(status)) 501 return -EIO; 502 503 if (output > U8_MAX) 504 return -ENXIO; 505 506 usleep_range(UNIWILL_EC_DELAY_US, UNIWILL_EC_DELAY_US * 2); 507 508 *val = output; 509 510 return 0; 511 } 512 513 static const struct regmap_bus uniwill_ec_bus = { 514 .reg_write = uniwill_ec_reg_write, 515 .reg_read = uniwill_ec_reg_read, 516 .reg_format_endian_default = REGMAP_ENDIAN_LITTLE, 517 .val_format_endian_default = REGMAP_ENDIAN_LITTLE, 518 }; 519 520 static bool uniwill_writeable_reg(struct device *dev, unsigned int reg) 521 { 522 switch (reg) { 523 case EC_ADDR_AP_OEM: 524 case EC_ADDR_LIGHTBAR_AC_CTRL: 525 case EC_ADDR_LIGHTBAR_AC_RED: 526 case EC_ADDR_LIGHTBAR_AC_GREEN: 527 case EC_ADDR_LIGHTBAR_AC_BLUE: 528 case EC_ADDR_BIOS_OEM: 529 case EC_ADDR_TRIGGER: 530 case EC_ADDR_OEM_4: 531 case EC_ADDR_CHARGE_CTRL: 532 case EC_ADDR_LIGHTBAR_BAT_CTRL: 533 case EC_ADDR_LIGHTBAR_BAT_RED: 534 case EC_ADDR_LIGHTBAR_BAT_GREEN: 535 case EC_ADDR_LIGHTBAR_BAT_BLUE: 536 case EC_ADDR_CTGP_DB_CTRL: 537 case EC_ADDR_CTGP_DB_CTGP_OFFSET: 538 case EC_ADDR_CTGP_DB_TPP_OFFSET: 539 case EC_ADDR_CTGP_DB_DB_OFFSET: 540 case EC_ADDR_USB_C_POWER_PRIORITY: 541 return true; 542 default: 543 return false; 544 } 545 } 546 547 static bool uniwill_readable_reg(struct device *dev, unsigned int reg) 548 { 549 switch (reg) { 550 case EC_ADDR_CPU_TEMP: 551 case EC_ADDR_GPU_TEMP: 552 case EC_ADDR_MAIN_FAN_RPM_1: 553 case EC_ADDR_MAIN_FAN_RPM_2: 554 case EC_ADDR_SECOND_FAN_RPM_1: 555 case EC_ADDR_SECOND_FAN_RPM_2: 556 case EC_ADDR_BAT_ALERT: 557 case EC_ADDR_PROJECT_ID: 558 case EC_ADDR_AP_OEM: 559 case EC_ADDR_LIGHTBAR_AC_CTRL: 560 case EC_ADDR_LIGHTBAR_AC_RED: 561 case EC_ADDR_LIGHTBAR_AC_GREEN: 562 case EC_ADDR_LIGHTBAR_AC_BLUE: 563 case EC_ADDR_BIOS_OEM: 564 case EC_ADDR_PWM_1: 565 case EC_ADDR_PWM_2: 566 case EC_ADDR_TRIGGER: 567 case EC_ADDR_SWITCH_STATUS: 568 case EC_ADDR_OEM_4: 569 case EC_ADDR_CHARGE_CTRL: 570 case EC_ADDR_LIGHTBAR_BAT_CTRL: 571 case EC_ADDR_LIGHTBAR_BAT_RED: 572 case EC_ADDR_LIGHTBAR_BAT_GREEN: 573 case EC_ADDR_LIGHTBAR_BAT_BLUE: 574 case EC_ADDR_SYSTEM_ID: 575 case EC_ADDR_CTGP_DB_CTRL: 576 case EC_ADDR_CTGP_DB_CTGP_OFFSET: 577 case EC_ADDR_CTGP_DB_TPP_OFFSET: 578 case EC_ADDR_CTGP_DB_DB_OFFSET: 579 case EC_ADDR_USB_C_POWER_PRIORITY: 580 return true; 581 default: 582 return false; 583 } 584 } 585 586 static bool uniwill_volatile_reg(struct device *dev, unsigned int reg) 587 { 588 switch (reg) { 589 case EC_ADDR_CPU_TEMP: 590 case EC_ADDR_GPU_TEMP: 591 case EC_ADDR_MAIN_FAN_RPM_1: 592 case EC_ADDR_MAIN_FAN_RPM_2: 593 case EC_ADDR_SECOND_FAN_RPM_1: 594 case EC_ADDR_SECOND_FAN_RPM_2: 595 case EC_ADDR_BAT_ALERT: 596 case EC_ADDR_BIOS_OEM: 597 case EC_ADDR_PWM_1: 598 case EC_ADDR_PWM_2: 599 case EC_ADDR_TRIGGER: 600 case EC_ADDR_SWITCH_STATUS: 601 case EC_ADDR_CHARGE_CTRL: 602 case EC_ADDR_USB_C_POWER_PRIORITY: 603 return true; 604 default: 605 return false; 606 } 607 } 608 609 static const struct regmap_config uniwill_ec_config = { 610 .reg_bits = 16, 611 .val_bits = 8, 612 .writeable_reg = uniwill_writeable_reg, 613 .readable_reg = uniwill_readable_reg, 614 .volatile_reg = uniwill_volatile_reg, 615 .can_sleep = true, 616 .max_register = 0xFFF, 617 .cache_type = REGCACHE_MAPLE, 618 .use_single_read = true, 619 .use_single_write = true, 620 }; 621 622 static ssize_t fn_lock_store(struct device *dev, struct device_attribute *attr, const char *buf, 623 size_t count) 624 { 625 struct uniwill_data *data = dev_get_drvdata(dev); 626 unsigned int value; 627 bool enable; 628 int ret; 629 630 ret = kstrtobool(buf, &enable); 631 if (ret < 0) 632 return ret; 633 634 if (enable) 635 value = FN_LOCK_STATUS; 636 else 637 value = 0; 638 639 ret = regmap_update_bits(data->regmap, EC_ADDR_BIOS_OEM, FN_LOCK_STATUS, value); 640 if (ret < 0) 641 return ret; 642 643 return count; 644 } 645 646 static ssize_t fn_lock_show(struct device *dev, struct device_attribute *attr, char *buf) 647 { 648 struct uniwill_data *data = dev_get_drvdata(dev); 649 unsigned int value; 650 int ret; 651 652 ret = regmap_read(data->regmap, EC_ADDR_BIOS_OEM, &value); 653 if (ret < 0) 654 return ret; 655 656 return sysfs_emit(buf, "%d\n", !!(value & FN_LOCK_STATUS)); 657 } 658 659 static DEVICE_ATTR_RW(fn_lock); 660 661 static ssize_t super_key_enable_store(struct device *dev, struct device_attribute *attr, 662 const char *buf, size_t count) 663 { 664 struct uniwill_data *data = dev_get_drvdata(dev); 665 unsigned int value; 666 bool enable; 667 int ret; 668 669 ret = kstrtobool(buf, &enable); 670 if (ret < 0) 671 return ret; 672 673 guard(mutex)(&data->super_key_lock); 674 675 ret = regmap_read(data->regmap, EC_ADDR_SWITCH_STATUS, &value); 676 if (ret < 0) 677 return ret; 678 679 /* 680 * We can only toggle the super key lock, so we return early if the setting 681 * is already in the correct state. 682 */ 683 if (enable == !(value & SUPER_KEY_LOCK_STATUS)) 684 return count; 685 686 ret = regmap_write_bits(data->regmap, EC_ADDR_TRIGGER, TRIGGER_SUPER_KEY_LOCK, 687 TRIGGER_SUPER_KEY_LOCK); 688 if (ret < 0) 689 return ret; 690 691 return count; 692 } 693 694 static ssize_t super_key_enable_show(struct device *dev, struct device_attribute *attr, char *buf) 695 { 696 struct uniwill_data *data = dev_get_drvdata(dev); 697 unsigned int value; 698 int ret; 699 700 ret = regmap_read(data->regmap, EC_ADDR_SWITCH_STATUS, &value); 701 if (ret < 0) 702 return ret; 703 704 return sysfs_emit(buf, "%d\n", !(value & SUPER_KEY_LOCK_STATUS)); 705 } 706 707 static DEVICE_ATTR_RW(super_key_enable); 708 709 static ssize_t touchpad_toggle_enable_store(struct device *dev, struct device_attribute *attr, 710 const char *buf, size_t count) 711 { 712 struct uniwill_data *data = dev_get_drvdata(dev); 713 unsigned int value; 714 bool enable; 715 int ret; 716 717 ret = kstrtobool(buf, &enable); 718 if (ret < 0) 719 return ret; 720 721 if (enable) 722 value = 0; 723 else 724 value = TOUCHPAD_TOGGLE_OFF; 725 726 ret = regmap_update_bits(data->regmap, EC_ADDR_OEM_4, TOUCHPAD_TOGGLE_OFF, value); 727 if (ret < 0) 728 return ret; 729 730 return count; 731 } 732 733 static ssize_t touchpad_toggle_enable_show(struct device *dev, struct device_attribute *attr, 734 char *buf) 735 { 736 struct uniwill_data *data = dev_get_drvdata(dev); 737 unsigned int value; 738 int ret; 739 740 ret = regmap_read(data->regmap, EC_ADDR_OEM_4, &value); 741 if (ret < 0) 742 return ret; 743 744 return sysfs_emit(buf, "%d\n", !(value & TOUCHPAD_TOGGLE_OFF)); 745 } 746 747 static DEVICE_ATTR_RW(touchpad_toggle_enable); 748 749 static ssize_t rainbow_animation_store(struct device *dev, struct device_attribute *attr, 750 const char *buf, size_t count) 751 { 752 struct uniwill_data *data = dev_get_drvdata(dev); 753 unsigned int value; 754 bool enable; 755 int ret; 756 757 ret = kstrtobool(buf, &enable); 758 if (ret < 0) 759 return ret; 760 761 if (enable) 762 value = LIGHTBAR_WELCOME; 763 else 764 value = 0; 765 766 guard(mutex)(&data->led_lock); 767 768 ret = regmap_update_bits(data->regmap, EC_ADDR_LIGHTBAR_AC_CTRL, LIGHTBAR_WELCOME, value); 769 if (ret < 0) 770 return ret; 771 772 ret = regmap_update_bits(data->regmap, EC_ADDR_LIGHTBAR_BAT_CTRL, LIGHTBAR_WELCOME, value); 773 if (ret < 0) 774 return ret; 775 776 return count; 777 } 778 779 static ssize_t rainbow_animation_show(struct device *dev, struct device_attribute *attr, char *buf) 780 { 781 struct uniwill_data *data = dev_get_drvdata(dev); 782 unsigned int value; 783 int ret; 784 785 ret = regmap_read(data->regmap, EC_ADDR_LIGHTBAR_AC_CTRL, &value); 786 if (ret < 0) 787 return ret; 788 789 return sysfs_emit(buf, "%d\n", !!(value & LIGHTBAR_WELCOME)); 790 } 791 792 static DEVICE_ATTR_RW(rainbow_animation); 793 794 static ssize_t breathing_in_suspend_store(struct device *dev, struct device_attribute *attr, 795 const char *buf, size_t count) 796 { 797 struct uniwill_data *data = dev_get_drvdata(dev); 798 unsigned int value; 799 bool enable; 800 int ret; 801 802 ret = kstrtobool(buf, &enable); 803 if (ret < 0) 804 return ret; 805 806 if (enable) 807 value = 0; 808 else 809 value = LIGHTBAR_S3_OFF; 810 811 /* We only access a single register here, so we do not need to use data->led_lock */ 812 ret = regmap_update_bits(data->regmap, EC_ADDR_LIGHTBAR_AC_CTRL, LIGHTBAR_S3_OFF, value); 813 if (ret < 0) 814 return ret; 815 816 return count; 817 } 818 819 static ssize_t breathing_in_suspend_show(struct device *dev, struct device_attribute *attr, 820 char *buf) 821 { 822 struct uniwill_data *data = dev_get_drvdata(dev); 823 unsigned int value; 824 int ret; 825 826 ret = regmap_read(data->regmap, EC_ADDR_LIGHTBAR_AC_CTRL, &value); 827 if (ret < 0) 828 return ret; 829 830 return sysfs_emit(buf, "%d\n", !(value & LIGHTBAR_S3_OFF)); 831 } 832 833 static DEVICE_ATTR_RW(breathing_in_suspend); 834 835 static ssize_t ctgp_offset_store(struct device *dev, struct device_attribute *attr, 836 const char *buf, size_t count) 837 { 838 struct uniwill_data *data = dev_get_drvdata(dev); 839 unsigned int value; 840 int ret; 841 842 ret = kstrtouint(buf, 0, &value); 843 if (ret < 0) 844 return ret; 845 846 if (value > U8_MAX) 847 return -EINVAL; 848 849 ret = regmap_write(data->regmap, EC_ADDR_CTGP_DB_CTGP_OFFSET, value); 850 if (ret < 0) 851 return ret; 852 853 return count; 854 } 855 856 static ssize_t ctgp_offset_show(struct device *dev, struct device_attribute *attr, 857 char *buf) 858 { 859 struct uniwill_data *data = dev_get_drvdata(dev); 860 unsigned int value; 861 int ret; 862 863 ret = regmap_read(data->regmap, EC_ADDR_CTGP_DB_CTGP_OFFSET, &value); 864 if (ret < 0) 865 return ret; 866 867 return sysfs_emit(buf, "%u\n", value); 868 } 869 870 static DEVICE_ATTR_RW(ctgp_offset); 871 872 static int uniwill_nvidia_ctgp_init(struct uniwill_data *data) 873 { 874 int ret; 875 876 if (!uniwill_device_supports(data, UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL)) 877 return 0; 878 879 ret = regmap_write(data->regmap, EC_ADDR_CTGP_DB_CTGP_OFFSET, 0); 880 if (ret < 0) 881 return ret; 882 883 ret = regmap_write(data->regmap, EC_ADDR_CTGP_DB_TPP_OFFSET, 255); 884 if (ret < 0) 885 return ret; 886 887 ret = regmap_write(data->regmap, EC_ADDR_CTGP_DB_DB_OFFSET, 25); 888 if (ret < 0) 889 return ret; 890 891 ret = regmap_set_bits(data->regmap, EC_ADDR_CTGP_DB_CTRL, 892 CTGP_DB_GENERAL_ENABLE | CTGP_DB_DB_ENABLE | CTGP_DB_CTGP_ENABLE); 893 if (ret < 0) 894 return ret; 895 896 return 0; 897 } 898 899 static const char * const usb_c_power_priority_text[] = { 900 [USB_C_POWER_PRIORITY_CHARGING] = "charging", 901 [USB_C_POWER_PRIORITY_PERFORMANCE] = "performance", 902 }; 903 904 static const u8 usb_c_power_priority_value[] = { 905 [USB_C_POWER_PRIORITY_CHARGING] = 0, 906 [USB_C_POWER_PRIORITY_PERFORMANCE] = USB_C_POWER_PRIORITY, 907 }; 908 909 static ssize_t usb_c_power_priority_store(struct device *dev, 910 struct device_attribute *attr, 911 const char *buf, size_t count) 912 { 913 struct uniwill_data *data = dev_get_drvdata(dev); 914 enum usb_c_power_priority_options option; 915 unsigned int value; 916 int ret; 917 918 ret = sysfs_match_string(usb_c_power_priority_text, buf); 919 if (ret < 0) 920 return ret; 921 922 option = ret; 923 value = usb_c_power_priority_value[option]; 924 925 guard(mutex)(&data->usb_c_power_priority_lock); 926 927 ret = regmap_update_bits(data->regmap, EC_ADDR_USB_C_POWER_PRIORITY, 928 USB_C_POWER_PRIORITY, value); 929 if (ret < 0) 930 return ret; 931 932 data->last_usb_c_power_priority_option = option; 933 934 return count; 935 } 936 937 static ssize_t usb_c_power_priority_show(struct device *dev, 938 struct device_attribute *attr, 939 char *buf) 940 { 941 struct uniwill_data *data = dev_get_drvdata(dev); 942 unsigned int value; 943 int ret; 944 945 ret = regmap_read(data->regmap, EC_ADDR_USB_C_POWER_PRIORITY, &value); 946 if (ret < 0) 947 return ret; 948 949 value &= USB_C_POWER_PRIORITY; 950 951 if (usb_c_power_priority_value[USB_C_POWER_PRIORITY_PERFORMANCE] == value) 952 return sysfs_emit(buf, "%s\n", 953 usb_c_power_priority_text[USB_C_POWER_PRIORITY_PERFORMANCE]); 954 955 return sysfs_emit(buf, "%s\n", usb_c_power_priority_text[USB_C_POWER_PRIORITY_CHARGING]); 956 } 957 958 static DEVICE_ATTR_RW(usb_c_power_priority); 959 960 static int usb_c_power_priority_restore(struct uniwill_data *data) 961 { 962 unsigned int value; 963 964 value = usb_c_power_priority_value[data->last_usb_c_power_priority_option]; 965 966 guard(mutex)(&data->usb_c_power_priority_lock); 967 968 return regmap_update_bits(data->regmap, EC_ADDR_USB_C_POWER_PRIORITY, 969 USB_C_POWER_PRIORITY, value); 970 } 971 972 static int usb_c_power_priority_init(struct uniwill_data *data) 973 { 974 unsigned int value; 975 int ret; 976 977 if (!uniwill_device_supports(data, UNIWILL_FEATURE_USB_C_POWER_PRIORITY)) 978 return 0; 979 980 ret = devm_mutex_init(data->dev, &data->usb_c_power_priority_lock); 981 if (ret < 0) 982 return ret; 983 984 ret = regmap_read(data->regmap, EC_ADDR_USB_C_POWER_PRIORITY, &value); 985 if (ret < 0) 986 return ret; 987 988 value &= USB_C_POWER_PRIORITY; 989 990 data->last_usb_c_power_priority_option = 991 usb_c_power_priority_value[USB_C_POWER_PRIORITY_PERFORMANCE] == value ? 992 USB_C_POWER_PRIORITY_PERFORMANCE : 993 USB_C_POWER_PRIORITY_CHARGING; 994 995 return 0; 996 } 997 998 static struct attribute *uniwill_attrs[] = { 999 /* Keyboard-related */ 1000 &dev_attr_fn_lock.attr, 1001 &dev_attr_super_key_enable.attr, 1002 &dev_attr_touchpad_toggle_enable.attr, 1003 /* Lightbar-related */ 1004 &dev_attr_rainbow_animation.attr, 1005 &dev_attr_breathing_in_suspend.attr, 1006 /* Power-management-related */ 1007 &dev_attr_ctgp_offset.attr, 1008 &dev_attr_usb_c_power_priority.attr, 1009 NULL 1010 }; 1011 1012 static umode_t uniwill_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) 1013 { 1014 struct device *dev = kobj_to_dev(kobj); 1015 struct uniwill_data *data = dev_get_drvdata(dev); 1016 1017 if (attr == &dev_attr_fn_lock.attr) { 1018 if (uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK)) 1019 return attr->mode; 1020 } 1021 1022 if (attr == &dev_attr_super_key_enable.attr) { 1023 if (uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY)) 1024 return attr->mode; 1025 } 1026 1027 if (attr == &dev_attr_touchpad_toggle_enable.attr) { 1028 if (uniwill_device_supports(data, UNIWILL_FEATURE_TOUCHPAD_TOGGLE)) 1029 return attr->mode; 1030 } 1031 1032 if (attr == &dev_attr_rainbow_animation.attr || 1033 attr == &dev_attr_breathing_in_suspend.attr) { 1034 if (uniwill_device_supports(data, UNIWILL_FEATURE_LIGHTBAR)) 1035 return attr->mode; 1036 } 1037 1038 if (attr == &dev_attr_ctgp_offset.attr) { 1039 if (uniwill_device_supports(data, UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL)) 1040 return attr->mode; 1041 } 1042 1043 if (attr == &dev_attr_usb_c_power_priority.attr) { 1044 if (uniwill_device_supports(data, UNIWILL_FEATURE_USB_C_POWER_PRIORITY)) 1045 return attr->mode; 1046 } 1047 1048 return 0; 1049 } 1050 1051 static const struct attribute_group uniwill_group = { 1052 .is_visible = uniwill_attr_is_visible, 1053 .attrs = uniwill_attrs, 1054 }; 1055 1056 static const struct attribute_group *uniwill_groups[] = { 1057 &uniwill_group, 1058 NULL 1059 }; 1060 1061 static umode_t uniwill_is_visible(const void *drvdata, enum hwmon_sensor_types type, u32 attr, 1062 int channel) 1063 { 1064 const struct uniwill_data *data = drvdata; 1065 unsigned int feature; 1066 1067 switch (type) { 1068 case hwmon_temp: 1069 switch (channel) { 1070 case 0: 1071 feature = UNIWILL_FEATURE_CPU_TEMP; 1072 break; 1073 case 1: 1074 feature = UNIWILL_FEATURE_GPU_TEMP; 1075 break; 1076 default: 1077 return 0; 1078 } 1079 break; 1080 case hwmon_fan: 1081 case hwmon_pwm: 1082 switch (channel) { 1083 case 0: 1084 feature = UNIWILL_FEATURE_PRIMARY_FAN; 1085 break; 1086 case 1: 1087 feature = UNIWILL_FEATURE_SECONDARY_FAN; 1088 break; 1089 default: 1090 return 0; 1091 } 1092 break; 1093 default: 1094 return 0; 1095 } 1096 1097 if (uniwill_device_supports(data, feature)) 1098 return 0444; 1099 1100 return 0; 1101 } 1102 1103 static int uniwill_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, 1104 long *val) 1105 { 1106 struct uniwill_data *data = dev_get_drvdata(dev); 1107 unsigned int value; 1108 __be16 rpm; 1109 int ret; 1110 1111 switch (type) { 1112 case hwmon_temp: 1113 switch (channel) { 1114 case 0: 1115 ret = regmap_read(data->regmap, EC_ADDR_CPU_TEMP, &value); 1116 break; 1117 case 1: 1118 ret = regmap_read(data->regmap, EC_ADDR_GPU_TEMP, &value); 1119 break; 1120 default: 1121 return -EOPNOTSUPP; 1122 } 1123 1124 if (ret < 0) 1125 return ret; 1126 1127 *val = value * MILLIDEGREE_PER_DEGREE; 1128 return 0; 1129 case hwmon_fan: 1130 switch (channel) { 1131 case 0: 1132 ret = regmap_bulk_read(data->regmap, EC_ADDR_MAIN_FAN_RPM_1, &rpm, 1133 sizeof(rpm)); 1134 break; 1135 case 1: 1136 ret = regmap_bulk_read(data->regmap, EC_ADDR_SECOND_FAN_RPM_1, &rpm, 1137 sizeof(rpm)); 1138 break; 1139 default: 1140 return -EOPNOTSUPP; 1141 } 1142 1143 if (ret < 0) 1144 return ret; 1145 1146 *val = be16_to_cpu(rpm); 1147 return 0; 1148 case hwmon_pwm: 1149 switch (channel) { 1150 case 0: 1151 ret = regmap_read(data->regmap, EC_ADDR_PWM_1, &value); 1152 break; 1153 case 1: 1154 ret = regmap_read(data->regmap, EC_ADDR_PWM_2, &value); 1155 break; 1156 default: 1157 return -EOPNOTSUPP; 1158 } 1159 1160 if (ret < 0) 1161 return ret; 1162 1163 *val = fixp_linear_interpolate(0, 0, PWM_MAX, U8_MAX, value); 1164 return 0; 1165 default: 1166 return -EOPNOTSUPP; 1167 } 1168 } 1169 1170 static int uniwill_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr, 1171 int channel, const char **str) 1172 { 1173 switch (type) { 1174 case hwmon_temp: 1175 *str = uniwill_temp_labels[channel]; 1176 return 0; 1177 case hwmon_fan: 1178 *str = uniwill_fan_labels[channel]; 1179 return 0; 1180 default: 1181 return -EOPNOTSUPP; 1182 } 1183 } 1184 1185 static const struct hwmon_ops uniwill_ops = { 1186 .is_visible = uniwill_is_visible, 1187 .read = uniwill_read, 1188 .read_string = uniwill_read_string, 1189 }; 1190 1191 static const struct hwmon_channel_info * const uniwill_info[] = { 1192 HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ), 1193 HWMON_CHANNEL_INFO(temp, 1194 HWMON_T_INPUT | HWMON_T_LABEL, 1195 HWMON_T_INPUT | HWMON_T_LABEL), 1196 HWMON_CHANNEL_INFO(fan, 1197 HWMON_F_INPUT | HWMON_F_LABEL, 1198 HWMON_F_INPUT | HWMON_F_LABEL), 1199 HWMON_CHANNEL_INFO(pwm, 1200 HWMON_PWM_INPUT, 1201 HWMON_PWM_INPUT), 1202 NULL 1203 }; 1204 1205 static const struct hwmon_chip_info uniwill_chip_info = { 1206 .ops = &uniwill_ops, 1207 .info = uniwill_info, 1208 }; 1209 1210 static int uniwill_hwmon_init(struct uniwill_data *data) 1211 { 1212 struct device *hdev; 1213 1214 if (!uniwill_device_supports(data, UNIWILL_FEATURE_CPU_TEMP) && 1215 !uniwill_device_supports(data, UNIWILL_FEATURE_GPU_TEMP) && 1216 !uniwill_device_supports(data, UNIWILL_FEATURE_PRIMARY_FAN) && 1217 !uniwill_device_supports(data, UNIWILL_FEATURE_SECONDARY_FAN)) 1218 return 0; 1219 1220 hdev = devm_hwmon_device_register_with_info(data->dev, "uniwill", data, 1221 &uniwill_chip_info, NULL); 1222 1223 return PTR_ERR_OR_ZERO(hdev); 1224 } 1225 1226 static const unsigned int uniwill_led_channel_to_bat_reg[LED_CHANNELS] = { 1227 EC_ADDR_LIGHTBAR_BAT_RED, 1228 EC_ADDR_LIGHTBAR_BAT_GREEN, 1229 EC_ADDR_LIGHTBAR_BAT_BLUE, 1230 }; 1231 1232 static const unsigned int uniwill_led_channel_to_ac_reg[LED_CHANNELS] = { 1233 EC_ADDR_LIGHTBAR_AC_RED, 1234 EC_ADDR_LIGHTBAR_AC_GREEN, 1235 EC_ADDR_LIGHTBAR_AC_BLUE, 1236 }; 1237 1238 static int uniwill_led_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness) 1239 { 1240 struct led_classdev_mc *led_mc_cdev = lcdev_to_mccdev(led_cdev); 1241 struct uniwill_data *data = container_of(led_mc_cdev, struct uniwill_data, led_mc_cdev); 1242 unsigned int value; 1243 int ret; 1244 1245 ret = led_mc_calc_color_components(led_mc_cdev, brightness); 1246 if (ret < 0) 1247 return ret; 1248 1249 guard(mutex)(&data->led_lock); 1250 1251 for (int i = 0; i < LED_CHANNELS; i++) { 1252 /* Prevent the brightness values from overflowing */ 1253 value = min(LED_MAX_BRIGHTNESS, data->led_mc_subled_info[i].brightness); 1254 ret = regmap_write(data->regmap, uniwill_led_channel_to_ac_reg[i], value); 1255 if (ret < 0) 1256 return ret; 1257 1258 ret = regmap_write(data->regmap, uniwill_led_channel_to_bat_reg[i], value); 1259 if (ret < 0) 1260 return ret; 1261 } 1262 1263 if (brightness) 1264 value = 0; 1265 else 1266 value = LIGHTBAR_S0_OFF; 1267 1268 ret = regmap_update_bits(data->regmap, EC_ADDR_LIGHTBAR_AC_CTRL, LIGHTBAR_S0_OFF, value); 1269 if (ret < 0) 1270 return ret; 1271 1272 return regmap_update_bits(data->regmap, EC_ADDR_LIGHTBAR_BAT_CTRL, LIGHTBAR_S0_OFF, value); 1273 } 1274 1275 #define LIGHTBAR_MASK (LIGHTBAR_APP_EXISTS | LIGHTBAR_S0_OFF | LIGHTBAR_S3_OFF | LIGHTBAR_WELCOME) 1276 1277 static int uniwill_led_init(struct uniwill_data *data) 1278 { 1279 struct led_init_data init_data = { 1280 .devicename = DRIVER_NAME, 1281 .default_label = "multicolor:" LED_FUNCTION_STATUS, 1282 .devname_mandatory = true, 1283 }; 1284 unsigned int color_indices[3] = { 1285 LED_COLOR_ID_RED, 1286 LED_COLOR_ID_GREEN, 1287 LED_COLOR_ID_BLUE, 1288 }; 1289 unsigned int value; 1290 int ret; 1291 1292 if (!uniwill_device_supports(data, UNIWILL_FEATURE_LIGHTBAR)) 1293 return 0; 1294 1295 ret = devm_mutex_init(data->dev, &data->led_lock); 1296 if (ret < 0) 1297 return ret; 1298 1299 /* 1300 * The EC has separate lightbar settings for AC and battery mode, 1301 * so we have to ensure that both settings are the same. 1302 */ 1303 ret = regmap_read(data->regmap, EC_ADDR_LIGHTBAR_AC_CTRL, &value); 1304 if (ret < 0) 1305 return ret; 1306 1307 value |= LIGHTBAR_APP_EXISTS; 1308 ret = regmap_write(data->regmap, EC_ADDR_LIGHTBAR_AC_CTRL, value); 1309 if (ret < 0) 1310 return ret; 1311 1312 /* 1313 * The breathing animation during suspend is not supported when 1314 * running on battery power. 1315 */ 1316 value |= LIGHTBAR_S3_OFF; 1317 ret = regmap_update_bits(data->regmap, EC_ADDR_LIGHTBAR_BAT_CTRL, LIGHTBAR_MASK, value); 1318 if (ret < 0) 1319 return ret; 1320 1321 data->led_mc_cdev.led_cdev.color = LED_COLOR_ID_MULTI; 1322 data->led_mc_cdev.led_cdev.max_brightness = LED_MAX_BRIGHTNESS; 1323 data->led_mc_cdev.led_cdev.flags = LED_REJECT_NAME_CONFLICT; 1324 data->led_mc_cdev.led_cdev.brightness_set_blocking = uniwill_led_brightness_set; 1325 1326 if (value & LIGHTBAR_S0_OFF) 1327 data->led_mc_cdev.led_cdev.brightness = 0; 1328 else 1329 data->led_mc_cdev.led_cdev.brightness = LED_MAX_BRIGHTNESS; 1330 1331 for (int i = 0; i < LED_CHANNELS; i++) { 1332 data->led_mc_subled_info[i].color_index = color_indices[i]; 1333 1334 ret = regmap_read(data->regmap, uniwill_led_channel_to_ac_reg[i], &value); 1335 if (ret < 0) 1336 return ret; 1337 1338 /* 1339 * Make sure that the initial intensity value is not greater than 1340 * the maximum brightness. 1341 */ 1342 value = min(LED_MAX_BRIGHTNESS, value); 1343 ret = regmap_write(data->regmap, uniwill_led_channel_to_ac_reg[i], value); 1344 if (ret < 0) 1345 return ret; 1346 1347 ret = regmap_write(data->regmap, uniwill_led_channel_to_bat_reg[i], value); 1348 if (ret < 0) 1349 return ret; 1350 1351 data->led_mc_subled_info[i].intensity = value; 1352 data->led_mc_subled_info[i].channel = i; 1353 } 1354 1355 data->led_mc_cdev.subled_info = data->led_mc_subled_info; 1356 data->led_mc_cdev.num_colors = LED_CHANNELS; 1357 1358 return devm_led_classdev_multicolor_register_ext(data->dev, &data->led_mc_cdev, 1359 &init_data); 1360 } 1361 1362 static int uniwill_get_property(struct power_supply *psy, const struct power_supply_ext *ext, 1363 void *drvdata, enum power_supply_property psp, 1364 union power_supply_propval *val) 1365 { 1366 struct uniwill_data *data = drvdata; 1367 union power_supply_propval prop; 1368 unsigned int regval; 1369 int ret; 1370 1371 switch (psp) { 1372 case POWER_SUPPLY_PROP_HEALTH: 1373 ret = power_supply_get_property_direct(psy, POWER_SUPPLY_PROP_PRESENT, &prop); 1374 if (ret < 0) 1375 return ret; 1376 1377 if (!prop.intval) { 1378 val->intval = POWER_SUPPLY_HEALTH_NO_BATTERY; 1379 return 0; 1380 } 1381 1382 ret = power_supply_get_property_direct(psy, POWER_SUPPLY_PROP_STATUS, &prop); 1383 if (ret < 0) 1384 return ret; 1385 1386 if (prop.intval == POWER_SUPPLY_STATUS_UNKNOWN) { 1387 val->intval = POWER_SUPPLY_HEALTH_UNKNOWN; 1388 return 0; 1389 } 1390 1391 ret = regmap_read(data->regmap, EC_ADDR_BAT_ALERT, ®val); 1392 if (ret < 0) 1393 return ret; 1394 1395 if (regval) { 1396 /* Charging issue */ 1397 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; 1398 return 0; 1399 } 1400 1401 val->intval = POWER_SUPPLY_HEALTH_GOOD; 1402 return 0; 1403 case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD: 1404 ret = regmap_read(data->regmap, EC_ADDR_CHARGE_CTRL, ®val); 1405 if (ret < 0) 1406 return ret; 1407 1408 val->intval = clamp_val(FIELD_GET(CHARGE_CTRL_MASK, regval), 0, 100); 1409 return 0; 1410 default: 1411 return -EINVAL; 1412 } 1413 } 1414 1415 static int uniwill_set_property(struct power_supply *psy, const struct power_supply_ext *ext, 1416 void *drvdata, enum power_supply_property psp, 1417 const union power_supply_propval *val) 1418 { 1419 struct uniwill_data *data = drvdata; 1420 1421 switch (psp) { 1422 case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD: 1423 if (val->intval < 1 || val->intval > 100) 1424 return -EINVAL; 1425 1426 return regmap_update_bits(data->regmap, EC_ADDR_CHARGE_CTRL, CHARGE_CTRL_MASK, 1427 val->intval); 1428 default: 1429 return -EINVAL; 1430 } 1431 } 1432 1433 static int uniwill_property_is_writeable(struct power_supply *psy, 1434 const struct power_supply_ext *ext, void *drvdata, 1435 enum power_supply_property psp) 1436 { 1437 if (psp == POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD) 1438 return true; 1439 1440 return false; 1441 } 1442 1443 static const enum power_supply_property uniwill_properties[] = { 1444 POWER_SUPPLY_PROP_HEALTH, 1445 POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD, 1446 }; 1447 1448 static const struct power_supply_ext uniwill_extension = { 1449 .name = DRIVER_NAME, 1450 .properties = uniwill_properties, 1451 .num_properties = ARRAY_SIZE(uniwill_properties), 1452 .get_property = uniwill_get_property, 1453 .set_property = uniwill_set_property, 1454 .property_is_writeable = uniwill_property_is_writeable, 1455 }; 1456 1457 static int uniwill_add_battery(struct power_supply *battery, struct acpi_battery_hook *hook) 1458 { 1459 struct uniwill_data *data = container_of(hook, struct uniwill_data, hook); 1460 struct uniwill_battery_entry *entry; 1461 int ret; 1462 1463 entry = kzalloc_obj(*entry); 1464 if (!entry) 1465 return -ENOMEM; 1466 1467 ret = power_supply_register_extension(battery, &uniwill_extension, data->dev, data); 1468 if (ret < 0) { 1469 kfree(entry); 1470 return ret; 1471 } 1472 1473 guard(mutex)(&data->battery_lock); 1474 1475 entry->battery = battery; 1476 list_add(&entry->head, &data->batteries); 1477 1478 return 0; 1479 } 1480 1481 static int uniwill_remove_battery(struct power_supply *battery, struct acpi_battery_hook *hook) 1482 { 1483 struct uniwill_data *data = container_of(hook, struct uniwill_data, hook); 1484 struct uniwill_battery_entry *entry, *tmp; 1485 1486 scoped_guard(mutex, &data->battery_lock) { 1487 list_for_each_entry_safe(entry, tmp, &data->batteries, head) { 1488 if (entry->battery == battery) { 1489 list_del(&entry->head); 1490 kfree(entry); 1491 break; 1492 } 1493 } 1494 } 1495 1496 power_supply_unregister_extension(battery, &uniwill_extension); 1497 1498 return 0; 1499 } 1500 1501 static int uniwill_battery_init(struct uniwill_data *data) 1502 { 1503 int ret; 1504 1505 if (!uniwill_device_supports(data, UNIWILL_FEATURE_BATTERY)) 1506 return 0; 1507 1508 ret = devm_mutex_init(data->dev, &data->battery_lock); 1509 if (ret < 0) 1510 return ret; 1511 1512 INIT_LIST_HEAD(&data->batteries); 1513 data->hook.name = "Uniwill Battery Extension"; 1514 data->hook.add_battery = uniwill_add_battery; 1515 data->hook.remove_battery = uniwill_remove_battery; 1516 1517 return devm_battery_hook_register(data->dev, &data->hook); 1518 } 1519 1520 static int uniwill_notifier_call(struct notifier_block *nb, unsigned long action, void *dummy) 1521 { 1522 struct uniwill_data *data = container_of(nb, struct uniwill_data, nb); 1523 struct uniwill_battery_entry *entry; 1524 1525 switch (action) { 1526 case UNIWILL_OSD_BATTERY_ALERT: 1527 if (!uniwill_device_supports(data, UNIWILL_FEATURE_BATTERY)) 1528 return NOTIFY_DONE; 1529 1530 mutex_lock(&data->battery_lock); 1531 list_for_each_entry(entry, &data->batteries, head) { 1532 power_supply_changed(entry->battery); 1533 } 1534 mutex_unlock(&data->battery_lock); 1535 1536 return NOTIFY_OK; 1537 case UNIWILL_OSD_DC_ADAPTER_CHANGED: 1538 if (!uniwill_device_supports(data, UNIWILL_FEATURE_USB_C_POWER_PRIORITY)) 1539 return NOTIFY_DONE; 1540 1541 return notifier_from_errno(usb_c_power_priority_restore(data)); 1542 case UNIWILL_OSD_FN_LOCK: 1543 if (!uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK)) 1544 return NOTIFY_DONE; 1545 1546 sysfs_notify(&data->dev->kobj, NULL, "fn_lock"); 1547 1548 return NOTIFY_OK; 1549 default: 1550 mutex_lock(&data->input_lock); 1551 sparse_keymap_report_event(data->input_device, action, 1, true); 1552 mutex_unlock(&data->input_lock); 1553 1554 return NOTIFY_OK; 1555 } 1556 } 1557 1558 static int uniwill_input_init(struct uniwill_data *data) 1559 { 1560 int ret; 1561 1562 ret = devm_mutex_init(data->dev, &data->input_lock); 1563 if (ret < 0) 1564 return ret; 1565 1566 data->input_device = devm_input_allocate_device(data->dev); 1567 if (!data->input_device) 1568 return -ENOMEM; 1569 1570 ret = sparse_keymap_setup(data->input_device, uniwill_keymap, NULL); 1571 if (ret < 0) 1572 return ret; 1573 1574 data->input_device->name = "Uniwill WMI hotkeys"; 1575 data->input_device->phys = "wmi/input0"; 1576 data->input_device->id.bustype = BUS_HOST; 1577 ret = input_register_device(data->input_device); 1578 if (ret < 0) 1579 return ret; 1580 1581 data->nb.notifier_call = uniwill_notifier_call; 1582 1583 return devm_uniwill_wmi_register_notifier(data->dev, &data->nb); 1584 } 1585 1586 static void uniwill_disable_manual_control(void *context) 1587 { 1588 struct uniwill_data *data = context; 1589 1590 regmap_clear_bits(data->regmap, EC_ADDR_AP_OEM, ENABLE_MANUAL_CTRL); 1591 } 1592 1593 static int uniwill_ec_init(struct uniwill_data *data) 1594 { 1595 unsigned int value; 1596 int ret; 1597 1598 ret = regmap_read(data->regmap, EC_ADDR_PROJECT_ID, &value); 1599 if (ret < 0) 1600 return ret; 1601 1602 dev_dbg(data->dev, "Project ID: %u\n", value); 1603 1604 ret = regmap_set_bits(data->regmap, EC_ADDR_AP_OEM, ENABLE_MANUAL_CTRL); 1605 if (ret < 0) 1606 return ret; 1607 1608 return devm_add_action_or_reset(data->dev, uniwill_disable_manual_control, data); 1609 } 1610 1611 static int uniwill_probe(struct platform_device *pdev) 1612 { 1613 struct uniwill_data *data; 1614 struct regmap *regmap; 1615 acpi_handle handle; 1616 int ret; 1617 1618 handle = ACPI_HANDLE(&pdev->dev); 1619 if (!handle) 1620 return -ENODEV; 1621 1622 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 1623 if (!data) 1624 return -ENOMEM; 1625 1626 data->dev = &pdev->dev; 1627 data->handle = handle; 1628 platform_set_drvdata(pdev, data); 1629 1630 regmap = devm_regmap_init(&pdev->dev, &uniwill_ec_bus, data, &uniwill_ec_config); 1631 if (IS_ERR(regmap)) 1632 return PTR_ERR(regmap); 1633 1634 data->regmap = regmap; 1635 1636 ret = devm_mutex_init(&pdev->dev, &data->super_key_lock); 1637 if (ret < 0) 1638 return ret; 1639 1640 ret = uniwill_ec_init(data); 1641 if (ret < 0) 1642 return ret; 1643 1644 data->features = device_descriptor.features; 1645 1646 /* 1647 * Some devices might need to perform some device-specific initialization steps 1648 * before the supported features are initialized. Because of this we have to call 1649 * this callback just after the EC itself was initialized. 1650 */ 1651 if (device_descriptor.probe) { 1652 ret = device_descriptor.probe(data); 1653 if (ret < 0) 1654 return ret; 1655 } 1656 1657 ret = uniwill_battery_init(data); 1658 if (ret < 0) 1659 return ret; 1660 1661 ret = uniwill_led_init(data); 1662 if (ret < 0) 1663 return ret; 1664 1665 ret = uniwill_hwmon_init(data); 1666 if (ret < 0) 1667 return ret; 1668 1669 ret = uniwill_nvidia_ctgp_init(data); 1670 if (ret < 0) 1671 return ret; 1672 1673 ret = usb_c_power_priority_init(data); 1674 if (ret < 0) 1675 return ret; 1676 1677 return uniwill_input_init(data); 1678 } 1679 1680 static void uniwill_shutdown(struct platform_device *pdev) 1681 { 1682 struct uniwill_data *data = platform_get_drvdata(pdev); 1683 1684 regmap_clear_bits(data->regmap, EC_ADDR_AP_OEM, ENABLE_MANUAL_CTRL); 1685 } 1686 1687 static int uniwill_suspend_fn_lock(struct uniwill_data *data) 1688 { 1689 if (!uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK)) 1690 return 0; 1691 1692 /* 1693 * The EC_ADDR_BIOS_OEM is marked as volatile, so we have to restore it 1694 * ourselves. 1695 */ 1696 return regmap_read(data->regmap, EC_ADDR_BIOS_OEM, &data->last_status); 1697 } 1698 1699 static int uniwill_suspend_super_key(struct uniwill_data *data) 1700 { 1701 if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY)) 1702 return 0; 1703 1704 /* 1705 * The EC_ADDR_SWITCH_STATUS is marked as volatile, so we have to restore it 1706 * ourselves. 1707 */ 1708 return regmap_read(data->regmap, EC_ADDR_SWITCH_STATUS, &data->last_switch_status); 1709 } 1710 1711 static int uniwill_suspend_battery(struct uniwill_data *data) 1712 { 1713 if (!uniwill_device_supports(data, UNIWILL_FEATURE_BATTERY)) 1714 return 0; 1715 1716 /* 1717 * Save the current charge limit in order to restore it during resume. 1718 * We cannot use the regmap code for that since this register needs to 1719 * be declared as volatile due to CHARGE_CTRL_REACHED. 1720 */ 1721 return regmap_read(data->regmap, EC_ADDR_CHARGE_CTRL, &data->last_charge_ctrl); 1722 } 1723 1724 static int uniwill_suspend_nvidia_ctgp(struct uniwill_data *data) 1725 { 1726 if (!uniwill_device_supports(data, UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL)) 1727 return 0; 1728 1729 return regmap_clear_bits(data->regmap, EC_ADDR_CTGP_DB_CTRL, 1730 CTGP_DB_DB_ENABLE | CTGP_DB_CTGP_ENABLE); 1731 } 1732 1733 static int uniwill_suspend(struct device *dev) 1734 { 1735 struct uniwill_data *data = dev_get_drvdata(dev); 1736 int ret; 1737 1738 ret = uniwill_suspend_fn_lock(data); 1739 if (ret < 0) 1740 return ret; 1741 1742 ret = uniwill_suspend_super_key(data); 1743 if (ret < 0) 1744 return ret; 1745 1746 ret = uniwill_suspend_battery(data); 1747 if (ret < 0) 1748 return ret; 1749 1750 ret = uniwill_suspend_nvidia_ctgp(data); 1751 if (ret < 0) 1752 return ret; 1753 1754 regcache_cache_only(data->regmap, true); 1755 regcache_mark_dirty(data->regmap); 1756 1757 return 0; 1758 } 1759 1760 static int uniwill_resume_fn_lock(struct uniwill_data *data) 1761 { 1762 if (!uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK)) 1763 return 0; 1764 1765 return regmap_update_bits(data->regmap, EC_ADDR_BIOS_OEM, FN_LOCK_STATUS, 1766 data->last_status); 1767 } 1768 1769 static int uniwill_resume_super_key(struct uniwill_data *data) 1770 { 1771 unsigned int value; 1772 int ret; 1773 1774 if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY)) 1775 return 0; 1776 1777 ret = regmap_read(data->regmap, EC_ADDR_SWITCH_STATUS, &value); 1778 if (ret < 0) 1779 return ret; 1780 1781 if ((data->last_switch_status & SUPER_KEY_LOCK_STATUS) == (value & SUPER_KEY_LOCK_STATUS)) 1782 return 0; 1783 1784 return regmap_write_bits(data->regmap, EC_ADDR_TRIGGER, TRIGGER_SUPER_KEY_LOCK, 1785 TRIGGER_SUPER_KEY_LOCK); 1786 } 1787 1788 static int uniwill_resume_battery(struct uniwill_data *data) 1789 { 1790 if (!uniwill_device_supports(data, UNIWILL_FEATURE_BATTERY)) 1791 return 0; 1792 1793 return regmap_update_bits(data->regmap, EC_ADDR_CHARGE_CTRL, CHARGE_CTRL_MASK, 1794 data->last_charge_ctrl); 1795 } 1796 1797 static int uniwill_resume_nvidia_ctgp(struct uniwill_data *data) 1798 { 1799 if (!uniwill_device_supports(data, UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL)) 1800 return 0; 1801 1802 return regmap_set_bits(data->regmap, EC_ADDR_CTGP_DB_CTRL, 1803 CTGP_DB_DB_ENABLE | CTGP_DB_CTGP_ENABLE); 1804 } 1805 1806 static int uniwill_resume_usb_c_power_priority(struct uniwill_data *data) 1807 { 1808 if (!uniwill_device_supports(data, UNIWILL_FEATURE_USB_C_POWER_PRIORITY)) 1809 return 0; 1810 1811 return usb_c_power_priority_restore(data); 1812 } 1813 1814 static int uniwill_resume(struct device *dev) 1815 { 1816 struct uniwill_data *data = dev_get_drvdata(dev); 1817 int ret; 1818 1819 regcache_cache_only(data->regmap, false); 1820 1821 ret = regcache_sync(data->regmap); 1822 if (ret < 0) 1823 return ret; 1824 1825 ret = uniwill_resume_fn_lock(data); 1826 if (ret < 0) 1827 return ret; 1828 1829 ret = uniwill_resume_super_key(data); 1830 if (ret < 0) 1831 return ret; 1832 1833 ret = uniwill_resume_battery(data); 1834 if (ret < 0) 1835 return ret; 1836 1837 ret = uniwill_resume_nvidia_ctgp(data); 1838 if (ret < 0) 1839 return ret; 1840 1841 return uniwill_resume_usb_c_power_priority(data); 1842 } 1843 1844 static DEFINE_SIMPLE_DEV_PM_OPS(uniwill_pm_ops, uniwill_suspend, uniwill_resume); 1845 1846 /* 1847 * We only use the DMI table for auoloading because the ACPI device itself 1848 * does not guarantee that the underlying EC implementation is supported. 1849 */ 1850 static const struct acpi_device_id uniwill_id_table[] = { 1851 { "INOU0000" }, 1852 { }, 1853 }; 1854 1855 static struct platform_driver uniwill_driver = { 1856 .driver = { 1857 .name = DRIVER_NAME, 1858 .dev_groups = uniwill_groups, 1859 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 1860 .acpi_match_table = uniwill_id_table, 1861 .pm = pm_sleep_ptr(&uniwill_pm_ops), 1862 }, 1863 .probe = uniwill_probe, 1864 .shutdown = uniwill_shutdown, 1865 }; 1866 1867 static struct uniwill_device_descriptor lapqc71a_lapqc71b_descriptor __initdata = { 1868 .features = UNIWILL_FEATURE_SUPER_KEY | 1869 UNIWILL_FEATURE_BATTERY | 1870 UNIWILL_FEATURE_CPU_TEMP | 1871 UNIWILL_FEATURE_GPU_TEMP | 1872 UNIWILL_FEATURE_PRIMARY_FAN | 1873 UNIWILL_FEATURE_SECONDARY_FAN, 1874 }; 1875 1876 static struct uniwill_device_descriptor lapac71h_descriptor __initdata = { 1877 .features = UNIWILL_FEATURE_FN_LOCK | 1878 UNIWILL_FEATURE_SUPER_KEY | 1879 UNIWILL_FEATURE_TOUCHPAD_TOGGLE | 1880 UNIWILL_FEATURE_BATTERY | 1881 UNIWILL_FEATURE_CPU_TEMP | 1882 UNIWILL_FEATURE_GPU_TEMP | 1883 UNIWILL_FEATURE_PRIMARY_FAN | 1884 UNIWILL_FEATURE_SECONDARY_FAN, 1885 }; 1886 1887 static struct uniwill_device_descriptor lapkc71f_descriptor __initdata = { 1888 .features = UNIWILL_FEATURE_FN_LOCK | 1889 UNIWILL_FEATURE_SUPER_KEY | 1890 UNIWILL_FEATURE_TOUCHPAD_TOGGLE | 1891 UNIWILL_FEATURE_LIGHTBAR | 1892 UNIWILL_FEATURE_BATTERY | 1893 UNIWILL_FEATURE_CPU_TEMP | 1894 UNIWILL_FEATURE_GPU_TEMP | 1895 UNIWILL_FEATURE_PRIMARY_FAN | 1896 UNIWILL_FEATURE_SECONDARY_FAN, 1897 }; 1898 1899 /* 1900 * The featuresets below reflect somewhat chronological changes: 1901 * 1 -> 2: UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL is added to the EC firmware. 1902 * 2 -> 3: UNIWILL_FEATURE_USB_C_POWER_PRIORITY is removed from the EC firmware. 1903 * Some devices might divert from this timeline. 1904 */ 1905 1906 static struct uniwill_device_descriptor tux_featureset_1_descriptor __initdata = { 1907 .features = UNIWILL_FEATURE_FN_LOCK | 1908 UNIWILL_FEATURE_SUPER_KEY | 1909 UNIWILL_FEATURE_CPU_TEMP | 1910 UNIWILL_FEATURE_PRIMARY_FAN | 1911 UNIWILL_FEATURE_SECONDARY_FAN | 1912 UNIWILL_FEATURE_USB_C_POWER_PRIORITY, 1913 }; 1914 1915 static struct uniwill_device_descriptor tux_featureset_1_nvidia_descriptor __initdata = { 1916 .features = UNIWILL_FEATURE_FN_LOCK | 1917 UNIWILL_FEATURE_SUPER_KEY | 1918 UNIWILL_FEATURE_CPU_TEMP | 1919 UNIWILL_FEATURE_GPU_TEMP | 1920 UNIWILL_FEATURE_PRIMARY_FAN | 1921 UNIWILL_FEATURE_SECONDARY_FAN | 1922 UNIWILL_FEATURE_USB_C_POWER_PRIORITY, 1923 }; 1924 1925 static struct uniwill_device_descriptor tux_featureset_2_nvidia_descriptor __initdata = { 1926 .features = UNIWILL_FEATURE_FN_LOCK | 1927 UNIWILL_FEATURE_SUPER_KEY | 1928 UNIWILL_FEATURE_CPU_TEMP | 1929 UNIWILL_FEATURE_GPU_TEMP | 1930 UNIWILL_FEATURE_PRIMARY_FAN | 1931 UNIWILL_FEATURE_SECONDARY_FAN | 1932 UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL | 1933 UNIWILL_FEATURE_USB_C_POWER_PRIORITY, 1934 }; 1935 1936 static struct uniwill_device_descriptor tux_featureset_3_descriptor __initdata = { 1937 .features = UNIWILL_FEATURE_FN_LOCK | 1938 UNIWILL_FEATURE_SUPER_KEY | 1939 UNIWILL_FEATURE_CPU_TEMP | 1940 UNIWILL_FEATURE_PRIMARY_FAN | 1941 UNIWILL_FEATURE_SECONDARY_FAN, 1942 }; 1943 1944 static struct uniwill_device_descriptor tux_featureset_3_nvidia_descriptor __initdata = { 1945 .features = UNIWILL_FEATURE_FN_LOCK | 1946 UNIWILL_FEATURE_SUPER_KEY | 1947 UNIWILL_FEATURE_CPU_TEMP | 1948 UNIWILL_FEATURE_GPU_TEMP | 1949 UNIWILL_FEATURE_PRIMARY_FAN | 1950 UNIWILL_FEATURE_SECONDARY_FAN | 1951 UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL, 1952 }; 1953 1954 static int phxtxx1_probe(struct uniwill_data *data) 1955 { 1956 unsigned int value; 1957 int ret; 1958 1959 ret = regmap_read(data->regmap, EC_ADDR_PROJECT_ID, &value); 1960 if (ret < 0) 1961 return ret; 1962 1963 if (value == PROJECT_ID_PH4TRX1 || value == PROJECT_ID_PH6TRX1) 1964 data->features |= UNIWILL_FEATURE_SECONDARY_FAN; 1965 1966 return 0; 1967 }; 1968 1969 static struct uniwill_device_descriptor phxtxx1_descriptor __initdata = { 1970 .features = UNIWILL_FEATURE_FN_LOCK | 1971 UNIWILL_FEATURE_SUPER_KEY | 1972 UNIWILL_FEATURE_CPU_TEMP | 1973 UNIWILL_FEATURE_PRIMARY_FAN | 1974 UNIWILL_FEATURE_USB_C_POWER_PRIORITY, 1975 .probe = phxtxx1_probe, 1976 }; 1977 1978 static int phxarx1_phxaqf1_probe(struct uniwill_data *data) 1979 { 1980 unsigned int value; 1981 int ret; 1982 1983 ret = regmap_read(data->regmap, EC_ADDR_SYSTEM_ID, &value); 1984 if (ret < 0) 1985 return ret; 1986 1987 if (value & HAS_GPU) 1988 data->features |= UNIWILL_FEATURE_GPU_TEMP | 1989 UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL; 1990 1991 return 0; 1992 }; 1993 1994 static struct uniwill_device_descriptor phxarx1_phxaqf1_descriptor __initdata = { 1995 .features = UNIWILL_FEATURE_FN_LOCK | 1996 UNIWILL_FEATURE_SUPER_KEY | 1997 UNIWILL_FEATURE_CPU_TEMP | 1998 UNIWILL_FEATURE_PRIMARY_FAN | 1999 UNIWILL_FEATURE_SECONDARY_FAN | 2000 UNIWILL_FEATURE_USB_C_POWER_PRIORITY, 2001 .probe = phxarx1_phxaqf1_probe, 2002 }; 2003 2004 static struct uniwill_device_descriptor pf5pu1g_descriptor __initdata = { 2005 .features = UNIWILL_FEATURE_FN_LOCK | 2006 UNIWILL_FEATURE_SUPER_KEY | 2007 UNIWILL_FEATURE_CPU_TEMP | 2008 UNIWILL_FEATURE_PRIMARY_FAN, 2009 }; 2010 2011 static const struct dmi_system_id uniwill_dmi_table[] __initconst = { 2012 { 2013 .ident = "XMG FUSION 15 (L19)", 2014 .matches = { 2015 DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"), 2016 DMI_EXACT_MATCH(DMI_BOARD_NAME, "LAPQC71A"), 2017 }, 2018 .driver_data = &lapqc71a_lapqc71b_descriptor, 2019 }, 2020 { 2021 .ident = "XMG FUSION 15 (L19)", 2022 .matches = { 2023 DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"), 2024 DMI_EXACT_MATCH(DMI_BOARD_NAME, "LAPQC71B"), 2025 }, 2026 .driver_data = &lapqc71a_lapqc71b_descriptor, 2027 }, 2028 { 2029 .ident = "XMG FUSION 15 (L19)", 2030 .matches = { 2031 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2032 DMI_EXACT_MATCH(DMI_BOARD_NAME, "LAPQC71A"), 2033 }, 2034 .driver_data = &lapqc71a_lapqc71b_descriptor, 2035 }, 2036 { 2037 .ident = "XMG FUSION 15 (L19)", 2038 .matches = { 2039 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2040 DMI_EXACT_MATCH(DMI_BOARD_NAME, "LAPQC71B"), 2041 }, 2042 .driver_data = &lapqc71a_lapqc71b_descriptor, 2043 }, 2044 { 2045 .ident = "Intel NUC x15", 2046 .matches = { 2047 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"), 2048 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LAPAC71H"), 2049 }, 2050 .driver_data = &lapac71h_descriptor, 2051 }, 2052 { 2053 .ident = "Intel NUC x15", 2054 .matches = { 2055 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"), 2056 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LAPKC71F"), 2057 }, 2058 .driver_data = &lapkc71f_descriptor, 2059 }, 2060 { 2061 .ident = "TUXEDO InfinityBook Pro 14 Gen6 Intel", 2062 .matches = { 2063 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2064 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PHxTxX1"), 2065 }, 2066 .driver_data = &phxtxx1_descriptor, 2067 }, 2068 { 2069 .ident = "TUXEDO InfinityBook Pro 14 Gen6 Intel", 2070 .matches = { 2071 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2072 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PHxTQx1"), 2073 }, 2074 .driver_data = &tux_featureset_2_nvidia_descriptor, 2075 }, 2076 { 2077 .ident = "TUXEDO InfinityBook Pro 14/16 Gen7 Intel", 2078 .matches = { 2079 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2080 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PHxARX1_PHxAQF1"), 2081 }, 2082 .driver_data = &phxarx1_phxaqf1_descriptor, 2083 }, 2084 { 2085 .ident = "TUXEDO InfinityBook Pro 16 Gen7 Intel/Commodore Omnia-Book Pro Gen 7", 2086 .matches = { 2087 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2088 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PH6AG01_PH6AQ71_PH6AQI1"), 2089 }, 2090 .driver_data = &tux_featureset_2_nvidia_descriptor, 2091 }, 2092 { 2093 .ident = "TUXEDO InfinityBook Pro 14/16 Gen8 Intel/Commodore Omnia-Book Pro Gen 8", 2094 .matches = { 2095 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2096 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PH4PRX1_PH6PRX1"), 2097 }, 2098 .driver_data = &tux_featureset_1_descriptor, 2099 }, 2100 { 2101 .ident = "TUXEDO InfinityBook Pro 14 Gen8 Intel/Commodore Omnia-Book Pro Gen 8", 2102 .matches = { 2103 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2104 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PH4PG31"), 2105 }, 2106 .driver_data = &tux_featureset_2_nvidia_descriptor, 2107 }, 2108 { 2109 .ident = "TUXEDO InfinityBook Pro 16 Gen8 Intel", 2110 .matches = { 2111 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2112 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PH6PG01_PH6PG71"), 2113 }, 2114 .driver_data = &tux_featureset_2_nvidia_descriptor, 2115 }, 2116 { 2117 .ident = "TUXEDO InfinityBook Pro 14/15 Gen9 AMD", 2118 .matches = { 2119 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2120 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GXxHRXx"), 2121 }, 2122 .driver_data = &tux_featureset_3_descriptor, 2123 }, 2124 { 2125 .ident = "TUXEDO InfinityBook Pro 14/15 Gen9 Intel/Commodore Omnia-Book 15 Gen9", 2126 .matches = { 2127 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2128 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GXxMRXx"), 2129 }, 2130 .driver_data = &tux_featureset_3_descriptor, 2131 }, 2132 { 2133 .ident = "TUXEDO InfinityBook Pro 14/15 Gen10 AMD", 2134 .matches = { 2135 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2136 DMI_EXACT_MATCH(DMI_BOARD_NAME, "XxHP4NAx"), 2137 }, 2138 .driver_data = &tux_featureset_3_descriptor, 2139 }, 2140 { 2141 .ident = "TUXEDO InfinityBook Pro 14/15 Gen10 AMD", 2142 .matches = { 2143 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2144 DMI_EXACT_MATCH(DMI_BOARD_NAME, "XxKK4NAx_XxSP4NAx"), 2145 }, 2146 .driver_data = &tux_featureset_3_descriptor, 2147 }, 2148 { 2149 .ident = "TUXEDO InfinityBook Pro 15 Gen10 Intel", 2150 .matches = { 2151 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2152 DMI_EXACT_MATCH(DMI_BOARD_NAME, "XxAR4NAx"), 2153 }, 2154 .driver_data = &tux_featureset_3_descriptor, 2155 }, 2156 { 2157 .ident = "TUXEDO InfinityBook Max 15 Gen10 AMD", 2158 .matches = { 2159 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2160 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X5KK45xS_X5SP45xS"), 2161 }, 2162 .driver_data = &tux_featureset_3_nvidia_descriptor, 2163 }, 2164 { 2165 .ident = "TUXEDO InfinityBook Max 16 Gen10 AMD", 2166 .matches = { 2167 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2168 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6HP45xU"), 2169 }, 2170 .driver_data = &tux_featureset_3_nvidia_descriptor, 2171 }, 2172 { 2173 .ident = "TUXEDO InfinityBook Max 16 Gen10 AMD", 2174 .matches = { 2175 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2176 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6KK45xU_X6SP45xU"), 2177 }, 2178 .driver_data = &tux_featureset_3_nvidia_descriptor, 2179 }, 2180 { 2181 .ident = "TUXEDO InfinityBook Max 15 Gen10 Intel", 2182 .matches = { 2183 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2184 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X5AR45xS"), 2185 }, 2186 .driver_data = &tux_featureset_3_nvidia_descriptor, 2187 }, 2188 { 2189 .ident = "TUXEDO InfinityBook Max 16 Gen10 Intel", 2190 .matches = { 2191 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2192 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6AR55xU"), 2193 }, 2194 .driver_data = &tux_featureset_3_nvidia_descriptor, 2195 }, 2196 { 2197 .ident = "TUXEDO Polaris 15 Gen1 AMD", 2198 .matches = { 2199 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2200 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1501A1650TI"), 2201 }, 2202 .driver_data = &tux_featureset_1_nvidia_descriptor, 2203 }, 2204 { 2205 .ident = "TUXEDO Polaris 15 Gen1 AMD", 2206 .matches = { 2207 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2208 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1501A2060"), 2209 }, 2210 .driver_data = &tux_featureset_1_nvidia_descriptor, 2211 }, 2212 { 2213 .ident = "TUXEDO Polaris 17 Gen1 AMD", 2214 .matches = { 2215 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2216 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1701A1650TI"), 2217 }, 2218 .driver_data = &tux_featureset_1_nvidia_descriptor, 2219 }, 2220 { 2221 .ident = "TUXEDO Polaris 17 Gen1 AMD", 2222 .matches = { 2223 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2224 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1701A2060"), 2225 }, 2226 .driver_data = &tux_featureset_1_nvidia_descriptor, 2227 }, 2228 { 2229 .ident = "TUXEDO Polaris 15 Gen1 Intel", 2230 .matches = { 2231 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2232 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1501I1650TI"), 2233 }, 2234 .driver_data = &tux_featureset_1_nvidia_descriptor, 2235 }, 2236 { 2237 .ident = "TUXEDO Polaris 15 Gen1 Intel", 2238 .matches = { 2239 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2240 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1501I2060"), 2241 }, 2242 .driver_data = &tux_featureset_1_nvidia_descriptor, 2243 }, 2244 { 2245 .ident = "TUXEDO Polaris 17 Gen1 Intel", 2246 .matches = { 2247 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2248 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1701I1650TI"), 2249 }, 2250 .driver_data = &tux_featureset_1_nvidia_descriptor, 2251 }, 2252 { 2253 .ident = "TUXEDO Polaris 17 Gen1 Intel", 2254 .matches = { 2255 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2256 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1701I2060"), 2257 }, 2258 .driver_data = &tux_featureset_1_nvidia_descriptor, 2259 }, 2260 { 2261 .ident = "TUXEDO Trinity 15 Intel Gen1", 2262 .matches = { 2263 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2264 DMI_EXACT_MATCH(DMI_BOARD_NAME, "TRINITY1501I"), 2265 }, 2266 .driver_data = &tux_featureset_1_nvidia_descriptor, 2267 }, 2268 { 2269 .ident = "TUXEDO Trinity 17 Intel Gen1", 2270 .matches = { 2271 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2272 DMI_EXACT_MATCH(DMI_BOARD_NAME, "TRINITY1701I"), 2273 }, 2274 .driver_data = &tux_featureset_1_nvidia_descriptor, 2275 }, 2276 { 2277 .ident = "TUXEDO Polaris 15/17 Gen2 AMD", 2278 .matches = { 2279 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2280 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxMGxx"), 2281 }, 2282 .driver_data = &tux_featureset_2_nvidia_descriptor, 2283 }, 2284 { 2285 .ident = "TUXEDO Polaris 15/17 Gen2 Intel", 2286 .matches = { 2287 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2288 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxNGxx"), 2289 }, 2290 .driver_data = &tux_featureset_2_nvidia_descriptor, 2291 }, 2292 { 2293 .ident = "TUXEDO Stellaris/Polaris 15/17 Gen3 AMD", 2294 .matches = { 2295 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2296 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxZGxx"), 2297 }, 2298 .driver_data = &tux_featureset_2_nvidia_descriptor, 2299 }, 2300 { 2301 .ident = "TUXEDO Stellaris/Polaris 15/17 Gen3 Intel", 2302 .matches = { 2303 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2304 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxTGxx"), 2305 }, 2306 .driver_data = &tux_featureset_2_nvidia_descriptor, 2307 }, 2308 { 2309 .ident = "TUXEDO Stellaris/Polaris 15/17 Gen4 AMD", 2310 .matches = { 2311 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2312 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxRGxx"), 2313 }, 2314 .driver_data = &tux_featureset_3_nvidia_descriptor, 2315 }, 2316 { 2317 .ident = "TUXEDO Stellaris 15 Gen4 Intel", 2318 .matches = { 2319 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2320 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxAGxx"), 2321 }, 2322 .driver_data = &tux_featureset_3_nvidia_descriptor, 2323 }, 2324 { 2325 .ident = "TUXEDO Polaris 15/17 Gen5 AMD", 2326 .matches = { 2327 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2328 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxXGxx"), 2329 }, 2330 .driver_data = &tux_featureset_2_nvidia_descriptor, 2331 }, 2332 { 2333 .ident = "TUXEDO Stellaris 16 Gen5 AMD", 2334 .matches = { 2335 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2336 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM6XGxX"), 2337 }, 2338 .driver_data = &tux_featureset_3_nvidia_descriptor, 2339 }, 2340 { 2341 .ident = "TUXEDO Stellaris 16/17 Gen5 Intel/Commodore ORION Gen 5", 2342 .matches = { 2343 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2344 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxPXxx"), 2345 }, 2346 .driver_data = &tux_featureset_3_nvidia_descriptor, 2347 }, 2348 { 2349 .ident = "TUXEDO Stellaris Slim 15 Gen6 AMD", 2350 .matches = { 2351 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2352 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxHGxx"), 2353 }, 2354 .driver_data = &tux_featureset_3_nvidia_descriptor, 2355 }, 2356 { 2357 .ident = "TUXEDO Stellaris Slim 15 Gen6 Intel/Commodore ORION Slim 15 Gen6", 2358 .matches = { 2359 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2360 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM5IXxA"), 2361 }, 2362 .driver_data = &tux_featureset_3_nvidia_descriptor, 2363 }, 2364 { 2365 .ident = "TUXEDO Stellaris 16 Gen6 Intel/Commodore ORION 16 Gen6", 2366 .matches = { 2367 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2368 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM6IXxB_MB1"), 2369 }, 2370 .driver_data = &tux_featureset_3_nvidia_descriptor, 2371 }, 2372 { 2373 .ident = "TUXEDO Stellaris 16 Gen6 Intel/Commodore ORION 16 Gen6", 2374 .matches = { 2375 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2376 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM6IXxB_MB2"), 2377 }, 2378 .driver_data = &tux_featureset_3_nvidia_descriptor, 2379 }, 2380 { 2381 .ident = "TUXEDO Stellaris 17 Gen6 Intel/Commodore ORION 17 Gen6", 2382 .matches = { 2383 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2384 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM7IXxN"), 2385 }, 2386 .driver_data = &tux_featureset_3_nvidia_descriptor, 2387 }, 2388 { 2389 .ident = "TUXEDO Stellaris 16 Gen7 AMD", 2390 .matches = { 2391 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2392 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6FR5xxY"), 2393 }, 2394 .driver_data = &tux_featureset_3_nvidia_descriptor, 2395 }, 2396 { 2397 .ident = "TUXEDO Stellaris 16 Gen7 Intel", 2398 .matches = { 2399 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2400 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6AR5xxY"), 2401 }, 2402 .driver_data = &tux_featureset_3_nvidia_descriptor, 2403 }, 2404 { 2405 .ident = "TUXEDO Stellaris 16 Gen7 Intel", 2406 .matches = { 2407 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2408 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6AR5xxY_mLED"), 2409 }, 2410 .driver_data = &tux_featureset_3_nvidia_descriptor, 2411 }, 2412 { 2413 .ident = "TUXEDO Book BA15 Gen10 AMD", 2414 .matches = { 2415 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2416 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PF5PU1G"), 2417 }, 2418 .driver_data = &pf5pu1g_descriptor, 2419 }, 2420 { 2421 .ident = "TUXEDO Pulse 14 Gen1 AMD", 2422 .matches = { 2423 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2424 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PULSE1401"), 2425 }, 2426 .driver_data = &tux_featureset_1_descriptor, 2427 }, 2428 { 2429 .ident = "TUXEDO Pulse 15 Gen1 AMD", 2430 .matches = { 2431 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2432 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PULSE1501"), 2433 }, 2434 .driver_data = &tux_featureset_1_descriptor, 2435 }, 2436 { 2437 .ident = "TUXEDO Pulse 15 Gen2 AMD", 2438 .matches = { 2439 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 2440 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PF5LUXG"), 2441 }, 2442 .driver_data = &tux_featureset_1_descriptor, 2443 }, 2444 { } 2445 }; 2446 MODULE_DEVICE_TABLE(dmi, uniwill_dmi_table); 2447 2448 static int __init uniwill_init(void) 2449 { 2450 const struct uniwill_device_descriptor *descriptor; 2451 const struct dmi_system_id *id; 2452 int ret; 2453 2454 id = dmi_first_match(uniwill_dmi_table); 2455 if (!id) { 2456 if (!force) 2457 return -ENODEV; 2458 2459 /* Assume that the device supports all features */ 2460 device_descriptor.features = UINT_MAX; 2461 pr_warn("Loading on a potentially unsupported device\n"); 2462 } else { 2463 /* 2464 * Some devices might support additional features depending on 2465 * the BIOS version/date, so we call this callback to let them 2466 * modify their device descriptor accordingly. 2467 */ 2468 if (id->callback) { 2469 ret = id->callback(id); 2470 if (ret < 0) 2471 return ret; 2472 } 2473 2474 descriptor = id->driver_data; 2475 device_descriptor = *descriptor; 2476 } 2477 2478 ret = platform_driver_register(&uniwill_driver); 2479 if (ret < 0) 2480 return ret; 2481 2482 ret = uniwill_wmi_register_driver(); 2483 if (ret < 0) { 2484 platform_driver_unregister(&uniwill_driver); 2485 return ret; 2486 } 2487 2488 return 0; 2489 } 2490 module_init(uniwill_init); 2491 2492 static void __exit uniwill_exit(void) 2493 { 2494 uniwill_wmi_unregister_driver(); 2495 platform_driver_unregister(&uniwill_driver); 2496 } 2497 module_exit(uniwill_exit); 2498 2499 MODULE_AUTHOR("Armin Wolf <W_Armin@gmx.de>"); 2500 MODULE_DESCRIPTION("Uniwill notebook driver"); 2501 MODULE_LICENSE("GPL"); 2502