xref: /openbmc/u-boot/drivers/gpio/da8xx_gpio.c (revision 8e51c0f2)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2f517afd5SLaurence Withers /*
3f517afd5SLaurence Withers  * GPIO driver for TI DaVinci DA8xx SOCs.
4f517afd5SLaurence Withers  *
5f517afd5SLaurence Withers  * (C) Copyright 2011 Guralp Systems Ltd.
6f517afd5SLaurence Withers  * Laurence Withers <lwithers@guralp.com>
7f517afd5SLaurence Withers  */
8f517afd5SLaurence Withers 
9f517afd5SLaurence Withers #include <common.h>
10*8e51c0f2SAdam Ford #include <dm.h>
11*8e51c0f2SAdam Ford #include <fdtdec.h>
12f517afd5SLaurence Withers #include <asm/io.h>
13f517afd5SLaurence Withers #include <asm/gpio.h>
14f517afd5SLaurence Withers #include <asm/arch/hardware.h>
15f517afd5SLaurence Withers #include <asm/arch/davinci_misc.h>
16f517afd5SLaurence Withers 
17*8e51c0f2SAdam Ford #ifndef CONFIG_DM_GPIO
18f517afd5SLaurence Withers static struct gpio_registry {
19f517afd5SLaurence Withers 	int is_registered;
20f517afd5SLaurence Withers 	char name[GPIO_NAME_SIZE];
21f517afd5SLaurence Withers } gpio_registry[MAX_NUM_GPIOS];
22f517afd5SLaurence Withers 
2303414ac4SHolger Hans Peter Freyther #if defined(CONFIG_SOC_DA8XX)
24f517afd5SLaurence Withers #define pinmux(x)       (&davinci_syscfg_regs->pinmux[x])
25f517afd5SLaurence Withers 
26b9f56698STomas Novotny #if defined(CONFIG_SOC_DA8XX) && !defined(CONFIG_SOC_DA850)
27b9f56698STomas Novotny static const struct pinmux_config gpio_pinmux[] = {
28b9f56698STomas Novotny 	{ pinmux(13), 8, 6 },	/* GP0[0] */
29b9f56698STomas Novotny 	{ pinmux(13), 8, 7 },
30b9f56698STomas Novotny 	{ pinmux(14), 8, 0 },
31b9f56698STomas Novotny 	{ pinmux(14), 8, 1 },
32b9f56698STomas Novotny 	{ pinmux(14), 8, 2 },
33b9f56698STomas Novotny 	{ pinmux(14), 8, 3 },
34b9f56698STomas Novotny 	{ pinmux(14), 8, 4 },
35b9f56698STomas Novotny 	{ pinmux(14), 8, 5 },
36b9f56698STomas Novotny 	{ pinmux(14), 8, 6 },
37b9f56698STomas Novotny 	{ pinmux(14), 8, 7 },
38b9f56698STomas Novotny 	{ pinmux(15), 8, 0 },
39b9f56698STomas Novotny 	{ pinmux(15), 8, 1 },
40b9f56698STomas Novotny 	{ pinmux(15), 8, 2 },
41b9f56698STomas Novotny 	{ pinmux(15), 8, 3 },
42b9f56698STomas Novotny 	{ pinmux(15), 8, 4 },
43b9f56698STomas Novotny 	{ pinmux(15), 8, 5 },
44b9f56698STomas Novotny 	{ pinmux(15), 8, 6 },	/* GP1[0] */
45b9f56698STomas Novotny 	{ pinmux(15), 8, 7 },
46b9f56698STomas Novotny 	{ pinmux(16), 8, 0 },
47b9f56698STomas Novotny 	{ pinmux(16), 8, 1 },
48b9f56698STomas Novotny 	{ pinmux(16), 8, 2 },
49b9f56698STomas Novotny 	{ pinmux(16), 8, 3 },
50b9f56698STomas Novotny 	{ pinmux(16), 8, 4 },
51b9f56698STomas Novotny 	{ pinmux(16), 8, 5 },
52b9f56698STomas Novotny 	{ pinmux(16), 8, 6 },
53b9f56698STomas Novotny 	{ pinmux(16), 8, 7 },
54b9f56698STomas Novotny 	{ pinmux(17), 8, 0 },
55b9f56698STomas Novotny 	{ pinmux(17), 8, 1 },
56b9f56698STomas Novotny 	{ pinmux(17), 8, 2 },
57b9f56698STomas Novotny 	{ pinmux(17), 8, 3 },
58b9f56698STomas Novotny 	{ pinmux(17), 8, 4 },
59b9f56698STomas Novotny 	{ pinmux(17), 8, 5 },
60b9f56698STomas Novotny 	{ pinmux(17), 8, 6 },	/* GP2[0] */
61b9f56698STomas Novotny 	{ pinmux(17), 8, 7 },
62b9f56698STomas Novotny 	{ pinmux(18), 8, 0 },
63b9f56698STomas Novotny 	{ pinmux(18), 8, 1 },
64b9f56698STomas Novotny 	{ pinmux(18), 8, 2 },
65b9f56698STomas Novotny 	{ pinmux(18), 8, 3 },
66b9f56698STomas Novotny 	{ pinmux(18), 8, 4 },
67b9f56698STomas Novotny 	{ pinmux(18), 8, 5 },
68b9f56698STomas Novotny 	{ pinmux(18), 8, 6 },
69b9f56698STomas Novotny 	{ pinmux(18), 8, 7 },
70b9f56698STomas Novotny 	{ pinmux(19), 8, 0 },
71b9f56698STomas Novotny 	{ pinmux(9), 8, 2 },
72b9f56698STomas Novotny 	{ pinmux(9), 8, 3 },
73b9f56698STomas Novotny 	{ pinmux(9), 8, 4 },
74b9f56698STomas Novotny 	{ pinmux(9), 8, 5 },
75b9f56698STomas Novotny 	{ pinmux(9), 8, 6 },
76b9f56698STomas Novotny 	{ pinmux(10), 8, 1 },	/* GP3[0] */
77b9f56698STomas Novotny 	{ pinmux(10), 8, 2 },
78b9f56698STomas Novotny 	{ pinmux(10), 8, 3 },
79b9f56698STomas Novotny 	{ pinmux(10), 8, 4 },
80b9f56698STomas Novotny 	{ pinmux(10), 8, 5 },
81b9f56698STomas Novotny 	{ pinmux(10), 8, 6 },
82b9f56698STomas Novotny 	{ pinmux(10), 8, 7 },
83b9f56698STomas Novotny 	{ pinmux(11), 8, 0 },
84b9f56698STomas Novotny 	{ pinmux(11), 8, 1 },
85b9f56698STomas Novotny 	{ pinmux(11), 8, 2 },
86b9f56698STomas Novotny 	{ pinmux(11), 8, 3 },
87b9f56698STomas Novotny 	{ pinmux(11), 8, 4 },
88b9f56698STomas Novotny 	{ pinmux(9), 8, 7 },
89b9f56698STomas Novotny 	{ pinmux(2), 8, 6 },
90b9f56698STomas Novotny 	{ pinmux(11), 8, 5 },
91b9f56698STomas Novotny 	{ pinmux(11), 8, 6 },
92b9f56698STomas Novotny 	{ pinmux(12), 8, 4 },	/* GP4[0] */
93b9f56698STomas Novotny 	{ pinmux(12), 8, 5 },
94b9f56698STomas Novotny 	{ pinmux(12), 8, 6 },
95b9f56698STomas Novotny 	{ pinmux(12), 8, 7 },
96b9f56698STomas Novotny 	{ pinmux(13), 8, 0 },
97b9f56698STomas Novotny 	{ pinmux(13), 8, 1 },
98b9f56698STomas Novotny 	{ pinmux(13), 8, 2 },
99b9f56698STomas Novotny 	{ pinmux(13), 8, 3 },
100b9f56698STomas Novotny 	{ pinmux(13), 8, 4 },
101b9f56698STomas Novotny 	{ pinmux(13), 8, 5 },
102b9f56698STomas Novotny 	{ pinmux(11), 8, 7 },
103b9f56698STomas Novotny 	{ pinmux(12), 8, 0 },
104b9f56698STomas Novotny 	{ pinmux(12), 8, 1 },
105b9f56698STomas Novotny 	{ pinmux(12), 8, 2 },
106b9f56698STomas Novotny 	{ pinmux(12), 8, 3 },
107b9f56698STomas Novotny 	{ pinmux(9), 8, 1 },
108b9f56698STomas Novotny 	{ pinmux(7), 8, 3 },	/* GP5[0] */
109b9f56698STomas Novotny 	{ pinmux(7), 8, 4 },
110b9f56698STomas Novotny 	{ pinmux(7), 8, 5 },
111b9f56698STomas Novotny 	{ pinmux(7), 8, 6 },
112b9f56698STomas Novotny 	{ pinmux(7), 8, 7 },
113b9f56698STomas Novotny 	{ pinmux(8), 8, 0 },
114b9f56698STomas Novotny 	{ pinmux(8), 8, 1 },
115b9f56698STomas Novotny 	{ pinmux(8), 8, 2 },
116b9f56698STomas Novotny 	{ pinmux(8), 8, 3 },
117b9f56698STomas Novotny 	{ pinmux(8), 8, 4 },
118b9f56698STomas Novotny 	{ pinmux(8), 8, 5 },
119b9f56698STomas Novotny 	{ pinmux(8), 8, 6 },
120b9f56698STomas Novotny 	{ pinmux(8), 8, 7 },
121b9f56698STomas Novotny 	{ pinmux(9), 8, 0 },
122b9f56698STomas Novotny 	{ pinmux(7), 8, 1 },
123b9f56698STomas Novotny 	{ pinmux(7), 8, 2 },
124b9f56698STomas Novotny 	{ pinmux(5), 8, 1 },	/* GP6[0] */
125b9f56698STomas Novotny 	{ pinmux(5), 8, 2 },
126b9f56698STomas Novotny 	{ pinmux(5), 8, 3 },
127b9f56698STomas Novotny 	{ pinmux(5), 8, 4 },
128b9f56698STomas Novotny 	{ pinmux(5), 8, 5 },
129b9f56698STomas Novotny 	{ pinmux(5), 8, 6 },
130b9f56698STomas Novotny 	{ pinmux(5), 8, 7 },
131b9f56698STomas Novotny 	{ pinmux(6), 8, 0 },
132b9f56698STomas Novotny 	{ pinmux(6), 8, 1 },
133b9f56698STomas Novotny 	{ pinmux(6), 8, 2 },
134b9f56698STomas Novotny 	{ pinmux(6), 8, 3 },
135b9f56698STomas Novotny 	{ pinmux(6), 8, 4 },
136b9f56698STomas Novotny 	{ pinmux(6), 8, 5 },
137b9f56698STomas Novotny 	{ pinmux(6), 8, 6 },
138b9f56698STomas Novotny 	{ pinmux(6), 8, 7 },
139b9f56698STomas Novotny 	{ pinmux(7), 8, 0 },
140b9f56698STomas Novotny 	{ pinmux(1), 8, 0 },	/* GP7[0] */
141b9f56698STomas Novotny 	{ pinmux(1), 8, 1 },
142b9f56698STomas Novotny 	{ pinmux(1), 8, 2 },
143b9f56698STomas Novotny 	{ pinmux(1), 8, 3 },
144b9f56698STomas Novotny 	{ pinmux(1), 8, 4 },
145b9f56698STomas Novotny 	{ pinmux(1), 8, 5 },
146b9f56698STomas Novotny 	{ pinmux(1), 8, 6 },
147b9f56698STomas Novotny 	{ pinmux(1), 8, 7 },
148b9f56698STomas Novotny 	{ pinmux(2), 8, 0 },
149b9f56698STomas Novotny 	{ pinmux(2), 8, 1 },
150b9f56698STomas Novotny 	{ pinmux(2), 8, 2 },
151b9f56698STomas Novotny 	{ pinmux(2), 8, 3 },
152b9f56698STomas Novotny 	{ pinmux(2), 8, 4 },
153b9f56698STomas Novotny 	{ pinmux(2), 8, 5 },
154b9f56698STomas Novotny 	{ pinmux(0), 1, 0 },
155b9f56698STomas Novotny 	{ pinmux(0), 1, 1 },
156b9f56698STomas Novotny };
15776b40ab4STom Rini #else /* CONFIG_SOC_DA8XX && CONFIG_SOC_DA850 */
158f517afd5SLaurence Withers static const struct pinmux_config gpio_pinmux[] = {
159f517afd5SLaurence Withers 	{ pinmux(1), 8, 7 },	/* GP0[0] */
160f517afd5SLaurence Withers 	{ pinmux(1), 8, 6 },
161f517afd5SLaurence Withers 	{ pinmux(1), 8, 5 },
162f517afd5SLaurence Withers 	{ pinmux(1), 8, 4 },
163f517afd5SLaurence Withers 	{ pinmux(1), 8, 3 },
164f517afd5SLaurence Withers 	{ pinmux(1), 8, 2 },
165f517afd5SLaurence Withers 	{ pinmux(1), 8, 1 },
166f517afd5SLaurence Withers 	{ pinmux(1), 8, 0 },
167f517afd5SLaurence Withers 	{ pinmux(0), 8, 7 },
168f517afd5SLaurence Withers 	{ pinmux(0), 8, 6 },
169f517afd5SLaurence Withers 	{ pinmux(0), 8, 5 },
170f517afd5SLaurence Withers 	{ pinmux(0), 8, 4 },
171f517afd5SLaurence Withers 	{ pinmux(0), 8, 3 },
172f517afd5SLaurence Withers 	{ pinmux(0), 8, 2 },
173f517afd5SLaurence Withers 	{ pinmux(0), 8, 1 },
174f517afd5SLaurence Withers 	{ pinmux(0), 8, 0 },
175f517afd5SLaurence Withers 	{ pinmux(4), 8, 7 },	/* GP1[0] */
176f517afd5SLaurence Withers 	{ pinmux(4), 8, 6 },
177f517afd5SLaurence Withers 	{ pinmux(4), 8, 5 },
178f517afd5SLaurence Withers 	{ pinmux(4), 8, 4 },
179f517afd5SLaurence Withers 	{ pinmux(4), 8, 3 },
180f517afd5SLaurence Withers 	{ pinmux(4), 8, 2 },
181f517afd5SLaurence Withers 	{ pinmux(4), 4, 1 },
182f517afd5SLaurence Withers 	{ pinmux(4), 4, 0 },
183f517afd5SLaurence Withers 	{ pinmux(3), 4, 0 },
184f517afd5SLaurence Withers 	{ pinmux(2), 4, 6 },
185f517afd5SLaurence Withers 	{ pinmux(2), 4, 5 },
186f517afd5SLaurence Withers 	{ pinmux(2), 4, 4 },
187f517afd5SLaurence Withers 	{ pinmux(2), 4, 3 },
188f517afd5SLaurence Withers 	{ pinmux(2), 4, 2 },
189f517afd5SLaurence Withers 	{ pinmux(2), 4, 1 },
190f517afd5SLaurence Withers 	{ pinmux(2), 8, 0 },
191f517afd5SLaurence Withers 	{ pinmux(6), 8, 7 },	/* GP2[0] */
192f517afd5SLaurence Withers 	{ pinmux(6), 8, 6 },
193f517afd5SLaurence Withers 	{ pinmux(6), 8, 5 },
194f517afd5SLaurence Withers 	{ pinmux(6), 8, 4 },
195f517afd5SLaurence Withers 	{ pinmux(6), 8, 3 },
196f517afd5SLaurence Withers 	{ pinmux(6), 8, 2 },
197f517afd5SLaurence Withers 	{ pinmux(6), 8, 1 },
198f517afd5SLaurence Withers 	{ pinmux(6), 8, 0 },
199f517afd5SLaurence Withers 	{ pinmux(5), 8, 7 },
200f517afd5SLaurence Withers 	{ pinmux(5), 8, 6 },
201f517afd5SLaurence Withers 	{ pinmux(5), 8, 5 },
202f517afd5SLaurence Withers 	{ pinmux(5), 8, 4 },
203f517afd5SLaurence Withers 	{ pinmux(5), 8, 3 },
204f517afd5SLaurence Withers 	{ pinmux(5), 8, 2 },
205f517afd5SLaurence Withers 	{ pinmux(5), 8, 1 },
206f517afd5SLaurence Withers 	{ pinmux(5), 8, 0 },
207f517afd5SLaurence Withers 	{ pinmux(8), 8, 7 },	/* GP3[0] */
208f517afd5SLaurence Withers 	{ pinmux(8), 8, 6 },
209f517afd5SLaurence Withers 	{ pinmux(8), 8, 5 },
210f517afd5SLaurence Withers 	{ pinmux(8), 8, 4 },
211f517afd5SLaurence Withers 	{ pinmux(8), 8, 3 },
212f517afd5SLaurence Withers 	{ pinmux(8), 8, 2 },
213f517afd5SLaurence Withers 	{ pinmux(8), 8, 1 },
214f517afd5SLaurence Withers 	{ pinmux(8), 8, 0 },
215f517afd5SLaurence Withers 	{ pinmux(7), 8, 7 },
216f517afd5SLaurence Withers 	{ pinmux(7), 8, 6 },
217f517afd5SLaurence Withers 	{ pinmux(7), 8, 5 },
218f517afd5SLaurence Withers 	{ pinmux(7), 8, 4 },
219f517afd5SLaurence Withers 	{ pinmux(7), 8, 3 },
220f517afd5SLaurence Withers 	{ pinmux(7), 8, 2 },
221f517afd5SLaurence Withers 	{ pinmux(7), 8, 1 },
222f517afd5SLaurence Withers 	{ pinmux(7), 8, 0 },
223f517afd5SLaurence Withers 	{ pinmux(10), 8, 7 },	/* GP4[0] */
224f517afd5SLaurence Withers 	{ pinmux(10), 8, 6 },
225f517afd5SLaurence Withers 	{ pinmux(10), 8, 5 },
226f517afd5SLaurence Withers 	{ pinmux(10), 8, 4 },
227f517afd5SLaurence Withers 	{ pinmux(10), 8, 3 },
228f517afd5SLaurence Withers 	{ pinmux(10), 8, 2 },
229f517afd5SLaurence Withers 	{ pinmux(10), 8, 1 },
230f517afd5SLaurence Withers 	{ pinmux(10), 8, 0 },
231f517afd5SLaurence Withers 	{ pinmux(9), 8, 7 },
232f517afd5SLaurence Withers 	{ pinmux(9), 8, 6 },
233f517afd5SLaurence Withers 	{ pinmux(9), 8, 5 },
234f517afd5SLaurence Withers 	{ pinmux(9), 8, 4 },
235f517afd5SLaurence Withers 	{ pinmux(9), 8, 3 },
236f517afd5SLaurence Withers 	{ pinmux(9), 8, 2 },
237f517afd5SLaurence Withers 	{ pinmux(9), 8, 1 },
238f517afd5SLaurence Withers 	{ pinmux(9), 8, 0 },
239f517afd5SLaurence Withers 	{ pinmux(12), 8, 7 },	/* GP5[0] */
240f517afd5SLaurence Withers 	{ pinmux(12), 8, 6 },
241f517afd5SLaurence Withers 	{ pinmux(12), 8, 5 },
242f517afd5SLaurence Withers 	{ pinmux(12), 8, 4 },
243f517afd5SLaurence Withers 	{ pinmux(12), 8, 3 },
244f517afd5SLaurence Withers 	{ pinmux(12), 8, 2 },
245f517afd5SLaurence Withers 	{ pinmux(12), 8, 1 },
246f517afd5SLaurence Withers 	{ pinmux(12), 8, 0 },
247f517afd5SLaurence Withers 	{ pinmux(11), 8, 7 },
248f517afd5SLaurence Withers 	{ pinmux(11), 8, 6 },
249f517afd5SLaurence Withers 	{ pinmux(11), 8, 5 },
250f517afd5SLaurence Withers 	{ pinmux(11), 8, 4 },
251f517afd5SLaurence Withers 	{ pinmux(11), 8, 3 },
252f517afd5SLaurence Withers 	{ pinmux(11), 8, 2 },
253f517afd5SLaurence Withers 	{ pinmux(11), 8, 1 },
254f517afd5SLaurence Withers 	{ pinmux(11), 8, 0 },
255f517afd5SLaurence Withers 	{ pinmux(19), 8, 6 },	/* GP6[0] */
256f517afd5SLaurence Withers 	{ pinmux(19), 8, 5 },
257f517afd5SLaurence Withers 	{ pinmux(19), 8, 4 },
258f517afd5SLaurence Withers 	{ pinmux(19), 8, 3 },
259f517afd5SLaurence Withers 	{ pinmux(19), 8, 2 },
260f517afd5SLaurence Withers 	{ pinmux(16), 8, 1 },
261f517afd5SLaurence Withers 	{ pinmux(14), 8, 1 },
262f517afd5SLaurence Withers 	{ pinmux(14), 8, 0 },
263f517afd5SLaurence Withers 	{ pinmux(13), 8, 7 },
264f517afd5SLaurence Withers 	{ pinmux(13), 8, 6 },
265f517afd5SLaurence Withers 	{ pinmux(13), 8, 5 },
266f517afd5SLaurence Withers 	{ pinmux(13), 8, 4 },
267f517afd5SLaurence Withers 	{ pinmux(13), 8, 3 },
268f517afd5SLaurence Withers 	{ pinmux(13), 8, 2 },
269f517afd5SLaurence Withers 	{ pinmux(13), 8, 1 },
270f517afd5SLaurence Withers 	{ pinmux(13), 8, 0 },
271f517afd5SLaurence Withers 	{ pinmux(18), 8, 1 },	/* GP7[0] */
272f517afd5SLaurence Withers 	{ pinmux(18), 8, 0 },
273f517afd5SLaurence Withers 	{ pinmux(17), 8, 7 },
274f517afd5SLaurence Withers 	{ pinmux(17), 8, 6 },
275f517afd5SLaurence Withers 	{ pinmux(17), 8, 5 },
276f517afd5SLaurence Withers 	{ pinmux(17), 8, 4 },
277f517afd5SLaurence Withers 	{ pinmux(17), 8, 3 },
278f517afd5SLaurence Withers 	{ pinmux(17), 8, 2 },
279f517afd5SLaurence Withers 	{ pinmux(17), 8, 1 },
280f517afd5SLaurence Withers 	{ pinmux(17), 8, 0 },
281f517afd5SLaurence Withers 	{ pinmux(16), 8, 7 },
282f517afd5SLaurence Withers 	{ pinmux(16), 8, 6 },
283f517afd5SLaurence Withers 	{ pinmux(16), 8, 5 },
284f517afd5SLaurence Withers 	{ pinmux(16), 8, 4 },
285f517afd5SLaurence Withers 	{ pinmux(16), 8, 3 },
286f517afd5SLaurence Withers 	{ pinmux(16), 8, 2 },
287f517afd5SLaurence Withers 	{ pinmux(19), 8, 0 },	/* GP8[0] */
288f517afd5SLaurence Withers 	{ pinmux(3), 4, 7 },
289f517afd5SLaurence Withers 	{ pinmux(3), 4, 6 },
290f517afd5SLaurence Withers 	{ pinmux(3), 4, 5 },
291f517afd5SLaurence Withers 	{ pinmux(3), 4, 4 },
292f517afd5SLaurence Withers 	{ pinmux(3), 4, 3 },
293f517afd5SLaurence Withers 	{ pinmux(3), 4, 2 },
294f517afd5SLaurence Withers 	{ pinmux(2), 4, 7 },
295f517afd5SLaurence Withers 	{ pinmux(19), 8, 1 },
296f517afd5SLaurence Withers 	{ pinmux(19), 8, 0 },
297f517afd5SLaurence Withers 	{ pinmux(18), 8, 7 },
298f517afd5SLaurence Withers 	{ pinmux(18), 8, 6 },
299f517afd5SLaurence Withers 	{ pinmux(18), 8, 5 },
300f517afd5SLaurence Withers 	{ pinmux(18), 8, 4 },
301f517afd5SLaurence Withers 	{ pinmux(18), 8, 3 },
302f517afd5SLaurence Withers 	{ pinmux(18), 8, 2 },
303f517afd5SLaurence Withers };
30476b40ab4STom Rini #endif /* CONFIG_SOC_DA8XX && !CONFIG_SOC_DA850 */
30576b40ab4STom Rini #else /* !CONFIG_SOC_DA8XX */
30603414ac4SHolger Hans Peter Freyther #define davinci_configure_pin_mux(a, b)
30776b40ab4STom Rini #endif /* CONFIG_SOC_DA8XX */
308f517afd5SLaurence Withers 
309*8e51c0f2SAdam Ford int gpio_request(unsigned int gpio, const char *label)
310f517afd5SLaurence Withers {
311365d6070SJoe Hershberger 	if (gpio >= MAX_NUM_GPIOS)
312f517afd5SLaurence Withers 		return -1;
313f517afd5SLaurence Withers 
314365d6070SJoe Hershberger 	if (gpio_registry[gpio].is_registered)
315f517afd5SLaurence Withers 		return -1;
316f517afd5SLaurence Withers 
317365d6070SJoe Hershberger 	gpio_registry[gpio].is_registered = 1;
318365d6070SJoe Hershberger 	strncpy(gpio_registry[gpio].name, label, GPIO_NAME_SIZE);
319365d6070SJoe Hershberger 	gpio_registry[gpio].name[GPIO_NAME_SIZE - 1] = 0;
320f517afd5SLaurence Withers 
321365d6070SJoe Hershberger 	davinci_configure_pin_mux(&gpio_pinmux[gpio], 1);
322f517afd5SLaurence Withers 
323f517afd5SLaurence Withers 	return 0;
324f517afd5SLaurence Withers }
325f517afd5SLaurence Withers 
326*8e51c0f2SAdam Ford int gpio_free(unsigned int gpio)
327f517afd5SLaurence Withers {
328365d6070SJoe Hershberger 	if (gpio >= MAX_NUM_GPIOS)
329365d6070SJoe Hershberger 		return -1;
330365d6070SJoe Hershberger 
331365d6070SJoe Hershberger 	if (!gpio_registry[gpio].is_registered)
332365d6070SJoe Hershberger 		return -1;
333365d6070SJoe Hershberger 
334365d6070SJoe Hershberger 	gpio_registry[gpio].is_registered = 0;
335365d6070SJoe Hershberger 	gpio_registry[gpio].name[0] = '\0';
336365d6070SJoe Hershberger 	/* Do not configure as input or change pin mux here */
337365d6070SJoe Hershberger 	return 0;
338f517afd5SLaurence Withers }
339*8e51c0f2SAdam Ford #endif
340f517afd5SLaurence Withers 
341*8e51c0f2SAdam Ford static int _gpio_direction_output(struct davinci_gpio *bank, unsigned int gpio, int value)
342f517afd5SLaurence Withers {
343365d6070SJoe Hershberger 	clrbits_le32(&bank->dir, 1U << GPIO_BIT(gpio));
344365d6070SJoe Hershberger 	gpio_set_value(gpio, value);
345f517afd5SLaurence Withers 	return 0;
346f517afd5SLaurence Withers }
347f517afd5SLaurence Withers 
348*8e51c0f2SAdam Ford static int _gpio_direction_input(struct davinci_gpio *bank, unsigned int gpio)
349f517afd5SLaurence Withers {
350*8e51c0f2SAdam Ford 	setbits_le32(&bank->dir, 1U << GPIO_BIT(gpio));
351*8e51c0f2SAdam Ford 	return 0;
352*8e51c0f2SAdam Ford }
353f517afd5SLaurence Withers 
354*8e51c0f2SAdam Ford static int _gpio_get_value(struct davinci_gpio *bank, unsigned int gpio)
355*8e51c0f2SAdam Ford {
356*8e51c0f2SAdam Ford 	unsigned int ip;
357365d6070SJoe Hershberger 	ip = in_le32(&bank->in_data) & (1U << GPIO_BIT(gpio));
358f517afd5SLaurence Withers 	return ip ? 1 : 0;
359f517afd5SLaurence Withers }
360f517afd5SLaurence Withers 
361*8e51c0f2SAdam Ford static int _gpio_set_value(struct davinci_gpio *bank, unsigned int gpio, int value)
362f517afd5SLaurence Withers {
363f517afd5SLaurence Withers 	if (value)
364365d6070SJoe Hershberger 		bank->set_data = 1U << GPIO_BIT(gpio);
365f517afd5SLaurence Withers 	else
366365d6070SJoe Hershberger 		bank->clr_data = 1U << GPIO_BIT(gpio);
367365d6070SJoe Hershberger 
368365d6070SJoe Hershberger 	return 0;
369f517afd5SLaurence Withers }
370f517afd5SLaurence Withers 
371*8e51c0f2SAdam Ford static int _gpio_get_dir(struct davinci_gpio *bank, unsigned int gpio)
372*8e51c0f2SAdam Ford {
373*8e51c0f2SAdam Ford 	return in_le32(&bank->dir) & (1U << GPIO_BIT(gpio));
374*8e51c0f2SAdam Ford }
375*8e51c0f2SAdam Ford 
376*8e51c0f2SAdam Ford #ifndef CONFIG_DM_GPIO
377*8e51c0f2SAdam Ford 
378f517afd5SLaurence Withers void gpio_info(void)
379f517afd5SLaurence Withers {
380*8e51c0f2SAdam Ford 	unsigned int gpio, dir, val;
381f517afd5SLaurence Withers 	struct davinci_gpio *bank;
382f517afd5SLaurence Withers 
383365d6070SJoe Hershberger 	for (gpio = 0; gpio < MAX_NUM_GPIOS; ++gpio) {
384365d6070SJoe Hershberger 		bank = GPIO_BANK(gpio);
385*8e51c0f2SAdam Ford 		dir = _gpio_get_dir(bank, gpio);
386365d6070SJoe Hershberger 		val = gpio_get_value(gpio);
387f517afd5SLaurence Withers 
388f517afd5SLaurence Withers 		printf("% 4d: %s: %d [%c] %s\n",
389365d6070SJoe Hershberger 			gpio, dir ? " in" : "out", val,
390365d6070SJoe Hershberger 			gpio_registry[gpio].is_registered ? 'x' : ' ',
391365d6070SJoe Hershberger 			gpio_registry[gpio].name);
392f517afd5SLaurence Withers 	}
393f517afd5SLaurence Withers }
394*8e51c0f2SAdam Ford 
395*8e51c0f2SAdam Ford int gpio_direction_input(unsigned int gpio)
396*8e51c0f2SAdam Ford {
397*8e51c0f2SAdam Ford 	struct davinci_gpio *bank;
398*8e51c0f2SAdam Ford 
399*8e51c0f2SAdam Ford 	bank = GPIO_BANK(gpio);
400*8e51c0f2SAdam Ford 	return _gpio_direction_input(bank, gpio);
401*8e51c0f2SAdam Ford }
402*8e51c0f2SAdam Ford 
403*8e51c0f2SAdam Ford int gpio_direction_output(unsigned int gpio, int value)
404*8e51c0f2SAdam Ford {
405*8e51c0f2SAdam Ford 	struct davinci_gpio *bank;
406*8e51c0f2SAdam Ford 
407*8e51c0f2SAdam Ford 	bank = GPIO_BANK(gpio);
408*8e51c0f2SAdam Ford 	return _gpio_direction_output(bank, gpio, value);
409*8e51c0f2SAdam Ford }
410*8e51c0f2SAdam Ford 
411*8e51c0f2SAdam Ford int gpio_get_value(unsigned int gpio)
412*8e51c0f2SAdam Ford {
413*8e51c0f2SAdam Ford 	struct davinci_gpio *bank;
414*8e51c0f2SAdam Ford 
415*8e51c0f2SAdam Ford 	bank = GPIO_BANK(gpio);
416*8e51c0f2SAdam Ford 	return _gpio_get_value(bank, gpio);
417*8e51c0f2SAdam Ford }
418*8e51c0f2SAdam Ford 
419*8e51c0f2SAdam Ford int gpio_set_value(unsigned int gpio, int value)
420*8e51c0f2SAdam Ford {
421*8e51c0f2SAdam Ford 	struct davinci_gpio *bank;
422*8e51c0f2SAdam Ford 
423*8e51c0f2SAdam Ford 	bank = GPIO_BANK(gpio);
424*8e51c0f2SAdam Ford 	return _gpio_set_value(bank, gpio, value);
425*8e51c0f2SAdam Ford }
426*8e51c0f2SAdam Ford 
427*8e51c0f2SAdam Ford #else /* CONFIG_DM_GPIO */
428*8e51c0f2SAdam Ford 
429*8e51c0f2SAdam Ford static struct davinci_gpio *davinci_get_gpio_bank(struct udevice *dev, unsigned int offset)
430*8e51c0f2SAdam Ford {
431*8e51c0f2SAdam Ford 	struct davinci_gpio_bank *bank = dev_get_priv(dev);
432*8e51c0f2SAdam Ford 
433*8e51c0f2SAdam Ford 	/* The device tree is not broken into banks but the infrastructure is
434*8e51c0f2SAdam Ford 	 * expecting it this way, so we'll first include the 0x10 offset, then
435*8e51c0f2SAdam Ford 	 * calculate the bank manually based on the offset.
436*8e51c0f2SAdam Ford 	 */
437*8e51c0f2SAdam Ford 
438*8e51c0f2SAdam Ford 	return ((struct davinci_gpio *)bank->base) + 0x10 + (offset >> 5);
439*8e51c0f2SAdam Ford }
440*8e51c0f2SAdam Ford 
441*8e51c0f2SAdam Ford static int davinci_gpio_direction_input(struct udevice *dev, unsigned int offset)
442*8e51c0f2SAdam Ford {
443*8e51c0f2SAdam Ford 	struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
444*8e51c0f2SAdam Ford 
445*8e51c0f2SAdam Ford 	_gpio_direction_input(base, offset);
446*8e51c0f2SAdam Ford 	return 0;
447*8e51c0f2SAdam Ford }
448*8e51c0f2SAdam Ford 
449*8e51c0f2SAdam Ford static int davinci_gpio_direction_output(struct udevice *dev, unsigned int offset,
450*8e51c0f2SAdam Ford 					 int value)
451*8e51c0f2SAdam Ford {
452*8e51c0f2SAdam Ford 	struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
453*8e51c0f2SAdam Ford 
454*8e51c0f2SAdam Ford 	_gpio_direction_output(base, offset, value);
455*8e51c0f2SAdam Ford 	return 0;
456*8e51c0f2SAdam Ford }
457*8e51c0f2SAdam Ford 
458*8e51c0f2SAdam Ford static int davinci_gpio_get_value(struct udevice *dev, unsigned int offset)
459*8e51c0f2SAdam Ford {
460*8e51c0f2SAdam Ford 	struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
461*8e51c0f2SAdam Ford 
462*8e51c0f2SAdam Ford 	return _gpio_get_value(base, offset);
463*8e51c0f2SAdam Ford }
464*8e51c0f2SAdam Ford 
465*8e51c0f2SAdam Ford static int davinci_gpio_set_value(struct udevice *dev, unsigned int offset,
466*8e51c0f2SAdam Ford 				  int value)
467*8e51c0f2SAdam Ford {
468*8e51c0f2SAdam Ford 	struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
469*8e51c0f2SAdam Ford 
470*8e51c0f2SAdam Ford 	_gpio_set_value(base, offset, value);
471*8e51c0f2SAdam Ford 
472*8e51c0f2SAdam Ford 	return 0;
473*8e51c0f2SAdam Ford }
474*8e51c0f2SAdam Ford 
475*8e51c0f2SAdam Ford static int davinci_gpio_get_function(struct udevice *dev, unsigned int offset)
476*8e51c0f2SAdam Ford {
477*8e51c0f2SAdam Ford 	unsigned int dir;
478*8e51c0f2SAdam Ford 	struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
479*8e51c0f2SAdam Ford 
480*8e51c0f2SAdam Ford 	dir = _gpio_get_dir(base, offset);
481*8e51c0f2SAdam Ford 
482*8e51c0f2SAdam Ford 	if (dir)
483*8e51c0f2SAdam Ford 		return GPIOF_INPUT;
484*8e51c0f2SAdam Ford 
485*8e51c0f2SAdam Ford 	return GPIOF_OUTPUT;
486*8e51c0f2SAdam Ford }
487*8e51c0f2SAdam Ford 
488*8e51c0f2SAdam Ford static const struct dm_gpio_ops gpio_davinci_ops = {
489*8e51c0f2SAdam Ford 	.direction_input	= davinci_gpio_direction_input,
490*8e51c0f2SAdam Ford 	.direction_output	= davinci_gpio_direction_output,
491*8e51c0f2SAdam Ford 	.get_value		= davinci_gpio_get_value,
492*8e51c0f2SAdam Ford 	.set_value		= davinci_gpio_set_value,
493*8e51c0f2SAdam Ford 	.get_function		= davinci_gpio_get_function,
494*8e51c0f2SAdam Ford };
495*8e51c0f2SAdam Ford 
496*8e51c0f2SAdam Ford static int davinci_gpio_probe(struct udevice *dev)
497*8e51c0f2SAdam Ford {
498*8e51c0f2SAdam Ford 	struct davinci_gpio_bank *bank = dev_get_priv(dev);
499*8e51c0f2SAdam Ford 	struct davinci_gpio_platdata *plat = dev_get_platdata(dev);
500*8e51c0f2SAdam Ford 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
501*8e51c0f2SAdam Ford 	const void *fdt = gd->fdt_blob;
502*8e51c0f2SAdam Ford 	int node = dev_of_offset(dev);
503*8e51c0f2SAdam Ford 
504*8e51c0f2SAdam Ford 	uc_priv->bank_name = plat->port_name;
505*8e51c0f2SAdam Ford 	uc_priv->gpio_count = fdtdec_get_int(fdt, node, "ti,ngpio", -1);
506*8e51c0f2SAdam Ford 	bank->base = (struct davinci_gpio *)plat->base;
507*8e51c0f2SAdam Ford 	return 0;
508*8e51c0f2SAdam Ford }
509*8e51c0f2SAdam Ford 
510*8e51c0f2SAdam Ford static const struct udevice_id davinci_gpio_ids[] = {
511*8e51c0f2SAdam Ford 	{ .compatible = "ti,dm6441-gpio" },
512*8e51c0f2SAdam Ford 	{ }
513*8e51c0f2SAdam Ford };
514*8e51c0f2SAdam Ford 
515*8e51c0f2SAdam Ford static int davinci_gpio_ofdata_to_platdata(struct udevice *dev)
516*8e51c0f2SAdam Ford {
517*8e51c0f2SAdam Ford 	struct davinci_gpio_platdata *plat = dev_get_platdata(dev);
518*8e51c0f2SAdam Ford 	fdt_addr_t addr;
519*8e51c0f2SAdam Ford 
520*8e51c0f2SAdam Ford 	addr = devfdt_get_addr(dev);
521*8e51c0f2SAdam Ford 	if (addr == FDT_ADDR_T_NONE)
522*8e51c0f2SAdam Ford 		return -EINVAL;
523*8e51c0f2SAdam Ford 
524*8e51c0f2SAdam Ford 	plat->base = addr;
525*8e51c0f2SAdam Ford 	return 0;
526*8e51c0f2SAdam Ford }
527*8e51c0f2SAdam Ford 
528*8e51c0f2SAdam Ford U_BOOT_DRIVER(gpio_davinci) = {
529*8e51c0f2SAdam Ford 	.name	= "gpio_davinci",
530*8e51c0f2SAdam Ford 	.id	= UCLASS_GPIO,
531*8e51c0f2SAdam Ford 	.ops	= &gpio_davinci_ops,
532*8e51c0f2SAdam Ford 	.ofdata_to_platdata = of_match_ptr(davinci_gpio_ofdata_to_platdata),
533*8e51c0f2SAdam Ford 	.of_match = davinci_gpio_ids,
534*8e51c0f2SAdam Ford 	.bind   = dm_scan_fdt_dev,
535*8e51c0f2SAdam Ford 	.platdata_auto_alloc_size = sizeof(struct davinci_gpio_platdata),
536*8e51c0f2SAdam Ford 	.probe	= davinci_gpio_probe,
537*8e51c0f2SAdam Ford 	.priv_auto_alloc_size = sizeof(struct davinci_gpio_bank),
538*8e51c0f2SAdam Ford };
539*8e51c0f2SAdam Ford 
540*8e51c0f2SAdam Ford #endif
541