From cc4c1445b97102f470ab44ae15cbc2461db6abc5 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Fri, 24 Sep 2021 22:26:15 +0200 Subject: [PATCH 01/26] Fix whitespace --- src/tuxedo_io/tuxedo_io_ioctl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tuxedo_io/tuxedo_io_ioctl.h b/src/tuxedo_io/tuxedo_io_ioctl.h index f271707..f63fb7f 100644 --- a/src/tuxedo_io/tuxedo_io_ioctl.h +++ b/src/tuxedo_io/tuxedo_io_ioctl.h @@ -85,6 +85,6 @@ #define W_UW_FANSPEED2 _IOW(MAGIC_WRITE_UW, 0x11, int32_t*) #define W_UW_MODE _IOW(MAGIC_WRITE_UW, 0x12, int32_t*) #define W_UW_MODE_ENABLE _IOW(MAGIC_WRITE_UW, 0x13, int32_t*) -#define W_UW_FANAUTO _IO(MAGIC_WRITE_UW, 0x14) // undo all previous calls of W_UW_FANSPEED and W_UW_FANSPEED2 +#define W_UW_FANAUTO _IO(MAGIC_WRITE_UW, 0x14) // undo all previous calls of W_UW_FANSPEED and W_UW_FANSPEED2 #endif From dd5e48fb0990f85993e881d8470c7f15dca8afc2 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Fri, 24 Sep 2021 23:32:25 +0200 Subject: [PATCH 02/26] Add uw TDP ioctl interface --- src/tuxedo_io/tuxedo_io.c | 79 +++++++++++++++++++++++++++++++++ src/tuxedo_io/tuxedo_io_ioctl.h | 8 ++++ 2 files changed, 87 insertions(+) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 22f51e4..874f89c 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include "../clevo_interfaces.h" #include "../uniwill_interfaces.h" #include "tuxedo_io_ioctl.h" @@ -50,8 +52,21 @@ static u32 clevo_identify(void) return clevo_get_active_interface_id(NULL) == 0 ? 1 : 0; } +static bool uniwill_tdp_config_two; +static bool uniwill_tdp_config_three; + static u32 uniwill_identify(void) { + // Device check for two configurable TDPs + uniwill_tdp_config_two = false +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) + || dmi_match(DMI_PRODUCT_SKU, "0001") +#endif + ; + + // Device check for three configurable TDPs + uniwill_tdp_config_three = false; + return uniwill_get_active_interface_id(NULL) == 0 ? 1 : 0; } @@ -203,6 +218,45 @@ static u32 uw_set_fan_auto(void) return 0; } +static int uw_get_tdp(u8 tdp_index) +{ + u8 tdp_data; + u16 tdp_base_addr = 0x0783; + u16 tdp_current_addr = tdp_base_addr + tdp_index; + bool has_current_setting = false; + + if (tdp_index < 2 && uniwill_tdp_config_two) + has_current_setting = true; + else if (tdp_index < 3 && uniwill_tdp_config_three) + has_current_setting = true; + + if (!has_current_setting) + return -1; + + uniwill_read_ec_ram(tdp_current_addr, &tdp_data); + + return tdp_data; +} + +static int uw_set_tdp(u8 tdp_index, u8 tdp_data) +{ + u16 tdp_base_addr = 0x0783; + u16 tdp_current_addr = tdp_base_addr + tdp_index; + bool has_current_setting = false; + + if (tdp_index < 2 && uniwill_tdp_config_two) + has_current_setting = true; + else if (tdp_index < 3 && uniwill_tdp_config_three) + has_current_setting = true; + + if (!has_current_setting) + return -1; + + uniwill_write_ec_ram(tdp_current_addr, tdp_data); + + return 0; +} + static long uniwill_ioctl_interface(struct file *file, unsigned int cmd, unsigned long arg) { u32 result = 0; @@ -261,6 +315,19 @@ static long uniwill_ioctl_interface(struct file *file, unsigned int cmd, unsigne result = byte_data; copy_result = copy_to_user((void *) arg, &result, sizeof(result)); break; + case R_UW_TDP0: + result = uw_get_tdp(0); + copy_result = copy_to_user((void *) arg, &result, sizeof(result)); + break; + case R_UW_TDP1: + result = uw_get_tdp(1); + copy_result = copy_to_user((void *) arg, &result, sizeof(result)); + break; + case R_UW_TDP2: + result = uw_get_tdp(2); + copy_result = copy_to_user((void *) arg, &result, sizeof(result)); + break; + #ifdef DEBUG case R_TF_BC: copy_result = copy_from_user(&uw_arg, (void *) arg, sizeof(uw_arg)); @@ -304,6 +371,18 @@ static long uniwill_ioctl_interface(struct file *file, unsigned int cmd, unsigne case W_UW_FANAUTO: uw_set_fan_auto(); break; + case W_UW_TDP0: + copy_result = copy_from_user(&argument, (int32_t *) arg, sizeof(argument)); + uw_set_tdp(0, argument); + break; + case W_UW_TDP1: + copy_result = copy_from_user(&argument, (int32_t *) arg, sizeof(argument)); + uw_set_tdp(1, argument); + break; + case W_UW_TDP2: + copy_result = copy_from_user(&argument, (int32_t *) arg, sizeof(argument)); + uw_set_tdp(2, argument); + break; #ifdef DEBUG case W_TF_BC: reg_write_return.dword = 0; diff --git a/src/tuxedo_io/tuxedo_io_ioctl.h b/src/tuxedo_io/tuxedo_io_ioctl.h index f63fb7f..e177fe1 100644 --- a/src/tuxedo_io/tuxedo_io_ioctl.h +++ b/src/tuxedo_io/tuxedo_io_ioctl.h @@ -80,6 +80,10 @@ #define R_UW_MODE _IOR(MAGIC_READ_UW, 0x14, int32_t*) #define R_UW_MODE_ENABLE _IOR(MAGIC_READ_UW, 0x15, int32_t*) +#define R_UW_TDP0 _IOR(MAGIC_READ_UW, 0x16, int32_t*) +#define R_UW_TDP1 _IOR(MAGIC_READ_UW, 0x17, int32_t*) +#define R_UW_TDP2 _IOR(MAGIC_READ_UW, 0x18, int32_t*) + // Write #define W_UW_FANSPEED _IOW(MAGIC_WRITE_UW, 0x10, int32_t*) #define W_UW_FANSPEED2 _IOW(MAGIC_WRITE_UW, 0x11, int32_t*) @@ -87,4 +91,8 @@ #define W_UW_MODE_ENABLE _IOW(MAGIC_WRITE_UW, 0x13, int32_t*) #define W_UW_FANAUTO _IO(MAGIC_WRITE_UW, 0x14) // undo all previous calls of W_UW_FANSPEED and W_UW_FANSPEED2 +#define W_UW_TDP0 _IOW(MAGIC_WRITE_UW, 0x15, int32_t*) +#define W_UW_TDP1 _IOW(MAGIC_WRITE_UW, 0x16, int32_t*) +#define W_UW_TDP2 _IOW(MAGIC_WRITE_UW, 0x17, int32_t*) + #endif From 7593dd33ee06d8c62bfe563e18857f67715df24e Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Tue, 19 Oct 2021 20:13:14 +0200 Subject: [PATCH 03/26] Add uw min/max TDP interface - Min/max TDP interface prototype - Identification structure for "old style" uw perf. profiles --- src/tuxedo_io/tuxedo_io.c | 122 +++++++++++++++++++++++++++++++- src/tuxedo_io/tuxedo_io_ioctl.h | 6 ++ 2 files changed, 125 insertions(+), 3 deletions(-) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 874f89c..9153e95 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -47,20 +47,68 @@ MODULE_ALIAS("wmi:" UNIWILL_WMI_MGMT_GUID_BC); static u32 id_check_clevo; static u32 id_check_uniwill; +/** + * strstr version of dmi_match + */ +static bool dmi_string_in(enum dmi_field f, const char *str) +{ + const char *info = dmi_get_system_info(f); + + if (info == NULL || str == NULL) + return info == str; + + return strstr(info, str) != NULL; +} + static u32 clevo_identify(void) { return clevo_get_active_interface_id(NULL) == 0 ? 1 : 0; } +/* + * Identification for uniwill_power_profile_v1 + * + * - Two profiles present in low power devices often called + * "power save" and "balanced". + * - Three profiles present mainly in devices with discrete + * graphics card often called "power save", "balanced" + * and "enthusiast" + */ +static bool uniwill_profile_v1; +static bool uniwill_profile_v1_two_profs; +static bool uniwill_profile_v1_three_profs; + static bool uniwill_tdp_config_two; static bool uniwill_tdp_config_three; static u32 uniwill_identify(void) { + uniwill_profile_v1_two_profs = false + // TODO: BA15 + || dmi_match(DMI_BOARD_NAME, "PULSE1401") + || dmi_match(DMI_BOARD_NAME, "PULSE1501") + ; + + uniwill_profile_v1_three_profs = false + || dmi_match(DMI_BOARD_NAME, "POLARIS1501A1650TI") + || dmi_match(DMI_BOARD_NAME, "POLARIS1501A2060") + || dmi_match(DMI_BOARD_NAME, "POLARIS1501I1650TI") + || dmi_match(DMI_BOARD_NAME, "POLARIS1501I2060") + || dmi_match(DMI_BOARD_NAME, "POLARIS1701A1650TI") + || dmi_match(DMI_BOARD_NAME, "POLARIS1701A2060") + || dmi_match(DMI_BOARD_NAME, "POLARIS1701I1650TI") + || dmi_match(DMI_BOARD_NAME, "POLARIS1701I2060") + ; + + uniwill_profile_v1 = + uniwill_profile_v1_two_profs || + uniwill_profile_v1_three_profs; + // Device check for two configurable TDPs uniwill_tdp_config_two = false #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) - || dmi_match(DMI_PRODUCT_SKU, "0001") + || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TUX") + || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TRX") #endif ; @@ -218,6 +266,44 @@ static u32 uw_set_fan_auto(void) return 0; } +/* + * TDP boundary definitions per device + */ +static int tdp_min_ph4tux[] = { 0x00, 0x00, 0x00 }; +static int tdp_max_ph4tux[] = { 0x26, 0x26, 0x00 }; +static int tdp_min_ph4trx[] = { 0x00, 0x00, 0x00 }; +static int tdp_max_ph4trx[] = { 0x32, 0x32, 0x00 }; + +static int uw_get_tdp_min(u8 tdp_index) +{ + int tdp_min = 0; + if (tdp_index > 2) + return -EINVAL; + + if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TUX")) { + tdp_min = tdp_min_ph4tux[tdp_index]; + } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TRX")) { + tdp_min = tdp_min_ph4trx[tdp_index]; + } + + return tdp_min; +} + +static int uw_get_tdp_max(u8 tdp_index) +{ + int tdp_max = 0; + if (tdp_index > 2) + return -EINVAL; + + if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TUX")) { + tdp_max = tdp_max_ph4tux[tdp_index]; + } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TRX")) { + tdp_max = tdp_max_ph4trx[tdp_index]; + } + + return tdp_max; +} + static int uw_get_tdp(u8 tdp_index) { u8 tdp_data; @@ -231,7 +317,7 @@ static int uw_get_tdp(u8 tdp_index) has_current_setting = true; if (!has_current_setting) - return -1; + return -EPERM; uniwill_read_ec_ram(tdp_current_addr, &tdp_data); @@ -240,6 +326,7 @@ static int uw_get_tdp(u8 tdp_index) static int uw_set_tdp(u8 tdp_index, u8 tdp_data) { + int tdp_min, tdp_max; u16 tdp_base_addr = 0x0783; u16 tdp_current_addr = tdp_base_addr + tdp_index; bool has_current_setting = false; @@ -249,8 +336,13 @@ static int uw_set_tdp(u8 tdp_index, u8 tdp_data) else if (tdp_index < 3 && uniwill_tdp_config_three) has_current_setting = true; + tdp_min = uw_get_tdp_min(tdp_index); + tdp_max = uw_get_tdp_max(tdp_index); + if (tdp_data < tdp_min || tdp_data > tdp_max) + return -EINVAL; + if (!has_current_setting) - return -1; + return -EPERM; uniwill_write_ec_ram(tdp_current_addr, tdp_data); @@ -327,6 +419,30 @@ static long uniwill_ioctl_interface(struct file *file, unsigned int cmd, unsigne result = uw_get_tdp(2); copy_result = copy_to_user((void *) arg, &result, sizeof(result)); break; + case R_UW_TDP0_MIN: + result = uw_get_tdp_min(0); + copy_result = copy_to_user((void *) arg, &result, sizeof(result)); + break; + case R_UW_TDP1_MIN: + result = uw_get_tdp_min(1); + copy_result = copy_to_user((void *) arg, &result, sizeof(result)); + break; + case R_UW_TDP2_MIN: + result = uw_get_tdp_min(2); + copy_result = copy_to_user((void *) arg, &result, sizeof(result)); + break; + case R_UW_TDP0_MAX: + result = uw_get_tdp_max(0); + copy_result = copy_to_user((void *) arg, &result, sizeof(result)); + break; + case R_UW_TDP1_MAX: + result = uw_get_tdp_max(1); + copy_result = copy_to_user((void *) arg, &result, sizeof(result)); + break; + case R_UW_TDP2_MAX: + result = uw_get_tdp_max(2); + copy_result = copy_to_user((void *) arg, &result, sizeof(result)); + break; #ifdef DEBUG case R_TF_BC: diff --git a/src/tuxedo_io/tuxedo_io_ioctl.h b/src/tuxedo_io/tuxedo_io_ioctl.h index e177fe1..45f55b0 100644 --- a/src/tuxedo_io/tuxedo_io_ioctl.h +++ b/src/tuxedo_io/tuxedo_io_ioctl.h @@ -83,6 +83,12 @@ #define R_UW_TDP0 _IOR(MAGIC_READ_UW, 0x16, int32_t*) #define R_UW_TDP1 _IOR(MAGIC_READ_UW, 0x17, int32_t*) #define R_UW_TDP2 _IOR(MAGIC_READ_UW, 0x18, int32_t*) +#define R_UW_TDP0_MIN _IOR(MAGIC_READ_UW, 0x19, int32_t*) +#define R_UW_TDP1_MIN _IOR(MAGIC_READ_UW, 0x1a, int32_t*) +#define R_UW_TDP2_MIN _IOR(MAGIC_READ_UW, 0x1b, int32_t*) +#define R_UW_TDP0_MAX _IOR(MAGIC_READ_UW, 0x1c, int32_t*) +#define R_UW_TDP1_MAX _IOR(MAGIC_READ_UW, 0x1d, int32_t*) +#define R_UW_TDP2_MAX _IOR(MAGIC_READ_UW, 0x1e, int32_t*) // Write #define W_UW_FANSPEED _IOW(MAGIC_WRITE_UW, 0x10, int32_t*) From ad8d42454ee0bfd2ab82ac1b678911f225b7a155 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Mon, 8 Nov 2021 20:26:15 +0100 Subject: [PATCH 04/26] Add PH4TQX --- src/tuxedo_io/tuxedo_io.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 9153e95..56e5cda 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -109,6 +109,7 @@ static u32 uniwill_identify(void) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TUX") || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TRX") + || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX") #endif ; @@ -269,11 +270,15 @@ static u32 uw_set_fan_auto(void) /* * TDP boundary definitions per device */ -static int tdp_min_ph4tux[] = { 0x00, 0x00, 0x00 }; +static int tdp_min_ph4tux[] = { 0x07, 0x07, 0x00 }; static int tdp_max_ph4tux[] = { 0x26, 0x26, 0x00 }; -static int tdp_min_ph4trx[] = { 0x00, 0x00, 0x00 }; + +static int tdp_min_ph4trx[] = { 0x07, 0x07, 0x00 }; static int tdp_max_ph4trx[] = { 0x32, 0x32, 0x00 }; +static int tdp_min_ph4tqx[] = { 0x07, 0x07, 0x00 }; +static int tdp_max_ph4tqx[] = { 0x32, 0x32, 0x00 }; + static int uw_get_tdp_min(u8 tdp_index) { int tdp_min = 0; @@ -284,6 +289,8 @@ static int uw_get_tdp_min(u8 tdp_index) tdp_min = tdp_min_ph4tux[tdp_index]; } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TRX")) { tdp_min = tdp_min_ph4trx[tdp_index]; + } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX")) { + tdp_min = tdp_min_ph4tqx[tdp_index]; } return tdp_min; @@ -299,6 +306,8 @@ static int uw_get_tdp_max(u8 tdp_index) tdp_max = tdp_max_ph4tux[tdp_index]; } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TRX")) { tdp_max = tdp_max_ph4trx[tdp_index]; + } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX")) { + tdp_max = tdp_max_ph4tqx[tdp_index]; } return tdp_max; From feca6dbcf4ee1ef7ecd1d24ddd84318b47443d50 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Mon, 8 Nov 2021 23:02:49 +0100 Subject: [PATCH 05/26] tuxedo_io: Add uw perf prof ioctl interface --- src/tuxedo_io/tuxedo_io.c | 47 +++++++++++++++++++++++++++++++++ src/tuxedo_io/tuxedo_io_ioctl.h | 4 +++ 2 files changed, 51 insertions(+) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 56e5cda..bb9720e 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -358,6 +358,41 @@ static int uw_set_tdp(u8 tdp_index, u8 tdp_data) return 0; } +/** + * Set profile 1-3 to 0xa0, 0x00 or 0x10 depending on + * device support. + */ +static u32 uw_set_performance_profile_v1(u8 profile_index) +{ + u8 current_value = 0x00, next_value; + u8 clear_bits = 0xa0 | 0x10; + u32 result; + result = uniwill_read_ec_ram(0x0751, ¤t_value); + if (result >= 0) { + next_value = current_value & ~clear_bits; + switch (profile_index) { + case 0x01: + next_value |= 0xa0; + break; + case 0x02: + next_value |= 0x00; + break; + case 0x03: + next_value |= 0x10; + break; + default: + result = -EINVAL; + break; + } + + if (result != -EINVAL) { + result = uniwill_write_ec_ram(0x0751, next_value); + } + } + + return result; +} + static long uniwill_ioctl_interface(struct file *file, unsigned int cmd, unsigned long arg) { u32 result = 0; @@ -452,6 +487,14 @@ static long uniwill_ioctl_interface(struct file *file, unsigned int cmd, unsigne result = uw_get_tdp_max(2); copy_result = copy_to_user((void *) arg, &result, sizeof(result)); break; + case R_UW_PROFS_AVAILABLE: + result = 0; + if (uniwill_profile_v1_two_profs) + result = 2; + else if (uniwill_profile_v1_three_profs) + result = 3; + copy_result = copy_to_user((void *) arg, &result, sizeof(result)); + break; #ifdef DEBUG case R_TF_BC: @@ -508,6 +551,10 @@ static long uniwill_ioctl_interface(struct file *file, unsigned int cmd, unsigne copy_result = copy_from_user(&argument, (int32_t *) arg, sizeof(argument)); uw_set_tdp(2, argument); break; + case W_UW_PERF_PROF: + copy_result = copy_from_user(&argument, (int32_t *) arg, sizeof(argument)); + uw_set_performance_profile_v1(argument); + break; #ifdef DEBUG case W_TF_BC: reg_write_return.dword = 0; diff --git a/src/tuxedo_io/tuxedo_io_ioctl.h b/src/tuxedo_io/tuxedo_io_ioctl.h index 45f55b0..a98d79c 100644 --- a/src/tuxedo_io/tuxedo_io_ioctl.h +++ b/src/tuxedo_io/tuxedo_io_ioctl.h @@ -90,6 +90,8 @@ #define R_UW_TDP1_MAX _IOR(MAGIC_READ_UW, 0x1d, int32_t*) #define R_UW_TDP2_MAX _IOR(MAGIC_READ_UW, 0x1e, int32_t*) +#define R_UW_PROFS_AVAILABLE _IOR(MAGIC_READ_UW, 0x1f, int32_t*) + // Write #define W_UW_FANSPEED _IOW(MAGIC_WRITE_UW, 0x10, int32_t*) #define W_UW_FANSPEED2 _IOW(MAGIC_WRITE_UW, 0x11, int32_t*) @@ -101,4 +103,6 @@ #define W_UW_TDP1 _IOW(MAGIC_WRITE_UW, 0x16, int32_t*) #define W_UW_TDP2 _IOW(MAGIC_WRITE_UW, 0x17, int32_t*) +#define W_UW_PERF_PROF _IOW(MAGIC_WRITE_UW, 0x18, int32_t*) + #endif From 55022eb636e2ae67090d9646d7121b73d3cb83a0 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Wed, 10 Nov 2021 20:28:33 +0100 Subject: [PATCH 06/26] Add BA15 with two power profiles --- src/tuxedo_io/tuxedo_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index bb9720e..8a6ebfb 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -84,7 +84,7 @@ static bool uniwill_tdp_config_three; static u32 uniwill_identify(void) { uniwill_profile_v1_two_profs = false - // TODO: BA15 + || dmi_match(DMI_BOARD_NAME, "PF5PU1G") || dmi_match(DMI_BOARD_NAME, "PULSE1401") || dmi_match(DMI_BOARD_NAME, "PULSE1501") ; From f08b9af71470b3c5f3ee15459cb6927f8f8865c2 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Wed, 10 Nov 2021 21:29:03 +0100 Subject: [PATCH 07/26] Add three profiles to polaris/stellaris gen2/3 for the LEDs --- src/tuxedo_io/tuxedo_io.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 8a6ebfb..2d5ee92 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -90,6 +90,7 @@ static u32 uniwill_identify(void) ; uniwill_profile_v1_three_profs = false + // Devices with "classic" profile support || dmi_match(DMI_BOARD_NAME, "POLARIS1501A1650TI") || dmi_match(DMI_BOARD_NAME, "POLARIS1501A2060") || dmi_match(DMI_BOARD_NAME, "POLARIS1501I1650TI") @@ -98,6 +99,13 @@ static u32 uniwill_identify(void) || dmi_match(DMI_BOARD_NAME, "POLARIS1701A2060") || dmi_match(DMI_BOARD_NAME, "POLARIS1701I1650TI") || dmi_match(DMI_BOARD_NAME, "POLARIS1701I2060") + // Devices where profile mainly controls power profile LED status + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") ; uniwill_profile_v1 = From 5173c0fc33106c9293fae4d5ba0b716794543589 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Wed, 10 Nov 2021 21:42:52 +0100 Subject: [PATCH 08/26] Add TDP support for stellaris/polaris gen 2/3 --- src/tuxedo_io/tuxedo_io.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 2d5ee92..14785c1 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -118,6 +118,12 @@ static u32 uniwill_identify(void) || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TUX") || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TRX") || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") #endif ; @@ -287,6 +293,9 @@ static int tdp_max_ph4trx[] = { 0x32, 0x32, 0x00 }; static int tdp_min_ph4tqx[] = { 0x07, 0x07, 0x00 }; static int tdp_max_ph4tqx[] = { 0x32, 0x32, 0x00 }; +static int tdp_min_gmxtgxx[] = { 0x00, 0x00, 0x00 }; +static int tdp_max_gmxtgxx[] = { 0x78, 0x78, 0x78 }; + static int uw_get_tdp_min(u8 tdp_index) { int tdp_min = 0; @@ -299,6 +308,9 @@ static int uw_get_tdp_min(u8 tdp_index) tdp_min = tdp_min_ph4trx[tdp_index]; } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX")) { tdp_min = tdp_min_ph4tqx[tdp_index]; + } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03")) { + tdp_min = tdp_min_gmxtgxx[tdp_index]; } return tdp_min; @@ -316,6 +328,9 @@ static int uw_get_tdp_max(u8 tdp_index) tdp_max = tdp_max_ph4trx[tdp_index]; } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX")) { tdp_max = tdp_max_ph4tqx[tdp_index]; + } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03")) { + tdp_max = tdp_max_gmxtgxx[tdp_index]; } return tdp_max; From d848111bb742914a295782163bf4d42f69c7c0bf Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Thu, 11 Nov 2021 22:09:21 +0100 Subject: [PATCH 09/26] Move uw device features to interfaces struct --- src/tuxedo_io/tuxedo_io.c | 78 +++++---------------------------------- src/uniwill_interfaces.h | 23 ++++++++++++ src/uniwill_keyboard.h | 59 +++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 69 deletions(-) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 14785c1..3eee737 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -47,6 +47,8 @@ MODULE_ALIAS("wmi:" UNIWILL_WMI_MGMT_GUID_BC); static u32 id_check_clevo; static u32 id_check_uniwill; +static struct uniwill_device_features_t *uw_feats; + /** * strstr version of dmi_match */ @@ -65,71 +67,9 @@ static u32 clevo_identify(void) return clevo_get_active_interface_id(NULL) == 0 ? 1 : 0; } -/* - * Identification for uniwill_power_profile_v1 - * - * - Two profiles present in low power devices often called - * "power save" and "balanced". - * - Three profiles present mainly in devices with discrete - * graphics card often called "power save", "balanced" - * and "enthusiast" - */ -static bool uniwill_profile_v1; -static bool uniwill_profile_v1_two_profs; -static bool uniwill_profile_v1_three_profs; - -static bool uniwill_tdp_config_two; -static bool uniwill_tdp_config_three; - static u32 uniwill_identify(void) { - uniwill_profile_v1_two_profs = false - || dmi_match(DMI_BOARD_NAME, "PF5PU1G") - || dmi_match(DMI_BOARD_NAME, "PULSE1401") - || dmi_match(DMI_BOARD_NAME, "PULSE1501") - ; - - uniwill_profile_v1_three_profs = false - // Devices with "classic" profile support - || dmi_match(DMI_BOARD_NAME, "POLARIS1501A1650TI") - || dmi_match(DMI_BOARD_NAME, "POLARIS1501A2060") - || dmi_match(DMI_BOARD_NAME, "POLARIS1501I1650TI") - || dmi_match(DMI_BOARD_NAME, "POLARIS1501I2060") - || dmi_match(DMI_BOARD_NAME, "POLARIS1701A1650TI") - || dmi_match(DMI_BOARD_NAME, "POLARIS1701A2060") - || dmi_match(DMI_BOARD_NAME, "POLARIS1701I1650TI") - || dmi_match(DMI_BOARD_NAME, "POLARIS1701I2060") - // Devices where profile mainly controls power profile LED status - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") - || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03") - || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") - ; - - uniwill_profile_v1 = - uniwill_profile_v1_two_profs || - uniwill_profile_v1_three_profs; - - // Device check for two configurable TDPs - uniwill_tdp_config_two = false -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) - || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TUX") - || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TRX") - || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") - || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03") - || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") -#endif - ; - - // Device check for three configurable TDPs - uniwill_tdp_config_three = false; - + uw_feats = uniwill_get_device_features(); return uniwill_get_active_interface_id(NULL) == 0 ? 1 : 0; } @@ -343,9 +283,9 @@ static int uw_get_tdp(u8 tdp_index) u16 tdp_current_addr = tdp_base_addr + tdp_index; bool has_current_setting = false; - if (tdp_index < 2 && uniwill_tdp_config_two) + if (tdp_index < 2 && uw_feats->uniwill_tdp_config_two) has_current_setting = true; - else if (tdp_index < 3 && uniwill_tdp_config_three) + else if (tdp_index < 3 && uw_feats->uniwill_tdp_config_three) has_current_setting = true; if (!has_current_setting) @@ -363,9 +303,9 @@ static int uw_set_tdp(u8 tdp_index, u8 tdp_data) u16 tdp_current_addr = tdp_base_addr + tdp_index; bool has_current_setting = false; - if (tdp_index < 2 && uniwill_tdp_config_two) + if (tdp_index < 2 && uw_feats->uniwill_tdp_config_two) has_current_setting = true; - else if (tdp_index < 3 && uniwill_tdp_config_three) + else if (tdp_index < 3 && uw_feats->uniwill_tdp_config_three) has_current_setting = true; tdp_min = uw_get_tdp_min(tdp_index); @@ -512,9 +452,9 @@ static long uniwill_ioctl_interface(struct file *file, unsigned int cmd, unsigne break; case R_UW_PROFS_AVAILABLE: result = 0; - if (uniwill_profile_v1_two_profs) + if (uw_feats->uniwill_profile_v1_two_profs) result = 2; - else if (uniwill_profile_v1_three_profs) + else if (uw_feats->uniwill_profile_v1_three_profs) result = 3; copy_result = copy_to_user((void *) arg, &result, sizeof(result)); break; diff --git a/src/uniwill_interfaces.h b/src/uniwill_interfaces.h index 3c1bf45..10ae6e3 100644 --- a/src/uniwill_interfaces.h +++ b/src/uniwill_interfaces.h @@ -46,11 +46,34 @@ struct uniwill_interface_t { uniwill_write_ec_ram_t *write_ec_ram; }; +struct uniwill_device_features_t { + /** + * Identification for uniwill_power_profile_v1 + * + * - Two profiles present in low power devices often called + * "power save" and "balanced". + * - Three profiles present mainly in devices with discrete + * graphics card often called "power save", "balanced" + * and "enthusiast" + */ + bool uniwill_profile_v1; + bool uniwill_profile_v1_two_profs; + bool uniwill_profile_v1_three_profs; + /** + * Two or three configurable TDP values. Generally two for + * low power/more mobile devices and three for heavier workstations + * and gaming devices. + */ + bool uniwill_tdp_config_two; + bool uniwill_tdp_config_three; +}; + u32 uniwill_add_interface(struct uniwill_interface_t *new_interface); u32 uniwill_remove_interface(struct uniwill_interface_t *interface); uniwill_read_ec_ram_t uniwill_read_ec_ram; uniwill_write_ec_ram_t uniwill_write_ec_ram; u32 uniwill_get_active_interface_id(char **id_str); +struct uniwill_device_features_t *uniwill_get_device_features(void); union uw_ec_read_return { u32 dword; diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 41f7b8d..969e3ca 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -67,6 +67,8 @@ struct kbd_led_state_uw_t { .color = UNIWILL_COLOR_DEFAULT, }; +struct uniwill_device_features_t uniwill_device_features; + static u8 uniwill_kbd_bl_enable_state_on_start; static bool uniwill_kbd_bl_type_rgb_single_color = true; @@ -180,6 +182,61 @@ u32 uniwill_get_active_interface_id(char **id_str) } EXPORT_SYMBOL(uniwill_get_active_interface_id); +struct uniwill_device_features_t *uniwill_get_device_features(void) +{ + struct uniwill_device_features_t *uw_feats = &uniwill_device_features; + + uw_feats->uniwill_profile_v1_two_profs = false + || dmi_match(DMI_BOARD_NAME, "PF5PU1G") + || dmi_match(DMI_BOARD_NAME, "PULSE1401") + || dmi_match(DMI_BOARD_NAME, "PULSE1501") + ; + + uw_feats->uniwill_profile_v1_three_profs = false + // Devices with "classic" profile support + || dmi_match(DMI_BOARD_NAME, "POLARIS1501A1650TI") + || dmi_match(DMI_BOARD_NAME, "POLARIS1501A2060") + || dmi_match(DMI_BOARD_NAME, "POLARIS1501I1650TI") + || dmi_match(DMI_BOARD_NAME, "POLARIS1501I2060") + || dmi_match(DMI_BOARD_NAME, "POLARIS1701A1650TI") + || dmi_match(DMI_BOARD_NAME, "POLARIS1701A2060") + || dmi_match(DMI_BOARD_NAME, "POLARIS1701I1650TI") + || dmi_match(DMI_BOARD_NAME, "POLARIS1701I2060") + // Devices where profile mainly controls power profile LED status + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") + ; + + uw_feats->uniwill_profile_v1 = + uw_feats->uniwill_profile_v1_two_profs || + uw_feats->uniwill_profile_v1_three_profs; + + // Device check for two configurable TDPs + uw_feats->uniwill_tdp_config_two = false +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) + || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TUX") + || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TRX") + || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") +#endif + ; + + // Device check for three configurable TDPs + uw_feats->uniwill_tdp_config_three = false; + + return uw_feats; +} +EXPORT_SYMBOL(uniwill_get_device_features); + static void key_event_work(struct work_struct *work) { sparse_keymap_report_known_event( @@ -742,6 +799,8 @@ static int uniwill_keyboard_probe(struct platform_device *dev) u8 data; int status; + uniwill_get_device_features(); + // FIXME Hard set balanced profile until we have implemented a way to // switch it while tuxedo_io is loaded // uw_ec_write_addr(0x51, 0x07, 0x00, 0x00, ®_write_return); From 4903b89239be4e5ddcb9d0a095149a5b443621a7 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Thu, 11 Nov 2021 22:19:57 +0100 Subject: [PATCH 10/26] Split v1 three profile feature to include leds only version extra --- src/tuxedo_io/tuxedo_io.c | 2 +- src/uniwill_interfaces.h | 1 + src/uniwill_keyboard.h | 7 ++++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 3eee737..28ffdc8 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -454,7 +454,7 @@ static long uniwill_ioctl_interface(struct file *file, unsigned int cmd, unsigne result = 0; if (uw_feats->uniwill_profile_v1_two_profs) result = 2; - else if (uw_feats->uniwill_profile_v1_three_profs) + else if (uw_feats->uniwill_profile_v1_three_profs || uw_feats->uniwill_profile_v1_three_profs_leds_only) result = 3; copy_result = copy_to_user((void *) arg, &result, sizeof(result)); break; diff --git a/src/uniwill_interfaces.h b/src/uniwill_interfaces.h index 10ae6e3..409319c 100644 --- a/src/uniwill_interfaces.h +++ b/src/uniwill_interfaces.h @@ -59,6 +59,7 @@ struct uniwill_device_features_t { bool uniwill_profile_v1; bool uniwill_profile_v1_two_profs; bool uniwill_profile_v1_three_profs; + bool uniwill_profile_v1_three_profs_leds_only; /** * Two or three configurable TDP values. Generally two for * low power/more mobile devices and three for heavier workstations diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 969e3ca..7a60656 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -202,13 +202,18 @@ struct uniwill_device_features_t *uniwill_get_device_features(void) || dmi_match(DMI_BOARD_NAME, "POLARIS1701A2060") || dmi_match(DMI_BOARD_NAME, "POLARIS1701I1650TI") || dmi_match(DMI_BOARD_NAME, "POLARIS1701I2060") + ; + + uw_feats->uniwill_profile_v1_three_profs_leds_only = false // Devices where profile mainly controls power profile LED status +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02") || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02") || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03") || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") +#endif ; uw_feats->uniwill_profile_v1 = @@ -799,7 +804,7 @@ static int uniwill_keyboard_probe(struct platform_device *dev) u8 data; int status; - uniwill_get_device_features(); + struct uniwill_device_features_t *uw_feats = uniwill_get_device_features(); // FIXME Hard set balanced profile until we have implemented a way to // switch it while tuxedo_io is loaded From bd56c1ecb912bb5cbe7c12dd2ae26f7aed16d2ba Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Thu, 11 Nov 2021 22:31:12 +0100 Subject: [PATCH 11/26] Restrict fan-curve copy to "v1" profile devices only --- src/uniwill_keyboard.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 7a60656..72febab 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -811,11 +811,13 @@ static int uniwill_keyboard_probe(struct platform_device *dev) // uw_ec_write_addr(0x51, 0x07, 0x00, 0x00, ®_write_return); uniwill_write_ec_ram(0x0751, 0x00); - // Set manual-mode fan-curve in 0x0743 - 0x0747 - // Some kind of default fan-curve is stored in 0x0786 - 0x078a: Using it to initialize manual-mode fan-curve - for (i = 0; i < 5; ++i) { - uniwill_read_ec_ram(0x0786 + i, &data); - uniwill_write_ec_ram(0x0743 + i, data); + if (uw_feats->uniwill_profile_v1) { + // Set manual-mode fan-curve in 0x0743 - 0x0747 + // Some kind of default fan-curve is stored in 0x0786 - 0x078a: Using it to initialize manual-mode fan-curve + for (i = 0; i < 5; ++i) { + uniwill_read_ec_ram(0x0786 + i, &data); + uniwill_write_ec_ram(0x0743 + i, data); + } } // Enable manual mode From 91742ab1c590cafdd1b551f29b69961e2c0392ea Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Thu, 11 Nov 2021 23:01:46 +0100 Subject: [PATCH 12/26] Move and correct TDP device ids --- src/uniwill_keyboard.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 72febab..ffb77ab 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -226,17 +226,18 @@ struct uniwill_device_features_t *uniwill_get_device_features(void) || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TUX") || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TRX") || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") - || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03") - || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") #endif ; // Device check for three configurable TDPs - uw_feats->uniwill_tdp_config_three = false; + uw_feats->uniwill_tdp_config_three = false + //|| dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02") + //|| dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02") + //|| dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03") + //|| dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") + ; return uw_feats; } From 68800661b4ac972f45fcf28250f4b76dfbe87ab7 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Fri, 12 Nov 2021 23:10:10 +0100 Subject: [PATCH 13/26] Modify and add TDP device definitions - Basic 120W upper limit over all - Change min limit to 1W - Add Polaris gen 2 - Add Polaris/Stellaris AMD gen 3 --- src/tuxedo_io/tuxedo_io.c | 31 +++++++++++++++++++++++++++---- src/uniwill_keyboard.h | 8 ++++---- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 28ffdc8..6955d51 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -224,18 +224,27 @@ static u32 uw_set_fan_auto(void) /* * TDP boundary definitions per device */ -static int tdp_min_ph4tux[] = { 0x07, 0x07, 0x00 }; +static int tdp_min_ph4tux[] = { 0x01, 0x01, 0x00 }; static int tdp_max_ph4tux[] = { 0x26, 0x26, 0x00 }; -static int tdp_min_ph4trx[] = { 0x07, 0x07, 0x00 }; +static int tdp_min_ph4trx[] = { 0x01, 0x01, 0x00 }; static int tdp_max_ph4trx[] = { 0x32, 0x32, 0x00 }; -static int tdp_min_ph4tqx[] = { 0x07, 0x07, 0x00 }; +static int tdp_min_ph4tqx[] = { 0x01, 0x01, 0x00 }; static int tdp_max_ph4tqx[] = { 0x32, 0x32, 0x00 }; -static int tdp_min_gmxtgxx[] = { 0x00, 0x00, 0x00 }; +static int tdp_min_gmxngxx[] = { 0x01, 0x01, 0x01 }; +static int tdp_max_gmxngxx[] = { 0x78, 0x78, 0x78 }; + +static int tdp_min_gmxmgxx[] = { 0x01, 0x01, 0x01 }; +static int tdp_max_gmxmgxx[] = { 0x78, 0x78, 0x78 }; + +static int tdp_min_gmxtgxx[] = { 0x01, 0x01, 0x01 }; static int tdp_max_gmxtgxx[] = { 0x78, 0x78, 0x78 }; +static int tdp_min_gmxzgxx[] = { 0x01, 0x01, 0x01 }; +static int tdp_max_gmxzgxx[] = { 0x78, 0x78, 0x78 }; + static int uw_get_tdp_min(u8 tdp_index) { int tdp_min = 0; @@ -248,9 +257,16 @@ static int uw_get_tdp_min(u8 tdp_index) tdp_min = tdp_min_ph4trx[tdp_index]; } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX")) { tdp_min = tdp_min_ph4tqx[tdp_index]; + } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02")) { + tdp_min = tdp_min_gmxngxx[tdp_index]; + } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02")) { + tdp_min = tdp_min_gmxmgxx[tdp_index]; } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03")) { tdp_min = tdp_min_gmxtgxx[tdp_index]; + } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03")) { + tdp_min = tdp_min_gmxzgxx[tdp_index]; } return tdp_min; @@ -268,9 +284,16 @@ static int uw_get_tdp_max(u8 tdp_index) tdp_max = tdp_max_ph4trx[tdp_index]; } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX")) { tdp_max = tdp_max_ph4tqx[tdp_index]; + } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02")) { + tdp_max = tdp_max_gmxngxx[tdp_index]; + } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02")) { + tdp_max = tdp_max_gmxmgxx[tdp_index]; } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03")) { tdp_max = tdp_max_gmxtgxx[tdp_index]; + } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03")) { + tdp_max = tdp_max_gmxzgxx[tdp_index]; } return tdp_max; diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index ffb77ab..fb0ed3a 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -231,12 +231,12 @@ struct uniwill_device_features_t *uniwill_get_device_features(void) // Device check for three configurable TDPs uw_feats->uniwill_tdp_config_three = false - //|| dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02") - //|| dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02") - //|| dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03") - //|| dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") ; return uw_feats; From 50ea0bb09f69ebef64f5cef57d2a821076082776 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Tue, 23 Nov 2021 15:38:45 +0100 Subject: [PATCH 14/26] Change model ID for some models --- src/tuxedo_io/tuxedo_io.c | 8 ++++---- src/uniwill_interfaces.h | 1 + src/uniwill_keyboard.h | 9 +++++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 6955d51..24714fe 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -251,9 +251,9 @@ static int uw_get_tdp_min(u8 tdp_index) if (tdp_index > 2) return -EINVAL; - if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TUX")) { + if (uw_feats->model == 0x13) { tdp_min = tdp_min_ph4tux[tdp_index]; - } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TRX")) { + } else if (uw_feats->model == 0x12) { tdp_min = tdp_min_ph4trx[tdp_index]; } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX")) { tdp_min = tdp_min_ph4tqx[tdp_index]; @@ -278,9 +278,9 @@ static int uw_get_tdp_max(u8 tdp_index) if (tdp_index > 2) return -EINVAL; - if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TUX")) { + if (uw_feats->model == 0x13) { tdp_max = tdp_max_ph4tux[tdp_index]; - } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TRX")) { + } else if (uw_feats->model == 0x12) { tdp_max = tdp_max_ph4trx[tdp_index]; } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX")) { tdp_max = tdp_max_ph4tqx[tdp_index]; diff --git a/src/uniwill_interfaces.h b/src/uniwill_interfaces.h index 409319c..c161d26 100644 --- a/src/uniwill_interfaces.h +++ b/src/uniwill_interfaces.h @@ -47,6 +47,7 @@ struct uniwill_interface_t { }; struct uniwill_device_features_t { + u8 model; /** * Identification for uniwill_power_profile_v1 * diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index fb0ed3a..518130f 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -185,6 +185,11 @@ EXPORT_SYMBOL(uniwill_get_active_interface_id); struct uniwill_device_features_t *uniwill_get_device_features(void) { struct uniwill_device_features_t *uw_feats = &uniwill_device_features; + u32 status; + + status = uniwill_read_ec_ram(0x0740, &uw_feats->model); + if (status != 0) + uw_feats->model = 0; uw_feats->uniwill_profile_v1_two_profs = false || dmi_match(DMI_BOARD_NAME, "PF5PU1G") @@ -223,8 +228,8 @@ struct uniwill_device_features_t *uniwill_get_device_features(void) // Device check for two configurable TDPs uw_feats->uniwill_tdp_config_two = false #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) - || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TUX") - || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TRX") + || uw_feats->model == 0x13 + || uw_feats->model == 0x12 || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX") #endif ; From 3fbc761cc9ca30e2a02480f6088d47f2ec55bad5 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Fri, 26 Nov 2021 15:43:18 +0100 Subject: [PATCH 15/26] Rearrange uw tdp identification + min/max getters Support for a device now only depending on if min/max definitions exist for chosen tdp parameter. --- src/tuxedo_io/tuxedo_io.c | 160 ++++++++++++++++++++------------------ src/uniwill_interfaces.h | 7 -- src/uniwill_keyboard.h | 19 ----- 3 files changed, 83 insertions(+), 103 deletions(-) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 24714fe..86d16ab 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -67,9 +67,68 @@ static u32 clevo_identify(void) return clevo_get_active_interface_id(NULL) == 0 ? 1 : 0; } +/* + * TDP boundary definitions per device + */ +static int tdp_min_ph4tux[] = { 0x01, 0x01, 0x00 }; +static int tdp_max_ph4tux[] = { 0x26, 0x26, 0x00 }; + +static int tdp_min_ph4trx[] = { 0x01, 0x01, 0x00 }; +static int tdp_max_ph4trx[] = { 0x32, 0x32, 0x00 }; + +static int tdp_min_ph4tqx[] = { 0x01, 0x01, 0x00 }; +static int tdp_max_ph4tqx[] = { 0x32, 0x32, 0x00 }; + +static int tdp_min_gmxngxx[] = { 0x01, 0x01, 0x01 }; +static int tdp_max_gmxngxx[] = { 0x78, 0x78, 0x78 }; + +static int tdp_min_gmxmgxx[] = { 0x01, 0x01, 0x01 }; +static int tdp_max_gmxmgxx[] = { 0x78, 0x78, 0x78 }; + +static int tdp_min_gmxtgxx[] = { 0x01, 0x01, 0x01 }; +static int tdp_max_gmxtgxx[] = { 0x78, 0x78, 0x78 }; + +static int tdp_min_gmxzgxx[] = { 0x01, 0x01, 0x01 }; +static int tdp_max_gmxzgxx[] = { 0x78, 0x78, 0x78 }; + +static int *tdp_min_defs = NULL; +static int *tdp_max_defs = NULL; + +void uw_id_tdp(void) +{ + if (uw_feats->model == 0x13) { + tdp_min_defs = tdp_min_ph4tux; + tdp_max_defs = tdp_max_ph4tux; + } else if (uw_feats->model == 0x12) { + tdp_min_defs = tdp_min_ph4trx; + tdp_max_defs = tdp_max_ph4trx; + } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX")) { + tdp_min_defs = tdp_min_ph4tqx; + tdp_max_defs = tdp_max_ph4tqx; + } else if (dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02")) { + tdp_min_defs = tdp_min_gmxngxx; + tdp_max_defs = tdp_max_gmxngxx; + } else if (dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02")) { + tdp_min_defs = tdp_min_gmxmgxx; + tdp_max_defs = tdp_max_gmxmgxx; + } else if (dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03")) { + tdp_min_defs = tdp_min_gmxtgxx; + tdp_max_defs = tdp_max_gmxtgxx; + } else if (dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03")) { + tdp_min_defs = tdp_min_gmxzgxx; + tdp_max_defs = tdp_max_gmxzgxx; + } else { + tdp_min_defs = NULL; + tdp_max_defs = NULL; + } +} + static u32 uniwill_identify(void) { uw_feats = uniwill_get_device_features(); + uw_id_tdp(); return uniwill_get_active_interface_id(NULL) == 0 ? 1 : 0; } @@ -221,82 +280,34 @@ static u32 uw_set_fan_auto(void) return 0; } -/* - * TDP boundary definitions per device - */ -static int tdp_min_ph4tux[] = { 0x01, 0x01, 0x00 }; -static int tdp_max_ph4tux[] = { 0x26, 0x26, 0x00 }; - -static int tdp_min_ph4trx[] = { 0x01, 0x01, 0x00 }; -static int tdp_max_ph4trx[] = { 0x32, 0x32, 0x00 }; - -static int tdp_min_ph4tqx[] = { 0x01, 0x01, 0x00 }; -static int tdp_max_ph4tqx[] = { 0x32, 0x32, 0x00 }; - -static int tdp_min_gmxngxx[] = { 0x01, 0x01, 0x01 }; -static int tdp_max_gmxngxx[] = { 0x78, 0x78, 0x78 }; - -static int tdp_min_gmxmgxx[] = { 0x01, 0x01, 0x01 }; -static int tdp_max_gmxmgxx[] = { 0x78, 0x78, 0x78 }; - -static int tdp_min_gmxtgxx[] = { 0x01, 0x01, 0x01 }; -static int tdp_max_gmxtgxx[] = { 0x78, 0x78, 0x78 }; - -static int tdp_min_gmxzgxx[] = { 0x01, 0x01, 0x01 }; -static int tdp_max_gmxzgxx[] = { 0x78, 0x78, 0x78 }; - static int uw_get_tdp_min(u8 tdp_index) { - int tdp_min = 0; if (tdp_index > 2) return -EINVAL; - if (uw_feats->model == 0x13) { - tdp_min = tdp_min_ph4tux[tdp_index]; - } else if (uw_feats->model == 0x12) { - tdp_min = tdp_min_ph4trx[tdp_index]; - } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX")) { - tdp_min = tdp_min_ph4tqx[tdp_index]; - } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02")) { - tdp_min = tdp_min_gmxngxx[tdp_index]; - } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02")) { - tdp_min = tdp_min_gmxmgxx[tdp_index]; - } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") - || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03")) { - tdp_min = tdp_min_gmxtgxx[tdp_index]; - } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") - || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03")) { - tdp_min = tdp_min_gmxzgxx[tdp_index]; + if (tdp_min_defs == NULL) + return -ENODEV; + + if (tdp_min_defs[tdp_index] <= 0) { + return -ENODEV; } - return tdp_min; + return tdp_min_defs[tdp_index]; } static int uw_get_tdp_max(u8 tdp_index) { - int tdp_max = 0; if (tdp_index > 2) return -EINVAL; - if (uw_feats->model == 0x13) { - tdp_max = tdp_max_ph4tux[tdp_index]; - } else if (uw_feats->model == 0x12) { - tdp_max = tdp_max_ph4trx[tdp_index]; - } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX")) { - tdp_max = tdp_max_ph4tqx[tdp_index]; - } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02")) { - tdp_max = tdp_max_gmxngxx[tdp_index]; - } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02")) { - tdp_max = tdp_max_gmxmgxx[tdp_index]; - } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") - || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03")) { - tdp_max = tdp_max_gmxtgxx[tdp_index]; - } else if ( dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") - || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03")) { - tdp_max = tdp_max_gmxzgxx[tdp_index]; + if (tdp_max_defs == NULL) + return -ENODEV; + + if (tdp_max_defs[tdp_index] <= 0) { + return -ENODEV; } - return tdp_max; + return tdp_max_defs[tdp_index]; } static int uw_get_tdp(u8 tdp_index) @@ -304,17 +315,16 @@ static int uw_get_tdp(u8 tdp_index) u8 tdp_data; u16 tdp_base_addr = 0x0783; u16 tdp_current_addr = tdp_base_addr + tdp_index; - bool has_current_setting = false; + int status; - if (tdp_index < 2 && uw_feats->uniwill_tdp_config_two) - has_current_setting = true; - else if (tdp_index < 3 && uw_feats->uniwill_tdp_config_three) - has_current_setting = true; + // Use min tdp to detect support for chosen tdp parameter + int min_tdp_status = uw_get_tdp_min(tdp_index); + if (min_tdp_status < 0) + return min_tdp_status; - if (!has_current_setting) - return -EPERM; - - uniwill_read_ec_ram(tdp_current_addr, &tdp_data); + status = uniwill_read_ec_ram(tdp_current_addr, &tdp_data); + if (status < 0) + return status; return tdp_data; } @@ -324,21 +334,17 @@ static int uw_set_tdp(u8 tdp_index, u8 tdp_data) int tdp_min, tdp_max; u16 tdp_base_addr = 0x0783; u16 tdp_current_addr = tdp_base_addr + tdp_index; - bool has_current_setting = false; - if (tdp_index < 2 && uw_feats->uniwill_tdp_config_two) - has_current_setting = true; - else if (tdp_index < 3 && uw_feats->uniwill_tdp_config_three) - has_current_setting = true; + // Use min tdp to detect support for chosen tdp parameter + int min_tdp_status = uw_get_tdp_min(tdp_index); + if (min_tdp_status < 0) + return min_tdp_status; tdp_min = uw_get_tdp_min(tdp_index); tdp_max = uw_get_tdp_max(tdp_index); if (tdp_data < tdp_min || tdp_data > tdp_max) return -EINVAL; - if (!has_current_setting) - return -EPERM; - uniwill_write_ec_ram(tdp_current_addr, tdp_data); return 0; diff --git a/src/uniwill_interfaces.h b/src/uniwill_interfaces.h index c161d26..b7f29f1 100644 --- a/src/uniwill_interfaces.h +++ b/src/uniwill_interfaces.h @@ -61,13 +61,6 @@ struct uniwill_device_features_t { bool uniwill_profile_v1_two_profs; bool uniwill_profile_v1_three_profs; bool uniwill_profile_v1_three_profs_leds_only; - /** - * Two or three configurable TDP values. Generally two for - * low power/more mobile devices and three for heavier workstations - * and gaming devices. - */ - bool uniwill_tdp_config_two; - bool uniwill_tdp_config_three; }; u32 uniwill_add_interface(struct uniwill_interface_t *new_interface); diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 518130f..45cbb81 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -225,25 +225,6 @@ struct uniwill_device_features_t *uniwill_get_device_features(void) uw_feats->uniwill_profile_v1_two_profs || uw_feats->uniwill_profile_v1_three_profs; - // Device check for two configurable TDPs - uw_feats->uniwill_tdp_config_two = false -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) - || uw_feats->model == 0x13 - || uw_feats->model == 0x12 - || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX") -#endif - ; - - // Device check for three configurable TDPs - uw_feats->uniwill_tdp_config_three = false - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") - || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03") - || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") - ; - return uw_feats; } EXPORT_SYMBOL(uniwill_get_device_features); From b6dea7ac2e873c9c6ee62593e9967f09b23a9d16 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Fri, 26 Nov 2021 15:49:17 +0100 Subject: [PATCH 16/26] Update uw tdp defs for polaris/stellaris Changes according to reported original table values - Min TDPs changed to 10W - Intel PL4 now max 200W resulting in 120/120/200 - AMD max defs lowered to 80/80/95 --- src/tuxedo_io/tuxedo_io.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 86d16ab..3a532d6 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -79,17 +79,17 @@ static int tdp_max_ph4trx[] = { 0x32, 0x32, 0x00 }; static int tdp_min_ph4tqx[] = { 0x01, 0x01, 0x00 }; static int tdp_max_ph4tqx[] = { 0x32, 0x32, 0x00 }; -static int tdp_min_gmxngxx[] = { 0x01, 0x01, 0x01 }; -static int tdp_max_gmxngxx[] = { 0x78, 0x78, 0x78 }; +static int tdp_min_gmxngxx[] = { 0x0a, 0x0a, 0x0a }; +static int tdp_max_gmxngxx[] = { 0x50, 0x50, 0x5f }; -static int tdp_min_gmxmgxx[] = { 0x01, 0x01, 0x01 }; -static int tdp_max_gmxmgxx[] = { 0x78, 0x78, 0x78 }; +static int tdp_min_gmxmgxx[] = { 0x0a, 0x0a, 0x0a }; +static int tdp_max_gmxmgxx[] = { 0x78, 0x78, 0xc8 }; -static int tdp_min_gmxtgxx[] = { 0x01, 0x01, 0x01 }; -static int tdp_max_gmxtgxx[] = { 0x78, 0x78, 0x78 }; +static int tdp_min_gmxtgxx[] = { 0x0a, 0x0a, 0x0a }; +static int tdp_max_gmxtgxx[] = { 0x78, 0x78, 0xc8 }; -static int tdp_min_gmxzgxx[] = { 0x01, 0x01, 0x01 }; -static int tdp_max_gmxzgxx[] = { 0x78, 0x78, 0x78 }; +static int tdp_min_gmxzgxx[] = { 0x0a, 0x0a, 0x0a }; +static int tdp_max_gmxzgxx[] = { 0x50, 0x50, 0x5f }; static int *tdp_min_defs = NULL; static int *tdp_max_defs = NULL; From 0d4a633c6569f4d3ea80560adae71a7b5af05839 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Mon, 10 Jan 2022 19:44:15 +0100 Subject: [PATCH 17/26] Add IBP14gen6 id and refactor model numbers --- src/tuxedo_io/tuxedo_io.c | 6 +++--- src/uniwill_interfaces.h | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 3a532d6..94e5625 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -96,13 +96,13 @@ static int *tdp_max_defs = NULL; void uw_id_tdp(void) { - if (uw_feats->model == 0x13) { + if (uw_feats->model == UW_MODEL_PH4TUX) { tdp_min_defs = tdp_min_ph4tux; tdp_max_defs = tdp_max_ph4tux; - } else if (uw_feats->model == 0x12) { + } else if (uw_feats->model == UW_MODEL_PH4TRX) { tdp_min_defs = tdp_min_ph4trx; tdp_max_defs = tdp_max_ph4trx; - } else if (dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX")) { + } else if (uw_feats->model == UW_MODEL_PH4TQF) { tdp_min_defs = tdp_min_ph4tqx; tdp_max_defs = tdp_max_ph4tqx; } else if (dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02")) { diff --git a/src/uniwill_interfaces.h b/src/uniwill_interfaces.h index b7f29f1..fbc1d71 100644 --- a/src/uniwill_interfaces.h +++ b/src/uniwill_interfaces.h @@ -46,6 +46,10 @@ struct uniwill_interface_t { uniwill_write_ec_ram_t *write_ec_ram; }; +#define UW_MODEL_PH4TUX 0x13 +#define UW_MODEL_PH4TRX 0x12 +#define UW_MODEL_PH4TQF 0x14 + struct uniwill_device_features_t { u8 model; /** From 0b6d0073b2feb0b21f8b41988d83a177fd91c0e0 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Mon, 17 Jan 2022 21:16:29 +0100 Subject: [PATCH 18/26] Assign three profiles to xmg fusion --- src/uniwill_keyboard.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 45cbb81..ea5a50f 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -207,6 +207,9 @@ struct uniwill_device_features_t *uniwill_get_device_features(void) || dmi_match(DMI_BOARD_NAME, "POLARIS1701A2060") || dmi_match(DMI_BOARD_NAME, "POLARIS1701I1650TI") || dmi_match(DMI_BOARD_NAME, "POLARIS1701I2060") + || dmi_match(DMI_BOARD_NAME, "LAPQC71A") + || dmi_match(DMI_BOARD_NAME, "LAPQC71B") + || dmi_match(DMI_PRODUCT_NAME, "A60 MUV") ; uw_feats->uniwill_profile_v1_three_profs_leds_only = false From e9b429cceac6a639153ff0edfc6d65004464885a Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Wed, 30 Mar 2022 11:15:06 +0200 Subject: [PATCH 19/26] Fix build on older kernel --- src/tuxedo_io/tuxedo_io.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 94e5625..02380d5 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -1,5 +1,5 @@ /*! - * Copyright (c) 2019-2021 TUXEDO Computers GmbH + * Copyright (c) 2019-2022 TUXEDO Computers GmbH * * This file is part of tuxedo-io. * @@ -105,6 +105,7 @@ void uw_id_tdp(void) } else if (uw_feats->model == UW_MODEL_PH4TQF) { tdp_min_defs = tdp_min_ph4tqx; tdp_max_defs = tdp_max_ph4tqx; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) } else if (dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02")) { tdp_min_defs = tdp_min_gmxngxx; tdp_max_defs = tdp_max_gmxngxx; @@ -119,6 +120,7 @@ void uw_id_tdp(void) || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03")) { tdp_min_defs = tdp_min_gmxzgxx; tdp_max_defs = tdp_max_gmxzgxx; +#endif } else { tdp_min_defs = NULL; tdp_max_defs = NULL; From a3f73cc50254e83ef387688937b3e017d85b5e27 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Wed, 30 Mar 2022 11:16:08 +0200 Subject: [PATCH 20/26] ioctl: Add uw model id getter --- src/tuxedo_io/tuxedo_io.c | 4 ++++ src/tuxedo_io/tuxedo_io_ioctl.h | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 02380d5..90a310b 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -415,6 +415,10 @@ static long uniwill_ioctl_interface(struct file *file, unsigned int cmd, unsigne copy_result = copy_to_user((char *) arg, str_no_if, strlen(str_no_if) + 1); } break; + case R_UW_MODEL_ID: + result = uw_feats->model; + copy_result = copy_to_user((void *) arg, &result, sizeof(result)); + break; case R_UW_FANSPEED: uniwill_read_ec_ram(0x1804, &byte_data); result = byte_data; diff --git a/src/tuxedo_io/tuxedo_io_ioctl.h b/src/tuxedo_io/tuxedo_io_ioctl.h index a98d79c..596dbfe 100644 --- a/src/tuxedo_io/tuxedo_io_ioctl.h +++ b/src/tuxedo_io/tuxedo_io_ioctl.h @@ -1,5 +1,5 @@ /*! - * Copyright (c) 2019-2021 TUXEDO Computers GmbH + * Copyright (c) 2019-2022 TUXEDO Computers GmbH * * This file is part of tuxedo-io. * @@ -72,6 +72,7 @@ // Read #define R_UW_HW_IF_STR _IOR(MAGIC_READ_UW, 0x00, char*) +#define R_UW_MODEL_ID _IOR(MAGIC_READ_UW, 0x01, int32_t*) #define R_UW_FANSPEED _IOR(MAGIC_READ_UW, 0x10, int32_t*) #define R_UW_FANSPEED2 _IOR(MAGIC_READ_UW, 0x11, int32_t*) #define R_UW_FAN_TEMP _IOR(MAGIC_READ_UW, 0x12, int32_t*) From a8a934b4f176f1b0c2fb6d165c236da6c581e985 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Wed, 27 Jul 2022 12:27:14 +0200 Subject: [PATCH 21/26] Add polaris intel gen 4 power defs --- src/tuxedo_io/tuxedo_io.c | 6 ++++++ src/uniwill_keyboard.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 90a310b..8526b40 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -91,6 +91,9 @@ static int tdp_max_gmxtgxx[] = { 0x78, 0x78, 0xc8 }; static int tdp_min_gmxzgxx[] = { 0x0a, 0x0a, 0x0a }; static int tdp_max_gmxzgxx[] = { 0x50, 0x50, 0x5f }; +static int tdp_min_gmxagxx[] = { 0x0a, 0x0a, 0x0a }; +static int tdp_max_gmxagxx[] = { 0x78, 0x78, 0xd7 }; + static int *tdp_min_defs = NULL; static int *tdp_max_defs = NULL; @@ -120,6 +123,9 @@ void uw_id_tdp(void) || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03")) { tdp_min_defs = tdp_min_gmxzgxx; tdp_max_defs = tdp_max_gmxzgxx; + } else if (dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI04")) { + tdp_min_defs = tdp_min_gmxagxx; + tdp_max_defs = tdp_max_gmxagxx; #endif } else { tdp_min_defs = NULL; diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index ea5a50f..e242419 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -221,6 +221,7 @@ struct uniwill_device_features_t *uniwill_get_device_features(void) || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03") || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI04") #endif ; From dd26ff6100f1af47acc6ff02053a5f346c2788df Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Fri, 12 Aug 2022 15:26:18 +0200 Subject: [PATCH 22/26] Change min selectable TDP for all impl. devices to 5 W --- src/tuxedo_io/tuxedo_io.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 8526b40..5c66979 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -70,28 +70,28 @@ static u32 clevo_identify(void) /* * TDP boundary definitions per device */ -static int tdp_min_ph4tux[] = { 0x01, 0x01, 0x00 }; +static int tdp_min_ph4tux[] = { 0x05, 0x05, 0x00 }; static int tdp_max_ph4tux[] = { 0x26, 0x26, 0x00 }; -static int tdp_min_ph4trx[] = { 0x01, 0x01, 0x00 }; +static int tdp_min_ph4trx[] = { 0x05, 0x05, 0x00 }; static int tdp_max_ph4trx[] = { 0x32, 0x32, 0x00 }; -static int tdp_min_ph4tqx[] = { 0x01, 0x01, 0x00 }; +static int tdp_min_ph4tqx[] = { 0x05, 0x05, 0x00 }; static int tdp_max_ph4tqx[] = { 0x32, 0x32, 0x00 }; -static int tdp_min_gmxngxx[] = { 0x0a, 0x0a, 0x0a }; +static int tdp_min_gmxngxx[] = { 0x05, 0x05, 0x05 }; static int tdp_max_gmxngxx[] = { 0x50, 0x50, 0x5f }; -static int tdp_min_gmxmgxx[] = { 0x0a, 0x0a, 0x0a }; +static int tdp_min_gmxmgxx[] = { 0x05, 0x05, 0x05 }; static int tdp_max_gmxmgxx[] = { 0x78, 0x78, 0xc8 }; -static int tdp_min_gmxtgxx[] = { 0x0a, 0x0a, 0x0a }; +static int tdp_min_gmxtgxx[] = { 0x05, 0x05, 0x05 }; static int tdp_max_gmxtgxx[] = { 0x78, 0x78, 0xc8 }; -static int tdp_min_gmxzgxx[] = { 0x0a, 0x0a, 0x0a }; +static int tdp_min_gmxzgxx[] = { 0x05, 0x05, 0x05 }; static int tdp_max_gmxzgxx[] = { 0x50, 0x50, 0x5f }; -static int tdp_min_gmxagxx[] = { 0x0a, 0x0a, 0x0a }; +static int tdp_min_gmxagxx[] = { 0x05, 0x05, 0x05 }; static int tdp_max_gmxagxx[] = { 0x78, 0x78, 0xd7 }; static int *tdp_min_defs = NULL; From 44801d689f5bd2e583a283f2d23a24d78a03bf71 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Fri, 19 Aug 2022 17:12:34 +0200 Subject: [PATCH 23/26] Add Pulse 15 Gen 2 defs (tdp + id) --- src/tuxedo_io/tuxedo_io.c | 6 ++++++ src/uniwill_interfaces.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 5c66979..6bb514d 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -79,6 +79,9 @@ static int tdp_max_ph4trx[] = { 0x32, 0x32, 0x00 }; static int tdp_min_ph4tqx[] = { 0x05, 0x05, 0x00 }; static int tdp_max_ph4tqx[] = { 0x32, 0x32, 0x00 }; +static int tdp_min_pfxluxg[] = { 0x05, 0x05, 0x05 }; +static int tdp_max_pfxluxg[] = { 0x23, 0x23, 0x28 }; + static int tdp_min_gmxngxx[] = { 0x05, 0x05, 0x05 }; static int tdp_max_gmxngxx[] = { 0x50, 0x50, 0x5f }; @@ -109,6 +112,9 @@ void uw_id_tdp(void) tdp_min_defs = tdp_min_ph4tqx; tdp_max_defs = tdp_max_ph4tqx; #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) + } else if (dmi_match(DMI_PRODUCT_SKU, "PULSE1502")) { + tdp_min_defs = tdp_min_pfxluxg; + tdp_max_defs = tdp_max_pfxluxg; } else if (dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02")) { tdp_min_defs = tdp_min_gmxngxx; tdp_max_defs = tdp_max_gmxngxx; diff --git a/src/uniwill_interfaces.h b/src/uniwill_interfaces.h index fbc1d71..7287d00 100644 --- a/src/uniwill_interfaces.h +++ b/src/uniwill_interfaces.h @@ -46,6 +46,7 @@ struct uniwill_interface_t { uniwill_write_ec_ram_t *write_ec_ram; }; +#define UW_MODEL_PF5LUXG 0x09 #define UW_MODEL_PH4TUX 0x13 #define UW_MODEL_PH4TRX 0x12 #define UW_MODEL_PH4TQF 0x14 From 67a80ca3a220c45cbc6780cee5d706ae555da774 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Fri, 23 Sep 2022 11:45:40 +0200 Subject: [PATCH 24/26] Remove XMG Fusion from three profiles list Not compatible with current control mechanism --- src/uniwill_keyboard.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index e242419..382f7e4 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -207,9 +207,11 @@ struct uniwill_device_features_t *uniwill_get_device_features(void) || dmi_match(DMI_BOARD_NAME, "POLARIS1701A2060") || dmi_match(DMI_BOARD_NAME, "POLARIS1701I1650TI") || dmi_match(DMI_BOARD_NAME, "POLARIS1701I2060") - || dmi_match(DMI_BOARD_NAME, "LAPQC71A") - || dmi_match(DMI_BOARD_NAME, "LAPQC71B") - || dmi_match(DMI_PRODUCT_NAME, "A60 MUV") + // Note: XMG Fusion removed for now, seem to have + // neither same power profile control nor TDP set + //|| dmi_match(DMI_BOARD_NAME, "LAPQC71A") + //|| dmi_match(DMI_BOARD_NAME, "LAPQC71B") + //|| dmi_match(DMI_PRODUCT_NAME, "A60 MUV") ; uw_feats->uniwill_profile_v1_three_profs_leds_only = false From e6ecf69560ae8023e5dd8a1155a8b4ce8f9f580e Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Tue, 27 Sep 2022 15:06:23 +0200 Subject: [PATCH 25/26] Add TDP ranges for IBPGen7 --- src/tuxedo_io/tuxedo_io.c | 6 ++++++ src/uniwill_interfaces.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 6bb514d..29eafe3 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -79,6 +79,9 @@ static int tdp_max_ph4trx[] = { 0x32, 0x32, 0x00 }; static int tdp_min_ph4tqx[] = { 0x05, 0x05, 0x00 }; static int tdp_max_ph4tqx[] = { 0x32, 0x32, 0x00 }; +static int tdp_min_ph4axx[] = { 0x05, 0x05, 0x00 }; +static int tdp_max_ph4axx[] = { 0x2d, 0x3c, 0x00 }; + static int tdp_min_pfxluxg[] = { 0x05, 0x05, 0x05 }; static int tdp_max_pfxluxg[] = { 0x23, 0x23, 0x28 }; @@ -111,6 +114,9 @@ void uw_id_tdp(void) } else if (uw_feats->model == UW_MODEL_PH4TQF) { tdp_min_defs = tdp_min_ph4tqx; tdp_max_defs = tdp_max_ph4tqx; + } else if (uw_feats->model == UW_MODEL_PH4AQF_ARX) { + tdp_min_defs = tdp_min_ph4axx; + tdp_max_defs = tdp_max_ph4axx; #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) } else if (dmi_match(DMI_PRODUCT_SKU, "PULSE1502")) { tdp_min_defs = tdp_min_pfxluxg; diff --git a/src/uniwill_interfaces.h b/src/uniwill_interfaces.h index 7287d00..219c814 100644 --- a/src/uniwill_interfaces.h +++ b/src/uniwill_interfaces.h @@ -50,6 +50,7 @@ struct uniwill_interface_t { #define UW_MODEL_PH4TUX 0x13 #define UW_MODEL_PH4TRX 0x12 #define UW_MODEL_PH4TQF 0x14 +#define UW_MODEL_PH4AQF_ARX 0x17 struct uniwill_device_features_t { u8 model; From b9b6f240c8d10c00372c51cd351f1716b4272ee6 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Tue, 27 Sep 2022 15:13:13 +0200 Subject: [PATCH 26/26] Add Stellaris AMD Gen4 TDP ranges + threeprofile leds id --- src/tuxedo_io/tuxedo_io.c | 6 ++++++ src/uniwill_keyboard.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 29eafe3..d25583a 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -100,6 +100,9 @@ static int tdp_max_gmxzgxx[] = { 0x50, 0x50, 0x5f }; static int tdp_min_gmxagxx[] = { 0x05, 0x05, 0x05 }; static int tdp_max_gmxagxx[] = { 0x78, 0x78, 0xd7 }; +static int tdp_min_gmxrgxx[] = { 0x05, 0x05, 0x05 }; +static int tdp_max_gmxrgxx[] = { 0x64, 0x64, 0x6e }; + static int *tdp_min_defs = NULL; static int *tdp_max_defs = NULL; @@ -138,6 +141,9 @@ void uw_id_tdp(void) } else if (dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI04")) { tdp_min_defs = tdp_min_gmxagxx; tdp_max_defs = tdp_max_gmxagxx; + } else if (dmi_match(DMI_PRODUCT_SKU, "STEPOL1XA04")) { + tdp_min_defs = tdp_min_gmxrgxx; + tdp_max_defs = tdp_max_gmxrgxx; #endif } else { tdp_min_defs = NULL; diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 382f7e4..547e505 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -224,6 +224,7 @@ struct uniwill_device_features_t *uniwill_get_device_features(void) || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03") || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI04") + || dmi_match(DMI_PRODUCT_SKU, "STEPOL1XA04") #endif ;