xref: /linux/drivers/platform/x86/dell/alienware-wmi-wmax.c (revision d9a0788093565c300f7c8dd034dbfa6ac4da9aa6)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Alienware WMAX WMI device driver
4  *
5  * Copyright (C) 2014 Dell Inc <Dell.Client.Kernel@dell.com>
6  * Copyright (C) 2025 Kurt Borja <kuurtb@gmail.com>
7  */
8 
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10 
11 #include <linux/array_size.h>
12 #include <linux/bitfield.h>
13 #include <linux/bitmap.h>
14 #include <linux/bits.h>
15 #include <linux/debugfs.h>
16 #include <linux/dmi.h>
17 #include <linux/hwmon.h>
18 #include <linux/hwmon-sysfs.h>
19 #include <linux/kstrtox.h>
20 #include <linux/minmax.h>
21 #include <linux/moduleparam.h>
22 #include <linux/platform_profile.h>
23 #include <linux/pm.h>
24 #include <linux/seq_file.h>
25 #include <linux/units.h>
26 #include <linux/wmi.h>
27 #include "alienware-wmi.h"
28 
29 #define WMAX_METHOD_HDMI_SOURCE			0x1
30 #define WMAX_METHOD_HDMI_STATUS			0x2
31 #define WMAX_METHOD_HDMI_CABLE			0x5
32 #define WMAX_METHOD_AMPLIFIER_CABLE		0x6
33 #define WMAX_METHOD_DEEP_SLEEP_CONTROL		0x0B
34 #define WMAX_METHOD_DEEP_SLEEP_STATUS		0x0C
35 #define WMAX_METHOD_BRIGHTNESS			0x3
36 #define WMAX_METHOD_ZONE_CONTROL		0x4
37 
38 #define AWCC_METHOD_GET_FAN_SENSORS		0x13
39 #define AWCC_METHOD_THERMAL_INFORMATION		0x14
40 #define AWCC_METHOD_THERMAL_CONTROL		0x15
41 #define AWCC_METHOD_FWUP_GPIO_CONTROL		0x20
42 #define AWCC_METHOD_READ_TOTAL_GPIOS		0x21
43 #define AWCC_METHOD_READ_GPIO_STATUS		0x22
44 #define AWCC_METHOD_GAME_SHIFT_STATUS		0x25
45 
46 #define AWCC_FAILURE_CODE			0xFFFFFFFF
47 #define AWCC_FAILURE_CODE_2			0xFFFFFFFE
48 
49 #define AWCC_SENSOR_ID_FLAG			BIT(8)
50 #define AWCC_THERMAL_MODE_MASK			GENMASK(3, 0)
51 #define AWCC_THERMAL_TABLE_MASK			GENMASK(7, 4)
52 #define AWCC_RESOURCE_ID_MASK			GENMASK(7, 0)
53 
54 /* Arbitrary limit based on supported models */
55 #define AWCC_MAX_RES_COUNT			16
56 #define AWCC_ID_BITMAP_SIZE			(U8_MAX + 1)
57 #define AWCC_ID_BITMAP_LONGS			BITS_TO_LONGS(AWCC_ID_BITMAP_SIZE)
58 
59 static bool force_hwmon;
60 module_param_unsafe(force_hwmon, bool, 0);
61 MODULE_PARM_DESC(force_hwmon, "Force probing for HWMON support without checking if the WMI backend is available");
62 
63 static bool force_platform_profile;
64 module_param_unsafe(force_platform_profile, bool, 0);
65 MODULE_PARM_DESC(force_platform_profile, "Forces auto-detecting thermal profiles without checking if WMI thermal backend is available");
66 
67 static bool force_gmode;
68 module_param_unsafe(force_gmode, bool, 0);
69 MODULE_PARM_DESC(force_gmode, "Forces G-Mode when performance profile is selected");
70 
71 struct awcc_quirks {
72 	bool hwmon;
73 	bool pprof;
74 	bool gmode;
75 };
76 
77 static struct awcc_quirks g_series_quirks = {
78 	.hwmon = true,
79 	.pprof = true,
80 	.gmode = true,
81 };
82 
83 static struct awcc_quirks generic_quirks = {
84 	.hwmon = true,
85 	.pprof = true,
86 	.gmode = false,
87 };
88 
89 static struct awcc_quirks empty_quirks;
90 
91 static const struct dmi_system_id awcc_dmi_table[] __initconst = {
92 	{
93 		.ident = "Alienware Area-51m R2",
94 		.matches = {
95 			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
96 			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware Area-51m R2"),
97 		},
98 		.driver_data = &generic_quirks,
99 	},
100 	{
101 		.ident = "Alienware m15 R7",
102 		.matches = {
103 			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
104 			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m15 R7"),
105 		},
106 		.driver_data = &generic_quirks,
107 	},
108 	{
109 		.ident = "Alienware m16 R1",
110 		.matches = {
111 			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
112 			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R1"),
113 		},
114 		.driver_data = &g_series_quirks,
115 	},
116 	{
117 		.ident = "Alienware m16 R1 AMD",
118 		.matches = {
119 			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
120 			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R1 AMD"),
121 		},
122 		.driver_data = &generic_quirks,
123 	},
124 	{
125 		.ident = "Alienware m16 R2",
126 		.matches = {
127 			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
128 			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R2"),
129 		},
130 		.driver_data = &generic_quirks,
131 	},
132 	{
133 		.ident = "Alienware m17 R5",
134 		.matches = {
135 			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
136 			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
137 		},
138 		.driver_data = &generic_quirks,
139 	},
140 	{
141 		.ident = "Alienware m18 R2",
142 		.matches = {
143 			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
144 			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18 R2"),
145 		},
146 		.driver_data = &generic_quirks,
147 	},
148 	{
149 		.ident = "Alienware x15 R1",
150 		.matches = {
151 			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
152 			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R1"),
153 		},
154 		.driver_data = &generic_quirks,
155 	},
156 	{
157 		.ident = "Alienware x15 R2",
158 		.matches = {
159 			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
160 			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R2"),
161 		},
162 		.driver_data = &generic_quirks,
163 	},
164 	{
165 		.ident = "Alienware x17 R2",
166 		.matches = {
167 			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
168 			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17 R2"),
169 		},
170 		.driver_data = &generic_quirks,
171 	},
172 	{
173 		.ident = "Dell Inc. G15 5510",
174 		.matches = {
175 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
176 			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5510"),
177 		},
178 		.driver_data = &g_series_quirks,
179 	},
180 	{
181 		.ident = "Dell Inc. G15 5511",
182 		.matches = {
183 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
184 			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5511"),
185 		},
186 		.driver_data = &g_series_quirks,
187 	},
188 	{
189 		.ident = "Dell Inc. G15 5515",
190 		.matches = {
191 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
192 			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"),
193 		},
194 		.driver_data = &g_series_quirks,
195 	},
196 	{
197 		.ident = "Dell Inc. G16 7630",
198 		.matches = {
199 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
200 			DMI_MATCH(DMI_PRODUCT_NAME, "Dell G16 7630"),
201 		},
202 		.driver_data = &g_series_quirks,
203 	},
204 	{
205 		.ident = "Dell Inc. G3 3500",
206 		.matches = {
207 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
208 			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3500"),
209 		},
210 		.driver_data = &g_series_quirks,
211 	},
212 	{
213 		.ident = "Dell Inc. G3 3590",
214 		.matches = {
215 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
216 			DMI_MATCH(DMI_PRODUCT_NAME, "G3 3590"),
217 		},
218 		.driver_data = &g_series_quirks,
219 	},
220 	{
221 		.ident = "Dell Inc. G5 5500",
222 		.matches = {
223 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
224 			DMI_MATCH(DMI_PRODUCT_NAME, "G5 5500"),
225 		},
226 		.driver_data = &g_series_quirks,
227 	},
228 	{
229 		.ident = "Dell Inc. G5 5505",
230 		.matches = {
231 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
232 			DMI_MATCH(DMI_PRODUCT_NAME, "G5 5505"),
233 		},
234 		.driver_data = &g_series_quirks,
235 	},
236 };
237 
238 enum AWCC_GET_FAN_SENSORS_OPERATIONS {
239 	AWCC_OP_GET_TOTAL_FAN_TEMPS		= 0x01,
240 	AWCC_OP_GET_FAN_TEMP_ID			= 0x02,
241 };
242 
243 enum AWCC_THERMAL_INFORMATION_OPERATIONS {
244 	AWCC_OP_GET_SYSTEM_DESCRIPTION		= 0x02,
245 	AWCC_OP_GET_RESOURCE_ID			= 0x03,
246 	AWCC_OP_GET_TEMPERATURE			= 0x04,
247 	AWCC_OP_GET_FAN_RPM			= 0x05,
248 	AWCC_OP_GET_FAN_MIN_RPM			= 0x08,
249 	AWCC_OP_GET_FAN_MAX_RPM			= 0x09,
250 	AWCC_OP_GET_CURRENT_PROFILE		= 0x0B,
251 	AWCC_OP_GET_FAN_BOOST			= 0x0C,
252 };
253 
254 enum AWCC_THERMAL_CONTROL_OPERATIONS {
255 	AWCC_OP_ACTIVATE_PROFILE		= 0x01,
256 	AWCC_OP_SET_FAN_BOOST			= 0x02,
257 };
258 
259 enum AWCC_GAME_SHIFT_STATUS_OPERATIONS {
260 	AWCC_OP_TOGGLE_GAME_SHIFT		= 0x01,
261 	AWCC_OP_GET_GAME_SHIFT_STATUS		= 0x02,
262 };
263 
264 enum AWCC_THERMAL_TABLES {
265 	AWCC_THERMAL_TABLE_LEGACY		= 0x9,
266 	AWCC_THERMAL_TABLE_USTT			= 0xA,
267 };
268 
269 enum AWCC_SPECIAL_THERMAL_CODES {
270 	AWCC_SPECIAL_PROFILE_CUSTOM		= 0x00,
271 	AWCC_SPECIAL_PROFILE_GMODE		= 0xAB,
272 };
273 
274 enum AWCC_TEMP_SENSOR_TYPES {
275 	AWCC_TEMP_SENSOR_CPU			= 0x01,
276 	AWCC_TEMP_SENSOR_FRONT			= 0x03,
277 	AWCC_TEMP_SENSOR_GPU			= 0x06,
278 };
279 
280 enum AWCC_FAN_TYPES {
281 	AWCC_FAN_CPU_1				= 0x32,
282 	AWCC_FAN_GPU_1				= 0x33,
283 	AWCC_FAN_PCI				= 0x34,
284 	AWCC_FAN_MID				= 0x35,
285 	AWCC_FAN_TOP_1				= 0x36,
286 	AWCC_FAN_SIDE				= 0x37,
287 	AWCC_FAN_U2_1				= 0x38,
288 	AWCC_FAN_U2_2				= 0x39,
289 	AWCC_FAN_FRONT_1			= 0x3A,
290 	AWCC_FAN_CPU_2				= 0x3B,
291 	AWCC_FAN_GPU_2				= 0x3C,
292 	AWCC_FAN_TOP_2				= 0x3D,
293 	AWCC_FAN_TOP_3				= 0x3E,
294 	AWCC_FAN_FRONT_2			= 0x3F,
295 	AWCC_FAN_BOTTOM_1			= 0x40,
296 	AWCC_FAN_BOTTOM_2			= 0x41,
297 };
298 
299 enum awcc_thermal_profile {
300 	AWCC_PROFILE_USTT_BALANCED,
301 	AWCC_PROFILE_USTT_BALANCED_PERFORMANCE,
302 	AWCC_PROFILE_USTT_COOL,
303 	AWCC_PROFILE_USTT_QUIET,
304 	AWCC_PROFILE_USTT_PERFORMANCE,
305 	AWCC_PROFILE_USTT_LOW_POWER,
306 	AWCC_PROFILE_LEGACY_QUIET,
307 	AWCC_PROFILE_LEGACY_BALANCED,
308 	AWCC_PROFILE_LEGACY_BALANCED_PERFORMANCE,
309 	AWCC_PROFILE_LEGACY_PERFORMANCE,
310 	AWCC_PROFILE_LAST,
311 };
312 
313 struct wmax_led_args {
314 	u32 led_mask;
315 	struct color_platform colors;
316 	u8 state;
317 } __packed;
318 
319 struct wmax_brightness_args {
320 	u32 led_mask;
321 	u32 percentage;
322 };
323 
324 struct wmax_basic_args {
325 	u8 arg;
326 };
327 
328 struct wmax_u32_args {
329 	u8 operation;
330 	u8 arg1;
331 	u8 arg2;
332 	u8 arg3;
333 };
334 
335 struct awcc_fan_data {
336 	unsigned long auto_channels_temp;
337 	u32 min_rpm;
338 	u32 max_rpm;
339 	u8 suspend_cache;
340 	u8 id;
341 };
342 
343 struct awcc_priv {
344 	struct wmi_device *wdev;
345 	union {
346 		u32 system_description;
347 		struct {
348 			u8 fan_count;
349 			u8 temp_count;
350 			u8 unknown_count;
351 			u8 profile_count;
352 		};
353 		u8 res_count[4];
354 	};
355 
356 	struct device *ppdev;
357 	u8 supported_profiles[PLATFORM_PROFILE_LAST];
358 
359 	struct device *hwdev;
360 	struct awcc_fan_data **fan_data;
361 	unsigned long temp_sensors[AWCC_ID_BITMAP_LONGS];
362 
363 	u32 gpio_count;
364 };
365 
366 static const enum platform_profile_option awcc_mode_to_platform_profile[AWCC_PROFILE_LAST] = {
367 	[AWCC_PROFILE_USTT_BALANCED]			= PLATFORM_PROFILE_BALANCED,
368 	[AWCC_PROFILE_USTT_BALANCED_PERFORMANCE]	= PLATFORM_PROFILE_BALANCED_PERFORMANCE,
369 	[AWCC_PROFILE_USTT_COOL]			= PLATFORM_PROFILE_COOL,
370 	[AWCC_PROFILE_USTT_QUIET]			= PLATFORM_PROFILE_QUIET,
371 	[AWCC_PROFILE_USTT_PERFORMANCE]			= PLATFORM_PROFILE_PERFORMANCE,
372 	[AWCC_PROFILE_USTT_LOW_POWER]			= PLATFORM_PROFILE_LOW_POWER,
373 	[AWCC_PROFILE_LEGACY_QUIET]			= PLATFORM_PROFILE_QUIET,
374 	[AWCC_PROFILE_LEGACY_BALANCED]			= PLATFORM_PROFILE_BALANCED,
375 	[AWCC_PROFILE_LEGACY_BALANCED_PERFORMANCE]	= PLATFORM_PROFILE_BALANCED_PERFORMANCE,
376 	[AWCC_PROFILE_LEGACY_PERFORMANCE]		= PLATFORM_PROFILE_PERFORMANCE,
377 };
378 
379 static struct awcc_quirks *awcc;
380 
381 /*
382  *	The HDMI mux sysfs node indicates the status of the HDMI input mux.
383  *	It can toggle between standard system GPU output and HDMI input.
384  */
385 static ssize_t cable_show(struct device *dev, struct device_attribute *attr,
386 			  char *buf)
387 {
388 	struct alienfx_platdata *pdata = dev_get_platdata(dev);
389 	struct wmax_basic_args in_args = {
390 		.arg = 0,
391 	};
392 	u32 out_data;
393 	int ret;
394 
395 	ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_HDMI_CABLE,
396 				    &in_args, sizeof(in_args), &out_data);
397 	if (!ret) {
398 		if (out_data == 0)
399 			return sysfs_emit(buf, "[unconnected] connected unknown\n");
400 		else if (out_data == 1)
401 			return sysfs_emit(buf, "unconnected [connected] unknown\n");
402 	}
403 
404 	pr_err("alienware-wmi: unknown HDMI cable status: %d\n", ret);
405 	return sysfs_emit(buf, "unconnected connected [unknown]\n");
406 }
407 
408 static ssize_t source_show(struct device *dev, struct device_attribute *attr,
409 			   char *buf)
410 {
411 	struct alienfx_platdata *pdata = dev_get_platdata(dev);
412 	struct wmax_basic_args in_args = {
413 		.arg = 0,
414 	};
415 	u32 out_data;
416 	int ret;
417 
418 	ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_HDMI_STATUS,
419 				    &in_args, sizeof(in_args), &out_data);
420 	if (!ret) {
421 		if (out_data == 1)
422 			return sysfs_emit(buf, "[input] gpu unknown\n");
423 		else if (out_data == 2)
424 			return sysfs_emit(buf, "input [gpu] unknown\n");
425 	}
426 
427 	pr_err("alienware-wmi: unknown HDMI source status: %u\n", ret);
428 	return sysfs_emit(buf, "input gpu [unknown]\n");
429 }
430 
431 static ssize_t source_store(struct device *dev, struct device_attribute *attr,
432 			    const char *buf, size_t count)
433 {
434 	struct alienfx_platdata *pdata = dev_get_platdata(dev);
435 	struct wmax_basic_args args;
436 	int ret;
437 
438 	if (strcmp(buf, "gpu\n") == 0)
439 		args.arg = 1;
440 	else if (strcmp(buf, "input\n") == 0)
441 		args.arg = 2;
442 	else
443 		args.arg = 3;
444 	pr_debug("alienware-wmi: setting hdmi to %d : %s", args.arg, buf);
445 
446 	ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_HDMI_SOURCE, &args,
447 				    sizeof(args), NULL);
448 	if (ret < 0)
449 		pr_err("alienware-wmi: HDMI toggle failed: results: %u\n", ret);
450 
451 	return count;
452 }
453 
454 static DEVICE_ATTR_RO(cable);
455 static DEVICE_ATTR_RW(source);
456 
457 static bool hdmi_group_visible(struct kobject *kobj)
458 {
459 	return alienware_interface == WMAX && alienfx->hdmi_mux;
460 }
461 DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(hdmi);
462 
463 static struct attribute *hdmi_attrs[] = {
464 	&dev_attr_cable.attr,
465 	&dev_attr_source.attr,
466 	NULL,
467 };
468 
469 const struct attribute_group wmax_hdmi_attribute_group = {
470 	.name = "hdmi",
471 	.is_visible = SYSFS_GROUP_VISIBLE(hdmi),
472 	.attrs = hdmi_attrs,
473 };
474 
475 /*
476  * Alienware GFX amplifier support
477  * - Currently supports reading cable status
478  * - Leaving expansion room to possibly support dock/undock events later
479  */
480 static ssize_t status_show(struct device *dev, struct device_attribute *attr,
481 			   char *buf)
482 {
483 	struct alienfx_platdata *pdata = dev_get_platdata(dev);
484 	struct wmax_basic_args in_args = {
485 		.arg = 0,
486 	};
487 	u32 out_data;
488 	int ret;
489 
490 	ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_AMPLIFIER_CABLE,
491 				    &in_args, sizeof(in_args), &out_data);
492 	if (!ret) {
493 		if (out_data == 0)
494 			return sysfs_emit(buf, "[unconnected] connected unknown\n");
495 		else if (out_data == 1)
496 			return sysfs_emit(buf, "unconnected [connected] unknown\n");
497 	}
498 
499 	pr_err("alienware-wmi: unknown amplifier cable status: %d\n", ret);
500 	return sysfs_emit(buf, "unconnected connected [unknown]\n");
501 }
502 
503 static DEVICE_ATTR_RO(status);
504 
505 static bool amplifier_group_visible(struct kobject *kobj)
506 {
507 	return alienware_interface == WMAX && alienfx->amplifier;
508 }
509 DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(amplifier);
510 
511 static struct attribute *amplifier_attrs[] = {
512 	&dev_attr_status.attr,
513 	NULL,
514 };
515 
516 const struct attribute_group wmax_amplifier_attribute_group = {
517 	.name = "amplifier",
518 	.is_visible = SYSFS_GROUP_VISIBLE(amplifier),
519 	.attrs = amplifier_attrs,
520 };
521 
522 /*
523  * Deep Sleep Control support
524  * - Modifies BIOS setting for deep sleep control allowing extra wakeup events
525  */
526 static ssize_t deepsleep_show(struct device *dev, struct device_attribute *attr,
527 			      char *buf)
528 {
529 	struct alienfx_platdata *pdata = dev_get_platdata(dev);
530 	struct wmax_basic_args in_args = {
531 		.arg = 0,
532 	};
533 	u32 out_data;
534 	int ret;
535 
536 	ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_DEEP_SLEEP_STATUS,
537 				    &in_args, sizeof(in_args), &out_data);
538 	if (!ret) {
539 		if (out_data == 0)
540 			return sysfs_emit(buf, "[disabled] s5 s5_s4\n");
541 		else if (out_data == 1)
542 			return sysfs_emit(buf, "disabled [s5] s5_s4\n");
543 		else if (out_data == 2)
544 			return sysfs_emit(buf, "disabled s5 [s5_s4]\n");
545 	}
546 
547 	pr_err("alienware-wmi: unknown deep sleep status: %d\n", ret);
548 	return sysfs_emit(buf, "disabled s5 s5_s4 [unknown]\n");
549 }
550 
551 static ssize_t deepsleep_store(struct device *dev, struct device_attribute *attr,
552 			       const char *buf, size_t count)
553 {
554 	struct alienfx_platdata *pdata = dev_get_platdata(dev);
555 	struct wmax_basic_args args;
556 	int ret;
557 
558 	if (strcmp(buf, "disabled\n") == 0)
559 		args.arg = 0;
560 	else if (strcmp(buf, "s5\n") == 0)
561 		args.arg = 1;
562 	else
563 		args.arg = 2;
564 	pr_debug("alienware-wmi: setting deep sleep to %d : %s", args.arg, buf);
565 
566 	ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_DEEP_SLEEP_CONTROL,
567 				    &args, sizeof(args), NULL);
568 	if (!ret)
569 		pr_err("alienware-wmi: deep sleep control failed: results: %u\n", ret);
570 
571 	return count;
572 }
573 
574 static DEVICE_ATTR_RW(deepsleep);
575 
576 static bool deepsleep_group_visible(struct kobject *kobj)
577 {
578 	return alienware_interface == WMAX && alienfx->deepslp;
579 }
580 DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(deepsleep);
581 
582 static struct attribute *deepsleep_attrs[] = {
583 	&dev_attr_deepsleep.attr,
584 	NULL,
585 };
586 
587 const struct attribute_group wmax_deepsleep_attribute_group = {
588 	.name = "deepsleep",
589 	.is_visible = SYSFS_GROUP_VISIBLE(deepsleep),
590 	.attrs = deepsleep_attrs,
591 };
592 
593 /*
594  * AWCC Helpers
595  */
596 static bool is_awcc_thermal_profile_id(u8 code)
597 {
598 	u8 table = FIELD_GET(AWCC_THERMAL_TABLE_MASK, code);
599 	u8 mode = FIELD_GET(AWCC_THERMAL_MODE_MASK, code);
600 
601 	if (mode >= AWCC_PROFILE_LAST)
602 		return false;
603 
604 	if (table == AWCC_THERMAL_TABLE_LEGACY && mode >= AWCC_PROFILE_LEGACY_QUIET)
605 		return true;
606 
607 	if (table == AWCC_THERMAL_TABLE_USTT && mode <= AWCC_PROFILE_USTT_LOW_POWER)
608 		return true;
609 
610 	return false;
611 }
612 
613 static int awcc_wmi_command(struct wmi_device *wdev, u32 method_id,
614 			    struct wmax_u32_args *args, u32 *out)
615 {
616 	int ret;
617 
618 	ret = alienware_wmi_command(wdev, method_id, args, sizeof(*args), out);
619 	if (ret)
620 		return ret;
621 
622 	if (*out == AWCC_FAILURE_CODE || *out == AWCC_FAILURE_CODE_2)
623 		return -EBADRQC;
624 
625 	return 0;
626 }
627 
628 static int awcc_get_fan_sensors(struct wmi_device *wdev, u8 operation,
629 				u8 fan_id, u8 index, u32 *out)
630 {
631 	struct wmax_u32_args args = {
632 		.operation = operation,
633 		.arg1 = fan_id,
634 		.arg2 = index,
635 		.arg3 = 0,
636 	};
637 
638 	return awcc_wmi_command(wdev, AWCC_METHOD_GET_FAN_SENSORS, &args, out);
639 }
640 
641 static int awcc_thermal_information(struct wmi_device *wdev, u8 operation, u8 arg,
642 				    u32 *out)
643 {
644 	struct wmax_u32_args args = {
645 		.operation = operation,
646 		.arg1 = arg,
647 		.arg2 = 0,
648 		.arg3 = 0,
649 	};
650 
651 	return awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, out);
652 }
653 
654 static int awcc_fwup_gpio_control(struct wmi_device *wdev, u8 pin, u8 status)
655 {
656 	struct wmax_u32_args args = {
657 		.operation = pin,
658 		.arg1 = status,
659 		.arg2 = 0,
660 		.arg3 = 0,
661 	};
662 	u32 out;
663 
664 	return awcc_wmi_command(wdev, AWCC_METHOD_FWUP_GPIO_CONTROL, &args, &out);
665 }
666 
667 static int awcc_read_total_gpios(struct wmi_device *wdev, u32 *count)
668 {
669 	struct wmax_u32_args args = {};
670 
671 	return awcc_wmi_command(wdev, AWCC_METHOD_READ_TOTAL_GPIOS, &args, count);
672 }
673 
674 static int awcc_read_gpio_status(struct wmi_device *wdev, u8 pin, u32 *status)
675 {
676 	struct wmax_u32_args args = {
677 		.operation = pin,
678 		.arg1 = 0,
679 		.arg2 = 0,
680 		.arg3 = 0,
681 	};
682 
683 	return awcc_wmi_command(wdev, AWCC_METHOD_READ_GPIO_STATUS, &args, status);
684 }
685 
686 static int awcc_game_shift_status(struct wmi_device *wdev, u8 operation,
687 				  u32 *out)
688 {
689 	struct wmax_u32_args args = {
690 		.operation = operation,
691 		.arg1 = 0,
692 		.arg2 = 0,
693 		.arg3 = 0,
694 	};
695 
696 	return awcc_wmi_command(wdev, AWCC_METHOD_GAME_SHIFT_STATUS, &args, out);
697 }
698 
699 /**
700  * awcc_op_get_resource_id - Get the resource ID at a given index
701  * @wdev: AWCC WMI device
702  * @index: Index
703  * @out: Value returned by the WMI call
704  *
705  * Get the resource ID at a given @index. Resource IDs are listed in the
706  * following order:
707  *
708  *	- Fan IDs
709  *	- Sensor IDs
710  *	- Unknown IDs
711  *	- Thermal Profile IDs
712  *
713  * The total number of IDs of a given type can be obtained with
714  * AWCC_OP_GET_SYSTEM_DESCRIPTION.
715  *
716  * Return: 0 on success, -errno on failure
717  */
718 static int awcc_op_get_resource_id(struct wmi_device *wdev, u8 index, u8 *out)
719 {
720 	struct wmax_u32_args args = {
721 		.operation = AWCC_OP_GET_RESOURCE_ID,
722 		.arg1 = index,
723 		.arg2 = 0,
724 		.arg3 = 0,
725 	};
726 	u32 out_data;
727 	int ret;
728 
729 	ret = awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, &out_data);
730 	if (ret)
731 		return ret;
732 
733 	*out = FIELD_GET(AWCC_RESOURCE_ID_MASK, out_data);
734 
735 	return 0;
736 }
737 
738 static int awcc_op_get_fan_rpm(struct wmi_device *wdev, u8 fan_id, u32 *out)
739 {
740 	struct wmax_u32_args args = {
741 		.operation = AWCC_OP_GET_FAN_RPM,
742 		.arg1 = fan_id,
743 		.arg2 = 0,
744 		.arg3 = 0,
745 	};
746 
747 	return awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, out);
748 }
749 
750 static int awcc_op_get_temperature(struct wmi_device *wdev, u8 temp_id, u32 *out)
751 {
752 	struct wmax_u32_args args = {
753 		.operation = AWCC_OP_GET_TEMPERATURE,
754 		.arg1 = temp_id,
755 		.arg2 = 0,
756 		.arg3 = 0,
757 	};
758 
759 	return awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, out);
760 }
761 
762 static int awcc_op_get_fan_boost(struct wmi_device *wdev, u8 fan_id, u32 *out)
763 {
764 	struct wmax_u32_args args = {
765 		.operation = AWCC_OP_GET_FAN_BOOST,
766 		.arg1 = fan_id,
767 		.arg2 = 0,
768 		.arg3 = 0,
769 	};
770 
771 	return awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, out);
772 }
773 
774 static int awcc_op_get_current_profile(struct wmi_device *wdev, u32 *out)
775 {
776 	struct wmax_u32_args args = {
777 		.operation = AWCC_OP_GET_CURRENT_PROFILE,
778 		.arg1 = 0,
779 		.arg2 = 0,
780 		.arg3 = 0,
781 	};
782 
783 	return awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, out);
784 }
785 
786 static int awcc_op_activate_profile(struct wmi_device *wdev, u8 profile)
787 {
788 	struct wmax_u32_args args = {
789 		.operation = AWCC_OP_ACTIVATE_PROFILE,
790 		.arg1 = profile,
791 		.arg2 = 0,
792 		.arg3 = 0,
793 	};
794 	u32 out;
795 
796 	return awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_CONTROL, &args, &out);
797 }
798 
799 static int awcc_op_set_fan_boost(struct wmi_device *wdev, u8 fan_id, u8 boost)
800 {
801 	struct wmax_u32_args args = {
802 		.operation = AWCC_OP_SET_FAN_BOOST,
803 		.arg1 = fan_id,
804 		.arg2 = boost,
805 		.arg3 = 0,
806 	};
807 	u32 out;
808 
809 	return awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_CONTROL, &args, &out);
810 }
811 
812 /*
813  * HWMON
814  *  - Provides temperature and fan speed monitoring as well as manual fan
815  *    control
816  */
817 static umode_t awcc_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_types type,
818 				     u32 attr, int channel)
819 {
820 	const struct awcc_priv *priv = drvdata;
821 	unsigned int temp_count;
822 
823 	switch (type) {
824 	case hwmon_temp:
825 		temp_count = bitmap_weight(priv->temp_sensors, AWCC_ID_BITMAP_SIZE);
826 
827 		return channel < temp_count ? 0444 : 0;
828 	case hwmon_fan:
829 		return channel < priv->fan_count ? 0444 : 0;
830 	case hwmon_pwm:
831 		return channel < priv->fan_count ? 0444 : 0;
832 	default:
833 		return 0;
834 	}
835 }
836 
837 static int awcc_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
838 			   u32 attr, int channel, long *val)
839 {
840 	struct awcc_priv *priv = dev_get_drvdata(dev);
841 	const struct awcc_fan_data *fan;
842 	u32 state;
843 	int ret;
844 	u8 temp;
845 
846 	switch (type) {
847 	case hwmon_temp:
848 		temp = find_nth_bit(priv->temp_sensors, AWCC_ID_BITMAP_SIZE, channel);
849 
850 		switch (attr) {
851 		case hwmon_temp_input:
852 			ret = awcc_op_get_temperature(priv->wdev, temp, &state);
853 			if (ret)
854 				return ret;
855 
856 			*val = state * MILLIDEGREE_PER_DEGREE;
857 			break;
858 		default:
859 			return -EOPNOTSUPP;
860 		}
861 
862 		break;
863 	case hwmon_fan:
864 		fan = priv->fan_data[channel];
865 
866 		switch (attr) {
867 		case hwmon_fan_input:
868 			ret = awcc_op_get_fan_rpm(priv->wdev, fan->id, &state);
869 			if (ret)
870 				return ret;
871 
872 			*val = state;
873 			break;
874 		case hwmon_fan_min:
875 			*val = fan->min_rpm;
876 			break;
877 		case hwmon_fan_max:
878 			*val = fan->max_rpm;
879 			break;
880 		default:
881 			return -EOPNOTSUPP;
882 		}
883 
884 		break;
885 	case hwmon_pwm:
886 		fan = priv->fan_data[channel];
887 
888 		switch (attr) {
889 		case hwmon_pwm_auto_channels_temp:
890 			*val = fan->auto_channels_temp;
891 			break;
892 		default:
893 			return -EOPNOTSUPP;
894 		}
895 
896 		break;
897 	default:
898 		return -EOPNOTSUPP;
899 	}
900 
901 	return 0;
902 }
903 
904 static int awcc_hwmon_read_string(struct device *dev, enum hwmon_sensor_types type,
905 				  u32 attr, int channel, const char **str)
906 {
907 	struct awcc_priv *priv = dev_get_drvdata(dev);
908 	u8 temp;
909 
910 	switch (type) {
911 	case hwmon_temp:
912 		temp = find_nth_bit(priv->temp_sensors, AWCC_ID_BITMAP_SIZE, channel);
913 
914 		switch (temp) {
915 		case AWCC_TEMP_SENSOR_CPU:
916 			*str = "CPU";
917 			break;
918 		case AWCC_TEMP_SENSOR_FRONT:
919 			*str = "Front";
920 			break;
921 		case AWCC_TEMP_SENSOR_GPU:
922 			*str = "GPU";
923 			break;
924 		default:
925 			*str = "Unknown";
926 			break;
927 		}
928 
929 		break;
930 	case hwmon_fan:
931 		switch (priv->fan_data[channel]->id) {
932 		case AWCC_FAN_CPU_1:
933 		case AWCC_FAN_CPU_2:
934 			*str = "CPU Fan";
935 			break;
936 		case AWCC_FAN_GPU_1:
937 		case AWCC_FAN_GPU_2:
938 			*str = "GPU Fan";
939 			break;
940 		case AWCC_FAN_PCI:
941 			*str = "PCI Fan";
942 			break;
943 		case AWCC_FAN_MID:
944 			*str = "Mid Fan";
945 			break;
946 		case AWCC_FAN_TOP_1:
947 		case AWCC_FAN_TOP_2:
948 		case AWCC_FAN_TOP_3:
949 			*str = "Top Fan";
950 			break;
951 		case AWCC_FAN_SIDE:
952 			*str = "Side Fan";
953 			break;
954 		case AWCC_FAN_U2_1:
955 		case AWCC_FAN_U2_2:
956 			*str = "U.2 Fan";
957 			break;
958 		case AWCC_FAN_FRONT_1:
959 		case AWCC_FAN_FRONT_2:
960 			*str = "Front Fan";
961 			break;
962 		case AWCC_FAN_BOTTOM_1:
963 		case AWCC_FAN_BOTTOM_2:
964 			*str = "Bottom Fan";
965 			break;
966 		default:
967 			*str = "Unknown Fan";
968 			break;
969 		}
970 
971 		break;
972 	default:
973 		return -EOPNOTSUPP;
974 	}
975 
976 	return 0;
977 }
978 
979 static const struct hwmon_ops awcc_hwmon_ops = {
980 	.is_visible = awcc_hwmon_is_visible,
981 	.read = awcc_hwmon_read,
982 	.read_string = awcc_hwmon_read_string,
983 };
984 
985 static const struct hwmon_channel_info * const awcc_hwmon_info[] = {
986 	HWMON_CHANNEL_INFO(temp,
987 			   HWMON_T_LABEL | HWMON_T_INPUT,
988 			   HWMON_T_LABEL | HWMON_T_INPUT,
989 			   HWMON_T_LABEL | HWMON_T_INPUT,
990 			   HWMON_T_LABEL | HWMON_T_INPUT,
991 			   HWMON_T_LABEL | HWMON_T_INPUT,
992 			   HWMON_T_LABEL | HWMON_T_INPUT
993 			   ),
994 	HWMON_CHANNEL_INFO(fan,
995 			   HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX,
996 			   HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX,
997 			   HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX,
998 			   HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX,
999 			   HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX,
1000 			   HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX
1001 			   ),
1002 	HWMON_CHANNEL_INFO(pwm,
1003 			   HWMON_PWM_AUTO_CHANNELS_TEMP,
1004 			   HWMON_PWM_AUTO_CHANNELS_TEMP,
1005 			   HWMON_PWM_AUTO_CHANNELS_TEMP,
1006 			   HWMON_PWM_AUTO_CHANNELS_TEMP,
1007 			   HWMON_PWM_AUTO_CHANNELS_TEMP,
1008 			   HWMON_PWM_AUTO_CHANNELS_TEMP
1009 			   ),
1010 	NULL
1011 };
1012 
1013 static const struct hwmon_chip_info awcc_hwmon_chip_info = {
1014 	.ops = &awcc_hwmon_ops,
1015 	.info = awcc_hwmon_info,
1016 };
1017 
1018 static ssize_t fan_boost_show(struct device *dev, struct device_attribute *attr,
1019 			      char *buf)
1020 {
1021 	struct awcc_priv *priv = dev_get_drvdata(dev);
1022 	int index = to_sensor_dev_attr(attr)->index;
1023 	struct awcc_fan_data *fan = priv->fan_data[index];
1024 	u32 boost;
1025 	int ret;
1026 
1027 	ret = awcc_op_get_fan_boost(priv->wdev, fan->id, &boost);
1028 	if (ret)
1029 		return ret;
1030 
1031 	return sysfs_emit(buf, "%u\n", boost);
1032 }
1033 
1034 static ssize_t fan_boost_store(struct device *dev, struct device_attribute *attr,
1035 			       const char *buf, size_t count)
1036 {
1037 	struct awcc_priv *priv = dev_get_drvdata(dev);
1038 	int index = to_sensor_dev_attr(attr)->index;
1039 	struct awcc_fan_data *fan = priv->fan_data[index];
1040 	unsigned long val;
1041 	int ret;
1042 
1043 	ret = kstrtoul(buf, 0, &val);
1044 	if (ret)
1045 		return ret;
1046 
1047 	ret = awcc_op_set_fan_boost(priv->wdev, fan->id, clamp_val(val, 0, 255));
1048 
1049 	return ret ? ret : count;
1050 }
1051 
1052 static SENSOR_DEVICE_ATTR_RW(fan1_boost, fan_boost, 0);
1053 static SENSOR_DEVICE_ATTR_RW(fan2_boost, fan_boost, 1);
1054 static SENSOR_DEVICE_ATTR_RW(fan3_boost, fan_boost, 2);
1055 static SENSOR_DEVICE_ATTR_RW(fan4_boost, fan_boost, 3);
1056 static SENSOR_DEVICE_ATTR_RW(fan5_boost, fan_boost, 4);
1057 static SENSOR_DEVICE_ATTR_RW(fan6_boost, fan_boost, 5);
1058 
1059 static umode_t fan_boost_attr_visible(struct kobject *kobj, struct attribute *attr, int n)
1060 {
1061 	struct awcc_priv *priv = dev_get_drvdata(kobj_to_dev(kobj));
1062 
1063 	return n < priv->fan_count ? attr->mode : 0;
1064 }
1065 
1066 static bool fan_boost_group_visible(struct kobject *kobj)
1067 {
1068 	return true;
1069 }
1070 
1071 DEFINE_SYSFS_GROUP_VISIBLE(fan_boost);
1072 
1073 static struct attribute *fan_boost_attrs[] = {
1074 	&sensor_dev_attr_fan1_boost.dev_attr.attr,
1075 	&sensor_dev_attr_fan2_boost.dev_attr.attr,
1076 	&sensor_dev_attr_fan3_boost.dev_attr.attr,
1077 	&sensor_dev_attr_fan4_boost.dev_attr.attr,
1078 	&sensor_dev_attr_fan5_boost.dev_attr.attr,
1079 	&sensor_dev_attr_fan6_boost.dev_attr.attr,
1080 	NULL
1081 };
1082 
1083 static const struct attribute_group fan_boost_group = {
1084 	.attrs = fan_boost_attrs,
1085 	.is_visible = SYSFS_GROUP_VISIBLE(fan_boost),
1086 };
1087 
1088 static const struct attribute_group *awcc_hwmon_groups[] = {
1089 	&fan_boost_group,
1090 	NULL
1091 };
1092 
1093 static int awcc_hwmon_temps_init(struct wmi_device *wdev)
1094 {
1095 	struct awcc_priv *priv = dev_get_drvdata(&wdev->dev);
1096 	unsigned int i;
1097 	int ret;
1098 	u8 id;
1099 
1100 	for (i = 0; i < priv->temp_count; i++) {
1101 		/*
1102 		 * Temperature sensors IDs are listed after the fan IDs at
1103 		 * offset `fan_count`
1104 		 */
1105 		ret = awcc_op_get_resource_id(wdev, i + priv->fan_count, &id);
1106 		if (ret)
1107 			return ret;
1108 
1109 		__set_bit(id, priv->temp_sensors);
1110 	}
1111 
1112 	return 0;
1113 }
1114 
1115 static int awcc_hwmon_fans_init(struct wmi_device *wdev)
1116 {
1117 	struct awcc_priv *priv = dev_get_drvdata(&wdev->dev);
1118 	unsigned long fan_temps[AWCC_ID_BITMAP_LONGS];
1119 	unsigned long gather[AWCC_ID_BITMAP_LONGS];
1120 	u32 min_rpm, max_rpm, temp_count, temp_id;
1121 	struct awcc_fan_data *fan_data;
1122 	unsigned int i, j;
1123 	int ret;
1124 	u8 id;
1125 
1126 	for (i = 0; i < priv->fan_count; i++) {
1127 		fan_data = devm_kzalloc(&wdev->dev, sizeof(*fan_data), GFP_KERNEL);
1128 		if (!fan_data)
1129 			return -ENOMEM;
1130 
1131 		/*
1132 		 * Fan IDs are listed first at offset 0
1133 		 */
1134 		ret = awcc_op_get_resource_id(wdev, i, &id);
1135 		if (ret)
1136 			return ret;
1137 
1138 		ret = awcc_thermal_information(wdev, AWCC_OP_GET_FAN_MIN_RPM, id,
1139 					       &min_rpm);
1140 		if (ret)
1141 			return ret;
1142 
1143 		ret = awcc_thermal_information(wdev, AWCC_OP_GET_FAN_MAX_RPM, id,
1144 					       &max_rpm);
1145 		if (ret)
1146 			return ret;
1147 
1148 		ret = awcc_get_fan_sensors(wdev, AWCC_OP_GET_TOTAL_FAN_TEMPS, id,
1149 					   0, &temp_count);
1150 		if (ret)
1151 			return ret;
1152 
1153 		bitmap_zero(fan_temps, AWCC_ID_BITMAP_SIZE);
1154 
1155 		for (j = 0; j < temp_count; j++) {
1156 			ret = awcc_get_fan_sensors(wdev, AWCC_OP_GET_FAN_TEMP_ID,
1157 						   id, j, &temp_id);
1158 			if (ret)
1159 				break;
1160 
1161 			temp_id = FIELD_GET(AWCC_RESOURCE_ID_MASK, temp_id);
1162 			__set_bit(temp_id, fan_temps);
1163 		}
1164 
1165 		fan_data->id = id;
1166 		fan_data->min_rpm = min_rpm;
1167 		fan_data->max_rpm = max_rpm;
1168 		bitmap_gather(gather, fan_temps, priv->temp_sensors, AWCC_ID_BITMAP_SIZE);
1169 		bitmap_copy(&fan_data->auto_channels_temp, gather, BITS_PER_LONG);
1170 		priv->fan_data[i] = fan_data;
1171 	}
1172 
1173 	return 0;
1174 }
1175 
1176 static int awcc_hwmon_init(struct wmi_device *wdev)
1177 {
1178 	struct awcc_priv *priv = dev_get_drvdata(&wdev->dev);
1179 	int ret;
1180 
1181 	priv->fan_data = devm_kcalloc(&wdev->dev, priv->fan_count,
1182 				      sizeof(*priv->fan_data), GFP_KERNEL);
1183 	if (!priv->fan_data)
1184 		return -ENOMEM;
1185 
1186 	ret = awcc_hwmon_temps_init(wdev);
1187 	if (ret)
1188 		return ret;
1189 
1190 	ret = awcc_hwmon_fans_init(wdev);
1191 	if (ret)
1192 		return ret;
1193 
1194 	priv->hwdev = devm_hwmon_device_register_with_info(&wdev->dev, "alienware_wmi",
1195 							   priv, &awcc_hwmon_chip_info,
1196 							   awcc_hwmon_groups);
1197 
1198 	return PTR_ERR_OR_ZERO(priv->hwdev);
1199 }
1200 
1201 static void awcc_hwmon_suspend(struct device *dev)
1202 {
1203 	struct awcc_priv *priv = dev_get_drvdata(dev);
1204 	struct awcc_fan_data *fan;
1205 	unsigned int i;
1206 	u32 boost;
1207 	int ret;
1208 
1209 	for (i = 0; i < priv->fan_count; i++) {
1210 		fan = priv->fan_data[i];
1211 
1212 		ret = awcc_thermal_information(priv->wdev, AWCC_OP_GET_FAN_BOOST,
1213 					       fan->id, &boost);
1214 		if (ret)
1215 			dev_err(dev, "Failed to store Fan %u boost while suspending\n", i);
1216 
1217 		fan->suspend_cache = ret ? 0 : clamp_val(boost, 0, 255);
1218 
1219 		awcc_op_set_fan_boost(priv->wdev, fan->id, 0);
1220 		if (ret)
1221 			dev_err(dev, "Failed to set Fan %u boost to 0 while suspending\n", i);
1222 	}
1223 }
1224 
1225 static void awcc_hwmon_resume(struct device *dev)
1226 {
1227 	struct awcc_priv *priv = dev_get_drvdata(dev);
1228 	struct awcc_fan_data *fan;
1229 	unsigned int i;
1230 	int ret;
1231 
1232 	for (i = 0; i < priv->fan_count; i++) {
1233 		fan = priv->fan_data[i];
1234 
1235 		if (!fan->suspend_cache)
1236 			continue;
1237 
1238 		ret = awcc_op_set_fan_boost(priv->wdev, fan->id, fan->suspend_cache);
1239 		if (ret)
1240 			dev_err(dev, "Failed to restore Fan %u boost while resuming\n", i);
1241 	}
1242 }
1243 
1244 /*
1245  * Thermal Profile control
1246  *  - Provides thermal profile control through the Platform Profile API
1247  */
1248 static int awcc_platform_profile_get(struct device *dev,
1249 				     enum platform_profile_option *profile)
1250 {
1251 	struct awcc_priv *priv = dev_get_drvdata(dev);
1252 	u32 out_data;
1253 	int ret;
1254 
1255 	ret = awcc_op_get_current_profile(priv->wdev, &out_data);
1256 	if (ret)
1257 		return ret;
1258 
1259 	switch (out_data) {
1260 	case AWCC_SPECIAL_PROFILE_CUSTOM:
1261 		*profile = PLATFORM_PROFILE_CUSTOM;
1262 		return 0;
1263 	case AWCC_SPECIAL_PROFILE_GMODE:
1264 		*profile = PLATFORM_PROFILE_PERFORMANCE;
1265 		return 0;
1266 	default:
1267 		break;
1268 	}
1269 
1270 	if (!is_awcc_thermal_profile_id(out_data))
1271 		return -ENODATA;
1272 
1273 	out_data = FIELD_GET(AWCC_THERMAL_MODE_MASK, out_data);
1274 	*profile = awcc_mode_to_platform_profile[out_data];
1275 
1276 	return 0;
1277 }
1278 
1279 static int awcc_platform_profile_set(struct device *dev,
1280 				     enum platform_profile_option profile)
1281 {
1282 	struct awcc_priv *priv = dev_get_drvdata(dev);
1283 
1284 	if (awcc->gmode) {
1285 		u32 gmode_status;
1286 		int ret;
1287 
1288 		ret = awcc_game_shift_status(priv->wdev,
1289 					     AWCC_OP_GET_GAME_SHIFT_STATUS,
1290 					     &gmode_status);
1291 
1292 		if (ret < 0)
1293 			return ret;
1294 
1295 		if ((profile == PLATFORM_PROFILE_PERFORMANCE && !gmode_status) ||
1296 		    (profile != PLATFORM_PROFILE_PERFORMANCE && gmode_status)) {
1297 			ret = awcc_game_shift_status(priv->wdev,
1298 						     AWCC_OP_TOGGLE_GAME_SHIFT,
1299 						     &gmode_status);
1300 
1301 			if (ret < 0)
1302 				return ret;
1303 		}
1304 	}
1305 
1306 	return awcc_op_activate_profile(priv->wdev, priv->supported_profiles[profile]);
1307 }
1308 
1309 static int awcc_platform_profile_probe(void *drvdata, unsigned long *choices)
1310 {
1311 	enum platform_profile_option profile;
1312 	struct awcc_priv *priv = drvdata;
1313 	enum awcc_thermal_profile mode;
1314 	u8 id, offset = 0;
1315 	int ret;
1316 
1317 	/*
1318 	 * Thermal profile IDs are listed last at offset
1319 	 *	fan_count + temp_count + unknown_count
1320 	 */
1321 	for (unsigned int i = 0; i < ARRAY_SIZE(priv->res_count) - 1; i++)
1322 		offset += priv->res_count[i];
1323 
1324 	for (unsigned int i = 0; i < priv->profile_count; i++) {
1325 		ret = awcc_op_get_resource_id(priv->wdev, i + offset, &id);
1326 		/*
1327 		 * Some devices report an incorrect number of thermal profiles
1328 		 * so the resource ID list may end prematurely
1329 		 */
1330 		if (ret == -EBADRQC)
1331 			break;
1332 		if (ret)
1333 			return ret;
1334 
1335 		if (!is_awcc_thermal_profile_id(id)) {
1336 			dev_dbg(&priv->wdev->dev, "Unmapped thermal profile ID 0x%02x\n", id);
1337 			continue;
1338 		}
1339 
1340 		mode = FIELD_GET(AWCC_THERMAL_MODE_MASK, id);
1341 		profile = awcc_mode_to_platform_profile[mode];
1342 		priv->supported_profiles[profile] = id;
1343 
1344 		__set_bit(profile, choices);
1345 	}
1346 
1347 	if (bitmap_empty(choices, PLATFORM_PROFILE_LAST))
1348 		return -ENODEV;
1349 
1350 	if (awcc->gmode) {
1351 		priv->supported_profiles[PLATFORM_PROFILE_PERFORMANCE] =
1352 			AWCC_SPECIAL_PROFILE_GMODE;
1353 
1354 		__set_bit(PLATFORM_PROFILE_PERFORMANCE, choices);
1355 	}
1356 
1357 	/* Every model supports the "custom" profile */
1358 	priv->supported_profiles[PLATFORM_PROFILE_CUSTOM] =
1359 		AWCC_SPECIAL_PROFILE_CUSTOM;
1360 
1361 	__set_bit(PLATFORM_PROFILE_CUSTOM, choices);
1362 
1363 	return 0;
1364 }
1365 
1366 static const struct platform_profile_ops awcc_platform_profile_ops = {
1367 	.probe = awcc_platform_profile_probe,
1368 	.profile_get = awcc_platform_profile_get,
1369 	.profile_set = awcc_platform_profile_set,
1370 };
1371 
1372 static int awcc_platform_profile_init(struct wmi_device *wdev)
1373 {
1374 	struct awcc_priv *priv = dev_get_drvdata(&wdev->dev);
1375 
1376 	priv->ppdev = devm_platform_profile_register(&wdev->dev, "alienware-wmi",
1377 						     priv, &awcc_platform_profile_ops);
1378 
1379 	return PTR_ERR_OR_ZERO(priv->ppdev);
1380 }
1381 
1382 /*
1383  * DebugFS
1384  */
1385 static int awcc_debugfs_system_description_read(struct seq_file *seq, void *data)
1386 {
1387 	struct device *dev = seq->private;
1388 	struct awcc_priv *priv = dev_get_drvdata(dev);
1389 
1390 	seq_printf(seq, "0x%08x\n", priv->system_description);
1391 
1392 	return 0;
1393 }
1394 
1395 static int awcc_debugfs_hwmon_data_read(struct seq_file *seq, void *data)
1396 {
1397 	struct device *dev = seq->private;
1398 	struct awcc_priv *priv = dev_get_drvdata(dev);
1399 	const struct awcc_fan_data *fan;
1400 	unsigned int bit;
1401 
1402 	seq_printf(seq, "Number of fans: %u\n", priv->fan_count);
1403 	seq_printf(seq, "Number of temperature sensors: %u\n\n", priv->temp_count);
1404 
1405 	for (u32 i = 0; i < priv->fan_count; i++) {
1406 		fan = priv->fan_data[i];
1407 
1408 		seq_printf(seq, "Fan %u:\n", i);
1409 		seq_printf(seq, "  ID: 0x%02x\n", fan->id);
1410 		seq_printf(seq, "  Related temperature sensors bitmap: %lu\n",
1411 			   fan->auto_channels_temp);
1412 	}
1413 
1414 	seq_puts(seq, "\nTemperature sensor IDs:\n");
1415 	for_each_set_bit(bit, priv->temp_sensors, AWCC_ID_BITMAP_SIZE)
1416 		seq_printf(seq, "  0x%02x\n", bit);
1417 
1418 	return 0;
1419 }
1420 
1421 static int awcc_debugfs_pprof_data_read(struct seq_file *seq, void *data)
1422 {
1423 	struct device *dev = seq->private;
1424 	struct awcc_priv *priv = dev_get_drvdata(dev);
1425 
1426 	seq_printf(seq, "Number of thermal profiles: %u\n\n", priv->profile_count);
1427 
1428 	for (u32 i = 0; i < PLATFORM_PROFILE_LAST; i++) {
1429 		if (!priv->supported_profiles[i])
1430 			continue;
1431 
1432 		seq_printf(seq, "Platform profile %u:\n", i);
1433 		seq_printf(seq, "  ID: 0x%02x\n", priv->supported_profiles[i]);
1434 	}
1435 
1436 	return 0;
1437 }
1438 
1439 static int awcc_gpio_pin_show(struct seq_file *seq, void *data)
1440 {
1441 	unsigned long pin = debugfs_get_aux_num(seq->file);
1442 	struct wmi_device *wdev = seq->private;
1443 	u32 status;
1444 	int ret;
1445 
1446 	ret = awcc_read_gpio_status(wdev, pin, &status);
1447 	if (ret)
1448 		return ret;
1449 
1450 	seq_printf(seq, "%u\n", status);
1451 
1452 	return 0;
1453 }
1454 
1455 static ssize_t awcc_gpio_pin_write(struct file *file, const char __user *buf,
1456 				   size_t count, loff_t *ppos)
1457 {
1458 	unsigned long pin = debugfs_get_aux_num(file);
1459 	struct seq_file *seq = file->private_data;
1460 	struct wmi_device *wdev = seq->private;
1461 	bool status;
1462 	int ret;
1463 
1464 	if (!ppos || *ppos)
1465 		return -EINVAL;
1466 
1467 	ret = kstrtobool_from_user(buf, count, &status);
1468 	if (ret)
1469 		return ret;
1470 
1471 	ret = awcc_fwup_gpio_control(wdev, pin, status);
1472 	if (ret)
1473 		return ret;
1474 
1475 	return count;
1476 }
1477 
1478 DEFINE_SHOW_STORE_ATTRIBUTE(awcc_gpio_pin);
1479 
1480 static void awcc_debugfs_remove(void *data)
1481 {
1482 	struct dentry *root = data;
1483 
1484 	debugfs_remove(root);
1485 }
1486 
1487 static void awcc_debugfs_init(struct wmi_device *wdev)
1488 {
1489 	struct awcc_priv *priv = dev_get_drvdata(&wdev->dev);
1490 	struct dentry *root, *gpio_ctl;
1491 	u32 gpio_count;
1492 	char name[64];
1493 	int ret;
1494 
1495 	scnprintf(name, sizeof(name), "%s-%s", "alienware-wmi", dev_name(&wdev->dev));
1496 	root = debugfs_create_dir(name, NULL);
1497 
1498 	debugfs_create_devm_seqfile(&wdev->dev, "system_description", root,
1499 				    awcc_debugfs_system_description_read);
1500 
1501 	if (awcc->hwmon)
1502 		debugfs_create_devm_seqfile(&wdev->dev, "hwmon_data", root,
1503 					    awcc_debugfs_hwmon_data_read);
1504 
1505 	if (awcc->pprof)
1506 		debugfs_create_devm_seqfile(&wdev->dev, "pprof_data", root,
1507 					    awcc_debugfs_pprof_data_read);
1508 
1509 	ret = awcc_read_total_gpios(wdev, &gpio_count);
1510 	if (ret) {
1511 		dev_dbg(&wdev->dev, "Failed to get total GPIO Pin count\n");
1512 		goto out_add_action;
1513 	} else if (gpio_count > AWCC_MAX_RES_COUNT) {
1514 		dev_dbg(&wdev->dev, "Reported GPIO Pin count may be incorrect: %u\n", gpio_count);
1515 		goto out_add_action;
1516 	}
1517 
1518 	gpio_ctl = debugfs_create_dir("gpio_ctl", root);
1519 
1520 	priv->gpio_count = gpio_count;
1521 	debugfs_create_u32("total_gpios", 0444, gpio_ctl, &priv->gpio_count);
1522 
1523 	for (unsigned int i = 0; i < gpio_count; i++) {
1524 		scnprintf(name, sizeof(name), "pin%u", i);
1525 		debugfs_create_file_aux_num(name, 0644, gpio_ctl, wdev, i,
1526 					    &awcc_gpio_pin_fops);
1527 	}
1528 
1529 out_add_action:
1530 	devm_add_action_or_reset(&wdev->dev, awcc_debugfs_remove, root);
1531 }
1532 
1533 static int alienware_awcc_setup(struct wmi_device *wdev)
1534 {
1535 	struct awcc_priv *priv;
1536 	int ret;
1537 
1538 	priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL);
1539 	if (!priv)
1540 		return -ENOMEM;
1541 
1542 	ret = awcc_thermal_information(wdev, AWCC_OP_GET_SYSTEM_DESCRIPTION,
1543 				       0, &priv->system_description);
1544 	if (ret < 0)
1545 		return ret;
1546 
1547 	/* Sanity check */
1548 	for (unsigned int i = 0; i < ARRAY_SIZE(priv->res_count); i++) {
1549 		if (priv->res_count[i] > AWCC_MAX_RES_COUNT) {
1550 			dev_err(&wdev->dev, "Malformed system description: 0x%08x\n",
1551 				priv->system_description);
1552 			return -ENXIO;
1553 		}
1554 	}
1555 
1556 	priv->wdev = wdev;
1557 	dev_set_drvdata(&wdev->dev, priv);
1558 
1559 	if (awcc->hwmon) {
1560 		ret = awcc_hwmon_init(wdev);
1561 		if (ret)
1562 			return ret;
1563 	}
1564 
1565 	if (awcc->pprof) {
1566 		ret = awcc_platform_profile_init(wdev);
1567 		if (ret)
1568 			return ret;
1569 	}
1570 
1571 	awcc_debugfs_init(wdev);
1572 
1573 	return 0;
1574 }
1575 
1576 /*
1577  * WMAX WMI driver
1578  */
1579 static int wmax_wmi_update_led(struct alienfx_priv *priv,
1580 			       struct wmi_device *wdev, u8 location)
1581 {
1582 	struct wmax_led_args in_args = {
1583 		.led_mask = 1 << location,
1584 		.colors = priv->colors[location],
1585 		.state = priv->lighting_control_state,
1586 	};
1587 
1588 	return alienware_wmi_command(wdev, WMAX_METHOD_ZONE_CONTROL, &in_args,
1589 				     sizeof(in_args), NULL);
1590 }
1591 
1592 static int wmax_wmi_update_brightness(struct alienfx_priv *priv,
1593 				      struct wmi_device *wdev, u8 brightness)
1594 {
1595 	struct wmax_brightness_args in_args = {
1596 		.led_mask = 0xFF,
1597 		.percentage = brightness,
1598 	};
1599 
1600 	return alienware_wmi_command(wdev, WMAX_METHOD_BRIGHTNESS, &in_args,
1601 				     sizeof(in_args), NULL);
1602 }
1603 
1604 static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
1605 {
1606 	struct alienfx_platdata pdata = {
1607 		.wdev = wdev,
1608 		.ops = {
1609 			.upd_led = wmax_wmi_update_led,
1610 			.upd_brightness = wmax_wmi_update_brightness,
1611 		},
1612 	};
1613 	int ret;
1614 
1615 	if (awcc)
1616 		ret = alienware_awcc_setup(wdev);
1617 	else
1618 		ret = alienware_alienfx_setup(&pdata);
1619 
1620 	return ret;
1621 }
1622 
1623 static int wmax_wmi_suspend(struct device *dev)
1624 {
1625 	if (awcc->hwmon)
1626 		awcc_hwmon_suspend(dev);
1627 
1628 	return 0;
1629 }
1630 
1631 static int wmax_wmi_resume(struct device *dev)
1632 {
1633 	if (awcc->hwmon)
1634 		awcc_hwmon_resume(dev);
1635 
1636 	return 0;
1637 }
1638 
1639 static DEFINE_SIMPLE_DEV_PM_OPS(wmax_wmi_pm_ops, wmax_wmi_suspend, wmax_wmi_resume);
1640 
1641 static const struct wmi_device_id alienware_wmax_device_id_table[] = {
1642 	{ WMAX_CONTROL_GUID, NULL },
1643 	{ },
1644 };
1645 MODULE_DEVICE_TABLE(wmi, alienware_wmax_device_id_table);
1646 
1647 static struct wmi_driver alienware_wmax_wmi_driver = {
1648 	.driver = {
1649 		.name = "alienware-wmi-wmax",
1650 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
1651 		.pm = pm_sleep_ptr(&wmax_wmi_pm_ops),
1652 	},
1653 	.id_table = alienware_wmax_device_id_table,
1654 	.probe = wmax_wmi_probe,
1655 	.no_singleton = true,
1656 };
1657 
1658 int __init alienware_wmax_wmi_init(void)
1659 {
1660 	const struct dmi_system_id *id;
1661 
1662 	id = dmi_first_match(awcc_dmi_table);
1663 	if (id)
1664 		awcc = id->driver_data;
1665 
1666 	if (force_hwmon) {
1667 		if (!awcc)
1668 			awcc = &empty_quirks;
1669 
1670 		awcc->hwmon = true;
1671 	}
1672 
1673 	if (force_platform_profile) {
1674 		if (!awcc)
1675 			awcc = &empty_quirks;
1676 
1677 		awcc->pprof = true;
1678 	}
1679 
1680 	if (force_gmode) {
1681 		if (awcc)
1682 			awcc->gmode = true;
1683 		else
1684 			pr_warn("force_gmode requires platform profile support\n");
1685 	}
1686 
1687 	return wmi_driver_register(&alienware_wmax_wmi_driver);
1688 }
1689 
1690 void __exit alienware_wmax_wmi_exit(void)
1691 {
1692 	wmi_driver_unregister(&alienware_wmax_wmi_driver);
1693 }
1694