From 63320ca7a85ebaab7ed656175a837338afe6abe4 Mon Sep 17 00:00:00 2001 From: Andrei Gansari Date: Thu, 26 Sep 2019 19:46:44 +0300 Subject: [PATCH 01/12] gpio: Update mcux lpc driver to use new gpio api Updates the mcux lpc driver and all associated boards to use new device tree compatible gpio configuration flags. Implements new port get/set/clear/toggle functions recently added to the gpio api. ISR functions to be added later. Signed-off-by: Andrei Gansari --- .../lpcxpresso54114/lpcxpresso54114_m4.dts | 6 +- .../lpcxpresso55s69/lpcxpresso55s69_cpu0.dts | 6 +- drivers/gpio/gpio_mcux_lpc.c | 98 ++++++++++++++++--- 3 files changed, 89 insertions(+), 21 deletions(-) diff --git a/boards/arm/lpcxpresso54114/lpcxpresso54114_m4.dts b/boards/arm/lpcxpresso54114/lpcxpresso54114_m4.dts index 6886b88411888..af47479ac4e97 100644 --- a/boards/arm/lpcxpresso54114/lpcxpresso54114_m4.dts +++ b/boards/arm/lpcxpresso54114/lpcxpresso54114_m4.dts @@ -30,15 +30,15 @@ compatible = "gpio-keys"; user_button_1: button_0 { label = "User SW1"; - gpios = <&gpio0 24 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio0 24 GPIO_ACTIVE_LOW>; }; user_button_2: button_1 { label = "User SW2"; - gpios = <&gpio0 31 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio0 31 GPIO_ACTIVE_LOW>; }; user_button_3: button_2 { label = "User SW3"; - gpios = <&gpio0 4 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio0 4 GPIO_ACTIVE_LOW>; }; }; }; diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts index 8bced3280fb65..b978290c6c7c6 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts @@ -30,15 +30,15 @@ compatible = "gpio-keys"; user_button_1: button_0 { label = "User SW1"; - gpios = <&gpio0 5 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>; }; user_button_2: button_1 { label = "User SW2"; - gpios = <&gpio1 18 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio1 18 GPIO_ACTIVE_LOW>; }; user_button_3: button_2 { label = "User SW3"; - gpios = <&gpio1 9 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; }; }; }; diff --git a/drivers/gpio/gpio_mcux_lpc.c b/drivers/gpio/gpio_mcux_lpc.c index cfbdc90a03784..6894ac4b65315 100644 --- a/drivers/gpio/gpio_mcux_lpc.c +++ b/drivers/gpio/gpio_mcux_lpc.c @@ -32,8 +32,7 @@ struct gpio_mcux_lpc_config { }; struct gpio_mcux_lpc_data { - /* gpio_driver_data needs to be first */ - struct gpio_driver_data common; + struct gpio_driver_data general; /* port ISR callback routine address */ sys_slist_t callbacks; /* pin callback routine enable flags, by pin number */ @@ -44,27 +43,34 @@ static int gpio_mcux_lpc_configure(struct device *dev, int access_op, u32_t pin, int flags) { const struct gpio_mcux_lpc_config *config = dev->config->config_info; + struct gpio_mcux_lpc_data *data = dev->driver_data; GPIO_Type *gpio_base = config->gpio_base; + u32_t port = config->port_no; - /* 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; } - /* Check if GPIO port supports interrupts */ - if (flags & GPIO_INT) { + if ((flags & GPIO_SINGLE_ENDED) != 0) { return -ENOTSUP; } /* supports access by pin now,you can add access by port when needed */ if (access_op == GPIO_ACCESS_BY_PIN) { - /* input-0,output-1 */ - if ((flags & GPIO_DIR_MASK) == GPIO_DIR_IN) { - gpio_base->DIR[config->port_no] &= ~(BIT(pin)); - } else { - gpio_base->SET[config->port_no] = BIT(pin); - gpio_base->DIR[config->port_no] |= BIT(pin); + WRITE_BIT(data->general.invert, pin, + flags & GPIO_ACTIVE_LOW); + + if (flags & GPIO_OUTPUT_INIT_HIGH) { + gpio_base->SET[port] = BIT(pin); } + + if (flags & GPIO_OUTPUT_INIT_LOW) { + gpio_base->CLR[port] = BIT(pin); + } + + /* input-0,output-1 */ + WRITE_BIT(gpio_base->DIR[port], pin, flags & GPIO_OUTPUT); + } else { return -EINVAL; @@ -78,15 +84,16 @@ static int gpio_mcux_lpc_write(struct device *dev, { const struct gpio_mcux_lpc_config *config = dev->config->config_info; GPIO_Type *gpio_base = config->gpio_base; + u32_t port = config->port_no; /* Check for an invalid pin number */ - if (pin >= ARRAY_SIZE(gpio_base->B[config->port_no])) { + if (pin >= ARRAY_SIZE(gpio_base->B[port])) { return -EINVAL; } if (access_op == GPIO_ACCESS_BY_PIN) { /* Set/Clear the data output for the respective pin */ - gpio_base->B[config->port_no][pin] = value; + gpio_base->B[port][pin] = value; } else { /* return an error for all other options */ return -EINVAL; } @@ -111,6 +118,62 @@ static int gpio_mcux_lpc_read(struct device *dev, return 0; } +static int gpio_mcux_lpc_port_get_raw(struct device *dev, u32_t *value) +{ + const struct gpio_mcux_lpc_config *config = dev->config->config_info; + GPIO_Type *gpio_base = config->gpio_base; + + *value = gpio_base->PIN[config->port_no]; + + return 0; +} + +static int gpio_mcux_lpc_port_set_masked_raw(struct device *dev, u32_t mask, + u32_t value) +{ + const struct gpio_mcux_lpc_config *config = dev->config->config_info; + GPIO_Type *gpio_base = config->gpio_base; + u32_t port = config->port_no; + + /* Writing 0 allows R+W, 1 disables the pin */ + gpio_base->MASK[port] = ~mask; + gpio_base->PIN[port] = value; + /* Enable back the pins, user won't assume pins remain masked*/ + gpio_base->MASK[port] = 0U; + + return 0; +} + +static int gpio_mcux_lpc_port_set_bits_raw(struct device *dev, u32_t mask) +{ + const struct gpio_mcux_lpc_config *config = dev->config->config_info; + GPIO_Type *gpio_base = config->gpio_base; + + gpio_base->SET[config->port_no] = mask; + + return 0; +} + +static int gpio_mcux_lpc_port_clear_bits_raw(struct device *dev, u32_t mask) +{ + const struct gpio_mcux_lpc_config *config = dev->config->config_info; + GPIO_Type *gpio_base = config->gpio_base; + + gpio_base->CLR[config->port_no] = mask; + + return 0; +} + +static int gpio_mcux_lpc_port_toggle_bits(struct device *dev, u32_t mask) +{ + const struct gpio_mcux_lpc_config *config = dev->config->config_info; + GPIO_Type *gpio_base = config->gpio_base; + + gpio_base->NOT[config->port_no] = mask; + + return 0; +} + static int gpio_mcux_lpc_init(struct device *dev) { const struct gpio_mcux_lpc_config *config = dev->config->config_info; @@ -124,6 +187,11 @@ static const struct gpio_driver_api gpio_mcux_lpc_driver_api = { .config = gpio_mcux_lpc_configure, .write = gpio_mcux_lpc_write, .read = gpio_mcux_lpc_read, + .port_get_raw = gpio_mcux_lpc_port_get_raw, + .port_set_masked_raw = gpio_mcux_lpc_port_set_masked_raw, + .port_set_bits_raw = gpio_mcux_lpc_port_set_bits_raw, + .port_clear_bits_raw = gpio_mcux_lpc_port_clear_bits_raw, + .port_toggle_bits = gpio_mcux_lpc_port_toggle_bits }; #ifdef CONFIG_GPIO_MCUX_LPC_PORT0 From 6568ded3002b2763d9e2a1c09bcff2ca494a6379 Mon Sep 17 00:00:00 2001 From: Andrei Gansari Date: Tue, 4 Jun 2019 09:03:13 +0300 Subject: [PATCH 02/12] dts: NXP LPC gpio updates NXP's LPC family of MCU's GPIOs parameters is udated. Boards LPC54xxx and LPC55xxx have updated values according pin and interrupt layout. Signed-off-by: Andrei Gansari --- dts/arm/nxp/nxp_lpc54xxx.dtsi | 4 ++-- dts/arm/nxp/nxp_lpc55S6x.dtsi | 28 ++++++++++++++++++++++------ dts/bindings/gpio/nxp,lpc-gpio.yaml | 26 ++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 dts/bindings/gpio/nxp,lpc-gpio.yaml diff --git a/dts/arm/nxp/nxp_lpc54xxx.dtsi b/dts/arm/nxp/nxp_lpc54xxx.dtsi index 31dad79df35a9..6f584e87c4cf5 100644 --- a/dts/arm/nxp/nxp_lpc54xxx.dtsi +++ b/dts/arm/nxp/nxp_lpc54xxx.dtsi @@ -58,7 +58,7 @@ }; gpio0: gpio@0 { - compatible = "nxp,kinetis-gpio"; + compatible = "nxp,lpc-gpio"; reg = <0x4008c000 0x2488>; interrupts = <2 2>; label = "GPIO_0"; @@ -67,7 +67,7 @@ }; gpio1: gpio@1 { - compatible = "nxp,kinetis-gpio"; + compatible = "nxp,lpc-gpio"; reg = <0x4008C000 0x2488>; interrupts = <3 2>; label = "GPIO_1"; diff --git a/dts/arm/nxp/nxp_lpc55S6x.dtsi b/dts/arm/nxp/nxp_lpc55S6x.dtsi index 094dc26a2fda8..1cf5e7d6a2237 100644 --- a/dts/arm/nxp/nxp_lpc55S6x.dtsi +++ b/dts/arm/nxp/nxp_lpc55S6x.dtsi @@ -63,23 +63,39 @@ status = "disabled"; }; - gpio0: gpio@0 { - compatible = "nxp,kinetis-gpio"; + gpio0:gpio@0 { + compatible = "nxp,lpc-gpio"; reg = <0x5008c000 0x2488>; - interrupts = <2 2>; + interrupts = <4 2>; label = "GPIO_0"; gpio-controller; #gpio-cells = <2>; }; - gpio1: gpio@1 { - compatible = "nxp,kinetis-gpio"; + gpio1:gpio@1 { + compatible = "nxp,lpc-gpio"; reg = <0x5008c000 0x2488>; - interrupts = <3 2>; + interrupts = <5 2>,<6 2>; label = "GPIO_1"; gpio-controller; #gpio-cells = <2>; }; + + gpio2:gpio@2 { + compatible = "nxp,lpc-gpio"; + reg = <0x5008c000 0x2488>; + label = "GPIO_2"; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio3:gpio@3 { + compatible = "nxp,lpc-gpio"; + reg = <0x5008c000 0x2488>; + label = "GPIO_3"; + gpio-controller; + #gpio-cells = <2>; + }; }; }; diff --git a/dts/bindings/gpio/nxp,lpc-gpio.yaml b/dts/bindings/gpio/nxp,lpc-gpio.yaml new file mode 100644 index 0000000000000..3b18a3ae9a28e --- /dev/null +++ b/dts/bindings/gpio/nxp,lpc-gpio.yaml @@ -0,0 +1,26 @@ +# Copyright (c) 2019, NXP +# SPDX-License-Identifier: Apache-2.0 + +title: LPC GPIO + +description: > + This is a representation of the LPC GPIO nodes + +compatible: "nxp,lpc-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + label: + required: true + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags +... \ No newline at end of file From 28d7000173d5049188211e58e8482f898a920da7 Mon Sep 17 00:00:00 2001 From: Andrei Gansari Date: Tue, 28 May 2019 16:24:10 +0300 Subject: [PATCH 03/12] boards: lpcxpresso55s69 pinmux macros refactor Board is refactored to use DTS generated value, not use magic numbers. Signed-off-by: Andrei Gansari --- boards/arm/lpcxpresso55s69/pinmux.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/boards/arm/lpcxpresso55s69/pinmux.c b/boards/arm/lpcxpresso55s69/pinmux.c index fd24f1f476805..73a23df14bc44 100644 --- a/boards/arm/lpcxpresso55s69/pinmux.c +++ b/boards/arm/lpcxpresso55s69/pinmux.c @@ -48,8 +48,8 @@ static int lpcxpresso_55s69_pinmux_init(struct device *dev) #endif -#ifdef CONFIG_GPIO_MCUX_LPC_PORT0 - const u32_t port0_pin5_config = ( +#ifdef DT_GPIO_KEYS_SW0_GPIO_CONTROLLER + const u32_t sw0_config = ( IOCON_PIO_FUNC0 | IOCON_PIO_MODE_PULLUP | IOCON_PIO_INV_DI | @@ -58,12 +58,11 @@ static int lpcxpresso_55s69_pinmux_init(struct device *dev) IOCON_PIO_SLEW_STANDARD | IOCON_PIO_OPENDRAIN_DI ); - - pinmux_pin_set(port0, 5, port0_pin5_config); + pinmux_pin_set(port0, DT_ALIAS_SW0_GPIOS_PIN, sw0_config); #endif -#ifdef CONFIG_GPIO_MCUX_LPC_PORT0 - const u32_t port1_pin18_config = ( +#ifdef DT_GPIO_KEYS_SW1_GPIO_CONTROLLER + const u32_t sw1_config = ( IOCON_PIO_FUNC0 | IOCON_PIO_MODE_PULLUP | IOCON_PIO_INV_DI | @@ -72,10 +71,11 @@ static int lpcxpresso_55s69_pinmux_init(struct device *dev) IOCON_PIO_SLEW_STANDARD | IOCON_PIO_OPENDRAIN_DI ); + pinmux_pin_set(port1, DT_ALIAS_SW0_GPIOS_PIN, sw1_config); +#endif - pinmux_pin_set(port1, 18, port1_pin18_config); - - const u32_t port1_pin9_config = ( +#ifdef DT_GPIO_KEYS_SW2_GPIO_CONTROLLER + const u32_t sw2_config = ( IOCON_PIO_FUNC0 | IOCON_PIO_MODE_PULLUP | IOCON_PIO_INV_DI | @@ -84,8 +84,7 @@ static int lpcxpresso_55s69_pinmux_init(struct device *dev) IOCON_PIO_SLEW_STANDARD | IOCON_PIO_OPENDRAIN_DI ); - - pinmux_pin_set(port1, 9, port1_pin9_config); + pinmux_pin_set(port1, DT_ALIAS_SW0_GPIOS_PIN, sw2_config); #endif return 0; From 64346d5937583c6e816dc587fd1856dc5c1cd4bf Mon Sep 17 00:00:00 2001 From: Andrei Gansari Date: Thu, 8 Aug 2019 14:17:29 +0300 Subject: [PATCH 04/12] soc: enable PINT device at LPC SoC boot PINT device is enabled when SoC is booting up. Applies to LPC54xxx and LPC55xxx families. Signed-off-by: Andrei Gansari --- soc/arm/nxp_lpc/lpc54xxx/soc.c | 6 ++++++ soc/arm/nxp_lpc/lpc55xxx/soc.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/soc/arm/nxp_lpc/lpc54xxx/soc.c b/soc/arm/nxp_lpc/lpc54xxx/soc.c index 869a85f9ef5b5..a9273d7769d91 100644 --- a/soc/arm/nxp_lpc/lpc54xxx/soc.c +++ b/soc/arm/nxp_lpc/lpc54xxx/soc.c @@ -24,6 +24,7 @@ #include #include #include +#include /** * @@ -90,6 +91,11 @@ static int nxp_lpc54114_init(struct device *arg) /* Initialize FRO/system clock to 48 MHz */ clock_init(); +#ifdef CONFIG_GPIO_MCUX_LPC + /* Turn on PINT device*/ + PINT_Init(PINT); +#endif + /* * install default handler that simply resets the CPU if configured in * the kernel, NOP otherwise diff --git a/soc/arm/nxp_lpc/lpc55xxx/soc.c b/soc/arm/nxp_lpc/lpc55xxx/soc.c index 8a7eb674f7651..47c5f43085158 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/soc.c +++ b/soc/arm/nxp_lpc/lpc55xxx/soc.c @@ -24,6 +24,7 @@ #include #include #include +#include /** * @@ -87,6 +88,11 @@ static int nxp_lpc55s69_init(struct device *arg) /* Initialize FRO/system clock to 48 MHz */ clock_init(); +#ifdef CONFIG_GPIO_MCUX_LPC + /* Turn on PINT device*/ + PINT_Init(PINT); +#endif + /* * install default handler that simply resets the CPU if configured in * the kernel, NOP otherwise From 82300ad1db65fd99d9bd0e8d9896d3f57348f912 Mon Sep 17 00:00:00 2001 From: Andrei Gansari Date: Wed, 9 Oct 2019 14:38:01 +0300 Subject: [PATCH 05/12] west.yaml: hal_nxp updated to latest commit Use the latest commit available in hal_nxp repository. Signed-off-by: Andrei Gansari --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 25d8890834d35..9516661f504df 100644 --- a/west.yml +++ b/west.yml @@ -83,7 +83,7 @@ manifest: revision: bc62a2fa9d98ddb5d633c932ea199bc68e10f194 path: modules/fs/nffs - name: hal_nxp - revision: 97265a5396edc6a9de5f2fb643d505f37064e606 + revision: 47914cb291b3cfdea8248bd15787d7d733f71729 path: modules/hal/nxp - name: open-amp revision: 9b591b289e1f37339bd038b5a1f0e6c8ad39c63a From 67f6c37959fc716dc21cda1d6e98fcb71a2a6c01 Mon Sep 17 00:00:00 2001 From: Andrei Gansari Date: Wed, 9 Oct 2019 14:52:07 +0300 Subject: [PATCH 06/12] soc: LPC55xxx clock comment fix SoC initialization had an incorrect comment regarding system clock. Corrected from 48Mhz -> 96Mhz. Signed-off-by: Andrei Gansari --- soc/arm/nxp_lpc/lpc55xxx/soc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/arm/nxp_lpc/lpc55xxx/soc.c b/soc/arm/nxp_lpc/lpc55xxx/soc.c index 47c5f43085158..29e25342185d8 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/soc.c +++ b/soc/arm/nxp_lpc/lpc55xxx/soc.c @@ -85,7 +85,7 @@ static int nxp_lpc55s69_init(struct device *arg) z_arm_clear_faults(); - /* Initialize FRO/system clock to 48 MHz */ + /* Initialize FRO/system clock to 96 MHz */ clock_init(); #ifdef CONFIG_GPIO_MCUX_LPC From 1fab3c52561bdcd37c37141e43967e03c0614bf4 Mon Sep 17 00:00:00 2001 From: Andrei Gansari Date: Wed, 9 Oct 2019 15:21:40 +0300 Subject: [PATCH 07/12] tests: gpio_basic_api fix bad message Pull-up replaced by pull-down in particular test_gpio_port. Signed-off-by: Andrei Gansari --- tests/drivers/gpio/gpio_basic_api/src/test_gpio_port.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/drivers/gpio/gpio_basic_api/src/test_gpio_port.c b/tests/drivers/gpio/gpio_basic_api/src/test_gpio_port.c index a97b5610c3b46..55b16ad21ba84 100644 --- a/tests/drivers/gpio/gpio_basic_api/src/test_gpio_port.c +++ b/tests/drivers/gpio/gpio_basic_api/src/test_gpio_port.c @@ -415,7 +415,7 @@ static int check_pulls(void) return TC_FAIL; } zassert_equal(raw_in(), false, - "logical pull-up does not read low"); + "logical pull-down does not read low"); zassert_equal(logic_in(), true, "logical pull-down reads false"); From 2ddfddb9c1b49eae02959f0d8d40b7d93470a698 Mon Sep 17 00:00:00 2001 From: Andrei Gansari Date: Wed, 9 Oct 2019 15:26:43 +0300 Subject: [PATCH 08/12] tests: add LPC boards to gpio_basic_api LPC54114 to use D0 and D1 pinout. LPC55S69 to use A0 and A1 pinout. 2 pin test gpio_basic_api uses pins set up in boars' pinmux. Signed-off-by: Andrei Gansari --- .../boards/lpcxpresso54114_m4.overlay | 13 +++++++++++++ .../boards/lpcxpresso55s69_cpu0.overlay | 13 +++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 tests/drivers/gpio/gpio_basic_api/boards/lpcxpresso54114_m4.overlay create mode 100644 tests/drivers/gpio/gpio_basic_api/boards/lpcxpresso55s69_cpu0.overlay diff --git a/tests/drivers/gpio/gpio_basic_api/boards/lpcxpresso54114_m4.overlay b/tests/drivers/gpio/gpio_basic_api/boards/lpcxpresso54114_m4.overlay new file mode 100644 index 0000000000000..1c161abe96232 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/lpcxpresso54114_m4.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2019, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + resources { + compatible = "test,gpio_basic_api"; + out-gpios = <&gpio0 8 0>; /* Arduino D0 */ + in-gpios = <&gpio0 9 0>; /* Arduino D1 */ + }; +}; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/lpcxpresso55s69_cpu0.overlay b/tests/drivers/gpio/gpio_basic_api/boards/lpcxpresso55s69_cpu0.overlay new file mode 100644 index 0000000000000..cecc632da6d39 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/lpcxpresso55s69_cpu0.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2019, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + resources { + compatible = "test,gpio_basic_api"; + out-gpios = <&gpio0 16 0>; /* Arduino A0 */ + in-gpios = <&gpio0 23 0>; /* Arduino A1 */ + }; +}; From 3fd9c6d1c7db8052037644d550d542ee6b9ce485 Mon Sep 17 00:00:00 2001 From: Andrei Gansari Date: Wed, 9 Oct 2019 15:24:23 +0300 Subject: [PATCH 09/12] tests: lpc devices test pins enablement LPC54114 to use D0 and D1 pinout. LPC55S69 to use A0 and A1 pinout. Pins enabled to be used as GPIO for 2 pin test gpio_basic_api. Signed-off-by: Andrei Gansari --- boards/arm/lpcxpresso54114/pinmux.c | 1 + boards/arm/lpcxpresso55s69/pinmux.c | 4 +-- tests/drivers/gpio/gpio_basic_api/src/main.c | 28 ++++++++++++++------ 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/boards/arm/lpcxpresso54114/pinmux.c b/boards/arm/lpcxpresso54114/pinmux.c index eb1abb2b4da7d..7cb6e23f25e76 100644 --- a/boards/arm/lpcxpresso54114/pinmux.c +++ b/boards/arm/lpcxpresso54114/pinmux.c @@ -90,6 +90,7 @@ static int lpcxpresso_54114_pinmux_init(struct device *dev) IOCON_PIO_OPENDRAIN_DI ); pinmux_pin_set(port0, 4, port0_pin4_config); + #endif #ifdef CONFIG_GPIO_MCUX_LPC_PORT1 diff --git a/boards/arm/lpcxpresso55s69/pinmux.c b/boards/arm/lpcxpresso55s69/pinmux.c index 73a23df14bc44..8380adc6bd88e 100644 --- a/boards/arm/lpcxpresso55s69/pinmux.c +++ b/boards/arm/lpcxpresso55s69/pinmux.c @@ -71,7 +71,7 @@ static int lpcxpresso_55s69_pinmux_init(struct device *dev) IOCON_PIO_SLEW_STANDARD | IOCON_PIO_OPENDRAIN_DI ); - pinmux_pin_set(port1, DT_ALIAS_SW0_GPIOS_PIN, sw1_config); + pinmux_pin_set(port1, DT_ALIAS_SW1_GPIOS_PIN, sw1_config); #endif #ifdef DT_GPIO_KEYS_SW2_GPIO_CONTROLLER @@ -84,7 +84,7 @@ static int lpcxpresso_55s69_pinmux_init(struct device *dev) IOCON_PIO_SLEW_STANDARD | IOCON_PIO_OPENDRAIN_DI ); - pinmux_pin_set(port1, DT_ALIAS_SW0_GPIOS_PIN, sw2_config); + pinmux_pin_set(port1, DT_ALIAS_SW2_GPIOS_PIN, sw2_config); #endif return 0; diff --git a/tests/drivers/gpio/gpio_basic_api/src/main.c b/tests/drivers/gpio/gpio_basic_api/src/main.c index a7dc9bda5925b..b4adadbcedfcd 100644 --- a/tests/drivers/gpio/gpio_basic_api/src/main.c +++ b/tests/drivers/gpio/gpio_basic_api/src/main.c @@ -8,15 +8,16 @@ #include "test_gpio.h" /* Grotesque hack for pinmux boards */ -#ifdef CONFIG_BOARD_FRDM_K64F +#if defined(CONFIG_BOARD_FRDM_K64F) #include #include #elif defined(CONFIG_BOARD_UDOO_NEO_FULL_M4) #include "device_imx.h" -#endif - -#ifdef CONFIG_BOARD_MIMXRT1050_EVK +#elif defined(CONFIG_BOARD_MIMXRT1050_EVK) #include +#elif defined(CONFIG_SOC_FAMILY_LPC) +#include +#include "soc.h" #endif static void board_setup(void) @@ -32,7 +33,7 @@ static void board_setup(void) } #endif -#ifdef CONFIG_BOARD_FRDM_K64F +#if defined(CONFIG_BOARD_FRDM_K64F) /* TODO figure out how to get this from "GPIO_2" */ const char *pmx_name = "portc"; struct device *pmx = device_get_binding(pmx_name); @@ -81,9 +82,7 @@ static void board_setup(void) IOMUXC_SW_PAD_CTL_PAD_RGMII2_RD3_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_RGMII2_RD3_SPEED(2) | IOMUXC_SW_PAD_CTL_PAD_RGMII2_RD3_DSE(6); -#endif - -#ifdef CONFIG_BOARD_MIMXRT1050_EVK +#elif defined(CONFIG_BOARD_MIMXRT1050_EVK) IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_06_GPIO1_IO22, 0); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_07_GPIO1_IO23, 0); @@ -97,6 +96,19 @@ static void board_setup(void) IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_SPEED(2) | IOMUXC_SW_PAD_CTL_PAD_DSE(6)); +#elif defined(CONFIG_SOC_FAMILY_LPC) + /* Assumes ARDUINO pins are mapped on PORT0 on all boards*/ + struct device *port0 = + device_get_binding(CONFIG_PINMUX_MCUX_LPC_PORT0_NAME); + const u32_t pin_config = ( + IOCON_PIO_FUNC0 | + IOCON_PIO_INV_DI | + IOCON_PIO_DIGITAL_EN | + IOCON_PIO_INPFILT_OFF | + IOCON_PIO_OPENDRAIN_DI + ); + pinmux_pin_set(port0, PIN_IN, pin_config); + pinmux_pin_set(port0, PIN_OUT, pin_config); #endif } From 7c07aeccf98bf8dda95e6ac5c6e9cb85f831c8fb Mon Sep 17 00:00:00 2001 From: Andrei Gansari Date: Wed, 9 Oct 2019 15:28:11 +0300 Subject: [PATCH 10/12] soc: define gpio pull-down for LPC54114 Add define that maps to IOCON register PULL-DOWN bit. Signed-off-by: Andrei Gansari --- soc/arm/nxp_lpc/lpc54xxx/soc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/arm/nxp_lpc/lpc54xxx/soc.h b/soc/arm/nxp_lpc/lpc54xxx/soc.h index 91d7dd0744ed3..3372c51ab1057 100644 --- a/soc/arm/nxp_lpc/lpc54xxx/soc.h +++ b/soc/arm/nxp_lpc/lpc54xxx/soc.h @@ -34,5 +34,6 @@ #define IOCON_PIO_OPENDRAIN_DI 0x00u #define IOCON_PIO_SLEW_STANDARD 0x00u #define IOCON_PIO_MODE_PULLUP 0x10u +#define IOCON_PIO_MODE_PULLDOWN 0x08u #endif /* _SOC__H_ */ From fe7eed3c7eb46e48b586c54e740f956b9cd66d62 Mon Sep 17 00:00:00 2001 From: Andrei Gansari Date: Wed, 9 Oct 2019 15:31:03 +0300 Subject: [PATCH 11/12] dts: lpc devices allocate all gpio interrupts Allocate all 8 PINT interrupts to ports 0 and 1, allocate 4 to each. Signed-off-by: Andrei Gansari --- dts/arm/nxp/nxp_lpc54xxx.dtsi | 4 ++-- dts/arm/nxp/nxp_lpc55S6x.dtsi | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dts/arm/nxp/nxp_lpc54xxx.dtsi b/dts/arm/nxp/nxp_lpc54xxx.dtsi index 6f584e87c4cf5..e12c316d0c62e 100644 --- a/dts/arm/nxp/nxp_lpc54xxx.dtsi +++ b/dts/arm/nxp/nxp_lpc54xxx.dtsi @@ -60,7 +60,7 @@ gpio0: gpio@0 { compatible = "nxp,lpc-gpio"; reg = <0x4008c000 0x2488>; - interrupts = <2 2>; + interrupts = <4 2>,<5 2>,<6 2>,<7 2>; label = "GPIO_0"; gpio-controller; #gpio-cells = <2>; @@ -69,7 +69,7 @@ gpio1: gpio@1 { compatible = "nxp,lpc-gpio"; reg = <0x4008C000 0x2488>; - interrupts = <3 2>; + interrupts = <32 2>,<33 2>,<34 2>,<35 2>; label = "GPIO_1"; gpio-controller; #gpio-cells = <2>; diff --git a/dts/arm/nxp/nxp_lpc55S6x.dtsi b/dts/arm/nxp/nxp_lpc55S6x.dtsi index 1cf5e7d6a2237..a8f7b732e1207 100644 --- a/dts/arm/nxp/nxp_lpc55S6x.dtsi +++ b/dts/arm/nxp/nxp_lpc55S6x.dtsi @@ -66,7 +66,7 @@ gpio0:gpio@0 { compatible = "nxp,lpc-gpio"; reg = <0x5008c000 0x2488>; - interrupts = <4 2>; + interrupts = <4 2>,<5 2>,<6 2>,<7 2>; label = "GPIO_0"; gpio-controller; #gpio-cells = <2>; @@ -75,7 +75,7 @@ gpio1:gpio@1 { compatible = "nxp,lpc-gpio"; reg = <0x5008c000 0x2488>; - interrupts = <5 2>,<6 2>; + interrupts = <32 2>,<33 2>,<34 2>,<35 2>; label = "GPIO_1"; gpio-controller; #gpio-cells = <2>; From b5344b514333c2e8373ec79a82bfa67951f68eca Mon Sep 17 00:00:00 2001 From: Andrei Gansari Date: Wed, 9 Oct 2019 15:33:08 +0300 Subject: [PATCH 12/12] drivers: gpio_mcux_lpc GPIO interrupts LPC GPIO architecture uses multiple devices. GPIO input is routed via INPUTMUX to the PINT device which roots the interrupt to NVIC. Signed-off-by: Andrei Gansari --- drivers/gpio/Kconfig.mcux_lpc | 1 + drivers/gpio/gpio_mcux_lpc.c | 363 +++++++++++++++++++++++++++++++--- 2 files changed, 336 insertions(+), 28 deletions(-) diff --git a/drivers/gpio/Kconfig.mcux_lpc b/drivers/gpio/Kconfig.mcux_lpc index b264158e4c05e..152e3b47e5ec4 100644 --- a/drivers/gpio/Kconfig.mcux_lpc +++ b/drivers/gpio/Kconfig.mcux_lpc @@ -8,6 +8,7 @@ menuconfig GPIO_MCUX_LPC bool "MCUX LPC GPIO driver" depends on HAS_MCUX + select HAS_DTS_GPIO help Enable the MCUX LPC pinmux driver. diff --git a/drivers/gpio/gpio_mcux_lpc.c b/drivers/gpio/gpio_mcux_lpc.c index 6894ac4b65315..fe8bb8d19c9f8 100644 --- a/drivers/gpio/gpio_mcux_lpc.c +++ b/drivers/gpio/gpio_mcux_lpc.c @@ -8,9 +8,8 @@ * @brief GPIO driver for LPC54XXX family * * Note: - * - Only basic GPIO features sufficient to blinky functionality - * are currently implemented. - * - Interrupt mode is not implemented. + * - fsl_pint internally tries to manage interrupts, but this is not used (e.g. + * s_pintCallback), Zephyr's interrupt management system is used in place. */ #include @@ -20,30 +19,45 @@ #include #include "gpio_utils.h" #include +#include +#include #include -#define PORT0_IDX 0u -#define PORT1_IDX 1u +#define PORT0_IDX 0u +#define PORT1_IDX 1u + +#define PIN_TO_INPUT_MUX_CONNECTION(port, pin) \ + ((PINTSEL0 << PMUX_SHIFT) + (32 * port) + (pin)) + +#define NO_PINT_INT ((1 << sizeof(pint_pin_int_t)) - 1) struct gpio_mcux_lpc_config { GPIO_Type *gpio_base; + PINT_Type *pint_base; + IOCON_Type *pinmux_base; u32_t port_no; clock_ip_name_t clock_ip_name; }; struct gpio_mcux_lpc_data { - struct gpio_driver_data general; + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; /* port ISR callback routine address */ sys_slist_t callbacks; /* pin callback routine enable flags, by pin number */ u32_t pin_callback_enables; + /* pin association with PINT id */ + pint_pin_int_t pint_id[32]; + /* ISR allocated in device tree to this port */ + u32_t isr_list[8]; + /* index to to table above */ + u32_t isr_list_idx; }; -static int gpio_mcux_lpc_configure(struct device *dev, - int access_op, u32_t pin, int flags) +static int gpio_mcux_lpc_configure(struct device *dev, int access_op, u32_t pin, + int flags) { const struct gpio_mcux_lpc_config *config = dev->config->config_info; - struct gpio_mcux_lpc_data *data = dev->driver_data; GPIO_Type *gpio_base = config->gpio_base; u32_t port = config->port_no; @@ -55,11 +69,20 @@ static int gpio_mcux_lpc_configure(struct device *dev, return -ENOTSUP; } + if (flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) { + IOCON_Type *pinmux_base = config->pinmux_base; + u32_t *pinconfig = (u32_t *)&(pinmux_base->PIO[port][pin]); + + *pinconfig &= ~(IOCON_PIO_MODE_PULLUP|IOCON_PIO_MODE_PULLDOWN); + if ((flags & GPIO_PULL_UP) != 0) { + *pinconfig |= IOCON_PIO_MODE_PULLUP; + } else if ((flags & GPIO_PULL_DOWN) != 0) { + *pinconfig |= IOCON_PIO_MODE_PULLDOWN; + } + } + /* supports access by pin now,you can add access by port when needed */ if (access_op == GPIO_ACCESS_BY_PIN) { - WRITE_BIT(data->general.invert, pin, - flags & GPIO_ACTIVE_LOW); - if (flags & GPIO_OUTPUT_INIT_HIGH) { gpio_base->SET[port] = BIT(pin); } @@ -70,17 +93,15 @@ static int gpio_mcux_lpc_configure(struct device *dev, /* input-0,output-1 */ WRITE_BIT(gpio_base->DIR[port], pin, flags & GPIO_OUTPUT); - } else { - return -EINVAL; } return 0; } -static int gpio_mcux_lpc_write(struct device *dev, - int access_op, u32_t pin, u32_t value) +static int gpio_mcux_lpc_write(struct device *dev, int access_op, u32_t pin, + u32_t value) { const struct gpio_mcux_lpc_config *config = dev->config->config_info; GPIO_Type *gpio_base = config->gpio_base; @@ -101,8 +122,8 @@ static int gpio_mcux_lpc_write(struct device *dev, return 0; } -static int gpio_mcux_lpc_read(struct device *dev, - int access_op, u32_t pin, u32_t *value) +static int gpio_mcux_lpc_read(struct device *dev, int access_op, u32_t pin, + u32_t *value) { const struct gpio_mcux_lpc_config *config = dev->config->config_info; GPIO_Type *gpio_base = config->gpio_base; @@ -129,7 +150,7 @@ static int gpio_mcux_lpc_port_get_raw(struct device *dev, u32_t *value) } static int gpio_mcux_lpc_port_set_masked_raw(struct device *dev, u32_t mask, - u32_t value) + u32_t value) { const struct gpio_mcux_lpc_config *config = dev->config->config_info; GPIO_Type *gpio_base = config->gpio_base; @@ -174,12 +195,192 @@ static int gpio_mcux_lpc_port_toggle_bits(struct device *dev, u32_t mask) return 0; } +static void gpio_mcux_lpc_port_isr(void *arg) +{ + struct device *dev = (struct device *)arg; + const struct gpio_mcux_lpc_config *config = dev->config->config_info; + struct gpio_mcux_lpc_data *data = dev->driver_data; + u32_t enabled_int; + u32_t int_flags; + u32_t pin; + + for (pin = 0; pin < 32; pin++) { + if (data->pint_id[pin] != NO_PINT_INT) { + int_flags = PINT_PinInterruptGetStatus( + config->pint_base, data->pint_id[pin]); + enabled_int = + (int_flags << pin) & data->pin_callback_enables; + + PINT_PinInterruptClrStatus(config->pint_base, + data->pint_id[pin]); + + gpio_fire_callbacks(&data->callbacks, dev, enabled_int); + } + } +} + +static u32_t get_free_isr(struct gpio_mcux_lpc_data *data) +{ + u32_t i; + u32_t isr; + + for (i = 0; i < data->isr_list_idx; i++) { + if (data->isr_list[i] != -1) { + isr = data->isr_list[i]; + data->isr_list[i] = -1; + return isr; + } + } + + return -EINVAL; +} + +/* Function configures INPUTMUX device to route pin interrupts to a certain + * PINT. PINT no. is unknown, rather it's determined from ISR no. + */ +static u32_t attach_pin_to_isr(u32_t port, u32_t pin, u32_t isr_no) +{ + u32_t pint_idx; + /* Connect trigger sources to PINT */ + INPUTMUX_Init(INPUTMUX); + + /* Code asumes PIN_INT values are grouped [0..3] and [4..7]. + * This scenario is true in LPC54xxx/LPC55xxx. + */ + if (isr_no < PIN_INT4_IRQn) { + pint_idx = isr_no - PIN_INT0_IRQn; + } else { + pint_idx = isr_no - PIN_INT4_IRQn; + } + + INPUTMUX_AttachSignal(INPUTMUX, pint_idx, + PIN_TO_INPUT_MUX_CONNECTION(port, pin)); + + /* Turnoff clock to inputmux to save power. Clock is only needed to make + * changes. Can be turned off after. + */ + INPUTMUX_Deinit(INPUTMUX); + + return pint_idx; +} + +static void gpio_mcux_lpc_port_isr(void *arg); + + +static int gpio_mcux_lpc_pin_interrupt_configure(struct device *dev, + unsigned int pin, enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + const struct gpio_mcux_lpc_config *config = dev->config->config_info; + struct gpio_mcux_lpc_data *data = dev->driver_data; + pint_pin_enable_t interruptMode = kPINT_PinIntEnableNone; + GPIO_Type *gpio_base = config->gpio_base; + u32_t port = config->port_no; + u32_t isr; + u32_t pint_idx; + + /* Ensure pin used as interrupt is set as input*/ + if ((mode & GPIO_INT_ENABLE) && + ((gpio_base->DIR[port] & BIT(pin)) != 0)) { + return -ENOTSUP; + } + + switch (mode) { + case GPIO_INT_MODE_DISABLED: + interruptMode = kPINT_PinIntEnableNone; + break; + case GPIO_INT_MODE_LEVEL: + if (trig == GPIO_INT_TRIG_HIGH) { + interruptMode = kPINT_PinIntEnableHighLevel; + } else if (trig == GPIO_INT_TRIG_LOW) { + interruptMode = kPINT_PinIntEnableLowLevel; + } else { + return -ENOTSUP; + } + break; + case GPIO_INT_MODE_EDGE: + if (trig == GPIO_INT_TRIG_HIGH) { + interruptMode = kPINT_PinIntEnableRiseEdge; + } else if (trig == GPIO_INT_TRIG_LOW) { + interruptMode = kPINT_PinIntEnableFallEdge; + } else { + interruptMode = kPINT_PinIntEnableBothEdges; + } + break; + default: + return -ENOTSUP; + } + + /* First time calling this function routes PIN->PINT->INPUTMUX->NVIC */ + if (data->pint_id[pin] == NO_PINT_INT) { + isr = get_free_isr(data); + if (isr == -EINVAL) { + /* Didn't find any free interrupt in this port */ + return -EBUSY; + } + pint_idx = attach_pin_to_isr(port, pin, isr); + data->pint_id[pin] = pint_idx; + } + + PINT_PinInterruptConfig(config->pint_base, data->pint_id[pin], + interruptMode, + (pint_cb_t)gpio_mcux_lpc_port_isr); + + WRITE_BIT(data->pin_callback_enables, pin, mode != GPIO_INT_DISABLE); + + return 0; +} + +static int gpio_mcux_lpc_manage_cb(struct device *port, + struct gpio_callback *callback, bool set) +{ + struct gpio_mcux_lpc_data *data = port->driver_data; + + return gpio_manage_callback(&data->callbacks, callback, set); +} + +static int gpio_mcux_lpc_enable_cb(struct device *port, int access_op, + u32_t pin) +{ + struct gpio_mcux_lpc_data *data = port->driver_data; + + if (access_op == GPIO_ACCESS_BY_PIN) { + data->pin_callback_enables |= BIT(pin); + } else { + data->pin_callback_enables = 0xFFFFFFFF; + } + + return 0; +} + +static int gpio_mcux_lpc_disable_cb(struct device *port, int access_op, + u32_t pin) +{ + struct gpio_mcux_lpc_data *data = port->driver_data; + + if (access_op == GPIO_ACCESS_BY_PIN) { + data->pin_callback_enables &= ~BIT(pin); + } else { + data->pin_callback_enables = 0U; + } + + return 0; +} + static int gpio_mcux_lpc_init(struct device *dev) { const struct gpio_mcux_lpc_config *config = dev->config->config_info; + struct gpio_mcux_lpc_data *data = dev->driver_data; + int i; CLOCK_EnableClock(config->clock_ip_name); + for (i = 0; i < 32; i++) { + data->pint_id[i] = NO_PINT_INT; + } + + data->isr_list_idx = 0; + return 0; } @@ -191,37 +392,143 @@ static const struct gpio_driver_api gpio_mcux_lpc_driver_api = { .port_set_masked_raw = gpio_mcux_lpc_port_set_masked_raw, .port_set_bits_raw = gpio_mcux_lpc_port_set_bits_raw, .port_clear_bits_raw = gpio_mcux_lpc_port_clear_bits_raw, - .port_toggle_bits = gpio_mcux_lpc_port_toggle_bits + .port_toggle_bits = gpio_mcux_lpc_port_toggle_bits, + .pin_interrupt_configure = gpio_mcux_lpc_pin_interrupt_configure, + .manage_callback = gpio_mcux_lpc_manage_cb, + .enable_callback = gpio_mcux_lpc_enable_cb, + .disable_callback = gpio_mcux_lpc_disable_cb, }; #ifdef CONFIG_GPIO_MCUX_LPC_PORT0 +static int lpc_gpio_0_init(struct device *dev); + static const struct gpio_mcux_lpc_config gpio_mcux_lpc_port0_config = { .gpio_base = GPIO, + .pint_base = PINT, /* TODO: SECPINT issue #16330 */ + .pinmux_base = IOCON, .port_no = PORT0_IDX, .clock_ip_name = kCLOCK_Gpio0, }; static struct gpio_mcux_lpc_data gpio_mcux_lpc_port0_data; -DEVICE_AND_API_INIT(gpio_mcux_lpc_port0, CONFIG_GPIO_MCUX_LPC_PORT0_NAME, - gpio_mcux_lpc_init, - &gpio_mcux_lpc_port0_data, &gpio_mcux_lpc_port0_config, - POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, +DEVICE_AND_API_INIT(gpio_mcux_lpc_port0, DT_INST_0_NXP_LPC_GPIO_LABEL, + lpc_gpio_0_init, &gpio_mcux_lpc_port0_data, + &gpio_mcux_lpc_port0_config, POST_KERNEL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &gpio_mcux_lpc_driver_api); + +static int lpc_gpio_0_init(struct device *dev) +{ +#if defined(DT_INST_0_NXP_LPC_GPIO_IRQ_0) || \ + defined(DT_INST_0_NXP_LPC_GPIO_IRQ_1) || \ + defined(DT_INST_0_NXP_LPC_GPIO_IRQ_2) || \ + defined(DT_INST_0_NXP_LPC_GPIO_IRQ_3) + struct gpio_mcux_lpc_data *data = dev->driver_data; +#endif + + gpio_mcux_lpc_init(dev); + +#ifdef DT_INST_0_NXP_LPC_GPIO_IRQ_0 + IRQ_CONNECT(DT_INST_0_NXP_LPC_GPIO_IRQ_0, + DT_INST_0_NXP_LPC_GPIO_IRQ_0_PRIORITY, + gpio_mcux_lpc_port_isr, DEVICE_GET(gpio_mcux_lpc_port0), 0); + irq_enable(DT_INST_0_NXP_LPC_GPIO_IRQ_0); + data->isr_list[data->isr_list_idx++] = DT_INST_0_NXP_LPC_GPIO_IRQ_0; +#endif + +#ifdef DT_INST_0_NXP_LPC_GPIO_IRQ_1 + IRQ_CONNECT(DT_INST_0_NXP_LPC_GPIO_IRQ_1, + DT_INST_0_NXP_LPC_GPIO_IRQ_1_PRIORITY, + gpio_mcux_lpc_port_isr, DEVICE_GET(gpio_mcux_lpc_port0), 0); + irq_enable(DT_INST_0_NXP_LPC_GPIO_IRQ_1); + data->isr_list[data->isr_list_idx++] = DT_INST_0_NXP_LPC_GPIO_IRQ_1; +#endif + +#ifdef DT_INST_0_NXP_LPC_GPIO_IRQ_2 + IRQ_CONNECT(DT_INST_0_NXP_LPC_GPIO_IRQ_2, + DT_INST_0_NXP_LPC_GPIO_IRQ_2_PRIORITY, + gpio_mcux_lpc_port_isr, DEVICE_GET(gpio_mcux_lpc_port0), 0); + irq_enable(DT_INST_0_NXP_LPC_GPIO_IRQ_2); + data->isr_list[data->isr_list_idx++] = DT_INST_0_NXP_LPC_GPIO_IRQ_2; +#endif + +#ifdef DT_INST_0_NXP_LPC_GPIO_IRQ_3 + IRQ_CONNECT(DT_INST_0_NXP_LPC_GPIO_IRQ_3, + DT_INST_0_NXP_LPC_GPIO_IRQ_3_PRIORITY, + gpio_mcux_lpc_port_isr, DEVICE_GET(gpio_mcux_lpc_port0), 0); + irq_enable(DT_INST_0_NXP_LPC_GPIO_IRQ_3); + data->isr_list[data->isr_list_idx++] = DT_INST_0_NXP_LPC_GPIO_IRQ_3; +#endif + + return 0; +} + #endif /* CONFIG_GPIO_MCUX_LPC_PORT0 */ #ifdef CONFIG_GPIO_MCUX_LPC_PORT1 +static int lpc_gpio_1_init(struct device *dev); + static const struct gpio_mcux_lpc_config gpio_mcux_lpc_port1_config = { .gpio_base = GPIO, + .pint_base = PINT, + .pinmux_base = IOCON, .port_no = PORT1_IDX, .clock_ip_name = kCLOCK_Gpio1, }; static struct gpio_mcux_lpc_data gpio_mcux_lpc_port1_data; -DEVICE_AND_API_INIT(gpio_mcux_lpc_port1, CONFIG_GPIO_MCUX_LPC_PORT1_NAME, - gpio_mcux_lpc_init, - &gpio_mcux_lpc_port1_data, &gpio_mcux_lpc_port1_config, - POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, +DEVICE_AND_API_INIT(gpio_mcux_lpc_port1, DT_INST_1_NXP_LPC_GPIO_LABEL, + lpc_gpio_1_init, &gpio_mcux_lpc_port1_data, + &gpio_mcux_lpc_port1_config, POST_KERNEL, + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &gpio_mcux_lpc_driver_api); + +static int lpc_gpio_1_init(struct device *dev) +{ +#if defined(DT_INST_1_NXP_LPC_GPIO_IRQ_0) || \ + defined(DT_INST_1_NXP_LPC_GPIO_IRQ_1) || \ + defined(DT_INST_1_NXP_LPC_GPIO_IRQ_2) || \ + defined(DT_INST_1_NXP_LPC_GPIO_IRQ_3) + struct gpio_mcux_lpc_data *data = dev->driver_data; +#endif + + gpio_mcux_lpc_init(dev); + +#ifdef DT_INST_1_NXP_LPC_GPIO_IRQ_0 + IRQ_CONNECT(DT_INST_1_NXP_LPC_GPIO_IRQ_0, + DT_INST_1_NXP_LPC_GPIO_IRQ_0_PRIORITY, + gpio_mcux_lpc_port_isr, DEVICE_GET(gpio_mcux_lpc_port1), 0); + irq_enable(DT_INST_1_NXP_LPC_GPIO_IRQ_0); + data->isr_list[data->isr_list_idx++] = DT_INST_1_NXP_LPC_GPIO_IRQ_0; +#endif + +#ifdef DT_INST_1_NXP_LPC_GPIO_IRQ_1 + IRQ_CONNECT(DT_INST_1_NXP_LPC_GPIO_IRQ_1, + DT_INST_1_NXP_LPC_GPIO_IRQ_1_PRIORITY, + gpio_mcux_lpc_port_isr, DEVICE_GET(gpio_mcux_lpc_port1), 0); + irq_enable(DT_INST_1_NXP_LPC_GPIO_IRQ_1); + data->isr_list[data->isr_list_idx++] = DT_INST_1_NXP_LPC_GPIO_IRQ_1; +#endif + +#ifdef DT_INST_1_NXP_LPC_GPIO_IRQ_2 + IRQ_CONNECT(DT_INST_1_NXP_LPC_GPIO_IRQ_2, + DT_INST_1_NXP_LPC_GPIO_IRQ_2_PRIORITY, + gpio_mcux_lpc_port_isr, DEVICE_GET(gpio_mcux_lpc_port1), 0); + irq_enable(DT_INST_1_NXP_LPC_GPIO_IRQ_2); + data->isr_list[data->isr_list_idx++] = DT_INST_1_NXP_LPC_GPIO_IRQ_2; +#endif + +#ifdef DT_INST_1_NXP_LPC_GPIO_IRQ_3 + IRQ_CONNECT(DT_INST_1_NXP_LPC_GPIO_IRQ_3, + DT_INST_1_NXP_LPC_GPIO_IRQ_3_PRIORITY, + gpio_mcux_lpc_port_isr, DEVICE_GET(gpio_mcux_lpc_port1), 0); + irq_enable(DT_INST_1_NXP_LPC_GPIO_IRQ_3); + data->isr_list[data->isr_list_idx++] = DT_INST_1_NXP_LPC_GPIO_IRQ_3; +#endif + + return 0; +} + #endif /* CONFIG_GPIO_MCUX_LPC_PORT1 */