mirror of
https://github.com/wessel-novacustom/clevo-keyboard.git
synced 2024-11-15 03:34:01 +01:00
Add uw min/max TDP interface
- Min/max TDP interface prototype - Identification structure for "old style" uw perf. profiles
This commit is contained in:
parent
dd5e48fb09
commit
7593dd33ee
|
@ -47,20 +47,68 @@ MODULE_ALIAS("wmi:" UNIWILL_WMI_MGMT_GUID_BC);
|
||||||
static u32 id_check_clevo;
|
static u32 id_check_clevo;
|
||||||
static u32 id_check_uniwill;
|
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)
|
static u32 clevo_identify(void)
|
||||||
{
|
{
|
||||||
return clevo_get_active_interface_id(NULL) == 0 ? 1 : 0;
|
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_two;
|
||||||
static bool uniwill_tdp_config_three;
|
static bool uniwill_tdp_config_three;
|
||||||
|
|
||||||
static u32 uniwill_identify(void)
|
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
|
// Device check for two configurable TDPs
|
||||||
uniwill_tdp_config_two = false
|
uniwill_tdp_config_two = false
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)
|
#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
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -218,6 +266,44 @@ static u32 uw_set_fan_auto(void)
|
||||||
return 0;
|
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)
|
static int uw_get_tdp(u8 tdp_index)
|
||||||
{
|
{
|
||||||
u8 tdp_data;
|
u8 tdp_data;
|
||||||
|
@ -231,7 +317,7 @@ static int uw_get_tdp(u8 tdp_index)
|
||||||
has_current_setting = true;
|
has_current_setting = true;
|
||||||
|
|
||||||
if (!has_current_setting)
|
if (!has_current_setting)
|
||||||
return -1;
|
return -EPERM;
|
||||||
|
|
||||||
uniwill_read_ec_ram(tdp_current_addr, &tdp_data);
|
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)
|
static int uw_set_tdp(u8 tdp_index, u8 tdp_data)
|
||||||
{
|
{
|
||||||
|
int tdp_min, tdp_max;
|
||||||
u16 tdp_base_addr = 0x0783;
|
u16 tdp_base_addr = 0x0783;
|
||||||
u16 tdp_current_addr = tdp_base_addr + tdp_index;
|
u16 tdp_current_addr = tdp_base_addr + tdp_index;
|
||||||
bool has_current_setting = false;
|
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)
|
else if (tdp_index < 3 && uniwill_tdp_config_three)
|
||||||
has_current_setting = true;
|
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)
|
if (!has_current_setting)
|
||||||
return -1;
|
return -EPERM;
|
||||||
|
|
||||||
uniwill_write_ec_ram(tdp_current_addr, tdp_data);
|
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);
|
result = uw_get_tdp(2);
|
||||||
copy_result = copy_to_user((void *) arg, &result, sizeof(result));
|
copy_result = copy_to_user((void *) arg, &result, sizeof(result));
|
||||||
break;
|
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
|
#ifdef DEBUG
|
||||||
case R_TF_BC:
|
case R_TF_BC:
|
||||||
|
|
|
@ -83,6 +83,12 @@
|
||||||
#define R_UW_TDP0 _IOR(MAGIC_READ_UW, 0x16, 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_TDP1 _IOR(MAGIC_READ_UW, 0x17, int32_t*)
|
||||||
#define R_UW_TDP2 _IOR(MAGIC_READ_UW, 0x18, 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
|
// Write
|
||||||
#define W_UW_FANSPEED _IOW(MAGIC_WRITE_UW, 0x10, int32_t*)
|
#define W_UW_FANSPEED _IOW(MAGIC_WRITE_UW, 0x10, int32_t*)
|
||||||
|
|
Loading…
Reference in a new issue