diff options
-rw-r--r-- | include/fan.h | 92 | ||||
-rw-r--r-- | zephyr/Kconfig.temperature | 8 | ||||
-rw-r--r-- | zephyr/shim/src/fan.c | 35 |
3 files changed, 83 insertions, 52 deletions
diff --git a/include/fan.h b/include/fan.h index 25068a653b..29552e0e6a 100644 --- a/include/fan.h +++ b/include/fan.h @@ -10,6 +10,7 @@ #include "config.h" +#include <stdbool.h> #include <stdint.h> #ifdef CONFIG_ZEPHYR @@ -29,6 +30,38 @@ BUILD_ASSERT(FAN_CH_COUNT == CONFIG_PLATFORM_EC_NUM_FANS); #endif /* CONFIG_PLATFORM_EC_FAN */ #endif /* CONFIG_ZEPHYR */ +/** + * STOPPED means not spinning. + * + * When setting fan rpm, some implementations in chip layer (npcx and it83xx) + * is to adjust fan pwm duty steps by steps. In this period, fan_status will + * be marked as CHANGING. After change is done, fan_status will become LOCKED. + * + * In the period of changing pwm duty, if it's trying to increase/decrease duty + * even when duty is already in upper/lower bound. Then this action won't work, + * and fan_status will be marked as FRUSTRATED. + * + * For other implementations in chip layer (mchp), there is no + * changing period. So they don't have CHANGING status. + * Just return status as LOCKED in normal spinning case, return STOPPED when + * not spinning, return FRUSTRATED when the related flags (which is read from + * chip's register) is set. + */ +enum fan_status { + FAN_STATUS_STOPPED = 0, + FAN_STATUS_CHANGING = 1, + FAN_STATUS_LOCKED = 2, + FAN_STATUS_FRUSTRATED = 3 +}; + +/* Fan mode */ +enum fan_mode { + /* FAN rpm mode */ + FAN_RPM = 0, + /* FAN duty mode */ + FAN_DUTY, +}; + struct fan_conf { unsigned int flags; /* Hardware channel number (the meaning is chip-specific) */ @@ -53,6 +86,26 @@ struct fan_t { const struct fan_rpm *rpm; }; +/* Fan status data structure */ +struct fan_data { + /* Fan mode */ + enum fan_mode current_fan_mode; + /* Actual rpm */ + int rpm_actual; + /* Previous rpm */ + int rpm_pre; + /* Target rpm */ + int rpm_target; + /* Fan config flags */ + unsigned int flags; + /* Automatic fan status */ + enum fan_status auto_status; + /* Current PWM duty cycle percentage */ + int pwm_percent; + /* Whether the PWM channel is enabled */ + bool pwm_enabled; +}; + /* Values for .flags field */ /* Enable automatic RPM control using tach input */ #define FAN_USE_RPM_MODE BIT(0) @@ -167,29 +220,6 @@ int fan_get_rpm_target(int ch); /* Is the fan stalled when it shouldn't be? */ int fan_is_stalled(int ch); -/** - * STOPPED means not spinning. - * - * When setting fan rpm, some implementations in chip layer (npcx and it83xx) - * is to adjust fan pwm duty steps by steps. In this period, fan_status will - * be marked as CHANGING. After change is done, fan_status will become LOCKED. - * - * In the period of changing pwm duty, if it's trying to increase/decrease duty - * even when duty is already in upper/lower bound. Then this action won't work, - * and fan_status will be marked as FRUSTRATED. - * - * For other implementations in chip layer (mchp), there is no - * changing period. So they don't have CHANGING status. - * Just return status as LOCKED in normal spinning case, return STOPPED when - * not spinning, return FRUSTRATED when the related flags (which is read from - * chip's register) is set. - */ -enum fan_status { - FAN_STATUS_STOPPED = 0, - FAN_STATUS_CHANGING = 1, - FAN_STATUS_LOCKED = 2, - FAN_STATUS_FRUSTRATED = 3 -}; enum fan_status fan_get_status(int ch); /* Initialize the HW according to the desired flags */ @@ -201,4 +231,20 @@ void fan_set_count(int count); int is_thermal_control_enabled(int idx); +#ifdef CONFIG_ZEPHYR +extern struct fan_data fan_data[]; + +/** + * This function sets PWM duty based on target RPM. + * + * The target and current RPM values in fan_data entry that + * corresponds to selected fan has to be updated before this + * function is called. + * + * @param ch Fan number (index into fan_data[] and fans[]) + * Return Fan status (see fan_status enum definition) + */ +enum fan_status board_override_fan_control_duty(int ch); +#endif + #endif /* __CROS_EC_FAN_H */ diff --git a/zephyr/Kconfig.temperature b/zephyr/Kconfig.temperature index bd977b2832..84e65907e4 100644 --- a/zephyr/Kconfig.temperature +++ b/zephyr/Kconfig.temperature @@ -117,6 +117,14 @@ config PLATFORM_EC_CUSTOM_FAN_CONTROL Enable fan custom control to let projects define their own fan control mechanism by EC. +config PLATFORM_EC_CUSTOM_FAN_DUTY_CONTROL + bool "Fan custom control support" + default n + help + Enable fan duty custom control to let projects define + their own fan duty control mechanism by implementing + the routine board_override_fan_control_duty(). + if PLATFORM_EC_FAN config PLATFORM_EC_NUM_FANS diff --git a/zephyr/shim/src/fan.c b/zephyr/shim/src/fan.c index 9978e6f4ca..69c23fa9fd 100644 --- a/zephyr/shim/src/fan.c +++ b/zephyr/shim/src/fan.c @@ -62,34 +62,6 @@ DT_INST_FOREACH_CHILD(0, FAN_CONFIGS) const struct fan_t fans[FAN_CH_COUNT] = { DT_INST_FOREACH_CHILD(0, FAN_INST) }; -/* Fan mode */ -enum fan_mode { - /* FAN rpm mode */ - FAN_RPM = 0, - /* FAN duty mode */ - FAN_DUTY, -}; - -/* Fan status data structure */ -struct fan_data { - /* Fan mode */ - enum fan_mode current_fan_mode; - /* Actual rpm */ - int rpm_actual; - /* Previous rpm */ - int rpm_pre; - /* Target rpm */ - int rpm_target; - /* Fan config flags */ - unsigned int flags; - /* Automatic fan status */ - enum fan_status auto_status; - /* Current PWM duty cycle percentage */ - int pwm_percent; - /* Whether the PWM channel is enabled */ - bool pwm_enabled; -}; - /* Data structure to define PWM and tachometer. */ struct fan_config { struct pwm_dt_spec pwm; @@ -97,7 +69,7 @@ struct fan_config { const struct device *tach; }; -static struct fan_data fan_data[FAN_CH_COUNT]; +struct fan_data fan_data[FAN_CH_COUNT]; static const struct fan_config fan_config[FAN_CH_COUNT] = { DT_INST_FOREACH_CHILD(0, FAN_CONTROL_INST) }; @@ -268,8 +240,13 @@ static void fan_tick_func_rpm(int ch) /* Get actual rpm */ data->rpm_actual = fan_rpm(ch); + /* TODO: b/279132492 */ +#ifdef CONFIG_PLATFORM_EC_CUSTOM_FAN_DUTY_CONTROL + data->auto_status = board_override_fan_control_duty(ch); +#else /* Do smart fan stuff */ data->auto_status = fan_smart_control(ch); +#endif } static void fan_tick_func_duty(int ch) |