1*2cb06a4fSStefan Roese /* 2*2cb06a4fSStefan Roese * Copyright (C) 2012 Stefan Roese <sr@denx.de> 3*2cb06a4fSStefan Roese * 4*2cb06a4fSStefan Roese * See file CREDITS for list of people who contributed to this 5*2cb06a4fSStefan Roese * project. 6*2cb06a4fSStefan Roese * 7*2cb06a4fSStefan Roese * This program is free software; you can redistribute it and/or 8*2cb06a4fSStefan Roese * modify it under the terms of the GNU General Public License as 9*2cb06a4fSStefan Roese * published by the Free Software Foundation; either version 2 of 10*2cb06a4fSStefan Roese * the License, or (at your option) any later version. 11*2cb06a4fSStefan Roese * 12*2cb06a4fSStefan Roese * This program is distributed in the hope that it will be useful, 13*2cb06a4fSStefan Roese * but WITHOUT ANY WARRANTY; without even the implied warranty of 14*2cb06a4fSStefan Roese * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*2cb06a4fSStefan Roese * GNU General Public License for more details. 16*2cb06a4fSStefan Roese * 17*2cb06a4fSStefan Roese * You should have received a copy of the GNU General Public License 18*2cb06a4fSStefan Roese * along with this program; if not, write to the Free Software 19*2cb06a4fSStefan Roese * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 20*2cb06a4fSStefan Roese * MA 02111-1307 USA 21*2cb06a4fSStefan Roese */ 22*2cb06a4fSStefan Roese 23*2cb06a4fSStefan Roese /* 24*2cb06a4fSStefan Roese * Driver for SPEAr600 GPIO controller 25*2cb06a4fSStefan Roese */ 26*2cb06a4fSStefan Roese 27*2cb06a4fSStefan Roese #include <common.h> 28*2cb06a4fSStefan Roese #include <asm/arch/hardware.h> 29*2cb06a4fSStefan Roese #include <asm/gpio.h> 30*2cb06a4fSStefan Roese #include <asm/io.h> 31*2cb06a4fSStefan Roese #include <errno.h> 32*2cb06a4fSStefan Roese 33*2cb06a4fSStefan Roese static int gpio_direction(unsigned gpio, 34*2cb06a4fSStefan Roese enum gpio_direction direction) 35*2cb06a4fSStefan Roese { 36*2cb06a4fSStefan Roese struct gpio_regs *regs = (struct gpio_regs *)CONFIG_GPIO_BASE; 37*2cb06a4fSStefan Roese u32 val; 38*2cb06a4fSStefan Roese 39*2cb06a4fSStefan Roese val = readl(®s->gpiodir); 40*2cb06a4fSStefan Roese 41*2cb06a4fSStefan Roese if (direction == GPIO_DIRECTION_OUT) 42*2cb06a4fSStefan Roese val |= 1 << gpio; 43*2cb06a4fSStefan Roese else 44*2cb06a4fSStefan Roese val &= ~(1 << gpio); 45*2cb06a4fSStefan Roese 46*2cb06a4fSStefan Roese writel(val, ®s->gpiodir); 47*2cb06a4fSStefan Roese 48*2cb06a4fSStefan Roese return 0; 49*2cb06a4fSStefan Roese } 50*2cb06a4fSStefan Roese 51*2cb06a4fSStefan Roese int gpio_set_value(unsigned gpio, int value) 52*2cb06a4fSStefan Roese { 53*2cb06a4fSStefan Roese struct gpio_regs *regs = (struct gpio_regs *)CONFIG_GPIO_BASE; 54*2cb06a4fSStefan Roese 55*2cb06a4fSStefan Roese writel(1 << gpio, ®s->gpiodata[DATA_REG_ADDR(gpio)]); 56*2cb06a4fSStefan Roese 57*2cb06a4fSStefan Roese return 0; 58*2cb06a4fSStefan Roese } 59*2cb06a4fSStefan Roese 60*2cb06a4fSStefan Roese int gpio_get_value(unsigned gpio) 61*2cb06a4fSStefan Roese { 62*2cb06a4fSStefan Roese struct gpio_regs *regs = (struct gpio_regs *)CONFIG_GPIO_BASE; 63*2cb06a4fSStefan Roese u32 val; 64*2cb06a4fSStefan Roese 65*2cb06a4fSStefan Roese val = readl(®s->gpiodata[DATA_REG_ADDR(gpio)]); 66*2cb06a4fSStefan Roese 67*2cb06a4fSStefan Roese return !!val; 68*2cb06a4fSStefan Roese } 69*2cb06a4fSStefan Roese 70*2cb06a4fSStefan Roese int gpio_request(unsigned gpio, const char *label) 71*2cb06a4fSStefan Roese { 72*2cb06a4fSStefan Roese if (gpio >= SPEAR_GPIO_COUNT) 73*2cb06a4fSStefan Roese return -EINVAL; 74*2cb06a4fSStefan Roese 75*2cb06a4fSStefan Roese return 0; 76*2cb06a4fSStefan Roese } 77*2cb06a4fSStefan Roese 78*2cb06a4fSStefan Roese int gpio_free(unsigned gpio) 79*2cb06a4fSStefan Roese { 80*2cb06a4fSStefan Roese return 0; 81*2cb06a4fSStefan Roese } 82*2cb06a4fSStefan Roese 83*2cb06a4fSStefan Roese void gpio_toggle_value(unsigned gpio) 84*2cb06a4fSStefan Roese { 85*2cb06a4fSStefan Roese gpio_set_value(gpio, !gpio_get_value(gpio)); 86*2cb06a4fSStefan Roese } 87*2cb06a4fSStefan Roese 88*2cb06a4fSStefan Roese int gpio_direction_input(unsigned gpio) 89*2cb06a4fSStefan Roese { 90*2cb06a4fSStefan Roese return gpio_direction(gpio, GPIO_DIRECTION_IN); 91*2cb06a4fSStefan Roese } 92*2cb06a4fSStefan Roese 93*2cb06a4fSStefan Roese int gpio_direction_output(unsigned gpio, int value) 94*2cb06a4fSStefan Roese { 95*2cb06a4fSStefan Roese int ret = gpio_direction(gpio, GPIO_DIRECTION_OUT); 96*2cb06a4fSStefan Roese 97*2cb06a4fSStefan Roese if (ret < 0) 98*2cb06a4fSStefan Roese return ret; 99*2cb06a4fSStefan Roese 100*2cb06a4fSStefan Roese gpio_set_value(gpio, value); 101*2cb06a4fSStefan Roese return 0; 102*2cb06a4fSStefan Roese } 103