Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions drivers/sensor/adt7420/adt7420.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

Expand Down
8 changes: 5 additions & 3 deletions drivers/sensor/adt7420/adt7420.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand All @@ -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
};

Expand Down
95 changes: 66 additions & 29 deletions drivers/sensor/adt7420/adt7420_trigger.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,33 @@
#include <logging/log.h>
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;
Expand All @@ -33,23 +57,23 @@ 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,
struct gpio_callback *cb, u32_t pins)
{
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)
Expand All @@ -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);
}
}

Expand All @@ -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

Expand All @@ -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;

if (handler != NULL) {
drv_data->th_trigger = *trig;

setup_int(dev, true);

gpio_pin_enable_callback(drv_data->gpio, cfg->int_gpio);
/* Check whether already asserted */
int pv = gpio_pin_get(drv_data->gpio, cfg->int_pin);

if (pv > 0) {
handle_int(dev);
}
}

return 0;
}
Expand All @@ -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) {
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 -EIO;
return rc;
}

drv_data->dev = dev;

#if defined(CONFIG_ADT7420_TRIGGER_OWN_THREAD)
k_sem_init(&drv_data->gpio_sem, 0, UINT_MAX);

Expand All @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions dts/bindings/sensor/adi,adt7420.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
2 changes: 1 addition & 1 deletion samples/sensor/adt7420/boards/frdm_k64f.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@
compatible = "adi,adt7420";
reg = <0x48>;
label = "ADT7420";
int-gpios = <&gpioc 16 0>;
int-gpios = <&gpioc 16 GPIO_ACTIVE_LOW>;
};
};
2 changes: 1 addition & 1 deletion samples/sensor/adt7420/boards/nrf52_pca10040.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@
compatible = "adi,adt7420";
reg = <0x48>;
label = "ADT7420";
int-gpios = <&gpio0 11 0>;
int-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
};
};