diff --git a/drivers/sensor/st/lis2dux12/CMakeLists.txt b/drivers/sensor/st/lis2dux12/CMakeLists.txt index 87f0e6b8928..f22572af1cd 100644 --- a/drivers/sensor/st/lis2dux12/CMakeLists.txt +++ b/drivers/sensor/st/lis2dux12/CMakeLists.txt @@ -4,5 +4,6 @@ zephyr_library() zephyr_library_sources(lis2dux12.c) zephyr_library_sources_ifdef(CONFIG_LIS2DUX12_TRIGGER lis2dux12_trigger.c) +zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_LIS2DUX12_ENABLED lis2dux12_api.c ) zephyr_library_include_directories(../stmemsc) diff --git a/drivers/sensor/st/lis2dux12/lis2dux12.c b/drivers/sensor/st/lis2dux12/lis2dux12.c index f41e23daad4..32895857105 100644 --- a/drivers/sensor/st/lis2dux12/lis2dux12.c +++ b/drivers/sensor/st/lis2dux12/lis2dux12.c @@ -8,8 +8,6 @@ * https://www.st.com/resource/en/datasheet/lis2dux12.pdf */ -#define DT_DRV_COMPAT st_lis2dux12 - #include #include #include @@ -18,59 +16,15 @@ #include #include #include -#include #include "lis2dux12.h" +#if DT_HAS_COMPAT_STATUS_OKAY(st_lis2dux12) +#include "lis2dux12_api.h" +#endif + LOG_MODULE_REGISTER(LIS2DUX12, CONFIG_SENSOR_LOG_LEVEL); -static int lis2dux12_set_odr(const struct device *dev, uint8_t odr) -{ - struct lis2dux12_data *data = dev->data; - const struct lis2dux12_config *cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - lis2dux12_md_t mode = {.odr = odr, .fs = data->range}; - - data->odr = odr; - return lis2dux12_mode_set(ctx, &mode); -} - -static int lis2dux12_set_range(const struct device *dev, uint8_t range) -{ - int err; - struct lis2dux12_data *data = dev->data; - const struct lis2dux12_config *cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - lis2dux12_md_t val = { .odr = data->odr, .fs = range }; - - err = lis2dux12_mode_set(ctx, &val); - - if (err) { - return err; - } - - switch (range) { - default: - LOG_ERR("range [%d] not supported.", range); - return -EINVAL; - case LIS2DUX12_DT_FS_2G: - data->gain = lis2dux12_from_fs2g_to_mg(1); - break; - case LIS2DUX12_DT_FS_4G: - data->gain = lis2dux12_from_fs4g_to_mg(1); - break; - case LIS2DUX12_DT_FS_8G: - data->gain = lis2dux12_from_fs8g_to_mg(1); - break; - case LIS2DUX12_DT_FS_16G: - data->gain = lis2dux12_from_fs16g_to_mg(1); - break; - } - - data->range = range; - return 0; -} - #define FOREACH_ODR_ENUM(ODR_VAL) \ ODR_VAL(LIS2DUX12_DT_ODR_OFF, 0.0f) \ ODR_VAL(LIS2DUX12_DT_ODR_1Hz_ULP, 1.0f) \ @@ -113,6 +67,8 @@ static int lis2dux12_set_fs(const struct device *dev, int16_t fs) { int ret; uint8_t range; + const struct lis2dux12_config *const cfg = dev->config; + const struct lis2dux12_chip_api *chip_api = cfg->chip_api; switch (fs) { case 2: @@ -132,7 +88,7 @@ static int lis2dux12_set_fs(const struct device *dev, int16_t fs) return -EINVAL; } - ret = lis2dux12_set_range(dev, range); + ret = chip_api->set_range(dev, range); if (ret < 0) { LOG_ERR("%s: range init error %d", dev->name, range); return ret; @@ -146,6 +102,8 @@ static int lis2dux12_accel_config(const struct device *dev, enum sensor_channel enum sensor_attribute attr, const struct sensor_value *val) { int odr_val; + const struct lis2dux12_config *const cfg = dev->config; + const struct lis2dux12_chip_api *chip_api = cfg->chip_api; switch (attr) { case SENSOR_ATTR_FULL_SCALE: @@ -159,7 +117,7 @@ static int lis2dux12_accel_config(const struct device *dev, enum sensor_channel LOG_DBG("%s: set odr to %d Hz", dev->name, val->val1); - return lis2dux12_set_odr(dev, odr_val); + return chip_api->set_odr_raw(dev, odr_val); default: LOG_ERR("Accel attribute not supported."); return -ENOTSUP; @@ -182,71 +140,34 @@ static int lis2dux12_attr_set(const struct device *dev, enum sensor_channel chan return 0; } -static int lis2dux12_sample_fetch_accel(const struct device *dev) -{ - struct lis2dux12_data *data = dev->data; - const struct lis2dux12_config *cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - - /* fetch raw data sample */ - lis2dux12_md_t mode = {.fs = data->range}; - lis2dux12_xl_data_t xzy_data = {0}; - - if (lis2dux12_xl_data_get(ctx, &mode, &xzy_data) < 0) { - LOG_ERR("Failed to fetch raw data sample"); - return -EIO; - } - - data->sample_x = xzy_data.raw[0]; - data->sample_y = xzy_data.raw[1]; - data->sample_z = xzy_data.raw[2]; - - return 0; -} - -#ifdef CONFIG_LIS2DUX12_ENABLE_TEMP -static int lis2dux12_sample_fetch_temp(const struct device *dev) -{ - struct lis2dux12_data *data = dev->data; - const struct lis2dux12_config *cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - - /* fetch raw data sample */ - lis2dux12_outt_data_t temp_data = {0}; - - if (lis2dux12_outt_data_get(ctx, &temp_data) < 0) { - LOG_ERR("Failed to fetch raw temperature data sample"); - return -EIO; - } - - data->sample_temp = temp_data.heat.deg_c; - - return 0; -} -#endif - static int lis2dux12_sample_fetch(const struct device *dev, enum sensor_channel chan) { + const struct lis2dux12_config *const cfg = dev->config; + const struct lis2dux12_chip_api *chip_api = cfg->chip_api; + int ret; + switch (chan) { case SENSOR_CHAN_ACCEL_XYZ: - lis2dux12_sample_fetch_accel(dev); + ret = chip_api->sample_fetch_accel(dev); break; #if defined(CONFIG_LIS2DUX12_ENABLE_TEMP) case SENSOR_CHAN_DIE_TEMP: - lis2dux12_sample_fetch_temp(dev); + ret = chip_api->sample_fetch_temp(dev); break; #endif case SENSOR_CHAN_ALL: - lis2dux12_sample_fetch_accel(dev); + ret = chip_api->sample_fetch_accel(dev); + if (ret != 0) + break; #if defined(CONFIG_LIS2DUX12_ENABLE_TEMP) - lis2dux12_sample_fetch_temp(dev); + ret = chip_api->sample_fetch_temp(dev); #endif break; default: return -ENOTSUP; } - return 0; + return ret; } static inline void lis2dux12_convert(struct sensor_value *val, int raw_val, float gain) @@ -307,129 +228,59 @@ static DEVICE_API(sensor, lis2dux12_driver_api) = { .channel_get = lis2dux12_channel_get, }; -static int lis2dux12_init(const struct device *dev) -{ - const struct lis2dux12_config *const cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - uint8_t chip_id; - int ret; - - lis2dux12_exit_deep_power_down(ctx); - k_busy_wait(25000); - - /* check chip ID */ - ret = lis2dux12_device_id_get(ctx, &chip_id); - if (ret < 0) { - LOG_ERR("%s: Not able to read dev id", dev->name); - return ret; - } - - if (chip_id != LIS2DUX12_ID) { - LOG_ERR("%s: Invalid chip ID 0x%02x", dev->name, chip_id); - return -EINVAL; - } - - /* reset device */ - ret = lis2dux12_init_set(ctx, LIS2DUX12_RESET); - if (ret < 0) { - return ret; - } - - k_busy_wait(100); - - LOG_INF("%s: chip id 0x%x", dev->name, chip_id); - - /* Set bdu and if_inc recommended for driver usage */ - lis2dux12_init_set(ctx, LIS2DUX12_SENSOR_ONLY_ON); - - lis2dux12_timestamp_set(ctx, PROPERTY_ENABLE); - -#ifdef CONFIG_LIS2DUX12_TRIGGER - if (cfg->trig_enabled) { - ret = lis2dux12_trigger_init(dev); - if (ret < 0) { - LOG_ERR("%s: Failed to initialize triggers", dev->name); - return ret; - } - } -#endif - - /* set sensor default pm and odr */ - LOG_DBG("%s: pm: %d, odr: %d", dev->name, cfg->pm, cfg->odr); - ret = lis2dux12_set_odr(dev, cfg->odr); - if (ret < 0) { - LOG_ERR("%s: odr init error (12.5 Hz)", dev->name); - return ret; - } - - /* set sensor default scale (used to convert sample values) */ - LOG_DBG("%s: range is %d", dev->name, cfg->range); - ret = lis2dux12_set_range(dev, cfg->range); - if (ret < 0) { - LOG_ERR("%s: range init error %d", dev->name, cfg->range); - return ret; - } - - return 0; -} - /* * Device creation macro, shared by LIS2DUX12_DEFINE_SPI() and * LIS2DUX12_DEFINE_I2C(). */ -#define LIS2DUX12_DEVICE_INIT(inst) \ - SENSOR_DEVICE_DT_INST_DEFINE(inst, lis2dux12_init, NULL, &lis2dux12_data_##inst, \ - &lis2dux12_config_##inst, POST_KERNEL, \ - CONFIG_SENSOR_INIT_PRIORITY, &lis2dux12_driver_api); - /* * Instantiation macros used when a device is on a SPI bus. */ #ifdef CONFIG_LIS2DUX12_TRIGGER -#define LIS2DUX12_CFG_IRQ(inst) \ - .trig_enabled = true, \ - .int1_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int1_gpios, {0}), \ - .int2_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int2_gpios, {0}), \ +#define LIS2DUX12_CFG_IRQ(inst) \ + .trig_enabled = true, \ + .int1_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int1_gpios, {0}), \ + .int2_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int2_gpios, {0}), \ .drdy_pin = DT_INST_PROP(inst, drdy_pin), #else #define LIS2DUX12_CFG_IRQ(inst) #endif /* CONFIG_LIS2DUX12_TRIGGER */ +#define LIS2DUX12_CONFIG_COMMON(inst, name) \ + .chip_api = &name##_chip_api, \ + .range = DT_INST_PROP(inst, range), \ + .pm = DT_INST_PROP(inst, power_mode), \ + .odr = DT_INST_PROP(inst, odr), \ + IF_ENABLED(UTIL_OR(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \ + DT_INST_NODE_HAS_PROP(inst, int2_gpios)), \ + (LIS2DUX12_CFG_IRQ(inst))) \ + #define LIS2DUX12_SPI_OPERATION \ (SPI_WORD_SET(8) | SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA) -#define LIS2DUX12_CONFIG_SPI(inst) \ +/* + * Instantiation macros used when a device is on a SPI bus. + */ +#define LIS2DUX12_CONFIG_SPI(inst, name) \ { \ - STMEMSC_CTX_SPI(&lis2dux12_config_##inst.stmemsc_cfg), \ + STMEMSC_CTX_SPI(&lis2dux12_config_##name##_##inst.stmemsc_cfg), \ .stmemsc_cfg = { \ .spi = SPI_DT_SPEC_INST_GET(inst, LIS2DUX12_SPI_OPERATION, 0), \ }, \ - .range = DT_INST_PROP(inst, range), \ - .pm = DT_INST_PROP(inst, power_mode), \ - .odr = DT_INST_PROP(inst, odr), \ - IF_ENABLED(UTIL_OR(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \ - DT_INST_NODE_HAS_PROP(inst, int2_gpios)), \ - (LIS2DUX12_CFG_IRQ(inst))) \ + LIS2DUX12_CONFIG_COMMON(inst, name) \ } /* * Instantiation macros used when a device is on an I2C bus. */ - -#define LIS2DUX12_CONFIG_I2C(inst) \ +#define LIS2DUX12_CONFIG_I2C(inst, name) \ { \ - STMEMSC_CTX_I2C(&lis2dux12_config_##inst.stmemsc_cfg), \ + STMEMSC_CTX_I2C(&lis2dux12_config_##name##_##inst.stmemsc_cfg), \ .stmemsc_cfg = { \ .i2c = I2C_DT_SPEC_INST_GET(inst), \ }, \ - .range = DT_INST_PROP(inst, range), \ - .pm = DT_INST_PROP(inst, power_mode), \ - .odr = DT_INST_PROP(inst, odr), \ - IF_ENABLED(UTIL_OR(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \ - DT_INST_NODE_HAS_PROP(inst, int2_gpios)), \ - (LIS2DUX12_CFG_IRQ(inst))) \ + LIS2DUX12_CONFIG_COMMON(inst, name) \ } /* @@ -437,11 +288,20 @@ static int lis2dux12_init(const struct device *dev) * bus-specific macro at preprocessor time. */ -#define LIS2DUX12_DEFINE(inst) \ - static struct lis2dux12_data lis2dux12_data_##inst; \ - static const struct lis2dux12_config lis2dux12_config_##inst = \ - COND_CODE_1(DT_INST_ON_BUS(inst, spi), (LIS2DUX12_CONFIG_SPI(inst)), \ - (LIS2DUX12_CONFIG_I2C(inst))); \ - LIS2DUX12_DEVICE_INIT(inst) +#define LIS2DUX12_DEFINE(inst, name) \ + static struct lis2dux12_data lis2dux12_data_##name##_##inst; \ + static const struct lis2dux12_config lis2dux12_config_##name##_##inst = \ + COND_CODE_1(DT_INST_ON_BUS(inst, spi), \ + (LIS2DUX12_CONFIG_SPI(inst, name)), \ + (LIS2DUX12_CONFIG_I2C(inst, name))); \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, name##_init, NULL, \ + &lis2dux12_data_##name##_##inst, \ + &lis2dux12_config_##name##_##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, \ + &lis2dux12_driver_api); -DT_INST_FOREACH_STATUS_OKAY(LIS2DUX12_DEFINE) + +#define DT_DRV_COMPAT st_lis2dux12 +DT_INST_FOREACH_STATUS_OKAY_VARGS(LIS2DUX12_DEFINE, DT_DRV_COMPAT) +#undef DT_DRV_COMPAT diff --git a/drivers/sensor/st/lis2dux12/lis2dux12.h b/drivers/sensor/st/lis2dux12/lis2dux12.h index 7d0d85f34ed..37f6b5fae5c 100644 --- a/drivers/sensor/st/lis2dux12/lis2dux12.h +++ b/drivers/sensor/st/lis2dux12/lis2dux12.h @@ -15,23 +15,50 @@ #include #include #include + +#if DT_HAS_COMPAT_STATUS_OKAY(st_lis2dux12) #include "lis2dux12_reg.h" +#endif -#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2dux12, spi) #include -#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */ +#endif -#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2dux12, i2c) #include -#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) */ +#endif + +typedef int32_t (*api_lis2dux12_set_odr_raw)(const struct device *dev, uint8_t odr); +typedef int32_t (*api_lis2dux12_set_range)(const struct device *dev, uint8_t range); +typedef int32_t (*api_lis2dux12_sample_fetch_accel)(const struct device *dev); +#ifdef CONFIG_LIS2DUX12_ENABLE_TEMP +typedef int32_t (*api_lis2dux12_sample_fetch_temp)(const struct device *dev); +#endif +#ifdef CONFIG_LIS2DUX12_TRIGGER +typedef void (*api_lis2dux12_handle_interrupt)(const struct device *dev); +typedef int32_t (*api_lis2dux12_init_interrupt)(const struct device *dev); +#endif + +struct lis2dux12_chip_api { + api_lis2dux12_set_odr_raw set_odr_raw; + api_lis2dux12_set_range set_range; + api_lis2dux12_sample_fetch_accel sample_fetch_accel; +#ifdef CONFIG_LIS2DUX12_ENABLE_TEMP + api_lis2dux12_sample_fetch_temp sample_fetch_temp; +#endif +#ifdef CONFIG_LIS2DUX12_TRIGGER + api_lis2dux12_handle_interrupt handle_interrupt; + api_lis2dux12_init_interrupt init_interrupt; +#endif +}; struct lis2dux12_config { stmdev_ctx_t ctx; union { -#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2dux12, i2c) const struct i2c_dt_spec i2c; #endif -#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2dux12, spi) const struct spi_dt_spec spi; #endif } stmemsc_cfg; @@ -44,6 +71,8 @@ struct lis2dux12_config { uint8_t drdy_pin; bool trig_enabled; #endif + + const struct lis2dux12_chip_api *chip_api; }; struct lis2dux12_data { diff --git a/drivers/sensor/st/lis2dux12/lis2dux12_api.c b/drivers/sensor/st/lis2dux12/lis2dux12_api.c new file mode 100644 index 00000000000..3a00fdf1f63 --- /dev/null +++ b/drivers/sensor/st/lis2dux12/lis2dux12_api.c @@ -0,0 +1,237 @@ +/* ST Microelectronics LIS2DUX12 smart accelerometer APIs + * + * Copyright (c) 2024 STMicroelectronics + * Copyright (c) 2023 PHYTEC Messtechnik GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "lis2dux12.h" +#include "lis2dux12_api.h" +#include + +LOG_MODULE_DECLARE(LIS2DUX12, CONFIG_SENSOR_LOG_LEVEL); + +static int32_t st_lis2dux12_set_odr_raw(const struct device *dev, uint8_t odr) +{ + struct lis2dux12_data *data = dev->data; + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lis2dux12_md_t mode = {.odr = odr, .fs = data->range}; + + data->odr = odr; + return lis2dux12_mode_set(ctx, &mode); +} + +static int32_t st_lis2dux12_set_range(const struct device *dev, uint8_t range) +{ + int err; + struct lis2dux12_data *data = dev->data; + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lis2dux12_md_t val = { .odr = data->odr, .fs = range }; + + err = lis2dux12_mode_set(ctx, &val); + if (err) { + return err; + } + + switch (range) { + case LIS2DUX12_DT_FS_2G: + data->gain = lis2dux12_from_fs2g_to_mg(1); + break; + case LIS2DUX12_DT_FS_4G: + data->gain = lis2dux12_from_fs4g_to_mg(1); + break; + case LIS2DUX12_DT_FS_8G: + data->gain = lis2dux12_from_fs8g_to_mg(1); + break; + case LIS2DUX12_DT_FS_16G: + data->gain = lis2dux12_from_fs16g_to_mg(1); + break; + default: + LOG_ERR("range %d not supported.", range); + return -EINVAL; + } + + data->range = range; + return 0; +} + +static int32_t st_lis2dux12_sample_fetch_accel(const struct device *dev) +{ + struct lis2dux12_data *data = dev->data; + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + + /* fetch raw data sample */ + lis2dux12_md_t mode = {.fs = data->range}; + lis2dux12_xl_data_t xzy_data = {0}; + + if (lis2dux12_xl_data_get(ctx, &mode, &xzy_data) < 0) { + LOG_ERR("Failed to fetch raw data sample"); + return -EIO; + } + + data->sample_x = xzy_data.raw[0]; + data->sample_y = xzy_data.raw[1]; + data->sample_z = xzy_data.raw[2]; + + return 0; +} + +#ifdef CONFIG_LIS2DUX12_ENABLE_TEMP +static int32_t st_lis2dux12_sample_fetch_temp(const struct device *dev) +{ + struct lis2dux12_data *data = dev->data; + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + + /* fetch raw data sample */ + lis2dux12_outt_data_t temp_data = {0}; + + if (lis2dux12_outt_data_get(ctx, &temp_data) < 0) { + LOG_ERR("Failed to fetch raw temperature data sample"); + return -EIO; + } + + data->sample_temp = temp_data.heat.deg_c; + + return 0; +} +#endif + +#ifdef CONFIG_LIS2DUX12_TRIGGER +static void st_lis2dux12_handle_interrupt(const struct device *dev) +{ + struct lis2dux12_data *lis2dux12 = dev->data; + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lis2dux12_all_sources_t sources; + int ret; + + lis2dux12_all_sources_get(ctx, &sources); + + if (sources.drdy == 0) { + goto exit; /* spurious interrupt */ + } + + if (lis2dux12->data_ready_handler != NULL) { + lis2dux12->data_ready_handler(dev, lis2dux12->data_ready_trigger); + } + +exit: + ret = gpio_pin_interrupt_configure_dt(lis2dux12->drdy_gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (ret < 0) { + LOG_ERR("%s: Not able to configure pin_int", dev->name); + } +} + +static int32_t st_lis2dux12_init_interrupt(const struct device *dev) +{ + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lis2dux12_pin_int_route_t route; + int err; + + /* Enable pulsed mode */ + err = lis2dux12_data_ready_mode_set(ctx, LIS2DUX12_DRDY_PULSED); + if (err < 0) { + return err; + } + + /* route data-ready interrupt on int1 */ + err = lis2dux12_pin_int1_route_get(ctx, &route); + if (err < 0) { + return err; + } + + route.drdy = 1; + + err = lis2dux12_pin_int1_route_set(ctx, &route); + if (err < 0) { + return err; + } + + return 0; +} +#endif + +const struct lis2dux12_chip_api st_lis2dux12_chip_api = { + .set_odr_raw = st_lis2dux12_set_odr_raw, + .set_range = st_lis2dux12_set_range, + .sample_fetch_accel = st_lis2dux12_sample_fetch_accel, +#ifdef CONFIG_LIS2DUX12_ENABLE_TEMP + .sample_fetch_temp = st_lis2dux12_sample_fetch_temp, +#endif +#ifdef CONFIG_LIS2DUX12_TRIGGER + .handle_interrupt = st_lis2dux12_handle_interrupt, + .init_interrupt = st_lis2dux12_init_interrupt, +#endif +}; + +int st_lis2dux12_init(const struct device *dev) +{ + const struct lis2dux12_config *const cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + uint8_t chip_id; + int ret; + + lis2dux12_exit_deep_power_down(ctx); + k_busy_wait(25000); + + /* check chip ID */ + ret = lis2dux12_device_id_get(ctx, &chip_id); + if (ret < 0) { + LOG_ERR("%s: Not able to read dev id", dev->name); + return ret; + } + + if (chip_id != LIS2DUX12_ID) { + LOG_ERR("%s: Invalid chip ID 0x%02x", dev->name, chip_id); + return -EINVAL; + } + + /* reset device */ + ret = lis2dux12_init_set(ctx, LIS2DUX12_RESET); + if (ret < 0) { + return ret; + } + + k_busy_wait(100); + + LOG_INF("%s: chip id 0x%x", dev->name, chip_id); + + /* Set bdu and if_inc recommended for driver usage */ + lis2dux12_init_set(ctx, LIS2DUX12_SENSOR_ONLY_ON); + + lis2dux12_timestamp_set(ctx, PROPERTY_ENABLE); + +#ifdef CONFIG_LIS2DUX12_TRIGGER + if (cfg->trig_enabled) { + ret = lis2dux12_trigger_init(dev); + if (ret < 0) { + LOG_ERR("%s: Failed to initialize triggers", dev->name); + return ret; + } + } +#endif + + /* set sensor default pm and odr */ + LOG_DBG("%s: pm: %d, odr: %d", dev->name, cfg->pm, cfg->odr); + ret = st_lis2dux12_set_odr_raw(dev, cfg->odr); + if (ret < 0) { + LOG_ERR("%s: odr init error (12.5 Hz)", dev->name); + return ret; + } + + /* set sensor default scale (used to convert sample values) */ + LOG_DBG("%s: range is %d", dev->name, cfg->range); + ret = st_lis2dux12_set_range(dev, cfg->range); + if (ret < 0) { + LOG_ERR("%s: range init error %d", dev->name, cfg->range); + return ret; + } + + return 0; +} diff --git a/drivers/sensor/st/lis2dux12/lis2dux12_api.h b/drivers/sensor/st/lis2dux12/lis2dux12_api.h new file mode 100644 index 00000000000..dd7efe35401 --- /dev/null +++ b/drivers/sensor/st/lis2dux12/lis2dux12_api.h @@ -0,0 +1,24 @@ +/* ST Microelectronics LIS2DUX12 smart accelerometer APIs + * + * Copyright (c) 2024 STMicroelectronics + * Copyright (c) 2023 PHYTEC Messtechnik GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "lis2dux12_reg.h" +#include + +#include + +#ifndef ZEPHYR_DRIVERS_SENSOR_LIS2DUX12_ST_LIS2DUX12_H_ +#define ZEPHYR_DRIVERS_SENSOR_LIS2DUX12_ST_LIS2DUX12_H_ + +extern const struct lis2dux12_chip_api st_lis2dux12_chip_api; + +int st_lis2dux12_init(const struct device *dev); + +#endif /* ZEPHYR_DRIVERS_SENSOR_LIS2DUX12_ST_LIS2DUX12_H_ */ diff --git a/drivers/sensor/st/lis2dux12/lis2dux12_trigger.c b/drivers/sensor/st/lis2dux12/lis2dux12_trigger.c index 30ede375ec3..effc40e5d2b 100644 --- a/drivers/sensor/st/lis2dux12/lis2dux12_trigger.c +++ b/drivers/sensor/st/lis2dux12/lis2dux12_trigger.c @@ -8,8 +8,6 @@ * https://www.st.com/resource/en/datasheet/lis2dux12.pdf */ -#define DT_DRV_COMPAT st_lis2dux12 - #include #include "lis2dux12.h" @@ -35,41 +33,16 @@ static void lis2dux12_gpio_callback(const struct device *dev, struct gpio_callba #endif } -static void lis2dux12_handle_drdy_int(const struct device *dev) -{ - struct lis2dux12_data *data = dev->data; - - if (data->data_ready_handler != NULL) { - data->data_ready_handler(dev, data->data_ready_trigger); - } -} - -static void lis2dux12_handle_int(const struct device *dev) -{ - struct lis2dux12_data *lis2dux12 = dev->data; - const struct lis2dux12_config *cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - lis2dux12_all_sources_t sources; - int ret; - - lis2dux12_all_sources_get(ctx, &sources); - - if (sources.drdy) { - lis2dux12_handle_drdy_int(dev); - } - - ret = gpio_pin_interrupt_configure_dt(lis2dux12->drdy_gpio, GPIO_INT_EDGE_TO_ACTIVE); - if (ret < 0) { - LOG_ERR("%s: Not able to configure pin_int", dev->name); - } -} - #ifdef CONFIG_LIS2DUX12_TRIGGER_OWN_THREAD static void lis2dux12_thread(struct lis2dux12_data *data) { + const struct device *dev = data->dev; + const struct lis2dux12_config *const cfg = dev->config; + const struct lis2dux12_chip_api *chip_api = cfg->chip_api; + while (1) { k_sem_take(&data->trig_sem, K_FOREVER); - lis2dux12_handle_int(data->dev); + chip_api->handle_interrupt(dev); } } #endif @@ -78,40 +51,14 @@ static void lis2dux12_thread(struct lis2dux12_data *data) static void lis2dux12_work_cb(struct k_work *work) { struct lis2dux12_data *data = CONTAINER_OF(work, struct lis2dux12_data, work); + const struct device *dev = data->dev; + const struct lis2dux12_config *const cfg = dev->config; + const struct lis2dux12_chip_api *chip_api = cfg->chip_api; - lis2dux12_handle_int(data->dev); + chip_api->handle_interrupt(dev); } #endif -static int lis2dux12_init_interrupt(const struct device *dev) -{ - const struct lis2dux12_config *cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - lis2dux12_pin_int_route_t route; - int err; - - /* Enable pulsed mode */ - err = lis2dux12_data_ready_mode_set(ctx, LIS2DUX12_DRDY_PULSED); - if (err < 0) { - return err; - } - - /* route data-ready interrupt on int1 */ - err = lis2dux12_pin_int1_route_get(ctx, &route); - if (err < 0) { - return err; - } - - route.drdy = 1; - - err = lis2dux12_pin_int1_route_set(ctx, &route); - if (err < 0) { - return err; - } - - return 0; -} - int lis2dux12_trigger_init(const struct device *dev) { struct lis2dux12_data *data = dev->data; @@ -162,9 +109,7 @@ int lis2dux12_trigger_set(const struct device *dev, const struct sensor_trigger { struct lis2dux12_data *data = dev->data; const struct lis2dux12_config *cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - lis2dux12_xl_data_t xldata; - lis2dux12_md_t mode = {.fs = cfg->range}; + const struct lis2dux12_chip_api *chip_api = cfg->chip_api; int ret; if (!cfg->trig_enabled) { @@ -190,10 +135,15 @@ int lis2dux12_trigger_set(const struct device *dev, const struct sensor_trigger } /* re-trigger lost interrupt */ - lis2dux12_xl_data_get(ctx, &mode, &xldata); + chip_api->sample_fetch_accel(dev); data->data_ready_trigger = trig; - lis2dux12_init_interrupt(dev); + ret = chip_api->init_interrupt(dev); + if (ret < 0) { + LOG_ERR("%s: Not able to initialize device interrupt", dev->name); + return ret; + } + return gpio_pin_interrupt_configure_dt(data->drdy_gpio, GPIO_INT_EDGE_TO_ACTIVE); }