diff options
author | Moritz Fischer <moritz.fischer@ettus.com> | 2018-09-11 09:34:27 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-09-13 18:59:05 -0700 |
commit | fbff15e3e7ad1cb87f973fa9ee52f8a9528dd96b (patch) | |
tree | 84575af865b07f84712b937ef7a614e5ae576190 /driver/temp_sensor | |
parent | 04c593b8175b7b73204b6ce800573d769d83cd7a (diff) | |
download | chrome-ec-fbff15e3e7ad1cb87f973fa9ee52f8a9528dd96b.tar.gz |
temp_sensor: Add (basic) support for TI TMP468 Temperature Sensor
Add (basic) support for TI TMP468 a 8 Remote + 1 Local channel
temperature sensor.
BUG=none
BRANCH=master
TEST=Hook up EVM to I2C port of a STM32F072, read temperatures
Change-Id: I6d6644825af04391841847c060f8ffaeff620094
Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
Reviewed-on: https://chromium-review.googlesource.com/1213554
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'driver/temp_sensor')
-rw-r--r-- | driver/temp_sensor/tmp468.c | 99 | ||||
-rw-r--r-- | driver/temp_sensor/tmp468.h | 126 |
2 files changed, 225 insertions, 0 deletions
diff --git a/driver/temp_sensor/tmp468.c b/driver/temp_sensor/tmp468.c new file mode 100644 index 0000000000..e1d34079f2 --- /dev/null +++ b/driver/temp_sensor/tmp468.c @@ -0,0 +1,99 @@ +/* Copyright (c) 2018 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. + */ + +/* TMP468 temperature sensor module for Chrome EC */ + +#include "common.h" +#include "console.h" +#include "tmp432.h" +#include "gpio.h" +#include "i2c.h" +#include "hooks.h" +#include "util.h" + +#include "tmp468.h" + + +static int fake_temp[TMP468_CHANNEL_COUNT] = {-1, -1, -1, -1, -1, -1, -1 , -1, -1}; +static int temp_val[TMP468_CHANNEL_COUNT] = {0, 0, 0, 0, 0, 0, 0 , 0, 0}; +static uint8_t is_sensor_shutdown; + +static int has_power(void) +{ + return !is_sensor_shutdown; +} + +static int raw_read16(const int offset, int *data_ptr) +{ + return i2c_read16(I2C_PORT_THERMAL, TMP468_I2C_ADDR, offset, data_ptr); +} + +static int raw_write16(const int offset, int data_ptr) +{ + return i2c_write16(I2C_PORT_THERMAL, TMP468_I2C_ADDR, offset, data_ptr); +} + +static int tmp468_shutdown(uint8_t want_shutdown) +{ + int ret, value; + + if (want_shutdown == is_sensor_shutdown) + return EC_SUCCESS; + + ret = raw_read16(TMP468_CONFIGURATION, &value); + if (ret < 0) { + ccprintf("ERROR: Temp sensor I2C read16 error.\n"); + return ret; + } + + if (want_shutdown) + value |= TMP468_SHUTDOWN; + else + value &= ~TMP468_SHUTDOWN; + + ret = raw_write16(TMP468_CONFIGURATION, value); + if (ret == EC_SUCCESS) + is_sensor_shutdown = want_shutdown; + + return EC_SUCCESS; +} + +int tmp468_get_val(int idx, int *temp_ptr) +{ + if(!has_power()) + return EC_ERROR_NOT_POWERED; + + if (idx < TMP468_CHANNEL_COUNT) { + *temp_ptr = C_TO_K(temp_val[idx]); + return EC_SUCCESS; + } + + return EC_ERROR_INVAL; +} + +static void temp_sensor_poll(void) +{ + int i, ret; + + if (!has_power()) + return; + + for (i = 0; i < TMP468_CHANNEL_COUNT; i++) + if (fake_temp[i] != -1) { + temp_val[i] = fake_temp[i]; + } else { + ret = raw_read16(TMP468_LOCAL + i, &temp_val[i]); + if (ret < 0) + return; + temp_val[i] >>= TMP468_SHIFT1; + } +} +DECLARE_HOOK(HOOK_SECOND, temp_sensor_poll, HOOK_PRIO_TEMP_SENSOR); + +int tmp468_set_power(enum tmp468_power_state power_on) +{ + uint8_t shutdown = (power_on == TMP468_POWER_OFF) ? 1 : 0; + return tmp468_shutdown(shutdown); +} diff --git a/driver/temp_sensor/tmp468.h b/driver/temp_sensor/tmp468.h new file mode 100644 index 0000000000..ec528d0dcc --- /dev/null +++ b/driver/temp_sensor/tmp468.h @@ -0,0 +1,126 @@ +/* Copyright (c) 2018 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. + */ + +/* TMP468 temperature sensor module for Chrome EC */ + +#ifndef __CROS_EC_TMP468_H +#define __CROS_EC_TMP468_H + +#define TMP468_I2C_ADDR (0x90 | I2C_FLAG_BIG_ENDIAN) +#define TMP468_SHIFT1 7 + +#define TMP468_LOCAL 0x00 +#define TMP468_REMOTE1 0x01 +#define TMP468_REMOTE2 0x02 +#define TMP468_REMOTE3 0x03 +#define TMP468_REMOTE4 0x04 +#define TMP468_REMOTE5 0x05 +#define TMP468_REMOTE6 0x06 +#define TMP468_REMOTE7 0x07 +#define TMP468_REMOTE8 0x08 + +#define TMP468_SRST 0x20 +#define TMP468_THERM 0x21 +#define TMP468_THERM2 0x22 +#define TMP468_ROPEN 0x23 + +#define TMP468_CONFIGURATION 0x30 +#define TMP468_THERM_HYST 0x38 + +#define TMP468_LOCAL_LOW_LIMIT 0x39 +#define TMP468_LOCAL_HIGH_LIMT 0x3a + +#define TMP468_REMOTE1_OFFSET 0x40 +#define TMP468_REMOTE1_NFACTOR 0x41 +#define TMP468_REMOTE1_LOW_LIMIT 0x41 +#define TMP468_REMOTE1_HIGH_LIMIT 0x42 + +#define TMP468_REMOTE2_OFFSET 0x48 +#define TMP468_REMOTE2_NFACTOR 0x49 +#define TMP468_REMOTE2_LOW_LIMIT 0x4a +#define TMP468_REMOTE2_HIGH_LIMIT 0x4b + +#define TMP468_REMOTE3_OFFSET 0x50 +#define TMP468_REMOTE3_NFACTOR 0x51 +#define TMP468_REMOTE3_LOW_LIMIT 0x52 +#define TMP468_REMOTE3_HIGH_LIMIT 0x53 + +#define TMP468_REMOTE4_OFFSET 0x58 +#define TMP468_REMOTE4_NFACTOR 0x59 +#define TMP468_REMOTE4_LOW_LIMIT 0x59 +#define TMP468_REMOTE4_HIGH_LIMIT 0x5a + +#define TMP468_REMOTE5_OFFSET 0x60 +#define TMP468_REMOTE5_NFACTOR 0x61 +#define TMP468_REMOTE5_LOW_LIMIT 0x62 +#define TMP468_REMOTE5_HIGH_LIMIT 0x63 + +#define TMP468_REMOTE6_OFFSET 0x68 +#define TMP468_REMOTE6_NFACTOR 0x69 +#define TMP468_REMOTE6_LOW_LIMIT 0x6a +#define TMP468_REMOTE6_HIGH_LIMIT 0x6b + +#define TMP468_REMOTE7_OFFSET 0x70 +#define TMP468_REMOTE7_NFACTOR 0x71 +#define TMP468_REMOTE7_LOW_LIMIT 0x72 +#define TMP468_REMOTE7_HIGH_LIMIT 0x73 + +#define TMP468_REMOTE8_OFFSET 0x78 +#define TMP468_REMOTE8_NFACTOR 0x79 +#define TMP468_REMOTE8_LOW_LIMIT 0x7a +#define TMP468_REMOTE8_HIGH_LIMIT 0x7b + +#define TMP468_LOCK 0xc4 + +#define TMP468_DEVICE_ID 0xfd +#define TMP468_MANUFACTURER_ID 0xfe + +#define TMP468_SHUTDOWN (1 << 5) + +enum tmp468_channel_id { + TMP468_CHANNEL_LOCAL, + + TMP468_CHANNEL_REMOTE1, + TMP468_CHANNEL_REMOTE2, + TMP468_CHANNEL_REMOTE3, + TMP468_CHANNEL_REMOTE4, + TMP468_CHANNEL_REMOTE5, + TMP468_CHANNEL_REMOTE6, + TMP468_CHANNEL_REMOTE7, + TMP468_CHANNEL_REMOTE8, + + TMP468_CHANNEL_COUNT +}; + +enum tmp468_power_state { + TMP468_POWER_OFF = 0, + TMP468_POWER_ON, + + TMP468_POWER_COUNT +}; + + +/** + * Get the last polled value of a sensor. + * + * @param idx Index to read. Idx indicates whether to read die + * temperature or external temperature. + * @param temp_ptr Destination for temperature in K. + * + * @return EC_SUCCESS if successful, non-zero if error. + */ +int tmp468_get_val(int idx, int *temp_ptr); + +/** + * Power control function of tmp432 temperature sensor. + * + * @param power_on TMP468_POWER_ON: turn tmp468 sensor on. + * TMP468_POWER_OFF: shut tmp468 sensor down. + * + * @return EC_SUCCESS if successful, non-zero if error. + */ +int tmp468_set_power(enum tmp468_power_state power_on); + +#endif /* __CROS_EC_TMP468_H */ |