diff --git a/boards/st/steval_stwinbx1/steval_stwinbx1.dts b/boards/st/steval_stwinbx1/steval_stwinbx1.dts index 040452e91b00e3..1ca613ff12d23f 100644 --- a/boards/st/steval_stwinbx1/steval_stwinbx1.dts +++ b/boards/st/steval_stwinbx1/steval_stwinbx1.dts @@ -218,6 +218,12 @@ stm32_lp_tick_source: &lptim1 { drdy-gpios = <&gpiof 9 GPIO_ACTIVE_HIGH>; status = "okay"; }; + + ilps22qs@5c { + compatible = "st,ilps22qs"; + reg = <0x5c>; + status = "okay"; + }; }; &timers5 { diff --git a/drivers/sensor/st/lps2xdf/CMakeLists.txt b/drivers/sensor/st/lps2xdf/CMakeLists.txt index 24a1b5844a8eec..40fb08371a4066 100644 --- a/drivers/sensor/st/lps2xdf/CMakeLists.txt +++ b/drivers/sensor/st/lps2xdf/CMakeLists.txt @@ -8,6 +8,7 @@ zephyr_library() zephyr_library_sources(lps2xdf.c) +zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_ILPS22QS_ENABLED ilps22qs.c ) zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_LPS22DF_ENABLED lps22df.c ) zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_LPS28DFW_ENABLED lps28dfw.c ) zephyr_library_sources_ifdef(CONFIG_LPS2XDF_TRIGGER lps2xdf_trigger.c) diff --git a/drivers/sensor/st/lps2xdf/Kconfig b/drivers/sensor/st/lps2xdf/Kconfig index 754f8c3b4511f9..66cd51c7fceab0 100644 --- a/drivers/sensor/st/lps2xdf/Kconfig +++ b/drivers/sensor/st/lps2xdf/Kconfig @@ -7,14 +7,19 @@ menuconfig LPS2XDF bool "LPS2xDF pressure and temperature" default y - depends on DT_HAS_ST_LPS22DF_ENABLED || DT_HAS_ST_LPS28DFW_ENABLED + depends on DT_HAS_ST_LPS22DF_ENABLED || DT_HAS_ST_LPS28DFW_ENABLED ||\ + DT_HAS_ST_ILPS22QS_ENABLED depends on ZEPHYR_HAL_ST_MODULE select I2C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LPS22DF),i2c) ||\ + $(dt_compat_on_bus,$(DT_COMPAT_ST_ILPS22QS),i2c) ||\ $(dt_compat_on_bus,$(DT_COMPAT_ST_LPS28DFW),i2c) - select I2C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LPS22DF),i3c) ||\ + select I3C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LPS22DF),i3c) ||\ + $(dt_compat_on_bus,$(DT_COMPAT_ST_ILPS22QS),i3c) ||\ $(dt_compat_on_bus,$(DT_COMPAT_ST_LPS28DFW),i3c) - select SPI if $(dt_compat_on_bus,$(DT_COMPAT_ST_LPS22DF),spi) + select SPI if $(dt_compat_on_bus,$(DT_COMPAT_ST_LPS22DF),spi) ||\ + $(dt_compat_on_bus,$(DT_COMPAT_ST_ILPS22QS),spi) select HAS_STMEMSC + select USE_STDC_ILPS22QS if DT_HAS_ST_ILPS22QS_ENABLED select USE_STDC_LPS22DF if DT_HAS_ST_LPS22DF_ENABLED select USE_STDC_LPS28DFW if DT_HAS_ST_LPS28DFW_ENABLED help diff --git a/drivers/sensor/st/lps2xdf/ilps22qs.c b/drivers/sensor/st/lps2xdf/ilps22qs.c new file mode 100644 index 00000000000000..5502c62a00a533 --- /dev/null +++ b/drivers/sensor/st/lps2xdf/ilps22qs.c @@ -0,0 +1,175 @@ +/* ST Microelectronics ILPS22QS pressure and temperature sensor + * + * Copyright (c) 2023-2024 STMicroelectronics + * Copyright (c) 2023 PHYTEC Messtechnik GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "lps2xdf.h" +#include "ilps22qs.h" +#include + +LOG_MODULE_DECLARE(LPS2XDF, CONFIG_SENSOR_LOG_LEVEL); + +static inline int ilps22qs_mode_set_odr_raw(const struct device *dev, uint8_t odr) +{ + const struct lps2xdf_config *const cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + ilps22qs_md_t md = { 0 }; + + md.odr = odr; + md.avg = cfg->avg; + md.lpf = cfg->lpf; + md.fs = cfg->fs; + + return ilps22qs_mode_set(ctx, &md); +} + +static int ilps22qs_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + struct lps2xdf_data *data = dev->data; + const struct lps2xdf_config *const cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + ilps22qs_data_t raw_data; + ilps22qs_md_t md = { 0 }; + + md.fs = cfg->fs; + + if (ilps22qs_data_get(ctx, &md, &raw_data) < 0) { + LOG_DBG("Failed to read sample"); + return -EIO; + } + + data->sample_press = raw_data.pressure.raw; + data->sample_temp = raw_data.heat.raw; + + return 0; +} + +#ifdef CONFIG_LPS2XDF_TRIGGER +/** + * ilps22qs_config_interrupt - not supported + */ +static int ilps22qs_config_interrupt(const struct device *dev) +{ + return -ENOTSUP; +} + +/** + * ilps22qs_handle_interrupt - not supported + */ +static void ilps22qs_handle_interrupt(const struct device *dev) +{ +} + +/** + * ilps22qs_trigger_set - not supported + */ +static int ilps22qs_trigger_set(const struct device *dev, + const struct sensor_trigger *trig, + sensor_trigger_handler_t handler) +{ + return -ENOTSUP; +} +#endif /* CONFIG_LPS2XDF_TRIGGER */ + +const struct lps2xdf_chip_api st_ilps22qs_chip_api = { + .mode_set_odr_raw = ilps22qs_mode_set_odr_raw, + .sample_fetch = ilps22qs_sample_fetch, +#if CONFIG_LPS2XDF_TRIGGER + .config_interrupt = ilps22qs_config_interrupt, + .handle_interrupt = ilps22qs_handle_interrupt, + .trigger_set = ilps22qs_trigger_set, +#endif +}; + +int st_ilps22qs_init(const struct device *dev) +{ + const struct lps2xdf_config *const cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + ilps22qs_id_t id; + ilps22qs_stat_t status; + uint8_t tries = 10; + int ret; + +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_ilps22qs, i3c) + if (cfg->i3c.bus != NULL) { + struct lps2xdf_data *data = dev->data; + /* + * Need to grab the pointer to the I3C device descriptor + * before we can talk to the sensor. + */ + data->i3c_dev = i3c_device_find(cfg->i3c.bus, &cfg->i3c.dev_id); + if (data->i3c_dev == NULL) { + LOG_ERR("Cannot find I3C device descriptor"); + return -ENODEV; + } + } +#endif + + if (ilps22qs_id_get(ctx, &id) < 0) { + LOG_ERR("%s: Not able to read dev id", dev->name); + return -EIO; + } + + if (id.whoami != ILPS22QS_ID) { + LOG_ERR("%s: Invalid chip ID 0x%02x", dev->name, id.whoami); + return -EIO; + } + + LOG_DBG("%s: chip id 0x%x", dev->name, id.whoami); + + /* Restore default configuration */ + if (ilps22qs_init_set(ctx, ILPS22QS_RESET) < 0) { + LOG_ERR("%s: Not able to reset device", dev->name); + return -EIO; + } + + do { + if (!--tries) { + LOG_DBG("sw reset timed out"); + return -ETIMEDOUT; + } + k_usleep(LPS2XDF_SWRESET_WAIT_TIME_US); + + if (ilps22qs_status_get(ctx, &status) < 0) { + return -EIO; + } + } while (status.sw_reset); + + /* Set bdu and if_inc recommended for driver usage */ + if (ilps22qs_init_set(ctx, ILPS22QS_DRV_RDY) < 0) { + LOG_ERR("%s: Not able to set device to ready state", dev->name); + return -EIO; + } + + if (ON_I3C_BUS(cfg)) { + ilps22qs_bus_mode_t bus_mode; + + /* Select bus interface */ + ilps22qs_bus_mode_get(ctx, &bus_mode); + bus_mode.filter = ILPS22QS_AUTO; + bus_mode.interface = ILPS22QS_SEL_BY_HW; + ilps22qs_bus_mode_set(ctx, &bus_mode); + } + + /* set sensor default odr */ + LOG_DBG("%s: odr: %d", dev->name, cfg->odr); + ret = ilps22qs_mode_set_odr_raw(dev, cfg->odr); + if (ret < 0) { + LOG_ERR("%s: Failed to set odr %d", dev->name, cfg->odr); + return ret; + } + +#ifdef CONFIG_LPS2XDF_TRIGGER + if (cfg->trig_enabled) { + if (lps2xdf_init_interrupt(dev, DEVICE_VARIANT_ILPS22QS) < 0) { + LOG_ERR("Failed to initialize interrupt."); + return -EIO; + } + } +#endif + + return 0; +} diff --git a/drivers/sensor/st/lps2xdf/ilps22qs.h b/drivers/sensor/st/lps2xdf/ilps22qs.h new file mode 100644 index 00000000000000..eb2488eeb5746a --- /dev/null +++ b/drivers/sensor/st/lps2xdf/ilps22qs.h @@ -0,0 +1,23 @@ +/* ST Microelectronics ILPS22QS pressure and temperature sensor + * + * Copyright (c) 2023-2024 STMicroelectronics + * Copyright (c) 2023 PHYTEC Messtechnik GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "ilps22qs_reg.h" + +#include + +#ifndef ZEPHYR_DRIVERS_SENSOR_ILPS22QS_ILPS22QS_H_ +#define ZEPHYR_DRIVERS_SENSOR_ILPS22QS_ILPS22QS_H_ + +extern const struct lps2xdf_chip_api st_ilps22qs_chip_api; + +int st_ilps22qs_init(const struct device *dev); + +#endif /* ZEPHYR_DRIVERS_SENSOR_ILPS22QS_H_ */ diff --git a/drivers/sensor/st/lps2xdf/lps22df.c b/drivers/sensor/st/lps2xdf/lps22df.c index ff5537cf37c02d..d18536984c486f 100644 --- a/drivers/sensor/st/lps2xdf/lps22df.c +++ b/drivers/sensor/st/lps2xdf/lps22df.c @@ -43,11 +43,29 @@ static int lps22df_sample_fetch(const struct device *dev, enum sensor_channel ch return 0; } +#ifdef CONFIG_LPS2XDF_TRIGGER +/** + * lps22df_config_interrupt - config the interrupt mode + */ +static int lps22df_config_interrupt(const struct device *dev) +{ + const struct lps2xdf_config *const cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lps22df_int_mode_t mode; + + if (lps22df_interrupt_mode_get(ctx, &mode) < 0) { + return -EIO; + } + + mode.drdy_latched = ~cfg->drdy_pulsed; + + return lps22df_interrupt_mode_set(ctx, &mode); +} + /** * lps22df_handle_interrupt - handle the drdy event * read data and call handler if registered any */ -#ifdef CONFIG_LPS2XDF_TRIGGER static void lps22df_handle_interrupt(const struct device *dev) { int ret; @@ -138,6 +156,7 @@ const struct lps2xdf_chip_api st_lps22df_chip_api = { .mode_set_odr_raw = lps22df_mode_set_odr_raw, .sample_fetch = lps22df_sample_fetch, #if CONFIG_LPS2XDF_TRIGGER + .config_interrupt = lps22df_config_interrupt, .handle_interrupt = lps22df_handle_interrupt, .trigger_set = lps22df_trigger_set, #endif diff --git a/drivers/sensor/st/lps2xdf/lps28dfw.c b/drivers/sensor/st/lps2xdf/lps28dfw.c index 40ea39bb571c98..22715d6ff602f1 100644 --- a/drivers/sensor/st/lps2xdf/lps28dfw.c +++ b/drivers/sensor/st/lps2xdf/lps28dfw.c @@ -47,11 +47,29 @@ static int lps28dfw_sample_fetch(const struct device *dev, enum sensor_channel c return 0; } +#ifdef CONFIG_LPS2XDF_TRIGGER +/** + * lps28dfw_config_interrupt - config the interrupt mode + */ +static int lps28dfw_config_interrupt(const struct device *dev) +{ + const struct lps2xdf_config *const cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lps28dfw_int_mode_t mode; + + if (lps28dfw_interrupt_mode_get(ctx, &mode) < 0) { + return -EIO; + } + + mode.drdy_latched = ~cfg->drdy_pulsed; + + return lps28dfw_interrupt_mode_set(ctx, &mode); +} + /** * lps28dfw_handle_interrupt - handle the drdy event * read data and call handler if registered any */ -#ifdef CONFIG_LPS2XDF_TRIGGER static void lps28dfw_handle_interrupt(const struct device *dev) { int ret; @@ -105,7 +123,7 @@ static int lps28dfw_enable_int(const struct device *dev, int enable) } /** - * lps22df_trigger_set - link external trigger to event data ready + * lps28dfw_trigger_set - link external trigger to event data ready */ static int lps28dfw_trigger_set(const struct device *dev, const struct sensor_trigger *trig, @@ -145,6 +163,7 @@ const struct lps2xdf_chip_api st_lps28dfw_chip_api = { .mode_set_odr_raw = lps28dfw_mode_set_odr_raw, .sample_fetch = lps28dfw_sample_fetch, #if CONFIG_LPS2XDF_TRIGGER + .config_interrupt = lps28dfw_config_interrupt, .handle_interrupt = lps28dfw_handle_interrupt, .trigger_set = lps28dfw_trigger_set, #endif diff --git a/drivers/sensor/st/lps2xdf/lps2xdf.c b/drivers/sensor/st/lps2xdf/lps2xdf.c index 2196c265ffc237..0fb7ce87bf8285 100644 --- a/drivers/sensor/st/lps2xdf/lps2xdf.c +++ b/drivers/sensor/st/lps2xdf/lps2xdf.c @@ -6,6 +6,7 @@ * SPDX-License-Identifier: Apache-2.0 * * Datasheet: + * https://www.st.com/resource/en/datasheet/ilps22qs.pdf * https://www.st.com/resource/en/datasheet/lps22df.pdf * https://www.st.com/resource/en/datasheet/lps28df.pdf */ @@ -20,6 +21,10 @@ #include "lps2xdf.h" +#if DT_HAS_COMPAT_STATUS_OKAY(st_ilps22qs) +#include "ilps22qs.h" +#endif + #if DT_HAS_COMPAT_STATUS_OKAY(st_lps22df) #include "lps22df.h" #endif @@ -159,7 +164,7 @@ static const struct sensor_driver_api lps2xdf_driver_api = { .lpf = DT_INST_PROP(inst, lpf), \ .avg = DT_INST_PROP(inst, avg), \ .chip_api = &name##_chip_api, \ - IF_ENABLED(DT_INST_NODE_HAS_COMPAT(inst, st_lps28dfw), \ + IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, fs), \ (.fs = DT_INST_PROP(inst, fs),)) \ IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, drdy_gpios), \ (LPS2XDF_CFG_IRQ(inst))) @@ -214,6 +219,10 @@ static const struct sensor_driver_api lps2xdf_driver_api = { &lps2xdf_config_##name##_##inst, POST_KERNEL, \ CONFIG_SENSOR_INIT_PRIORITY, &lps2xdf_driver_api); +#define DT_DRV_COMPAT st_ilps22qs +DT_INST_FOREACH_STATUS_OKAY_VARGS(LPS2XDF_DEFINE, DT_DRV_COMPAT) +#undef DT_DRV_COMPAT + #define DT_DRV_COMPAT st_lps22df DT_INST_FOREACH_STATUS_OKAY_VARGS(LPS2XDF_DEFINE, DT_DRV_COMPAT) #undef DT_DRV_COMPAT diff --git a/drivers/sensor/st/lps2xdf/lps2xdf.h b/drivers/sensor/st/lps2xdf/lps2xdf.h index 10a38a5a133d67..2efd08ad6412e7 100644 --- a/drivers/sensor/st/lps2xdf/lps2xdf.h +++ b/drivers/sensor/st/lps2xdf/lps2xdf.h @@ -16,6 +16,10 @@ #include #include +#if DT_HAS_COMPAT_STATUS_OKAY(st_ilps22qs) +#include "ilps22qs_reg.h" +#endif + #if DT_HAS_COMPAT_STATUS_OKAY(st_lps28dfw) #include "lps28dfw_reg.h" #endif @@ -32,6 +36,7 @@ #define LPS2XDF_SWRESET_WAIT_TIME_US 50 #if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps22df, i3c) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_ilps22qs, i3c) || \ DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps28dfw, i3c)) #define ON_I3C_BUS(cfg) (cfg->i3c.bus != NULL) #else @@ -40,8 +45,9 @@ typedef int32_t (*api_lps2xdf_mode_set_odr_raw)(const struct device *dev, uint8_t odr); typedef int32_t (*api_lps2xdf_sample_fetch)(const struct device *dev, enum sensor_channel chan); -typedef void (*api_lps2xdf_handle_interrupt)(const struct device *dev); #ifdef CONFIG_LPS2XDF_TRIGGER +typedef int (*api_lps2xdf_config_interrupt)(const struct device *dev); +typedef void (*api_lps2xdf_handle_interrupt)(const struct device *dev); typedef int (*api_lps2xdf_trigger_set)(const struct device *dev, const struct sensor_trigger *trig, sensor_trigger_handler_t handler); @@ -50,8 +56,9 @@ typedef int (*api_lps2xdf_trigger_set)(const struct device *dev, struct lps2xdf_chip_api { api_lps2xdf_mode_set_odr_raw mode_set_odr_raw; api_lps2xdf_sample_fetch sample_fetch; - api_lps2xdf_handle_interrupt handle_interrupt; #ifdef CONFIG_LPS2XDF_TRIGGER + api_lps2xdf_config_interrupt config_interrupt; + api_lps2xdf_handle_interrupt handle_interrupt; api_lps2xdf_trigger_set trigger_set; #endif }; @@ -60,6 +67,7 @@ struct lps2xdf_chip_api { enum sensor_variant { DEVICE_VARIANT_LPS22DF = 0, DEVICE_VARIANT_LPS28DFW = 1, + DEVICE_VARIANT_ILPS22QS = 2, }; @@ -67,13 +75,16 @@ struct lps2xdf_config { stmdev_ctx_t ctx; union { #if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps22df, i2c) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_ilps22qs, i2c) || \ DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps28dfw, i2c)) const struct i2c_dt_spec i2c; #endif -#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps22df, spi) +#if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps22df, spi) ||\ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_ilps22qs, spi)) const struct spi_dt_spec spi; #endif #if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps22df, i3c) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_ilps22qs, i3c) || \ DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps28dfw, i3c)) struct i3c_device_desc **i3c; #endif @@ -89,6 +100,7 @@ struct lps2xdf_config { #endif #if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps22df, i3c) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_ilps22qs, i3c) || \ DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps28dfw, i3c)) struct { const struct device *bus; @@ -120,12 +132,15 @@ struct lps2xdf_data { #endif /* CONFIG_LPS2XDF_TRIGGER */ #if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps22df, i3c) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_ilps22qs, i3c) || \ DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps28dfw, i3c)) struct i3c_device_desc *i3c_dev; #endif }; #ifdef CONFIG_LPS2XDF_TRIGGER +int lps2xdf_config_int(const struct device *dev); + int lps2xdf_trigger_set(const struct device *dev, const struct sensor_trigger *trig, sensor_trigger_handler_t handler); diff --git a/drivers/sensor/st/lps2xdf/lps2xdf_trigger.c b/drivers/sensor/st/lps2xdf/lps2xdf_trigger.c index b196e1f40c2d1a..de51ba14e6ef46 100644 --- a/drivers/sensor/st/lps2xdf/lps2xdf_trigger.c +++ b/drivers/sensor/st/lps2xdf/lps2xdf_trigger.c @@ -27,6 +27,14 @@ LOG_MODULE_DECLARE(LPS2XDF, CONFIG_SENSOR_LOG_LEVEL); +int lps2xdf_config_int(const struct device *dev) +{ + const struct lps2xdf_config *const cfg = dev->config; + const struct lps2xdf_chip_api *chip_api = cfg->chip_api; + + return chip_api->config_interrupt(dev); +} + int lps2xdf_trigger_set(const struct device *dev, const struct sensor_trigger *trig, sensor_trigger_handler_t handler) @@ -111,7 +119,6 @@ int lps2xdf_init_interrupt(const struct device *dev, enum sensor_variant variant { struct lps2xdf_data *lps2xdf = dev->data; const struct lps2xdf_config *cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; int ret; /* setup data ready gpio interrupt */ @@ -164,32 +171,10 @@ int lps2xdf_init_interrupt(const struct device *dev, enum sensor_variant variant LOG_DBG("drdy_pulsed is %d", (int)cfg->drdy_pulsed); /* enable drdy in pulsed/latched mode */ - if (variant == DEVICE_VARIANT_LPS22DF) { -#if DT_HAS_COMPAT_STATUS_OKAY(st_lps22df) - lps22df_int_mode_t mode; - - if (lps22df_interrupt_mode_get(ctx, &mode) < 0) { - return -EIO; - } - mode.drdy_latched = ~cfg->drdy_pulsed; - if (lps22df_interrupt_mode_set(ctx, &mode) < 0) { - return -EIO; - } -#endif - } else if (variant == DEVICE_VARIANT_LPS28DFW) { -#if DT_HAS_COMPAT_STATUS_OKAY(st_lps28dfw) - lps28dfw_int_mode_t mode; - - if (lps28dfw_interrupt_mode_get(ctx, &mode) < 0) { - return -EIO; - } - mode.drdy_latched = ~cfg->drdy_pulsed; - if (lps28dfw_interrupt_mode_set(ctx, &mode) < 0) { - return -EIO; - } -#endif - } else { - return -ENOTSUP; + ret = lps2xdf_config_int(dev); + if (ret < 0) { + LOG_ERR("Could not configure interrupt mode"); + return ret; } #if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps22df, i3c) ||\ diff --git a/dts/bindings/sensor/st,ilps22qs-common.yaml b/dts/bindings/sensor/st,ilps22qs-common.yaml new file mode 100644 index 00000000000000..a400667aaa12d8 --- /dev/null +++ b/dts/bindings/sensor/st,ilps22qs-common.yaml @@ -0,0 +1,83 @@ +# Copyright (c) 2023 STMicroelectronics +# Copyright (c) 2023 PHYTEC Messtechnik GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: | + When setting the odr, lpf, avg properties in a .dts or .dtsi file + you may include ilps22qs.h and use the macros defined there. + + Example: + #include + + ilps22qs@5d { + ... + + odr = ; + lpf = ; + avg = ; + }; + +include: sensor-device.yaml + +properties: + odr: + type: int + default: 0 + description: | + Specify the output data rate expressed in samples per second (Hz). + The default is the power-on reset value. + + - 0 # LPS2xDF_DT_ODR_POWER_DOWN + - 1 # LPS2xDF_DT_ODR_1HZ + - 2 # LPS2xDF_DT_ODR_4HZ + - 3 # LPS2xDF_DT_ODR_10HZ + - 4 # LPS2xDF_DT_ODR_25HZ + - 5 # LPS2xDF_DT_ODR_50HZ + - 6 # LPS2xDF_DT_ODR_75HZ + - 7 # LPS2xDF_DT_ODR_100HZ + - 8 # LPS2xDF_DT_ODR_200HZ + + enum: [0, 1, 2, 3, 4, 5, 6, 7, 8] + + lpf: + type: int + default: 0 + description: | + Specify the low pass filter value to be applied to pressure data. + The default is the power-on reset value. + + - 0 # LPS2xDF_DT_LP_FILTER_OFF + - 1 # LPS2xDF_DT_LP_FILTER_ODR_4 + - 3 # LPS2xDF_DT_LP_FILTER_ODR_9 + + enum: [0, 1, 3] + + avg: + type: int + default: 0 + description: | + Specify the average filter value (i.e. number of samples) to be applied + to pressure and temperature data. + The default is the power-on reset value. + + - 0 # LPS2xDF_DT_AVG_4_SAMPLES + - 1 # LPS2xDF_DT_AVG_8_SAMPLES + - 2 # LPS2xDF_DT_AVG_16_SAMPLES + - 3 # LPS2xDF_DT_AVG_32_SAMPLES + - 4 # LPS2xDF_DT_AVG_64_SAMPLES + - 5 # LPS2xDF_DT_AVG_128_SAMPLES + - 6 # LPS2xDF_DT_AVG_256_SAMPLES + - 7 # LPS2xDF_DT_AVG_512_SAMPLES + + enum: [0, 1, 2, 3, 4, 5, 6, 7] + + fs: + type: int + default: 0 + description: | + Specify the full-scale mode. + The default is the power-on reset value. + + - 0 # ILPS22QS_DT_FS_MODE_1_1260 + - 1 # ILPS22QS_DT_FS_MODE_2_4060 + enum: [0, 1] diff --git a/dts/bindings/sensor/st,ilps22qs-i2c.yaml b/dts/bindings/sensor/st,ilps22qs-i2c.yaml new file mode 100644 index 00000000000000..428c1731c9292b --- /dev/null +++ b/dts/bindings/sensor/st,ilps22qs-i2c.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics LPS22DF pressure and temperature sensor connected to I2C + bus + +compatible: "st,ilps22qs" + +include: ["i2c-device.yaml", "st,ilps22qs-common.yaml"] diff --git a/dts/bindings/sensor/st,ilps22qs-i3c.yaml b/dts/bindings/sensor/st,ilps22qs-i3c.yaml new file mode 100644 index 00000000000000..0662b27fffc0e8 --- /dev/null +++ b/dts/bindings/sensor/st,ilps22qs-i3c.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics LPS22DF pressure and temperature sensor connected to I2C + bus + +compatible: "st,ilps22qs" + +include: ["i3c-device.yaml", "st,ilps22qs-common.yaml"] diff --git a/dts/bindings/sensor/st,ilps22qs-spi.yaml b/dts/bindings/sensor/st,ilps22qs-spi.yaml new file mode 100644 index 00000000000000..9527c189f33b73 --- /dev/null +++ b/dts/bindings/sensor/st,ilps22qs-spi.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics LPS22DF pressure and temperature sensor connected to I2C + bus + +compatible: "st,ilps22qs" + +include: ["spi-device.yaml", "st,ilps22qs-common.yaml"] diff --git a/include/zephyr/dt-bindings/sensor/lps2xdf.h b/include/zephyr/dt-bindings/sensor/lps2xdf.h index bcbb831bae57c6..b1dffa818a0101 100644 --- a/include/zephyr/dt-bindings/sensor/lps2xdf.h +++ b/include/zephyr/dt-bindings/sensor/lps2xdf.h @@ -37,4 +37,8 @@ #define LPS28DFW_DT_FS_MODE_1_1260 0 #define LPS28DFW_DT_FS_MODE_2_4060 1 +/* Full Scale Pressure Mode */ +#define ILPS22QS_DT_FS_MODE_1_1260 0 +#define ILPS22QS_DT_FS_MODE_2_4060 1 + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_LPS22DF_H_ */ diff --git a/samples/boards/st/steval_stwinbx1/sensors/README.rst b/samples/boards/st/steval_stwinbx1/sensors/README.rst index bf3f1d91a4802d..9f276fd066c583 100644 --- a/samples/boards/st/steval_stwinbx1/sensors/README.rst +++ b/samples/boards/st/steval_stwinbx1/sensors/README.rst @@ -17,6 +17,7 @@ sensors: - ISM330DHCX: IMU, 3D accelerometer and 3D gyroscope with Machine Learning Core and Finite State Machine - IIS2DLPC: high-performance ultra-low-power 3-axis accelerometer for industrial applications - IIS2ICLX: high-accuracy, high-resolution, low-power, 2-axis digital inclinometer with Machine Learning Core +- ILPS22QS: ultra-compact piezoresistive absolute pressure sensor Requirements ************ @@ -70,6 +71,8 @@ The sample code outputs sensors data on the STWIN.box console. ISM330DHCX: Accel (m.s-2): x: 0.000, y: 5.704, z: 7.982 ISM330DHCX: Gyro (dps): x: 0.026, y: -0.006, z: -0.008 IIS2ICLX: Accel (m.s-2): x: -0.157, y: 5.699 + ILPS22QS: Temperature: 26.4 C + ILPS22QS: Pressure: 100.539 kpa 1:: iis2dlpc trig 2021 1:: iis2mdc trig 993 1:: ism330dhcx acc trig 4447 diff --git a/samples/boards/st/steval_stwinbx1/sensors/src/main.c b/samples/boards/st/steval_stwinbx1/sensors/src/main.c index 5e4131eff6da7e..eda5982b96fb1d 100644 --- a/samples/boards/st/steval_stwinbx1/sensors/src/main.c +++ b/samples/boards/st/steval_stwinbx1/sensors/src/main.c @@ -238,6 +238,21 @@ static void ism330dhcx_config(const struct device *ism330dhcx) #endif } +static void ilps22qs_config(const struct device *ilps22qs) +{ + struct sensor_value odr_attr; + + /* set ILPS22QS sampling frequency to 50 Hz */ + odr_attr.val1 = 50; + odr_attr.val2 = 0; + + if (sensor_attr_set(ilps22qs, SENSOR_CHAN_ALL, + SENSOR_ATTR_SAMPLING_FREQUENCY, &odr_attr) < 0) { + printk("Cannot set sampling frequency for ILPS22QS\n"); + return; + } +} + static int led_pattern_out(void) { const struct gpio_dt_spec led0_gpio = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios); @@ -295,6 +310,7 @@ int main(void) const struct device *const ism330dhcx = DEVICE_DT_GET_ONE(st_ism330dhcx); const struct device *const iis2dlpc = DEVICE_DT_GET_ONE(st_iis2dlpc); const struct device *const iis2iclx = DEVICE_DT_GET_ONE(st_iis2iclx); + const struct device *const ilps22qs = DEVICE_DT_GET_ONE(st_ilps22qs); if (!device_is_ready(stts22h)) { printk("%s: device not ready.\n", stts22h->name); @@ -316,12 +332,17 @@ int main(void) printk("%s: device not ready.\n", iis2iclx->name); return 0; } + if (!device_is_ready(ilps22qs)) { + printk("%s: device not ready.\n", ilps22qs->name); + return 0; + } stts22h_config(stts22h); iis2mdc_config(iis2mdc); ism330dhcx_config(ism330dhcx); iis2dlpc_config(iis2dlpc); iis2iclx_config(iis2iclx); + ilps22qs_config(ilps22qs); while (1) { struct sensor_value stts22h_temp; @@ -331,6 +352,7 @@ int main(void) struct sensor_value ism330dhcx_accel[3]; struct sensor_value ism330dhcx_gyro[3]; struct sensor_value iis2iclx_accel[2]; + struct sensor_value ilps22qs_press, ilps22qs_temp; #ifndef CONFIG_STTS22H_TRIGGER if (sensor_sample_fetch(stts22h) < 0) { @@ -363,6 +385,11 @@ int main(void) } #endif + if (sensor_sample_fetch(ilps22qs) < 0) { + printf("ILPS22QS Sensor sample update error\n"); + return 0; + } + sensor_channel_get(stts22h, SENSOR_CHAN_AMBIENT_TEMP, &stts22h_temp); sensor_channel_get(iis2dlpc, SENSOR_CHAN_ACCEL_XYZ, iis2dlpc_accel); sensor_channel_get(iis2mdc, SENSOR_CHAN_MAGN_XYZ, iis2mdc_magn); @@ -370,6 +397,8 @@ int main(void) sensor_channel_get(ism330dhcx, SENSOR_CHAN_ACCEL_XYZ, ism330dhcx_accel); sensor_channel_get(ism330dhcx, SENSOR_CHAN_GYRO_XYZ, ism330dhcx_gyro); sensor_channel_get(iis2iclx, SENSOR_CHAN_ACCEL_XYZ, iis2iclx_accel); + sensor_channel_get(ilps22qs, SENSOR_CHAN_AMBIENT_TEMP, &ilps22qs_temp); + sensor_channel_get(ilps22qs, SENSOR_CHAN_PRESS, &ilps22qs_press); /* Display sensor data */ @@ -413,6 +442,14 @@ int main(void) sensor_value_to_double(&iis2iclx_accel[0]), sensor_value_to_double(&iis2iclx_accel[1])); + /* temperature */ + printf("ILPS22QS: Temperature: %.1f C\n", + sensor_value_to_double(&ilps22qs_temp)); + + /* pressure */ + printf("ILPS22QS: Pressure: %.3f kpa\n", + sensor_value_to_double(&ilps22qs_press)); + #ifdef CONFIG_STTS22H_TRIGGER printk("%d:: stts22h trig %d\n", cnt, stts22h_trig_cnt); #endif diff --git a/tests/drivers/build_all/sensor/app.overlay b/tests/drivers/build_all/sensor/app.overlay index 5b1d17ce3fee24..6d558b4c7f42d7 100644 --- a/tests/drivers/build_all/sensor/app.overlay +++ b/tests/drivers/build_all/sensor/app.overlay @@ -145,7 +145,8 @@ <&test_gpio 0 0>, <&test_gpio 0 0>, <&test_gpio 0 0>, - <&test_gpio 0 0>; /* 0x2e */ + <&test_gpio 0 0>, + <&test_gpio 0 0>; /* 0x2f */ #include "spi.dtsi" }; diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 4d222494da256b..6e051b56c5d1e6 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -1087,3 +1087,12 @@ test_i2c_tmp1075: tmp1075@98 { consecutive-fault-measurements = <4>; interrupt-mode; }; + +test_i2c_ilps22qs: ilps22qs@99 { + compatible = "st,ilps22qs"; + reg = <0x99>; + status = "okay"; + odr = ; + lpf = ; + avg = ; +}; diff --git a/tests/drivers/build_all/sensor/i3c.dtsi b/tests/drivers/build_all/sensor/i3c.dtsi index d90c72bc1543ab..caf72488c1605a 100644 --- a/tests/drivers/build_all/sensor/i3c.dtsi +++ b/tests/drivers/build_all/sensor/i3c.dtsi @@ -30,3 +30,9 @@ test_i3c_lps28dfw: lps28dfw@300000803E0000003 { assigned-address = <0x3>; drdy-gpios = <&test_gpio 0 0>; }; + +test_i3c_ilps22qs: ilps22qs@400000803E0000004 { + compatible = "st,ilps22qs"; + reg = <0x3 0x00000803 0xE0000004>; + assigned-address = <0x4>; +}; diff --git a/tests/drivers/build_all/sensor/spi.dtsi b/tests/drivers/build_all/sensor/spi.dtsi index c173c5ccecb61f..60cb2bbbe7f6de 100644 --- a/tests/drivers/build_all/sensor/spi.dtsi +++ b/tests/drivers/build_all/sensor/spi.dtsi @@ -379,3 +379,10 @@ test_spi_tle9104: tle9104@2e { #sensor-cells = <0>; }; }; + +test_spi_ilps22qs: ilps22qs@2f { + compatible = "st,ilps22qs"; + reg = <0x2f>; + spi-max-frequency = <0>; + status = "okay"; +};