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