Implement new fan control

This commit is contained in:
Werner Sembach 2022-09-28 19:23:16 +02:00
parent 48666348c6
commit 5055221eea

View file

@ -156,6 +156,67 @@ static long clevo_ioctl_interface(struct file *file, unsigned int cmd, unsigned
return 0; return 0;
} }
static int has_universal_ec_fan_control(void) {
int ret;
u8 data;
ret = uniwill_read_ec_ram(0x0751, &data);
if (ret < 0) {
return ret;
}
return (data >> 6) & 1;
}
static bool fans_initialized = false;
static int uw_init_fan(void) {
int i;
u16 addr_use_custom_fan_table_0 = 0x07c5;
u16 addr_use_custom_fan_table_1 = 0x07c6;
u8 offset_use_custom_fan_table_0 = 7;
u8 offset_use_custom_fan_table_1 = 2;
u8 value_use_custom_fan_table_0;
u8 value_use_custom_fan_table_1;
u16 addr_cpu_custom_fan_table_end_temp = 0x0f00;
u16 addr_cpu_custom_fan_table_start_temp = 0x0f10;
u16 addr_cpu_custom_fan_table_fan_speed = 0x0f20;
u16 addr_gpu_custom_fan_table_end_temp = 0x0f30;
u16 addr_gpu_custom_fan_table_start_temp = 0x0f40;
u16 addr_gpu_custom_fan_table_fan_speed = 0x0f50;
if (!fans_initialized && (has_universal_ec_fan_control() == 1)) {
uniwill_read_ec_ram(addr_use_custom_fan_table_0, &value_use_custom_fan_table_0);
uniwill_read_ec_ram(addr_use_custom_fan_table_1, &value_use_custom_fan_table_1);
if (!((value_use_custom_fan_table_0 >> offset_use_custom_fan_table_0) & 1)) {
uniwill_write_ec_ram(addr_use_custom_fan_table_0, value_use_custom_fan_table_0 + (1 << offset_use_custom_fan_table_0));
}
if (!((value_use_custom_fan_table_1 >> offset_use_custom_fan_table_1) & 1)) {
uniwill_write_ec_ram(addr_use_custom_fan_table_1, value_use_custom_fan_table_1 + (1 << offset_use_custom_fan_table_1));
}
uniwill_write_ec_ram(addr_cpu_custom_fan_table_end_temp, 0xff);
uniwill_write_ec_ram(addr_cpu_custom_fan_table_start_temp, 0x00);
uniwill_write_ec_ram(addr_cpu_custom_fan_table_fan_speed, 0x00);
uniwill_write_ec_ram(addr_gpu_custom_fan_table_end_temp, 0xff);
uniwill_write_ec_ram(addr_gpu_custom_fan_table_start_temp, 0x00);
uniwill_write_ec_ram(addr_gpu_custom_fan_table_fan_speed, 0x00);
for (i = 0x1; i <= 0xf; ++i) {
uniwill_write_ec_ram(addr_cpu_custom_fan_table_end_temp + i, 0xff);
uniwill_write_ec_ram(addr_cpu_custom_fan_table_start_temp + i, 0xff);
uniwill_write_ec_ram(addr_cpu_custom_fan_table_fan_speed + i, 0x00);
uniwill_write_ec_ram(addr_gpu_custom_fan_table_end_temp + i, 0xff);
uniwill_write_ec_ram(addr_gpu_custom_fan_table_start_temp + i, 0xff);
uniwill_write_ec_ram(addr_gpu_custom_fan_table_fan_speed + i, 0x00);
}
}
fans_initialized = true;
return 0; // TODO Sensefull error handling
}
static u32 uw_set_fan(u32 fan_index, u8 fan_speed) static u32 uw_set_fan(u32 fan_index, u8 fan_speed)
{ {
u32 i; u32 i;
@ -164,6 +225,24 @@ static u32 uw_set_fan(u32 fan_index, u8 fan_speed)
u16 addr_fan1 = 0x1809; u16 addr_fan1 = 0x1809;
u16 addr_for_fan; u16 addr_for_fan;
u16 addr_cpu_custom_fan_table_fan_speed = 0x0f20;
u16 addr_gpu_custom_fan_table_fan_speed = 0x0f50;
if (has_universal_ec_fan_control() == 1) {
uw_init_fan();
// TODO Disable full fan mode
if (fan_index == 0)
addr_for_fan = addr_cpu_custom_fan_table_fan_speed;
else if (fan_index == 1)
addr_for_fan = addr_gpu_custom_fan_table_fan_speed;
else
return -EINVAL;
uniwill_write_ec_ram(addr_for_fan, fan_speed & 0xff);
}
else { // old workaround using full fan mode
if (fan_index == 0) if (fan_index == 0)
addr_for_fan = addr_fan0; addr_for_fan = addr_fan0;
else if (fan_index == 1) else if (fan_index == 1)
@ -188,6 +267,7 @@ static u32 uw_set_fan(u32 fan_index, u8 fan_speed)
// Otherwise just set the chosen fan // Otherwise just set the chosen fan
uniwill_write_ec_ram(addr_for_fan, fan_speed & 0xff); uniwill_write_ec_ram(addr_for_fan, fan_speed & 0xff);
} }
}
return 0; return 0;
} }