drivers: sensor: tmp112: Add default device initialization
This allow to have a smaller driver footprint when a single configuration is required. Signed-off-by: Guillaume Lager <g.lager@innoseis.com>
This commit is contained in:
parent
cd207ca0bc
commit
4c986a266f
4 changed files with 134 additions and 57 deletions
|
@ -12,3 +12,17 @@ config TMP112
|
|||
|
||||
The TMP102 is compatible with the TMP112 but is less accurate and has
|
||||
been successfully tested with this driver.
|
||||
|
||||
config TMP112_FULL_SCALE_RUNTIME
|
||||
bool "Allow to set extended mode at runtime"
|
||||
default y
|
||||
help
|
||||
When set extended mode can be selected using tmp112_attr_set
|
||||
with SENSOR_ATTR_FULL_SCALE and value to set either 128 or 150
|
||||
|
||||
config TMP112_SAMPLING_FREQUENCY_RUNTIME
|
||||
bool "Allow to set conversion rate at runtime"
|
||||
default y
|
||||
help
|
||||
When set conversion rate can be set at runtime using sensor_attr_set
|
||||
with SENSOR_ATTR_SAMPLING_FREQUENCY
|
||||
|
|
|
@ -14,29 +14,10 @@
|
|||
#include <drivers/sensor.h>
|
||||
#include <sys/__assert.h>
|
||||
#include <logging/log.h>
|
||||
#include "tmp112.h"
|
||||
|
||||
LOG_MODULE_REGISTER(TMP112, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
|
||||
#define TMP112_REG_TEMPERATURE 0x00
|
||||
#define TMP112_D0_BIT BIT(0)
|
||||
|
||||
#define TMP112_REG_CONFIG 0x01
|
||||
#define TMP112_EM_BIT BIT(4)
|
||||
#define TMP112_CR0_BIT BIT(6)
|
||||
#define TMP112_CR1_BIT BIT(7)
|
||||
|
||||
/* scale in micro degrees Celsius */
|
||||
#define TMP112_TEMP_SCALE 62500
|
||||
|
||||
struct tmp112_data {
|
||||
int16_t sample;
|
||||
};
|
||||
|
||||
struct tmp112_config {
|
||||
struct i2c_dt_spec bus;
|
||||
};
|
||||
|
||||
static int tmp112_reg_read(const struct tmp112_config *cfg,
|
||||
uint8_t reg, uint16_t *val)
|
||||
{
|
||||
|
@ -59,20 +40,25 @@ static int tmp112_reg_write(const struct tmp112_config *cfg,
|
|||
return i2c_burst_write_dt(&cfg->bus, reg, (uint8_t *)&val_be, 2);
|
||||
}
|
||||
|
||||
static int tmp112_reg_update(const struct tmp112_config *cfg, uint8_t reg,
|
||||
uint16_t mask, uint16_t val)
|
||||
static uint16_t set_config_flags(struct tmp112_data *data, uint16_t mask,
|
||||
uint16_t value)
|
||||
{
|
||||
uint16_t old_val = 0U;
|
||||
uint16_t new_val;
|
||||
return (data->config_reg & ~mask) | (value & mask);
|
||||
}
|
||||
|
||||
if (tmp112_reg_read(cfg, reg, &old_val) < 0) {
|
||||
return -EIO;
|
||||
static int tmp112_update_config(const struct device *dev, uint16_t mask,
|
||||
uint16_t val)
|
||||
{
|
||||
int rc;
|
||||
struct tmp112_data *data = dev->data;
|
||||
const uint16_t new_val = set_config_flags(data, mask, val);
|
||||
|
||||
rc = tmp112_reg_write(dev->config, TMP112_REG_CONFIG, new_val);
|
||||
if (rc == 0) {
|
||||
data->config_reg = val;
|
||||
}
|
||||
|
||||
new_val = old_val & ~mask;
|
||||
new_val |= val & mask;
|
||||
|
||||
return tmp112_reg_write(cfg, reg, new_val);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int tmp112_attr_set(const struct device *dev,
|
||||
|
@ -80,7 +66,6 @@ static int tmp112_attr_set(const struct device *dev,
|
|||
enum sensor_attribute attr,
|
||||
const struct sensor_value *val)
|
||||
{
|
||||
const struct tmp112_config *cfg = dev->config;
|
||||
uint16_t value;
|
||||
uint16_t cr;
|
||||
|
||||
|
@ -89,26 +74,26 @@ static int tmp112_attr_set(const struct device *dev,
|
|||
}
|
||||
|
||||
switch (attr) {
|
||||
#if CONFIG_TMP112_FULL_SCALE_RUNTIME
|
||||
case SENSOR_ATTR_FULL_SCALE:
|
||||
/* the sensor supports two ranges -55 to 128 and -55 to 150 */
|
||||
/* the value contains the upper limit */
|
||||
if (val->val1 == 128) {
|
||||
value = 0x0000;
|
||||
} else if (val->val1 == 150) {
|
||||
value = TMP112_EM_BIT;
|
||||
value = TMP112_CONFIG_EM;
|
||||
} else {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (tmp112_reg_update(cfg, TMP112_REG_CONFIG,
|
||||
TMP112_EM_BIT, value) < 0) {
|
||||
if (tmp112_update_config(dev, TMP112_CONFIG_EM, value) < 0) {
|
||||
LOG_DBG("Failed to set attribute!");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
break;
|
||||
#endif
|
||||
case SENSOR_ATTR_SAMPLING_FREQUENCY:
|
||||
#if CONFIG_TMP112_SAMPLING_FREQUENCY_RUNTIME
|
||||
/* conversion rate in mHz */
|
||||
cr = val->val1 * 1000 + val->val2 / 1000;
|
||||
|
||||
|
@ -116,33 +101,32 @@ static int tmp112_attr_set(const struct device *dev,
|
|||
/* conversion rate */
|
||||
switch (cr) {
|
||||
case 250:
|
||||
value = 0x0000;
|
||||
value = TMP112_CONV_RATE(TMP112_CONV_RATE_025);
|
||||
break;
|
||||
|
||||
case 1000:
|
||||
value = TMP112_CR0_BIT;
|
||||
value = TMP112_CONV_RATE(TMP112_CONV_RATE_1000);
|
||||
break;
|
||||
|
||||
case 4000:
|
||||
value = TMP112_CR1_BIT;
|
||||
value = TMP112_CONV_RATE(TMP112_CONV_RATE_4);
|
||||
break;
|
||||
|
||||
case 8000:
|
||||
value = TMP112_CR0_BIT | TMP112_CR1_BIT;
|
||||
value = TMP112_CONV_RATE(TMP112_CONV_RATE_8);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (tmp112_reg_update(cfg, TMP112_REG_CONFIG,
|
||||
TMP112_CR0_BIT | TMP112_CR1_BIT,
|
||||
value) < 0) {
|
||||
if (tmp112_update_config(dev, TMP112_CONV_RATE_MASK, value) < 0) {
|
||||
LOG_DBG("Failed to set attribute!");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
|
@ -164,10 +148,12 @@ static int tmp112_sample_fetch(const struct device *dev,
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
if (val & TMP112_D0_BIT) {
|
||||
drv_data->sample = arithmetic_shift_right((int16_t)val, 3);
|
||||
if (val & TMP112_DATA_EXTENDED) {
|
||||
drv_data->sample = arithmetic_shift_right((int16_t)val,
|
||||
TMP112_DATA_EXTENDED_SHIFT);
|
||||
} else {
|
||||
drv_data->sample = arithmetic_shift_right((int16_t)val, 4);
|
||||
drv_data->sample = arithmetic_shift_right((int16_t)val,
|
||||
TMP112_DATA_NORMAL_SHIFT);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -200,22 +186,30 @@ static const struct sensor_driver_api tmp112_driver_api = {
|
|||
int tmp112_init(const struct device *dev)
|
||||
{
|
||||
const struct tmp112_config *cfg = dev->config;
|
||||
struct tmp112_data *data = dev->data;
|
||||
|
||||
if (!device_is_ready(cfg->bus.bus)) {
|
||||
LOG_ERR("I2C dev %s not ready", cfg->bus.bus->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
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);
|
||||
}
|
||||
|
||||
#define TMP112_INST(inst) \
|
||||
static struct tmp112_data tmp112_data_##inst; \
|
||||
static const struct tmp112_config tmp112_config_##inst = { \
|
||||
.bus = I2C_DT_SPEC_INST_GET(inst) \
|
||||
}; \
|
||||
DEVICE_DT_INST_DEFINE(inst, tmp112_init, NULL, &tmp112_data_##inst, \
|
||||
&tmp112_config_##inst, POST_KERNEL, \
|
||||
CONFIG_SENSOR_INIT_PRIORITY, &tmp112_driver_api);
|
||||
|
||||
#define TMP112_INST(inst) \
|
||||
static struct tmp112_data tmp112_data_##inst; \
|
||||
static const struct tmp112_config tmp112_config_##inst = { \
|
||||
.bus = I2C_DT_SPEC_INST_GET(inst), \
|
||||
.cr = DT_ENUM_IDX(DT_DRV_INST(inst), conversion_rate), \
|
||||
.extended_mode = DT_INST_PROP(inst, extended_mode), \
|
||||
}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(inst, tmp112_init, NULL, &tmp112_data_##inst, \
|
||||
&tmp112_config_##inst, POST_KERNEL, \
|
||||
CONFIG_SENSOR_INIT_PRIORITY, &tmp112_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(TMP112_INST)
|
||||
|
|
55
drivers/sensor/tmp112/tmp112.h
Normal file
55
drivers/sensor/tmp112/tmp112.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Innoseis BV
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_DRIVERS_SENSOR_TMP112_TMP112_H_
|
||||
#define ZEPHYR_DRIVERS_SENSOR_TMP112_TMP112_H_
|
||||
|
||||
#include <device.h>
|
||||
#include <sys/util.h>
|
||||
|
||||
#define TMP112_REG_TEMPERATURE 0x00
|
||||
#define TMP112_DATA_INVALID_BIT (BIT(1) | BIT(2))
|
||||
#define TMP112_DATA_EXTENDED (BIT(0))
|
||||
#define TMP112_DATA_EXTENDED_SHIFT 3
|
||||
#define TMP112_DATA_NORMAL_SHIFT 4
|
||||
|
||||
|
||||
#define TMP112_REG_CONFIG 0x01
|
||||
#define TMP112_CONFIG_EM BIT(4)
|
||||
|
||||
#define TMP112_ALERT_EN_BIT BIT(5)
|
||||
#define TMP112_CONV_RATE_SHIFT 6
|
||||
#define TMP112_CONV_RATE_MASK (BIT_MASK(2) << TMP112_CONV_RATE_SHIFT)
|
||||
#define TMP112_CONV_RATE_025 0
|
||||
#define TMP112_CONV_RATE_1000 1
|
||||
#define TMP112_CONV_RATE_4 2
|
||||
#define TMP112_CONV_RATE_8 3
|
||||
|
||||
#define TMP112_CONV_RATE(cr) ((cr) << TMP112_CONV_RATE_SHIFT)
|
||||
|
||||
#define TMP112_CONV_RES_SHIFT 13
|
||||
#define TMP112_CONV_RES_MASK (BIT_MASK(2) << TMP112_CONV_RES_SHIFT)
|
||||
|
||||
#define TMP112_ONE_SHOT BIT(15)
|
||||
|
||||
#define TMP112_REG_TLOW 0x02
|
||||
#define TMP112_REG_THIGH 0x03
|
||||
|
||||
/* scale in micro degrees Celsius */
|
||||
#define TMP112_TEMP_SCALE 62500
|
||||
|
||||
struct tmp112_data {
|
||||
int16_t sample;
|
||||
uint16_t config_reg;
|
||||
};
|
||||
|
||||
struct tmp112_config {
|
||||
const struct i2c_dt_spec bus;
|
||||
uint8_t cr;
|
||||
bool extended_mode : 1;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -8,3 +8,17 @@ description: |
|
|||
compatible: "ti,tmp112"
|
||||
|
||||
include: i2c-device.yaml
|
||||
|
||||
properties:
|
||||
conversion-rate:
|
||||
description: Conversion rate in mHz (milli-Hertz)
|
||||
type: int
|
||||
default: 4000
|
||||
enum:
|
||||
- 250
|
||||
- 1000
|
||||
- 4000
|
||||
- 8000
|
||||
extended-mode:
|
||||
description: When true use 13-bit data format allowing measuring temperature up to 128°C
|
||||
type: boolean
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue