xref: /openbmc/u-boot/drivers/gpio/da8xx_gpio.c (revision f517afd5)
1*f517afd5SLaurence Withers /*
2*f517afd5SLaurence Withers  * GPIO driver for TI DaVinci DA8xx SOCs.
3*f517afd5SLaurence Withers  *
4*f517afd5SLaurence Withers  * (C) Copyright 2011 Guralp Systems Ltd.
5*f517afd5SLaurence Withers  * Laurence Withers <lwithers@guralp.com>
6*f517afd5SLaurence Withers  *
7*f517afd5SLaurence Withers  * This program is free software; you can redistribute it and/or
8*f517afd5SLaurence Withers  * modify it under the terms of the GNU General Public License as
9*f517afd5SLaurence Withers  * published by the Free Software Foundation; either version 2 of
10*f517afd5SLaurence Withers  * the License, or (at your option) any later version.
11*f517afd5SLaurence Withers  *
12*f517afd5SLaurence Withers  * This program is distributed in the hope that it will be useful,
13*f517afd5SLaurence Withers  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14*f517afd5SLaurence Withers  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*f517afd5SLaurence Withers  * GNU General Public License for more details.
16*f517afd5SLaurence Withers  *
17*f517afd5SLaurence Withers  * You should have received a copy of the GNU General Public License
18*f517afd5SLaurence Withers  * along with this program; if not, write to the Free Software
19*f517afd5SLaurence Withers  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20*f517afd5SLaurence Withers  * MA 02111-1307 USA
21*f517afd5SLaurence Withers  */
22*f517afd5SLaurence Withers 
23*f517afd5SLaurence Withers #include <common.h>
24*f517afd5SLaurence Withers #include <asm/io.h>
25*f517afd5SLaurence Withers #include <asm/gpio.h>
26*f517afd5SLaurence Withers #include <asm/arch/gpio.h>
27*f517afd5SLaurence Withers #include <asm/arch/hardware.h>
28*f517afd5SLaurence Withers #include <asm/arch/davinci_misc.h>
29*f517afd5SLaurence Withers 
30*f517afd5SLaurence Withers 
31*f517afd5SLaurence Withers static struct gpio_registry {
32*f517afd5SLaurence Withers 	int is_registered;
33*f517afd5SLaurence Withers 	char name[GPIO_NAME_SIZE];
34*f517afd5SLaurence Withers } gpio_registry[MAX_NUM_GPIOS];
35*f517afd5SLaurence Withers 
36*f517afd5SLaurence Withers 
37*f517afd5SLaurence Withers #define pinmux(x)       (&davinci_syscfg_regs->pinmux[x])
38*f517afd5SLaurence Withers 
39*f517afd5SLaurence Withers static const struct pinmux_config gpio_pinmux[] = {
40*f517afd5SLaurence Withers 	{ pinmux(1), 8, 7 },	/* GP0[0] */
41*f517afd5SLaurence Withers 	{ pinmux(1), 8, 6 },
42*f517afd5SLaurence Withers 	{ pinmux(1), 8, 5 },
43*f517afd5SLaurence Withers 	{ pinmux(1), 8, 4 },
44*f517afd5SLaurence Withers 	{ pinmux(1), 8, 3 },
45*f517afd5SLaurence Withers 	{ pinmux(1), 8, 2 },
46*f517afd5SLaurence Withers 	{ pinmux(1), 8, 1 },
47*f517afd5SLaurence Withers 	{ pinmux(1), 8, 0 },
48*f517afd5SLaurence Withers 	{ pinmux(0), 8, 7 },
49*f517afd5SLaurence Withers 	{ pinmux(0), 8, 6 },
50*f517afd5SLaurence Withers 	{ pinmux(0), 8, 5 },
51*f517afd5SLaurence Withers 	{ pinmux(0), 8, 4 },
52*f517afd5SLaurence Withers 	{ pinmux(0), 8, 3 },
53*f517afd5SLaurence Withers 	{ pinmux(0), 8, 2 },
54*f517afd5SLaurence Withers 	{ pinmux(0), 8, 1 },
55*f517afd5SLaurence Withers 	{ pinmux(0), 8, 0 },
56*f517afd5SLaurence Withers 	{ pinmux(4), 8, 7 },	/* GP1[0] */
57*f517afd5SLaurence Withers 	{ pinmux(4), 8, 6 },
58*f517afd5SLaurence Withers 	{ pinmux(4), 8, 5 },
59*f517afd5SLaurence Withers 	{ pinmux(4), 8, 4 },
60*f517afd5SLaurence Withers 	{ pinmux(4), 8, 3 },
61*f517afd5SLaurence Withers 	{ pinmux(4), 8, 2 },
62*f517afd5SLaurence Withers 	{ pinmux(4), 4, 1 },
63*f517afd5SLaurence Withers 	{ pinmux(4), 4, 0 },
64*f517afd5SLaurence Withers 	{ pinmux(3), 4, 0 },
65*f517afd5SLaurence Withers 	{ pinmux(2), 4, 6 },
66*f517afd5SLaurence Withers 	{ pinmux(2), 4, 5 },
67*f517afd5SLaurence Withers 	{ pinmux(2), 4, 4 },
68*f517afd5SLaurence Withers 	{ pinmux(2), 4, 3 },
69*f517afd5SLaurence Withers 	{ pinmux(2), 4, 2 },
70*f517afd5SLaurence Withers 	{ pinmux(2), 4, 1 },
71*f517afd5SLaurence Withers 	{ pinmux(2), 8, 0 },
72*f517afd5SLaurence Withers 	{ pinmux(6), 8, 7 },	/* GP2[0] */
73*f517afd5SLaurence Withers 	{ pinmux(6), 8, 6 },
74*f517afd5SLaurence Withers 	{ pinmux(6), 8, 5 },
75*f517afd5SLaurence Withers 	{ pinmux(6), 8, 4 },
76*f517afd5SLaurence Withers 	{ pinmux(6), 8, 3 },
77*f517afd5SLaurence Withers 	{ pinmux(6), 8, 2 },
78*f517afd5SLaurence Withers 	{ pinmux(6), 8, 1 },
79*f517afd5SLaurence Withers 	{ pinmux(6), 8, 0 },
80*f517afd5SLaurence Withers 	{ pinmux(5), 8, 7 },
81*f517afd5SLaurence Withers 	{ pinmux(5), 8, 6 },
82*f517afd5SLaurence Withers 	{ pinmux(5), 8, 5 },
83*f517afd5SLaurence Withers 	{ pinmux(5), 8, 4 },
84*f517afd5SLaurence Withers 	{ pinmux(5), 8, 3 },
85*f517afd5SLaurence Withers 	{ pinmux(5), 8, 2 },
86*f517afd5SLaurence Withers 	{ pinmux(5), 8, 1 },
87*f517afd5SLaurence Withers 	{ pinmux(5), 8, 0 },
88*f517afd5SLaurence Withers 	{ pinmux(8), 8, 7 },	/* GP3[0] */
89*f517afd5SLaurence Withers 	{ pinmux(8), 8, 6 },
90*f517afd5SLaurence Withers 	{ pinmux(8), 8, 5 },
91*f517afd5SLaurence Withers 	{ pinmux(8), 8, 4 },
92*f517afd5SLaurence Withers 	{ pinmux(8), 8, 3 },
93*f517afd5SLaurence Withers 	{ pinmux(8), 8, 2 },
94*f517afd5SLaurence Withers 	{ pinmux(8), 8, 1 },
95*f517afd5SLaurence Withers 	{ pinmux(8), 8, 0 },
96*f517afd5SLaurence Withers 	{ pinmux(7), 8, 7 },
97*f517afd5SLaurence Withers 	{ pinmux(7), 8, 6 },
98*f517afd5SLaurence Withers 	{ pinmux(7), 8, 5 },
99*f517afd5SLaurence Withers 	{ pinmux(7), 8, 4 },
100*f517afd5SLaurence Withers 	{ pinmux(7), 8, 3 },
101*f517afd5SLaurence Withers 	{ pinmux(7), 8, 2 },
102*f517afd5SLaurence Withers 	{ pinmux(7), 8, 1 },
103*f517afd5SLaurence Withers 	{ pinmux(7), 8, 0 },
104*f517afd5SLaurence Withers 	{ pinmux(10), 8, 7 },	/* GP4[0] */
105*f517afd5SLaurence Withers 	{ pinmux(10), 8, 6 },
106*f517afd5SLaurence Withers 	{ pinmux(10), 8, 5 },
107*f517afd5SLaurence Withers 	{ pinmux(10), 8, 4 },
108*f517afd5SLaurence Withers 	{ pinmux(10), 8, 3 },
109*f517afd5SLaurence Withers 	{ pinmux(10), 8, 2 },
110*f517afd5SLaurence Withers 	{ pinmux(10), 8, 1 },
111*f517afd5SLaurence Withers 	{ pinmux(10), 8, 0 },
112*f517afd5SLaurence Withers 	{ pinmux(9), 8, 7 },
113*f517afd5SLaurence Withers 	{ pinmux(9), 8, 6 },
114*f517afd5SLaurence Withers 	{ pinmux(9), 8, 5 },
115*f517afd5SLaurence Withers 	{ pinmux(9), 8, 4 },
116*f517afd5SLaurence Withers 	{ pinmux(9), 8, 3 },
117*f517afd5SLaurence Withers 	{ pinmux(9), 8, 2 },
118*f517afd5SLaurence Withers 	{ pinmux(9), 8, 1 },
119*f517afd5SLaurence Withers 	{ pinmux(9), 8, 0 },
120*f517afd5SLaurence Withers 	{ pinmux(12), 8, 7 },	/* GP5[0] */
121*f517afd5SLaurence Withers 	{ pinmux(12), 8, 6 },
122*f517afd5SLaurence Withers 	{ pinmux(12), 8, 5 },
123*f517afd5SLaurence Withers 	{ pinmux(12), 8, 4 },
124*f517afd5SLaurence Withers 	{ pinmux(12), 8, 3 },
125*f517afd5SLaurence Withers 	{ pinmux(12), 8, 2 },
126*f517afd5SLaurence Withers 	{ pinmux(12), 8, 1 },
127*f517afd5SLaurence Withers 	{ pinmux(12), 8, 0 },
128*f517afd5SLaurence Withers 	{ pinmux(11), 8, 7 },
129*f517afd5SLaurence Withers 	{ pinmux(11), 8, 6 },
130*f517afd5SLaurence Withers 	{ pinmux(11), 8, 5 },
131*f517afd5SLaurence Withers 	{ pinmux(11), 8, 4 },
132*f517afd5SLaurence Withers 	{ pinmux(11), 8, 3 },
133*f517afd5SLaurence Withers 	{ pinmux(11), 8, 2 },
134*f517afd5SLaurence Withers 	{ pinmux(11), 8, 1 },
135*f517afd5SLaurence Withers 	{ pinmux(11), 8, 0 },
136*f517afd5SLaurence Withers 	{ pinmux(19), 8, 6 },	/* GP6[0] */
137*f517afd5SLaurence Withers 	{ pinmux(19), 8, 5 },
138*f517afd5SLaurence Withers 	{ pinmux(19), 8, 4 },
139*f517afd5SLaurence Withers 	{ pinmux(19), 8, 3 },
140*f517afd5SLaurence Withers 	{ pinmux(19), 8, 2 },
141*f517afd5SLaurence Withers 	{ pinmux(16), 8, 1 },
142*f517afd5SLaurence Withers 	{ pinmux(14), 8, 1 },
143*f517afd5SLaurence Withers 	{ pinmux(14), 8, 0 },
144*f517afd5SLaurence Withers 	{ pinmux(13), 8, 7 },
145*f517afd5SLaurence Withers 	{ pinmux(13), 8, 6 },
146*f517afd5SLaurence Withers 	{ pinmux(13), 8, 5 },
147*f517afd5SLaurence Withers 	{ pinmux(13), 8, 4 },
148*f517afd5SLaurence Withers 	{ pinmux(13), 8, 3 },
149*f517afd5SLaurence Withers 	{ pinmux(13), 8, 2 },
150*f517afd5SLaurence Withers 	{ pinmux(13), 8, 1 },
151*f517afd5SLaurence Withers 	{ pinmux(13), 8, 0 },
152*f517afd5SLaurence Withers 	{ pinmux(18), 8, 1 },	/* GP7[0] */
153*f517afd5SLaurence Withers 	{ pinmux(18), 8, 0 },
154*f517afd5SLaurence Withers 	{ pinmux(17), 8, 7 },
155*f517afd5SLaurence Withers 	{ pinmux(17), 8, 6 },
156*f517afd5SLaurence Withers 	{ pinmux(17), 8, 5 },
157*f517afd5SLaurence Withers 	{ pinmux(17), 8, 4 },
158*f517afd5SLaurence Withers 	{ pinmux(17), 8, 3 },
159*f517afd5SLaurence Withers 	{ pinmux(17), 8, 2 },
160*f517afd5SLaurence Withers 	{ pinmux(17), 8, 1 },
161*f517afd5SLaurence Withers 	{ pinmux(17), 8, 0 },
162*f517afd5SLaurence Withers 	{ pinmux(16), 8, 7 },
163*f517afd5SLaurence Withers 	{ pinmux(16), 8, 6 },
164*f517afd5SLaurence Withers 	{ pinmux(16), 8, 5 },
165*f517afd5SLaurence Withers 	{ pinmux(16), 8, 4 },
166*f517afd5SLaurence Withers 	{ pinmux(16), 8, 3 },
167*f517afd5SLaurence Withers 	{ pinmux(16), 8, 2 },
168*f517afd5SLaurence Withers 	{ pinmux(19), 8, 0 },	/* GP8[0] */
169*f517afd5SLaurence Withers 	{ pinmux(3), 4, 7 },
170*f517afd5SLaurence Withers 	{ pinmux(3), 4, 6 },
171*f517afd5SLaurence Withers 	{ pinmux(3), 4, 5 },
172*f517afd5SLaurence Withers 	{ pinmux(3), 4, 4 },
173*f517afd5SLaurence Withers 	{ pinmux(3), 4, 3 },
174*f517afd5SLaurence Withers 	{ pinmux(3), 4, 2 },
175*f517afd5SLaurence Withers 	{ pinmux(2), 4, 7 },
176*f517afd5SLaurence Withers 	{ pinmux(19), 8, 1 },
177*f517afd5SLaurence Withers 	{ pinmux(19), 8, 0 },
178*f517afd5SLaurence Withers 	{ pinmux(18), 8, 7 },
179*f517afd5SLaurence Withers 	{ pinmux(18), 8, 6 },
180*f517afd5SLaurence Withers 	{ pinmux(18), 8, 5 },
181*f517afd5SLaurence Withers 	{ pinmux(18), 8, 4 },
182*f517afd5SLaurence Withers 	{ pinmux(18), 8, 3 },
183*f517afd5SLaurence Withers 	{ pinmux(18), 8, 2 },
184*f517afd5SLaurence Withers };
185*f517afd5SLaurence Withers 
186*f517afd5SLaurence Withers 
187*f517afd5SLaurence Withers 
188*f517afd5SLaurence Withers int gpio_request(int gp, const char *label)
189*f517afd5SLaurence Withers {
190*f517afd5SLaurence Withers 	if (gp >= MAX_NUM_GPIOS)
191*f517afd5SLaurence Withers 		return -1;
192*f517afd5SLaurence Withers 
193*f517afd5SLaurence Withers 	if (gpio_registry[gp].is_registered)
194*f517afd5SLaurence Withers 		return -1;
195*f517afd5SLaurence Withers 
196*f517afd5SLaurence Withers 	gpio_registry[gp].is_registered = 1;
197*f517afd5SLaurence Withers 	strncpy(gpio_registry[gp].name, label, GPIO_NAME_SIZE);
198*f517afd5SLaurence Withers 	gpio_registry[gp].name[GPIO_NAME_SIZE - 1] = 0;
199*f517afd5SLaurence Withers 
200*f517afd5SLaurence Withers 	davinci_configure_pin_mux(&gpio_pinmux[gp], 1);
201*f517afd5SLaurence Withers 
202*f517afd5SLaurence Withers 	return 0;
203*f517afd5SLaurence Withers }
204*f517afd5SLaurence Withers 
205*f517afd5SLaurence Withers 
206*f517afd5SLaurence Withers void gpio_free(int gp)
207*f517afd5SLaurence Withers {
208*f517afd5SLaurence Withers 	gpio_registry[gp].is_registered = 0;
209*f517afd5SLaurence Withers }
210*f517afd5SLaurence Withers 
211*f517afd5SLaurence Withers 
212*f517afd5SLaurence Withers void gpio_toggle_value(int gp)
213*f517afd5SLaurence Withers {
214*f517afd5SLaurence Withers 	struct davinci_gpio *bank;
215*f517afd5SLaurence Withers 
216*f517afd5SLaurence Withers 	bank = GPIO_BANK(gp);
217*f517afd5SLaurence Withers 	gpio_set_value(gp, !gpio_get_value(gp));
218*f517afd5SLaurence Withers }
219*f517afd5SLaurence Withers 
220*f517afd5SLaurence Withers 
221*f517afd5SLaurence Withers int gpio_direction_input(int gp)
222*f517afd5SLaurence Withers {
223*f517afd5SLaurence Withers 	struct davinci_gpio *bank;
224*f517afd5SLaurence Withers 
225*f517afd5SLaurence Withers 	bank = GPIO_BANK(gp);
226*f517afd5SLaurence Withers 	setbits_le32(&bank->dir, 1U << GPIO_BIT(gp));
227*f517afd5SLaurence Withers 	return 0;
228*f517afd5SLaurence Withers }
229*f517afd5SLaurence Withers 
230*f517afd5SLaurence Withers 
231*f517afd5SLaurence Withers int gpio_direction_output(int gp, int value)
232*f517afd5SLaurence Withers {
233*f517afd5SLaurence Withers 	struct davinci_gpio *bank;
234*f517afd5SLaurence Withers 
235*f517afd5SLaurence Withers 	bank = GPIO_BANK(gp);
236*f517afd5SLaurence Withers 	clrbits_le32(&bank->dir, 1U << GPIO_BIT(gp));
237*f517afd5SLaurence Withers 	gpio_set_value(gp, value);
238*f517afd5SLaurence Withers 	return 0;
239*f517afd5SLaurence Withers }
240*f517afd5SLaurence Withers 
241*f517afd5SLaurence Withers 
242*f517afd5SLaurence Withers int gpio_get_value(int gp)
243*f517afd5SLaurence Withers {
244*f517afd5SLaurence Withers 	struct davinci_gpio *bank;
245*f517afd5SLaurence Withers 	unsigned int ip;
246*f517afd5SLaurence Withers 
247*f517afd5SLaurence Withers 	bank = GPIO_BANK(gp);
248*f517afd5SLaurence Withers 	ip = in_le32(&bank->in_data) & (1U << GPIO_BIT(gp));
249*f517afd5SLaurence Withers 	return ip ? 1 : 0;
250*f517afd5SLaurence Withers }
251*f517afd5SLaurence Withers 
252*f517afd5SLaurence Withers 
253*f517afd5SLaurence Withers void gpio_set_value(int gp, int value)
254*f517afd5SLaurence Withers {
255*f517afd5SLaurence Withers 	struct davinci_gpio *bank;
256*f517afd5SLaurence Withers 
257*f517afd5SLaurence Withers 	bank = GPIO_BANK(gp);
258*f517afd5SLaurence Withers 
259*f517afd5SLaurence Withers 	if (value)
260*f517afd5SLaurence Withers 		bank->set_data = 1U << GPIO_BIT(gp);
261*f517afd5SLaurence Withers 	else
262*f517afd5SLaurence Withers 		bank->clr_data = 1U << GPIO_BIT(gp);
263*f517afd5SLaurence Withers }
264*f517afd5SLaurence Withers 
265*f517afd5SLaurence Withers 
266*f517afd5SLaurence Withers void gpio_info(void)
267*f517afd5SLaurence Withers {
268*f517afd5SLaurence Withers 	int gp, dir, val;
269*f517afd5SLaurence Withers 	struct davinci_gpio *bank;
270*f517afd5SLaurence Withers 
271*f517afd5SLaurence Withers 	for (gp = 0; gp < MAX_NUM_GPIOS; ++gp) {
272*f517afd5SLaurence Withers 		bank = GPIO_BANK(gp);
273*f517afd5SLaurence Withers 		dir = in_le32(&bank->dir) & (1U << GPIO_BIT(gp));
274*f517afd5SLaurence Withers 		val = gpio_get_value(gp);
275*f517afd5SLaurence Withers 
276*f517afd5SLaurence Withers 		printf("% 4d: %s: %d [%c] %s\n",
277*f517afd5SLaurence Withers 			gp, dir ? " in" : "out", val,
278*f517afd5SLaurence Withers 			gpio_registry[gp].is_registered ? 'x' : ' ',
279*f517afd5SLaurence Withers 			gpio_registry[gp].name);
280*f517afd5SLaurence Withers 	}
281*f517afd5SLaurence Withers }
282