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