diff --git a/boards/arm/reel_board/dts/reel_board.dtsi b/boards/arm/reel_board/dts/reel_board.dtsi index 2b71117fa72..f1f37d07006 100644 --- a/boards/arm/reel_board/dts/reel_board.dtsi +++ b/boards/arm/reel_board/dts/reel_board.dtsi @@ -139,7 +139,7 @@ arduino_i2c: &i2c0 { compatible = "avago,apds9960"; reg = <0x39>; label = "APDS9960"; - int-gpios = <&gpio0 23 0>; + int-gpios = <&gpio0 23 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; }; }; diff --git a/drivers/sensor/apds9960/apds9960.c b/drivers/sensor/apds9960/apds9960.c index 21a293c24e5..390956c47b5 100644 --- a/drivers/sensor/apds9960/apds9960.c +++ b/drivers/sensor/apds9960/apds9960.c @@ -23,13 +23,9 @@ LOG_MODULE_REGISTER(APDS9960, CONFIG_SENSOR_LOG_LEVEL); -static void apds9960_gpio_callback(struct device *dev, - struct gpio_callback *cb, u32_t pins) +static void apds9960_handle_cb(struct apds9960_data *drv_data) { - struct apds9960_data *drv_data = - CONTAINER_OF(cb, struct apds9960_data, gpio_cb); - - gpio_pin_disable_callback(dev, drv_data->gpio_pin); + apds9960_setup_int(drv_data, false); #ifdef CONFIG_APDS9960_TRIGGER k_work_submit(&drv_data->work); @@ -38,6 +34,15 @@ static void apds9960_gpio_callback(struct device *dev, #endif } +static void apds9960_gpio_callback(struct device *dev, + struct gpio_callback *cb, u32_t pins) +{ + struct apds9960_data *drv_data = + CONTAINER_OF(cb, struct apds9960_data, gpio_cb); + + apds9960_handle_cb(drv_data); +} + static int apds9960_sample_fetch(struct device *dev, enum sensor_channel chan) { const struct apds9960_config *config = dev->config->config_info; @@ -50,7 +55,7 @@ static int apds9960_sample_fetch(struct device *dev, enum sensor_channel chan) } #ifndef CONFIG_APDS9960_TRIGGER - gpio_pin_enable_callback(data->gpio, config->gpio_pin); + apds9960_setup_int(data, true); #ifdef CONFIG_APDS9960_ENABLE_ALS tmp = APDS9960_ENABLE_PON | APDS9960_ENABLE_AIEN; @@ -365,9 +370,7 @@ static int apds9960_init_interrupt(struct device *dev) drv_data->gpio_pin = config->gpio_pin; gpio_pin_configure(drv_data->gpio, config->gpio_pin, - GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE | - GPIO_INT_ACTIVE_LOW | GPIO_INT_DEBOUNCE | - GPIO_PUD_PULL_UP); + GPIO_INPUT | config->gpio_flags); gpio_init_callback(&drv_data->gpio_cb, apds9960_gpio_callback, @@ -392,6 +395,12 @@ static int apds9960_init_interrupt(struct device *dev) #else k_sem_init(&drv_data->data_sem, 0, UINT_MAX); #endif + apds9960_setup_int(drv_data, true); + + if (gpio_pin_get(drv_data->gpio, drv_data->gpio_pin) > 0) { + apds9960_handle_cb(drv_data); + } + return 0; } @@ -485,6 +494,7 @@ static const struct apds9960_config apds9960_config = { .i2c_address = DT_INST_0_AVAGO_APDS9960_BASE_ADDRESS, .gpio_name = DT_INST_0_AVAGO_APDS9960_INT_GPIOS_CONTROLLER, .gpio_pin = DT_INST_0_AVAGO_APDS9960_INT_GPIOS_PIN, + .gpio_flags = DT_INST_0_AVAGO_APDS9960_INT_GPIOS_FLAGS, #if CONFIG_APDS9960_PGAIN_8X .pgain = APDS9960_PGAIN_8X, #elif CONFIG_APDS9960_PGAIN_4X diff --git a/drivers/sensor/apds9960/apds9960.h b/drivers/sensor/apds9960/apds9960.h index 7e0ed606157..cc920495d7c 100644 --- a/drivers/sensor/apds9960/apds9960.h +++ b/drivers/sensor/apds9960/apds9960.h @@ -216,6 +216,7 @@ struct apds9960_config { char *i2c_name; char *gpio_name; u8_t gpio_pin; + unsigned int gpio_flags; u8_t i2c_address; u8_t pgain; u8_t again; @@ -241,6 +242,18 @@ struct apds9960_data { #endif }; +static inline void apds9960_setup_int(struct apds9960_data *drv_data, + bool enable) +{ + unsigned int flags = enable + ? GPIO_INT_EDGE_TO_ACTIVE + : GPIO_INT_DISABLE; + + gpio_pin_interrupt_configure(drv_data->gpio, + drv_data->gpio_pin, + flags); +} + #ifdef CONFIG_APDS9960_TRIGGER void apds9960_work_cb(struct k_work *work); diff --git a/drivers/sensor/apds9960/apds9960_trigger.c b/drivers/sensor/apds9960/apds9960_trigger.c index 5a5f6725873..79388fa5b52 100644 --- a/drivers/sensor/apds9960/apds9960_trigger.c +++ b/drivers/sensor/apds9960/apds9960_trigger.c @@ -28,7 +28,7 @@ void apds9960_work_cb(struct k_work *work) data->p_th_handler(dev, &data->p_th_trigger); } - gpio_pin_enable_callback(data->gpio, data->gpio_pin); + apds9960_setup_int(data, true); } int apds9960_attr_set(struct device *dev, @@ -72,7 +72,7 @@ int apds9960_trigger_set(struct device *dev, const struct apds9960_config *config = dev->config->config_info; struct apds9960_data *data = dev->driver_data; - gpio_pin_disable_callback(data->gpio, config->gpio_pin); + apds9960_setup_int(data, false); switch (trig->type) { case SENSOR_TRIG_THRESHOLD: @@ -94,7 +94,10 @@ int apds9960_trigger_set(struct device *dev, return -ENOTSUP; } - gpio_pin_enable_callback(data->gpio, config->gpio_pin); + apds9960_setup_int(data, true); + if (gpio_pin_get(data->gpio, data->gpio_pin) > 0) { + k_work_submit(&data->work); + } return 0; } diff --git a/dts/bindings/sensor/avago,apds9960.yaml b/dts/bindings/sensor/avago,apds9960.yaml index c8fd993f958..fd254657585 100644 --- a/dts/bindings/sensor/avago,apds9960.yaml +++ b/dts/bindings/sensor/avago,apds9960.yaml @@ -11,3 +11,8 @@ properties: int-gpios: type: phandle-array required: true + description: Interrupt pin. + + The interrupt pin of APDS9960 is open-drain, active low. + If connected directly the MCU pin should be configured + as pull-up, active low.