Skip to content

Commit

Permalink
drivers: sensor: tmp112: Add default device initialization
Browse files Browse the repository at this point in the history
This allow to have a smaller driver footprint when a single
configuration is required.

Signed-off-by: Guillaume Lager <g.lager@innoseis.com>
  • Loading branch information
kurddt authored and carlescufi committed Nov 23, 2021
1 parent cd207ca commit 4c986a2
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 57 deletions.
14 changes: 14 additions & 0 deletions drivers/sensor/tmp112/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
108 changes: 51 additions & 57 deletions drivers/sensor/tmp112/tmp112.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -59,28 +40,32 @@ 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);

new_val = old_val & ~mask;
new_val |= val & mask;
rc = tmp112_reg_write(dev->config, TMP112_REG_CONFIG, new_val);
if (rc == 0) {
data->config_reg = val;
}

return tmp112_reg_write(cfg, reg, new_val);
return rc;
}

static int tmp112_attr_set(const struct device *dev,
enum sensor_channel chan,
enum sensor_attribute attr,
const struct sensor_value *val)
{
const struct tmp112_config *cfg = dev->config;
uint16_t value;
uint16_t cr;

Expand All @@ -89,60 +74,59 @@ 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;

/* the sensor supports 0.25Hz, 1Hz, 4Hz and 8Hz */
/* 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;
Expand All @@ -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;
Expand Down Expand Up @@ -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 changes: 55 additions & 0 deletions drivers/sensor/tmp112/tmp112.h
Original file line number Diff line number Diff line change
@@ -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
14 changes: 14 additions & 0 deletions dts/bindings/sensor/ti,tmp112.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 4c986a2

Please sign in to comment.