diff --git a/drivers/sensor/adt7420/adt7420.c b/drivers/sensor/adt7420/adt7420.c index e1be0b25df5..7672d0bc623 100644 --- a/drivers/sensor/adt7420/adt7420.c +++ b/drivers/sensor/adt7420/adt7420.c @@ -219,8 +219,9 @@ static const struct adt7420_dev_config adt7420_config = { .i2c_port = DT_INST_0_ADI_ADT7420_BUS_NAME, .i2c_addr = DT_INST_0_ADI_ADT7420_BASE_ADDRESS, #ifdef CONFIG_ADT7420_TRIGGER - .gpio_port = DT_INST_0_ADI_ADT7420_INT_GPIOS_CONTROLLER, - .int_gpio = DT_INST_0_ADI_ADT7420_INT_GPIOS_PIN, + .int_pin = DT_INST_0_ADI_ADT7420_INT_GPIOS_PIN, + .int_flags = DT_INST_0_ADI_ADT7420_INT_GPIOS_FLAGS, + .int_name = DT_INST_0_ADI_ADT7420_INT_GPIOS_CONTROLLER, #endif }; diff --git a/drivers/sensor/adt7420/adt7420.h b/drivers/sensor/adt7420/adt7420.h index 1f378483f12..d0624abd679 100644 --- a/drivers/sensor/adt7420/adt7420.h +++ b/drivers/sensor/adt7420/adt7420.h @@ -68,13 +68,14 @@ struct adt7420_data { sensor_trigger_handler_t th_handler; struct sensor_trigger th_trigger; + struct device *dev; + #if defined(CONFIG_ADT7420_TRIGGER_OWN_THREAD) K_THREAD_STACK_MEMBER(thread_stack, CONFIG_ADT7420_THREAD_STACK_SIZE); struct k_sem gpio_sem; struct k_thread thread; #elif defined(CONFIG_ADT7420_TRIGGER_GLOBAL_THREAD) struct k_work work; - struct device *dev; #endif #endif /* CONFIG_ADT7420_TRIGGER */ @@ -84,8 +85,9 @@ struct adt7420_dev_config { const char *i2c_port; u16_t i2c_addr; #ifdef CONFIG_ADT7420_TRIGGER - const char *gpio_port; - u8_t int_gpio; + gpio_pin_t int_pin; + gpio_flags_t int_flags; + const char *int_name; #endif }; diff --git a/drivers/sensor/adt7420/adt7420_trigger.c b/drivers/sensor/adt7420/adt7420_trigger.c index 0d0e16c4399..3df0fa8379d 100644 --- a/drivers/sensor/adt7420/adt7420_trigger.c +++ b/drivers/sensor/adt7420/adt7420_trigger.c @@ -16,9 +16,33 @@ #include LOG_MODULE_DECLARE(ADT7420, CONFIG_SENSOR_LOG_LEVEL); -static void adt7420_thread_cb(void *arg) +static void setup_int(struct device *dev, + bool enable) +{ + struct adt7420_data *drv_data = dev->driver_data; + const struct adt7420_dev_config *cfg = dev->config->config_info; + gpio_flags_t flags = enable + ? GPIO_INT_EDGE_TO_ACTIVE + : GPIO_INT_DISABLE; + + gpio_pin_interrupt_configure(drv_data->gpio, cfg->int_pin, flags); +} + +static void handle_int(struct device *dev) +{ + struct adt7420_data *drv_data = dev->driver_data; + + setup_int(dev, false); + +#if defined(CONFIG_ADT7420_TRIGGER_OWN_THREAD) + k_sem_give(&drv_data->gpio_sem); +#elif defined(CONFIG_ADT7420_TRIGGER_GLOBAL_THREAD) + k_work_submit(&drv_data->work); +#endif +} + +static void process_int(struct device *dev) { - struct device *dev = arg; struct adt7420_data *drv_data = dev->driver_data; const struct adt7420_dev_config *cfg = dev->config->config_info; u8_t status; @@ -33,7 +57,14 @@ static void adt7420_thread_cb(void *arg) drv_data->th_handler(dev, &drv_data->th_trigger); } - gpio_pin_enable_callback(drv_data->gpio, cfg->int_gpio); + setup_int(dev, true); + + /* Check for pin that asserted while we were offline */ + int pv = gpio_pin_get(drv_data->gpio, cfg->int_pin); + + if (pv > 0) { + handle_int(dev); + } } static void adt7420_gpio_callback(struct device *dev, @@ -41,15 +72,8 @@ static void adt7420_gpio_callback(struct device *dev, { struct adt7420_data *drv_data = CONTAINER_OF(cb, struct adt7420_data, gpio_cb); - const struct adt7420_dev_config *cfg = dev->config->config_info; - gpio_pin_disable_callback(dev, cfg->int_gpio); - -#if defined(CONFIG_ADT7420_TRIGGER_OWN_THREAD) - k_sem_give(&drv_data->gpio_sem); -#elif defined(CONFIG_ADT7420_TRIGGER_GLOBAL_THREAD) - k_work_submit(&drv_data->work); -#endif + handle_int(drv_data->dev); } #if defined(CONFIG_ADT7420_TRIGGER_OWN_THREAD) @@ -62,7 +86,7 @@ static void adt7420_thread(int dev_ptr, int unused) while (true) { k_sem_take(&drv_data->gpio_sem, K_FOREVER); - adt7420_thread_cb(dev); + process_int(dev); } } @@ -71,7 +95,8 @@ static void adt7420_work_cb(struct k_work *work) { struct adt7420_data *drv_data = CONTAINER_OF(work, struct adt7420_data, work); - adt7420_thread_cb(drv_data->dev); + + process_int(drv_data->dev); } #endif @@ -82,17 +107,26 @@ int adt7420_trigger_set(struct device *dev, struct adt7420_data *drv_data = dev->driver_data; const struct adt7420_dev_config *cfg = dev->config->config_info; - gpio_pin_disable_callback(drv_data->gpio, cfg->int_gpio); + setup_int(dev, false); - if (trig->type == SENSOR_TRIG_THRESHOLD) { - drv_data->th_handler = handler; - drv_data->th_trigger = *trig; - } else { + if (trig->type != SENSOR_TRIG_THRESHOLD) { LOG_ERR("Unsupported sensor trigger"); return -ENOTSUP; } + drv_data->th_handler = handler; - gpio_pin_enable_callback(drv_data->gpio, cfg->int_gpio); + if (handler != NULL) { + drv_data->th_trigger = *trig; + + setup_int(dev, true); + + /* Check whether already asserted */ + int pv = gpio_pin_get(drv_data->gpio, cfg->int_pin); + + if (pv > 0) { + handle_int(dev); + } + } return 0; } @@ -102,26 +136,30 @@ int adt7420_init_interrupt(struct device *dev) struct adt7420_data *drv_data = dev->driver_data; const struct adt7420_dev_config *cfg = dev->config->config_info; - drv_data->gpio = device_get_binding(cfg->gpio_port); + drv_data->gpio = device_get_binding(cfg->int_name); if (drv_data->gpio == NULL) { LOG_DBG("Failed to get pointer to %s device!", - cfg->gpio_port); + cfg->int_name); return -EINVAL; } - gpio_pin_configure(drv_data->gpio, cfg->int_gpio, - GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE | - GPIO_INT_ACTIVE_LOW | GPIO_INT_DEBOUNCE); - gpio_init_callback(&drv_data->gpio_cb, adt7420_gpio_callback, - BIT(cfg->int_gpio)); + BIT(cfg->int_pin)); - if (gpio_add_callback(drv_data->gpio, &drv_data->gpio_cb) < 0) { - LOG_DBG("Failed to set gpio callback!"); - return -EIO; + int rc = gpio_pin_configure(drv_data->gpio, cfg->int_pin, + GPIO_INPUT | cfg->int_flags); + if (rc == 0) { + gpio_add_callback(drv_data->gpio, &drv_data->gpio_cb); } + if (rc != 0) { + LOG_DBG("Failed to set gpio callback!"); + return rc; + } + + drv_data->dev = dev; + #if defined(CONFIG_ADT7420_TRIGGER_OWN_THREAD) k_sem_init(&drv_data->gpio_sem, 0, UINT_MAX); @@ -132,7 +170,6 @@ int adt7420_init_interrupt(struct device *dev) 0, K_NO_WAIT); #elif defined(CONFIG_ADT7420_TRIGGER_GLOBAL_THREAD) drv_data->work.handler = adt7420_work_cb; - drv_data->dev = dev; #endif return 0; diff --git a/dts/bindings/sensor/adi,adt7420.yaml b/dts/bindings/sensor/adi,adt7420.yaml index d3e7c806d3a..0cd6293e0d5 100644 --- a/dts/bindings/sensor/adi,adt7420.yaml +++ b/dts/bindings/sensor/adi,adt7420.yaml @@ -11,3 +11,6 @@ properties: int-gpios: type: phandle-array required: false + description: | + The INT signal defaults to active low open drain, so requires a + pull-up on the board or in the flags cell of this entry. diff --git a/samples/sensor/adt7420/boards/frdm_k64f.overlay b/samples/sensor/adt7420/boards/frdm_k64f.overlay index f0292229aae..b90eaa52fce 100644 --- a/samples/sensor/adt7420/boards/frdm_k64f.overlay +++ b/samples/sensor/adt7420/boards/frdm_k64f.overlay @@ -11,6 +11,6 @@ compatible = "adi,adt7420"; reg = <0x48>; label = "ADT7420"; - int-gpios = <&gpioc 16 0>; + int-gpios = <&gpioc 16 GPIO_ACTIVE_LOW>; }; }; diff --git a/samples/sensor/adt7420/boards/nrf52_pca10040.overlay b/samples/sensor/adt7420/boards/nrf52_pca10040.overlay index 1b96a722768..d80ba8cc1e7 100644 --- a/samples/sensor/adt7420/boards/nrf52_pca10040.overlay +++ b/samples/sensor/adt7420/boards/nrf52_pca10040.overlay @@ -11,6 +11,6 @@ compatible = "adi,adt7420"; reg = <0x48>; label = "ADT7420"; - int-gpios = <&gpio0 11 0>; + int-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; }; };