From 76784bf1eb6e1d24d5bde56de9b1b810ccdc2718 Mon Sep 17 00:00:00 2001 From: Daisuke Nojiri Date: Mon, 5 Mar 2018 09:49:40 -0800 Subject: fan: Allow board to configure fans at run time This patch splits struct fan_t into two parts: base configuration and RPM configuration. RPMs are expected to be different from model to model while a base configuration is most likely shared. BUG=b:73720175 BRANCH=none TEST=make buildall Change-Id: Iff17573f110e07e88d097dd848cf91ee98b83176 Signed-off-by: Daisuke Nojiri Reviewed-on: https://chromium-review.googlesource.com/949382 Reviewed-by: Vincent Palatin Reviewed-on: https://chromium-review.googlesource.com/1083932 --- board/fizz/board.c | 27 +++++++++------ board/host/fan.c | 25 ++++++++------ board/it83xx_evb/board.c | 28 ++++++++------- board/kahlee/board.c | 25 ++++++++------ board/nami/board.c | 27 +++++++++++++++ board/npcx7_evb/board.c | 25 ++++++++------ board/npcx_evb/board.c | 48 ++++++++++++++++---------- board/npcx_evb_arm/board.c | 25 ++++++++------ board/samus/board.c | 40 ++++++++++++--------- chip/it83xx/fan.c | 16 ++++----- chip/npcx/fan.c | 8 ++--- common/fan.c | 86 +++++++++++++++++++++++----------------------- include/fan.h | 24 +++++++++---- test/fan.c | 39 +++++++++++---------- 14 files changed, 262 insertions(+), 181 deletions(-) diff --git a/board/fizz/board.c b/board/fizz/board.c index 0bde95bdfb..07ab85b841 100644 --- a/board/fizz/board.c +++ b/board/fizz/board.c @@ -150,16 +150,21 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* Physical fans. These are logically separate from pwm_channels. */ -const struct fan_t fans[] = { - [FAN_CH_0] = { - .flags = FAN_USE_RPM_MODE, - .rpm_min = 2800, - .rpm_start = 2800, - .rpm_max = 5600, - .ch = MFT_CH_0, /* Use MFT id to control fan */ - .pgood_gpio = -1, - .enable_gpio = GPIO_FAN_PWR_EN, - }, +const struct fan_conf fan_conf_0 = { + .flags = FAN_USE_RPM_MODE, + .ch = MFT_CH_0, /* Use MFT id to control fan */ + .pgood_gpio = -1, + .enable_gpio = GPIO_FAN_PWR_EN, +}; + +const struct fan_rpm fan_rpm_0 = { + .rpm_min = 2800, + .rpm_start = 2800, + .rpm_max = 5600, +}; + +struct fan_t fans[] = { + [FAN_CH_0] = { .conf = &fan_conf_0, .rpm = &fan_rpm_0, }, }; BUILD_ASSERT(ARRAY_SIZE(fans) == FAN_CH_COUNT); @@ -669,7 +674,7 @@ static int get_custom_rpm(int fan, int pct, int oem_id) previous_pct = pct; if (fan_table[current_level].rpm != - fan_get_rpm_target(fans[fan].ch)) + fan_get_rpm_target(FAN_CH(fan))) cprintf(CC_THERMAL, "[%T Setting fan RPM to %d]\n", fan_table[current_level].rpm); diff --git a/board/host/fan.c b/board/host/fan.c index ee7b15ef12..557baaaa7d 100644 --- a/board/host/fan.c +++ b/board/host/fan.c @@ -8,17 +8,22 @@ #include "fan.h" #include "util.h" -const struct fan_t fans[] = { - {.flags = FAN_USE_RPM_MODE, - .rpm_min = 1000, - .rpm_start = 1500, - .rpm_max = 5000, - .ch = 0, - .pgood_gpio = -1, - .enable_gpio = -1, - }, +const struct fan_conf fan_conf_0 = { + .flags = FAN_USE_RPM_MODE, + .ch = 0, + .pgood_gpio = -1, + .enable_gpio = -1, +}; + +const struct fan_rpm fan_rpm_0 = { + .rpm_min = 1000, + .rpm_start = 1500, + .rpm_max = 5000, +}; + +struct fan_t fans[CONFIG_FANS] = { + { .conf = &fan_conf_0, .rpm = &fan_rpm_0, }, }; -BUILD_ASSERT(ARRAY_SIZE(fans) == CONFIG_FANS); static int mock_enabled; void fan_set_enabled(int ch, int enabled) diff --git a/board/it83xx_evb/board.c b/board/it83xx_evb/board.c index cd0b9ff1e4..8bc2740beb 100644 --- a/board/it83xx_evb/board.c +++ b/board/it83xx_evb/board.c @@ -106,19 +106,21 @@ const struct pwm_t pwm_channels[] = { BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); -const struct fan_t fans[] = { - {.flags = FAN_USE_RPM_MODE, - .rpm_min = 1500, - .rpm_start = 1500, - .rpm_max = 6500, - /* - * index of pwm_channels, not pwm output channel. - * pwm output channel is member "channel" of pwm_t. - */ - .ch = 0, - .pgood_gpio = -1, - .enable_gpio = -1, - }, +const struct fan_conf fan_conf_0 = { + .flags = FAN_USE_RPM_MODE, + .ch = 0, /* Use MFT id to control fan */ + .pgood_gpio = -1, + .enable_gpio = -1, +}; + +const struct fan_rpm fan_rpm_0 = { + .rpm_min = 1500, + .rpm_start = 1500, + .rpm_max = 6500, +}; + +struct fan_t fans[] = { + { .conf = &fan_conf_0, .rpm = &fan_rpm_0, }, }; BUILD_ASSERT(ARRAY_SIZE(fans) == CONFIG_FANS); diff --git a/board/kahlee/board.c b/board/kahlee/board.c index 1369dce43e..97a6ae40ce 100644 --- a/board/kahlee/board.c +++ b/board/kahlee/board.c @@ -132,16 +132,21 @@ BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); /******************************************************************************/ /* Physical fans. These are logically separate from pwm_channels. */ -const struct fan_t fans[] = { - [FAN_CH_0] = { - .flags = FAN_USE_RPM_MODE, - .rpm_min = 1000, - .rpm_start = 1000, - .rpm_max = 4300, - .ch = 0,/* Use MFT id to control fan */ - .pgood_gpio = -1, - .enable_gpio = -1, - }, +const struct fan_conf fan_conf_0 = { + .flags = FAN_USE_RPM_MODE, + .ch = 0, /* Use MFT id to control fan */ + .pgood_gpio = -1, + .enable_gpio = -1, +}; + +const struct fan_rpm fan_rpm_0 = { + .rpm_min = 1000, + .rpm_start = 1000, + .rpm_max = 4300, +}; + +struct fan_t fans[] = { + [FAN_CH_0] = { .conf = &fan_conf_0, .rpm = &fan_rpm_0, }, }; BUILD_ASSERT(ARRAY_SIZE(fans) == FAN_CH_COUNT); diff --git a/board/nami/board.c b/board/nami/board.c index a5a9a1ac68..3c59dbb160 100644 --- a/board/nami/board.c +++ b/board/nami/board.c @@ -144,6 +144,33 @@ const struct adc_t adc_channels[] = { }; BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); +/******************************************************************************/ +/* Physical fans. These are logically separate from pwm_channels. */ + +const struct fan_conf fan_conf_0 = { + .flags = FAN_USE_RPM_MODE, + .ch = MFT_CH_0, /* Use MFT id to control fan */ + .pgood_gpio = -1, + .enable_gpio = -1, +}; + +const struct fan_rpm fan_rpm_0 = { + .rpm_min = 2800, + .rpm_start = 3000, + .rpm_max = 6000, +}; + +struct fan_t fans[FAN_CH_COUNT] = { + [FAN_CH_0] = { .conf = &fan_conf_0, .rpm = &fan_rpm_0, }, +}; + +/******************************************************************************/ +/* MFT channels. These are logically separate from pwm_channels. */ +const struct mft_t mft_channels[] = { + [MFT_CH_0] = {NPCX_MFT_MODULE_2, TCKC_LFCLK, PWM_CH_FAN}, +}; +BUILD_ASSERT(ARRAY_SIZE(mft_channels) == MFT_CH_COUNT); + /* I2C port map */ const struct i2c_port_t i2c_ports[] = { {"tcpc0", NPCX_I2C_PORT0_0, 400, GPIO_I2C0_0_SCL, GPIO_I2C0_0_SDA}, diff --git a/board/npcx7_evb/board.c b/board/npcx7_evb/board.c index 0a97942dbb..671671a21f 100644 --- a/board/npcx7_evb/board.c +++ b/board/npcx7_evb/board.c @@ -55,16 +55,21 @@ BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); /******************************************************************************/ /* Physical fans. These are logically separate from pwm_channels. */ -const struct fan_t fans[] = { - [FAN_CH_0] = { - .flags = FAN_USE_RPM_MODE, - .rpm_min = 1000, - .rpm_start = 1000, - .rpm_max = 5200, - .ch = 0,/* Use MFT id to control fan */ - .pgood_gpio = GPIO_PGOOD_FAN, - .enable_gpio = -1, - }, +const struct fan_conf fan_conf_0 = { + .flags = FAN_USE_RPM_MODE, + .ch = 0, /* Use MFT id to control fan */ + .pgood_gpio = GPIO_PGOOD_FAN, + .enable_gpio = -1, +}; + +const struct fan_rpm fan_rpm_0 = { + .rpm_min = 1000, + .rpm_start = 1000, + .rpm_max = 5200, +}; + +struct fan_t fans[] = { + [FAN_CH_0] = { .conf = &fan_conf_0, .rpm = &fan_rpm_0, }, }; BUILD_ASSERT(ARRAY_SIZE(fans) == FAN_CH_COUNT); diff --git a/board/npcx_evb/board.c b/board/npcx_evb/board.c index 9a185ada2f..d4741fbe31 100644 --- a/board/npcx_evb/board.c +++ b/board/npcx_evb/board.c @@ -55,26 +55,36 @@ BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); /******************************************************************************/ /* Physical fans. These are logically separate from pwm_channels. */ -const struct fan_t fans[] = { - [FAN_CH_0] = { - .flags = FAN_USE_RPM_MODE, - .rpm_min = 1000, - .rpm_start = 1000, - .rpm_max = 5200, - .ch = 0,/* Use MFT id to control fan */ - .pgood_gpio = GPIO_PGOOD_FAN, - .enable_gpio = -1, - }, +const struct fan_conf fan_conf_0 = { + .flags = FAN_USE_RPM_MODE, + .ch = 0, /* Use MFT id to control fan */ + .pgood_gpio = GPIO_PGOOD_FAN, + .enable_gpio = -1, +}; + +const struct fan_conf fan_conf_1 = { + .flags = FAN_USE_RPM_MODE, + .ch = 1, /* Use MFT id to control fan */ + .pgood_gpio = -1, + .enable_gpio = -1, +}; + +const struct fan_rpm fan_rpm_0 = { + .rpm_min = 1000, + .rpm_start = 1000, + .rpm_max = 5200, +}; + +const struct fan_rpm fan_rpm_1 = { + .rpm_min = 1000, + .rpm_start = 1000, + .rpm_max = 4300, +}; + +struct fan_t fans[] = { + [FAN_CH_0] = { .conf = &fan_conf_0, .rpm = &fan_rpm_0, }, #if (CONFIG_FANS == 2) - [FAN_CH_1] = { - .flags = FAN_USE_RPM_MODE, - .rpm_min = 1000, - .rpm_start = 1000, - .rpm_max = 4300, - .ch = 1,/* Use MFT id to control fan */ - .pgood_gpio = -1, - .enable_gpio = -1, - }, + [FAN_CH_1] = { .conf = &fan_conf_1, .rpm = &fan_rpm_1, }, #endif }; BUILD_ASSERT(ARRAY_SIZE(fans) == FAN_CH_COUNT); diff --git a/board/npcx_evb_arm/board.c b/board/npcx_evb_arm/board.c index 9e3ae7d0dd..da4d55a3bd 100644 --- a/board/npcx_evb_arm/board.c +++ b/board/npcx_evb_arm/board.c @@ -52,16 +52,21 @@ BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); /******************************************************************************/ /* Physical fans. These are logically separate from pwm_channels. */ -const struct fan_t fans[] = { - [FAN_CH_0] = { - .flags = FAN_USE_RPM_MODE, - .rpm_min = 1000, - .rpm_start = 1000, - .rpm_max = 5200, - .ch = 0,/* Use MFT id to control fan */ - .pgood_gpio = GPIO_PGOOD_FAN, - .enable_gpio = -1, - }, +const struct fan_conf fan_conf_0 = { + .flags = FAN_USE_RPM_MODE, + .ch = 0, /* Use MFT id to control fan */ + .pgood_gpio = GPIO_PGOOD_FAN, + .enable_gpio = -1, +}; + +const struct fan_rpm fan_rpm_0 = { + .rpm_min = 1000, + .rpm_start = 1000, + .rpm_max = 5200, +}; + +struct fan_t fans[] = { + [FAN_CH_0] = { .conf = &fan_conf_0, .rpm = &fan_rpm_0, }, }; BUILD_ASSERT(ARRAY_SIZE(fans) == FAN_CH_COUNT); diff --git a/board/samus/board.c b/board/samus/board.c index db49a573af..167b20093c 100644 --- a/board/samus/board.c +++ b/board/samus/board.c @@ -96,23 +96,29 @@ const struct pwm_t pwm_channels[] = { BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); /* Physical fans. These are logically separate from pwm_channels. */ -const struct fan_t fans[] = { - {.flags = FAN_USE_RPM_MODE, - .rpm_min = 1000, - .rpm_start = 1000, - .rpm_max = 6350, - .ch = 2, - .pgood_gpio = -1, - .enable_gpio = -1, - }, - {.flags = FAN_USE_RPM_MODE, - .rpm_min = 1000, - .rpm_start = 1000, - .rpm_max = 6350, - .ch = 3, - .pgood_gpio = -1, - .enable_gpio = -1, - }, +const struct fan_conf fan_conf_0 = { + .flags = FAN_USE_RPM_MODE, + .ch = 2, /* Use MFT id to control fan */ + .pgood_gpio = -1, + .enable_gpio = -1, +}; + +const struct fan_conf fan_conf_1 = { + .flags = FAN_USE_RPM_MODE, + .ch = 3, /* Use MFT id to control fan */ + .pgood_gpio = -1, + .enable_gpio = -1, +}; + +const struct fan_rpm fan_rpm_0 = { + .rpm_min = 1000, + .rpm_start = 1000, + .rpm_max = 6350, +}; + +struct fan_t fans[] = { + { .conf = &fan_conf_0, .rpm = &fan_rpm_0, }, + { .conf = &fan_conf_1, .rpm = &fan_rpm_0, }, }; BUILD_ASSERT(ARRAY_SIZE(fans) == CONFIG_FANS); diff --git a/chip/it83xx/fan.c b/chip/it83xx/fan.c index d412e14123..d8cf010695 100644 --- a/chip/it83xx/fan.c +++ b/chip/it83xx/fan.c @@ -98,7 +98,7 @@ static int fan_all_disabled(void) int fan, all_disabled = 0; for (fan = 0; fan < CONFIG_FANS; fan++) { - if (!fan_get_enabled(fans[fan].ch)) + if (!fan_get_enabled(FAN_CH(fan))) all_disabled++; } @@ -423,9 +423,9 @@ void fan_ext_timer_interrupt(void) task_clear_pending_irq(et_ctrl_regs[FAN_CTRL_EXT_TIMER].irq); for (fan = 0; fan < CONFIG_FANS; fan++) { - if (fan_get_enabled(fans[fan].ch)) { - proc_tach(fans[fan].ch); - fan_ctrl(fans[fan].ch); + if (fan_get_enabled(FAN_CH(fan))) { + proc_tach(FAN_CH(fan)); + fan_ctrl(FAN_CH(fan)); } } } @@ -437,10 +437,10 @@ static void fan_init(void) for (ch = 0; ch < CONFIG_FANS; ch++) { - rpm_re = fan_tach[pwm_channels[fans[ch].ch].channel].rpm_re; - fan_p = fan_tach[pwm_channels[fans[ch].ch].channel].fan_p; - s_duty = fan_tach[pwm_channels[fans[ch].ch].channel].s_duty; - tach_ch = tach_bind(fans[ch].ch); + rpm_re = fan_tach[pwm_channels[FAN_CH(ch)].channel].rpm_re; + fan_p = fan_tach[pwm_channels[FAN_CH(ch)].channel].fan_p; + s_duty = fan_tach[pwm_channels[FAN_CH(ch)].channel].s_duty; + tach_ch = tach_bind(FAN_CH(ch)); if (tach_ch < TACH_CH_COUNT) { diff --git a/chip/npcx/fan.c b/chip/npcx/fan.c index 8e08e4ec58..a92b01e60c 100644 --- a/chip/npcx/fan.c +++ b/chip/npcx/fan.c @@ -492,10 +492,10 @@ void fan_set_rpm_target(int ch, int rpm) /* If rpm = 0, disable PWM */ if (rpm == 0) fan_set_duty(ch, 0); - else if (rpm > fans[ch].rpm_max) - rpm = fans[ch].rpm_max; - else if (rpm < fans[ch].rpm_min) - rpm = fans[ch].rpm_min; + else if (rpm > fans[ch].rpm->rpm_max) + rpm = fans[ch].rpm->rpm_max; + else if (rpm < fans[ch].rpm->rpm_min) + rpm = fans[ch].rpm->rpm_min; /* Set target rpm */ fan_status[ch].rpm_target = rpm; diff --git a/common/fan.c b/common/fan.c index 5e2f85475f..d193240150 100644 --- a/common/fan.c +++ b/common/fan.c @@ -37,8 +37,8 @@ int fan_percent_to_rpm(int fan, int pct) if (!pct) { rpm = 0; } else { - min = fans[fan].rpm_min; - max = fans[fan].rpm_max; + min = fans[fan].rpm->rpm_min; + max = fans[fan].rpm->rpm_max; rpm = ((pct - 1) * max + (100 - pct) * min) / 99; } @@ -62,25 +62,25 @@ test_mockable void fan_set_percent_needed(int fan, int pct) #endif new_rpm = fan_percent_to_rpm(fan, pct); - actual_rpm = fan_get_rpm_actual(fans[fan].ch); + actual_rpm = fan_get_rpm_actual(FAN_CH(fan)); /* If we want to turn and the fans are currently significantly below * the minimum turning speed, we should turn at least as fast as the * necessary start speed instead. */ if (new_rpm && - actual_rpm < fans[fan].rpm_min * 9 / 10 && - new_rpm < fans[fan].rpm_start) - new_rpm = fans[fan].rpm_start; + actual_rpm < fans[fan].rpm->rpm_min * 9 / 10 && + new_rpm < fans[fan].rpm->rpm_start) + new_rpm = fans[fan].rpm->rpm_start; - fan_set_rpm_target(fans[fan].ch, new_rpm); + fan_set_rpm_target(FAN_CH(fan), new_rpm); } static void set_enabled(int fan, int enable) { - fan_set_enabled(fans[fan].ch, enable); + fan_set_enabled(FAN_CH(fan), enable); - if (fans[fan].enable_gpio >= 0) - gpio_set_level(fans[fan].enable_gpio, enable); + if (fans[fan].conf->enable_gpio >= 0) + gpio_set_level(fans[fan].conf->enable_gpio, enable); } static void set_thermal_control_enabled(int fan, int enable) @@ -89,13 +89,13 @@ static void set_thermal_control_enabled(int fan, int enable) /* If controlling the fan, need it in RPM-control mode */ if (enable) - fan_set_rpm_mode(fans[fan].ch, 1); + fan_set_rpm_mode(FAN_CH(fan), 1); } static void set_duty_cycle(int fan, int percent) { /* Move the fan to manual control */ - fan_set_rpm_mode(fans[fan].ch, 0); + fan_set_rpm_mode(FAN_CH(fan), 0); /* enable the fan when non-zero duty */ set_enabled(fan, (percent > 0) ? 1 : 0); @@ -104,7 +104,7 @@ static void set_duty_cycle(int fan, int percent) set_thermal_control_enabled(fan, 0); /* Set the duty cycle */ - fan_set_duty(fans[fan].ch, percent); + fan_set_duty(FAN_CH(fan), percent); } /*****************************************************************************/ @@ -140,11 +140,11 @@ static int is_powered(int fan) int is_pgood = -1; /* If we have an enable output, see if it's on or off. */ - if (fans[fan].enable_gpio >= 0) - is_pgood = gpio_get_level(fans[fan].enable_gpio); + if (fans[fan].conf->enable_gpio >= 0) + is_pgood = gpio_get_level(fans[fan].conf->enable_gpio); /* If we have a pgood input, it overrides any enable output. */ - if (fans[fan].pgood_gpio >= 0) - is_pgood = gpio_get_level(fans[fan].pgood_gpio); + if (fans[fan].conf->pgood_gpio >= 0) + is_pgood = gpio_get_level(fans[fan].conf->pgood_gpio); return is_pgood; } @@ -163,20 +163,20 @@ static int cc_faninfo(int argc, char **argv) if (fan) ccprintf("\n"); ccprintf("%sActual: %4d rpm\n", leader, - fan_get_rpm_actual(fans[fan].ch)); + fan_get_rpm_actual(FAN_CH(fan))); ccprintf("%sTarget: %4d rpm\n", leader, - fan_get_rpm_target(fans[fan].ch)); + fan_get_rpm_target(FAN_CH(fan))); ccprintf("%sDuty: %d%%\n", leader, - fan_get_duty(fans[fan].ch)); - tmp = fan_get_status(fans[fan].ch); + fan_get_duty(FAN_CH(fan))); + tmp = fan_get_status(FAN_CH(fan)); ccprintf("%sStatus: %d (%s)\n", leader, tmp, human_status[tmp]); ccprintf("%sMode: %s\n", leader, - fan_get_rpm_mode(fans[fan].ch) ? "rpm" : "duty"); + fan_get_rpm_mode(FAN_CH(fan)) ? "rpm" : "duty"); ccprintf("%sAuto: %s\n", leader, thermal_control_enabled[fan] ? "yes" : "no"); ccprintf("%sEnable: %s\n", leader, - fan_get_enabled(fans[fan].ch) ? "yes" : "no"); + fan_get_enabled(FAN_CH(fan)) ? "yes" : "no"); is_pgood = is_powered(fan); if (is_pgood >= 0) ccprintf("%sPower: %s\n", leader, @@ -223,7 +223,7 @@ static int cc_fanset(int argc, char **argv) } /* Move the fan to automatic control */ - fan_set_rpm_mode(fans[fan].ch, 1); + fan_set_rpm_mode(FAN_CH(fan), 1); /* enable the fan when non-zero rpm */ set_enabled(fan, (rpm > 0) ? 1 : 0); @@ -231,7 +231,7 @@ static int cc_fanset(int argc, char **argv) /* Disable thermal engine automatic fan control. */ set_thermal_control_enabled(fan, 0); - fan_set_rpm_target(fans[fan].ch, rpm); + fan_set_rpm_target(FAN_CH(fan), rpm); ccprintf("Setting fan %d rpm target to %d\n", fan, rpm); @@ -283,10 +283,10 @@ int dptf_get_fan_duty_target(void) { int fan = 0; /* TODO(crosbug.com/p/23803) */ - if (thermal_control_enabled[fan] || fan_get_rpm_mode(fans[fan].ch)) + if (thermal_control_enabled[fan] || fan_get_rpm_mode(FAN_CH(fan))) return -1; - return fan_get_duty(fans[fan].ch); + return fan_get_duty(FAN_CH(fan)); } /* 0-100% sets duty, out of range means let the EC drive */ @@ -314,7 +314,7 @@ static int hc_pwm_get_fan_target_rpm(struct host_cmd_handler_args *args) int fan = 0; /* TODO(crosbug.com/p/23803) */ - r->rpm = fan_get_rpm_target(fans[fan].ch); + r->rpm = fan_get_rpm_target(FAN_CH(fan)); args->response_size = sizeof(*r); return EC_RES_SUCCESS; @@ -335,8 +335,8 @@ static int hc_pwm_set_fan_target_rpm(struct host_cmd_handler_args *args) set_enabled(fan, (p_v0->rpm > 0) ? 1 : 0); set_thermal_control_enabled(fan, 0); - fan_set_rpm_mode(fans[fan].ch, 1); - fan_set_rpm_target(fans[fan].ch, p_v0->rpm); + fan_set_rpm_mode(FAN_CH(fan), 1); + fan_set_rpm_target(FAN_CH(fan), p_v0->rpm); } return EC_RES_SUCCESS; @@ -350,8 +350,8 @@ static int hc_pwm_set_fan_target_rpm(struct host_cmd_handler_args *args) set_enabled(fan, (p_v1->rpm > 0) ? 1 :0); set_thermal_control_enabled(fan, 0); - fan_set_rpm_mode(fans[fan].ch, 1); - fan_set_rpm_target(fans[fan].ch, p_v1->rpm); + fan_set_rpm_mode(FAN_CH(fan), 1); + fan_set_rpm_target(FAN_CH(fan), p_v1->rpm); return EC_RES_SUCCESS; } @@ -436,21 +436,21 @@ static void pwm_fan_init(void) int fan = 0; for (fan = 0; fan < CONFIG_FANS; fan++) - fan_channel_setup(fans[fan].ch, fans[fan].flags); + fan_channel_setup(FAN_CH(fan), fans[fan].conf->flags); prev = (const struct pwm_fan_state *) system_get_jump_tag(PWMFAN_SYSJUMP_TAG, &version, &size); if (prev && version == PWM_HOOK_VERSION && size == sizeof(*prev)) { /* Restore previous state. */ for (fan = 0; fan < CONFIG_FANS; fan++) { - fan_set_enabled(fans[fan].ch, prev->fan_en); - fan_set_rpm_target(fans[fan].ch, prev->fan_rpm); + fan_set_enabled(FAN_CH(fan), prev->fan_en); + fan_set_rpm_target(FAN_CH(fan), prev->fan_rpm); } } else { /* Set initial fan speed */ for (fan = 0; fan < CONFIG_FANS; fan++) - fan_set_rpm_target(fans[fan].ch, - fan_percent_to_rpm(fans[fan].ch, + fan_set_rpm_target(FAN_CH(fan), + fan_percent_to_rpm(FAN_CH(fan), CONFIG_FAN_INIT_SPEED)); } @@ -472,12 +472,12 @@ static void pwm_fan_second(void) int fan; for (fan = 0; fan < CONFIG_FANS; fan++) { - if (fan_is_stalled(fans[fan].ch)) { + if (fan_is_stalled(FAN_CH(fan))) { rpm = EC_FAN_SPEED_STALLED; stalled = 1; cprints(CC_PWM, "Fan %d stalled!", fan); } else { - rpm = fan_get_rpm_actual(fans[fan].ch); + rpm = fan_get_rpm_actual(FAN_CH(fan)); } mapped[fan] = rpm; @@ -498,8 +498,8 @@ static void pwm_fan_preserve_state(void) int fan = 0; /* TODO(crosbug.com/p/23530): Still treating all fans as one. */ - state.fan_en = fan_get_enabled(fans[fan].ch); - state.fan_rpm = fan_get_rpm_target(fans[fan].ch); + state.fan_en = fan_get_enabled(FAN_CH(fan)); + state.fan_rpm = fan_get_rpm_target(FAN_CH(fan)); system_add_jump_tag(PWMFAN_SYSJUMP_TAG, PWM_HOOK_VERSION, sizeof(state), &state); @@ -515,7 +515,7 @@ static void pwm_fan_resume(void) #else set_thermal_control_enabled(fan, 0); #endif - fan_set_rpm_target(fans[fan].ch, fans[fan].rpm_max); + fan_set_rpm_target(FAN_CH(fan), fans[fan].rpm->rpm_max); set_enabled(fan, 1); } } @@ -533,7 +533,7 @@ static void pwm_fan_S3_S5(void) * again if we need active cooling during heavy battery * charging or something. */ - fan_set_rpm_target(fans[fan].ch, 0); + fan_set_rpm_target(FAN_CH(fan), 0); set_enabled(fan, 0); /* crosbug.com/p/8097 */ } } diff --git a/include/fan.h b/include/fan.h index bd94ba8bd1..86c2822f80 100644 --- a/include/fan.h +++ b/include/fan.h @@ -8,13 +8,8 @@ #ifndef __CROS_EC_FAN_H #define __CROS_EC_FAN_H -/* Characteristic of each physical fan */ -struct fan_t { +struct fan_conf { unsigned int flags; - /* rpm_min is to keep turning. rpm_start is to begin turning */ - int rpm_min; - int rpm_start; - int rpm_max; /* Hardware channel number (the meaning is chip-specific) */ int ch; /* Active-high power_good input GPIO, or -1 if none */ @@ -23,6 +18,19 @@ struct fan_t { int enable_gpio; }; +struct fan_rpm { + /* rpm_min is to keep turning. rpm_start is to begin turning */ + int rpm_min; + int rpm_start; + int rpm_max; +}; + +/* Characteristic of each physical fan */ +struct fan_t { + const struct fan_conf *conf; + const struct fan_rpm *rpm; +}; + /* Values for .flags field */ /* Enable automatic RPM control using tach input */ #define FAN_USE_RPM_MODE (1 << 0) @@ -30,8 +38,10 @@ struct fan_t { #define FAN_USE_FAST_START (1 << 1) /* The list of fans is instantiated in board.c. */ -extern const struct fan_t fans[]; +extern struct fan_t fans[]; +/* For convenience */ +#define FAN_CH(fan) fans[fan].conf->ch /** * Set the amount of active cooling needed. The thermal control task will call diff --git a/test/fan.c b/test/fan.c index 9a0fa0d225..6082de1553 100644 --- a/test/fan.c +++ b/test/fan.c @@ -17,6 +17,7 @@ #include "timer.h" #include "util.h" +#define FAN_RPM(fan) fans[fan].rpm /*****************************************************************************/ /* Tests */ @@ -29,7 +30,7 @@ static int test_fan(void) sleep(2); /* With nothing else to do, fans default to full-on */ - TEST_ASSERT(fan_get_rpm_actual(0) == fans[0].rpm_max); + TEST_ASSERT(fan_get_rpm_actual(0) == FAN_RPM(0)->rpm_max); /* * fan_set_percent_needed() is normally called once a second by the @@ -46,22 +47,22 @@ static int test_fan(void) /* On, but just barely */ fan_set_percent_needed(0, 1); - TEST_ASSERT(fan_get_rpm_actual(0) == fans[0].rpm_start); + TEST_ASSERT(fan_get_rpm_actual(0) == FAN_RPM(0)->rpm_start); /* fan is above min speed now, so should be set to min */ fan_set_percent_needed(0, 1); - TEST_ASSERT(fan_get_rpm_actual(0) == fans[0].rpm_min); + TEST_ASSERT(fan_get_rpm_actual(0) == FAN_RPM(0)->rpm_min); /* Full speed */ fan_set_percent_needed(0, 100); - TEST_ASSERT(fan_get_rpm_actual(0) == fans[0].rpm_max); + TEST_ASSERT(fan_get_rpm_actual(0) == FAN_RPM(0)->rpm_max); fan_set_percent_needed(0, 100); - TEST_ASSERT(fan_get_rpm_actual(0) == fans[0].rpm_max); + TEST_ASSERT(fan_get_rpm_actual(0) == FAN_RPM(0)->rpm_max); /* Slow again */ fan_set_percent_needed(0, 1); - TEST_ASSERT(fan_get_rpm_actual(0) == fans[0].rpm_min); + TEST_ASSERT(fan_get_rpm_actual(0) == FAN_RPM(0)->rpm_min); fan_set_percent_needed(0, 1); - TEST_ASSERT(fan_get_rpm_actual(0) == fans[0].rpm_min); + TEST_ASSERT(fan_get_rpm_actual(0) == FAN_RPM(0)->rpm_min); /* Off */ fan_set_percent_needed(0, 0); @@ -71,31 +72,31 @@ static int test_fan(void) /* On, but just barely */ fan_set_percent_needed(0, 1); - TEST_ASSERT(fan_get_rpm_actual(0) == fans[0].rpm_start); + TEST_ASSERT(fan_get_rpm_actual(0) == FAN_RPM(0)->rpm_start); /* Force the mock_rpm to be slow, to simulate dragging */ - mock_rpm = fans[0].rpm_min - 105; + mock_rpm = FAN_RPM(0)->rpm_min - 105; /* It should keep trying for the start speed */ fan_set_percent_needed(0, 1); - TEST_ASSERT(fan_get_rpm_actual(0) == fans[0].rpm_start); + TEST_ASSERT(fan_get_rpm_actual(0) == FAN_RPM(0)->rpm_start); /* But we have to keep forcing the mock_rpm back down */ - mock_rpm = fans[0].rpm_min - 105; + mock_rpm = FAN_RPM(0)->rpm_min - 105; fan_set_percent_needed(0, 1); - TEST_ASSERT(fan_get_rpm_actual(0) == fans[0].rpm_start); + TEST_ASSERT(fan_get_rpm_actual(0) == FAN_RPM(0)->rpm_start); /* Now let it turn just under rpm_min. Should be okay there. */ - mock_rpm = fans[0].rpm_min - 10; + mock_rpm = FAN_RPM(0)->rpm_min - 10; fan_set_percent_needed(0, 1); - TEST_ASSERT(fan_get_rpm_actual(0) == fans[0].rpm_min); + TEST_ASSERT(fan_get_rpm_actual(0) == FAN_RPM(0)->rpm_min); /* Let it go a little faster, still okay */ - mock_rpm = fans[0].rpm_min + 10; + mock_rpm = FAN_RPM(0)->rpm_min + 10; fan_set_percent_needed(0, 1); - TEST_ASSERT(fan_get_rpm_actual(0) == fans[0].rpm_min); + TEST_ASSERT(fan_get_rpm_actual(0) == FAN_RPM(0)->rpm_min); /* But if it drops too low, it should go back to the start speed */ - mock_rpm = fans[0].rpm_min - 105; + mock_rpm = FAN_RPM(0)->rpm_min - 105; fan_set_percent_needed(0, 1); - TEST_ASSERT(fan_get_rpm_actual(0) == fans[0].rpm_start); + TEST_ASSERT(fan_get_rpm_actual(0) == FAN_RPM(0)->rpm_start); /* And then relax */ fan_set_percent_needed(0, 1); - TEST_ASSERT(fan_get_rpm_actual(0) == fans[0].rpm_min); + TEST_ASSERT(fan_get_rpm_actual(0) == FAN_RPM(0)->rpm_min); return EC_SUCCESS; } -- cgit v1.2.1