drivers: sensor: lsm6dsl: make the driver multi-instance
Make this driver multi-instance and use the new API. Fixes #28390 Signed-off-by: Armando Visconti <armando.visconti@st.com>
This commit is contained in:
parent
0e49f5570c
commit
ce0cc3a7cc
5 changed files with 264 additions and 117 deletions
|
@ -92,7 +92,7 @@ static inline int lsm6dsl_reboot(const struct device *dev)
|
|||
{
|
||||
struct lsm6dsl_data *data = dev->data;
|
||||
|
||||
if (data->hw_tf->update_reg(data, LSM6DSL_REG_CTRL3_C,
|
||||
if (data->hw_tf->update_reg(dev, LSM6DSL_REG_CTRL3_C,
|
||||
LSM6DSL_MASK_CTRL3_C_BOOT,
|
||||
1 << LSM6DSL_SHIFT_CTRL3_C_BOOT) < 0) {
|
||||
return -EIO;
|
||||
|
@ -108,7 +108,7 @@ static int lsm6dsl_accel_set_fs_raw(const struct device *dev, uint8_t fs)
|
|||
{
|
||||
struct lsm6dsl_data *data = dev->data;
|
||||
|
||||
if (data->hw_tf->update_reg(data,
|
||||
if (data->hw_tf->update_reg(dev,
|
||||
LSM6DSL_REG_CTRL1_XL,
|
||||
LSM6DSL_MASK_CTRL1_XL_FS_XL,
|
||||
fs << LSM6DSL_SHIFT_CTRL1_XL_FS_XL) < 0) {
|
||||
|
@ -124,7 +124,7 @@ static int lsm6dsl_accel_set_odr_raw(const struct device *dev, uint8_t odr)
|
|||
{
|
||||
struct lsm6dsl_data *data = dev->data;
|
||||
|
||||
if (data->hw_tf->update_reg(data,
|
||||
if (data->hw_tf->update_reg(dev,
|
||||
LSM6DSL_REG_CTRL1_XL,
|
||||
LSM6DSL_MASK_CTRL1_XL_ODR_XL,
|
||||
odr << LSM6DSL_SHIFT_CTRL1_XL_ODR_XL) < 0) {
|
||||
|
@ -141,14 +141,14 @@ static int lsm6dsl_gyro_set_fs_raw(const struct device *dev, uint8_t fs)
|
|||
struct lsm6dsl_data *data = dev->data;
|
||||
|
||||
if (fs == GYRO_FULLSCALE_125) {
|
||||
if (data->hw_tf->update_reg(data,
|
||||
if (data->hw_tf->update_reg(dev,
|
||||
LSM6DSL_REG_CTRL2_G,
|
||||
LSM6DSL_MASK_CTRL2_FS125,
|
||||
1 << LSM6DSL_SHIFT_CTRL2_FS125) < 0) {
|
||||
return -EIO;
|
||||
}
|
||||
} else {
|
||||
if (data->hw_tf->update_reg(data,
|
||||
if (data->hw_tf->update_reg(dev,
|
||||
LSM6DSL_REG_CTRL2_G,
|
||||
LSM6DSL_MASK_CTRL2_G_FS_G,
|
||||
fs << LSM6DSL_SHIFT_CTRL2_G_FS_G) < 0) {
|
||||
|
@ -163,7 +163,7 @@ static int lsm6dsl_gyro_set_odr_raw(const struct device *dev, uint8_t odr)
|
|||
{
|
||||
struct lsm6dsl_data *data = dev->data;
|
||||
|
||||
if (data->hw_tf->update_reg(data,
|
||||
if (data->hw_tf->update_reg(dev,
|
||||
LSM6DSL_REG_CTRL2_G,
|
||||
LSM6DSL_MASK_CTRL2_G_ODR_G,
|
||||
odr << LSM6DSL_SHIFT_CTRL2_G_ODR_G) < 0) {
|
||||
|
@ -322,7 +322,7 @@ static int lsm6dsl_sample_fetch_accel(const struct device *dev)
|
|||
struct lsm6dsl_data *data = dev->data;
|
||||
uint8_t buf[6];
|
||||
|
||||
if (data->hw_tf->read_data(data, LSM6DSL_REG_OUTX_L_XL,
|
||||
if (data->hw_tf->read_data(dev, LSM6DSL_REG_OUTX_L_XL,
|
||||
buf, sizeof(buf)) < 0) {
|
||||
LOG_DBG("failed to read sample");
|
||||
return -EIO;
|
||||
|
@ -343,7 +343,7 @@ static int lsm6dsl_sample_fetch_gyro(const struct device *dev)
|
|||
struct lsm6dsl_data *data = dev->data;
|
||||
uint8_t buf[6];
|
||||
|
||||
if (data->hw_tf->read_data(data, LSM6DSL_REG_OUTX_L_G,
|
||||
if (data->hw_tf->read_data(dev, LSM6DSL_REG_OUTX_L_G,
|
||||
buf, sizeof(buf)) < 0) {
|
||||
LOG_DBG("failed to read sample");
|
||||
return -EIO;
|
||||
|
@ -365,7 +365,7 @@ static int lsm6dsl_sample_fetch_temp(const struct device *dev)
|
|||
struct lsm6dsl_data *data = dev->data;
|
||||
uint8_t buf[2];
|
||||
|
||||
if (data->hw_tf->read_data(data, LSM6DSL_REG_OUT_TEMP_L,
|
||||
if (data->hw_tf->read_data(dev, LSM6DSL_REG_OUT_TEMP_L,
|
||||
buf, sizeof(buf)) < 0) {
|
||||
LOG_DBG("failed to read sample");
|
||||
return -EIO;
|
||||
|
@ -699,7 +699,7 @@ static int lsm6dsl_channel_get(const struct device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct sensor_driver_api lsm6dsl_api_funcs = {
|
||||
static const struct sensor_driver_api lsm6dsl_driver_api = {
|
||||
.attr_set = lsm6dsl_attr_set,
|
||||
#if CONFIG_LSM6DSL_TRIGGER
|
||||
.trigger_set = lsm6dsl_trigger_set,
|
||||
|
@ -718,7 +718,7 @@ static int lsm6dsl_init_chip(const struct device *dev)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
if (data->hw_tf->read_reg(data, LSM6DSL_REG_WHO_AM_I, &chip_id) < 0) {
|
||||
if (data->hw_tf->read_reg(dev, LSM6DSL_REG_WHO_AM_I, &chip_id) < 0) {
|
||||
LOG_DBG("failed reading chip id");
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -754,7 +754,7 @@ static int lsm6dsl_init_chip(const struct device *dev)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
if (data->hw_tf->update_reg(data,
|
||||
if (data->hw_tf->update_reg(dev,
|
||||
LSM6DSL_REG_FIFO_CTRL5,
|
||||
LSM6DSL_MASK_FIFO_CTRL5_FIFO_MODE,
|
||||
0 << LSM6DSL_SHIFT_FIFO_CTRL5_FIFO_MODE) < 0) {
|
||||
|
@ -762,7 +762,7 @@ static int lsm6dsl_init_chip(const struct device *dev)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
if (data->hw_tf->update_reg(data,
|
||||
if (data->hw_tf->update_reg(dev,
|
||||
LSM6DSL_REG_CTRL3_C,
|
||||
LSM6DSL_MASK_CTRL3_C_BDU |
|
||||
LSM6DSL_MASK_CTRL3_C_BLE |
|
||||
|
@ -777,27 +777,18 @@ static int lsm6dsl_init_chip(const struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct lsm6dsl_config lsm6dsl_config = {
|
||||
.comm_master_dev_name = DT_INST_BUS_LABEL(0),
|
||||
};
|
||||
|
||||
static int lsm6dsl_init(const struct device *dev)
|
||||
{
|
||||
const struct lsm6dsl_config * const config = dev->config;
|
||||
struct lsm6dsl_data *data = dev->data;
|
||||
|
||||
data->comm_master = device_get_binding(config->comm_master_dev_name);
|
||||
if (!data->comm_master) {
|
||||
LOG_DBG("master not found: %s",
|
||||
config->comm_master_dev_name);
|
||||
data->bus = device_get_binding(config->bus_name);
|
||||
if (!data->bus) {
|
||||
LOG_DBG("master not found: %s", config->bus_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
||||
lsm6dsl_spi_init(dev);
|
||||
#else
|
||||
lsm6dsl_i2c_init(dev);
|
||||
#endif
|
||||
config->bus_init(dev);
|
||||
|
||||
if (lsm6dsl_init_chip(dev) < 0) {
|
||||
LOG_DBG("failed to initialize chip");
|
||||
|
@ -822,8 +813,129 @@ static int lsm6dsl_init(const struct device *dev)
|
|||
}
|
||||
|
||||
|
||||
static struct lsm6dsl_data lsm6dsl_data;
|
||||
#if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0
|
||||
#warning "LSM6DSL driver enabled without any devices"
|
||||
#endif
|
||||
|
||||
DEVICE_AND_API_INIT(lsm6dsl, DT_INST_LABEL(0), lsm6dsl_init,
|
||||
&lsm6dsl_data, &lsm6dsl_config, POST_KERNEL,
|
||||
CONFIG_SENSOR_INIT_PRIORITY, &lsm6dsl_api_funcs);
|
||||
/*
|
||||
* Device creation macro, shared by LSM6DSL_DEFINE_SPI() and
|
||||
* LSM6DSL_DEFINE_I2C().
|
||||
*/
|
||||
|
||||
#define LSM6DSL_DEVICE_INIT(inst) \
|
||||
DEVICE_AND_API_INIT(lsm6dsl_##inst, \
|
||||
DT_INST_LABEL(inst), \
|
||||
lsm6dsl_init, \
|
||||
&lsm6dsl_data_##inst, \
|
||||
&lsm6dsl_config_##inst, \
|
||||
POST_KERNEL, \
|
||||
CONFIG_SENSOR_INIT_PRIORITY, \
|
||||
&lsm6dsl_driver_api);
|
||||
|
||||
/*
|
||||
* Instantiation macros used when a device is on a SPI bus.
|
||||
*/
|
||||
|
||||
#define LSM6DSL_HAS_CS(inst) DT_INST_SPI_DEV_HAS_CS_GPIOS(inst)
|
||||
|
||||
#define LSM6DSL_DATA_SPI_CS(inst) \
|
||||
{ .cs_ctrl = { \
|
||||
.gpio_pin = DT_INST_SPI_DEV_CS_GPIOS_PIN(inst), \
|
||||
.gpio_dt_flags = DT_INST_SPI_DEV_CS_GPIOS_FLAGS(inst), \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define LSM6DSL_DATA_SPI(inst) \
|
||||
COND_CODE_1(LSM6DSL_HAS_CS(inst), \
|
||||
(LSM6DSL_DATA_SPI_CS(inst)), \
|
||||
({}))
|
||||
|
||||
#define LSM6DSL_SPI_CS_PTR(inst) \
|
||||
COND_CODE_1(LSM6DSL_HAS_CS(inst), \
|
||||
(&(lsm6dsl_data_##inst.cs_ctrl)), \
|
||||
(NULL))
|
||||
|
||||
#define LSM6DSL_SPI_CS_LABEL(inst) \
|
||||
COND_CODE_1(LSM6DSL_HAS_CS(inst), \
|
||||
(DT_INST_SPI_DEV_CS_GPIOS_LABEL(inst)), (NULL))
|
||||
|
||||
#define LSM6DSL_SPI_CFG(inst) \
|
||||
(&(struct lsm6dsl_spi_cfg) { \
|
||||
.spi_conf = { \
|
||||
.frequency = \
|
||||
DT_INST_PROP(inst, spi_max_frequency), \
|
||||
.operation = (SPI_WORD_SET(8) | \
|
||||
SPI_OP_MODE_MASTER | \
|
||||
SPI_MODE_CPOL | \
|
||||
SPI_MODE_CPHA), \
|
||||
.slave = DT_INST_REG_ADDR(inst), \
|
||||
.cs = LSM6DSL_SPI_CS_PTR(inst), \
|
||||
}, \
|
||||
.cs_gpios_label = LSM6DSL_SPI_CS_LABEL(inst), \
|
||||
})
|
||||
|
||||
#ifdef CONFIG_LSM6DSL_TRIGGER
|
||||
#define LSM6DSL_CONFIG_SPI(inst) \
|
||||
{ \
|
||||
.bus_name = DT_INST_BUS_LABEL(inst), \
|
||||
.bus_init = lsm6dsl_spi_init, \
|
||||
.bus_cfg = { .spi_cfg = LSM6DSL_SPI_CFG(inst) }, \
|
||||
.irq_dev_name = DT_INST_GPIO_LABEL(inst, irq_gpios), \
|
||||
.irq_pin = DT_INST_GPIO_PIN(inst, irq_gpios), \
|
||||
.irq_flags = DT_INST_GPIO_FLAGS(inst, irq_gpios), \
|
||||
}
|
||||
#else
|
||||
#define LSM6DSL_CONFIG_SPI(inst) \
|
||||
{ \
|
||||
.bus_name = DT_INST_BUS_LABEL(inst), \
|
||||
.bus_init = lsm6dsl_spi_init, \
|
||||
.bus_cfg = { .spi_cfg = LSM6DSL_SPI_CFG(inst) } \
|
||||
}
|
||||
#endif /* CONFIG_LSM6DSL_TRIGGER */
|
||||
|
||||
#define LSM6DSL_DEFINE_SPI(inst) \
|
||||
static struct lsm6dsl_data lsm6dsl_data_##inst = \
|
||||
LSM6DSL_DATA_SPI(inst); \
|
||||
static const struct lsm6dsl_config lsm6dsl_config_##inst = \
|
||||
LSM6DSL_CONFIG_SPI(inst); \
|
||||
LSM6DSL_DEVICE_INIT(inst)
|
||||
|
||||
/*
|
||||
* Instantiation macros used when a device is on an I2C bus.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_LSM6DSL_TRIGGER
|
||||
#define LSM6DSL_CONFIG_I2C(inst) \
|
||||
{ \
|
||||
.bus_name = DT_INST_BUS_LABEL(inst), \
|
||||
.bus_init = lsm6dsl_i2c_init, \
|
||||
.bus_cfg = { .i2c_slv_addr = DT_INST_REG_ADDR(inst), }, \
|
||||
.irq_dev_name = DT_INST_GPIO_LABEL(inst, irq_gpios), \
|
||||
.irq_pin = DT_INST_GPIO_PIN(inst, irq_gpios), \
|
||||
.irq_flags = DT_INST_GPIO_FLAGS(inst, irq_gpios), \
|
||||
}
|
||||
#else
|
||||
#define LSM6DSL_CONFIG_I2C(inst) \
|
||||
{ \
|
||||
.bus_name = DT_INST_BUS_LABEL(inst), \
|
||||
.bus_init = lsm6dsl_i2c_init, \
|
||||
.bus_cfg = { .i2c_slv_addr = DT_INST_REG_ADDR(inst), } \
|
||||
}
|
||||
#endif /* CONFIG_LSM6DSL_TRIGGER */
|
||||
|
||||
#define LSM6DSL_DEFINE_I2C(inst) \
|
||||
static struct lsm6dsl_data lsm6dsl_data_##inst; \
|
||||
static const struct lsm6dsl_config lsm6dsl_config_##inst = \
|
||||
LSM6DSL_CONFIG_I2C(inst); \
|
||||
LSM6DSL_DEVICE_INIT(inst)
|
||||
/*
|
||||
* Main instantiation macro. Use of COND_CODE_1() selects the right
|
||||
* bus-specific macro at preprocessor time.
|
||||
*/
|
||||
|
||||
#define LSM6DSL_DEFINE(inst) \
|
||||
COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
|
||||
(LSM6DSL_DEFINE_SPI(inst)), \
|
||||
(LSM6DSL_DEFINE_I2C(inst)))
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(LSM6DSL_DEFINE)
|
||||
|
|
|
@ -16,6 +16,14 @@
|
|||
#include <drivers/gpio.h>
|
||||
#include <sys/util.h>
|
||||
|
||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
||||
#include <drivers/spi.h>
|
||||
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
|
||||
|
||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
|
||||
#include <drivers/i2c.h>
|
||||
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) */
|
||||
|
||||
#define LSM6DSL_REG_FUNC_CFG_ACCESS 0x01
|
||||
#define LSM6DSL_MASK_FUNC_CFG_EN BIT(7)
|
||||
#define LSM6DSL_SHIFT_FUNC_CFG_EN 7
|
||||
|
@ -603,25 +611,53 @@
|
|||
#define LSM6DSL_GYRO_ODR_RUNTIME 1
|
||||
#endif
|
||||
|
||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
||||
struct lsm6dsl_spi_cfg {
|
||||
struct spi_config spi_conf;
|
||||
const char *cs_gpios_label;
|
||||
};
|
||||
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
|
||||
|
||||
union lsm6dsl_bus_cfg {
|
||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
|
||||
uint16_t i2c_slv_addr;
|
||||
#endif
|
||||
|
||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
||||
const struct lsm6dsl_spi_cfg *spi_cfg;
|
||||
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
|
||||
};
|
||||
|
||||
struct lsm6dsl_config {
|
||||
char *comm_master_dev_name;
|
||||
char *bus_name;
|
||||
int (*bus_init)(const struct device *dev);
|
||||
const union lsm6dsl_bus_cfg bus_cfg;
|
||||
#ifdef CONFIG_LSM6DSL_TRIGGER
|
||||
char *irq_dev_name;
|
||||
uint32_t irq_pin;
|
||||
int irq_flags;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct lsm6dsl_data;
|
||||
|
||||
struct lsm6dsl_transfer_function {
|
||||
int (*read_data)(struct lsm6dsl_data *data, uint8_t reg_addr,
|
||||
int (*read_data)(const struct device *dev, uint8_t reg_addr,
|
||||
uint8_t *value, uint8_t len);
|
||||
int (*write_data)(struct lsm6dsl_data *data, uint8_t reg_addr,
|
||||
int (*write_data)(const struct device *dev, uint8_t reg_addr,
|
||||
uint8_t *value, uint8_t len);
|
||||
int (*read_reg)(struct lsm6dsl_data *data, uint8_t reg_addr,
|
||||
int (*read_reg)(const struct device *dev, uint8_t reg_addr,
|
||||
uint8_t *value);
|
||||
int (*update_reg)(struct lsm6dsl_data *data, uint8_t reg_addr,
|
||||
int (*update_reg)(const struct device *dev, uint8_t reg_addr,
|
||||
uint8_t mask, uint8_t value);
|
||||
};
|
||||
|
||||
struct lsm6dsl_data {
|
||||
const struct device *comm_master;
|
||||
const struct device *bus;
|
||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
||||
struct spi_cs_control cs_ctrl;
|
||||
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
|
||||
|
||||
int accel_sample_x;
|
||||
int accel_sample_y;
|
||||
int accel_sample_z;
|
||||
|
|
|
@ -10,45 +10,57 @@
|
|||
#define DT_DRV_COMPAT st_lsm6dsl
|
||||
|
||||
#include <string.h>
|
||||
#include <drivers/i2c.h>
|
||||
#include <logging/log.h>
|
||||
|
||||
#include "lsm6dsl.h"
|
||||
|
||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
|
||||
|
||||
static uint16_t lsm6dsl_i2c_slave_addr = DT_INST_REG_ADDR(0);
|
||||
|
||||
LOG_MODULE_DECLARE(LSM6DSL, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
static int lsm6dsl_i2c_read_data(struct lsm6dsl_data *data, uint8_t reg_addr,
|
||||
static int lsm6dsl_i2c_read_data(const struct device *dev, uint8_t reg_addr,
|
||||
uint8_t *value, uint8_t len)
|
||||
{
|
||||
return i2c_burst_read(data->comm_master, lsm6dsl_i2c_slave_addr,
|
||||
struct lsm6dsl_data *data = dev->data;
|
||||
const struct lsm6dsl_config *cfg = dev->config;
|
||||
|
||||
return i2c_burst_read(data->bus, cfg->bus_cfg.i2c_slv_addr,
|
||||
reg_addr, value, len);
|
||||
}
|
||||
|
||||
static int lsm6dsl_i2c_write_data(struct lsm6dsl_data *data, uint8_t reg_addr,
|
||||
static int lsm6dsl_i2c_write_data(const struct device *dev, uint8_t reg_addr,
|
||||
uint8_t *value, uint8_t len)
|
||||
{
|
||||
return i2c_burst_write(data->comm_master, lsm6dsl_i2c_slave_addr,
|
||||
struct lsm6dsl_data *data = dev->data;
|
||||
const struct lsm6dsl_config *cfg = dev->config;
|
||||
|
||||
return i2c_burst_write(data->bus, cfg->bus_cfg.i2c_slv_addr,
|
||||
reg_addr, value, len);
|
||||
}
|
||||
|
||||
static int lsm6dsl_i2c_read_reg(struct lsm6dsl_data *data, uint8_t reg_addr,
|
||||
static int lsm6dsl_i2c_read_reg(const struct device *dev, uint8_t reg_addr,
|
||||
uint8_t *value)
|
||||
{
|
||||
return i2c_reg_read_byte(data->comm_master, lsm6dsl_i2c_slave_addr,
|
||||
struct lsm6dsl_data *data = dev->data;
|
||||
const struct lsm6dsl_config *cfg = dev->config;
|
||||
|
||||
return i2c_reg_read_byte(data->bus,
|
||||
cfg->bus_cfg.i2c_slv_addr,
|
||||
reg_addr, value);
|
||||
}
|
||||
|
||||
static int lsm6dsl_i2c_update_reg(struct lsm6dsl_data *data, uint8_t reg_addr,
|
||||
uint8_t mask, uint8_t value)
|
||||
static int lsm6dsl_i2c_update_reg(const struct device *dev, uint8_t reg_addr,
|
||||
uint8_t mask, uint8_t value)
|
||||
{
|
||||
return i2c_reg_update_byte(data->comm_master, lsm6dsl_i2c_slave_addr,
|
||||
reg_addr, mask, value);
|
||||
struct lsm6dsl_data *data = dev->data;
|
||||
const struct lsm6dsl_config *cfg = dev->config;
|
||||
|
||||
return i2c_reg_update_byte(data->bus,
|
||||
cfg->bus_cfg.i2c_slv_addr,
|
||||
reg_addr, mask, value);
|
||||
}
|
||||
|
||||
|
||||
static const struct lsm6dsl_transfer_function lsm6dsl_i2c_transfer_fn = {
|
||||
.read_data = lsm6dsl_i2c_read_data,
|
||||
.write_data = lsm6dsl_i2c_write_data,
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#define DT_DRV_COMPAT st_lsm6dsl
|
||||
|
||||
#include <string.h>
|
||||
#include <drivers/spi.h>
|
||||
#include "lsm6dsl.h"
|
||||
#include <logging/log.h>
|
||||
|
||||
|
@ -20,24 +19,12 @@
|
|||
|
||||
LOG_MODULE_DECLARE(LSM6DSL, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0)
|
||||
static struct spi_cs_control lsm6dsl_cs_ctrl;
|
||||
#endif
|
||||
|
||||
#define SPI_CS NULL
|
||||
|
||||
static struct spi_config lsm6dsl_spi_conf = {
|
||||
.frequency = DT_INST_PROP(0, spi_max_frequency),
|
||||
.operation = (SPI_OP_MODE_MASTER | SPI_MODE_CPOL |
|
||||
SPI_MODE_CPHA | SPI_WORD_SET(8) | SPI_LINES_SINGLE),
|
||||
.slave = DT_INST_REG_ADDR(0),
|
||||
.cs = SPI_CS,
|
||||
};
|
||||
|
||||
static int lsm6dsl_raw_read(struct lsm6dsl_data *data, uint8_t reg_addr,
|
||||
static int lsm6dsl_raw_read(const struct device *dev, uint8_t reg_addr,
|
||||
uint8_t *value, uint8_t len)
|
||||
{
|
||||
struct spi_config *spi_cfg = &lsm6dsl_spi_conf;
|
||||
struct lsm6dsl_data *data = dev->data;
|
||||
const struct lsm6dsl_config *cfg = dev->config;
|
||||
const struct spi_config *spi_cfg = &cfg->bus_cfg.spi_cfg->spi_conf;
|
||||
uint8_t buffer_tx[2] = { reg_addr | LSM6DSL_SPI_READ, 0 };
|
||||
const struct spi_buf tx_buf = {
|
||||
.buf = buffer_tx,
|
||||
|
@ -67,17 +54,19 @@ static int lsm6dsl_raw_read(struct lsm6dsl_data *data, uint8_t reg_addr,
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
if (spi_transceive(data->comm_master, spi_cfg, &tx, &rx)) {
|
||||
if (spi_transceive(data->bus, spi_cfg, &tx, &rx)) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lsm6dsl_raw_write(struct lsm6dsl_data *data, uint8_t reg_addr,
|
||||
static int lsm6dsl_raw_write(const struct device *dev, uint8_t reg_addr,
|
||||
uint8_t *value, uint8_t len)
|
||||
{
|
||||
struct spi_config *spi_cfg = &lsm6dsl_spi_conf;
|
||||
struct lsm6dsl_data *data = dev->data;
|
||||
const struct lsm6dsl_config *cfg = dev->config;
|
||||
const struct spi_config *spi_cfg = &cfg->bus_cfg.spi_cfg->spi_conf;
|
||||
uint8_t buffer_tx[1] = { reg_addr & ~LSM6DSL_SPI_READ };
|
||||
const struct spi_buf tx_buf[2] = {
|
||||
{
|
||||
|
@ -99,40 +88,40 @@ static int lsm6dsl_raw_write(struct lsm6dsl_data *data, uint8_t reg_addr,
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
if (spi_write(data->comm_master, spi_cfg, &tx)) {
|
||||
if (spi_write(data->bus, spi_cfg, &tx)) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lsm6dsl_spi_read_data(struct lsm6dsl_data *data, uint8_t reg_addr,
|
||||
static int lsm6dsl_spi_read_data(const struct device *dev, uint8_t reg_addr,
|
||||
uint8_t *value, uint8_t len)
|
||||
{
|
||||
return lsm6dsl_raw_read(data, reg_addr, value, len);
|
||||
return lsm6dsl_raw_read(dev, reg_addr, value, len);
|
||||
}
|
||||
|
||||
static int lsm6dsl_spi_write_data(struct lsm6dsl_data *data, uint8_t reg_addr,
|
||||
static int lsm6dsl_spi_write_data(const struct device *dev, uint8_t reg_addr,
|
||||
uint8_t *value, uint8_t len)
|
||||
{
|
||||
return lsm6dsl_raw_write(data, reg_addr, value, len);
|
||||
return lsm6dsl_raw_write(dev, reg_addr, value, len);
|
||||
}
|
||||
|
||||
static int lsm6dsl_spi_read_reg(struct lsm6dsl_data *data, uint8_t reg_addr,
|
||||
static int lsm6dsl_spi_read_reg(const struct device *dev, uint8_t reg_addr,
|
||||
uint8_t *value)
|
||||
{
|
||||
return lsm6dsl_raw_read(data, reg_addr, value, 1);
|
||||
return lsm6dsl_raw_read(dev, reg_addr, value, 1);
|
||||
}
|
||||
|
||||
static int lsm6dsl_spi_update_reg(struct lsm6dsl_data *data, uint8_t reg_addr,
|
||||
static int lsm6dsl_spi_update_reg(const struct device *dev, uint8_t reg_addr,
|
||||
uint8_t mask, uint8_t value)
|
||||
{
|
||||
uint8_t tmp_val;
|
||||
|
||||
lsm6dsl_raw_read(data, reg_addr, &tmp_val, 1);
|
||||
lsm6dsl_raw_read(dev, reg_addr, &tmp_val, 1);
|
||||
tmp_val = (tmp_val & ~mask) | (value & mask);
|
||||
|
||||
return lsm6dsl_raw_write(data, reg_addr, &tmp_val, 1);
|
||||
return lsm6dsl_raw_write(dev, reg_addr, &tmp_val, 1);
|
||||
}
|
||||
|
||||
static const struct lsm6dsl_transfer_function lsm6dsl_spi_transfer_fn = {
|
||||
|
@ -145,29 +134,25 @@ static const struct lsm6dsl_transfer_function lsm6dsl_spi_transfer_fn = {
|
|||
int lsm6dsl_spi_init(const struct device *dev)
|
||||
{
|
||||
struct lsm6dsl_data *data = dev->data;
|
||||
const struct lsm6dsl_config *cfg = dev->config;
|
||||
const struct lsm6dsl_spi_cfg *spi_cfg = cfg->bus_cfg.spi_cfg;
|
||||
|
||||
data->hw_tf = &lsm6dsl_spi_transfer_fn;
|
||||
|
||||
#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0)
|
||||
/* handle SPI CS thru GPIO if it is the case */
|
||||
lsm6dsl_cs_ctrl.gpio_dev = device_get_binding(
|
||||
DT_INST_SPI_DEV_CS_GPIOS_LABEL(0));
|
||||
if (!lsm6dsl_cs_ctrl.gpio_dev) {
|
||||
LOG_ERR("Unable to get GPIO SPI CS device");
|
||||
return -ENODEV;
|
||||
if (spi_cfg->cs_gpios_label != NULL) {
|
||||
|
||||
/* handle SPI CS thru GPIO if it is the case */
|
||||
data->cs_ctrl.gpio_dev =
|
||||
device_get_binding(spi_cfg->cs_gpios_label);
|
||||
if (!data->cs_ctrl.gpio_dev) {
|
||||
LOG_ERR("Unable to get GPIO SPI CS device");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
LOG_DBG("SPI GPIO CS configured on %s:%u",
|
||||
spi_cfg->cs_gpios_label, data->cs_ctrl.gpio_pin);
|
||||
}
|
||||
|
||||
lsm6dsl_cs_ctrl.gpio_pin = DT_INST_SPI_DEV_CS_GPIOS_PIN(0);
|
||||
lsm6dsl_cs_ctrl.gpio_dt_flags = DT_INST_SPI_DEV_CS_GPIOS_FLAGS(0);
|
||||
lsm6dsl_cs_ctrl.delay = 0U;
|
||||
|
||||
lsm6dsl_spi_conf.cs = &lsm6dsl_cs_ctrl;
|
||||
|
||||
LOG_DBG("SPI GPIO CS configured on %s:%u",
|
||||
DT_INST_SPI_DEV_CS_GPIOS_LABEL(0),
|
||||
DT_INST_SPI_DEV_CS_GPIOS_PIN(0));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
|
||||
|
|
|
@ -18,20 +18,20 @@
|
|||
LOG_MODULE_DECLARE(LSM6DSL, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
static inline void setup_irq(struct lsm6dsl_data *drv_data,
|
||||
bool enable)
|
||||
uint32_t irq_pin, bool enable)
|
||||
{
|
||||
unsigned int flags = enable
|
||||
? GPIO_INT_EDGE_TO_ACTIVE
|
||||
: GPIO_INT_DISABLE;
|
||||
|
||||
gpio_pin_interrupt_configure(drv_data->gpio,
|
||||
DT_INST_GPIO_PIN(0, irq_gpios),
|
||||
flags);
|
||||
irq_pin, flags);
|
||||
}
|
||||
|
||||
static inline void handle_irq(struct lsm6dsl_data *drv_data)
|
||||
static inline void handle_irq(struct lsm6dsl_data *drv_data,
|
||||
uint32_t irq_pin)
|
||||
{
|
||||
setup_irq(drv_data, false);
|
||||
setup_irq(drv_data, irq_pin, false);
|
||||
|
||||
#if defined(CONFIG_LSM6DSL_TRIGGER_OWN_THREAD)
|
||||
k_sem_give(&drv_data->gpio_sem);
|
||||
|
@ -44,11 +44,12 @@ int lsm6dsl_trigger_set(const struct device *dev,
|
|||
const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler)
|
||||
{
|
||||
const struct lsm6dsl_config *config = dev->config;
|
||||
struct lsm6dsl_data *drv_data = dev->data;
|
||||
|
||||
__ASSERT_NO_MSG(trig->type == SENSOR_TRIG_DATA_READY);
|
||||
|
||||
setup_irq(drv_data, false);
|
||||
setup_irq(drv_data, config->irq_pin, false);
|
||||
|
||||
drv_data->data_ready_handler = handler;
|
||||
if (handler == NULL) {
|
||||
|
@ -57,9 +58,9 @@ int lsm6dsl_trigger_set(const struct device *dev,
|
|||
|
||||
drv_data->data_ready_trigger = *trig;
|
||||
|
||||
setup_irq(drv_data, true);
|
||||
if (gpio_pin_get(drv_data->gpio, DT_INST_GPIO_PIN(0, irq_gpios)) > 0) {
|
||||
handle_irq(drv_data);
|
||||
setup_irq(drv_data, config->irq_pin, true);
|
||||
if (gpio_pin_get(drv_data->gpio, config->irq_pin) > 0) {
|
||||
handle_irq(drv_data, config->irq_pin);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -68,16 +69,18 @@ int lsm6dsl_trigger_set(const struct device *dev,
|
|||
static void lsm6dsl_gpio_callback(const struct device *dev,
|
||||
struct gpio_callback *cb, uint32_t pins)
|
||||
{
|
||||
const struct lsm6dsl_config *config = dev->config;
|
||||
struct lsm6dsl_data *drv_data =
|
||||
CONTAINER_OF(cb, struct lsm6dsl_data, gpio_cb);
|
||||
|
||||
ARG_UNUSED(pins);
|
||||
|
||||
handle_irq(drv_data);
|
||||
handle_irq(drv_data, config->irq_pin);
|
||||
}
|
||||
|
||||
static void lsm6dsl_thread_cb(const struct device *dev)
|
||||
{
|
||||
const struct lsm6dsl_config *config = dev->config;
|
||||
struct lsm6dsl_data *drv_data = dev->data;
|
||||
|
||||
if (drv_data->data_ready_handler != NULL) {
|
||||
|
@ -85,7 +88,7 @@ static void lsm6dsl_thread_cb(const struct device *dev)
|
|||
&drv_data->data_ready_trigger);
|
||||
}
|
||||
|
||||
setup_irq(drv_data, true);
|
||||
setup_irq(drv_data, config->irq_pin, true);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LSM6DSL_TRIGGER_OWN_THREAD
|
||||
|
@ -110,22 +113,21 @@ static void lsm6dsl_work_cb(struct k_work *work)
|
|||
|
||||
int lsm6dsl_init_interrupt(const struct device *dev)
|
||||
{
|
||||
const struct lsm6dsl_config *config = dev->config;
|
||||
struct lsm6dsl_data *drv_data = dev->data;
|
||||
|
||||
/* setup data ready gpio interrupt */
|
||||
drv_data->gpio = device_get_binding(DT_INST_GPIO_LABEL(0, irq_gpios));
|
||||
drv_data->gpio = device_get_binding(config->irq_dev_name);
|
||||
if (drv_data->gpio == NULL) {
|
||||
LOG_ERR("Cannot get pointer to %s device.",
|
||||
DT_INST_GPIO_LABEL(0, irq_gpios));
|
||||
LOG_ERR("Cannot get pointer to %s.", config->irq_dev_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gpio_pin_configure(drv_data->gpio, DT_INST_GPIO_PIN(0, irq_gpios),
|
||||
GPIO_INPUT | DT_INST_GPIO_FLAGS(0, irq_gpios));
|
||||
gpio_pin_configure(drv_data->gpio, config->irq_pin,
|
||||
GPIO_INPUT | config->irq_flags);
|
||||
|
||||
gpio_init_callback(&drv_data->gpio_cb,
|
||||
lsm6dsl_gpio_callback,
|
||||
BIT(DT_INST_GPIO_PIN(0, irq_gpios)));
|
||||
lsm6dsl_gpio_callback, BIT(config->irq_pin));
|
||||
|
||||
if (gpio_add_callback(drv_data->gpio, &drv_data->gpio_cb) < 0) {
|
||||
LOG_ERR("Could not set gpio callback.");
|
||||
|
@ -133,7 +135,7 @@ int lsm6dsl_init_interrupt(const struct device *dev)
|
|||
}
|
||||
|
||||
/* enable data-ready interrupt */
|
||||
if (drv_data->hw_tf->update_reg(drv_data,
|
||||
if (drv_data->hw_tf->update_reg(dev,
|
||||
LSM6DSL_REG_INT1_CTRL,
|
||||
LSM6DSL_MASK_INT1_CTRL_DRDY_XL |
|
||||
LSM6DSL_MASK_INT1_CTRL_DRDY_G,
|
||||
|
@ -157,7 +159,7 @@ int lsm6dsl_init_interrupt(const struct device *dev)
|
|||
drv_data->work.handler = lsm6dsl_work_cb;
|
||||
#endif
|
||||
|
||||
setup_irq(drv_data, true);
|
||||
setup_irq(drv_data, config->irq_pin, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue