add at91 SoC access with c structures
Subsystems (2)
PATCH 6/8 add at91 SoC access with c structures
* add new at91_gpio driver, using c structure SoC access
--- 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 +106 -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