diff options
author | Bo Shen <voice.shen@atmel.com> | 2012-05-20 15:50:00 +0000 |
---|---|---|
committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2012-07-07 14:07:30 +0200 |
commit | 2b3b1c668be539d897d2a9352bc8dca54467f425 (patch) | |
tree | 52510f9161b017f898b984ea86c5ad0ebc4bde78 /drivers/gpio/at91_gpio.c | |
parent | 81f40345d1d5c5ba04620873e3ca0bc60b6b2fe0 (diff) | |
download | u-boot-imx-2b3b1c668be539d897d2a9352bc8dca54467f425.zip u-boot-imx-2b3b1c668be539d897d2a9352bc8dca54467f425.tar.gz u-boot-imx-2b3b1c668be539d897d2a9352bc8dca54467f425.tar.bz2 |
ATMEL/PIO: Enable new feature of PIO on Atmel device
Enable new PIO feature supported by Atmel SoC.
Using CPU_HAS_PIO3 micro to enable PIO new feature.
Signed-off-by: Bo Shen <voice.shen@atmel.com>
Signed-off-by: Andreas Bießmann <andreas.devel@googlemail.com>
Diffstat (limited to 'drivers/gpio/at91_gpio.c')
-rw-r--r-- | drivers/gpio/at91_gpio.c | 125 |
1 files changed, 123 insertions, 2 deletions
diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c index be2a026..ac3b322 100644 --- a/drivers/gpio/at91_gpio.c +++ b/drivers/gpio/at91_gpio.c @@ -86,7 +86,14 @@ int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup) mask = 1 << pin; writel(mask, &pio->port[port].idr); at91_set_pio_pullup(port, pin, use_pullup); +#if defined(CPU_HAS_PIO3) + writel(readl(&pio->port[port].abcdsr1) & ~mask, + &pio->port[port].abcdsr1); + writel(readl(&pio->port[port].abcdsr2) & ~mask, + &pio->port[port].abcdsr2); +#else writel(mask, &pio->port[port].asr); +#endif writel(mask, &pio->port[port].pdr); } return 0; @@ -104,12 +111,63 @@ int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup) mask = 1 << pin; writel(mask, &pio->port[port].idr); at91_set_pio_pullup(port, pin, use_pullup); +#if defined(CPU_HAS_PIO3) + writel(readl(&pio->port[port].abcdsr1) | mask, + &pio->port[port].abcdsr1); + writel(readl(&pio->port[port].abcdsr2) & ~mask, + &pio->port[port].abcdsr2); +#else writel(mask, &pio->port[port].bsr); +#endif writel(mask, &pio->port[port].pdr); } return 0; } +#if defined(CPU_HAS_PIO3) +/* + * mux the pin to the "C" internal peripheral role. + */ +int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup) +{ + at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; + u32 mask; + + if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { + mask = 1 << pin; + writel(mask, &pio->port[port].idr); + at91_set_pio_pullup(port, pin, use_pullup); + writel(readl(&pio->port[port].abcdsr1) & ~mask, + &pio->port[port].abcdsr1); + writel(readl(&pio->port[port].abcdsr2) | mask, + &pio->port[port].abcdsr2); + writel(mask, &pio->port[port].pdr); + } + return 0; +} + +/* + * mux the pin to the "D" internal peripheral role. + */ +int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup) +{ + at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; + u32 mask; + + if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { + mask = 1 << pin; + writel(mask, &pio->port[port].idr); + at91_set_pio_pullup(port, pin, use_pullup); + writel(readl(&pio->port[port].abcdsr1) | mask, + &pio->port[port].abcdsr1); + writel(readl(&pio->port[port].abcdsr2) | mask, + &pio->port[port].abcdsr2); + writel(mask, &pio->port[port].pdr); + } + return 0; +} +#endif + /* * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and * configure it for an input. @@ -162,13 +220,76 @@ int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on) if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { mask = 1 << pin; - if (is_on) + if (is_on) { +#if defined(CPU_HAS_PIO3) + writel(mask, &pio->port[port].ifscdr); +#endif writel(mask, &pio->port[port].ifer); - else + } else { writel(mask, &pio->port[port].ifdr); + } + } + return 0; +} + +#if defined(CPU_HAS_PIO3) +/* + * enable/disable the debounce filter. + */ +int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div) +{ + at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; + u32 mask; + + if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { + mask = 1 << pin; + if (is_on) { + writel(mask, &pio->port[port].ifscer); + writel(div & PIO_SCDR_DIV, &pio->port[port].scdr); + writel(mask, &pio->port[port].ifer); + } else { + writel(mask, &pio->port[port].ifdr); + } + } + return 0; +} + +/* + * enable/disable the pull-down. + * If pull-up already enabled while calling the function, we disable it. + */ +int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on) +{ + at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; + u32 mask; + + if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { + mask = 1 << pin; + writel(mask, &pio->port[port].pudr); + if (is_on) + writel(mask, &pio->port[port].ppder); + else + writel(mask, &pio->port[port].ppddr); + } + return 0; +} + +/* + * disable Schmitt trigger + */ +int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin) +{ + at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; + u32 mask; + + if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { + mask = 1 << pin; + writel(readl(&pio->port[port].schmitt) | mask, + &pio->port[port].schmitt); } return 0; } +#endif /* * enable/disable the multi-driver. This is only valid for output and |