From 2b2f78d9295103a8df550086feeaaaa80aa56a2d Mon Sep 17 00:00:00 2001 From: Dave Parker Date: Wed, 7 Aug 2013 19:47:26 -0700 Subject: Console command for g781 temperature sensor. Read status, set temperature alert thresholds, get and set configuration options. I2c offsets and status/config register bits are documented in temp_sensor_g781.h Usage by example: g781 - Print status info g781 settemp 0x0e 12 - Set remote low temp alarm to 12C g781 setbyte 0x09 0x40 - Enable single-shot mode g781 getbyte 0xfe - Read device ID BUG=None BRANCH=falco,peppy TEST=Manual. Run g781 console command Signed-off-by: Dave Parker Change-Id: Id051f79ea643255d57c3fc694b7ae685a6611c81 Reviewed-on: https://gerrit.chromium.org/gerrit/65234 Reviewed-by: Randall Spangler Commit-Queue: Dave Parker Tested-by: Dave Parker --- common/temp_sensor_g781.c | 162 ++++++++++++++++++++++++++++++++++++++++++--- include/temp_sensor_g781.h | 45 ++++++++++++- 2 files changed, 194 insertions(+), 13 deletions(-) diff --git a/common/temp_sensor_g781.c b/common/temp_sensor_g781.c index 4a2698ea2e..267cc4a0e5 100644 --- a/common/temp_sensor_g781.c +++ b/common/temp_sensor_g781.c @@ -9,37 +9,179 @@ #include "console.h" #include "i2c.h" #include "temp_sensor_g781.h" +#include "util.h" -int g781_get_val(int idx, int *temp_ptr) +static int g781_read8(const int offset, int *data_ptr) +{ + return i2c_read8(I2C_PORT_THERMAL, G781_I2C_ADDR, offset, data_ptr); +} + +static int g781_write8(const int offset, int data) +{ + return i2c_write8(I2C_PORT_THERMAL, G781_I2C_ADDR, offset, data); +} + +static int g781_get_temp(const int offset, int *temp_ptr) { - int command; int rv; int temp_raw = 0; + rv = g781_read8(offset, &temp_raw); + if (rv < 0) + return rv; + + *temp_ptr = (int)(int8_t)temp_raw; + return EC_SUCCESS; +} + +static int g781_set_temp(const int offset, int temp) +{ + if (temp < -127 || temp > 127) + return EC_ERROR_INVAL; + + return g781_write8(offset, (uint8_t)temp); +} + +int g781_get_val(int idx, int *temp_ptr) +{ + int offset; + int rv; + if (!board_g781_has_power()) return EC_ERROR_NOT_POWERED; switch (idx) { case 0: - command = G781_TEMP_LOCAL; + offset = G781_TEMP_LOCAL; break; case 1: - command = G781_TEMP_REMOTE; + offset = G781_TEMP_REMOTE; break; default: return EC_ERROR_UNKNOWN; } - rv = i2c_read8(I2C_PORT_THERMAL, G781_I2C_ADDR, command, &temp_raw); + rv = g781_get_temp(offset, temp_ptr); + if (rv < 0) + return rv; + + /* Temperature from sensor is in degrees Celsius */ + *temp_ptr = C_TO_K(*temp_ptr); + return EC_SUCCESS; +} +static int g781_show_status(void) +{ + int value; + int rv; + + + rv = g781_get_temp(G781_TEMP_LOCAL, &value); if (rv < 0) return rv; + ccprintf("Local Temp: %3dC\n", value); - /* Negative numbers are 2's compliment with sign bit 7 */ - if (temp_raw & (1 << 7)) - temp_raw = ~(~temp_raw & 0xff) + 1; + rv = g781_get_temp(G781_LOCAL_TEMP_THERM_LIMIT, &value); + if (rv < 0) + return rv; + ccprintf(" Therm Trip: %3dC\n", value); + + rv = g781_get_temp(G781_LOCAL_TEMP_HIGH_LIMIT_R, &value); + if (rv < 0) + return rv; + ccprintf(" High Alarm: %3dC\n", value); + + rv = g781_get_temp(G781_LOCAL_TEMP_LOW_LIMIT_R, &value); + if (rv < 0) + return rv; + ccprintf(" Low Alarm: %3dC\n", value); + + rv = g781_get_temp(G781_TEMP_REMOTE, &value); + if (rv < 0) + return rv; + ccprintf("Remote Temp: %3dC\n", value); + + rv = g781_get_temp(G781_REMOTE_TEMP_THERM_LIMIT, &value); + if (rv < 0) + return rv; + ccprintf(" Therm Trip: %3dC\n", value); + + rv = g781_get_temp(G781_REMOTE_TEMP_HIGH_LIMIT_R, &value); + if (rv < 0) + return rv; + ccprintf(" High Alarm: %3dC\n", value); + + rv = g781_get_temp(G781_REMOTE_TEMP_LOW_LIMIT_R, &value); + if (rv < 0) + return rv; + ccprintf(" Low Alarm: %3dC\n", value); + + rv = g781_read8(G781_STATUS, &value); + if (rv < 0) + return rv; + ccprintf("\nSTATUS: %08b\n", value); + + rv = g781_read8(G781_CONFIGURATION_R, &value); + if (rv < 0) + return rv; + ccprintf("CONFIG: %08b\n", value); - /* Temperature from sensor is in degrees Celsius */ - *temp_ptr = C_TO_K(temp_raw); return EC_SUCCESS; } + +static int command_g781(int argc, char **argv) +{ + char *command; + char *e; + int data; + int offset; + int rv; + + if (!board_g781_has_power()) { + ccprintf("ERROR: Temp sensor not powered.\n"); + return EC_ERROR_NOT_POWERED; + } + + /* If no args just print status */ + if (argc == 1) + return g781_show_status(); + + if (argc < 3) + return EC_ERROR_PARAM_COUNT; + + command = argv[1]; + offset = strtoi(argv[2], &e, 0); + if (*e || offset < 0 || offset > 255) + return EC_ERROR_PARAM2; + + if (!strcasecmp(command, "getbyte")) { + rv = g781_read8(offset, &data); + if (rv < 0) + return rv; + ccprintf("Byte at offset 0x%02x is %08b\n", offset, data); + return rv; + } + + /* Remaining commands are of the form "g781 set-command offset data" */ + if (argc != 4) + return EC_ERROR_PARAM_COUNT; + + data = strtoi(argv[3], &e, 0); + if (*e) + return EC_ERROR_PARAM3; + + if (!strcasecmp(command, "settemp")) { + ccprintf("Setting 0x%02x to %dC\n", offset, data); + rv = g781_set_temp(offset, data); + } else if (!strcasecmp(command, "setbyte")) { + ccprintf("Setting 0x%02x to 0x%02x\n", offset, data); + rv = g781_write8(offset, data); + } else + return EC_ERROR_PARAM1; + + return rv; +} +DECLARE_CONSOLE_COMMAND(g781, command_g781, + "[settemp|setbyte ] or [getbyte ]. " + "Temps in Celsius.", + "Print g781 temp sensor status or set parameters.", NULL); diff --git a/include/temp_sensor_g781.h b/include/temp_sensor_g781.h index 2e5c428bc6..ce79cb0d05 100644 --- a/include/temp_sensor_g781.h +++ b/include/temp_sensor_g781.h @@ -11,13 +11,52 @@ #define G781_I2C_ADDR 0x98 /* 7-bit address is 0x4C */ /* Chip-specific commands */ -#define G781_TEMP_LOCAL 0x00 -#define G781_TEMP_REMOTE 0x01 +#define G781_TEMP_LOCAL 0x00 +#define G781_TEMP_REMOTE 0x01 +#define G781_STATUS 0x02 +#define G781_CONFIGURATION_R 0x03 +#define G781_CONVERSION_RATE_R 0x04 +#define G781_LOCAL_TEMP_HIGH_LIMIT_R 0x05 +#define G781_LOCAL_TEMP_LOW_LIMIT_R 0x06 +#define G781_REMOTE_TEMP_HIGH_LIMIT_R 0x07 +#define G781_REMOTE_TEMP_LOW_LIMIT_R 0x08 +#define G781_CONFIGURATION_W 0x09 +#define G781_CONVERSION_RATE_W 0x0a +#define G781_LOCAL_TEMP_HIGH_LIMIT_W 0x0b +#define G781_LOCAL_TEMP_LOW_LIMIT_W 0x0c +#define G781_REMOTE_TEMP_HIGH_LIMIT_W 0x0d +#define G781_REMOTE_TEMP_LOW_LIMIT_W 0x0e +#define G781_ONESHOT 0x0f +#define G781_REMOTE_TEMP_EXTENDED 0x10 +#define G781_REMOTE_TEMP_OFFSET_HIGH 0x11 +#define G781_REMOTE_TEMP_OFFSET_EXTD 0x12 +#define G781_REMOTE_T_HIGH_LIMIT_EXTD 0x13 +#define G781_REMOTE_T_LOW_LIMIT_EXTD 0x14 +#define G781_REMOTE_TEMP_THERM_LIMIT 0x19 +#define G781_LOCAL_TEMP_THERM_LIMIT 0x20 +#define G781_THERM_HYSTERESIS 0x21 +#define G781_ALERT_FAULT_QUEUE_CODE 0x22 +#define G781_MANUFACTURER_ID 0xFE +#define G781_DEVICE_ID 0xFF + +/* Config register bits */ +#define G781_CONFIGURATION_STANDBY (1 << 6) +#define G781_CONFIGURATION_ALERT_MASK (1 << 7) + +/* Status register bits */ +#define G781_STATUS_LOCAL_TEMP_THERM_ALARM (1 << 0) +#define G781_STATUS_REMOTE_TEMP_THERM_ALARM (1 << 1) +#define G781_STATUS_REMOTE_TEMP_FAULT (1 << 2) +#define G781_STATUS_REMOTE_TEMP_LOW_ALARM (1 << 3) +#define G781_STATUS_REMOTE_TEMP_HIGH_ALARM (1 << 4) +#define G781_STATUS_LOCAL_TEMP_LOW_ALARM (1 << 5) +#define G781_STATUS_LOCAL_TEMP_HIGH_ALARM (1 << 6) +#define G781_STATUS_BUSY (1 << 7) /** * Get the last polled value of a sensor. * - * @param idx Index to read. Idx indicates whether to read die + * @param idx Index to read. Idx indicates whether to read die * temperature or external temperature. * @param temp_ptr Destination for temperature in K. * -- cgit v1.2.1