3333#include <linux/units.h>
3434#include <linux/unaligned.h>
3535#include <linux/bitfield.h>
36+ #include <linux/bitmap.h>
3637
3738MODULE_AUTHOR ("Carlos Corbacho" );
3839MODULE_DESCRIPTION ("Acer Laptop WMI Extras Driver" );
@@ -127,6 +128,7 @@ enum acer_wmi_predator_v4_oc {
127128enum acer_wmi_gaming_misc_setting {
128129 ACER_WMID_MISC_SETTING_OC_1 = 0x0005 ,
129130 ACER_WMID_MISC_SETTING_OC_2 = 0x0007 ,
131+ ACER_WMID_MISC_SETTING_SUPPORTED_PROFILES = 0x000A ,
130132 ACER_WMID_MISC_SETTING_PLATFORM_PROFILE = 0x000B ,
131133};
132134
@@ -782,6 +784,9 @@ static bool platform_profile_support;
782784 */
783785static int last_non_turbo_profile ;
784786
787+ /* The most performant supported profile */
788+ static int acer_predator_v4_max_perf ;
789+
785790enum acer_predator_v4_thermal_profile {
786791 ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET = 0x00 ,
787792 ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED = 0x01 ,
@@ -1999,7 +2004,7 @@ acer_predator_v4_platform_profile_set(struct platform_profile_handler *pprof,
19992004 if (err )
20002005 return err ;
20012006
2002- if (tp != ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO )
2007+ if (tp != acer_predator_v4_max_perf )
20032008 last_non_turbo_profile = tp ;
20042009
20052010 return 0 ;
@@ -2008,6 +2013,7 @@ acer_predator_v4_platform_profile_set(struct platform_profile_handler *pprof,
20082013static int acer_platform_profile_setup (struct platform_device * device )
20092014{
20102015 if (quirks -> predator_v4 ) {
2016+ unsigned long supported_profiles ;
20112017 int err ;
20122018
20132019 platform_profile_handler .name = "acer-wmi" ;
@@ -2017,16 +2023,46 @@ static int acer_platform_profile_setup(struct platform_device *device)
20172023 platform_profile_handler .profile_set =
20182024 acer_predator_v4_platform_profile_set ;
20192025
2020- set_bit (PLATFORM_PROFILE_PERFORMANCE ,
2021- platform_profile_handler .choices );
2022- set_bit (PLATFORM_PROFILE_BALANCED_PERFORMANCE ,
2023- platform_profile_handler .choices );
2024- set_bit (PLATFORM_PROFILE_BALANCED ,
2025- platform_profile_handler .choices );
2026- set_bit (PLATFORM_PROFILE_QUIET ,
2027- platform_profile_handler .choices );
2028- set_bit (PLATFORM_PROFILE_LOW_POWER ,
2029- platform_profile_handler .choices );
2026+ err = WMID_gaming_get_misc_setting (ACER_WMID_MISC_SETTING_SUPPORTED_PROFILES ,
2027+ (u8 * )& supported_profiles );
2028+ if (err )
2029+ return err ;
2030+
2031+ /* Iterate through supported profiles in order of increasing performance */
2032+ if (test_bit (ACER_PREDATOR_V4_THERMAL_PROFILE_ECO , & supported_profiles )) {
2033+ set_bit (PLATFORM_PROFILE_LOW_POWER ,
2034+ platform_profile_handler .choices );
2035+ acer_predator_v4_max_perf =
2036+ ACER_PREDATOR_V4_THERMAL_PROFILE_ECO ;
2037+ }
2038+
2039+ if (test_bit (ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET , & supported_profiles )) {
2040+ set_bit (PLATFORM_PROFILE_QUIET ,
2041+ platform_profile_handler .choices );
2042+ acer_predator_v4_max_perf =
2043+ ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET ;
2044+ }
2045+
2046+ if (test_bit (ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED , & supported_profiles )) {
2047+ set_bit (PLATFORM_PROFILE_BALANCED ,
2048+ platform_profile_handler .choices );
2049+ acer_predator_v4_max_perf =
2050+ ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED ;
2051+ }
2052+
2053+ if (test_bit (ACER_PREDATOR_V4_THERMAL_PROFILE_PERFORMANCE , & supported_profiles )) {
2054+ set_bit (PLATFORM_PROFILE_BALANCED_PERFORMANCE ,
2055+ platform_profile_handler .choices );
2056+ acer_predator_v4_max_perf =
2057+ ACER_PREDATOR_V4_THERMAL_PROFILE_PERFORMANCE ;
2058+ }
2059+
2060+ if (test_bit (ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO , & supported_profiles )) {
2061+ set_bit (PLATFORM_PROFILE_PERFORMANCE ,
2062+ platform_profile_handler .choices );
2063+ acer_predator_v4_max_perf =
2064+ ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO ;
2065+ }
20302066
20312067 err = platform_profile_register (& platform_profile_handler );
20322068 if (err )
@@ -2044,7 +2080,8 @@ static int acer_platform_profile_setup(struct platform_device *device)
20442080static int acer_thermal_profile_change (void )
20452081{
20462082 /*
2047- * This mode key will either cycle through each mode or toggle the turbo profile.
2083+ * This mode key will either cycle through each mode or toggle the
2084+ * most performant profile.
20482085 */
20492086 if (quirks -> predator_v4 ) {
20502087 u8 current_tp ;
@@ -2058,18 +2095,18 @@ static int acer_thermal_profile_change(void)
20582095 if (err )
20592096 return err ;
20602097
2061- if (current_tp == ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO )
2098+ if (current_tp == acer_predator_v4_max_perf )
20622099 tp = last_non_turbo_profile ;
20632100 else
2064- tp = ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO ;
2101+ tp = acer_predator_v4_max_perf ;
20652102
20662103 err = WMID_gaming_set_misc_setting (
20672104 ACER_WMID_MISC_SETTING_PLATFORM_PROFILE , tp );
20682105 if (err )
20692106 return err ;
20702107
20712108 /* Store last profile for toggle */
2072- if (current_tp != ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO )
2109+ if (current_tp != acer_predator_v4_max_perf )
20732110 last_non_turbo_profile = current_tp ;
20742111
20752112 platform_profile_notify (& platform_profile_handler );
0 commit comments