From be25e34a7c4c410e70d95c2c8d1a0107de483136 Mon Sep 17 00:00:00 2001 From: Fredrik Gihl Date: Wed, 24 Apr 2024 21:40:44 +0200 Subject: [PATCH] drivers: sensor: Add TI TMP114 temperature sensors Add device driver for TI TMP114 I2C temperature sensor. The driver only support basic functionality, i.e. fetch temperature using default values. Datasheet: https://www.ti.com/lit/ds/symlink/tmp114.pdf Signed-off-by: Fredrik Gihl --- doc/releases/release-notes-3.7.rst | 2 + drivers/sensor/ti/CMakeLists.txt | 1 + drivers/sensor/ti/Kconfig | 1 + drivers/sensor/ti/tmp114/CMakeLists.txt | 5 + drivers/sensor/ti/tmp114/Kconfig | 12 ++ drivers/sensor/ti/tmp114/tmp114.c | 196 ++++++++++++++++++++++++ dts/bindings/sensor/ti,tmp114.yaml | 8 + tests/drivers/build_all/sensor/i2c.dtsi | 5 + 8 files changed, 230 insertions(+) create mode 100644 drivers/sensor/ti/tmp114/CMakeLists.txt create mode 100644 drivers/sensor/ti/tmp114/Kconfig create mode 100644 drivers/sensor/ti/tmp114/tmp114.c create mode 100644 dts/bindings/sensor/ti,tmp114.yaml diff --git a/doc/releases/release-notes-3.7.rst b/doc/releases/release-notes-3.7.rst index 5328fec40e..adbd2071b7 100644 --- a/doc/releases/release-notes-3.7.rst +++ b/doc/releases/release-notes-3.7.rst @@ -214,6 +214,8 @@ Drivers and Sensors * Sensor + * Added TMP114 driver + * Serial * Added driver to support UART over Bluetooth LE using NUS (Nordic UART Service). This driver diff --git a/drivers/sensor/ti/CMakeLists.txt b/drivers/sensor/ti/CMakeLists.txt index 39c7af3042..6fae283ad4 100644 --- a/drivers/sensor/ti/CMakeLists.txt +++ b/drivers/sensor/ti/CMakeLists.txt @@ -15,5 +15,6 @@ add_subdirectory_ifdef(CONFIG_TMAG5273 tmag5273) add_subdirectory_ifdef(CONFIG_TMP007 tmp007) add_subdirectory_ifdef(CONFIG_TMP108 tmp108) add_subdirectory_ifdef(CONFIG_TMP112 tmp112) +add_subdirectory_ifdef(CONFIG_TMP114 tmp114) add_subdirectory_ifdef(CONFIG_TMP116 tmp116) # zephyr-keep-sorted-stop diff --git a/drivers/sensor/ti/Kconfig b/drivers/sensor/ti/Kconfig index 713c8f2f09..d3b5569815 100644 --- a/drivers/sensor/ti/Kconfig +++ b/drivers/sensor/ti/Kconfig @@ -15,5 +15,6 @@ source "drivers/sensor/ti/tmag5273/Kconfig" source "drivers/sensor/ti/tmp007/Kconfig" source "drivers/sensor/ti/tmp108/Kconfig" source "drivers/sensor/ti/tmp112/Kconfig" +source "drivers/sensor/ti/tmp114/Kconfig" source "drivers/sensor/ti/tmp116/Kconfig" # zephyr-keep-sorted-stop diff --git a/drivers/sensor/ti/tmp114/CMakeLists.txt b/drivers/sensor/ti/tmp114/CMakeLists.txt new file mode 100644 index 0000000000..c15a1091d2 --- /dev/null +++ b/drivers/sensor/ti/tmp114/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(tmp114.c) diff --git a/drivers/sensor/ti/tmp114/Kconfig b/drivers/sensor/ti/tmp114/Kconfig new file mode 100644 index 0000000000..eb532e2f55 --- /dev/null +++ b/drivers/sensor/ti/tmp114/Kconfig @@ -0,0 +1,12 @@ +# TMP114 temperature sensor configuration options + +# Copyright (c) 2024 Fredrik Gihl +# SPDX-License-Identifier: Apache-2.0 + +config TMP114 + bool "TMP114 Temperature Sensor" + default y + depends on DT_HAS_TI_TMP114_ENABLED + select I2C + help + Enable driver for TMP114 temperature sensors. diff --git a/drivers/sensor/ti/tmp114/tmp114.c b/drivers/sensor/ti/tmp114/tmp114.c new file mode 100644 index 0000000000..747a825057 --- /dev/null +++ b/drivers/sensor/ti/tmp114/tmp114.c @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2024 Fredrik Gihl + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_tmp114 + +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(TMP114, CONFIG_SENSOR_LOG_LEVEL); + +#define TMP114_REG_TEMP 0x0 +#define TMP114_REG_ALERT 0x2 +#define TMP114_REG_CFGR 0x3 +#define TMP114_REG_DEVICE_ID 0xb + +#define TMP114_RESOLUTION 78125 /* in tens of uCelsius*/ +#define TMP114_RESOLUTION_DIV 10000000 + +#define TMP114_DEVICE_ID 0x1114 + +#define TMP114_ALERT_DATA_READY BIT(0) + +struct tmp114_data { + uint16_t sample; + uint16_t id; +}; + +struct tmp114_dev_config { + struct i2c_dt_spec bus; +}; + +static int tmp114_reg_read(const struct device *dev, uint8_t reg, + uint16_t *val) +{ + const struct tmp114_dev_config *cfg = dev->config; + + if (i2c_burst_read_dt(&cfg->bus, reg, (uint8_t *)val, 2) + < 0) { + return -EIO; + } + + *val = sys_be16_to_cpu(*val); + + return 0; +} + +static inline int tmp114_device_id_check(const struct device *dev, uint16_t *id) +{ + if (tmp114_reg_read(dev, TMP114_REG_DEVICE_ID, id) != 0) { + LOG_ERR("%s: Failed to get Device ID register!", dev->name); + return -EIO; + } + + if (*id != TMP114_DEVICE_ID) { + LOG_ERR("%s: Failed to match the device ID!", dev->name); + return -EINVAL; + } + + return 0; +} + +static int tmp114_sample_fetch(const struct device *dev, + enum sensor_channel chan) +{ + struct tmp114_data *drv_data = dev->data; + uint16_t value; + uint16_t cfg_reg = 0; + int rc; + + __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL || + chan == SENSOR_CHAN_AMBIENT_TEMP); + + /* clear sensor values */ + drv_data->sample = 0U; + + /* Check alert register to make sure that a data is available */ + rc = tmp114_reg_read(dev, TMP114_REG_ALERT, &cfg_reg); + if (rc < 0) { + LOG_ERR("%s, Failed to read from CFGR register", dev->name); + return rc; + } + + if ((cfg_reg & TMP114_ALERT_DATA_READY) == 0) { + LOG_DBG("%s: no data ready", dev->name); + return -EBUSY; + } + + /* Get the most recent temperature measurement */ + rc = tmp114_reg_read(dev, TMP114_REG_TEMP, &value); + if (rc < 0) { + LOG_ERR("%s: Failed to read from TEMP register!", dev->name); + return rc; + } + + /* store measurements to the driver */ + drv_data->sample = (int16_t)value; + + return 0; +} + +static int tmp114_channel_get(const struct device *dev, + enum sensor_channel chan, + struct sensor_value *val) +{ + struct tmp114_data *drv_data = dev->data; + int32_t tmp; + + if (chan != SENSOR_CHAN_AMBIENT_TEMP) { + return -ENOTSUP; + } + + /* + * See datasheet for tmp114, section 'Temp_Result Register' section + * for more details on processing sample data. + */ + tmp = ((int16_t)drv_data->sample * (int32_t)TMP114_RESOLUTION) / 10; + val->val1 = tmp / 1000000; /* uCelsius */ + val->val2 = tmp % 1000000; + + return 0; +} + +static int tmp114_attr_get(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, struct sensor_value *val) +{ + uint16_t data; + int rc; + + if (chan != SENSOR_CHAN_AMBIENT_TEMP) { + return -ENOTSUP; + } + + switch (attr) { + case SENSOR_ATTR_CONFIGURATION: + rc = tmp114_reg_read(dev, TMP114_REG_CFGR, &data); + if (rc < 0) { + return rc; + } + break; + default: + return -ENOTSUP; + } + + val->val1 = data; + val->val2 = 0; + + return 0; +} + +static const struct sensor_driver_api tmp114_driver_api = { + .attr_get = tmp114_attr_get, + .sample_fetch = tmp114_sample_fetch, + .channel_get = tmp114_channel_get +}; + +static int tmp114_init(const struct device *dev) +{ + struct tmp114_data *drv_data = dev->data; + const struct tmp114_dev_config *cfg = dev->config; + int rc; + uint16_t id; + + if (!i2c_is_ready_dt(&cfg->bus)) { + LOG_ERR("I2C dev %s not ready", cfg->bus.bus->name); + return -EINVAL; + } + + /* Check the Device ID */ + rc = tmp114_device_id_check(dev, &id); + if (rc < 0) { + return rc; + } + LOG_INF("Got device ID: %x", id); + drv_data->id = id; + + return 0; +} + +#define DEFINE_TMP114(_num) \ + static struct tmp114_data tmp114_data_##_num; \ + static const struct tmp114_dev_config tmp114_config_##_num = { \ + .bus = I2C_DT_SPEC_INST_GET(_num) \ + }; \ + SENSOR_DEVICE_DT_INST_DEFINE(_num, tmp114_init, NULL, \ + &tmp114_data_##_num, &tmp114_config_##_num, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &tmp114_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(DEFINE_TMP114) diff --git a/dts/bindings/sensor/ti,tmp114.yaml b/dts/bindings/sensor/ti,tmp114.yaml new file mode 100644 index 0000000000..494df18109 --- /dev/null +++ b/dts/bindings/sensor/ti,tmp114.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Fredrik Gihl +# SPDX-License-Identifier: Apache-2.0 + +description: Texas Instruments TMP114 temperature sensor + +compatible: "ti,tmp114" + +include: [sensor-device.yaml, i2c-device.yaml] diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index ffc1142566..eb5a0e9737 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -1036,3 +1036,8 @@ test_i2c_nct75: test_i2c_nct75@8b { reg = <0x8b>; status = "okay"; }; + +test_i2c_tmp114: tmp114@8c { + compatible = "ti,tmp114"; + reg = <0x8c>; +};