ppc4xx: Add functionality to GPIO support
PATCH 1/1 ppc4xx: Add functionality to GPIO support
This patch makes two additions to GPIO support:
First, it adds function gpio_read_in_bit() to read the a bit from the GPIO Input Register (GPIOx_IR) in the same way that function gpio_read_out_bit() reads a bit from the GPIO Output Register (GPIOx_OR).
Second, it modifies function gpio_set_chip_configuration() to provide an additional option for configuring the GPIO from the "CFG_4xx_GPIO_TABLE".
According to the 440EPx User's Manual, when an alternate output is used, the three-state control is configured in one of two ways, depending on the particular output. The first option is to select the corresponding alternate three-state control in the GPIOx_TRSH/L registers. The second option is to select the GPIO Three-State Control Register (GPIOx_TCR) in the GPIOx_TRSH/L registers, and set the corresponding bit in the GPIOx_TCR register to enable the output. For example, the Manual specifies configuring the GPIO00 Alternate 1 Signal (PreAddr07) to use the alternate three-state control (first option), and specifies configuring the GPIO32 Alternate 1 Signal (USB2OM0) with the output enabled in the GPIOx_TCR register (second option).
Currently, gpio_set_chip_configuration() configures all alternate signal outputs to use the first option. This patch allow the second option to be selected by setting the "out_val" element in the table entry to "GPIO_OUT_1". The first option is used when the "out_val" element is set to "GPIO_OUT_0". Because "out_val" is not currently used when an alternate signal is selected, and because all current GPIO tables set "out_val" to "GPIO_OUT_0" for all alternate signals, this patch should not change any existing configurations.
--- cpu/ppc4xx/gpio.c | 63 ++++++++++++++++++++++++++++++----------------- include/asm-ppc/gpio.h | 1 + 2 files changed, 41 insertions(+), 23 deletions(-)
cpu/ppc4xx/gpio.c +40 -23
@@ -27,7 +27,7 @@#include <asm/gpio.h> #if defined(CFG_4xx_GPIO_TABLE) -gpio_param_s gpio_tab[GPIO_GROUP_MAX ][GPIO_MAX ] = CFG_4xx_GPIO_TABLE; +gpio_param_s const gpio_tab[GPIO_GROUP_MAX ][GPIO_MAX ] = CFG_4xx_GPIO_TABLE;#endif #if defined(GPIO0_OSRL )
@@ -120,6 +120,18 @@ int gpio_read_out_bit(int pin)return (in_be32 ((void *)GPIO0_OR + offs) &GPIO_VAL (pin) ?1 :0 ); } +int gpio_read_in_bit (int pin) +{ +u32 offs =0 ; + +if (pin >=GPIO_MAX ) { + offs =0x100 ; + pin -=GPIO_MAX ; + } + +return (in_be32 ((void *)GPIO0_IR + offs) &GPIO_VAL (pin) ?1 :0 ); +} +#if defined(CFG_4xx_GPIO_TABLE)void gpio_set_chip_configuration (void ) {
@@ -171,6 +183,8 @@ void gpio_set_chip_configuration(void)if ((gpio_tab[gpio_core][i].in_out ==GPIO_OUT ) || (gpio_tab[gpio_core][i].in_out ==GPIO_BI )) { +u32 gpio_alt_sel =0 ; +switch (gpio_tab[gpio_core][i].alt_nb) {case GPIO_SEL :/*
@@ -199,37 +213,40 @@ void gpio_set_chip_configuration(void)break ;case GPIO_ALT1 : - reg =in_be32 ((void *)GPIO_OS (core_add+offs)) - & ~(GPIO_MASK >> (j*2 )); - reg = reg | (GPIO_ALT1_SEL >> (j*2 )); -out_be32 ((void *)GPIO_OS (core_add+offs), reg); - reg =in_be32 ((void *)GPIO_TS (core_add+offs)) - & ~(GPIO_MASK >> (j*2 )); - reg = reg | (GPIO_ALT1_SEL >> (j*2 )); -out_be32 ((void *)GPIO_TS (core_add+offs), reg); + gpio_alt_sel =GPIO_ALT1_SEL ;break ;case GPIO_ALT2 : - reg =in_be32 ((void *)GPIO_OS (core_add+offs)) - & ~(GPIO_MASK >> (j*2 )); - reg = reg | (GPIO_ALT2_SEL >> (j*2 )); -out_be32 ((void *)GPIO_OS (core_add+offs), reg); - reg =in_be32 ((void *)GPIO_TS (core_add+offs)) - & ~(GPIO_MASK >> (j*2 )); - reg = reg | (GPIO_ALT2_SEL >> (j*2 )); -out_be32 ((void *)GPIO_TS (core_add+offs), reg); + gpio_alt_sel =GPIO_ALT2_SEL ;break ;case GPIO_ALT3 : + gpio_alt_sel =GPIO_ALT3_SEL ; +break ; + } + +if (0 != gpio_alt_sel) { reg =in_be32 ((void *)GPIO_OS (core_add+offs)) & ~(GPIO_MASK >> (j*2 )); - reg = reg | (GPIO_ALT3_SEL >> (j*2 )); + reg = reg | (gpio_alt_sel >> (j*2 ));out_be32 ((void *)GPIO_OS (core_add+offs), reg); - reg =in_be32 ((void *)GPIO_TS (core_add+offs)) - & ~(GPIO_MASK >> (j*2 )); - reg = reg | (GPIO_ALT3_SEL >> (j*2 )); -out_be32 ((void *)GPIO_TS (core_add+offs), reg); -break ; + +if (gpio_tab[gpio_core][i].out_val ==GPIO_OUT_1 ) { + reg =in_be32 ((void *)GPIO_TCR (core_add)) + | (0x80000000 >> (i)); +out_be32 ((void *)GPIO_TCR (core_add), reg); + reg =in_be32 ((void *)GPIO_TS (core_add+offs)) + & ~(GPIO_MASK >> (j*2 )); +out_be32 ((void *)GPIO_TS (core_add+offs), reg); + }else { + reg =in_be32 ((void *)GPIO_TCR (core_add)) + & ~(0x80000000 >> (i)); +out_be32 ((void *)GPIO_TCR (core_add), reg); + reg =in_be32 ((void *)GPIO_TS (core_add+offs)) + & ~(GPIO_MASK >> (j*2 )); + reg = reg | (gpio_alt_sel >> (j*2 )); +out_be32 ((void *)GPIO_TS (core_add+offs), reg); + } } } }
include/asm-ppc/gpio.h +1 -0
@@ -88,6 +88,7 @@ typedef struct {void gpio_config (int pin,int in_out,int gpio_alt,int out_val);void gpio_write_bit (int pin,int val);int gpio_read_out_bit (int pin); +int gpio_read_in_bit (int pin);void gpio_set_chip_configuration (void );#endif /* __ASM_PPC_GPIO_H */