diff --git a/common/tmp006.c b/common/tmp006.c index ecc55ee14f..72e004de4d 100644 --- a/common/tmp006.c +++ b/common/tmp006.c @@ -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; diff --git a/include/ec_commands.h b/include/ec_commands.h index 2dc53f1feb..e8f406cae7 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -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 */ diff --git a/util/ectool.c b/util/ectool.c index 263477c951..fbfa9be214 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -128,6 +128,8 @@ const char help_str[] = " Get the threshold temperature value from thermal engine.\n" " thermalset \n" " Set the threshold temperature value for thermal engine.\n" + " tmp006cal [ ]\n" + " Get/set TMP006 calibration\n" " usbchargemode \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},