From 3aebc9d258e70dbde3b193e990eb27b204b4ff1c Mon Sep 17 00:00:00 2001 From: Corey Wharton Date: Wed, 26 Mar 2025 19:47:17 -0700 Subject: [PATCH] drivers: sensor: tmp112: add support for setting ALERT thresholds Allows setting tLow/tHigh threasholds via the SENSOR_ATTR_LOWER_THRESH/ SENSOR_ATTR_UPPER_THRESH attributes. Signed-off-by: Corey Wharton --- drivers/sensor/ti/tmp112/tmp112.c | 62 ++++++++++++++++++++++++++---- drivers/sensor/ti/tmp112/tmp112.h | 12 ++++++ dts/bindings/sensor/ti,tmp112.yaml | 17 +++++++- 3 files changed, 82 insertions(+), 9 deletions(-) diff --git a/drivers/sensor/ti/tmp112/tmp112.c b/drivers/sensor/ti/tmp112/tmp112.c index 056fe46ede7..0de33b4cdde 100644 --- a/drivers/sensor/ti/tmp112/tmp112.c +++ b/drivers/sensor/ti/tmp112/tmp112.c @@ -58,6 +58,29 @@ static int tmp112_update_config(const struct device *dev, uint16_t mask, uint16_ return rc; } +static int tmp112_set_threshold(const struct device *dev, uint8_t reg, int64_t micro_c) +{ + struct tmp112_data *drv_data = dev->data; + int64_t v; + uint16_t reg_value; + + v = DIV_ROUND_CLOSEST(micro_c, TMP112_TEMP_SCALE); + + if (drv_data->config_reg & TMP112_CONFIG_EM) { + if (!IN_RANGE(v, TMP112_TEMP_MIN_EM, TMP112_TEMP_MAX_EM)) { + return -EINVAL; + } + reg_value = (uint16_t)v << TMP112_DATA_EXTENDED_SHIFT; + } else { + if (!IN_RANGE(v, TMP112_TEMP_MIN, TMP112_TEMP_MAX)) { + return -EINVAL; + } + reg_value = (uint16_t)v << TMP112_DATA_NORMAL_SHIFT; + } + + return tmp112_reg_write(dev->config, reg, reg_value); +} + static int tmp112_attr_set(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr, const struct sensor_value *val) { @@ -87,8 +110,9 @@ static int tmp112_attr_set(const struct device *dev, enum sensor_channel chan, } break; #endif - case SENSOR_ATTR_SAMPLING_FREQUENCY: + #if CONFIG_TMP112_SAMPLING_FREQUENCY_RUNTIME + case SENSOR_ATTR_SAMPLING_FREQUENCY: /* conversion rate in mHz */ cr = val->val1 * 1000 + val->val2 / 1000; @@ -123,6 +147,12 @@ static int tmp112_attr_set(const struct device *dev, enum sensor_channel chan, break; #endif + case SENSOR_ATTR_LOWER_THRESH: + return tmp112_set_threshold(dev, TMP112_REG_TLOW, sensor_value_to_micro(val)); + + case SENSOR_ATTR_UPPER_THRESH: + return tmp112_set_threshold(dev, TMP112_REG_THIGH, sensor_value_to_micro(val)); + default: return -ENOTSUP; } @@ -155,17 +185,12 @@ static int tmp112_channel_get(const struct device *dev, enum sensor_channel chan struct sensor_value *val) { struct tmp112_data *drv_data = dev->data; - int32_t uval; if (chan != SENSOR_CHAN_AMBIENT_TEMP) { return -ENOTSUP; } - uval = (int32_t)drv_data->sample * TMP112_TEMP_SCALE; - val->val1 = uval / 1000000; - val->val2 = uval % 1000000; - - return 0; + return sensor_value_from_micro(val, (int32_t)drv_data->sample * TMP112_TEMP_SCALE); } static DEVICE_API(sensor, tmp112_driver_api) = { @@ -178,6 +203,7 @@ int tmp112_init(const struct device *dev) { const struct tmp112_config *cfg = dev->config; struct tmp112_data *data = dev->data; + int ret; if (!device_is_ready(cfg->bus.bus)) { LOG_ERR("I2C dev %s not ready", cfg->bus.bus->name); @@ -187,7 +213,25 @@ int tmp112_init(const struct device *dev) data->config_reg = TMP112_CONV_RATE(cfg->cr) | TMP112_CONV_RES_MASK | (cfg->extended_mode ? TMP112_CONFIG_EM : 0); - return tmp112_update_config(dev, 0, 0); + ret = tmp112_update_config(dev, 0, 0); + if (ret) { + LOG_ERR("Failed to set configuration (%d)", ret); + return ret; + } + + ret = tmp112_set_threshold(dev, TMP112_REG_TLOW, cfg->t_low_micro_c); + if (ret) { + LOG_ERR("Failed to set tLow threshold (%d)", ret); + return ret; + } + + ret = tmp112_set_threshold(dev, TMP112_REG_THIGH, cfg->t_high_micro_c); + if (ret) { + LOG_ERR("Failed to set tHigh threshold (%d)", ret); + return ret; + } + + return 0; } #define TMP112_INST(inst) \ @@ -195,6 +239,8 @@ int tmp112_init(const struct device *dev) static const struct tmp112_config tmp112_config_##inst = { \ .bus = I2C_DT_SPEC_INST_GET(inst), \ .cr = DT_INST_ENUM_IDX(inst, conversion_rate), \ + .t_low_micro_c = DT_INST_PROP(inst, t_low_micro_c), \ + .t_high_micro_c = DT_INST_PROP(inst, t_high_micro_c), \ .extended_mode = DT_INST_PROP(inst, extended_mode), \ }; \ \ diff --git a/drivers/sensor/ti/tmp112/tmp112.h b/drivers/sensor/ti/tmp112/tmp112.h index 6f2b3f7b32b..6ea1258115b 100644 --- a/drivers/sensor/ti/tmp112/tmp112.h +++ b/drivers/sensor/ti/tmp112/tmp112.h @@ -41,6 +41,16 @@ /* scale in micro degrees Celsius */ #define TMP112_TEMP_SCALE 62500 +/* RAW min/max temperature values - LSB=TMP112_TEMP_SCALE */ +/* 128C */ +#define TMP112_TEMP_MAX 2047 +/* -55C */ +#define TMP112_TEMP_MIN -880 +/* 150C */ +#define TMP112_TEMP_MAX_EM 2400 +/* -55C */ +#define TMP112_TEMP_MIN_EM TMP112_TEMP_MIN + struct tmp112_data { int16_t sample; uint16_t config_reg; @@ -49,6 +59,8 @@ struct tmp112_data { struct tmp112_config { const struct i2c_dt_spec bus; uint8_t cr; + int32_t t_low_micro_c; + int32_t t_high_micro_c; bool extended_mode : 1; }; diff --git a/dts/bindings/sensor/ti,tmp112.yaml b/dts/bindings/sensor/ti,tmp112.yaml index 8708dbd39eb..36346e6c234 100644 --- a/dts/bindings/sensor/ti,tmp112.yaml +++ b/dts/bindings/sensor/ti,tmp112.yaml @@ -19,6 +19,21 @@ properties: - 1000 - 4000 - 8000 + extended-mode: - description: When true use 13-bit data format allowing measuring temperature up to 128°C + description: When true use 13-bit data format allowing measuring temperature up to 150°C type: boolean + + t-low-micro-c: + description: | + Sets the default tLow threshold in micro-Celsius. The default value is the chip reset + value. + type: int + default: 75000000 + + t-high-micro-c: + description: | + Sets the default tHigh threshold in micro-Celsius. The default value is the chip reset + value. + type: int + default: 85000000