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
uniwill_device_supports(const struct uniwill_data * data,unsigned int features)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
uniwill_ec_reg_write(void * context,unsigned int reg,unsigned int val)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
uniwill_ec_reg_read(void * context,unsigned int reg,unsigned int * val)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
uniwill_writeable_reg(struct device * dev,unsigned int reg)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
uniwill_readable_reg(struct device * dev,unsigned int reg)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
uniwill_volatile_reg(struct device * dev,unsigned int reg)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
fn_lock_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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
fn_lock_show(struct device * dev,struct device_attribute * attr,char * buf)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
super_key_enable_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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
super_key_enable_show(struct device * dev,struct device_attribute * attr,char * buf)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
touchpad_toggle_enable_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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
touchpad_toggle_enable_show(struct device * dev,struct device_attribute * attr,char * buf)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
rainbow_animation_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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
rainbow_animation_show(struct device * dev,struct device_attribute * attr,char * buf)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
breathing_in_suspend_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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
breathing_in_suspend_show(struct device * dev,struct device_attribute * attr,char * buf)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
ctgp_offset_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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
ctgp_offset_show(struct device * dev,struct device_attribute * attr,char * buf)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
uniwill_nvidia_ctgp_init(struct uniwill_data * data)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
usb_c_power_priority_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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
usb_c_power_priority_show(struct device * dev,struct device_attribute * attr,char * buf)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
usb_c_power_priority_restore(struct uniwill_data * data)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
usb_c_power_priority_init(struct uniwill_data * data)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
uniwill_attr_is_visible(struct kobject * kobj,struct attribute * attr,int n)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
uniwill_is_visible(const void * drvdata,enum hwmon_sensor_types type,u32 attr,int channel)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
uniwill_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * val)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
uniwill_read_string(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,const char ** str)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
uniwill_hwmon_init(struct uniwill_data * data)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
uniwill_led_brightness_set(struct led_classdev * led_cdev,enum led_brightness brightness)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
uniwill_led_init(struct uniwill_data * data)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
uniwill_sanitize_battery_threshold(unsigned int value)1362 static unsigned int uniwill_sanitize_battery_threshold(unsigned int value)
1363 {
1364 /* 0 means "charging threshold not active" */
1365 if (!value)
1366 return 100;
1367
1368 /* Guard against invalid values */
1369 return min(value, 100);
1370 }
1371
uniwill_get_property(struct power_supply * psy,const struct power_supply_ext * ext,void * drvdata,enum power_supply_property psp,union power_supply_propval * val)1372 static int uniwill_get_property(struct power_supply *psy, const struct power_supply_ext *ext,
1373 void *drvdata, enum power_supply_property psp,
1374 union power_supply_propval *val)
1375 {
1376 struct uniwill_data *data = drvdata;
1377 union power_supply_propval prop;
1378 unsigned int regval;
1379 int ret;
1380
1381 switch (psp) {
1382 case POWER_SUPPLY_PROP_HEALTH:
1383 ret = power_supply_get_property_direct(psy, POWER_SUPPLY_PROP_PRESENT, &prop);
1384 if (ret < 0)
1385 return ret;
1386
1387 if (!prop.intval) {
1388 val->intval = POWER_SUPPLY_HEALTH_NO_BATTERY;
1389 return 0;
1390 }
1391
1392 ret = power_supply_get_property_direct(psy, POWER_SUPPLY_PROP_STATUS, &prop);
1393 if (ret < 0)
1394 return ret;
1395
1396 if (prop.intval == POWER_SUPPLY_STATUS_UNKNOWN) {
1397 val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
1398 return 0;
1399 }
1400
1401 ret = regmap_read(data->regmap, EC_ADDR_BAT_ALERT, ®val);
1402 if (ret < 0)
1403 return ret;
1404
1405 if (regval) {
1406 /* Charging issue */
1407 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
1408 return 0;
1409 }
1410
1411 val->intval = POWER_SUPPLY_HEALTH_GOOD;
1412 return 0;
1413 case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD:
1414 ret = regmap_read(data->regmap, EC_ADDR_CHARGE_CTRL, ®val);
1415 if (ret < 0)
1416 return ret;
1417
1418 regval = FIELD_GET(CHARGE_CTRL_MASK, regval);
1419 val->intval = uniwill_sanitize_battery_threshold(regval);
1420 return 0;
1421 default:
1422 return -EINVAL;
1423 }
1424 }
1425
uniwill_set_property(struct power_supply * psy,const struct power_supply_ext * ext,void * drvdata,enum power_supply_property psp,const union power_supply_propval * val)1426 static int uniwill_set_property(struct power_supply *psy, const struct power_supply_ext *ext,
1427 void *drvdata, enum power_supply_property psp,
1428 const union power_supply_propval *val)
1429 {
1430 struct uniwill_data *data = drvdata;
1431
1432 switch (psp) {
1433 case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD:
1434 if (val->intval < 0 || val->intval > 100)
1435 return -EINVAL;
1436
1437 return regmap_update_bits(data->regmap, EC_ADDR_CHARGE_CTRL, CHARGE_CTRL_MASK,
1438 max(val->intval, 1));
1439 default:
1440 return -EINVAL;
1441 }
1442 }
1443
uniwill_property_is_writeable(struct power_supply * psy,const struct power_supply_ext * ext,void * drvdata,enum power_supply_property psp)1444 static int uniwill_property_is_writeable(struct power_supply *psy,
1445 const struct power_supply_ext *ext, void *drvdata,
1446 enum power_supply_property psp)
1447 {
1448 if (psp == POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD)
1449 return true;
1450
1451 return false;
1452 }
1453
1454 static const enum power_supply_property uniwill_properties[] = {
1455 POWER_SUPPLY_PROP_HEALTH,
1456 POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD,
1457 };
1458
1459 static const struct power_supply_ext uniwill_extension = {
1460 .name = DRIVER_NAME,
1461 .properties = uniwill_properties,
1462 .num_properties = ARRAY_SIZE(uniwill_properties),
1463 .get_property = uniwill_get_property,
1464 .set_property = uniwill_set_property,
1465 .property_is_writeable = uniwill_property_is_writeable,
1466 };
1467
uniwill_add_battery(struct power_supply * battery,struct acpi_battery_hook * hook)1468 static int uniwill_add_battery(struct power_supply *battery, struct acpi_battery_hook *hook)
1469 {
1470 struct uniwill_data *data = container_of(hook, struct uniwill_data, hook);
1471 struct uniwill_battery_entry *entry;
1472 int ret;
1473
1474 entry = kzalloc_obj(*entry);
1475 if (!entry)
1476 return -ENOMEM;
1477
1478 ret = power_supply_register_extension(battery, &uniwill_extension, data->dev, data);
1479 if (ret < 0) {
1480 kfree(entry);
1481 return ret;
1482 }
1483
1484 guard(mutex)(&data->battery_lock);
1485
1486 entry->battery = battery;
1487 list_add(&entry->head, &data->batteries);
1488
1489 return 0;
1490 }
1491
uniwill_remove_battery(struct power_supply * battery,struct acpi_battery_hook * hook)1492 static int uniwill_remove_battery(struct power_supply *battery, struct acpi_battery_hook *hook)
1493 {
1494 struct uniwill_data *data = container_of(hook, struct uniwill_data, hook);
1495 struct uniwill_battery_entry *entry, *tmp;
1496
1497 scoped_guard(mutex, &data->battery_lock) {
1498 list_for_each_entry_safe(entry, tmp, &data->batteries, head) {
1499 if (entry->battery == battery) {
1500 list_del(&entry->head);
1501 kfree(entry);
1502 break;
1503 }
1504 }
1505 }
1506
1507 power_supply_unregister_extension(battery, &uniwill_extension);
1508
1509 return 0;
1510 }
1511
uniwill_battery_init(struct uniwill_data * data)1512 static int uniwill_battery_init(struct uniwill_data *data)
1513 {
1514 unsigned int value, threshold, sanitized;
1515 int ret;
1516
1517 if (!uniwill_device_supports(data, UNIWILL_FEATURE_BATTERY))
1518 return 0;
1519
1520 ret = regmap_read(data->regmap, EC_ADDR_CHARGE_CTRL, &value);
1521 if (ret < 0)
1522 return ret;
1523
1524 /*
1525 * The charge control threshold might be initialized with 0 by
1526 * the EC to signal that said threshold is uninitialized. We thus
1527 * need to replace this placeholder value with a valid one (100)
1528 * to signal that we want to take control of battery charging.
1529 * For the sake of completeness we also apply this to other
1530 * invalid threshold values.
1531 */
1532 threshold = FIELD_GET(CHARGE_CTRL_MASK, value);
1533 sanitized = uniwill_sanitize_battery_threshold(threshold);
1534 if (threshold != sanitized) {
1535 FIELD_MODIFY(CHARGE_CTRL_MASK, &value, sanitized);
1536 ret = regmap_write(data->regmap, EC_ADDR_CHARGE_CTRL, value);
1537 if (ret < 0)
1538 return ret;
1539 }
1540
1541 ret = devm_mutex_init(data->dev, &data->battery_lock);
1542 if (ret < 0)
1543 return ret;
1544
1545 INIT_LIST_HEAD(&data->batteries);
1546 data->hook.name = "Uniwill Battery Extension";
1547 data->hook.add_battery = uniwill_add_battery;
1548 data->hook.remove_battery = uniwill_remove_battery;
1549
1550 return devm_battery_hook_register(data->dev, &data->hook);
1551 }
1552
uniwill_notifier_call(struct notifier_block * nb,unsigned long action,void * dummy)1553 static int uniwill_notifier_call(struct notifier_block *nb, unsigned long action, void *dummy)
1554 {
1555 struct uniwill_data *data = container_of(nb, struct uniwill_data, nb);
1556 struct uniwill_battery_entry *entry;
1557
1558 switch (action) {
1559 case UNIWILL_OSD_BATTERY_ALERT:
1560 if (!uniwill_device_supports(data, UNIWILL_FEATURE_BATTERY))
1561 return NOTIFY_DONE;
1562
1563 mutex_lock(&data->battery_lock);
1564 list_for_each_entry(entry, &data->batteries, head) {
1565 power_supply_changed(entry->battery);
1566 }
1567 mutex_unlock(&data->battery_lock);
1568
1569 return NOTIFY_OK;
1570 case UNIWILL_OSD_DC_ADAPTER_CHANGED:
1571 if (!uniwill_device_supports(data, UNIWILL_FEATURE_USB_C_POWER_PRIORITY))
1572 return NOTIFY_DONE;
1573
1574 return notifier_from_errno(usb_c_power_priority_restore(data));
1575 case UNIWILL_OSD_FN_LOCK:
1576 if (!uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK))
1577 return NOTIFY_DONE;
1578
1579 sysfs_notify(&data->dev->kobj, NULL, "fn_lock");
1580
1581 return NOTIFY_OK;
1582 default:
1583 mutex_lock(&data->input_lock);
1584 sparse_keymap_report_event(data->input_device, action, 1, true);
1585 mutex_unlock(&data->input_lock);
1586
1587 return NOTIFY_OK;
1588 }
1589 }
1590
uniwill_input_init(struct uniwill_data * data)1591 static int uniwill_input_init(struct uniwill_data *data)
1592 {
1593 int ret;
1594
1595 ret = devm_mutex_init(data->dev, &data->input_lock);
1596 if (ret < 0)
1597 return ret;
1598
1599 data->input_device = devm_input_allocate_device(data->dev);
1600 if (!data->input_device)
1601 return -ENOMEM;
1602
1603 ret = sparse_keymap_setup(data->input_device, uniwill_keymap, NULL);
1604 if (ret < 0)
1605 return ret;
1606
1607 data->input_device->name = "Uniwill WMI hotkeys";
1608 data->input_device->phys = "wmi/input0";
1609 data->input_device->id.bustype = BUS_HOST;
1610 ret = input_register_device(data->input_device);
1611 if (ret < 0)
1612 return ret;
1613
1614 data->nb.notifier_call = uniwill_notifier_call;
1615
1616 return devm_uniwill_wmi_register_notifier(data->dev, &data->nb);
1617 }
1618
uniwill_disable_manual_control(void * context)1619 static void uniwill_disable_manual_control(void *context)
1620 {
1621 struct uniwill_data *data = context;
1622
1623 regmap_clear_bits(data->regmap, EC_ADDR_AP_OEM, ENABLE_MANUAL_CTRL);
1624 }
1625
uniwill_ec_init(struct uniwill_data * data)1626 static int uniwill_ec_init(struct uniwill_data *data)
1627 {
1628 unsigned int value;
1629 int ret;
1630
1631 ret = regmap_read(data->regmap, EC_ADDR_PROJECT_ID, &value);
1632 if (ret < 0)
1633 return ret;
1634
1635 dev_dbg(data->dev, "Project ID: %u\n", value);
1636
1637 ret = regmap_set_bits(data->regmap, EC_ADDR_AP_OEM, ENABLE_MANUAL_CTRL);
1638 if (ret < 0)
1639 return ret;
1640
1641 return devm_add_action_or_reset(data->dev, uniwill_disable_manual_control, data);
1642 }
1643
uniwill_probe(struct platform_device * pdev)1644 static int uniwill_probe(struct platform_device *pdev)
1645 {
1646 struct uniwill_data *data;
1647 struct regmap *regmap;
1648 acpi_handle handle;
1649 int ret;
1650
1651 handle = ACPI_HANDLE(&pdev->dev);
1652 if (!handle)
1653 return -ENODEV;
1654
1655 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
1656 if (!data)
1657 return -ENOMEM;
1658
1659 data->dev = &pdev->dev;
1660 data->handle = handle;
1661 platform_set_drvdata(pdev, data);
1662
1663 regmap = devm_regmap_init(&pdev->dev, &uniwill_ec_bus, data, &uniwill_ec_config);
1664 if (IS_ERR(regmap))
1665 return PTR_ERR(regmap);
1666
1667 data->regmap = regmap;
1668
1669 ret = devm_mutex_init(&pdev->dev, &data->super_key_lock);
1670 if (ret < 0)
1671 return ret;
1672
1673 ret = uniwill_ec_init(data);
1674 if (ret < 0)
1675 return ret;
1676
1677 data->features = device_descriptor.features;
1678
1679 /*
1680 * Some devices might need to perform some device-specific initialization steps
1681 * before the supported features are initialized. Because of this we have to call
1682 * this callback just after the EC itself was initialized.
1683 */
1684 if (device_descriptor.probe) {
1685 ret = device_descriptor.probe(data);
1686 if (ret < 0)
1687 return ret;
1688 }
1689
1690 ret = uniwill_battery_init(data);
1691 if (ret < 0)
1692 return ret;
1693
1694 ret = uniwill_led_init(data);
1695 if (ret < 0)
1696 return ret;
1697
1698 ret = uniwill_hwmon_init(data);
1699 if (ret < 0)
1700 return ret;
1701
1702 ret = uniwill_nvidia_ctgp_init(data);
1703 if (ret < 0)
1704 return ret;
1705
1706 ret = usb_c_power_priority_init(data);
1707 if (ret < 0)
1708 return ret;
1709
1710 return uniwill_input_init(data);
1711 }
1712
uniwill_shutdown(struct platform_device * pdev)1713 static void uniwill_shutdown(struct platform_device *pdev)
1714 {
1715 struct uniwill_data *data = platform_get_drvdata(pdev);
1716
1717 regmap_clear_bits(data->regmap, EC_ADDR_AP_OEM, ENABLE_MANUAL_CTRL);
1718 }
1719
uniwill_suspend_fn_lock(struct uniwill_data * data)1720 static int uniwill_suspend_fn_lock(struct uniwill_data *data)
1721 {
1722 if (!uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK))
1723 return 0;
1724
1725 /*
1726 * The EC_ADDR_BIOS_OEM is marked as volatile, so we have to restore it
1727 * ourselves.
1728 */
1729 return regmap_read(data->regmap, EC_ADDR_BIOS_OEM, &data->last_status);
1730 }
1731
uniwill_suspend_super_key(struct uniwill_data * data)1732 static int uniwill_suspend_super_key(struct uniwill_data *data)
1733 {
1734 if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY))
1735 return 0;
1736
1737 /*
1738 * The EC_ADDR_SWITCH_STATUS is marked as volatile, so we have to restore it
1739 * ourselves.
1740 */
1741 return regmap_read(data->regmap, EC_ADDR_SWITCH_STATUS, &data->last_switch_status);
1742 }
1743
uniwill_suspend_battery(struct uniwill_data * data)1744 static int uniwill_suspend_battery(struct uniwill_data *data)
1745 {
1746 if (!uniwill_device_supports(data, UNIWILL_FEATURE_BATTERY))
1747 return 0;
1748
1749 /*
1750 * Save the current charge limit in order to restore it during resume.
1751 * We cannot use the regmap code for that since this register needs to
1752 * be declared as volatile due to CHARGE_CTRL_REACHED.
1753 */
1754 return regmap_read(data->regmap, EC_ADDR_CHARGE_CTRL, &data->last_charge_ctrl);
1755 }
1756
uniwill_suspend_nvidia_ctgp(struct uniwill_data * data)1757 static int uniwill_suspend_nvidia_ctgp(struct uniwill_data *data)
1758 {
1759 if (!uniwill_device_supports(data, UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL))
1760 return 0;
1761
1762 return regmap_clear_bits(data->regmap, EC_ADDR_CTGP_DB_CTRL,
1763 CTGP_DB_DB_ENABLE | CTGP_DB_CTGP_ENABLE);
1764 }
1765
uniwill_suspend(struct device * dev)1766 static int uniwill_suspend(struct device *dev)
1767 {
1768 struct uniwill_data *data = dev_get_drvdata(dev);
1769 int ret;
1770
1771 ret = uniwill_suspend_fn_lock(data);
1772 if (ret < 0)
1773 return ret;
1774
1775 ret = uniwill_suspend_super_key(data);
1776 if (ret < 0)
1777 return ret;
1778
1779 ret = uniwill_suspend_battery(data);
1780 if (ret < 0)
1781 return ret;
1782
1783 ret = uniwill_suspend_nvidia_ctgp(data);
1784 if (ret < 0)
1785 return ret;
1786
1787 regcache_cache_only(data->regmap, true);
1788 regcache_mark_dirty(data->regmap);
1789
1790 return 0;
1791 }
1792
uniwill_resume_fn_lock(struct uniwill_data * data)1793 static int uniwill_resume_fn_lock(struct uniwill_data *data)
1794 {
1795 if (!uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK))
1796 return 0;
1797
1798 return regmap_update_bits(data->regmap, EC_ADDR_BIOS_OEM, FN_LOCK_STATUS,
1799 data->last_status);
1800 }
1801
uniwill_resume_super_key(struct uniwill_data * data)1802 static int uniwill_resume_super_key(struct uniwill_data *data)
1803 {
1804 unsigned int value;
1805 int ret;
1806
1807 if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY))
1808 return 0;
1809
1810 ret = regmap_read(data->regmap, EC_ADDR_SWITCH_STATUS, &value);
1811 if (ret < 0)
1812 return ret;
1813
1814 if ((data->last_switch_status & SUPER_KEY_LOCK_STATUS) == (value & SUPER_KEY_LOCK_STATUS))
1815 return 0;
1816
1817 return regmap_write_bits(data->regmap, EC_ADDR_TRIGGER, TRIGGER_SUPER_KEY_LOCK,
1818 TRIGGER_SUPER_KEY_LOCK);
1819 }
1820
uniwill_resume_battery(struct uniwill_data * data)1821 static int uniwill_resume_battery(struct uniwill_data *data)
1822 {
1823 if (!uniwill_device_supports(data, UNIWILL_FEATURE_BATTERY))
1824 return 0;
1825
1826 return regmap_update_bits(data->regmap, EC_ADDR_CHARGE_CTRL, CHARGE_CTRL_MASK,
1827 data->last_charge_ctrl);
1828 }
1829
uniwill_resume_nvidia_ctgp(struct uniwill_data * data)1830 static int uniwill_resume_nvidia_ctgp(struct uniwill_data *data)
1831 {
1832 if (!uniwill_device_supports(data, UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL))
1833 return 0;
1834
1835 return regmap_set_bits(data->regmap, EC_ADDR_CTGP_DB_CTRL,
1836 CTGP_DB_DB_ENABLE | CTGP_DB_CTGP_ENABLE);
1837 }
1838
uniwill_resume_usb_c_power_priority(struct uniwill_data * data)1839 static int uniwill_resume_usb_c_power_priority(struct uniwill_data *data)
1840 {
1841 if (!uniwill_device_supports(data, UNIWILL_FEATURE_USB_C_POWER_PRIORITY))
1842 return 0;
1843
1844 return usb_c_power_priority_restore(data);
1845 }
1846
uniwill_resume(struct device * dev)1847 static int uniwill_resume(struct device *dev)
1848 {
1849 struct uniwill_data *data = dev_get_drvdata(dev);
1850 int ret;
1851
1852 regcache_cache_only(data->regmap, false);
1853
1854 ret = regcache_sync(data->regmap);
1855 if (ret < 0)
1856 return ret;
1857
1858 ret = uniwill_resume_fn_lock(data);
1859 if (ret < 0)
1860 return ret;
1861
1862 ret = uniwill_resume_super_key(data);
1863 if (ret < 0)
1864 return ret;
1865
1866 ret = uniwill_resume_battery(data);
1867 if (ret < 0)
1868 return ret;
1869
1870 ret = uniwill_resume_nvidia_ctgp(data);
1871 if (ret < 0)
1872 return ret;
1873
1874 return uniwill_resume_usb_c_power_priority(data);
1875 }
1876
1877 static DEFINE_SIMPLE_DEV_PM_OPS(uniwill_pm_ops, uniwill_suspend, uniwill_resume);
1878
1879 /*
1880 * We only use the DMI table for auoloading because the ACPI device itself
1881 * does not guarantee that the underlying EC implementation is supported.
1882 */
1883 static const struct acpi_device_id uniwill_id_table[] = {
1884 { "INOU0000" },
1885 { },
1886 };
1887
1888 static struct platform_driver uniwill_driver = {
1889 .driver = {
1890 .name = DRIVER_NAME,
1891 .dev_groups = uniwill_groups,
1892 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
1893 .acpi_match_table = uniwill_id_table,
1894 .pm = pm_sleep_ptr(&uniwill_pm_ops),
1895 },
1896 .probe = uniwill_probe,
1897 .shutdown = uniwill_shutdown,
1898 };
1899
1900 static struct uniwill_device_descriptor lapqc71a_lapqc71b_descriptor __initdata = {
1901 .features = UNIWILL_FEATURE_SUPER_KEY |
1902 UNIWILL_FEATURE_BATTERY |
1903 UNIWILL_FEATURE_CPU_TEMP |
1904 UNIWILL_FEATURE_GPU_TEMP |
1905 UNIWILL_FEATURE_PRIMARY_FAN |
1906 UNIWILL_FEATURE_SECONDARY_FAN,
1907 };
1908
1909 static struct uniwill_device_descriptor lapac71h_descriptor __initdata = {
1910 .features = UNIWILL_FEATURE_FN_LOCK |
1911 UNIWILL_FEATURE_SUPER_KEY |
1912 UNIWILL_FEATURE_TOUCHPAD_TOGGLE |
1913 UNIWILL_FEATURE_BATTERY |
1914 UNIWILL_FEATURE_CPU_TEMP |
1915 UNIWILL_FEATURE_GPU_TEMP |
1916 UNIWILL_FEATURE_PRIMARY_FAN |
1917 UNIWILL_FEATURE_SECONDARY_FAN,
1918 };
1919
1920 static struct uniwill_device_descriptor lapkc71f_descriptor __initdata = {
1921 .features = UNIWILL_FEATURE_FN_LOCK |
1922 UNIWILL_FEATURE_SUPER_KEY |
1923 UNIWILL_FEATURE_TOUCHPAD_TOGGLE |
1924 UNIWILL_FEATURE_LIGHTBAR |
1925 UNIWILL_FEATURE_BATTERY |
1926 UNIWILL_FEATURE_CPU_TEMP |
1927 UNIWILL_FEATURE_GPU_TEMP |
1928 UNIWILL_FEATURE_PRIMARY_FAN |
1929 UNIWILL_FEATURE_SECONDARY_FAN,
1930 };
1931
1932 /*
1933 * The featuresets below reflect somewhat chronological changes:
1934 * 1 -> 2: UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL is added to the EC firmware.
1935 * 2 -> 3: UNIWILL_FEATURE_USB_C_POWER_PRIORITY is removed from the EC firmware.
1936 * Some devices might divert from this timeline.
1937 */
1938
1939 static struct uniwill_device_descriptor tux_featureset_1_descriptor __initdata = {
1940 .features = UNIWILL_FEATURE_FN_LOCK |
1941 UNIWILL_FEATURE_SUPER_KEY |
1942 UNIWILL_FEATURE_CPU_TEMP |
1943 UNIWILL_FEATURE_PRIMARY_FAN |
1944 UNIWILL_FEATURE_SECONDARY_FAN |
1945 UNIWILL_FEATURE_USB_C_POWER_PRIORITY,
1946 };
1947
1948 static struct uniwill_device_descriptor tux_featureset_1_nvidia_descriptor __initdata = {
1949 .features = UNIWILL_FEATURE_FN_LOCK |
1950 UNIWILL_FEATURE_SUPER_KEY |
1951 UNIWILL_FEATURE_CPU_TEMP |
1952 UNIWILL_FEATURE_GPU_TEMP |
1953 UNIWILL_FEATURE_PRIMARY_FAN |
1954 UNIWILL_FEATURE_SECONDARY_FAN |
1955 UNIWILL_FEATURE_USB_C_POWER_PRIORITY,
1956 };
1957
1958 static struct uniwill_device_descriptor tux_featureset_2_nvidia_descriptor __initdata = {
1959 .features = UNIWILL_FEATURE_FN_LOCK |
1960 UNIWILL_FEATURE_SUPER_KEY |
1961 UNIWILL_FEATURE_CPU_TEMP |
1962 UNIWILL_FEATURE_GPU_TEMP |
1963 UNIWILL_FEATURE_PRIMARY_FAN |
1964 UNIWILL_FEATURE_SECONDARY_FAN |
1965 UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL |
1966 UNIWILL_FEATURE_USB_C_POWER_PRIORITY,
1967 };
1968
1969 static struct uniwill_device_descriptor tux_featureset_3_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_SECONDARY_FAN,
1975 };
1976
1977 static struct uniwill_device_descriptor tux_featureset_3_nvidia_descriptor __initdata = {
1978 .features = UNIWILL_FEATURE_FN_LOCK |
1979 UNIWILL_FEATURE_SUPER_KEY |
1980 UNIWILL_FEATURE_CPU_TEMP |
1981 UNIWILL_FEATURE_GPU_TEMP |
1982 UNIWILL_FEATURE_PRIMARY_FAN |
1983 UNIWILL_FEATURE_SECONDARY_FAN |
1984 UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL,
1985 };
1986
phxtxx1_probe(struct uniwill_data * data)1987 static int phxtxx1_probe(struct uniwill_data *data)
1988 {
1989 unsigned int value;
1990 int ret;
1991
1992 ret = regmap_read(data->regmap, EC_ADDR_PROJECT_ID, &value);
1993 if (ret < 0)
1994 return ret;
1995
1996 if (value == PROJECT_ID_PH4TRX1 || value == PROJECT_ID_PH6TRX1)
1997 data->features |= UNIWILL_FEATURE_SECONDARY_FAN;
1998
1999 return 0;
2000 };
2001
2002 static struct uniwill_device_descriptor phxtxx1_descriptor __initdata = {
2003 .features = UNIWILL_FEATURE_FN_LOCK |
2004 UNIWILL_FEATURE_SUPER_KEY |
2005 UNIWILL_FEATURE_CPU_TEMP |
2006 UNIWILL_FEATURE_PRIMARY_FAN |
2007 UNIWILL_FEATURE_USB_C_POWER_PRIORITY,
2008 .probe = phxtxx1_probe,
2009 };
2010
phxarx1_phxaqf1_probe(struct uniwill_data * data)2011 static int phxarx1_phxaqf1_probe(struct uniwill_data *data)
2012 {
2013 unsigned int value;
2014 int ret;
2015
2016 ret = regmap_read(data->regmap, EC_ADDR_SYSTEM_ID, &value);
2017 if (ret < 0)
2018 return ret;
2019
2020 if (value & HAS_GPU)
2021 data->features |= UNIWILL_FEATURE_GPU_TEMP |
2022 UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL;
2023
2024 return 0;
2025 };
2026
2027 static struct uniwill_device_descriptor phxarx1_phxaqf1_descriptor __initdata = {
2028 .features = UNIWILL_FEATURE_FN_LOCK |
2029 UNIWILL_FEATURE_SUPER_KEY |
2030 UNIWILL_FEATURE_CPU_TEMP |
2031 UNIWILL_FEATURE_PRIMARY_FAN |
2032 UNIWILL_FEATURE_SECONDARY_FAN |
2033 UNIWILL_FEATURE_USB_C_POWER_PRIORITY,
2034 .probe = phxarx1_phxaqf1_probe,
2035 };
2036
2037 static struct uniwill_device_descriptor pf5pu1g_descriptor __initdata = {
2038 .features = UNIWILL_FEATURE_FN_LOCK |
2039 UNIWILL_FEATURE_SUPER_KEY |
2040 UNIWILL_FEATURE_CPU_TEMP |
2041 UNIWILL_FEATURE_PRIMARY_FAN,
2042 };
2043
2044 static const struct dmi_system_id uniwill_dmi_table[] __initconst = {
2045 {
2046 .ident = "XMG FUSION 15 (L19)",
2047 .matches = {
2048 DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"),
2049 DMI_EXACT_MATCH(DMI_BOARD_NAME, "LAPQC71A"),
2050 },
2051 .driver_data = &lapqc71a_lapqc71b_descriptor,
2052 },
2053 {
2054 .ident = "XMG FUSION 15 (L19)",
2055 .matches = {
2056 DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"),
2057 DMI_EXACT_MATCH(DMI_BOARD_NAME, "LAPQC71B"),
2058 },
2059 .driver_data = &lapqc71a_lapqc71b_descriptor,
2060 },
2061 {
2062 .ident = "XMG FUSION 15 (L19)",
2063 .matches = {
2064 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2065 DMI_EXACT_MATCH(DMI_BOARD_NAME, "LAPQC71A"),
2066 },
2067 .driver_data = &lapqc71a_lapqc71b_descriptor,
2068 },
2069 {
2070 .ident = "XMG FUSION 15 (L19)",
2071 .matches = {
2072 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2073 DMI_EXACT_MATCH(DMI_BOARD_NAME, "LAPQC71B"),
2074 },
2075 .driver_data = &lapqc71a_lapqc71b_descriptor,
2076 },
2077 {
2078 .ident = "Intel NUC x15",
2079 .matches = {
2080 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"),
2081 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LAPAC71H"),
2082 },
2083 .driver_data = &lapac71h_descriptor,
2084 },
2085 {
2086 .ident = "Intel NUC x15",
2087 .matches = {
2088 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"),
2089 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LAPKC71F"),
2090 },
2091 .driver_data = &lapkc71f_descriptor,
2092 },
2093 {
2094 .ident = "TUXEDO InfinityBook Pro 14 Gen6 Intel",
2095 .matches = {
2096 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2097 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PHxTxX1"),
2098 },
2099 .driver_data = &phxtxx1_descriptor,
2100 },
2101 {
2102 .ident = "TUXEDO InfinityBook Pro 14 Gen6 Intel",
2103 .matches = {
2104 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2105 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PHxTQx1"),
2106 },
2107 .driver_data = &tux_featureset_2_nvidia_descriptor,
2108 },
2109 {
2110 .ident = "TUXEDO InfinityBook Pro 14/16 Gen7 Intel",
2111 .matches = {
2112 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2113 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PHxARX1_PHxAQF1"),
2114 },
2115 .driver_data = &phxarx1_phxaqf1_descriptor,
2116 },
2117 {
2118 .ident = "TUXEDO InfinityBook Pro 16 Gen7 Intel/Commodore Omnia-Book Pro Gen 7",
2119 .matches = {
2120 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2121 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PH6AG01_PH6AQ71_PH6AQI1"),
2122 },
2123 .driver_data = &tux_featureset_2_nvidia_descriptor,
2124 },
2125 {
2126 .ident = "TUXEDO InfinityBook Pro 14/16 Gen8 Intel/Commodore Omnia-Book Pro Gen 8",
2127 .matches = {
2128 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2129 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PH4PRX1_PH6PRX1"),
2130 },
2131 .driver_data = &tux_featureset_1_descriptor,
2132 },
2133 {
2134 .ident = "TUXEDO InfinityBook Pro 14 Gen8 Intel/Commodore Omnia-Book Pro Gen 8",
2135 .matches = {
2136 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2137 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PH4PG31"),
2138 },
2139 .driver_data = &tux_featureset_2_nvidia_descriptor,
2140 },
2141 {
2142 .ident = "TUXEDO InfinityBook Pro 16 Gen8 Intel",
2143 .matches = {
2144 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2145 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PH6PG01_PH6PG71"),
2146 },
2147 .driver_data = &tux_featureset_2_nvidia_descriptor,
2148 },
2149 {
2150 .ident = "TUXEDO InfinityBook Pro 14/15 Gen9 AMD",
2151 .matches = {
2152 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2153 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GXxHRXx"),
2154 },
2155 .driver_data = &tux_featureset_3_descriptor,
2156 },
2157 {
2158 .ident = "TUXEDO InfinityBook Pro 14/15 Gen9 Intel/Commodore Omnia-Book 15 Gen9",
2159 .matches = {
2160 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2161 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GXxMRXx"),
2162 },
2163 .driver_data = &tux_featureset_3_descriptor,
2164 },
2165 {
2166 .ident = "TUXEDO InfinityBook Pro 14/15 Gen10 AMD",
2167 .matches = {
2168 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2169 DMI_EXACT_MATCH(DMI_BOARD_NAME, "XxHP4NAx"),
2170 },
2171 .driver_data = &tux_featureset_3_descriptor,
2172 },
2173 {
2174 .ident = "TUXEDO InfinityBook Pro 14/15 Gen10 AMD",
2175 .matches = {
2176 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2177 DMI_EXACT_MATCH(DMI_BOARD_NAME, "XxKK4NAx_XxSP4NAx"),
2178 },
2179 .driver_data = &tux_featureset_3_descriptor,
2180 },
2181 {
2182 .ident = "TUXEDO InfinityBook Pro 15 Gen10 Intel",
2183 .matches = {
2184 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2185 DMI_EXACT_MATCH(DMI_BOARD_NAME, "XxAR4NAx"),
2186 },
2187 .driver_data = &tux_featureset_3_descriptor,
2188 },
2189 {
2190 .ident = "TUXEDO InfinityBook Max 15 Gen10 AMD",
2191 .matches = {
2192 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2193 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X5KK45xS_X5SP45xS"),
2194 },
2195 .driver_data = &tux_featureset_3_nvidia_descriptor,
2196 },
2197 {
2198 .ident = "TUXEDO InfinityBook Max 16 Gen10 AMD",
2199 .matches = {
2200 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2201 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6HP45xU"),
2202 },
2203 .driver_data = &tux_featureset_3_nvidia_descriptor,
2204 },
2205 {
2206 .ident = "TUXEDO InfinityBook Max 16 Gen10 AMD",
2207 .matches = {
2208 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2209 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6KK45xU_X6SP45xU"),
2210 },
2211 .driver_data = &tux_featureset_3_nvidia_descriptor,
2212 },
2213 {
2214 .ident = "TUXEDO InfinityBook Max 15 Gen10 Intel",
2215 .matches = {
2216 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2217 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X5AR45xS"),
2218 },
2219 .driver_data = &tux_featureset_3_nvidia_descriptor,
2220 },
2221 {
2222 .ident = "TUXEDO InfinityBook Max 16 Gen10 Intel",
2223 .matches = {
2224 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2225 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6AR55xU"),
2226 },
2227 .driver_data = &tux_featureset_3_nvidia_descriptor,
2228 },
2229 {
2230 .ident = "TUXEDO Polaris 15 Gen1 AMD",
2231 .matches = {
2232 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2233 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1501A1650TI"),
2234 },
2235 .driver_data = &tux_featureset_1_nvidia_descriptor,
2236 },
2237 {
2238 .ident = "TUXEDO Polaris 15 Gen1 AMD",
2239 .matches = {
2240 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2241 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1501A2060"),
2242 },
2243 .driver_data = &tux_featureset_1_nvidia_descriptor,
2244 },
2245 {
2246 .ident = "TUXEDO Polaris 17 Gen1 AMD",
2247 .matches = {
2248 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2249 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1701A1650TI"),
2250 },
2251 .driver_data = &tux_featureset_1_nvidia_descriptor,
2252 },
2253 {
2254 .ident = "TUXEDO Polaris 17 Gen1 AMD",
2255 .matches = {
2256 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2257 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1701A2060"),
2258 },
2259 .driver_data = &tux_featureset_1_nvidia_descriptor,
2260 },
2261 {
2262 .ident = "TUXEDO Polaris 15 Gen1 Intel",
2263 .matches = {
2264 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2265 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1501I1650TI"),
2266 },
2267 .driver_data = &tux_featureset_1_nvidia_descriptor,
2268 },
2269 {
2270 .ident = "TUXEDO Polaris 15 Gen1 Intel",
2271 .matches = {
2272 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2273 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1501I2060"),
2274 },
2275 .driver_data = &tux_featureset_1_nvidia_descriptor,
2276 },
2277 {
2278 .ident = "TUXEDO Polaris 17 Gen1 Intel",
2279 .matches = {
2280 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2281 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1701I1650TI"),
2282 },
2283 .driver_data = &tux_featureset_1_nvidia_descriptor,
2284 },
2285 {
2286 .ident = "TUXEDO Polaris 17 Gen1 Intel",
2287 .matches = {
2288 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2289 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1701I2060"),
2290 },
2291 .driver_data = &tux_featureset_1_nvidia_descriptor,
2292 },
2293 {
2294 .ident = "TUXEDO Trinity 15 Intel Gen1",
2295 .matches = {
2296 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2297 DMI_EXACT_MATCH(DMI_BOARD_NAME, "TRINITY1501I"),
2298 },
2299 .driver_data = &tux_featureset_1_nvidia_descriptor,
2300 },
2301 {
2302 .ident = "TUXEDO Trinity 17 Intel Gen1",
2303 .matches = {
2304 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2305 DMI_EXACT_MATCH(DMI_BOARD_NAME, "TRINITY1701I"),
2306 },
2307 .driver_data = &tux_featureset_1_nvidia_descriptor,
2308 },
2309 {
2310 .ident = "TUXEDO Polaris 15/17 Gen2 AMD",
2311 .matches = {
2312 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2313 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxMGxx"),
2314 },
2315 .driver_data = &tux_featureset_2_nvidia_descriptor,
2316 },
2317 {
2318 .ident = "TUXEDO Polaris 15/17 Gen2 Intel",
2319 .matches = {
2320 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2321 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxNGxx"),
2322 },
2323 .driver_data = &tux_featureset_2_nvidia_descriptor,
2324 },
2325 {
2326 .ident = "TUXEDO Stellaris/Polaris 15/17 Gen3 AMD",
2327 .matches = {
2328 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2329 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxZGxx"),
2330 },
2331 .driver_data = &tux_featureset_2_nvidia_descriptor,
2332 },
2333 {
2334 .ident = "TUXEDO Stellaris/Polaris 15/17 Gen3 Intel",
2335 .matches = {
2336 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2337 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxTGxx"),
2338 },
2339 .driver_data = &tux_featureset_2_nvidia_descriptor,
2340 },
2341 {
2342 .ident = "TUXEDO Stellaris/Polaris 15/17 Gen4 AMD",
2343 .matches = {
2344 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2345 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxRGxx"),
2346 },
2347 .driver_data = &tux_featureset_3_nvidia_descriptor,
2348 },
2349 {
2350 .ident = "TUXEDO Stellaris 15 Gen4 Intel",
2351 .matches = {
2352 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2353 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxAGxx"),
2354 },
2355 .driver_data = &tux_featureset_3_nvidia_descriptor,
2356 },
2357 {
2358 .ident = "TUXEDO Polaris 15/17 Gen5 AMD",
2359 .matches = {
2360 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2361 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxXGxx"),
2362 },
2363 .driver_data = &tux_featureset_2_nvidia_descriptor,
2364 },
2365 {
2366 .ident = "TUXEDO Stellaris 16 Gen5 AMD",
2367 .matches = {
2368 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2369 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM6XGxX"),
2370 },
2371 .driver_data = &tux_featureset_3_nvidia_descriptor,
2372 },
2373 {
2374 .ident = "TUXEDO Stellaris 16/17 Gen5 Intel/Commodore ORION Gen 5",
2375 .matches = {
2376 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2377 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxPXxx"),
2378 },
2379 .driver_data = &tux_featureset_3_nvidia_descriptor,
2380 },
2381 {
2382 .ident = "TUXEDO Stellaris Slim 15 Gen6 AMD",
2383 .matches = {
2384 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2385 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxHGxx"),
2386 },
2387 .driver_data = &tux_featureset_3_nvidia_descriptor,
2388 },
2389 {
2390 .ident = "TUXEDO Stellaris Slim 15 Gen6 Intel/Commodore ORION Slim 15 Gen6",
2391 .matches = {
2392 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2393 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM5IXxA"),
2394 },
2395 .driver_data = &tux_featureset_3_nvidia_descriptor,
2396 },
2397 {
2398 .ident = "TUXEDO Stellaris 16 Gen6 Intel/Commodore ORION 16 Gen6",
2399 .matches = {
2400 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2401 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM6IXxB_MB1"),
2402 },
2403 .driver_data = &tux_featureset_3_nvidia_descriptor,
2404 },
2405 {
2406 .ident = "TUXEDO Stellaris 16 Gen6 Intel/Commodore ORION 16 Gen6",
2407 .matches = {
2408 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2409 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM6IXxB_MB2"),
2410 },
2411 .driver_data = &tux_featureset_3_nvidia_descriptor,
2412 },
2413 {
2414 .ident = "TUXEDO Stellaris 17 Gen6 Intel/Commodore ORION 17 Gen6",
2415 .matches = {
2416 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2417 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM7IXxN"),
2418 },
2419 .driver_data = &tux_featureset_3_nvidia_descriptor,
2420 },
2421 {
2422 .ident = "TUXEDO Stellaris 16 Gen7 AMD",
2423 .matches = {
2424 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2425 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6FR5xxY"),
2426 },
2427 .driver_data = &tux_featureset_3_nvidia_descriptor,
2428 },
2429 {
2430 .ident = "TUXEDO Stellaris 16 Gen7 Intel",
2431 .matches = {
2432 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2433 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6AR5xxY"),
2434 },
2435 .driver_data = &tux_featureset_3_nvidia_descriptor,
2436 },
2437 {
2438 .ident = "TUXEDO Stellaris 16 Gen7 Intel",
2439 .matches = {
2440 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2441 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6AR5xxY_mLED"),
2442 },
2443 .driver_data = &tux_featureset_3_nvidia_descriptor,
2444 },
2445 {
2446 .ident = "TUXEDO Book BA15 Gen10 AMD",
2447 .matches = {
2448 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2449 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PF5PU1G"),
2450 },
2451 .driver_data = &pf5pu1g_descriptor,
2452 },
2453 {
2454 .ident = "TUXEDO Pulse 14 Gen1 AMD",
2455 .matches = {
2456 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2457 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PULSE1401"),
2458 },
2459 .driver_data = &tux_featureset_1_descriptor,
2460 },
2461 {
2462 .ident = "TUXEDO Pulse 15 Gen1 AMD",
2463 .matches = {
2464 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2465 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PULSE1501"),
2466 },
2467 .driver_data = &tux_featureset_1_descriptor,
2468 },
2469 {
2470 .ident = "TUXEDO Pulse 15 Gen2 AMD",
2471 .matches = {
2472 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
2473 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PF5LUXG"),
2474 },
2475 .driver_data = &tux_featureset_1_descriptor,
2476 },
2477 { }
2478 };
2479 MODULE_DEVICE_TABLE(dmi, uniwill_dmi_table);
2480
uniwill_init(void)2481 static int __init uniwill_init(void)
2482 {
2483 const struct uniwill_device_descriptor *descriptor;
2484 const struct dmi_system_id *id;
2485 int ret;
2486
2487 id = dmi_first_match(uniwill_dmi_table);
2488 if (!id) {
2489 if (!force)
2490 return -ENODEV;
2491
2492 pr_warn("Loading on a potentially unsupported device\n");
2493 } else {
2494 /*
2495 * Some devices might support additional features depending on
2496 * the BIOS version/date, so we call this callback to let them
2497 * modify their device descriptor accordingly.
2498 */
2499 if (id->callback) {
2500 ret = id->callback(id);
2501 if (ret < 0)
2502 return ret;
2503 }
2504
2505 descriptor = id->driver_data;
2506 device_descriptor = *descriptor;
2507 }
2508
2509 if (force) {
2510 /* Assume that the device supports all features except the charge limit */
2511 device_descriptor.features = UINT_MAX & ~UNIWILL_FEATURE_BATTERY;
2512 pr_warn("Enabling potentially unsupported features\n");
2513 }
2514
2515 ret = platform_driver_register(&uniwill_driver);
2516 if (ret < 0)
2517 return ret;
2518
2519 ret = uniwill_wmi_register_driver();
2520 if (ret < 0) {
2521 platform_driver_unregister(&uniwill_driver);
2522 return ret;
2523 }
2524
2525 return 0;
2526 }
2527 module_init(uniwill_init);
2528
uniwill_exit(void)2529 static void __exit uniwill_exit(void)
2530 {
2531 uniwill_wmi_unregister_driver();
2532 platform_driver_unregister(&uniwill_driver);
2533 }
2534 module_exit(uniwill_exit);
2535
2536 MODULE_AUTHOR("Armin Wolf <W_Armin@gmx.de>");
2537 MODULE_DESCRIPTION("Uniwill notebook driver");
2538 MODULE_LICENSE("GPL");
2539