diff --git a/boards/arm/mimxrt1015_evk/mimxrt1015_evk.dts b/boards/arm/mimxrt1015_evk/mimxrt1015_evk.dts index ee4731e1e59..e6db04c84d9 100644 --- a/boards/arm/mimxrt1015_evk/mimxrt1015_evk.dts +++ b/boards/arm/mimxrt1015_evk/mimxrt1015_evk.dts @@ -25,7 +25,7 @@ leds { compatible = "gpio-leds"; green_led: led-1 { - gpios = <&gpio3 21 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio3 21 GPIO_ACTIVE_LOW>; label = "User LD1"; }; }; @@ -34,7 +34,7 @@ compatible = "gpio-keys"; user_button: button-1 { label = "User SW4"; - gpios = <&gpio2 9 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio2 9 GPIO_ACTIVE_LOW>; }; }; diff --git a/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts b/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts index 946db6db0dd..72c12d36ab0 100644 --- a/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts +++ b/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts @@ -32,7 +32,7 @@ leds { compatible = "gpio-leds"; green_led: led-1 { - gpios = <&gpio1 5 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; label = "User LD1"; }; }; @@ -41,7 +41,7 @@ compatible = "gpio-keys"; user_button: button-1 { label = "User SW8"; - gpios = <&gpio5 0 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; }; }; diff --git a/boards/arm/mimxrt1050_evk/mimxrt1050_evk.dts b/boards/arm/mimxrt1050_evk/mimxrt1050_evk.dts index 80be9d6096a..07e0b797a4f 100644 --- a/boards/arm/mimxrt1050_evk/mimxrt1050_evk.dts +++ b/boards/arm/mimxrt1050_evk/mimxrt1050_evk.dts @@ -32,7 +32,7 @@ leds { compatible = "gpio-leds"; green_led: led_0 { - gpios = <&gpio1 9 0>; + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; label = "User LD1"; }; }; @@ -41,7 +41,7 @@ compatible = "gpio-keys"; user_button: button_0 { label = "User SW8"; - gpios = <&gpio5 0 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; }; }; diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts b/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts index 84e248994ca..888e8cefcb8 100644 --- a/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts @@ -32,7 +32,7 @@ leds { compatible = "gpio-leds"; green_led: led-1 { - gpios = <&gpio1 9 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; label = "User LD1"; }; }; @@ -41,7 +41,7 @@ compatible = "gpio-keys"; user_button: button-1 { label = "User SW8"; - gpios = <&gpio5 0 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; }; }; diff --git a/boards/arm/mimxrt1064_evk/mimxrt1064_evk.dts b/boards/arm/mimxrt1064_evk/mimxrt1064_evk.dts index cc31f82053a..b739fdd47d9 100644 --- a/boards/arm/mimxrt1064_evk/mimxrt1064_evk.dts +++ b/boards/arm/mimxrt1064_evk/mimxrt1064_evk.dts @@ -33,7 +33,7 @@ leds { compatible = "gpio-leds"; green_led: led-1 { - gpios = <&gpio1 9 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; label = "User LD1"; }; }; @@ -50,7 +50,7 @@ compatible = "gpio-keys"; user_button: button-1 { label = "User SW8"; - gpios = <&gpio5 0 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; }; }; diff --git a/drivers/gpio/gpio_mcux_igpio.c b/drivers/gpio/gpio_mcux_igpio.c index 2d5d3c74fce..37ebda34d4b 100644 --- a/drivers/gpio/gpio_mcux_igpio.c +++ b/drivers/gpio/gpio_mcux_igpio.c @@ -18,6 +18,8 @@ struct mcux_igpio_config { }; struct mcux_igpio_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data general; /* port ISR callback routine address */ sys_slist_t callbacks; /* pin callback routine enable flags, by pin number */ @@ -28,49 +30,34 @@ static int mcux_igpio_configure(struct device *dev, int access_op, u32_t pin, int flags) { const struct mcux_igpio_config *config = dev->config->config_info; - gpio_pin_config_t pin_config; - u32_t i; + GPIO_Type *base = config->base; - /* Check for an invalid pin configuration */ - if ((flags & GPIO_INT) && (flags & GPIO_DIR_OUT)) { - return -EINVAL; + if (((flags & GPIO_INPUT) != 0) && ((flags & GPIO_OUTPUT) != 0)) { + return -ENOTSUP; } - pin_config.direction = ((flags & GPIO_DIR_MASK) == GPIO_DIR_IN) - ? kGPIO_DigitalInput : kGPIO_DigitalOutput; - - pin_config.outputLogic = 0; - - if (flags & GPIO_INT) { - if (flags & GPIO_INT_EDGE) { - if (flags & GPIO_INT_ACTIVE_HIGH) { - pin_config.interruptMode = kGPIO_IntRisingEdge; - } else if (flags & GPIO_INT_DOUBLE_EDGE) { - pin_config.interruptMode = - kGPIO_IntRisingOrFallingEdge; - } else { - pin_config.interruptMode = - kGPIO_IntFallingEdge; - } - } else { /* GPIO_INT_LEVEL */ - if (flags & GPIO_INT_ACTIVE_HIGH) { - pin_config.interruptMode = kGPIO_IntHighLevel; - } else { - pin_config.interruptMode = kGPIO_IntLowLevel; - } - } - } else { - pin_config.interruptMode = kGPIO_NoIntmode; + if ((flags & GPIO_SINGLE_ENDED) != 0) { + return -ENOTSUP; } - if (access_op == GPIO_ACCESS_BY_PIN) { - GPIO_PinInit(config->base, pin, &pin_config); - } else { /* GPIO_ACCESS_BY_PORT */ - for (i = 0U; i < 32; i++) { - GPIO_PinInit(config->base, i, &pin_config); - } + if (((flags & GPIO_PULL_UP) != 0) || ((flags & GPIO_PULL_DOWN) != 0)) { + return -ENOTSUP; } + if (access_op == GPIO_ACCESS_BY_PORT) { + return -ENOTSUP; + } + + if (flags & GPIO_OUTPUT_INIT_HIGH) { + base->DR_SET = BIT(pin); + } + + if (flags & GPIO_OUTPUT_INIT_LOW) { + base->DR_CLEAR = BIT(pin); + } + + WRITE_BIT(base->GDIR, pin, flags & GPIO_OUTPUT); + return 0; } @@ -102,6 +89,103 @@ static int mcux_igpio_read(struct device *dev, return 0; } +static int mcux_igpio_port_get_raw(struct device *dev, u32_t *value) +{ + const struct mcux_igpio_config *config = dev->config->config_info; + GPIO_Type *base = config->base; + + *value = base->DR; + + return 0; +} + +static int mcux_igpio_port_set_masked_raw(struct device *dev, u32_t mask, + u32_t value) +{ + const struct mcux_igpio_config *config = dev->config->config_info; + GPIO_Type *base = config->base; + + base->DR = (base->DR & ~mask) | (mask & value); + + return 0; +} + +static int mcux_igpio_port_set_bits_raw(struct device *dev, u32_t mask) +{ + const struct mcux_igpio_config *config = dev->config->config_info; + GPIO_Type *base = config->base; + + base->DR_SET = mask; + + return 0; +} + +static int mcux_igpio_port_clear_bits_raw(struct device *dev, u32_t mask) +{ + const struct mcux_igpio_config *config = dev->config->config_info; + GPIO_Type *base = config->base; + + base->DR_CLEAR = mask; + + return 0; +} + +static int mcux_igpio_port_toggle_bits(struct device *dev, u32_t mask) +{ + const struct mcux_igpio_config *config = dev->config->config_info; + GPIO_Type *base = config->base; + + base->DR_TOGGLE = mask; + + return 0; +} + +static int mcux_igpio_pin_interrupt_configure(struct device *dev, + unsigned int pin, enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + const struct mcux_igpio_config *config = dev->config->config_info; + struct mcux_igpio_data *data = dev->driver_data; + GPIO_Type *base = config->base; + unsigned int key; + u8_t icr; + int shift; + + if ((mode == GPIO_INT_MODE_EDGE) && (trig == GPIO_INT_TRIG_LOW)) { + icr = 3; + } else if ((mode == GPIO_INT_MODE_EDGE) && + (trig == GPIO_INT_TRIG_HIGH)) { + icr = 2; + } else if ((mode == GPIO_INT_MODE_LEVEL) && + (trig == GPIO_INT_TRIG_HIGH)) { + icr = 1; + } else { + icr = 0; + } + + if (pin < 16) { + shift = 2 * pin; + base->ICR1 = (base->ICR1 & ~(3 << shift)) | (icr << shift); + } else if (pin < 32) { + shift = 2 * (pin - 16); + base->ICR2 = (base->ICR2 & ~(3 << shift)) | (icr << shift); + } else { + return -EINVAL; + } + + key = irq_lock(); + + WRITE_BIT(base->EDGE_SEL, pin, trig == GPIO_INT_TRIG_BOTH); + WRITE_BIT(base->ISR, pin, mode != GPIO_INT_MODE_DISABLED); + WRITE_BIT(base->IMR, pin, mode != GPIO_INT_MODE_DISABLED); + WRITE_BIT(data->pin_callback_enables, pin, + mode != GPIO_INT_MODE_DISABLED); + + irq_unlock(key); + + return 0; +} + static int mcux_igpio_manage_callback(struct device *dev, struct gpio_callback *callback, bool set) { @@ -113,15 +197,12 @@ static int mcux_igpio_manage_callback(struct device *dev, static int mcux_igpio_enable_callback(struct device *dev, int access_op, u32_t pin) { - const struct mcux_igpio_config *config = dev->config->config_info; struct mcux_igpio_data *data = dev->driver_data; if (access_op == GPIO_ACCESS_BY_PIN) { data->pin_callback_enables |= BIT(pin); - GPIO_PortEnableInterrupts(config->base, BIT(pin)); } else { data->pin_callback_enables = 0xFFFFFFFF; - GPIO_PortEnableInterrupts(config->base, 0xFFFFFFFF); } return 0; @@ -130,14 +211,11 @@ static int mcux_igpio_enable_callback(struct device *dev, static int mcux_igpio_disable_callback(struct device *dev, int access_op, u32_t pin) { - const struct mcux_igpio_config *config = dev->config->config_info; struct mcux_igpio_data *data = dev->driver_data; if (access_op == GPIO_ACCESS_BY_PIN) { - GPIO_PortDisableInterrupts(config->base, BIT(pin)); data->pin_callback_enables &= ~BIT(pin); } else { - GPIO_PortDisableInterrupts(config->base, 0); data->pin_callback_enables = 0U; } @@ -149,20 +227,26 @@ static void mcux_igpio_port_isr(void *arg) struct device *dev = (struct device *)arg; const struct mcux_igpio_config *config = dev->config->config_info; struct mcux_igpio_data *data = dev->driver_data; + GPIO_Type *base = config->base; u32_t enabled_int, int_flags; - int_flags = GPIO_PortGetInterruptFlags(config->base); + int_flags = base->ISR; enabled_int = int_flags & data->pin_callback_enables; + base->ISR = enabled_int; gpio_fire_callbacks(&data->callbacks, dev, enabled_int); - - GPIO_ClearPinsInterruptFlags(config->base, enabled_int); } static const struct gpio_driver_api mcux_igpio_driver_api = { .config = mcux_igpio_configure, .write = mcux_igpio_write, .read = mcux_igpio_read, + .port_get_raw = mcux_igpio_port_get_raw, + .port_set_masked_raw = mcux_igpio_port_set_masked_raw, + .port_set_bits_raw = mcux_igpio_port_set_bits_raw, + .port_clear_bits_raw = mcux_igpio_port_clear_bits_raw, + .port_toggle_bits = mcux_igpio_port_toggle_bits, + .pin_interrupt_configure = mcux_igpio_pin_interrupt_configure, .manage_callback = mcux_igpio_manage_callback, .enable_callback = mcux_igpio_enable_callback, .disable_callback = mcux_igpio_disable_callback,