uboot/arch/arm/cpu/armv7/omap-common/gpio.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2009 Wind River Systems, Inc.
   3 * Tom Rix <Tom.Rix@windriver.com>
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License as
   7 * published by the Free Software Foundation; either version 2 of
   8 * the License, or (at your option) any later version.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  18 * MA 02111-1307 USA
  19 *
  20 * This work is derived from the linux 2.6.27 kernel source
  21 * To fetch, use the kernel repository
  22 * git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
  23 * Use the v2.6.27 tag.
  24 *
  25 * Below is the original's header including its copyright
  26 *
  27 *  linux/arch/arm/plat-omap/gpio.c
  28 *
  29 * Support functions for OMAP GPIO
  30 *
  31 * Copyright (C) 2003-2005 Nokia Corporation
  32 * Written by Juha Yrjölä <juha.yrjola@nokia.com>
  33 *
  34 * This program is free software; you can redistribute it and/or modify
  35 * it under the terms of the GNU General Public License version 2 as
  36 * published by the Free Software Foundation.
  37 */
  38#include <common.h>
  39#include <asm/gpio.h>
  40#include <asm/io.h>
  41#include <asm/errno.h>
  42
  43#define OMAP_GPIO_DIR_OUT       0
  44#define OMAP_GPIO_DIR_IN        1
  45
  46static inline const struct gpio_bank *get_gpio_bank(int gpio)
  47{
  48        return &omap_gpio_bank[gpio >> 5];
  49}
  50
  51static inline int get_gpio_index(int gpio)
  52{
  53        return gpio & 0x1f;
  54}
  55
  56static inline int gpio_valid(int gpio)
  57{
  58        if (gpio < 0)
  59                return -1;
  60        if (gpio < 192)
  61                return 0;
  62        return -1;
  63}
  64
  65static int check_gpio(int gpio)
  66{
  67        if (gpio_valid(gpio) < 0) {
  68                printf("ERROR : check_gpio: invalid GPIO %d\n", gpio);
  69                return -1;
  70        }
  71        return 0;
  72}
  73
  74static void _set_gpio_direction(const struct gpio_bank *bank, int gpio,
  75                                int is_input)
  76{
  77        void *reg = bank->base;
  78        u32 l;
  79
  80        switch (bank->method) {
  81        case METHOD_GPIO_24XX:
  82                reg += OMAP_GPIO_OE;
  83                break;
  84        default:
  85                return;
  86        }
  87        l = __raw_readl(reg);
  88        if (is_input)
  89                l |= 1 << gpio;
  90        else
  91                l &= ~(1 << gpio);
  92        __raw_writel(l, reg);
  93}
  94
  95/**
  96 * Get the direction of the GPIO by reading the GPIO_OE register
  97 * corresponding to the specified bank.
  98 */
  99static int _get_gpio_direction(const struct gpio_bank *bank, int gpio)
 100{
 101        void *reg = bank->base;
 102        u32 v;
 103
 104        switch (bank->method) {
 105        case METHOD_GPIO_24XX:
 106                reg += OMAP_GPIO_OE;
 107                break;
 108        default:
 109                return -1;
 110        }
 111
 112        v = __raw_readl(reg);
 113
 114        if (v & (1 << gpio))
 115                return OMAP_GPIO_DIR_IN;
 116        else
 117                return OMAP_GPIO_DIR_OUT;
 118}
 119
 120static void _set_gpio_dataout(const struct gpio_bank *bank, int gpio,
 121                                int enable)
 122{
 123        void *reg = bank->base;
 124        u32 l = 0;
 125
 126        switch (bank->method) {
 127        case METHOD_GPIO_24XX:
 128                if (enable)
 129                        reg += OMAP_GPIO_SETDATAOUT;
 130                else
 131                        reg += OMAP_GPIO_CLEARDATAOUT;
 132                l = 1 << gpio;
 133                break;
 134        default:
 135                printf("omap3-gpio unknown bank method %s %d\n",
 136                       __FILE__, __LINE__);
 137                return;
 138        }
 139        __raw_writel(l, reg);
 140}
 141
 142/**
 143 * Set value of the specified gpio
 144 */
 145int gpio_set_value(unsigned gpio, int value)
 146{
 147        const struct gpio_bank *bank;
 148
 149        if (check_gpio(gpio) < 0)
 150                return -1;
 151        bank = get_gpio_bank(gpio);
 152        _set_gpio_dataout(bank, get_gpio_index(gpio), value);
 153
 154        return 0;
 155}
 156
 157/**
 158 * Get value of the specified gpio
 159 */
 160int gpio_get_value(unsigned gpio)
 161{
 162        const struct gpio_bank *bank;
 163        void *reg;
 164        int input;
 165
 166        if (check_gpio(gpio) < 0)
 167                return -1;
 168        bank = get_gpio_bank(gpio);
 169        reg = bank->base;
 170        switch (bank->method) {
 171        case METHOD_GPIO_24XX:
 172                input = _get_gpio_direction(bank, get_gpio_index(gpio));
 173                switch (input) {
 174                case OMAP_GPIO_DIR_IN:
 175                        reg += OMAP_GPIO_DATAIN;
 176                        break;
 177                case OMAP_GPIO_DIR_OUT:
 178                        reg += OMAP_GPIO_DATAOUT;
 179                        break;
 180                default:
 181                        return -1;
 182                }
 183                break;
 184        default:
 185                return -1;
 186        }
 187        return (__raw_readl(reg)
 188                        & (1 << get_gpio_index(gpio))) != 0;
 189}
 190
 191/**
 192 * Set gpio direction as input
 193 */
 194int gpio_direction_input(unsigned gpio)
 195{
 196        const struct gpio_bank *bank;
 197
 198        if (check_gpio(gpio) < 0)
 199                return -1;
 200
 201        bank = get_gpio_bank(gpio);
 202        _set_gpio_direction(bank, get_gpio_index(gpio), 1);
 203
 204        return 0;
 205}
 206
 207/**
 208 * Set gpio direction as output
 209 */
 210int gpio_direction_output(unsigned gpio, int value)
 211{
 212        const struct gpio_bank *bank;
 213
 214        if (check_gpio(gpio) < 0)
 215                return -1;
 216
 217        bank = get_gpio_bank(gpio);
 218        _set_gpio_dataout(bank, get_gpio_index(gpio), value);
 219        _set_gpio_direction(bank, get_gpio_index(gpio), 0);
 220
 221        return 0;
 222}
 223
 224/**
 225 * Request a gpio before using it.
 226 *
 227 * NOTE: Argument 'label' is unused.
 228 */
 229int gpio_request(unsigned gpio, const char *label)
 230{
 231        if (check_gpio(gpio) < 0)
 232                return -1;
 233
 234        return 0;
 235}
 236
 237/**
 238 * Reset and free the gpio after using it.
 239 */
 240int gpio_free(unsigned gpio)
 241{
 242        return 0;
 243}
 244