xref: /linux/drivers/platform/x86/asus-armoury.h (revision 9d588a1140b9ae211581a7a154d0b806d8cd8238)
1 /* SPDX-License-Identifier: GPL-2.0
2  *
3  * Definitions for kernel modules using asus-armoury driver
4  *
5  * Copyright (c) 2024 Luke Jones <luke@ljones.dev>
6  */
7 
8 #ifndef _ASUS_ARMOURY_H_
9 #define _ASUS_ARMOURY_H_
10 
11 #include <linux/dmi.h>
12 #include <linux/platform_device.h>
13 #include <linux/sysfs.h>
14 #include <linux/types.h>
15 
16 #define DRIVER_NAME "asus-armoury"
17 
18 /**
19  * armoury_attr_uint_store() - Send an uint to WMI method if within min/max.
20  * @kobj: Pointer to the driver object.
21  * @attr: Pointer to the attribute calling this function.
22  * @buf: The buffer to read from, this is parsed to `uint` type.
23  * @count: Required by sysfs attribute macros, pass in from the callee attr.
24  * @min: Minimum accepted value. Below this returns -EINVAL.
25  * @max: Maximum accepted value. Above this returns -EINVAL.
26  * @store_value: Pointer to where the parsed value should be stored.
27  * @wmi_dev: The WMI function ID to use.
28  *
29  * This function is intended to be generic so it can be called from any "_store"
30  * attribute which works only with integers.
31  *
32  * Integers to be sent to the WMI method is inclusive range checked and
33  * an error returned if out of range.
34  *
35  * If the value is valid and WMI is success then the sysfs attribute is notified
36  * and if asus_bios_requires_reboot() is true then reboot attribute
37  * is also notified.
38  *
39  * Returns: Either count, or an error.
40  */
41 ssize_t armoury_attr_uint_store(struct kobject *kobj, struct kobj_attribute *attr,
42 				const char *buf, size_t count, u32 min, u32 max,
43 				u32 *store_value, u32 wmi_dev);
44 
45 /**
46  * armoury_attr_uint_show() - Receive an uint from a WMI method.
47  * @kobj: Pointer to the driver object.
48  * @attr: Pointer to the attribute calling this function.
49  * @buf: The buffer to write to, as an `uint` type.
50  * @wmi_dev: The WMI function ID to use.
51  *
52  * This function is intended to be generic so it can be called from any "_show"
53  * attribute which works only with integers.
54  *
55  * Returns: Either count, or an error.
56  */
57 ssize_t armoury_attr_uint_show(struct kobject *kobj, struct kobj_attribute *attr,
58 				char *buf, u32 wmi_dev);
59 
60 #define __ASUS_ATTR_RO(_func, _name)					\
61 	{								\
62 		.attr = { .name = __stringify(_name), .mode = 0444 },	\
63 		.show = _func##_##_name##_show,				\
64 	}
65 
66 #define __ASUS_ATTR_RO_AS(_name, _show)					\
67 	{								\
68 		.attr = { .name = __stringify(_name), .mode = 0444 },	\
69 		.show = _show,						\
70 	}
71 
72 #define __ASUS_ATTR_RW(_func, _name) \
73 	__ATTR(_name, 0644, _func##_##_name##_show, _func##_##_name##_store)
74 
75 #define __WMI_STORE_INT(_attr, _min, _max, _wmi)				\
76 	static ssize_t _attr##_store(struct kobject *kobj,			\
77 				     struct kobj_attribute *attr,		\
78 				     const char *buf, size_t count)		\
79 	{									\
80 		return armoury_attr_uint_store(kobj, attr, buf, count, _min,	\
81 					_max, NULL, _wmi);			\
82 	}
83 
84 #define ASUS_WMI_SHOW_INT(_attr, _wmi)						\
85 	static ssize_t _attr##_show(struct kobject *kobj,			\
86 				    struct kobj_attribute *attr, char *buf)	\
87 	{									\
88 		return armoury_attr_uint_show(kobj, attr, buf, _wmi);		\
89 	}
90 
91 /* Create functions and attributes for use in other macros or on their own */
92 
93 /* Shows a formatted static variable */
94 #define __ATTR_SHOW_FMT(_prop, _attrname, _fmt, _val)				\
95 	static ssize_t _attrname##_##_prop##_show(				\
96 		struct kobject *kobj, struct kobj_attribute *attr, char *buf)	\
97 	{									\
98 		return sysfs_emit(buf, _fmt, _val);				\
99 	}									\
100 	static struct kobj_attribute attr_##_attrname##_##_prop =		\
101 		__ASUS_ATTR_RO(_attrname, _prop)
102 
103 #define __ATTR_RO_INT_GROUP_ENUM(_attrname, _wmi, _fsname, _possible, _dispname)\
104 	ASUS_WMI_SHOW_INT(_attrname##_current_value, _wmi);		\
105 	static struct kobj_attribute attr_##_attrname##_current_value =		\
106 		__ASUS_ATTR_RO(_attrname, current_value);			\
107 	__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname);		\
108 	__ATTR_SHOW_FMT(possible_values, _attrname, "%s\n", _possible);		\
109 	static struct kobj_attribute attr_##_attrname##_type =			\
110 		__ASUS_ATTR_RO_AS(type, enum_type_show);			\
111 	static struct attribute *_attrname##_attrs[] = {			\
112 		&attr_##_attrname##_current_value.attr,				\
113 		&attr_##_attrname##_display_name.attr,				\
114 		&attr_##_attrname##_possible_values.attr,			\
115 		&attr_##_attrname##_type.attr,					\
116 		NULL								\
117 	};									\
118 	static const struct attribute_group _attrname##_attr_group = {		\
119 		.name = _fsname, .attrs = _attrname##_attrs			\
120 	}
121 
122 #define __ATTR_RW_INT_GROUP_ENUM(_attrname, _minv, _maxv, _wmi, _fsname,\
123 				 _possible, _dispname)			\
124 	__WMI_STORE_INT(_attrname##_current_value, _minv, _maxv, _wmi);	\
125 	ASUS_WMI_SHOW_INT(_attrname##_current_value, _wmi);	\
126 	static struct kobj_attribute attr_##_attrname##_current_value =	\
127 		__ASUS_ATTR_RW(_attrname, current_value);		\
128 	__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname);	\
129 	__ATTR_SHOW_FMT(possible_values, _attrname, "%s\n", _possible);	\
130 	static struct kobj_attribute attr_##_attrname##_type =		\
131 		__ASUS_ATTR_RO_AS(type, enum_type_show);		\
132 	static struct attribute *_attrname##_attrs[] = {		\
133 		&attr_##_attrname##_current_value.attr,			\
134 		&attr_##_attrname##_display_name.attr,			\
135 		&attr_##_attrname##_possible_values.attr,		\
136 		&attr_##_attrname##_type.attr,				\
137 		NULL							\
138 	};								\
139 	static const struct attribute_group _attrname##_attr_group = {	\
140 		.name = _fsname, .attrs = _attrname##_attrs		\
141 	}
142 
143 /* Boolean style enumeration, base macro. Requires adding show/store */
144 #define __ATTR_GROUP_ENUM(_attrname, _fsname, _possible, _dispname)	\
145 	__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname);	\
146 	__ATTR_SHOW_FMT(possible_values, _attrname, "%s\n", _possible);	\
147 	static struct kobj_attribute attr_##_attrname##_type =		\
148 		__ASUS_ATTR_RO_AS(type, enum_type_show);		\
149 	static struct attribute *_attrname##_attrs[] = {		\
150 		&attr_##_attrname##_current_value.attr,			\
151 		&attr_##_attrname##_display_name.attr,			\
152 		&attr_##_attrname##_possible_values.attr,		\
153 		&attr_##_attrname##_type.attr,				\
154 		NULL							\
155 	};								\
156 	static const struct attribute_group _attrname##_attr_group = {	\
157 		.name = _fsname, .attrs = _attrname##_attrs		\
158 	}
159 
160 #define ASUS_ATTR_GROUP_BOOL_RO(_attrname, _fsname, _wmi, _dispname)	\
161 	__ATTR_RO_INT_GROUP_ENUM(_attrname, _wmi, _fsname, "0;1", _dispname)
162 
163 
164 #define ASUS_ATTR_GROUP_BOOL_RW(_attrname, _fsname, _wmi, _dispname)	\
165 	__ATTR_RW_INT_GROUP_ENUM(_attrname, 0, 1, _wmi, _fsname, "0;1", _dispname)
166 
167 #define ASUS_ATTR_GROUP_ENUM_INT_RO(_attrname, _fsname, _wmi, _possible, _dispname)	\
168 	__ATTR_RO_INT_GROUP_ENUM(_attrname, _wmi, _fsname, _possible, _dispname)
169 
170 /*
171  * Requires <name>_current_value_show(), <name>_current_value_show()
172  */
173 #define ASUS_ATTR_GROUP_BOOL(_attrname, _fsname, _dispname)		\
174 	static struct kobj_attribute attr_##_attrname##_current_value =	\
175 		__ASUS_ATTR_RW(_attrname, current_value);		\
176 	__ATTR_GROUP_ENUM(_attrname, _fsname, "0;1", _dispname)
177 
178 /*
179  * Requires <name>_current_value_show(), <name>_current_value_show()
180  * and <name>_possible_values_show()
181  */
182 #define ASUS_ATTR_GROUP_ENUM(_attrname, _fsname, _dispname)			\
183 	__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname);		\
184 	static struct kobj_attribute attr_##_attrname##_current_value =		\
185 		__ASUS_ATTR_RW(_attrname, current_value);			\
186 	static struct kobj_attribute attr_##_attrname##_possible_values =	\
187 		__ASUS_ATTR_RO(_attrname, possible_values);			\
188 	static struct kobj_attribute attr_##_attrname##_type =			\
189 		__ASUS_ATTR_RO_AS(type, enum_type_show);			\
190 	static struct attribute *_attrname##_attrs[] = {			\
191 		&attr_##_attrname##_current_value.attr,				\
192 		&attr_##_attrname##_display_name.attr,				\
193 		&attr_##_attrname##_possible_values.attr,			\
194 		&attr_##_attrname##_type.attr,					\
195 		NULL								\
196 	};									\
197 	static const struct attribute_group _attrname##_attr_group = {		\
198 		.name = _fsname, .attrs = _attrname##_attrs			\
199 	}
200 
201 #define ASUS_ATTR_GROUP_INT_VALUE_ONLY_RO(_attrname, _fsname, _wmi, _dispname)	\
202 	ASUS_WMI_SHOW_INT(_attrname##_current_value, _wmi);		\
203 	static struct kobj_attribute attr_##_attrname##_current_value =		\
204 		__ASUS_ATTR_RO(_attrname, current_value);			\
205 	__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname);		\
206 	static struct kobj_attribute attr_##_attrname##_type =			\
207 		__ASUS_ATTR_RO_AS(type, int_type_show);				\
208 	static struct attribute *_attrname##_attrs[] = {			\
209 		&attr_##_attrname##_current_value.attr,				\
210 		&attr_##_attrname##_display_name.attr,				\
211 		&attr_##_attrname##_type.attr, NULL				\
212 	};									\
213 	static const struct attribute_group _attrname##_attr_group = {		\
214 		.name = _fsname, .attrs = _attrname##_attrs			\
215 	}
216 
217 /*
218  * ROG PPT attributes need a little different in setup as they
219  * require rog_tunables members.
220  */
221 
222 #define __ROG_TUNABLE_SHOW(_prop, _attrname, _val)				\
223 	static ssize_t _attrname##_##_prop##_show(				\
224 		struct kobject *kobj, struct kobj_attribute *attr, char *buf)	\
225 	{									\
226 		struct rog_tunables *tunables = get_current_tunables();		\
227 										\
228 		if (!tunables || !tunables->power_limits)			\
229 			return -ENODEV;						\
230 										\
231 		return sysfs_emit(buf, "%d\n", tunables->power_limits->_val);	\
232 	}									\
233 	static struct kobj_attribute attr_##_attrname##_##_prop =		\
234 		__ASUS_ATTR_RO(_attrname, _prop)
235 
236 #define __ROG_TUNABLE_SHOW_DEFAULT(_attrname)					\
237 	static ssize_t _attrname##_default_value_show(				\
238 		struct kobject *kobj, struct kobj_attribute *attr, char *buf)	\
239 	{									\
240 		struct rog_tunables *tunables = get_current_tunables();		\
241 										\
242 		if (!tunables || !tunables->power_limits)			\
243 			return -ENODEV;						\
244 										\
245 		return sysfs_emit(						\
246 			buf, "%d\n",						\
247 			tunables->power_limits->_attrname##_def ?		\
248 				tunables->power_limits->_attrname##_def :	\
249 				tunables->power_limits->_attrname##_max);	\
250 	}									\
251 	static struct kobj_attribute attr_##_attrname##_default_value =		\
252 		__ASUS_ATTR_RO(_attrname, default_value)
253 
254 #define __ROG_TUNABLE_RW(_attr, _wmi)						\
255 	static ssize_t _attr##_current_value_store(				\
256 		struct kobject *kobj, struct kobj_attribute *attr,		\
257 		const char *buf, size_t count)					\
258 	{									\
259 		struct rog_tunables *tunables = get_current_tunables();		\
260 										\
261 		if (!tunables || !tunables->power_limits)			\
262 			return -ENODEV;						\
263 										\
264 		if (tunables->power_limits->_attr##_min ==			\
265 		    tunables->power_limits->_attr##_max)			\
266 			return -EINVAL;						\
267 										\
268 		return armoury_attr_uint_store(kobj, attr, buf, count,		\
269 				       tunables->power_limits->_attr##_min,	\
270 				       tunables->power_limits->_attr##_max,	\
271 				       &tunables->_attr, _wmi);			\
272 	}									\
273 	static ssize_t _attr##_current_value_show(				\
274 		struct kobject *kobj, struct kobj_attribute *attr, char *buf)	\
275 	{									\
276 		struct rog_tunables *tunables = get_current_tunables();		\
277 										\
278 		if (!tunables)							\
279 			return -ENODEV;						\
280 										\
281 		return sysfs_emit(buf, "%u\n", tunables->_attr);		\
282 	}									\
283 	static struct kobj_attribute attr_##_attr##_current_value =		\
284 		__ASUS_ATTR_RW(_attr, current_value)
285 
286 #define ASUS_ATTR_GROUP_ROG_TUNABLE(_attrname, _fsname, _wmi, _dispname)	\
287 	__ROG_TUNABLE_RW(_attrname, _wmi);				\
288 	__ROG_TUNABLE_SHOW_DEFAULT(_attrname);				\
289 	__ROG_TUNABLE_SHOW(min_value, _attrname, _attrname##_min);	\
290 	__ROG_TUNABLE_SHOW(max_value, _attrname, _attrname##_max);	\
291 	__ATTR_SHOW_FMT(scalar_increment, _attrname, "%d\n", 1);	\
292 	__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname);	\
293 	static struct kobj_attribute attr_##_attrname##_type =		\
294 		__ASUS_ATTR_RO_AS(type, int_type_show);			\
295 	static struct attribute *_attrname##_attrs[] = {		\
296 		&attr_##_attrname##_current_value.attr,			\
297 		&attr_##_attrname##_default_value.attr,			\
298 		&attr_##_attrname##_min_value.attr,			\
299 		&attr_##_attrname##_max_value.attr,			\
300 		&attr_##_attrname##_scalar_increment.attr,		\
301 		&attr_##_attrname##_display_name.attr,			\
302 		&attr_##_attrname##_type.attr,				\
303 		NULL							\
304 	};								\
305 	static const struct attribute_group _attrname##_attr_group = {	\
306 		.name = _fsname, .attrs = _attrname##_attrs		\
307 	}
308 
309 /* Default is always the maximum value unless *_def is specified */
310 struct power_limits {
311 	u8 ppt_pl1_spl_min;
312 	u8 ppt_pl1_spl_def;
313 	u8 ppt_pl1_spl_max;
314 	u8 ppt_pl2_sppt_min;
315 	u8 ppt_pl2_sppt_def;
316 	u8 ppt_pl2_sppt_max;
317 	u8 ppt_pl3_fppt_min;
318 	u8 ppt_pl3_fppt_def;
319 	u8 ppt_pl3_fppt_max;
320 	u8 ppt_apu_sppt_min;
321 	u8 ppt_apu_sppt_def;
322 	u8 ppt_apu_sppt_max;
323 	u8 ppt_platform_sppt_min;
324 	u8 ppt_platform_sppt_def;
325 	u8 ppt_platform_sppt_max;
326 	/* Nvidia GPU specific, default is always max */
327 	u8 nv_dynamic_boost_def; // unused. exists for macro
328 	u8 nv_dynamic_boost_min;
329 	u8 nv_dynamic_boost_max;
330 	u8 nv_temp_target_def; // unused. exists for macro
331 	u8 nv_temp_target_min;
332 	u8 nv_temp_target_max;
333 	u8 nv_tgp_def; // unused. exists for macro
334 	u8 nv_tgp_min;
335 	u8 nv_tgp_max;
336 };
337 
338 struct power_data {
339 		const struct power_limits *ac_data;
340 		const struct power_limits *dc_data;
341 		bool requires_fan_curve;
342 };
343 
344 /*
345  * For each available attribute there must be a min and a max.
346  * _def is not required and will be assumed to be default == max if missing.
347  */
348 static const struct dmi_system_id power_limits[] = {
349 	{
350 		.matches = {
351 			DMI_MATCH(DMI_BOARD_NAME, "FA401W"),
352 		},
353 		.driver_data = &(struct power_data) {
354 			.ac_data = &(struct power_limits) {
355 				.ppt_pl1_spl_min = 15,
356 				.ppt_pl1_spl_max = 80,
357 				.ppt_pl2_sppt_min = 35,
358 				.ppt_pl2_sppt_max = 80,
359 				.ppt_pl3_fppt_min = 35,
360 				.ppt_pl3_fppt_max = 80,
361 				.nv_dynamic_boost_min = 5,
362 				.nv_dynamic_boost_max = 25,
363 				.nv_temp_target_min = 75,
364 				.nv_temp_target_max = 87,
365 				.nv_tgp_min = 55,
366 				.nv_tgp_max = 75,
367 			},
368 			.dc_data = &(struct power_limits) {
369 				.ppt_pl1_spl_min = 25,
370 				.ppt_pl1_spl_max = 30,
371 				.ppt_pl2_sppt_min = 31,
372 				.ppt_pl2_sppt_max = 44,
373 				.ppt_pl3_fppt_min = 45,
374 				.ppt_pl3_fppt_max = 65,
375 				.nv_temp_target_min = 75,
376 				.nv_temp_target_max = 87,
377 			},
378 		},
379 	},
380 	{
381 		.matches = {
382 			DMI_MATCH(DMI_BOARD_NAME, "FA507N"),
383 		},
384 		.driver_data = &(struct power_data) {
385 			.ac_data = &(struct power_limits) {
386 				.ppt_pl1_spl_min = 15,
387 				.ppt_pl1_spl_max = 80,
388 				.ppt_pl2_sppt_min = 35,
389 				.ppt_pl2_sppt_max = 80,
390 				.ppt_pl3_fppt_min = 35,
391 				.ppt_pl3_fppt_max = 80,
392 				.nv_dynamic_boost_min = 5,
393 				.nv_dynamic_boost_max = 25,
394 				.nv_temp_target_min = 75,
395 				.nv_temp_target_max = 87,
396 			},
397 			.dc_data = &(struct power_limits) {
398 				.ppt_pl1_spl_min = 15,
399 				.ppt_pl1_spl_def = 45,
400 				.ppt_pl1_spl_max = 65,
401 				.ppt_pl2_sppt_min = 35,
402 				.ppt_pl2_sppt_def = 54,
403 				.ppt_pl2_sppt_max = 65,
404 				.ppt_pl3_fppt_min = 35,
405 				.ppt_pl3_fppt_max = 65,
406 				.nv_temp_target_min = 75,
407 				.nv_temp_target_max = 87,
408 			},
409 		},
410 	},
411 	{
412 		.matches = {
413 			DMI_MATCH(DMI_BOARD_NAME, "FA507UV"),
414 		},
415 		.driver_data = &(struct power_data) {
416 			.ac_data = &(struct power_limits) {
417 				.ppt_pl1_spl_min = 15,
418 				.ppt_pl1_spl_max = 80,
419 				.ppt_pl2_sppt_min = 35,
420 				.ppt_pl2_sppt_max = 80,
421 				.ppt_pl3_fppt_min = 35,
422 				.ppt_pl3_fppt_max = 80,
423 				.nv_dynamic_boost_min = 5,
424 				.nv_dynamic_boost_max = 25,
425 				.nv_temp_target_min = 75,
426 				.nv_temp_target_max = 87,
427 				.nv_tgp_min = 55,
428 				.nv_tgp_max = 115,
429 			},
430 			.dc_data = &(struct power_limits) {
431 				.ppt_pl1_spl_min = 15,
432 				.ppt_pl1_spl_def = 45,
433 				.ppt_pl1_spl_max = 65,
434 				.ppt_pl2_sppt_min = 35,
435 				.ppt_pl2_sppt_def = 54,
436 				.ppt_pl2_sppt_max = 65,
437 				.ppt_pl3_fppt_min = 35,
438 				.ppt_pl3_fppt_max = 65,
439 				.nv_temp_target_min = 75,
440 				.nv_temp_target_max = 87,
441 			},
442 		},
443 	},
444 	{
445 		.matches = {
446 			DMI_MATCH(DMI_BOARD_NAME, "FA507R"),
447 		},
448 		.driver_data = &(struct power_data) {
449 			.ac_data = &(struct power_limits) {
450 				.ppt_pl1_spl_min = 15,
451 				.ppt_pl1_spl_max = 80,
452 				.ppt_pl2_sppt_min = 25,
453 				.ppt_pl2_sppt_max = 80,
454 				.ppt_pl3_fppt_min = 35,
455 				.ppt_pl3_fppt_max = 80
456 			},
457 			.dc_data = NULL,
458 		},
459 	},
460 	{
461 		.matches = {
462 			DMI_MATCH(DMI_BOARD_NAME, "FA507X"),
463 		},
464 		.driver_data = &(struct power_data) {
465 			.ac_data = &(struct power_limits) {
466 				.ppt_pl1_spl_min = 15,
467 				.ppt_pl1_spl_max = 80,
468 				.ppt_pl2_sppt_min = 35,
469 				.ppt_pl2_sppt_max = 80,
470 				.ppt_pl3_fppt_min = 35,
471 				.ppt_pl3_fppt_max = 80,
472 				.nv_dynamic_boost_min = 5,
473 				.nv_dynamic_boost_max = 20,
474 				.nv_temp_target_min = 75,
475 				.nv_temp_target_max = 87,
476 				.nv_tgp_min = 55,
477 				.nv_tgp_max = 85,
478 			},
479 			.dc_data = &(struct power_limits) {
480 				.ppt_pl1_spl_min = 15,
481 				.ppt_pl1_spl_def = 45,
482 				.ppt_pl1_spl_max = 65,
483 				.ppt_pl2_sppt_min = 35,
484 				.ppt_pl2_sppt_def = 54,
485 				.ppt_pl2_sppt_max = 65,
486 				.ppt_pl3_fppt_min = 35,
487 				.ppt_pl3_fppt_max = 65,
488 				.nv_temp_target_min = 75,
489 				.nv_temp_target_max = 87,
490 			},
491 		},
492 	},
493 	{
494 		.matches = {
495 			DMI_MATCH(DMI_BOARD_NAME, "FA507Z"),
496 		},
497 		.driver_data = &(struct power_data) {
498 			.ac_data = &(struct power_limits) {
499 				.ppt_pl1_spl_min = 28,
500 				.ppt_pl1_spl_max = 65,
501 				.ppt_pl2_sppt_min = 28,
502 				.ppt_pl2_sppt_max = 105,
503 				.nv_dynamic_boost_min = 5,
504 				.nv_dynamic_boost_max = 15,
505 				.nv_temp_target_min = 75,
506 				.nv_temp_target_max = 87,
507 				.nv_tgp_min = 55,
508 				.nv_tgp_max = 85,
509 			},
510 			.dc_data = &(struct power_limits) {
511 				.ppt_pl1_spl_min = 25,
512 				.ppt_pl1_spl_max = 45,
513 				.ppt_pl2_sppt_min = 35,
514 				.ppt_pl2_sppt_max = 60,
515 				.nv_temp_target_min = 75,
516 				.nv_temp_target_max = 87,
517 			},
518 		},
519 	},
520 	{
521 		.matches = {
522 			DMI_MATCH(DMI_BOARD_NAME, "FA607P"),
523 		},
524 		.driver_data = &(struct power_data) {
525 			.ac_data = &(struct power_limits) {
526 				.ppt_pl1_spl_min = 30,
527 				.ppt_pl1_spl_def = 100,
528 				.ppt_pl1_spl_max = 135,
529 				.ppt_pl2_sppt_min = 30,
530 				.ppt_pl2_sppt_def = 115,
531 				.ppt_pl2_sppt_max = 135,
532 				.ppt_pl3_fppt_min = 30,
533 				.ppt_pl3_fppt_max = 135,
534 				.nv_dynamic_boost_min = 5,
535 				.nv_dynamic_boost_max = 25,
536 				.nv_temp_target_min = 75,
537 				.nv_temp_target_max = 87,
538 				.nv_tgp_min = 55,
539 				.nv_tgp_max = 115,
540 			},
541 			.dc_data = &(struct power_limits) {
542 				.ppt_pl1_spl_min = 25,
543 				.ppt_pl1_spl_def = 45,
544 				.ppt_pl1_spl_max = 80,
545 				.ppt_pl2_sppt_min = 25,
546 				.ppt_pl2_sppt_def = 60,
547 				.ppt_pl2_sppt_max = 80,
548 				.ppt_pl3_fppt_min = 25,
549 				.ppt_pl3_fppt_max = 80,
550 				.nv_temp_target_min = 75,
551 				.nv_temp_target_max = 87,
552 			},
553 		},
554 	},
555 	{
556 		.matches = {
557 			DMI_MATCH(DMI_BOARD_NAME, "FA608WI"),
558 		},
559 		.driver_data = &(struct power_data) {
560 			.ac_data = &(struct power_limits) {
561 				.ppt_pl1_spl_min = 15,
562 				.ppt_pl1_spl_def = 90,
563 				.ppt_pl1_spl_max = 90,
564 				.ppt_pl2_sppt_min = 35,
565 				.ppt_pl2_sppt_def = 90,
566 				.ppt_pl2_sppt_max = 90,
567 				.ppt_pl3_fppt_min = 35,
568 				.ppt_pl3_fppt_def = 90,
569 				.ppt_pl3_fppt_max = 90,
570 				.nv_dynamic_boost_min = 5,
571 				.nv_dynamic_boost_max = 25,
572 				.nv_temp_target_min = 75,
573 				.nv_temp_target_max = 87,
574 				.nv_tgp_min = 55,
575 				.nv_tgp_max = 115,
576 			},
577 			.dc_data = &(struct power_limits) {
578 				.ppt_pl1_spl_min = 15,
579 				.ppt_pl1_spl_def = 45,
580 				.ppt_pl1_spl_max = 65,
581 				.ppt_pl2_sppt_min = 35,
582 				.ppt_pl2_sppt_def = 54,
583 				.ppt_pl2_sppt_max = 65,
584 				.ppt_pl3_fppt_min = 35,
585 				.ppt_pl3_fppt_def = 65,
586 				.ppt_pl3_fppt_max = 65,
587 				.nv_temp_target_min = 75,
588 				.nv_temp_target_max = 87,
589 			},
590 		},
591 	},
592 	{
593 		.matches = {
594 			DMI_MATCH(DMI_BOARD_NAME, "FA617NS"),
595 		},
596 		.driver_data = &(struct power_data) {
597 			.ac_data = &(struct power_limits) {
598 				.ppt_apu_sppt_min = 15,
599 				.ppt_apu_sppt_max = 80,
600 				.ppt_platform_sppt_min = 30,
601 				.ppt_platform_sppt_max = 120,
602 			},
603 			.dc_data = &(struct power_limits) {
604 				.ppt_apu_sppt_min = 25,
605 				.ppt_apu_sppt_max = 35,
606 				.ppt_platform_sppt_min = 45,
607 				.ppt_platform_sppt_max = 100,
608 			},
609 		},
610 	},
611 	{
612 		.matches = {
613 			DMI_MATCH(DMI_BOARD_NAME, "FA617NT"),
614 		},
615 		.driver_data = &(struct power_data) {
616 			.ac_data = &(struct power_limits) {
617 				.ppt_apu_sppt_min = 15,
618 				.ppt_apu_sppt_max = 80,
619 				.ppt_platform_sppt_min = 30,
620 				.ppt_platform_sppt_max = 115,
621 			},
622 			.dc_data = &(struct power_limits) {
623 				.ppt_apu_sppt_min = 15,
624 				.ppt_apu_sppt_max = 45,
625 				.ppt_platform_sppt_min = 30,
626 				.ppt_platform_sppt_max = 50,
627 			},
628 		},
629 	},
630 	{
631 		.matches = {
632 			DMI_MATCH(DMI_BOARD_NAME, "FA617XS"),
633 		},
634 		.driver_data = &(struct power_data) {
635 			.ac_data = &(struct power_limits) {
636 				.ppt_apu_sppt_min = 15,
637 				.ppt_apu_sppt_max = 80,
638 				.ppt_platform_sppt_min = 30,
639 				.ppt_platform_sppt_max = 120,
640 				.nv_temp_target_min = 75,
641 				.nv_temp_target_max = 87,
642 			},
643 			.dc_data = &(struct power_limits) {
644 				.ppt_apu_sppt_min = 25,
645 				.ppt_apu_sppt_max = 35,
646 				.ppt_platform_sppt_min = 45,
647 				.ppt_platform_sppt_max = 100,
648 				.nv_temp_target_min = 75,
649 				.nv_temp_target_max = 87,
650 			},
651 		},
652 	},
653 	{
654 		.matches = {
655 			DMI_MATCH(DMI_BOARD_NAME, "FX507VI"),
656 		},
657 		.driver_data = &(struct power_data) {
658 			.ac_data = &(struct power_limits) {
659 				.ppt_pl1_spl_min = 28,
660 				.ppt_pl1_spl_max = 135,
661 				.ppt_pl2_sppt_min = 28,
662 				.ppt_pl2_sppt_max = 135,
663 				.nv_dynamic_boost_min = 5,
664 				.nv_dynamic_boost_max = 25,
665 				.nv_temp_target_min = 75,
666 				.nv_temp_target_max = 87,
667 			},
668 			.dc_data = &(struct power_limits) {
669 				.ppt_pl1_spl_min = 25,
670 				.ppt_pl1_spl_max = 45,
671 				.ppt_pl2_sppt_min = 35,
672 				.ppt_pl2_sppt_max = 60,
673 				.nv_temp_target_min = 75,
674 				.nv_temp_target_max = 87,
675 			},
676 			.requires_fan_curve = true,
677 		},
678 	},
679 	{
680 		.matches = {
681 			DMI_MATCH(DMI_BOARD_NAME, "FX507VV"),
682 		},
683 		.driver_data = &(struct power_data) {
684 			.ac_data = &(struct power_limits) {
685 				.ppt_pl1_spl_min = 28,
686 				.ppt_pl1_spl_def = 115,
687 				.ppt_pl1_spl_max = 135,
688 				.ppt_pl2_sppt_min = 28,
689 				.ppt_pl2_sppt_max = 135,
690 				.nv_dynamic_boost_min = 5,
691 				.nv_dynamic_boost_max = 25,
692 				.nv_temp_target_min = 75,
693 				.nv_temp_target_max = 87,
694 			},
695 			.dc_data = &(struct power_limits) {
696 				.ppt_pl1_spl_min = 25,
697 				.ppt_pl1_spl_max = 45,
698 				.ppt_pl2_sppt_min = 35,
699 				.ppt_pl2_sppt_max = 60,
700 				.nv_temp_target_min = 75,
701 				.nv_temp_target_max = 87,
702 			},
703 			.requires_fan_curve = true,
704 		},
705 	},
706 	{
707 		.matches = {
708 			DMI_MATCH(DMI_BOARD_NAME, "FX507Z"),
709 		},
710 		.driver_data = &(struct power_data) {
711 			.ac_data = &(struct power_limits) {
712 				.ppt_pl1_spl_min = 28,
713 				.ppt_pl1_spl_max = 90,
714 				.ppt_pl2_sppt_min = 28,
715 				.ppt_pl2_sppt_max = 135,
716 				.nv_dynamic_boost_min = 5,
717 				.nv_dynamic_boost_max = 15,
718 			},
719 			.dc_data = &(struct power_limits) {
720 				.ppt_pl1_spl_min = 25,
721 				.ppt_pl1_spl_max = 45,
722 				.ppt_pl2_sppt_min = 35,
723 				.ppt_pl2_sppt_max = 60,
724 			},
725 			.requires_fan_curve = true,
726 		},
727 	},
728 	{
729 		.matches = {
730 			DMI_MATCH(DMI_BOARD_NAME, "GA401Q"),
731 		},
732 		.driver_data = &(struct power_data) {
733 			.ac_data = &(struct power_limits) {
734 				.ppt_pl1_spl_min = 15,
735 				.ppt_pl1_spl_max = 80,
736 				.ppt_pl2_sppt_min = 15,
737 				.ppt_pl2_sppt_max = 80,
738 			},
739 			.dc_data = NULL,
740 		},
741 	},
742 	{
743 		.matches = {
744 			// This model is full AMD. No Nvidia dGPU.
745 			DMI_MATCH(DMI_BOARD_NAME, "GA402R"),
746 		},
747 		.driver_data = &(struct power_data) {
748 			.ac_data = &(struct power_limits) {
749 				.ppt_apu_sppt_min = 15,
750 				.ppt_apu_sppt_max = 80,
751 				.ppt_platform_sppt_min = 30,
752 				.ppt_platform_sppt_max = 115,
753 			},
754 			.dc_data = &(struct power_limits) {
755 				.ppt_apu_sppt_min = 25,
756 				.ppt_apu_sppt_def = 30,
757 				.ppt_apu_sppt_max = 45,
758 				.ppt_platform_sppt_min = 40,
759 				.ppt_platform_sppt_max = 60,
760 			},
761 		},
762 	},
763 	{
764 		.matches = {
765 			DMI_MATCH(DMI_BOARD_NAME, "GA402X"),
766 		},
767 		.driver_data = &(struct power_data) {
768 			.ac_data = &(struct power_limits) {
769 				.ppt_pl1_spl_min = 15,
770 				.ppt_pl1_spl_def = 35,
771 				.ppt_pl1_spl_max = 80,
772 				.ppt_pl2_sppt_min = 25,
773 				.ppt_pl2_sppt_def = 65,
774 				.ppt_pl2_sppt_max = 80,
775 				.ppt_pl3_fppt_min = 35,
776 				.ppt_pl3_fppt_max = 80,
777 				.nv_temp_target_min = 75,
778 				.nv_temp_target_max = 87,
779 			},
780 			.dc_data = &(struct power_limits) {
781 				.ppt_pl1_spl_min = 15,
782 				.ppt_pl1_spl_max = 35,
783 				.ppt_pl2_sppt_min = 25,
784 				.ppt_pl2_sppt_max = 35,
785 				.ppt_pl3_fppt_min = 35,
786 				.ppt_pl3_fppt_max = 65,
787 				.nv_temp_target_min = 75,
788 				.nv_temp_target_max = 87,
789 			},
790 			.requires_fan_curve = true,
791 		},
792 	},
793 	{
794 		.matches = {
795 			DMI_MATCH(DMI_BOARD_NAME, "GA403U"),
796 		},
797 		.driver_data = &(struct power_data) {
798 			.ac_data = &(struct power_limits) {
799 				.ppt_pl1_spl_min = 15,
800 				.ppt_pl1_spl_max = 80,
801 				.ppt_pl2_sppt_min = 25,
802 				.ppt_pl2_sppt_max = 80,
803 				.ppt_pl3_fppt_min = 35,
804 				.ppt_pl3_fppt_max = 80,
805 				.nv_dynamic_boost_min = 5,
806 				.nv_dynamic_boost_max = 25,
807 				.nv_temp_target_min = 75,
808 				.nv_temp_target_max = 87,
809 				.nv_tgp_min = 55,
810 				.nv_tgp_max = 65,
811 			},
812 			.dc_data = &(struct power_limits) {
813 				.ppt_pl1_spl_min = 15,
814 				.ppt_pl1_spl_max = 35,
815 				.ppt_pl2_sppt_min = 25,
816 				.ppt_pl2_sppt_max = 35,
817 				.ppt_pl3_fppt_min = 35,
818 				.ppt_pl3_fppt_max = 65,
819 				.nv_temp_target_min = 75,
820 				.nv_temp_target_max = 87,
821 			},
822 			.requires_fan_curve = true,
823 		},
824 	},
825 	{
826 		.matches = {
827 			DMI_MATCH(DMI_BOARD_NAME, "GA503QR"),
828 		},
829 		.driver_data = &(struct power_data) {
830 			.ac_data = &(struct power_limits) {
831 				.ppt_pl1_spl_min = 15,
832 				.ppt_pl1_spl_def = 35,
833 				.ppt_pl1_spl_max = 80,
834 				.ppt_pl2_sppt_min = 65,
835 				.ppt_pl2_sppt_max = 80,
836 			},
837 		},
838 	},
839 	{
840 		.matches = {
841 			DMI_MATCH(DMI_BOARD_NAME, "GA503R"),
842 		},
843 		.driver_data = &(struct power_data) {
844 			.ac_data = &(struct power_limits) {
845 				.ppt_pl1_spl_min = 15,
846 				.ppt_pl1_spl_def = 35,
847 				.ppt_pl1_spl_max = 80,
848 				.ppt_pl2_sppt_min = 35,
849 				.ppt_pl2_sppt_def = 65,
850 				.ppt_pl2_sppt_max = 80,
851 				.ppt_pl3_fppt_min = 35,
852 				.ppt_pl3_fppt_max = 80,
853 				.nv_dynamic_boost_min = 5,
854 				.nv_dynamic_boost_max = 20,
855 				.nv_temp_target_min = 75,
856 				.nv_temp_target_max = 87,
857 			},
858 			.dc_data = &(struct power_limits) {
859 				.ppt_pl1_spl_min = 15,
860 				.ppt_pl1_spl_def = 25,
861 				.ppt_pl1_spl_max = 65,
862 				.ppt_pl2_sppt_min = 35,
863 				.ppt_pl2_sppt_def = 54,
864 				.ppt_pl2_sppt_max = 60,
865 				.ppt_pl3_fppt_min = 35,
866 				.ppt_pl3_fppt_max = 65,
867 			},
868 		},
869 	},
870 	{
871 		.matches = {
872 			DMI_MATCH(DMI_BOARD_NAME, "GA605W"),
873 		},
874 		.driver_data = &(struct power_data) {
875 			.ac_data = &(struct power_limits) {
876 				.ppt_pl1_spl_min = 15,
877 				.ppt_pl1_spl_max = 80,
878 				.ppt_pl2_sppt_min = 35,
879 				.ppt_pl2_sppt_max = 80,
880 				.ppt_pl3_fppt_min = 35,
881 				.ppt_pl3_fppt_max = 80,
882 				.nv_dynamic_boost_min = 5,
883 				.nv_dynamic_boost_max = 20,
884 				.nv_temp_target_min = 75,
885 				.nv_temp_target_max = 87,
886 				.nv_tgp_min = 55,
887 				.nv_tgp_max = 85,
888 			},
889 			.dc_data = &(struct power_limits) {
890 				.ppt_pl1_spl_min = 25,
891 				.ppt_pl1_spl_max = 35,
892 				.ppt_pl2_sppt_min = 31,
893 				.ppt_pl2_sppt_max = 44,
894 				.ppt_pl3_fppt_min = 45,
895 				.ppt_pl3_fppt_max = 65,
896 				.nv_temp_target_min = 75,
897 				.nv_temp_target_max = 87,
898 			},
899 			.requires_fan_curve = true,
900 		},
901 	},
902 	{
903 		.matches = {
904 			DMI_MATCH(DMI_BOARD_NAME, "GU603Z"),
905 		},
906 		.driver_data = &(struct power_data) {
907 			.ac_data = &(struct power_limits) {
908 				.ppt_pl1_spl_min = 25,
909 				.ppt_pl1_spl_max = 60,
910 				.ppt_pl2_sppt_min = 25,
911 				.ppt_pl2_sppt_max = 135,
912 				.nv_dynamic_boost_min = 5,
913 				.nv_dynamic_boost_max = 20,
914 				.nv_temp_target_min = 75,
915 				.nv_temp_target_max = 87,
916 			},
917 			.dc_data = &(struct power_limits) {
918 				.ppt_pl1_spl_min = 25,
919 				.ppt_pl1_spl_max = 40,
920 				.ppt_pl2_sppt_min = 25,
921 				.ppt_pl2_sppt_max = 40,
922 				.nv_temp_target_min = 75,
923 				.nv_temp_target_max = 87,
924 			}
925 		},
926 	},
927 	{
928 		.matches = {
929 			DMI_MATCH(DMI_BOARD_NAME, "GU604V"),
930 		},
931 		.driver_data = &(struct power_data) {
932 			.ac_data = &(struct power_limits) {
933 				.ppt_pl1_spl_min = 65,
934 				.ppt_pl1_spl_max = 120,
935 				.ppt_pl2_sppt_min = 65,
936 				.ppt_pl2_sppt_max = 150,
937 				.nv_dynamic_boost_min = 5,
938 				.nv_dynamic_boost_max = 25,
939 				.nv_temp_target_min = 75,
940 				.nv_temp_target_max = 87,
941 			},
942 			.dc_data = &(struct power_limits) {
943 				.ppt_pl1_spl_min = 25,
944 				.ppt_pl1_spl_max = 40,
945 				.ppt_pl2_sppt_min = 35,
946 				.ppt_pl2_sppt_def = 40,
947 				.ppt_pl2_sppt_max = 60,
948 				.nv_temp_target_min = 75,
949 				.nv_temp_target_max = 87,
950 			},
951 		},
952 	},
953 	{
954 		.matches = {
955 			DMI_MATCH(DMI_BOARD_NAME, "GU605CW"),
956 		},
957 		.driver_data = &(struct power_data) {
958 			.ac_data = &(struct power_limits) {
959 				.ppt_pl1_spl_min = 45,
960 				.ppt_pl1_spl_max = 85,
961 				.ppt_pl2_sppt_min = 56,
962 				.ppt_pl2_sppt_max = 110,
963 				.nv_dynamic_boost_min = 5,
964 				.nv_dynamic_boost_max = 20,
965 				.nv_temp_target_min = 75,
966 				.nv_temp_target_max = 87,
967 				.nv_tgp_min = 80,
968 				.nv_tgp_def = 90,
969 				.nv_tgp_max = 110,
970 			},
971 			.dc_data = &(struct power_limits) {
972 				.ppt_pl1_spl_min = 25,
973 				.ppt_pl1_spl_max = 85,
974 				.ppt_pl2_sppt_min = 32,
975 				.ppt_pl2_sppt_max = 110,
976 				.nv_temp_target_min = 75,
977 				.nv_temp_target_max = 87,
978 			},
979 			.requires_fan_curve = true,
980 		},
981 	},
982 	{
983 		.matches = {
984 			DMI_MATCH(DMI_BOARD_NAME, "GU605CX"),
985 		},
986 		.driver_data = &(struct power_data) {
987 			.ac_data = &(struct power_limits) {
988 				.ppt_pl1_spl_min = 45,
989 				.ppt_pl1_spl_max = 85,
990 				.ppt_pl2_sppt_min = 56,
991 				.ppt_pl2_sppt_max = 110,
992 				.nv_dynamic_boost_min = 5,
993 				.nv_dynamic_boost_max = 20,
994 				.nv_temp_target_min = 7,
995 				.nv_temp_target_max = 87,
996 				.nv_tgp_min = 95,
997 				.nv_tgp_def = 100,
998 				.nv_tgp_max = 110,
999 			},
1000 			.dc_data = &(struct power_limits) {
1001 				.ppt_pl1_spl_min = 25,
1002 				.ppt_pl1_spl_max = 85,
1003 				.ppt_pl2_sppt_min = 32,
1004 				.ppt_pl2_sppt_max = 110,
1005 				.nv_temp_target_min = 75,
1006 				.nv_temp_target_max = 87,
1007 			},
1008 			.requires_fan_curve = true,
1009 		},
1010 	},
1011 	{
1012 		.matches = {
1013 			DMI_MATCH(DMI_BOARD_NAME, "GU605M"),
1014 		},
1015 		.driver_data = &(struct power_data) {
1016 			.ac_data = &(struct power_limits) {
1017 				.ppt_pl1_spl_min = 28,
1018 				.ppt_pl1_spl_max = 90,
1019 				.ppt_pl2_sppt_min = 28,
1020 				.ppt_pl2_sppt_max = 135,
1021 				.nv_dynamic_boost_min = 5,
1022 				.nv_dynamic_boost_max = 20,
1023 				.nv_temp_target_min = 75,
1024 				.nv_temp_target_max = 87,
1025 			},
1026 			.dc_data = &(struct power_limits) {
1027 				.ppt_pl1_spl_min = 25,
1028 				.ppt_pl1_spl_max = 35,
1029 				.ppt_pl2_sppt_min = 38,
1030 				.ppt_pl2_sppt_max = 53,
1031 				.nv_temp_target_min = 75,
1032 				.nv_temp_target_max = 87,
1033 			},
1034 			.requires_fan_curve = true,
1035 		},
1036 	},
1037 	{
1038 		.matches = {
1039 			DMI_MATCH(DMI_BOARD_NAME, "GV301Q"),
1040 		},
1041 		.driver_data = &(struct power_data) {
1042 			.ac_data = &(struct power_limits) {
1043 				.ppt_pl1_spl_min = 15,
1044 				.ppt_pl1_spl_max = 45,
1045 				.ppt_pl2_sppt_min = 65,
1046 				.ppt_pl2_sppt_max = 80,
1047 			},
1048 			.dc_data = NULL,
1049 		},
1050 	},
1051 	{
1052 		.matches = {
1053 			DMI_MATCH(DMI_BOARD_NAME, "GV301R"),
1054 		},
1055 		.driver_data = &(struct power_data) {
1056 			.ac_data = &(struct power_limits) {
1057 				.ppt_pl1_spl_min = 15,
1058 				.ppt_pl1_spl_max = 45,
1059 				.ppt_pl2_sppt_min = 25,
1060 				.ppt_pl2_sppt_max = 54,
1061 				.ppt_pl3_fppt_min = 35,
1062 				.ppt_pl3_fppt_max = 65,
1063 				.nv_temp_target_min = 75,
1064 				.nv_temp_target_max = 87,
1065 			},
1066 			.dc_data = &(struct power_limits) {
1067 				.ppt_pl1_spl_min = 15,
1068 				.ppt_pl1_spl_max = 35,
1069 				.ppt_pl2_sppt_min = 25,
1070 				.ppt_pl2_sppt_max = 35,
1071 				.ppt_pl3_fppt_min = 35,
1072 				.ppt_pl3_fppt_max = 65,
1073 				.nv_temp_target_min = 75,
1074 				.nv_temp_target_max = 87,
1075 			},
1076 		},
1077 	},
1078 	{
1079 		.matches = {
1080 			DMI_MATCH(DMI_BOARD_NAME, "GV601R"),
1081 		},
1082 		.driver_data = &(struct power_data) {
1083 			.ac_data = &(struct power_limits) {
1084 				.ppt_pl1_spl_min = 15,
1085 				.ppt_pl1_spl_def = 35,
1086 				.ppt_pl1_spl_max = 90,
1087 				.ppt_pl2_sppt_min = 35,
1088 				.ppt_pl2_sppt_def = 54,
1089 				.ppt_pl2_sppt_max = 100,
1090 				.ppt_pl3_fppt_min = 35,
1091 				.ppt_pl3_fppt_def = 80,
1092 				.ppt_pl3_fppt_max = 125,
1093 				.nv_dynamic_boost_min = 5,
1094 				.nv_dynamic_boost_max = 25,
1095 				.nv_temp_target_min = 75,
1096 				.nv_temp_target_max = 87,
1097 			},
1098 			.dc_data = &(struct power_limits) {
1099 				.ppt_pl1_spl_min = 15,
1100 				.ppt_pl1_spl_def = 28,
1101 				.ppt_pl1_spl_max = 65,
1102 				.ppt_pl2_sppt_min = 35,
1103 				.ppt_pl2_sppt_def = 54,
1104 				.ppt_pl2_sppt_max = 60,
1105 				.ppt_pl3_fppt_min = 35,
1106 				.ppt_pl3_fppt_def = 80,
1107 				.ppt_pl3_fppt_max = 65,
1108 				.nv_temp_target_min = 75,
1109 				.nv_temp_target_max = 87,
1110 			},
1111 		},
1112 	},
1113 	{
1114 		.matches = {
1115 			DMI_MATCH(DMI_BOARD_NAME, "GV601V"),
1116 		},
1117 		.driver_data = &(struct power_data) {
1118 			.ac_data = &(struct power_limits) {
1119 				.ppt_pl1_spl_min = 28,
1120 				.ppt_pl1_spl_def = 100,
1121 				.ppt_pl1_spl_max = 110,
1122 				.ppt_pl2_sppt_min = 28,
1123 				.ppt_pl2_sppt_max = 135,
1124 				.nv_dynamic_boost_min = 5,
1125 				.nv_dynamic_boost_max = 20,
1126 				.nv_temp_target_min = 75,
1127 				.nv_temp_target_max = 87,
1128 			},
1129 			.dc_data = &(struct power_limits) {
1130 				.ppt_pl1_spl_min = 25,
1131 				.ppt_pl1_spl_max = 40,
1132 				.ppt_pl2_sppt_min = 35,
1133 				.ppt_pl2_sppt_def = 40,
1134 				.ppt_pl2_sppt_max = 60,
1135 				.nv_temp_target_min = 75,
1136 				.nv_temp_target_max = 87,
1137 			},
1138 		},
1139 	},
1140 	{
1141 		.matches = {
1142 			DMI_MATCH(DMI_BOARD_NAME, "GX650P"),
1143 		},
1144 		.driver_data = &(struct power_data) {
1145 			.ac_data = &(struct power_limits) {
1146 				.ppt_pl1_spl_min = 15,
1147 				.ppt_pl1_spl_def = 110,
1148 				.ppt_pl1_spl_max = 130,
1149 				.ppt_pl2_sppt_min = 35,
1150 				.ppt_pl2_sppt_def = 125,
1151 				.ppt_pl2_sppt_max = 130,
1152 				.ppt_pl3_fppt_min = 35,
1153 				.ppt_pl3_fppt_def = 125,
1154 				.ppt_pl3_fppt_max = 135,
1155 				.nv_dynamic_boost_min = 5,
1156 				.nv_dynamic_boost_max = 25,
1157 				.nv_temp_target_min = 75,
1158 				.nv_temp_target_max = 87,
1159 			},
1160 			.dc_data = &(struct power_limits) {
1161 				.ppt_pl1_spl_min = 15,
1162 				.ppt_pl1_spl_def = 25,
1163 				.ppt_pl1_spl_max = 65,
1164 				.ppt_pl2_sppt_min = 35,
1165 				.ppt_pl2_sppt_def = 35,
1166 				.ppt_pl2_sppt_max = 65,
1167 				.ppt_pl3_fppt_min = 35,
1168 				.ppt_pl3_fppt_def = 42,
1169 				.ppt_pl3_fppt_max = 65,
1170 				.nv_temp_target_min = 75,
1171 				.nv_temp_target_max = 87,
1172 			},
1173 		},
1174 	},
1175 	{
1176 		.matches = {
1177 			DMI_MATCH(DMI_BOARD_NAME, "G513I"),
1178 		},
1179 		.driver_data = &(struct power_data) {
1180 			.ac_data = &(struct power_limits) {
1181 				/* Yes this laptop is very limited */
1182 				.ppt_pl1_spl_min = 15,
1183 				.ppt_pl1_spl_max = 80,
1184 				.ppt_pl2_sppt_min = 15,
1185 				.ppt_pl2_sppt_max = 80,
1186 			},
1187 			.dc_data = NULL,
1188 			.requires_fan_curve = true,
1189 		},
1190 	},
1191 	{
1192 		.matches = {
1193 			DMI_MATCH(DMI_BOARD_NAME, "G513QM"),
1194 		},
1195 		.driver_data = &(struct power_data) {
1196 			.ac_data = &(struct power_limits) {
1197 				/* Yes this laptop is very limited */
1198 				.ppt_pl1_spl_min = 15,
1199 				.ppt_pl1_spl_max = 100,
1200 				.ppt_pl2_sppt_min = 15,
1201 				.ppt_pl2_sppt_max = 190,
1202 			},
1203 			.dc_data = NULL,
1204 			.requires_fan_curve = true,
1205 		},
1206 	},
1207 	{
1208 		.matches = {
1209 			DMI_MATCH(DMI_BOARD_NAME, "G513R"),
1210 		},
1211 		.driver_data = &(struct power_data) {
1212 			.ac_data = &(struct power_limits) {
1213 				.ppt_pl1_spl_min = 35,
1214 				.ppt_pl1_spl_max = 90,
1215 				.ppt_pl2_sppt_min = 54,
1216 				.ppt_pl2_sppt_max = 100,
1217 				.ppt_pl3_fppt_min = 54,
1218 				.ppt_pl3_fppt_max = 125,
1219 				.nv_dynamic_boost_min = 5,
1220 				.nv_dynamic_boost_max = 25,
1221 				.nv_temp_target_min = 75,
1222 				.nv_temp_target_max = 87,
1223 			},
1224 			.dc_data = &(struct power_limits) {
1225 				.ppt_pl1_spl_min = 28,
1226 				.ppt_pl1_spl_max = 50,
1227 				.ppt_pl2_sppt_min = 28,
1228 				.ppt_pl2_sppt_max = 50,
1229 				.ppt_pl3_fppt_min = 28,
1230 				.ppt_pl3_fppt_max = 65,
1231 				.nv_temp_target_min = 75,
1232 				.nv_temp_target_max = 87,
1233 			},
1234 			.requires_fan_curve = true,
1235 		},
1236 	},
1237 	{
1238 		.matches = {
1239 			DMI_MATCH(DMI_BOARD_NAME, "G614J"),
1240 		},
1241 		.driver_data = &(struct power_data) {
1242 			.ac_data = &(struct power_limits) {
1243 				.ppt_pl1_spl_min = 28,
1244 				.ppt_pl1_spl_max = 140,
1245 				.ppt_pl2_sppt_min = 28,
1246 				.ppt_pl2_sppt_max = 175,
1247 				.nv_temp_target_min = 75,
1248 				.nv_temp_target_max = 87,
1249 				.nv_dynamic_boost_min = 5,
1250 				.nv_dynamic_boost_max = 25,
1251 			},
1252 			.dc_data = &(struct power_limits) {
1253 				.ppt_pl1_spl_min = 25,
1254 				.ppt_pl1_spl_max = 55,
1255 				.ppt_pl2_sppt_min = 25,
1256 				.ppt_pl2_sppt_max = 70,
1257 				.nv_temp_target_min = 75,
1258 				.nv_temp_target_max = 87,
1259 			},
1260 			.requires_fan_curve = true,
1261 		},
1262 	},
1263 	{
1264 		.matches = {
1265 			DMI_MATCH(DMI_BOARD_NAME, "G634J"),
1266 		},
1267 		.driver_data = &(struct power_data) {
1268 			.ac_data = &(struct power_limits) {
1269 				.ppt_pl1_spl_min = 28,
1270 				.ppt_pl1_spl_max = 140,
1271 				.ppt_pl2_sppt_min = 28,
1272 				.ppt_pl2_sppt_max = 175,
1273 				.nv_temp_target_min = 75,
1274 				.nv_temp_target_max = 87,
1275 				.nv_dynamic_boost_min = 5,
1276 				.nv_dynamic_boost_max = 25,
1277 			},
1278 			.dc_data = &(struct power_limits) {
1279 				.ppt_pl1_spl_min = 25,
1280 				.ppt_pl1_spl_max = 55,
1281 				.ppt_pl2_sppt_min = 25,
1282 				.ppt_pl2_sppt_max = 70,
1283 				.nv_temp_target_min = 75,
1284 				.nv_temp_target_max = 87,
1285 			},
1286 			.requires_fan_curve = true,
1287 		},
1288 	},
1289 	{
1290 		.matches = {
1291 			DMI_MATCH(DMI_BOARD_NAME, "G713PV"),
1292 		},
1293 		.driver_data = &(struct power_data) {
1294 			.ac_data = &(struct power_limits) {
1295 				.ppt_pl1_spl_min = 30,
1296 				.ppt_pl1_spl_def = 120,
1297 				.ppt_pl1_spl_max = 130,
1298 				.ppt_pl2_sppt_min = 65,
1299 				.ppt_pl2_sppt_def = 125,
1300 				.ppt_pl2_sppt_max = 130,
1301 				.ppt_pl3_fppt_min = 65,
1302 				.ppt_pl3_fppt_def = 125,
1303 				.ppt_pl3_fppt_max = 130,
1304 				.nv_temp_target_min = 75,
1305 				.nv_temp_target_max = 87,
1306 				.nv_dynamic_boost_min = 5,
1307 				.nv_dynamic_boost_max = 25,
1308 			},
1309 			.dc_data = &(struct power_limits) {
1310 				.ppt_pl1_spl_min = 25,
1311 				.ppt_pl1_spl_max = 65,
1312 				.ppt_pl2_sppt_min = 25,
1313 				.ppt_pl2_sppt_max = 65,
1314 				.ppt_pl3_fppt_min = 35,
1315 				.ppt_pl3_fppt_max = 75,
1316 				.nv_temp_target_min = 75,
1317 				.nv_temp_target_max = 87,
1318 			},
1319 			.requires_fan_curve = true,
1320 		},
1321 	},
1322 	{
1323 		.matches = {
1324 			DMI_MATCH(DMI_BOARD_NAME, "G733C"),
1325 		},
1326 		.driver_data = &(struct power_data) {
1327 			.ac_data = &(struct power_limits) {
1328 				.ppt_pl1_spl_min = 28,
1329 				.ppt_pl1_spl_max = 170,
1330 				.ppt_pl2_sppt_min = 28,
1331 				.ppt_pl2_sppt_max = 175,
1332 				.nv_temp_target_min = 75,
1333 				.nv_temp_target_max = 87,
1334 				.nv_dynamic_boost_min = 5,
1335 				.nv_dynamic_boost_max = 25,
1336 			},
1337 			.dc_data = &(struct power_limits) {
1338 				.ppt_pl1_spl_min = 28,
1339 				.ppt_pl1_spl_max = 35,
1340 				.ppt_pl2_sppt_min = 28,
1341 				.ppt_pl2_sppt_max = 35,
1342 				.nv_temp_target_min = 75,
1343 				.nv_temp_target_max = 87,
1344 			},
1345 			.requires_fan_curve = true,
1346 		},
1347 	},
1348 	{
1349 		.matches = {
1350 			DMI_MATCH(DMI_BOARD_NAME, "G733P"),
1351 		},
1352 		.driver_data = &(struct power_data) {
1353 			.ac_data = &(struct power_limits) {
1354 				.ppt_pl1_spl_min = 30,
1355 				.ppt_pl1_spl_def = 100,
1356 				.ppt_pl1_spl_max = 130,
1357 				.ppt_pl2_sppt_min = 65,
1358 				.ppt_pl2_sppt_def = 125,
1359 				.ppt_pl2_sppt_max = 130,
1360 				.ppt_pl3_fppt_min = 65,
1361 				.ppt_pl3_fppt_def = 125,
1362 				.ppt_pl3_fppt_max = 130,
1363 				.nv_temp_target_min = 75,
1364 				.nv_temp_target_max = 87,
1365 				.nv_dynamic_boost_min = 5,
1366 				.nv_dynamic_boost_max = 25,
1367 			},
1368 			.dc_data = &(struct power_limits) {
1369 				.ppt_pl1_spl_min = 25,
1370 				.ppt_pl1_spl_max = 65,
1371 				.ppt_pl2_sppt_min = 25,
1372 				.ppt_pl2_sppt_max = 65,
1373 				.ppt_pl3_fppt_min = 35,
1374 				.ppt_pl3_fppt_max = 75,
1375 				.nv_temp_target_min = 75,
1376 				.nv_temp_target_max = 87,
1377 			},
1378 			.requires_fan_curve = true,
1379 		},
1380 	},
1381 	{
1382 		.matches = {
1383 			DMI_MATCH(DMI_BOARD_NAME, "G814J"),
1384 		},
1385 		.driver_data = &(struct power_data) {
1386 			.ac_data = &(struct power_limits) {
1387 				.ppt_pl1_spl_min = 28,
1388 				.ppt_pl1_spl_max = 140,
1389 				.ppt_pl2_sppt_min = 28,
1390 				.ppt_pl2_sppt_max = 140,
1391 				.nv_dynamic_boost_min = 5,
1392 				.nv_dynamic_boost_max = 25,
1393 			},
1394 			.dc_data = &(struct power_limits) {
1395 				.ppt_pl1_spl_min = 25,
1396 				.ppt_pl1_spl_max = 55,
1397 				.ppt_pl2_sppt_min = 25,
1398 				.ppt_pl2_sppt_max = 70,
1399 			},
1400 			.requires_fan_curve = true,
1401 		},
1402 	},
1403 	{
1404 		.matches = {
1405 			DMI_MATCH(DMI_BOARD_NAME, "G834J"),
1406 		},
1407 		.driver_data = &(struct power_data) {
1408 			.ac_data = &(struct power_limits) {
1409 				.ppt_pl1_spl_min = 28,
1410 				.ppt_pl1_spl_max = 140,
1411 				.ppt_pl2_sppt_min = 28,
1412 				.ppt_pl2_sppt_max = 175,
1413 				.nv_dynamic_boost_min = 5,
1414 				.nv_dynamic_boost_max = 25,
1415 				.nv_temp_target_min = 75,
1416 				.nv_temp_target_max = 87,
1417 			},
1418 			.dc_data = &(struct power_limits) {
1419 				.ppt_pl1_spl_min = 25,
1420 				.ppt_pl1_spl_max = 55,
1421 				.ppt_pl2_sppt_min = 25,
1422 				.ppt_pl2_sppt_max = 70,
1423 				.nv_temp_target_min = 75,
1424 				.nv_temp_target_max = 87,
1425 			},
1426 			.requires_fan_curve = true,
1427 		},
1428 	},
1429 	{
1430 		.matches = {
1431 			DMI_MATCH(DMI_BOARD_NAME, "H7606W"),
1432 		},
1433 		.driver_data = &(struct power_data) {
1434 			.ac_data = &(struct power_limits) {
1435 				.ppt_pl1_spl_min = 15,
1436 				.ppt_pl1_spl_max = 80,
1437 				.ppt_pl2_sppt_min = 35,
1438 				.ppt_pl2_sppt_max = 80,
1439 				.ppt_pl3_fppt_min = 35,
1440 				.ppt_pl3_fppt_max = 80,
1441 				.nv_dynamic_boost_min = 5,
1442 				.nv_dynamic_boost_max = 20,
1443 				.nv_temp_target_min = 75,
1444 				.nv_temp_target_max = 87,
1445 				.nv_tgp_min = 55,
1446 				.nv_tgp_max = 85,
1447 			},
1448 			.dc_data = &(struct power_limits) {
1449 				.ppt_pl1_spl_min = 25,
1450 				.ppt_pl1_spl_max = 35,
1451 				.ppt_pl2_sppt_min = 31,
1452 				.ppt_pl2_sppt_max = 44,
1453 				.ppt_pl3_fppt_min = 45,
1454 				.ppt_pl3_fppt_max = 65,
1455 				.nv_temp_target_min = 75,
1456 				.nv_temp_target_max = 87,
1457 			},
1458 		},
1459 	},
1460 	{
1461 		.matches = {
1462 			DMI_MATCH(DMI_BOARD_NAME, "RC71"),
1463 		},
1464 		.driver_data = &(struct power_data) {
1465 			.ac_data = &(struct power_limits) {
1466 				.ppt_pl1_spl_min = 7,
1467 				.ppt_pl1_spl_max = 30,
1468 				.ppt_pl2_sppt_min = 15,
1469 				.ppt_pl2_sppt_max = 43,
1470 				.ppt_pl3_fppt_min = 15,
1471 				.ppt_pl3_fppt_max = 53,
1472 			},
1473 			.dc_data = &(struct power_limits) {
1474 				.ppt_pl1_spl_min = 7,
1475 				.ppt_pl1_spl_def = 15,
1476 				.ppt_pl1_spl_max = 25,
1477 				.ppt_pl2_sppt_min = 15,
1478 				.ppt_pl2_sppt_def = 20,
1479 				.ppt_pl2_sppt_max = 30,
1480 				.ppt_pl3_fppt_min = 15,
1481 				.ppt_pl3_fppt_def = 25,
1482 				.ppt_pl3_fppt_max = 35,
1483 			},
1484 		},
1485 	},
1486 	{
1487 		.matches = {
1488 			DMI_MATCH(DMI_BOARD_NAME, "RC72"),
1489 		},
1490 		.driver_data = &(struct power_data) {
1491 			.ac_data = &(struct power_limits) {
1492 				.ppt_pl1_spl_min = 7,
1493 				.ppt_pl1_spl_max = 30,
1494 				.ppt_pl2_sppt_min = 15,
1495 				.ppt_pl2_sppt_max = 43,
1496 				.ppt_pl3_fppt_min = 15,
1497 				.ppt_pl3_fppt_max = 53,
1498 			},
1499 			.dc_data = &(struct power_limits) {
1500 				.ppt_pl1_spl_min = 7,
1501 				.ppt_pl1_spl_def = 17,
1502 				.ppt_pl1_spl_max = 25,
1503 				.ppt_pl2_sppt_min = 15,
1504 				.ppt_pl2_sppt_def = 24,
1505 				.ppt_pl2_sppt_max = 30,
1506 				.ppt_pl3_fppt_min = 15,
1507 				.ppt_pl3_fppt_def = 30,
1508 				.ppt_pl3_fppt_max = 35,
1509 			},
1510 		},
1511 	},
1512 	{
1513 		.matches = {
1514 			DMI_MATCH(DMI_BOARD_NAME, "RC73XA"),
1515 		},
1516 		.driver_data = &(struct power_data) {
1517 			.ac_data = &(struct power_limits) {
1518 				.ppt_pl1_spl_min = 7,
1519 				.ppt_pl1_spl_max = 35,
1520 				.ppt_pl2_sppt_min = 14,
1521 				.ppt_pl2_sppt_max = 45,
1522 				.ppt_pl3_fppt_min = 19,
1523 				.ppt_pl3_fppt_max = 55,
1524 			},
1525 			.dc_data = &(struct power_limits) {
1526 				.ppt_pl1_spl_min = 7,
1527 				.ppt_pl1_spl_def = 17,
1528 				.ppt_pl1_spl_max = 35,
1529 				.ppt_pl2_sppt_min = 13,
1530 				.ppt_pl2_sppt_def = 21,
1531 				.ppt_pl2_sppt_max = 45,
1532 				.ppt_pl3_fppt_min = 19,
1533 				.ppt_pl3_fppt_def = 26,
1534 				.ppt_pl3_fppt_max = 55,
1535 			},
1536 		},
1537 	},
1538 	{}
1539 };
1540 
1541 #endif /* _ASUS_ARMOURY_H_ */
1542