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