diff --git a/arch/arm/src/imx6/imx_gpio.c b/arch/arm/src/imx6/imx_gpio.c index 09f7efca3f6..b940712e8fa 100644 --- a/arch/arm/src/imx6/imx_gpio.c +++ b/arch/arm/src/imx6/imx_gpio.c @@ -375,7 +375,7 @@ static inline void imx_gpio_dirin(int port, int pin) * Name: imx_gpio_setoutput ****************************************************************************/ -static inline void imx_gpio_setoutput(int port, int pin, bool value) +static void imx_gpio_setoutput(int port, int pin, bool value) { uintptr_t regaddr = IMX_GPIO_DR(port); uint32_t regval; @@ -410,8 +410,10 @@ static inline bool imx_gpio_getinput(int port, int pin) * Name: imx_gpio_configinput ****************************************************************************/ -static inline int imx_gpio_configinput(gpio_pinset_t pinset, int port, int pin) +static int imx_gpio_configinput(gpio_pinset_t pinset) { + int port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + int pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; FAR const uint8_t *table; iomux_pinset_t ioset; uintptr_t regaddr; @@ -441,7 +443,6 @@ static inline int imx_gpio_configinput(gpio_pinset_t pinset, int port, int pin) /* Configure pin pad settings */ index = imx_padmux_map(index); - index = table[pin]; if (index >= IMX_PADCTL_NREGISTERS) { return -EINVAL; @@ -456,8 +457,10 @@ static inline int imx_gpio_configinput(gpio_pinset_t pinset, int port, int pin) * Name: imx_gpio_configoutput ****************************************************************************/ -static inline int imx_gpio_configoutput(gpio_pinset_t pinset, int port, int pin) +static inline int imx_gpio_configoutput(gpio_pinset_t pinset) { + int port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + int pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; bool value = ((pinset & GPIO_OUTPUT_ONE) != 0); /* Set the output value */ @@ -470,6 +473,41 @@ static inline int imx_gpio_configoutput(gpio_pinset_t pinset, int port, int pin) return OK; } +/**************************************************************************** + * Name: imx_gpio_configperiph + ****************************************************************************/ + +static inline int imx_gpio_configperiph(gpio_pinset_t pinset) +{ + iomux_pinset_t ioset; + uintptr_t regaddr; + uint32_t regval; + uint32_t value; + unsigned int index; + + /* Configure pin as a peripheral */ + + index = ((ioset & GPIO_PADMUX_MASK) >> GPIO_PADMUX_SHIFT); + regaddr = IMX_PADMUX_ADDRESS(index); + + value = ((ioset & GPIO_ALT_MASK) >> GPIO_ALT_SHIFT); + regval = (value << PADMUX_MUXMODE_SHIFT); + + putreg32(regval, regaddr); + + /* Configure pin pad settings */ + + index = imx_padmux_map(index); + if (index >= IMX_PADCTL_NREGISTERS) + { + return -EINVAL; + } + + regaddr = IMX_PADCTL_ADDRESS(index); + ioset = (iomux_pinset_t)((pinset & GPIO_IOMUX_MASK) >> GPIO_IOMUX_SHIFT); + return imx_iomux_configure(regaddr, ioset); +} + /**************************************************************************** * Public Funtions ****************************************************************************/ @@ -485,24 +523,51 @@ static inline int imx_gpio_configoutput(gpio_pinset_t pinset, int port, int pin) int imx_config_gpio(gpio_pinset_t pinset) { irqstate_t flags; - int port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; - int pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; int ret; /* Configure the pin as an input initially to avoid any spurios outputs */ flags = enter_critical_section(); - ret = imx_gpio_configinput(pinset, port, pin); - if (ret >= 0) + + /* Configure based upon the pin mode */ + + switch (pinset & GPIO_MODE_MASK) { - /* Was it really an output pin? */ - - if ((pinset & GPIO_OUTPUT) != 0) + case GPIO_INPUT: { - /* YES.. convert the input to an output */ + /* Configure the pin as a GPIO input */ - ret = imx_gpio_configoutput(pinset, port, pin); + ret = imx_gpio_configinput(pinset); } + break; + + case GPIO_OUTPUT: + { + /* First coonfigure the pin as a GPIO input to avoid output + * glitches. + */ + + ret = imx_gpio_configinput(pinset); + if (ret >= 0) + { + /* Convert the input to an output */ + + ret = imx_gpio_configperiph(pinset); + } + } + break; + + case GPIO_PERIPH: + { + /* Configure the pin as a peripheral */ + + ret = imx_gpio_configinput(pinset); + } + break; + + default: + ret = -EINVAL; + break; } leave_critical_section(flags); diff --git a/arch/arm/src/imx6/imx_gpio.h b/arch/arm/src/imx6/imx_gpio.h index 0caf7378ab3..2c3acd9abe2 100644 --- a/arch/arm/src/imx6/imx_gpio.h +++ b/arch/arm/src/imx6/imx_gpio.h @@ -50,87 +50,118 @@ /************************************************************************************ * Pre-processor Definitions ************************************************************************************/ -/* 28-bit Encoding: +/* 32-bit Encoding: * - * ENCODING ..IV GGGP PPPP MMMM MMMM MMMM MMMM - * GPIO INPUT ..0. GGGP PPPP MMMM MMMM MMMM MMMM - * GPIO OUTPUT ..1V GGGP PPPP MMMM MMMM MMMM MMMM + * ENCODING IIXX XXXX XXXX XXXX MMMM MMMM MMMM MMMM + * GPIO INPUT 00.. .... GGGP PPPP MMMM MMMM MMMM MMMM + * GPIO OUTPUT 01V. .... GGGP PPPP MMMM MMMM MMMM MMMM + * PERIPHERAL 10AA A... IIII IIII MMMM MMMM MMMM MMMM */ /* Input/Output Selection: * - * ENCODING ..I. .... .... .... .... .... .... + * ENCODING II.. .... .... .... .... .... .... .... */ -#define GPIO_INPUT (0) /* Bit 25: 0=input */ -#define GPIO_OUTPUT (1 << 25) /* Bit 25: 1=output */ +#define GPIO_MODE_SHIFT (30) /* Bits 30-31: Pin mode */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* GPIO input */ +# define GPIO_OUTPUT (1 << GPIO_MODE_SHIFT) /* GPIO output */ +# define GPIO_PERIPH (2 << GPIO_MODE_SHIFT) /* Peripheral */ /* Initial Ouptut Value: * - * GPIO OUTPUT ..1V .... .... .... .... .... .... + * GPIO OUTPUT 01V. .... .... .... .... .... .... .... */ -#define GPIO_OUTPUT_ZERO (0) /* Bit 24: 0=Initial output is low */ -#define GPIO_OUTPUT_ONE (1 << 24) /* Bit 24: 1=Initial output is high */ +#define GPIO_OUTPUT_ZERO (0) /* Bit 29: 0=Initial output is low */ +#define GPIO_OUTPUT_ONE (1 << 29) /* Bit 29: 1=Initial output is high */ /* GPIO Port Number * - * ENCODING .... GGG. .... .... .... .... .... + * GPIO INPUT 00.. .... GGG. .... .... .... .... .... + * GPIO OUTPUT 01.. .... GGG. .... .... .... .... .... */ #define GPIO_PORT_SHIFT (21) /* Bits 21-23: GPIO port index */ #define GPIO_PORT_MASK (7 << GPIO_PORT_SHIFT) -# define GPIO_PORT1 (0 << GPIO_PORT_SHIFT) /* GPIO1 */ -# define GPIO_PORT2 (1 << GPIO_PORT_SHIFT) /* GPIO2 */ -# define GPIO_PORT3 (2 << GPIO_PORT_SHIFT) /* GPIO3 */ -# define GPIO_PORT4 (3 << GPIO_PORT_SHIFT) /* GPIO4 */ -# define GPIO_PORT5 (4 << GPIO_PORT_SHIFT) /* GPIO5 */ -# define GPIO_PORT6 (5 << GPIO_PORT_SHIFT) /* GPIO6 */ -# define GPIO_PORT7 (6 << GPIO_PORT_SHIFT) /* GPIO7 */ +# define GPIO_PORT1 (0 << GPIO_PORT_SHIFT) /* GPIO1 */ +# define GPIO_PORT2 (1 << GPIO_PORT_SHIFT) /* GPIO2 */ +# define GPIO_PORT3 (2 << GPIO_PORT_SHIFT) /* GPIO3 */ +# define GPIO_PORT4 (3 << GPIO_PORT_SHIFT) /* GPIO4 */ +# define GPIO_PORT5 (4 << GPIO_PORT_SHIFT) /* GPIO5 */ +# define GPIO_PORT6 (5 << GPIO_PORT_SHIFT) /* GPIO6 */ +# define GPIO_PORT7 (6 << GPIO_PORT_SHIFT) /* GPIO7 */ /* GPIO Pin Number: * - * ENCODING .... ...P PPPP .... .... .... .... + * GPIO INPUT 00.. .... ...P PPPP .... .... .... .... + * GPIO OUTPUT 01.. .... ...P PPPP .... .... .... .... */ #define GPIO_PIN_SHIFT (16) /* Bits 16-20: GPIO pin number */ #define GPIO_PIN_MASK (15 << GPIO_PIN_SHIFT) -# define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) /* Pin 0 */ -# define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) /* Pin 1 */ -# define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) /* Pin 2 */ -# define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) /* Pin 3 */ -# define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) /* Pin 4 */ -# define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) /* Pin 5 */ -# define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) /* Pin 6 */ -# define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) /* Pin 7 */ -# define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) /* Pin 8 */ -# define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) /* Pin 9 */ -# define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) /* Pin 10 */ -# define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) /* Pin 11 */ -# define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) /* Pin 12 */ -# define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) /* Pin 13 */ -# define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) /* Pin 14 */ -# define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) /* Pin 15 */ -# define GPIO_PIN16 (16 << GPIO_PIN_SHIFT) /* Pin 16 */ -# define GPIO_PIN17 (17 << GPIO_PIN_SHIFT) /* Pin 17 */ -# define GPIO_PIN18 (18 << GPIO_PIN_SHIFT) /* Pin 18 */ -# define GPIO_PIN19 (19 << GPIO_PIN_SHIFT) /* Pin 19 */ -# define GPIO_PIN20 (20 << GPIO_PIN_SHIFT) /* Pin 20 */ -# define GPIO_PIN21 (21 << GPIO_PIN_SHIFT) /* Pin 21 */ -# define GPIO_PIN22 (22 << GPIO_PIN_SHIFT) /* Pin 22 */ -# define GPIO_PIN23 (23 << GPIO_PIN_SHIFT) /* Pin 23 */ -# define GPIO_PIN24 (24 << GPIO_PIN_SHIFT) /* Pin 24 */ -# define GPIO_PIN25 (25 << GPIO_PIN_SHIFT) /* Pin 25 */ -# define GPIO_PIN26 (26 << GPIO_PIN_SHIFT) /* Pin 26 */ -# define GPIO_PIN27 (27 << GPIO_PIN_SHIFT) /* Pin 27 */ -# define GPIO_PIN28 (28 << GPIO_PIN_SHIFT) /* Pin 28 */ -# define GPIO_PIN29 (29 << GPIO_PIN_SHIFT) /* Pin 29 */ -# define GPIO_PIN30 (30 << GPIO_PIN_SHIFT) /* Pin 30 */ -# define GPIO_PIN31 (31 << GPIO_PIN_SHIFT) /* Pin 31 */ +# define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) /* Pin 0 */ +# define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) /* Pin 1 */ +# define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) /* Pin 2 */ +# define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) /* Pin 3 */ +# define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) /* Pin 4 */ +# define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) /* Pin 5 */ +# define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) /* Pin 6 */ +# define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) /* Pin 7 */ +# define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) /* Pin 8 */ +# define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) /* Pin 9 */ +# define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) /* Pin 10 */ +# define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) /* Pin 11 */ +# define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) /* Pin 12 */ +# define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) /* Pin 13 */ +# define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) /* Pin 14 */ +# define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) /* Pin 15 */ +# define GPIO_PIN16 (16 << GPIO_PIN_SHIFT) /* Pin 16 */ +# define GPIO_PIN17 (17 << GPIO_PIN_SHIFT) /* Pin 17 */ +# define GPIO_PIN18 (18 << GPIO_PIN_SHIFT) /* Pin 18 */ +# define GPIO_PIN19 (19 << GPIO_PIN_SHIFT) /* Pin 19 */ +# define GPIO_PIN20 (20 << GPIO_PIN_SHIFT) /* Pin 20 */ +# define GPIO_PIN21 (21 << GPIO_PIN_SHIFT) /* Pin 21 */ +# define GPIO_PIN22 (22 << GPIO_PIN_SHIFT) /* Pin 22 */ +# define GPIO_PIN23 (23 << GPIO_PIN_SHIFT) /* Pin 23 */ +# define GPIO_PIN24 (24 << GPIO_PIN_SHIFT) /* Pin 24 */ +# define GPIO_PIN25 (25 << GPIO_PIN_SHIFT) /* Pin 25 */ +# define GPIO_PIN26 (26 << GPIO_PIN_SHIFT) /* Pin 26 */ +# define GPIO_PIN27 (27 << GPIO_PIN_SHIFT) /* Pin 27 */ +# define GPIO_PIN28 (28 << GPIO_PIN_SHIFT) /* Pin 28 */ +# define GPIO_PIN29 (29 << GPIO_PIN_SHIFT) /* Pin 29 */ +# define GPIO_PIN30 (30 << GPIO_PIN_SHIFT) /* Pin 30 */ +# define GPIO_PIN31 (31 << GPIO_PIN_SHIFT) /* Pin 31 */ + +/* Peripheral Alternate Function: + * + * PERIPHERAL 10AA A... .... .... MMMM MMMM MMMM MMMM + */ + +#define GPIO_ALT_SHIFT (27) /* Bits 27-29: Peripheral alternate function */ +#define GPIO_ALT_MASK (15 << GPIO_ALT_SHIFT) +# define GPIO_ALT0 (0 << GPIO_ALT_SHIFT) /* Alternate function 1 */ +# define GPIO_ALT1 (1 << GPIO_ALT_SHIFT) /* Alternate function 2 */ +# define GPIO_ALT2 (2 << GPIO_ALT_SHIFT) /* Alternate function 3 */ +# define GPIO_ALT3 (3 << GPIO_ALT_SHIFT) /* Alternate function 4 */ +# define GPIO_ALT4 (4 << GPIO_ALT_SHIFT) /* Alternate function 5 */ + /* Alternate function 5 is GPIO */ +# define GPIO_ALT6 (6 << GPIO_ALT_SHIFT) /* Alternate function 1 */ +# define GPIO_ALT7 (7 << GPIO_ALT_SHIFT) /* Alternate function 1 */ + +/* Pad Mux Register Index: + * + * PERIPHERAL 10.. .... IIII IIII MMMM MMMM MMMM MMMM + */ + +#define GPIO_PADMUX_SHIFT (16) /* Bits 16-23: Peripheral alternate function */ +#define GPIO_PADMUX_MASK (0xff << GPIO_PADMUX_SHIFT) +# define GPIO_PADMUX(n) ((uint32_t)(n) << GPIO_PADMUX_SHIFT) /* IOMUX Pin Configuration: * - * ENCODING .... .... .... MMMM MMMM MMMM MMMM + * ENCODING .... .... .... .... MMMM MMMM MMMM MMMM * * See imx_iomuxc.h for detailed content. */