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