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:
Armando Visconti 2020-09-16 17:27:27 +02:00 committed by Anas Nashif
commit ce0cc3a7cc
5 changed files with 264 additions and 117 deletions

View file

@ -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)

View file

@ -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;

View file

@ -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,

View file

@ -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) */

View file

@ -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;
}