add at91 SoC access with c structures
Subsystems (2)
PATCH v2 6/8 add at91 SoC access with c structures
* add new at91_gpio driver, using c structure SoC access
Signed-off-by Jens Scharsig <[email protected]>
--- drivers/gpio/at91_gpio.c | 240 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 240 insertions(+), 0 deletions(-) create mode 100644 drivers/gpio/at91_gpio.c
drivers/gpio/at91_gpio.c new file +240 -0
@@ -0,0 +1,240 @@ +/* +* Memory Setup stuff - taken from blob memsetup.S +* +* Copyright (C) 2009 Jens Scharsig (js_at_ng at scharsoft.de) +* +* Copyright (C) 2005 HP Labs +* +* See file CREDITS for list of people who contributed to this +* project. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, +* MA 02111-1307 USA +*/ + +#include <config.h> +#include <common.h> +#include <asm/sizes.h> +#include <asm/arch/hardware.h> +#include <asm/arch/io.h> +#include <asm/arch/at91_pio.h> + +#define PIN_BASE 32 + +u32 portpin_to_port (u32 portpin) +{ +return (portpin -PIN_BASE ) /32 ; +} + +u32 portpin_to_pin (u32 portpin) +{ +return 1 << ((portpin -PIN_BASE ) %32 ); +} + +/* +* mux the pin to the "GPIO" peripheral role. +*/ +int at91_set_gpio_periph (unsigned pin,int use_pullup) +{ +at91_pio_t *pio = (at91_pio_t *)AT91_PIO_BASE ; +u32 port =portpin_to_port (pin); +u32 mask =portpin_to_pin (pin); + +writel (mask, &pio->port[port].idr); +if (use_pullup) +writel (mask, &pio->port[port].puer); +else +writel (mask, &pio->port[port].pudr); +writel (mask, &pio->port[port].per); + +return 0 ; +} + +/* +* mux the pin to the "A" internal peripheral role. +*/ +int at91_set_a_periph (unsigned pin,int use_pullup) +{ +at91_pio_t *pio = (at91_pio_t *)AT91_PIO_BASE ; +u32 port =portpin_to_port (pin); +u32 mask =portpin_to_pin (pin); + +writel (mask, &pio->port[port].idr); +if (use_pullup) +writel (mask, &pio->port[port].puer); +else +writel (mask, &pio->port[port].pudr); +writel (mask, &pio->port[port].asr); +writel (mask, &pio->port[port].pdr); + +return 0 ; +} + +/* +* mux the pin to the "B" internal peripheral role. +*/ +int at91_set_b_periph (unsigned pin,int use_pullup) +{ +at91_pio_t *pio = (at91_pio_t *)AT91_PIO_BASE ; +u32 port =portpin_to_port (pin); +u32 mask =portpin_to_pin (pin); + +writel (mask, &pio->port[port].idr); +if (use_pullup) +writel (mask, &pio->port[port].puer); +else +writel (mask, &pio->port[port].pudr); +writel (mask, &pio->port[port].bsr); +writel (mask, &pio->port[port].pdr); + +return 0 ; +} + +/* +* mux the pin to the gpio controller (instead of "A" or "B" peripheral), and +* configure it for an input. +*/ +int at91_set_gpio_input (u32 pin,int use_pullup) +{ +at91_pio_t *pio = (at91_pio_t *)AT91_PIO_BASE ; +u32 port =portpin_to_port (pin); +u32 mask =portpin_to_pin (pin); + +writel (mask, &pio->port[port].idr); +if (use_pullup) +writel (mask, &pio->port[port].puer); +else +writel (mask, &pio->port[port].pudr); +writel (mask, &pio->port[port].odr); +writel (mask, &pio->port[port].per); +return 0 ; +} + +/* +* mux the pin to the gpio controller (instead of "A" or "B" peripheral), +* and configure it for an output. +*/ +int at91_set_gpio_output (u32 pin,int value) +{ +at91_pio_t *pio = (at91_pio_t *)AT91_PIO_BASE ; +u32 port =portpin_to_port (pin); +u32 mask =portpin_to_pin (pin); + +writel (mask, &pio->port[port].idr); +writel (mask, &pio->port[port].pudr); +if (value) +writel (mask, &pio->port[port].sodr); +else +writel (mask, &pio->port[port].codr); +writel (mask, &pio->port[port].oer); +writel (mask, &pio->port[port].per); + +return 0 ; +} + +/* +* enable/disable the glitch filter; mostly used with IRQ handling. +*/ +int at91_set_deglitch (unsigned pin,int is_on) +{ +at91_pio_t *pio = (at91_pio_t *)AT91_PIO_BASE ; +u32 port =portpin_to_port (pin); +u32 mask =portpin_to_pin (pin); + +if (is_on) +writel (mask, &pio->port[port].ifer); +else +writel (mask, &pio->port[port].ifdr); +return 0 ; +} + +/* +* enable/disable the multi-driver; This is only valid for output and +* allows the output pin to run as an open collector output. +*/ +int at91_set_multi_drive (unsigned pin,int is_on) +{ +at91_pio_t *pio = (at91_pio_t *)AT91_PIO_BASE ; +u32 port =portpin_to_port (pin); +u32 mask =portpin_to_pin (pin); + +if (is_on) +writel (mask, &pio->port[port].mder); +else +writel (mask, &pio->port[port].mddr); +return 0 ; +} + +/* +int gpio_direction_input(unsigned pin) +{ +at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE; +u32 port = portpin_to_port(pin); +u32 mask = portpin_to_pin(pin); + +if (!(readl(&pio->port[port].psr) & mask)) +return -EINVAL; +writel(mask, &pio->port[port].odr); +return 0; +} + +int gpio_direction_output(unsigned pin, int value) +{ +at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE; +u32 port = portpin_to_port(pin); +u32 mask = portpin_to_pin(pin); + +if (!(readl(&pio->port[port].psr) & mask)) +return -EINVAL; +if (value) +writel(mask, &pio->port[port].sodr); +else +writel(mask, &pio->port[port].codr); +writel(mask, &pio->port[port].oer); + +return 0; +} +*/ +/* +* assuming the pin is muxed as a gpio output, set its value. +*/ +int at91_set_gpio_value (unsigned pin,int value) +{ +at91_pio_t *pio = (at91_pio_t *)AT91_PIO_BASE ; +u32 port =portpin_to_port (pin); +u32 mask =portpin_to_pin (pin); + +/* printf("%d = Port %d Pin %d (%d)",pin, port, mask, value); */ +if (value) +writel (mask, &pio->port[port].sodr); +else +writel (mask, &pio->port[port].codr); +return 0 ; +} + +/* +* read the pin's value (works even if it's not muxed as a gpio). +*/ +int at91_get_gpio_value (unsigned pin) +{ +at91_pio_t *pio = (at91_pio_t *)AT91_PIO_BASE ; +u32 port =portpin_to_port (pin); +u32 mask =portpin_to_pin (pin); +u32 pdsr; + + pdsr =readl (&pio->port[port]); +return (pdsr & mask) !=0 ; +} +
Signature · 1 line
1.6.0.2