Add host command to get/set TMP006 calibration data

Needed for host-based thermal control and tweaking.

BUG=chrome-os-partner:14955
BRANCH=link
TEST=manual

From a root shell,
  ectool tmp006cal 0 3.5e-14 -2.8e-5 -5.5e-7 4.5e-9
  ectool tmp006cal 2 3.6e-14 -2.9e-5 -5.6e-7 4.6e-9
  ectool tmp006cal 0
    S0: 3.500000e-14
    b0: -2.800000e-05
    b1: -5.500000e-07
    b2: 4.500000e-09
  ectool tmp006cal 2
    S0: 3.600000e-14
    b0: -2.900000e-05
    b1: -5.600000e-07
    b2: 4.600000e-09

At the ec console, "t6cal" should show the settings took effect as well.

Change-Id: If43b11e1e827483f0a20db1a2e5644f3475fd95e
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/35215
This commit is contained in:
Randall Spangler
2012-10-10 16:39:42 -07:00
committed by Gerrit
parent bea56570f3
commit d1bebbbe66
3 changed files with 175 additions and 22 deletions

View File

@@ -10,6 +10,7 @@
#include "console.h"
#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
#include "i2c.h"
#include "math.h"
#include "task.h"
@@ -43,8 +44,8 @@ struct tmp006_data_t {
int t[4]; /* Circular buffer of last four die temperatures */
int tidx; /* Index of the current value in t[] */
int fail; /* Fail flags; non-zero if last read failed */
float S0; /* Sensitivity factor */
float B0, B1, B2; /* Coefficients for self-heating correction */
float s0; /* Sensitivity factor */
float b0, b1, b2; /* Coefficients for self-heating correction */
};
static struct tmp006_data_t tmp006_data[TMP006_COUNT];
@@ -93,9 +94,9 @@ static int tmp006_calculate_object_temp(int Tdie_i, int Vobj_i,
/* Calculate according to TMP006 users guide. */
Tx = Tdie - 298.15f;
/* S is the sensitivity */
S = tdata->S0 * (1.0f + A1 * Tx + A2 * Tx * Tx);
S = tdata->s0 * (1.0f + A1 * Tx + A2 * Tx * Tx);
/* Vos is the offset voltage */
Vos = tdata->B0 + tdata->B1 * Tx + tdata->B2 * Tx * Tx;
Vos = tdata->b0 + tdata->b1 * Tx + tdata->b2 * Tx * Tx;
Vx = Vobj - Vos;
/* fv is Seebeck coefficient f(Vobj) */
fv = Vx + C2 * Vx * Vx;
@@ -249,16 +250,67 @@ static int tmp006_init(void)
* TODO: remove default calibration data; sensor should fail
* until calibrated by host or console command.
*/
tdata->S0 = tmp006_sensors[i].S0;
tdata->B0 = B0;
tdata->B1 = B1;
tdata->B2 = B2;
tdata->s0 = tmp006_sensors[i].S0;
tdata->b0 = B0;
tdata->b1 = B1;
tdata->b2 = B2;
}
return EC_SUCCESS;
}
DECLARE_HOOK(HOOK_INIT, tmp006_init, HOOK_PRIO_DEFAULT);
/*****************************************************************************/
/* Host commands */
int tmp006_get_calibration(struct host_cmd_handler_args *args)
{
const struct ec_params_tmp006_get_calibration *p = args->params;
struct ec_response_tmp006_get_calibration *r = args->response;
const struct tmp006_data_t *tdata;
if (p->index >= TMP006_COUNT)
return EC_RES_INVALID_PARAM;
tdata = tmp006_data + p->index;
r->s0 = tdata->s0;
r->b0 = tdata->b0;
r->b1 = tdata->b1;
r->b2 = tdata->b2;
args->response_size = sizeof(*r);
return EC_RES_SUCCESS;
}
DECLARE_HOST_COMMAND(EC_CMD_TMP006_GET_CALIBRATION,
tmp006_get_calibration,
EC_VER_MASK(0));
/*****************************************************************************/
/* Host commands */
int tmp006_set_calibration(struct host_cmd_handler_args *args)
{
const struct ec_params_tmp006_set_calibration *p = args->params;
struct tmp006_data_t *tdata;
if (p->index >= TMP006_COUNT)
return EC_RES_INVALID_PARAM;
tdata = tmp006_data + p->index;
tdata->s0 = p->s0;
tdata->b0 = p->b0;
tdata->b1 = p->b1;
tdata->b2 = p->b2;
return EC_RES_SUCCESS;
}
DECLARE_HOST_COMMAND(EC_CMD_TMP006_SET_CALIBRATION,
tmp006_set_calibration,
EC_VER_MASK(0));
/*****************************************************************************/
/* Console commands */
@@ -330,17 +382,17 @@ static int command_t6cal(int argc, char **argv)
int i;
if (argc < 2) {
ccprintf("# Name S0 B0"
" B1 B2\n");
ccprintf("# Name S0 b0"
" b1 b2\n");
for (i = 0; i < TMP006_COUNT; i++) {
tdata = tmp006_data + i;
ccprintf("%d %-11s"
"%7de-17 %7de-8 %7de-10 %7de-12\n",
i, tmp006_sensors[i].name,
(int)(tdata->S0 * 1e17f),
(int)(tdata->B0 * 1e8f),
(int)(tdata->B1 * 1e10f),
(int)(tdata->B2 * 1e12f));
(int)(tdata->s0 * 1e17f),
(int)(tdata->b0 * 1e8f),
(int)(tdata->b1 * 1e10f),
(int)(tdata->b2 * 1e12f));
}
return EC_SUCCESS;
@@ -358,14 +410,14 @@ static int command_t6cal(int argc, char **argv)
if (*e)
return EC_ERROR_PARAM3;
if (!strcasecmp(argv[2], "S0"))
tdata->S0 = (float)v * 1e-17f;
else if (!strcasecmp(argv[2], "B0"))
tdata->B0 = (float)v * 1e-8f;
else if (!strcasecmp(argv[2], "B1"))
tdata->B1 = (float)v * 1e-10f;
else if (!strcasecmp(argv[2], "B2"))
tdata->B2 = (float)v * 1e-12f;
if (!strcasecmp(argv[2], "s0"))
tdata->s0 = (float)v * 1e-17f;
else if (!strcasecmp(argv[2], "b0"))
tdata->b0 = (float)v * 1e-8f;
else if (!strcasecmp(argv[2], "b1"))
tdata->b1 = (float)v * 1e-10f;
else if (!strcasecmp(argv[2], "b2"))
tdata->b2 = (float)v * 1e-12f;
else
return EC_ERROR_PARAM2;

View File

@@ -837,6 +837,32 @@ struct ec_response_thermal_get_threshold {
/* Toggle automatic fan control */
#define EC_CMD_THERMAL_AUTO_FAN_CTRL 0x52
/* Get TMP006 calibration data */
#define EC_CMD_TMP006_GET_CALIBRATION 0x53
struct ec_params_tmp006_get_calibration {
uint8_t index;
} __packed;
struct ec_response_tmp006_get_calibration {
float s0;
float b0;
float b1;
float b2;
} __packed;
/* Set TMP006 calibration data */
#define EC_CMD_TMP006_SET_CALIBRATION 0x54
struct ec_params_tmp006_set_calibration {
uint8_t index;
uint8_t reserved[3]; /* Reserved; set 0 */
float s0;
float b0;
float b1;
float b2;
} __packed;
/*****************************************************************************/
/* MKBP - Matrix KeyBoard Protocol */

View File

@@ -128,6 +128,8 @@ const char help_str[] =
" 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"
" tmp006cal <tmp006_index> [<S0> <b0> <b1> <b2>]\n"
" Get/set TMP006 calibration\n"
" usbchargemode <port> <mode>\n"
" Set USB charging mode\n"
" version\n"
@@ -2383,6 +2385,78 @@ static int cmd_keyconfig(int argc, char *argv[])
return 0;
}
int cmd_tmp006cal(int argc, char *argv[])
{
struct ec_params_tmp006_set_calibration p;
char *e;
int idx;
int rv;
if (argc < 2) {
fprintf(stderr, "Must specify tmp006 index.\n");
return -1;
}
idx = strtol(argv[1], &e, 0);
if ((e && *e) || idx < 0 || idx > 255) {
fprintf(stderr, "Bad index.\n");
return -1;
}
if (argc == 2) {
struct ec_params_tmp006_get_calibration pg;
struct ec_response_tmp006_get_calibration r;
pg.index = idx;
rv = ec_command(EC_CMD_TMP006_GET_CALIBRATION, 0,
&pg, sizeof(pg), &r, sizeof(r));
if (rv < 0)
return rv;
printf("S0: %e\n", r.s0);
printf("b0: %e\n", r.b0);
printf("b1: %e\n", r.b1);
printf("b2: %e\n", r.b2);
return EC_SUCCESS;
}
if (argc != 6) {
fprintf(stderr, "Must specify all calibration params.\n");
return -1;
}
memset(&p, 0, sizeof(p));
p.index = idx;
p.s0 = strtod(argv[2], &e);
if (e && *e) {
fprintf(stderr, "Bad S0.\n");
return -1;
}
p.b0 = strtod(argv[3], &e);
if (e && *e) {
fprintf(stderr, "Bad b0.\n");
return -1;
}
p.b1 = strtod(argv[4], &e);
if (e && *e) {
fprintf(stderr, "Bad b1.\n");
return -1;
}
p.b2 = strtod(argv[5], &e);
if (e && *e) {
fprintf(stderr, "Bad b2.\n");
return -1;
}
return ec_command(EC_CMD_TMP006_SET_CALIBRATION, 0,
&p, sizeof(p), NULL, 0);
}
struct command {
const char *name;
int (*handler)(int argc, char *argv[]);
@@ -2442,6 +2516,7 @@ const struct command commands[] = {
{"tempsinfo", cmd_temp_sensor_info},
{"thermalget", cmd_thermal_get_threshold},
{"thermalset", cmd_thermal_set_threshold},
{"tmp006cal", cmd_tmp006cal},
{"usbchargemode", cmd_usb_charge_set_mode},
{"version", cmd_version},
{"wireless", cmd_wireless},