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