sensor: eeprom: Add TMP116 EEPROM access
eeprom access is supported by using either custom or eeprom API Signed-off-by: Guillaume Lager <g.lager@innoseis.com>
This commit is contained in:
parent
918f0aac19
commit
972e5d0274
9 changed files with 209 additions and 1 deletions
|
@ -10,3 +10,4 @@ zephyr_library_sources_ifdef(CONFIG_EEPROM_LPC11U6X eeprom_lpc11u6x.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_EEPROM_STM32 eeprom_stm32.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_EEPROM_SIMULATOR eeprom_simulator.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_EEPROM_EMULATOR eeprom_emulator.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_EEPROM_TMP116 eeprom_tmp116.c)
|
||||
|
|
|
@ -58,6 +58,7 @@ config EEPROM_AT25
|
|||
source "drivers/eeprom/Kconfig.lpc11u6x"
|
||||
source "drivers/eeprom/Kconfig.stm32"
|
||||
source "drivers/eeprom/Kconfig.eeprom_emu"
|
||||
source "drivers/eeprom/Kconfig.tmp116"
|
||||
|
||||
config EEPROM_SIMULATOR
|
||||
bool "Simulated EEPROM driver"
|
||||
|
|
10
drivers/eeprom/Kconfig.tmp116
Normal file
10
drivers/eeprom/Kconfig.tmp116
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Copyright (c) 2021 Innoseis B.V.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config EEPROM_TMP116
|
||||
bool "TMP116 EEPROM driver"
|
||||
depends on TMP116
|
||||
default y
|
||||
help
|
||||
Enable support for the on-chip EEPROM found on
|
||||
Texas instrument TMP116 temperature sensor
|
68
drivers/eeprom/eeprom_tmp116.c
Normal file
68
drivers/eeprom/eeprom_tmp116.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Innoseis B.V
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <devicetree.h>
|
||||
#include <drivers/eeprom.h>
|
||||
#include <drivers/sensor/tmp116.h>
|
||||
|
||||
#define DT_DRV_COMPAT ti_tmp116_eeprom
|
||||
|
||||
struct eeprom_tmp116_config {
|
||||
const struct device *parent;
|
||||
};
|
||||
|
||||
BUILD_ASSERT(CONFIG_EEPROM_INIT_PRIORITY >
|
||||
CONFIG_SENSOR_INIT_PRIORITY,
|
||||
"TMP116 eeprom driver must be initialized after TMP116 sensor "
|
||||
"driver");
|
||||
|
||||
static size_t eeprom_tmp116_size(const struct device *dev)
|
||||
{
|
||||
return EEPROM_TMP116_SIZE;
|
||||
}
|
||||
|
||||
static int eeprom_tmp116_write(const struct device *dev, off_t offset,
|
||||
const void *data, size_t len)
|
||||
{
|
||||
const struct eeprom_tmp116_config *config = dev->config;
|
||||
|
||||
return tmp116_eeprom_write(config->parent, offset, data, len);
|
||||
}
|
||||
|
||||
static int eeprom_tmp116_read(const struct device *dev, off_t offset, void *data,
|
||||
size_t len)
|
||||
{
|
||||
const struct eeprom_tmp116_config *config = dev->config;
|
||||
|
||||
return tmp116_eeprom_read(config->parent, offset, data, len);
|
||||
}
|
||||
|
||||
static int eeprom_tmp116_init(const struct device *dev)
|
||||
{
|
||||
const struct eeprom_tmp116_config *config = dev->config;
|
||||
|
||||
if (!device_is_ready(config->parent)) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct eeprom_driver_api eeprom_tmp116_api = {
|
||||
.read = eeprom_tmp116_read,
|
||||
.write = eeprom_tmp116_write,
|
||||
.size = eeprom_tmp116_size,
|
||||
};
|
||||
|
||||
#define DEFINE_TMP116(_num) \
|
||||
static const struct eeprom_tmp116_config eeprom_tmp116_config##_num = { \
|
||||
.parent = DEVICE_DT_GET(DT_INST_BUS(_num)) \
|
||||
}; \
|
||||
DEVICE_DT_INST_DEFINE(_num, eeprom_tmp116_init, NULL, \
|
||||
NULL, &eeprom_tmp116_config##_num, POST_KERNEL, \
|
||||
CONFIG_EEPROM_INIT_PRIORITY, &eeprom_tmp116_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(DEFINE_TMP116);
|
|
@ -9,6 +9,7 @@
|
|||
#include <device.h>
|
||||
#include <drivers/i2c.h>
|
||||
#include <drivers/sensor.h>
|
||||
#include <drivers/sensor/tmp116.h>
|
||||
#include <sys/util.h>
|
||||
#include <sys/byteorder.h>
|
||||
#include <sys/__assert.h>
|
||||
|
@ -17,6 +18,10 @@
|
|||
|
||||
#include "tmp116.h"
|
||||
|
||||
#define EEPROM_SIZE_REG sizeof(uint16_t)
|
||||
#define EEPROM_TMP117_RESERVED (2 * sizeof(uint16_t))
|
||||
#define EEPROM_MIN_BUSY_MS 7
|
||||
|
||||
LOG_MODULE_REGISTER(TMP116, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
static int tmp116_reg_read(const struct device *dev, uint8_t reg,
|
||||
|
@ -43,6 +48,94 @@ static int tmp116_reg_write(const struct device *dev, uint8_t reg,
|
|||
return i2c_write_dt(&cfg->bus, tx_buf, sizeof(tx_buf));
|
||||
}
|
||||
|
||||
static bool check_eeprom_bounds(const struct device *dev, off_t offset,
|
||||
size_t len)
|
||||
{
|
||||
struct tmp116_data *drv_data = dev->data;
|
||||
|
||||
if ((offset + len) > EEPROM_TMP116_SIZE ||
|
||||
offset % EEPROM_SIZE_REG != 0 ||
|
||||
len % EEPROM_SIZE_REG != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* TMP117 uses EEPROM[2] as temperature offset register */
|
||||
if (drv_data->id == TMP117_DEVICE_ID &&
|
||||
offset <= EEPROM_TMP117_RESERVED &&
|
||||
(offset + len) > EEPROM_TMP117_RESERVED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int tmp116_eeprom_write(const struct device *dev, off_t offset,
|
||||
const void *data, size_t len)
|
||||
{
|
||||
uint8_t reg;
|
||||
const uint16_t *src = data;
|
||||
int res;
|
||||
|
||||
if (!check_eeprom_bounds(dev, offset, len)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
res = tmp116_reg_write(dev, TMP116_REG_EEPROM_UL, TMP116_EEPROM_UL_UNLOCK);
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
|
||||
for (reg = (offset / 2); reg < offset / 2 + len / 2; reg++) {
|
||||
uint16_t val = *src;
|
||||
|
||||
res = tmp116_reg_write(dev, reg + TMP116_REG_EEPROM1, val);
|
||||
if (res != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
k_sleep(K_MSEC(EEPROM_MIN_BUSY_MS));
|
||||
|
||||
do {
|
||||
res = tmp116_reg_read(dev, TMP116_REG_EEPROM_UL, &val);
|
||||
if (res != 0) {
|
||||
break;
|
||||
}
|
||||
} while (val & TMP116_EEPROM_UL_BUSY);
|
||||
src++;
|
||||
|
||||
if (res != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
res = tmp116_reg_write(dev, TMP116_REG_EEPROM_UL, 0);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int tmp116_eeprom_read(const struct device *dev, off_t offset, void *data,
|
||||
size_t len)
|
||||
{
|
||||
uint8_t reg;
|
||||
uint16_t *dst = data;
|
||||
int res = 0;
|
||||
|
||||
if (!check_eeprom_bounds(dev, offset, len)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (reg = (offset / 2); reg < offset / 2 + len / 2; reg++) {
|
||||
res = tmp116_reg_read(dev, reg + TMP116_REG_EEPROM1, dst);
|
||||
if (res != 0) {
|
||||
break;
|
||||
}
|
||||
dst++;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Check the Device ID
|
||||
*
|
||||
|
|
|
@ -25,7 +25,9 @@
|
|||
#define TMP116_DEVICE_ID 0x1116
|
||||
#define TMP117_DEVICE_ID 0x0117
|
||||
|
||||
#define TMP116_CFGR_DATA_READY BIT(13)
|
||||
#define TMP116_CFGR_DATA_READY BIT(13)
|
||||
#define TMP116_EEPROM_UL_UNLOCK BIT(15)
|
||||
#define TMP116_EEPROM_UL_BUSY BIT(14)
|
||||
|
||||
struct tmp116_data {
|
||||
uint16_t sample;
|
||||
|
|
10
dts/bindings/mtd/ti,tmp116-eeprom.yaml
Normal file
10
dts/bindings/mtd/ti,tmp116-eeprom.yaml
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Copyright (c) 2020 Innoseis B.V
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: TI TMP116 EEPROM controller binding
|
||||
|
||||
compatible: "ti,tmp116-eeprom"
|
||||
|
||||
include: eeprom-base.yaml
|
||||
|
||||
on-bus: tmp116
|
|
@ -5,4 +5,6 @@ description: Texas Instruments TMP116 temperature sensor
|
|||
|
||||
compatible: "ti,tmp116"
|
||||
|
||||
bus: tmp116
|
||||
|
||||
include: i2c-device.yaml
|
||||
|
|
21
include/drivers/sensor/tmp116.h
Normal file
21
include/drivers/sensor/tmp116.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Innoseis B.V
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_TMP116_H_
|
||||
#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_TMP116_H_
|
||||
|
||||
#include <device.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define EEPROM_TMP116_SIZE (4 * sizeof(uint16_t))
|
||||
|
||||
int tmp116_eeprom_read(const struct device *dev, off_t offset, void *data,
|
||||
size_t len);
|
||||
|
||||
int tmp116_eeprom_write(const struct device *dev, off_t offset,
|
||||
const void *data, size_t len);
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_TMP116_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue