diff --git a/src/board/system76/common/fan.c b/src/board/system76/common/fan.c index 1a07f10d5..be0e65b5e 100644 --- a/src/board/system76/common/fan.c +++ b/src/board/system76/common/fan.c @@ -10,6 +10,11 @@ bool fan_max = false; +static uint8_t fan1_level = 0; +#ifdef FAN2_PWM +static uint8_t fan2_level = 0; +#endif + struct FanInfo fan1_info = { .pwm_actual = 0, .pwm_target = 0, @@ -38,29 +43,6 @@ void fan_reset(void) { fan_max = false; } -// Get duty cycle based on temperature -static uint8_t fan_duty(const struct Fan *const fan, int16_t temp) { - for (uint8_t i = 0; i < fan->points_size; i++) { - const struct FanPoint *cur = &fan->points[i]; - - // If exactly the current temp, return the current duty - if (temp == cur->temp) { - return cur->duty; - } else if (temp < cur->temp) { - // If lower than first temp, return 0% - if (i == 0) { - return 0; - } else { - const struct FanPoint *prev = &fan->points[i - 1]; - return prev->duty; - } - } - } - - // If no point is found, return 100% - return CTR0; -} - static uint16_t fan_get_tach0_rpm(void) { uint16_t rpm = (F1TMRR << 8) | F1TLRR; @@ -92,26 +74,42 @@ void fan_event(void) { // Enabling fan max toggle and exiting S0 will cause duty to immediately // change instead of ramping to provide the desired effects. + // Get FAN1 target duty + if (fan1_level < FAN1.levels_size) { + if (sys_temp >= FAN1.levels[fan1_level].temp_up) { + fan1_level++; + } + } + if (fan1_level > 0) { + if (sys_temp <= FAN1.levels[fan1_level].temp_down) { + fan1_level--; + } + } + + fan1_info.pwm_target = FAN1.levels[fan1_level].duty; + // Set FAN1 duty - fan1_info.pwm_target = fan_duty(&FAN1, sys_temp); if (fan_max) { fan1_info.pwm_target = CTR0; fan1_info.pwm_actual = CTR0; } else if (power_state != POWER_STATE_S0) { fan1_info.pwm_target = 0; fan1_info.pwm_actual = 0; - } else if (fan1_info.pwm_actual < fan1_info.pwm_target) { - if (fan1_info.pwm_actual < CTR0) { - fan1_info.pwm_actual++; - if (fan1_info.pwm_actual < FAN1.pwm_min) { - fan1_info.pwm_actual = FAN1.pwm_min; + } else { + if (fan1_info.pwm_actual < fan1_info.pwm_target) { + if (fan1_info.pwm_actual < CTR0) { + fan1_info.pwm_actual++; + if (fan1_info.pwm_actual < FAN1.pwm_min) { + fan1_info.pwm_actual = FAN1.pwm_min; + } } } - } else if (fan1_info.pwm_actual > fan1_info.pwm_target) { - if (fan1_info.pwm_actual > 0) { - fan1_info.pwm_actual--; - if (fan1_info.pwm_actual < FAN1.pwm_min) { - fan1_info.pwm_actual = 0; + if (fan1_info.pwm_actual > fan1_info.pwm_target) { + if (fan1_info.pwm_actual > 0) { + fan1_info.pwm_actual--; + if (fan1_info.pwm_actual < FAN1.pwm_min) { + fan1_info.pwm_actual = 0; + } } } } @@ -120,26 +118,42 @@ void fan_event(void) { fan1_info.rpm = fan_get_tach0_rpm(); #ifdef FAN2_PWM + // Get FAN2 target duty + if (fan2_level < FAN2.levels_size) { + if (sys_temp >= FAN2.levels[fan2_level].temp_up) { + fan2_level++; + } + } + if (fan2_level > 0) { + if (sys_temp <= FAN2.levels[fan2_level].temp_down) { + fan2_level--; + } + } + + fan2_info.pwm_target = FAN2.levels[fan2_level].duty; + // set FAN2 duty - fan2_info.pwm_target = fan_duty(&FAN2, sys_temp); if (fan_max) { fan2_info.pwm_target = CTR0; fan2_info.pwm_actual = CTR0; } else if (power_state != POWER_STATE_S0) { fan2_info.pwm_target = 0; fan2_info.pwm_actual = 0; - } else if (fan2_info.pwm_actual < fan2_info.pwm_target) { - if (fan2_info.pwm_actual < CTR0) { - fan2_info.pwm_actual++; - if (fan2_info.pwm_actual < FAN2.pwm_min) { - fan2_info.pwm_actual = FAN2.pwm_min; + } else { + if (fan2_info.pwm_actual < fan2_info.pwm_target) { + if (fan2_info.pwm_actual < CTR0) { + fan2_info.pwm_actual++; + if (fan2_info.pwm_actual < FAN2.pwm_min) { + fan2_info.pwm_actual = FAN2.pwm_min; + } } } - } else if (fan2_info.pwm_actual > fan2_info.pwm_target) { - if (fan2_info.pwm_actual > 0) { - fan2_info.pwm_actual--; - if (fan2_info.pwm_actual < FAN2.pwm_min) { - fan2_info.pwm_actual = 0; + if (fan2_info.pwm_actual > fan2_info.pwm_target) { + if (fan2_info.pwm_actual > 0) { + fan2_info.pwm_actual--; + if (fan2_info.pwm_actual < FAN2.pwm_min) { + fan2_info.pwm_actual = 0; + } } } } diff --git a/src/board/system76/common/include/board/fan.h b/src/board/system76/common/include/board/fan.h index b56473c71..55d240fc6 100644 --- a/src/board/system76/common/include/board/fan.h +++ b/src/board/system76/common/include/board/fan.h @@ -8,16 +8,15 @@ #define PWM_DUTY(X) ((uint8_t)(((((uint16_t)(X)) * 255) + 99) / 100)) -struct FanPoint { - const int16_t temp; +struct FanLevel { + const int16_t temp_up; + const int16_t temp_down; const uint8_t duty; }; -#define FAN_POINT(T, D) { .temp = (int16_t)(T), .duty = PWM_DUTY(D) } - struct Fan { - const struct FanPoint *const points; - const uint8_t points_size; + const struct FanLevel *const levels; + const uint8_t levels_size; const uint8_t pwm_min; }; diff --git a/src/board/system76/oryp6/fan.c b/src/board/system76/oryp6/fan.c index 6c3e06b69..c48a02b2a 100644 --- a/src/board/system76/oryp6/fan.c +++ b/src/board/system76/oryp6/fan.c @@ -3,34 +3,36 @@ #include #include -static const struct FanPoint __code FAN1_POINTS[] = { - FAN_POINT(55, 25), - FAN_POINT(65, 30), - FAN_POINT(70, 40), - FAN_POINT(75, 60), - FAN_POINT(80, 75), - FAN_POINT(85, 90), - FAN_POINT(90, 100), +static const struct FanLevel __code fan1_table[] = { + { 55, 0, PWM_DUTY(0) }, + { 60, 52, PWM_DUTY(25) }, + { 65, 60, PWM_DUTY(30) }, + { 70, 65, PWM_DUTY(40) }, + { 75, 70, PWM_DUTY(60) }, + { 80, 75, PWM_DUTY(75) }, + { 85, 80, PWM_DUTY(90) }, + { 90, 85, PWM_DUTY(100) }, }; const struct Fan __code FAN1 = { - .points = FAN1_POINTS, - .points_size = ARRAY_SIZE(FAN1_POINTS), + .levels = fan1_table, + .levels_size = ARRAY_SIZE(fan1_table), .pwm_min = PWM_DUTY(25), }; -static const struct FanPoint __code FAN2_POINTS[] = { - FAN_POINT(55, 25), - FAN_POINT(65, 30), - FAN_POINT(70, 40), - FAN_POINT(75, 60), - FAN_POINT(80, 75), - FAN_POINT(85, 90), - FAN_POINT(90, 100), +static const struct FanLevel __code fan2_table[] = { + { 55, 0, PWM_DUTY(0) }, + { 60, 52, PWM_DUTY(25) }, + { 65, 60, PWM_DUTY(30) }, + { 70, 65, PWM_DUTY(40) }, + { 75, 70, PWM_DUTY(60) }, + { 80, 75, PWM_DUTY(75) }, + { 85, 80, PWM_DUTY(90) }, + { 90, 85, PWM_DUTY(100) }, }; const struct Fan __code FAN2 = { - .points = FAN2_POINTS, - .points_size = ARRAY_SIZE(FAN2_POINTS), + .levels = fan2_table, + .levels_size = ARRAY_SIZE(fan2_table), .pwm_min = PWM_DUTY(25), };