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
This commit is contained in:
Vic Yang
2012-02-29 10:04:46 -08:00
parent 13b5c41951
commit 747b1f7520
7 changed files with 240 additions and 7 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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);
}
}

52
common/thermal_commands.c Normal file
View File

@@ -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);

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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"))