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