uboot/drivers/gpio/at91_gpio.c
<<
>>
Prefs
   1/*
   2 * Memory Setup stuff - taken from blob memsetup.S
   3 *
   4 * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de)
   5 *
   6 *  Copyright (C) 2005 HP Labs
   7 *
   8 * See file CREDITS for list of people who contributed to this
   9 * project.
  10 *
  11 * This program is free software; you can redistribute it and/or
  12 * modify it under the terms of the GNU General Public License as
  13 * published by the Free Software Foundation; either version 2 of
  14 * the License, or (at your option) any later version.
  15 *
  16 * This program is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19 * GNU General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program; if not, write to the Free Software
  23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24 * MA 02111-1307 USA
  25 */
  26
  27/*
  28 * WARNING:
  29 *
  30 * As the code is right now, it expects all PIO ports A,B,C,...
  31 * to be evenly spaced in the memory map:
  32 * ATMEL_BASE_PIOA + port * sizeof at91pio_t
  33 * This might not necessaryly be true in future Atmel SoCs.
  34 * This code should be fixed to use a pointer array to the ports.
  35 */
  36
  37#include <config.h>
  38#include <common.h>
  39#include <asm/io.h>
  40#include <asm/sizes.h>
  41#include <asm/arch/hardware.h>
  42#include <asm/arch/at91_pio.h>
  43
  44int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)
  45{
  46        at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  47        u32             mask;
  48
  49        if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  50                mask = 1 << pin;
  51                if (use_pullup)
  52                        writel(1 << pin, &pio->port[port].puer);
  53                else
  54                        writel(1 << pin, &pio->port[port].pudr);
  55                writel(mask, &pio->port[port].per);
  56        }
  57        return 0;
  58}
  59
  60/*
  61 * mux the pin to the "GPIO" peripheral role.
  62 */
  63int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup)
  64{
  65        at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  66        u32             mask;
  67
  68        if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  69                mask = 1 << pin;
  70                writel(mask, &pio->port[port].idr);
  71                at91_set_pio_pullup(port, pin, use_pullup);
  72                writel(mask, &pio->port[port].per);
  73        }
  74        return 0;
  75}
  76
  77/*
  78 * mux the pin to the "A" internal peripheral role.
  79 */
  80int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup)
  81{
  82        at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  83        u32             mask;
  84
  85        if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  86                mask = 1 << pin;
  87                writel(mask, &pio->port[port].idr);
  88                at91_set_pio_pullup(port, pin, use_pullup);
  89                writel(mask, &pio->port[port].asr);
  90                writel(mask, &pio->port[port].pdr);
  91        }
  92        return 0;
  93}
  94
  95/*
  96 * mux the pin to the "B" internal peripheral role.
  97 */
  98int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup)
  99{
 100        at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
 101        u32             mask;
 102
 103        if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
 104                mask = 1 << pin;
 105                writel(mask, &pio->port[port].idr);
 106                at91_set_pio_pullup(port, pin, use_pullup);
 107                writel(mask, &pio->port[port].bsr);
 108                writel(mask, &pio->port[port].pdr);
 109        }
 110        return 0;
 111}
 112
 113/*
 114 * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
 115 * configure it for an input.
 116 */
 117int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)
 118{
 119        at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
 120        u32             mask;
 121
 122        if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
 123                mask = 1 << pin;
 124                writel(mask, &pio->port[port].idr);
 125                at91_set_pio_pullup(port, pin, use_pullup);
 126                writel(mask, &pio->port[port].odr);
 127                writel(mask, &pio->port[port].per);
 128        }
 129        return 0;
 130}
 131
 132/*
 133 * mux the pin to the gpio controller (instead of "A" or "B" peripheral),
 134 * and configure it for an output.
 135 */
 136int at91_set_pio_output(unsigned port, u32 pin, int value)
 137{
 138        at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
 139        u32             mask;
 140
 141        if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
 142                mask = 1 << pin;
 143                writel(mask, &pio->port[port].idr);
 144                writel(mask, &pio->port[port].pudr);
 145                if (value)
 146                        writel(mask, &pio->port[port].sodr);
 147                else
 148                        writel(mask, &pio->port[port].codr);
 149                writel(mask, &pio->port[port].oer);
 150                writel(mask, &pio->port[port].per);
 151        }
 152        return 0;
 153}
 154
 155/*
 156 * enable/disable the glitch filter. mostly used with IRQ handling.
 157 */
 158int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on)
 159{
 160        at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
 161        u32             mask;
 162
 163        if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
 164                mask = 1 << pin;
 165                if (is_on)
 166                        writel(mask, &pio->port[port].ifer);
 167                else
 168                        writel(mask, &pio->port[port].ifdr);
 169        }
 170        return 0;
 171}
 172
 173/*
 174 * enable/disable the multi-driver. This is only valid for output and
 175 * allows the output pin to run as an open collector output.
 176 */
 177int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
 178{
 179        at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
 180        u32             mask;
 181
 182        if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
 183                mask = 1 << pin;
 184                if (is_on)
 185                        writel(mask, &pio->port[port].mder);
 186                else
 187                        writel(mask, &pio->port[port].mddr);
 188        }
 189        return 0;
 190}
 191
 192/*
 193 * assuming the pin is muxed as a gpio output, set its value.
 194 */
 195int at91_set_pio_value(unsigned port, unsigned pin, int value)
 196{
 197        at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
 198        u32             mask;
 199
 200        if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
 201                mask = 1 << pin;
 202                if (value)
 203                        writel(mask, &pio->port[port].sodr);
 204                else
 205                        writel(mask, &pio->port[port].codr);
 206        }
 207        return 0;
 208}
 209
 210/*
 211 * read the pin's value (works even if it's not muxed as a gpio).
 212 */
 213int at91_get_pio_value(unsigned port, unsigned pin)
 214{
 215        u32             pdsr = 0;
 216        at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
 217        u32             mask;
 218
 219        if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
 220                mask = 1 << pin;
 221                pdsr = readl(&pio->port[port].pdsr) & mask;
 222        }
 223        return pdsr != 0;
 224}
 225