diff options
author | Vic Yang <victoryang@chromium.org> | 2012-02-29 10:04:46 -0800 |
---|---|---|
committer | Vic Yang <victoryang@chromium.org> | 2012-02-29 14:42:45 -0800 |
commit | 747b1f752007d6563288f7be41c20b8cc43ca3f6 (patch) | |
tree | a2137b57819b3eb368c95a3ed2956ff6485d10c7 | |
parent | 13b5c41951c2da3e90ac115a3dbe8aaddb959782 (diff) | |
download | chrome-ec-747b1f752007d6563288f7be41c20b8cc43ca3f6.tar.gz |
Thermal Engine: LPC commands.
Implement LPC commands and ectool commands to
1. Set/get threshold temperature values.
2. Toggle on/off automatic fan speed control.
Signed-off-by: Vic Yang <victoryang@chromium.org>
BUG=chrome-os-partner:8251
TEST=Manual test
Change-Id: Ia4282a6fa47a838aed26540f33c1eb7acc92ef0e
-rw-r--r-- | common/build.mk | 2 | ||||
-rw-r--r-- | common/pwm_commands.c | 4 | ||||
-rw-r--r-- | common/thermal.c | 49 | ||||
-rw-r--r-- | common/thermal_commands.c | 52 | ||||
-rw-r--r-- | include/lpc_commands.h | 24 | ||||
-rw-r--r-- | include/thermal.h | 9 | ||||
-rw-r--r-- | util/ectool.c | 107 |
7 files changed, 240 insertions, 7 deletions
diff --git a/common/build.mk b/common/build.mk index 649fe9b6d9..00386b15b3 100644 --- a/common/build.mk +++ b/common/build.mk @@ -16,7 +16,7 @@ common-$(CONFIG_TASK_GAIAPOWER)+=gaia_power.o common-$(CONFIG_FLASH)+=flash_commands.o common-$(CONFIG_PSTORE)+=pstore_commands.o common-$(CONFIG_PWM)+=pwm_commands.o -common-$(CONFIG_TASK_THERMAL)+=thermal.o +common-$(CONFIG_TASK_THERMAL)+=thermal.o thermal_commands.o common-$(CONFIG_TEMP_SENSOR)+=temp_sensor.o common-$(CONFIG_TMP006)+=tmp006.o common-$(CONFIG_LIGHTBAR)+=leds.o diff --git a/common/pwm_commands.c b/common/pwm_commands.c index 3e6a9ee52b..d40314459f 100644 --- a/common/pwm_commands.c +++ b/common/pwm_commands.c @@ -7,6 +7,7 @@ #include "host_command.h" #include "pwm.h" +#include "thermal.h" enum lpc_status pwm_command_get_fan_rpm(uint8_t *data) @@ -25,6 +26,9 @@ enum lpc_status pwm_command_set_fan_target_rpm(uint8_t *data) struct lpc_params_pwm_set_fan_target_rpm *p = (struct lpc_params_pwm_set_fan_target_rpm *)data; +#ifdef CONFIG_TASK_THERMAL + thermal_toggle_auto_fan_ctrl(0); +#endif pwm_set_fan_target_rpm(p->rpm); return EC_LPC_STATUS_SUCCESS; } diff --git a/common/thermal.c b/common/thermal.c index ffcd0986fd..4b7341444a 100644 --- a/common/thermal.c +++ b/common/thermal.c @@ -28,6 +28,41 @@ static int8_t ot_count[TEMP_SENSOR_COUNT][THRESHOLD_COUNT]; * are reached (since we can disable any threshold.) */ static int8_t overheated[THRESHOLD_COUNT]; +static int fan_ctrl_on = 1; + + +int thermal_set_threshold(int sensor_id, int threshold_id, int value) +{ + if (sensor_id < 0 || sensor_id >= TEMP_SENSOR_COUNT) + return EC_ERROR_INVAL; + if (threshold_id < 0 || threshold_id >= THRESHOLD_COUNT) + return EC_ERROR_INVAL; + if (value < 0) + return EC_ERROR_INVAL; + + thermal_config[sensor_id].thresholds[threshold_id] = value; + + return EC_SUCCESS; +} + + +int thermal_get_threshold(int sensor_id, int threshold_id) +{ + if (sensor_id < 0 || sensor_id >= TEMP_SENSOR_COUNT) + return EC_ERROR_INVAL; + if (threshold_id < 0 || threshold_id >= THRESHOLD_COUNT) + return EC_ERROR_INVAL; + + return thermal_config[sensor_id].thresholds[threshold_id]; +} + + +int thermal_toggle_auto_fan_ctrl(int auto_fan_on) +{ + fan_ctrl_on = auto_fan_on; + return EC_SUCCESS; +} + static void smi_overheated_warning(void) { @@ -56,12 +91,14 @@ static void overheated_action(void) smi_overheated_warning(); } - if (overheated[THRESHOLD_FAN_HI]) - pwm_set_fan_target_rpm(-1); /* Max RPM. */ - else if (overheated[THRESHOLD_FAN_LO]) - pwm_set_fan_target_rpm(6000); - else - pwm_set_fan_target_rpm(0); + if (fan_ctrl_on) { + if (overheated[THRESHOLD_FAN_HI]) + pwm_set_fan_target_rpm(-1); /* Max RPM. */ + else if (overheated[THRESHOLD_FAN_LO]) + pwm_set_fan_target_rpm(6000); + else + pwm_set_fan_target_rpm(0); + } } diff --git a/common/thermal_commands.c b/common/thermal_commands.c new file mode 100644 index 0000000000..6c590ca840 --- /dev/null +++ b/common/thermal_commands.c @@ -0,0 +1,52 @@ +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Thermal engine host commands for Chrome EC */ + +#include "thermal.h" +#include "host_command.h" + + +/*****************************************************************************/ +/* Host commands */ + +enum lpc_status thermal_command_set_threshold(uint8_t *data) +{ + struct lpc_params_thermal_set_threshold *p = + (struct lpc_params_thermal_set_threshold *)data; + + if (thermal_set_threshold(p->sensor_id, p->threshold_id, p->value)) + return EC_LPC_STATUS_ERROR; + return EC_LPC_STATUS_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_LPC_COMMAND_THERMAL_SET_THRESHOLD, + thermal_command_set_threshold); + + +enum lpc_status thermal_command_get_threshold(uint8_t *data) +{ + struct lpc_params_thermal_get_threshold *p = + (struct lpc_params_thermal_get_threshold *)data; + struct lpc_response_thermal_get_threshold *r = + (struct lpc_response_thermal_get_threshold *)data; + + r->value = thermal_get_threshold(p->sensor_id, p->threshold_id); + if (r->value == -1) + return EC_LPC_STATUS_ERROR; + + return EC_LPC_STATUS_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_LPC_COMMAND_THERMAL_GET_THRESHOLD, + thermal_command_get_threshold); + + +enum lpc_status thermal_command_auto_fan_ctrl(uint8_t *data) +{ + if (thermal_toggle_auto_fan_ctrl(1)) + return EC_LPC_STATUS_ERROR; + return EC_LPC_STATUS_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_LPC_COMMAND_THERMAL_AUTO_FAN_CTRL, + thermal_command_auto_fan_ctrl); diff --git a/include/lpc_commands.h b/include/lpc_commands.h index 3d419e5c9d..70d5fc594a 100644 --- a/include/lpc_commands.h +++ b/include/lpc_commands.h @@ -290,4 +290,28 @@ struct lpc_params_pstore_write { uint8_t data[EC_LPC_PSTORE_SIZE_MAX]; } __attribute__ ((packed)); +/*****************************************************************************/ +/* Thermal engine commands */ + +/* Set thershold value */ +#define EC_LPC_COMMAND_THERMAL_SET_THRESHOLD 0x50 +struct lpc_params_thermal_set_threshold { + uint8_t sensor_id; + uint8_t threshold_id; + uint16_t value; +} __attribute__ ((packed)); + +/* Get threshold value */ +#define EC_LPC_COMMAND_THERMAL_GET_THRESHOLD 0x51 +struct lpc_params_thermal_get_threshold { + uint8_t sensor_id; + uint8_t threshold_id; +} __attribute__ ((packed)); +struct lpc_response_thermal_get_threshold { + uint16_t value; +} __attribute__ ((packed)); + +/* Toggling automatic fan control */ +#define EC_LPC_COMMAND_THERMAL_AUTO_FAN_CTRL 0x52 + #endif /* __CROS_EC_LPC_COMMANDS_H */ diff --git a/include/thermal.h b/include/thermal.h index aa6cc08f4f..0998b70fcc 100644 --- a/include/thermal.h +++ b/include/thermal.h @@ -47,4 +47,13 @@ struct thermal_config_t { int16_t thresholds[THRESHOLD_COUNT]; }; +/* Set the threshold temperature value. Return -1 on error. */ +int thermal_set_threshold(int sensor_id, int threshold_id, int value); + +/* Get the threshold temperature value. Return -1 on error. */ +int thermal_get_threshold(int sensor_id, int threshold_id); + +/* Toggle automatic fan speed control. Return -1 on error. */ +int thermal_toggle_auto_fan_ctrl(int auto_fan_on); + #endif /* __CROS_EC_THERMAL_H */ diff --git a/util/ectool.c b/util/ectool.c index 676bcc4fe8..a7ebee84a3 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -42,6 +42,12 @@ const char help_str[] = " Prints EC version\n" " temps <sensorid>\n" " Print temperature.\n" + " thermalget <sensor_id> <threshold_id>\n" + " Get the threshold temperature value from thermal engine.\n" + " thermalset <sensor_id> <threshold_id> <value>\n" + " Set the threshold temperature value for thermal engine.\n" + " autofanctrl <on>\n" + " Turn on automatic fan speed control.\n" " pwmgetfanrpm\n" " Prints current fan RPM\n" " pwmsetfanrpm <targetrpm>\n" @@ -531,6 +537,101 @@ int cmd_temperature(int argc, char *argv[]) } +int cmd_thermal_get_threshold(int argc, char *argv[]) +{ + struct lpc_params_thermal_get_threshold p; + struct lpc_response_thermal_get_threshold r; + char *e; + int rv; + + if (argc != 2) { + fprintf(stderr, "Usage: thermalget <sensorid> <thresholdid>\n"); + return -1; + } + + p.sensor_id = strtol(argv[0], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad sensor ID.\n"); + return -1; + } + + p.threshold_id = strtol(argv[1], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad threshold ID.\n"); + return -1; + } + + rv = ec_command(EC_LPC_COMMAND_THERMAL_GET_THRESHOLD, + &p, sizeof(p), &r, sizeof(r)); + if (rv) + return rv; + + if (r.value < 0) + return -1; + + printf("Threshold %d for sensor %d is %d K.\n", + p.threshold_id, p.sensor_id, r.value); + + return 0; +} + + +int cmd_thermal_set_threshold(int argc, char *argv[]) +{ + struct lpc_params_thermal_set_threshold p; + char *e; + int rv; + + if (argc != 3) { + fprintf(stderr, + "Usage: thermalset <sensorid> <thresholdid> <value>\n"); + return -1; + } + + p.sensor_id = strtol(argv[0], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad sensor ID.\n"); + return -1; + } + + p.threshold_id = strtol(argv[1], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad threshold ID.\n"); + return -1; + } + + p.value = strtol(argv[2], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad threshold value.\n"); + return -1; + } + + rv = ec_command(EC_LPC_COMMAND_THERMAL_SET_THRESHOLD, + &p, sizeof(p), NULL, 0); + if (rv) + return rv; + + printf("Threshold %d for sensor %d set to %d.\n", + p.threshold_id, p.sensor_id, p.value); + + return 0; +} + + +int cmd_thermal_auto_fan_ctrl(int argc, char *argv[]) +{ + int rv; + + rv = ec_command(EC_LPC_COMMAND_THERMAL_AUTO_FAN_CTRL, + NULL, 0, NULL, 0); + if (rv) + return rv; + + printf("Automatic fan control is now on.\n"); + return 0; +} + + int cmd_pwm_get_fan_rpm(void) { int rv; @@ -802,6 +903,12 @@ int main(int argc, char *argv[]) return cmd_version(); if (!strcasecmp(argv[1], "temps")) return cmd_temperature(argc - 2, argv + 2); + if (!strcasecmp(argv[1], "thermalget")) + return cmd_thermal_get_threshold(argc - 2, argv + 2); + if (!strcasecmp(argv[1], "thermalset")) + return cmd_thermal_set_threshold(argc - 2, argv + 2); + if (!strcasecmp(argv[1], "autofanctrl")) + return cmd_thermal_auto_fan_ctrl(argc - 2, argv + 2); if (!strcasecmp(argv[1], "pwmgetfanrpm")) return cmd_pwm_get_fan_rpm(); if (!strcasecmp(argv[1], "pwmsetfanrpm")) |