From f1e4bb54c9c0c55e4312cfbf80567ed2c159e9f3 Mon Sep 17 00:00:00 2001 From: Peter Bigot Date: Sun, 1 Sep 2019 11:05:18 -0500 Subject: [PATCH] drivers: gpio_sx1509b: update to use new GPIO API Update driver code and board files to use new GPIO configuration flags such as GPIO_ACTIVE_LOW. Also add implementation of new port_* driver API. Tested on external SX1509B breakout board and Thingy:52. Signed-off-by: Peter Bigot --- CODEOWNERS | 1 + boards/arm/nrf52_pca20020/nrf52_pca20020.dts | 6 +- drivers/gpio/gpio_sx1509b.c | 505 +++++++++++------- .../boards/nrf52_pca20020.overlay | 13 + 4 files changed, 319 insertions(+), 206 deletions(-) create mode 100644 tests/drivers/gpio/gpio_basic_api/boards/nrf52_pca20020.overlay diff --git a/CODEOWNERS b/CODEOWNERS index f309ee6a1853f..499105243d00b 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -133,6 +133,7 @@ /drivers/flash/*stm32* @superna9999 /drivers/gpio/*ht16k33* @henrikbrixandersen /drivers/gpio/*stm32* @rsalveti @idlethread +/drivers/gpio/*sx1509b* @pabigot /drivers/hwinfo/ @alexanderwachter /drivers/i2s/i2s_ll_stm32* @avisconti /drivers/ieee802154/ @jukkar @tbursztyka diff --git a/boards/arm/nrf52_pca20020/nrf52_pca20020.dts b/boards/arm/nrf52_pca20020/nrf52_pca20020.dts index 4e31050b6b788..b20fdebab08f9 100644 --- a/boards/arm/nrf52_pca20020/nrf52_pca20020.dts +++ b/boards/arm/nrf52_pca20020/nrf52_pca20020.dts @@ -34,15 +34,15 @@ compatible = "gpio-leds"; /* Lightwell RGB */ led0: led_0 { - gpios = <&sx1509b 5 0>; + gpios = <&sx1509b 5 GPIO_ACTIVE_LOW>; label = "Green LED"; }; led1: led_1 { - gpios = <&sx1509b 6 0>; + gpios = <&sx1509b 6 GPIO_ACTIVE_LOW>; label = "Blue LED"; }; led2: led_2 { - gpios = <&sx1509b 7 0>; + gpios = <&sx1509b 7 GPIO_ACTIVE_LOW>; label = "Red LED"; }; }; diff --git a/drivers/gpio/gpio_sx1509b.c b/drivers/gpio/gpio_sx1509b.c index 34aa39a812419..a89c1c08ddcb7 100644 --- a/drivers/gpio/gpio_sx1509b.c +++ b/drivers/gpio/gpio_sx1509b.c @@ -1,5 +1,7 @@ /* * Copyright (c) 2018 Aapo Vienamo + * Copyright (c) 2018 Peter Bigot Consulting, LLC + * Copyright (c) 2019 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,39 +11,47 @@ #include #include #include -#include -#include +#include +#include #include #include -#ifdef CONFIG_HAS_DTS_I2C -#define CONFIG_GPIO_SX1509B_DEV_NAME DT_INST_0_SEMTECH_SX1509B_LABEL -#define CONFIG_GPIO_SX1509B_I2C_ADDR DT_INST_0_SEMTECH_SX1509B_BASE_ADDRESS -#define CONFIG_GPIO_SX1509B_I2C_MASTER_DEV_NAME DT_INST_0_SEMTECH_SX1509B_BUS_NAME -#endif - -/** Cache of the output configuration and data of the pins */ -struct gpio_sx1509b_pin_state { - u16_t input_disable; - u16_t pull_up; - u16_t pull_down; - u16_t open_drain; - u16_t polarity; - u16_t dir; - u16_t data; +#include +LOG_MODULE_REGISTER(sx1509b, CONFIG_GPIO_LOG_LEVEL); + +/* Number of pins supported by the device */ +#define NUM_PINS 16 + +/* Max to select all pins supported on the device. */ +#define ALL_PINS ((u16_t)BIT_MASK(NUM_PINS)) + +/* Reset delay is 2.5 ms, round up for Zephyr resolution */ +#define RESET_DELAY_MS 3 + +/** Cache of the output configuration and data of the pins. */ +struct sx1509b_pin_state { + u16_t input_disable; /* 0x00 */ + u16_t long_slew; /* 0x02 */ + u16_t low_drive; /* 0x04 */ + u16_t pull_up; /* 0x06 */ + u16_t pull_down; /* 0x08 */ + u16_t open_drain; /* 0x0A */ + u16_t polarity; /* 0x0C */ + u16_t dir; /* 0x0E */ + u16_t data; /* 0x10 */ }; /** Runtime driver data */ -struct gpio_sx1509b_drv_data { +struct sx1509b_drv_data { /* gpio_driver_data needs to be first */ struct gpio_driver_data common; struct device *i2c_master; - struct gpio_sx1509b_pin_state pin_state; + struct sx1509b_pin_state pin_state; struct k_sem lock; }; /** Configuration data */ -struct gpio_sx1509b_config { +struct sx1509b_config { const char *i2c_master_dev_name; u16_t i2c_slave_addr; }; @@ -49,32 +59,32 @@ struct gpio_sx1509b_config { /* General configuration register addresses */ enum { /* TODO: Add rest of the regs */ - SX1509B_REG_CLOCK = 0x1e, - SX1509B_REG_RESET = 0x7d, + SX1509B_REG_CLOCK = 0x1e, + SX1509B_REG_RESET = 0x7d, }; /* Magic values for softreset */ enum { - SX1509B_REG_RESET_MAGIC0 = 0x12, - SX1509B_REG_RESET_MAGIC1 = 0x34, + SX1509B_REG_RESET_MAGIC0 = 0x12, + SX1509B_REG_RESET_MAGIC1 = 0x34, }; /* Register bits for SX1509B_REG_CLOCK */ enum { - SX1509B_REG_CLOCK_FOSC_OFF = 0 << 5, - SX1509B_REG_CLOCK_FOSC_EXT = 1 << 5, - SX1509B_REG_CLOCK_FOSC_INT_2MHZ = 2 << 5, + SX1509B_REG_CLOCK_FOSC_OFF = 0 << 5, + SX1509B_REG_CLOCK_FOSC_EXT = 1 << 5, + SX1509B_REG_CLOCK_FOSC_INT_2MHZ = 2 << 5, }; /* Pin configuration register addresses */ enum { - SX1509B_REG_INPUT_DISABLE = 0x00, - SX1509B_REG_PULL_UP = 0x06, - SX1509B_REG_PULL_DOWN = 0x08, - SX1509B_REG_OPEN_DRAIN = 0x0a, - SX1509B_REG_DIR = 0x0e, - SX1509B_REG_DATA = 0x10, - SX1509B_REG_LED_DRIVER_ENABLE = 0x20, + SX1509B_REG_INPUT_DISABLE = 0x00, + SX1509B_REG_PULL_UP = 0x06, + SX1509B_REG_PULL_DOWN = 0x08, + SX1509B_REG_OPEN_DRAIN = 0x0a, + SX1509B_REG_DIR = 0x0e, + SX1509B_REG_DATA = 0x10, + SX1509B_REG_LED_DRIVER_ENABLE = 0x20, }; /** @@ -96,153 +106,241 @@ static inline int i2c_reg_write_word_be(struct device *dev, u16_t dev_addr, return i2c_write(dev, tx_buf, 3, dev_addr); } -/** - * @brief Configure pin or port - * - * @param dev Device struct of the SX1509B - * @param access_op Access operation (pin or port) - * @param pin The pin number - * @param flags Flags of pin or port - * - * @return 0 if successful, failed otherwise - */ -static int gpio_sx1509b_config(struct device *dev, int access_op, u32_t pin, - int flags) +static int sx1509b_config(struct device *dev, + int access_op, /* unused */ + u32_t pin, + int flags) { - const struct gpio_sx1509b_config *cfg = dev->config->config_info; - struct gpio_sx1509b_drv_data *drv_data = dev->driver_data; - struct gpio_sx1509b_pin_state *pins = &drv_data->pin_state; - int ret = 0; + const struct sx1509b_config *cfg = dev->config->config_info; + struct sx1509b_drv_data *drv_data = dev->driver_data; + struct sx1509b_pin_state *pins = &drv_data->pin_state; + + struct { + u8_t reg; + struct sx1509b_pin_state pins; + } __packed outbuf; + int rc = 0; + bool data_first = false; + + /* Can't do I2C bus operations from an ISR */ + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } - if (flags & GPIO_INT) { + /* Zephyr currently defines drive strength support based on + * the behavior and capabilities of the Nordic GPIO + * peripheral: strength defaults to low but can be set high, + * and is controlled independently for output levels. + * + * SX150x defaults to high strength, and does not support + * different strengths for different levels. + * + * Until something more general is available reject any + * attempt to set a non-default drive strength. + */ + if ((flags & (GPIO_DS_ALT_LOW | GPIO_DS_ALT_HIGH)) != 0) { return -ENOTSUP; } k_sem_take(&drv_data->lock, K_FOREVER); - switch (access_op) { - case GPIO_ACCESS_BY_PIN: - if ((flags & GPIO_DIR_MASK) == GPIO_DIR_IN) { - pins->dir |= BIT(pin); - pins->input_disable &= ~BIT(pin); - } else { - pins->dir &= ~BIT(pin); - pins->input_disable |= BIT(pin); - } - if ((flags & GPIO_PUD_MASK) == GPIO_PUD_PULL_UP) { - pins->pull_up |= BIT(pin); - } else { - pins->pull_up &= ~BIT(pin); - } - if ((flags & GPIO_PUD_MASK) == GPIO_PUD_PULL_DOWN) { - pins->pull_down |= BIT(pin); - } else { - pins->pull_down &= ~BIT(pin); - } - if ((flags & GPIO_PUD_MASK) == GPIO_PUD_NORMAL) { - pins->pull_up &= ~BIT(pin); - pins->pull_down &= ~BIT(pin); - } - if (flags & GPIO_DS_DISCONNECT_HIGH) { + pins->open_drain &= ~BIT(pin); + if ((flags & GPIO_SINGLE_ENDED) != 0) { + if ((flags & GPIO_LINE_OPEN_DRAIN) != 0) { pins->open_drain |= BIT(pin); } else { - pins->open_drain &= ~BIT(pin); - } - if (flags & GPIO_POL_INV) { - pins->polarity |= BIT(pin); - } else { - pins->polarity &= ~BIT(pin); - } - break; - case GPIO_ACCESS_BY_PORT: - if ((flags & GPIO_DIR_MASK) == GPIO_DIR_IN) { - pins->dir = 0xffff; - pins->input_disable = 0x0000; - } else { - pins->dir = 0x0000; - pins->input_disable = 0xffff; - } - if ((flags & GPIO_PUD_MASK) == GPIO_PUD_PULL_UP) { - pins->pull_up = 0xffff; - } else { - pins->pull_up = 0x0000; - } - if ((flags & GPIO_PUD_MASK) == GPIO_PUD_PULL_DOWN) { - pins->pull_down = 0xffff; - } else { - pins->pull_down = 0x0000; - } - if ((flags & GPIO_PUD_MASK) == GPIO_PUD_NORMAL) { - pins->pull_up = 0x0000; - pins->pull_down = 0x0000; - } - if (flags & GPIO_DS_DISCONNECT_HIGH) { - pins->open_drain = 0xffff; - } else { - pins->open_drain = 0x0000; - } - if (flags & GPIO_POL_INV) { - pins->polarity = 0xffff; - } else { - pins->polarity = 0x0000; + /* Open source not supported */ + rc = -ENOTSUP; + goto out; } - break; - default: - ret = -ENOTSUP; - goto out; } - ret = i2c_reg_write_word_be(drv_data->i2c_master, cfg->i2c_slave_addr, - SX1509B_REG_DIR, pins->dir); - if (ret) { - goto out; + if ((flags & GPIO_PULL_UP) != 0) { + pins->pull_up |= BIT(pin); + } else { + pins->pull_up &= ~BIT(pin); + } + if ((flags & GPIO_PULL_DOWN) != 0) { + pins->pull_down |= BIT(pin); + } else { + pins->pull_down &= ~BIT(pin); } - ret = i2c_reg_write_word_be(drv_data->i2c_master, cfg->i2c_slave_addr, - SX1509B_REG_INPUT_DISABLE, - pins->input_disable); - if (ret) { - goto out; + if ((flags & GPIO_INPUT) != 0) { + pins->input_disable &= ~BIT(pin); + } else { + pins->input_disable |= BIT(pin); } - ret = i2c_reg_write_word_be(drv_data->i2c_master, cfg->i2c_slave_addr, - SX1509B_REG_PULL_UP, - pins->pull_up); - if (ret) { - goto out; + if ((flags & GPIO_OUTPUT) != 0) { + pins->dir &= ~BIT(pin); + if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) { + pins->data &= ~BIT(pin); + } else if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) { + pins->data |= BIT(pin); + } + } else { + pins->dir |= BIT(pin); } - ret = i2c_reg_write_word_be(drv_data->i2c_master, cfg->i2c_slave_addr, - SX1509B_REG_PULL_DOWN, - pins->pull_down); - if (ret) { + outbuf.reg = SX1509B_REG_INPUT_DISABLE; + outbuf.pins.input_disable = sys_cpu_to_be16(pins->input_disable); + outbuf.pins.long_slew = sys_cpu_to_be16(pins->long_slew); + outbuf.pins.low_drive = sys_cpu_to_be16(pins->low_drive); + outbuf.pins.pull_up = sys_cpu_to_be16(pins->pull_up); + outbuf.pins.pull_down = sys_cpu_to_be16(pins->pull_down); + outbuf.pins.open_drain = sys_cpu_to_be16(pins->open_drain); + outbuf.pins.polarity = sys_cpu_to_be16(pins->polarity); + outbuf.pins.dir = sys_cpu_to_be16(pins->dir); + outbuf.pins.data = sys_cpu_to_be16(pins->data); + + LOG_DBG("CFG %u %x : ID %04x ; PU %04x ; PD %04x ; DIR %04x ; DAT %04x", + pin, flags, + pins->input_disable, pins->pull_up, pins->pull_down, + pins->dir, pins->data); + if (data_first) { + rc = i2c_reg_write_word_be(drv_data->i2c_master, + cfg->i2c_slave_addr, + SX1509B_REG_DATA, pins->data); + if (rc == 0) { + rc = i2c_write(drv_data->i2c_master, + &outbuf.reg, + sizeof(outbuf) - sizeof(pins->data), + cfg->i2c_slave_addr); + } + } else { + rc = i2c_write(drv_data->i2c_master, + &outbuf.reg, + sizeof(outbuf), + cfg->i2c_slave_addr); + } + +out: + k_sem_give(&drv_data->lock); + return rc; +} + +static int port_get(struct device *dev, + gpio_port_value_t *value) +{ + const struct sx1509b_config *cfg = dev->config->config_info; + struct sx1509b_drv_data *drv_data = dev->driver_data; + u16_t pin_data; + int rc = 0; + + /* Can't do I2C bus operations from an ISR */ + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + k_sem_take(&drv_data->lock, K_FOREVER); + + u8_t cmd = SX1509B_REG_DATA; + + rc = i2c_write_read(drv_data->i2c_master, cfg->i2c_slave_addr, + &cmd, sizeof(cmd), + &pin_data, sizeof(pin_data)); + LOG_DBG("read %04x got %d", sys_be16_to_cpu(pin_data), rc); + if (rc != 0) { goto out; } - ret = i2c_reg_write_word_be(drv_data->i2c_master, cfg->i2c_slave_addr, - SX1509B_REG_OPEN_DRAIN, - pins->open_drain); + *value = sys_be16_to_cpu(pin_data); out: k_sem_give(&drv_data->lock); + return rc; +} + +static int port_write(struct device *dev, + gpio_port_pins_t mask, + gpio_port_value_t value) +{ + const struct sx1509b_config *cfg = dev->config->config_info; + struct sx1509b_drv_data *drv_data = dev->driver_data; + u16_t *outp = &drv_data->pin_state.data; + + k_sem_take(&drv_data->lock, K_FOREVER); + + u16_t orig_out = *outp; + u16_t out = (orig_out & ~mask) | (u16_t)(value & mask); + int rc = i2c_reg_write_word_be(drv_data->i2c_master, cfg->i2c_slave_addr, + SX1509B_REG_DATA, out); + if (rc == 0) { + *outp = out; + } + + k_sem_give(&drv_data->lock); + + LOG_DBG("write %04x msk %04x val %04x => %04x: %d", orig_out, mask, value, out, rc); + + return rc; +} + +static int port_set_masked(struct device *dev, + gpio_port_pins_t mask, + gpio_port_value_t value) +{ + /* Can't do I2C bus operations from an ISR */ + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + if (mask & ~(gpio_port_pins_t)ALL_PINS) { + return -EINVAL; + } + + return port_write(dev, mask, value); +} + +static int port_set_bits(struct device *dev, + gpio_port_pins_t pins) +{ + return port_set_masked(dev, pins, pins); +} + +static int port_clear_bits(struct device *dev, + gpio_port_pins_t pins) +{ + return port_set_masked(dev, pins, 0); +} + +static int port_toggle_bits(struct device *dev, + gpio_port_pins_t pins) +{ + struct sx1509b_drv_data *drv_data = dev->driver_data; + + /* Can't do I2C bus operations from an ISR */ + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + if (pins & ~(gpio_port_pins_t)ALL_PINS) { + return -EINVAL; + } + + return port_write(dev, pins, + drv_data->pin_state.data ^ pins); +} + +static int pin_interrupt_configure(struct device *dev, + unsigned int pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + int ret = 0; + + if (mode != GPIO_INT_MODE_DISABLED) { + ret = -ENOTSUP; + } return ret; } -/** - * @brief Set the pin or port output - * - * @param dev Device struct of the SX1509B - * @param access_op Access operation (pin or port) - * @param pin The pin number - * @param value Value to set (0 or 1) - * - * @return 0 if successful, failed otherwise - */ -static int gpio_sx1509b_write(struct device *dev, int access_op, u32_t pin, - u32_t value) +static int sx1509b_write(struct device *dev, int access_op, u32_t pin, + u32_t value) { - const struct gpio_sx1509b_config *cfg = dev->config->config_info; - struct gpio_sx1509b_drv_data *drv_data = dev->driver_data; + const struct sx1509b_config *cfg = dev->config->config_info; + struct sx1509b_drv_data *drv_data = dev->driver_data; u16_t *pin_data = &drv_data->pin_state.data; int ret = 0; @@ -271,21 +369,11 @@ static int gpio_sx1509b_write(struct device *dev, int access_op, u32_t pin, return ret; } -/** - * @brief Read the pin or port data - * - * @param dev Device struct of the SX1509B - * @param access_op Access operation (pin or port) - * @param pin The pin number - * @param value Value of input pin(s) - * - * @return 0 if successful, failed otherwise - */ -static int gpio_sx1509b_read(struct device *dev, int access_op, u32_t pin, - u32_t *value) +static int sx1509b_read(struct device *dev, int access_op, u32_t pin, + u32_t *value) { - const struct gpio_sx1509b_config *cfg = dev->config->config_info; - struct gpio_sx1509b_drv_data *drv_data = dev->driver_data; + const struct sx1509b_config *cfg = dev->config->config_info; + struct sx1509b_drv_data *drv_data = dev->driver_data; u16_t pin_data; int ret; @@ -322,68 +410,79 @@ static int gpio_sx1509b_read(struct device *dev, int access_op, u32_t pin, * @param dev Device struct * @return 0 if successful, failed otherwise. */ -static int gpio_sx1509b_init(struct device *dev) +static int sx1509b_init(struct device *dev) { - const struct gpio_sx1509b_config *cfg = dev->config->config_info; - struct gpio_sx1509b_drv_data *drv_data = dev->driver_data; - int ret; + const struct sx1509b_config *cfg = dev->config->config_info; + struct sx1509b_drv_data *drv_data = dev->driver_data; + int rc; drv_data->i2c_master = device_get_binding(cfg->i2c_master_dev_name); if (!drv_data->i2c_master) { - ret = -EINVAL; + LOG_ERR("%s: no bus %s", dev->config->name, + cfg->i2c_master_dev_name); + rc = -EINVAL; goto out; } /* Reset state */ - drv_data->pin_state = (struct gpio_sx1509b_pin_state) { - .input_disable = 0x0000, - .pull_up = 0x0000, - .pull_down = 0x0000, - .open_drain = 0x0000, - .dir = 0xffff, - .data = 0xffff, + drv_data->pin_state = (struct sx1509b_pin_state) { + .dir = ALL_PINS, + .data = ALL_PINS, }; - ret = i2c_reg_write_byte(drv_data->i2c_master, cfg->i2c_slave_addr, - SX1509B_REG_RESET, SX1509B_REG_RESET_MAGIC0); - if (ret) { + rc = i2c_reg_write_byte(drv_data->i2c_master, cfg->i2c_slave_addr, + SX1509B_REG_RESET, SX1509B_REG_RESET_MAGIC0); + if (rc != 0) { + LOG_ERR("%s: reset m0 failed: %d\n", dev->config->name, rc); goto out; } - - ret = i2c_reg_write_byte(drv_data->i2c_master, cfg->i2c_slave_addr, - SX1509B_REG_RESET, SX1509B_REG_RESET_MAGIC1); - if (ret) { + rc = i2c_reg_write_byte(drv_data->i2c_master, cfg->i2c_slave_addr, + SX1509B_REG_RESET, SX1509B_REG_RESET_MAGIC1); + if (rc != 0) { goto out; } - ret = i2c_reg_write_byte(drv_data->i2c_master, cfg->i2c_slave_addr, - SX1509B_REG_CLOCK, - SX1509B_REG_CLOCK_FOSC_INT_2MHZ); - if (ret) { + k_sleep(K_MSEC(RESET_DELAY_MS)); + + rc = i2c_reg_write_byte(drv_data->i2c_master, cfg->i2c_slave_addr, + SX1509B_REG_CLOCK, + SX1509B_REG_CLOCK_FOSC_INT_2MHZ); + if (rc != 0) { goto out; } out: + if (rc != 0) { + LOG_ERR("%s init failed: %d", dev->config->name, rc); + } else { + LOG_INF("%s init ok", dev->config->name); + } k_sem_give(&drv_data->lock); - return ret; + return rc; } -static const struct gpio_sx1509b_config gpio_sx1509b_cfg = { - .i2c_master_dev_name = CONFIG_GPIO_SX1509B_I2C_MASTER_DEV_NAME, - .i2c_slave_addr = CONFIG_GPIO_SX1509B_I2C_ADDR, +static const struct gpio_driver_api api_table = { + .config = sx1509b_config, + .write = sx1509b_write, + .read = sx1509b_read, + .port_get_raw = port_get, + .port_set_masked_raw = port_set_masked, + .port_set_bits_raw = port_set_bits, + .port_clear_bits_raw = port_clear_bits, + .port_toggle_bits = port_toggle_bits, + .pin_interrupt_configure = pin_interrupt_configure, }; -static struct gpio_sx1509b_drv_data gpio_sx1509b_drvdata = { - .lock = Z_SEM_INITIALIZER(gpio_sx1509b_drvdata.lock, 1, 1), +static const struct sx1509b_config sx1509b_cfg = { + .i2c_master_dev_name = DT_INST_0_SEMTECH_SX1509B_BUS_NAME, + .i2c_slave_addr = DT_INST_0_SEMTECH_SX1509B_BASE_ADDRESS, }; -static const struct gpio_driver_api gpio_sx1509b_drv_api_funcs = { - .config = gpio_sx1509b_config, - .write = gpio_sx1509b_write, - .read = gpio_sx1509b_read, +static struct sx1509b_drv_data sx1509b_drvdata = { + .lock = Z_SEM_INITIALIZER(sx1509b_drvdata.lock, 1, 1), }; -DEVICE_AND_API_INIT(gpio_sx1509b, CONFIG_GPIO_SX1509B_DEV_NAME, - gpio_sx1509b_init, &gpio_sx1509b_drvdata, &gpio_sx1509b_cfg, +DEVICE_AND_API_INIT(sx1509b, DT_INST_0_SEMTECH_SX1509B_LABEL, + sx1509b_init, &sx1509b_drvdata, &sx1509b_cfg, POST_KERNEL, CONFIG_GPIO_SX1509B_INIT_PRIORITY, - &gpio_sx1509b_drv_api_funcs); + &api_table); diff --git a/tests/drivers/gpio/gpio_basic_api/boards/nrf52_pca20020.overlay b/tests/drivers/gpio/gpio_basic_api/boards/nrf52_pca20020.overlay new file mode 100644 index 0000000000000..1c23c216705a8 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/nrf52_pca20020.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2019 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + resources { + compatible = "test,gpio_basic_api"; + out-gpios = <&sx1509b 0 0>; /* EXT0 */ + in-gpios = <&sx1509b 1 0>; /* EXT1 */ + }; +};