summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/fan.h92
-rw-r--r--zephyr/Kconfig.temperature8
-rw-r--r--zephyr/shim/src/fan.c35
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)