diff options
Diffstat (limited to 'drivers/platform/x86/hp/hp-wmi.c')
-rw-r--r-- | drivers/platform/x86/hp/hp-wmi.c | 71 |
1 files changed, 65 insertions, 6 deletions
diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c index e536604225..630519c086 100644 --- a/drivers/platform/x86/hp/hp-wmi.c +++ b/drivers/platform/x86/hp/hp-wmi.c @@ -29,15 +29,19 @@ #include <linux/dmi.h> MODULE_AUTHOR("Matthew Garrett <mjg59@srcf.ucam.org>"); -MODULE_DESCRIPTION("HP laptop WMI hotkeys driver"); +MODULE_DESCRIPTION("HP laptop WMI driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("wmi:95F24279-4D7B-4334-9387-ACCDC67EF61C"); -MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4"); +MODULE_ALIAS("wmi:5FB7F034-2C63-45E9-BE91-3D44E2C707E4"); #define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C" -#define HPWMI_BIOS_GUID "5FB7F034-2C63-45e9-BE91-3D44E2C707E4" +#define HPWMI_BIOS_GUID "5FB7F034-2C63-45E9-BE91-3D44E2C707E4" + +#define HP_OMEN_EC_THERMAL_PROFILE_FLAGS_OFFSET 0x62 +#define HP_OMEN_EC_THERMAL_PROFILE_TIMER_OFFSET 0x63 #define HP_OMEN_EC_THERMAL_PROFILE_OFFSET 0x95 + #define zero_if_sup(tmp) (zero_insize_support?0:sizeof(tmp)) // use when zero insize is required /* DMI board names of devices that should use the omen specific path for @@ -55,17 +59,25 @@ static const char * const omen_thermal_profile_boards[] = { "874A", "8603", "8604", "8748", "886B", "886C", "878A", "878B", "878C", "88C8", "88CB", "8786", "8787", "8788", "88D1", "88D2", "88F4", "88FD", "88F5", "88F6", "88F7", "88FE", "88FF", "8900", "8901", "8902", "8912", - "8917", "8918", "8949", "894A", "89EB" + "8917", "8918", "8949", "894A", "89EB", "8BAD", "8A42" }; /* DMI Board names of Omen laptops that are specifically set to be thermal * profile version 0 by the Omen Command Center app, regardless of what * the get system design information WMI call returns */ -static const char *const omen_thermal_profile_force_v0_boards[] = { +static const char * const omen_thermal_profile_force_v0_boards[] = { "8607", "8746", "8747", "8749", "874A", "8748" }; +/* DMI board names of Omen laptops that have a thermal profile timer which will + * cause the embedded controller to set the thermal profile back to + * "balanced" when reaching zero. + */ +static const char * const omen_timed_thermal_profile_boards[] = { + "8BAD", "8A42" +}; + /* DMI Board names of Victus laptops */ static const char * const victus_thermal_profile_boards[] = { "8A25" @@ -182,6 +194,12 @@ enum hp_thermal_profile_omen_v1 { HP_OMEN_V1_THERMAL_PROFILE_COOL = 0x50, }; +enum hp_thermal_profile_omen_flags { + HP_OMEN_EC_FLAGS_TURBO = 0x04, + HP_OMEN_EC_FLAGS_NOTIMER = 0x02, + HP_OMEN_EC_FLAGS_JUSTSET = 0x01, +}; + enum hp_thermal_profile_victus { HP_VICTUS_THERMAL_PROFILE_DEFAULT = 0x00, HP_VICTUS_THERMAL_PROFILE_PERFORMANCE = 0x01, @@ -449,7 +467,11 @@ static int hp_wmi_get_tablet_mode(void) static int omen_thermal_profile_set(int mode) { - char buffer[2] = {0, mode}; + /* The Omen Control Center actively sets the first byte of the buffer to + * 255, so let's mimic this behaviour to be as close as possible to + * the original software. + */ + char buffer[2] = {-1, mode}; int ret; ret = hp_wmi_perform_query(HPWMI_SET_PERFORMANCE_MODE, HPWMI_GM, @@ -1201,10 +1223,33 @@ static int platform_profile_omen_get(struct platform_profile_handler *pprof, return 0; } +static bool has_omen_thermal_profile_ec_timer(void) +{ + const char *board_name = dmi_get_system_info(DMI_BOARD_NAME); + + if (!board_name) + return false; + + return match_string(omen_timed_thermal_profile_boards, + ARRAY_SIZE(omen_timed_thermal_profile_boards), + board_name) >= 0; +} + +inline int omen_thermal_profile_ec_flags_set(enum hp_thermal_profile_omen_flags flags) +{ + return ec_write(HP_OMEN_EC_THERMAL_PROFILE_FLAGS_OFFSET, flags); +} + +inline int omen_thermal_profile_ec_timer_set(u8 value) +{ + return ec_write(HP_OMEN_EC_THERMAL_PROFILE_TIMER_OFFSET, value); +} + static int platform_profile_omen_set(struct platform_profile_handler *pprof, enum platform_profile_option profile) { int err, tp, tp_version; + enum hp_thermal_profile_omen_flags flags = 0; tp_version = omen_get_thermal_policy_version(); @@ -1238,6 +1283,20 @@ static int platform_profile_omen_set(struct platform_profile_handler *pprof, if (err < 0) return err; + if (has_omen_thermal_profile_ec_timer()) { + err = omen_thermal_profile_ec_timer_set(0); + if (err < 0) + return err; + + if (profile == PLATFORM_PROFILE_PERFORMANCE) + flags = HP_OMEN_EC_FLAGS_NOTIMER | + HP_OMEN_EC_FLAGS_TURBO; + + err = omen_thermal_profile_ec_flags_set(flags); + if (err < 0) + return err; + } + return 0; } |