xref: /openbmc/u-boot/drivers/gpio/spear_gpio.c (revision 2cb06a4f)
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(&regs->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, &regs->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, &regs->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(&regs->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