diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 71edfcf..d52db86 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -189,8 +189,8 @@ 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; + u16 addr_use_custom_fan_table_0 = 0x07c5; // use different tables for both fans (0x0f00-0x0f2f and 0x0f30-0x0f5f respectivly) + u16 addr_use_custom_fan_table_1 = 0x07c6; // enable 0x0fxx fantables u8 offset_use_custom_fan_table_0 = 7; u8 offset_use_custom_fan_table_1 = 2; u8 value_use_custom_fan_table_0; @@ -206,28 +206,28 @@ static int uw_init_fan(void) { set_full_fan_mode(false); 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_with_retry(addr_use_custom_fan_table_0, value_use_custom_fan_table_0 + (1 << offset_use_custom_fan_table_0), 3); } - 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); + uniwill_write_ec_ram_with_retry(addr_cpu_custom_fan_table_end_temp, 0xff, 3); + uniwill_write_ec_ram_with_retry(addr_cpu_custom_fan_table_start_temp, 0x00, 3); + uniwill_write_ec_ram_with_retry(addr_cpu_custom_fan_table_fan_speed, 0x00, 3); + uniwill_write_ec_ram_with_retry(addr_gpu_custom_fan_table_end_temp, 0xff, 3); + uniwill_write_ec_ram_with_retry(addr_gpu_custom_fan_table_start_temp, 0x00, 3); + uniwill_write_ec_ram_with_retry(addr_gpu_custom_fan_table_fan_speed, 0x00, 3); 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); + uniwill_write_ec_ram_with_retry(addr_cpu_custom_fan_table_end_temp + i, 0xff, 3); + uniwill_write_ec_ram_with_retry(addr_cpu_custom_fan_table_start_temp + i, 0xff, 3); + uniwill_write_ec_ram_with_retry(addr_cpu_custom_fan_table_fan_speed + i, 0x00, 3); + uniwill_write_ec_ram_with_retry(addr_gpu_custom_fan_table_end_temp + i, 0xff, 3); + uniwill_write_ec_ram_with_retry(addr_gpu_custom_fan_table_start_temp + i, 0xff, 3); + uniwill_write_ec_ram_with_retry(addr_gpu_custom_fan_table_fan_speed + i, 0x00, 3); + } + + uniwill_read_ec_ram(addr_use_custom_fan_table_1, &value_use_custom_fan_table_1); + if (!((value_use_custom_fan_table_1 >> offset_use_custom_fan_table_1) & 1)) { + uniwill_write_ec_ram_with_retry(addr_use_custom_fan_table_1, value_use_custom_fan_table_1 + (1 << offset_use_custom_fan_table_1), 3); } } @@ -292,10 +292,15 @@ static u32 uw_set_fan(u32 fan_index, u8 fan_speed) static u32 uw_set_fan_auto(void) { u8 mode_data; - // Get current mode - uniwill_read_ec_ram(0x0751, &mode_data); - // Switch off "full fan mode" (i.e. unset 0x40 bit) - uniwill_write_ec_ram(0x0751, mode_data & 0xbf); + + if (has_universal_ec_fan_control() == 1) { + } + else { + // Get current mode + uniwill_read_ec_ram(0x0751, &mode_data); + // Switch off "full fan mode" (i.e. unset 0x40 bit) + uniwill_write_ec_ram(0x0751, mode_data & 0xbf); + } return 0; } diff --git a/src/uniwill_interfaces.h b/src/uniwill_interfaces.h index 3c1bf45..3ecd155 100644 --- a/src/uniwill_interfaces.h +++ b/src/uniwill_interfaces.h @@ -37,6 +37,7 @@ typedef u32 (uniwill_read_ec_ram_t)(u16, u8*); typedef u32 (uniwill_write_ec_ram_t)(u16, u8); +typedef u32 (uniwill_write_ec_ram_with_retry_t)(u16, u8, int); typedef void (uniwill_event_callb_t)(u32); struct uniwill_interface_t { @@ -50,6 +51,7 @@ 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; +uniwill_write_ec_ram_with_retry_t uniwill_write_ec_ram_with_retry; u32 uniwill_get_active_interface_id(char **id_str); union uw_ec_read_return { diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 41f7b8d..00e227f 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -124,6 +124,32 @@ u32 uniwill_write_ec_ram(u16 address, u8 data) } EXPORT_SYMBOL(uniwill_write_ec_ram); +u32 uniwill_write_ec_ram_with_retry(u16 address, u8 data, int retries) +{ + u32 status; + int i; + u8 control_data; + + for (i = 0; i < retries; ++i) { + status = uniwill_write_ec_ram(address, data); + if (status != 0) { + msleep(50); + continue; + } + else { + status = uniwill_read_ec_ram(address, &control_data); + if (status != 0 || data != control_data) { + msleep(50); + continue; + } + break; + } + } + + return status; +} +EXPORT_SYMBOL(uniwill_write_ec_ram_with_retry); + static DEFINE_MUTEX(uniwill_interface_modification_lock); u32 uniwill_add_interface(struct uniwill_interface_t *interface)