diff --git a/drivers/sensor/ti_hdc20xx/ti_hdc20xx.c b/drivers/sensor/ti_hdc20xx/ti_hdc20xx.c index 87d62658e0c..61f690a10d1 100644 --- a/drivers/sensor/ti_hdc20xx/ti_hdc20xx.c +++ b/drivers/sensor/ti_hdc20xx/ti_hdc20xx.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -16,6 +17,7 @@ LOG_MODULE_REGISTER(TI_HDC20XX, CONFIG_SENSOR_LOG_LEVEL); /* Register addresses */ #define TI_HDC20XX_REG_TEMP 0x00 #define TI_HDC20XX_REG_HUMIDITY 0x02 +#define TI_HDC20XX_REG_INT_EN 0x07 #define TI_HDC20XX_REG_CONFIG 0x0E #define TI_HDC20XX_REG_MEAS_CFG 0x0F #define TI_HDC20XX_REG_MANUFACTURER_ID 0xFC @@ -26,7 +28,9 @@ LOG_MODULE_REGISTER(TI_HDC20XX, CONFIG_SENSOR_LOG_LEVEL); #define TI_HDC20XX_DEVICE_ID 0x07D0 /* Register bits */ +#define TI_HDC20XX_BIT_INT_EN_DRDY_EN 0x80 #define TI_HDC20XX_BIT_CONFIG_SOFT_RES 0x80 +#define TI_HDC20XX_BIT_CONFIG_DRDY_INT_EN 0x04 /* Reset time: not in the datasheet, but found by trial and error */ #define TI_HDC20XX_RESET_TIME K_MSEC(1) @@ -41,13 +45,27 @@ LOG_MODULE_REGISTER(TI_HDC20XX, CONFIG_SENSOR_LOG_LEVEL); struct ti_hdc20xx_config { struct i2c_dt_spec bus; + struct gpio_dt_spec gpio_int; }; struct ti_hdc20xx_data { + struct gpio_callback cb_int; + struct k_sem sem_int; + uint16_t t_sample; uint16_t rh_sample; }; +static void ti_hdc20xx_int_callback(const struct device *dev, + struct gpio_callback *cb, uint32_t pins) +{ + struct ti_hdc20xx_data *data = CONTAINER_OF(cb, struct ti_hdc20xx_data, cb_int); + + ARG_UNUSED(pins); + + k_sem_give(&data->sem_int); +} + static int ti_hdc20xx_sample_fetch(const struct device *dev, enum sensor_channel chan) { @@ -66,7 +84,11 @@ static int ti_hdc20xx_sample_fetch(const struct device *dev, } /* wait for the conversion to finish */ - k_sleep(TI_HDC20XX_CONVERSION_TIME); + if (config->gpio_int.port) { + k_sem_take(&data->sem_int, K_FOREVER); + } else { + k_sleep(TI_HDC20XX_CONVERSION_TIME); + } /* temperature and humidity registers are consecutive, read them in the same burst */ rc = i2c_burst_read_dt(&config->bus, TI_HDC20XX_REG_TEMP, (uint8_t *)buf, sizeof(buf)); @@ -136,6 +158,7 @@ static int ti_hdc20xx_reset(const struct device *dev) static int ti_hdc20xx_init(const struct device *dev) { const struct ti_hdc20xx_config *config = dev->config; + struct ti_hdc20xx_data *data = dev->data; uint16_t buf[2]; int rc; @@ -167,6 +190,54 @@ static int ti_hdc20xx_init(const struct device *dev) return rc; } + /* Configure the interrupt GPIO if available */ + if (config->gpio_int.port) { + if (!device_is_ready(config->gpio_int.port)) { + LOG_ERR("Cannot get pointer to gpio interrupt device"); + return -ENODEV; + } + + rc = gpio_pin_configure_dt(&config->gpio_int, GPIO_INPUT); + if (rc) { + LOG_ERR("Failed to configure interrupt pin"); + return rc; + } + + gpio_init_callback(&data->cb_int, ti_hdc20xx_int_callback, + BIT(config->gpio_int.pin)); + + rc = gpio_add_callback(config->gpio_int.port, &data->cb_int); + if (rc) { + LOG_ERR("Failed to set interrupt callback"); + return rc; + } + + rc = gpio_pin_interrupt_configure_dt(&config->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); + if (rc) { + LOG_ERR("Failed to configure interrupt"); + return rc; + } + + /* Initialize the semaphore */ + k_sem_init(&data->sem_int, 0, K_SEM_MAX_LIMIT); + + /* Enable the data ready interrupt */ + rc = i2c_reg_write_byte_dt(&config->bus, TI_HDC20XX_REG_INT_EN, + TI_HDC20XX_BIT_INT_EN_DRDY_EN); + if (rc) { + LOG_ERR("Failed to enable the data ready interrupt"); + return rc; + } + + /* Enable the interrupt pin with level sensitive active low polarity */ + rc = i2c_reg_write_byte_dt(&config->bus, TI_HDC20XX_REG_CONFIG, + TI_HDC20XX_BIT_CONFIG_DRDY_INT_EN); + if (rc) { + LOG_ERR("Failed to enable the interrupt pin"); + return rc; + } + } + return 0; } @@ -175,6 +246,7 @@ static int ti_hdc20xx_init(const struct device *dev) static struct ti_hdc20xx_data ti_hdc20xx_data_##compat##inst; \ static const struct ti_hdc20xx_config ti_hdc20xx_config_##compat##inst = { \ .bus = I2C_DT_SPEC_GET(DT_INST(inst, compat)), \ + .gpio_int = GPIO_DT_SPEC_GET_OR(DT_INST(inst, compat), int_gpios, {0}), \ }; \ DEVICE_DT_DEFINE(DT_INST(inst, compat), \ ti_hdc20xx_init, \ diff --git a/dts/bindings/sensor/ti,hdc20xx.yaml b/dts/bindings/sensor/ti,hdc20xx.yaml index bb6be59eea9..ddd5d6c6930 100644 --- a/dts/bindings/sensor/ti,hdc20xx.yaml +++ b/dts/bindings/sensor/ti,hdc20xx.yaml @@ -6,3 +6,13 @@ description: Texas Instruments HDC20XX Temperature and Humidity Sensor compatible: "ti,hdc20xx" include: i2c-device.yaml + +properties: + int-gpios: + type: phandle-array + required: false + description: DRDY/INT pin. + + The DRDY/INT pin of HDC20xx sensor is open-drain, active low. If + connected directly the MCU pin should be configured as pull-up + as pull-up, active low.