xref: /openbmc/u-boot/drivers/gpio/da8xx_gpio.c (revision 401d74cb)
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>
108e51c0f2SAdam Ford #include <dm.h>
118e51c0f2SAdam 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>
161eddf549SAdam Ford #include <dt-bindings/gpio/gpio.h>
17f517afd5SLaurence Withers 
188e51c0f2SAdam Ford #ifndef CONFIG_DM_GPIO
19f517afd5SLaurence Withers static struct gpio_registry {
20f517afd5SLaurence Withers 	int is_registered;
21f517afd5SLaurence Withers 	char name[GPIO_NAME_SIZE];
22f517afd5SLaurence Withers } gpio_registry[MAX_NUM_GPIOS];
23f517afd5SLaurence Withers 
2403414ac4SHolger Hans Peter Freyther #if defined(CONFIG_SOC_DA8XX)
25f517afd5SLaurence Withers #define pinmux(x)       (&davinci_syscfg_regs->pinmux[x])
26f517afd5SLaurence Withers 
27b9f56698STomas Novotny #if defined(CONFIG_SOC_DA8XX) && !defined(CONFIG_SOC_DA850)
28b9f56698STomas Novotny static const struct pinmux_config gpio_pinmux[] = {
29b9f56698STomas Novotny 	{ pinmux(13), 8, 6 },	/* GP0[0] */
30b9f56698STomas Novotny 	{ pinmux(13), 8, 7 },
31b9f56698STomas Novotny 	{ pinmux(14), 8, 0 },
32b9f56698STomas Novotny 	{ pinmux(14), 8, 1 },
33b9f56698STomas Novotny 	{ pinmux(14), 8, 2 },
34b9f56698STomas Novotny 	{ pinmux(14), 8, 3 },
35b9f56698STomas Novotny 	{ pinmux(14), 8, 4 },
36b9f56698STomas Novotny 	{ pinmux(14), 8, 5 },
37b9f56698STomas Novotny 	{ pinmux(14), 8, 6 },
38b9f56698STomas Novotny 	{ pinmux(14), 8, 7 },
39b9f56698STomas Novotny 	{ pinmux(15), 8, 0 },
40b9f56698STomas Novotny 	{ pinmux(15), 8, 1 },
41b9f56698STomas Novotny 	{ pinmux(15), 8, 2 },
42b9f56698STomas Novotny 	{ pinmux(15), 8, 3 },
43b9f56698STomas Novotny 	{ pinmux(15), 8, 4 },
44b9f56698STomas Novotny 	{ pinmux(15), 8, 5 },
45b9f56698STomas Novotny 	{ pinmux(15), 8, 6 },	/* GP1[0] */
46b9f56698STomas Novotny 	{ pinmux(15), 8, 7 },
47b9f56698STomas Novotny 	{ pinmux(16), 8, 0 },
48b9f56698STomas Novotny 	{ pinmux(16), 8, 1 },
49b9f56698STomas Novotny 	{ pinmux(16), 8, 2 },
50b9f56698STomas Novotny 	{ pinmux(16), 8, 3 },
51b9f56698STomas Novotny 	{ pinmux(16), 8, 4 },
52b9f56698STomas Novotny 	{ pinmux(16), 8, 5 },
53b9f56698STomas Novotny 	{ pinmux(16), 8, 6 },
54b9f56698STomas Novotny 	{ pinmux(16), 8, 7 },
55b9f56698STomas Novotny 	{ pinmux(17), 8, 0 },
56b9f56698STomas Novotny 	{ pinmux(17), 8, 1 },
57b9f56698STomas Novotny 	{ pinmux(17), 8, 2 },
58b9f56698STomas Novotny 	{ pinmux(17), 8, 3 },
59b9f56698STomas Novotny 	{ pinmux(17), 8, 4 },
60b9f56698STomas Novotny 	{ pinmux(17), 8, 5 },
61b9f56698STomas Novotny 	{ pinmux(17), 8, 6 },	/* GP2[0] */
62b9f56698STomas Novotny 	{ pinmux(17), 8, 7 },
63b9f56698STomas Novotny 	{ pinmux(18), 8, 0 },
64b9f56698STomas Novotny 	{ pinmux(18), 8, 1 },
65b9f56698STomas Novotny 	{ pinmux(18), 8, 2 },
66b9f56698STomas Novotny 	{ pinmux(18), 8, 3 },
67b9f56698STomas Novotny 	{ pinmux(18), 8, 4 },
68b9f56698STomas Novotny 	{ pinmux(18), 8, 5 },
69b9f56698STomas Novotny 	{ pinmux(18), 8, 6 },
70b9f56698STomas Novotny 	{ pinmux(18), 8, 7 },
71b9f56698STomas Novotny 	{ pinmux(19), 8, 0 },
72b9f56698STomas Novotny 	{ pinmux(9), 8, 2 },
73b9f56698STomas Novotny 	{ pinmux(9), 8, 3 },
74b9f56698STomas Novotny 	{ pinmux(9), 8, 4 },
75b9f56698STomas Novotny 	{ pinmux(9), 8, 5 },
76b9f56698STomas Novotny 	{ pinmux(9), 8, 6 },
77b9f56698STomas Novotny 	{ pinmux(10), 8, 1 },	/* GP3[0] */
78b9f56698STomas Novotny 	{ pinmux(10), 8, 2 },
79b9f56698STomas Novotny 	{ pinmux(10), 8, 3 },
80b9f56698STomas Novotny 	{ pinmux(10), 8, 4 },
81b9f56698STomas Novotny 	{ pinmux(10), 8, 5 },
82b9f56698STomas Novotny 	{ pinmux(10), 8, 6 },
83b9f56698STomas Novotny 	{ pinmux(10), 8, 7 },
84b9f56698STomas Novotny 	{ pinmux(11), 8, 0 },
85b9f56698STomas Novotny 	{ pinmux(11), 8, 1 },
86b9f56698STomas Novotny 	{ pinmux(11), 8, 2 },
87b9f56698STomas Novotny 	{ pinmux(11), 8, 3 },
88b9f56698STomas Novotny 	{ pinmux(11), 8, 4 },
89b9f56698STomas Novotny 	{ pinmux(9), 8, 7 },
90b9f56698STomas Novotny 	{ pinmux(2), 8, 6 },
91b9f56698STomas Novotny 	{ pinmux(11), 8, 5 },
92b9f56698STomas Novotny 	{ pinmux(11), 8, 6 },
93b9f56698STomas Novotny 	{ pinmux(12), 8, 4 },	/* GP4[0] */
94b9f56698STomas Novotny 	{ pinmux(12), 8, 5 },
95b9f56698STomas Novotny 	{ pinmux(12), 8, 6 },
96b9f56698STomas Novotny 	{ pinmux(12), 8, 7 },
97b9f56698STomas Novotny 	{ pinmux(13), 8, 0 },
98b9f56698STomas Novotny 	{ pinmux(13), 8, 1 },
99b9f56698STomas Novotny 	{ pinmux(13), 8, 2 },
100b9f56698STomas Novotny 	{ pinmux(13), 8, 3 },
101b9f56698STomas Novotny 	{ pinmux(13), 8, 4 },
102b9f56698STomas Novotny 	{ pinmux(13), 8, 5 },
103b9f56698STomas Novotny 	{ pinmux(11), 8, 7 },
104b9f56698STomas Novotny 	{ pinmux(12), 8, 0 },
105b9f56698STomas Novotny 	{ pinmux(12), 8, 1 },
106b9f56698STomas Novotny 	{ pinmux(12), 8, 2 },
107b9f56698STomas Novotny 	{ pinmux(12), 8, 3 },
108b9f56698STomas Novotny 	{ pinmux(9), 8, 1 },
109b9f56698STomas Novotny 	{ pinmux(7), 8, 3 },	/* GP5[0] */
110b9f56698STomas Novotny 	{ pinmux(7), 8, 4 },
111b9f56698STomas Novotny 	{ pinmux(7), 8, 5 },
112b9f56698STomas Novotny 	{ pinmux(7), 8, 6 },
113b9f56698STomas Novotny 	{ pinmux(7), 8, 7 },
114b9f56698STomas Novotny 	{ pinmux(8), 8, 0 },
115b9f56698STomas Novotny 	{ pinmux(8), 8, 1 },
116b9f56698STomas Novotny 	{ pinmux(8), 8, 2 },
117b9f56698STomas Novotny 	{ pinmux(8), 8, 3 },
118b9f56698STomas Novotny 	{ pinmux(8), 8, 4 },
119b9f56698STomas Novotny 	{ pinmux(8), 8, 5 },
120b9f56698STomas Novotny 	{ pinmux(8), 8, 6 },
121b9f56698STomas Novotny 	{ pinmux(8), 8, 7 },
122b9f56698STomas Novotny 	{ pinmux(9), 8, 0 },
123b9f56698STomas Novotny 	{ pinmux(7), 8, 1 },
124b9f56698STomas Novotny 	{ pinmux(7), 8, 2 },
125b9f56698STomas Novotny 	{ pinmux(5), 8, 1 },	/* GP6[0] */
126b9f56698STomas Novotny 	{ pinmux(5), 8, 2 },
127b9f56698STomas Novotny 	{ pinmux(5), 8, 3 },
128b9f56698STomas Novotny 	{ pinmux(5), 8, 4 },
129b9f56698STomas Novotny 	{ pinmux(5), 8, 5 },
130b9f56698STomas Novotny 	{ pinmux(5), 8, 6 },
131b9f56698STomas Novotny 	{ pinmux(5), 8, 7 },
132b9f56698STomas Novotny 	{ pinmux(6), 8, 0 },
133b9f56698STomas Novotny 	{ pinmux(6), 8, 1 },
134b9f56698STomas Novotny 	{ pinmux(6), 8, 2 },
135b9f56698STomas Novotny 	{ pinmux(6), 8, 3 },
136b9f56698STomas Novotny 	{ pinmux(6), 8, 4 },
137b9f56698STomas Novotny 	{ pinmux(6), 8, 5 },
138b9f56698STomas Novotny 	{ pinmux(6), 8, 6 },
139b9f56698STomas Novotny 	{ pinmux(6), 8, 7 },
140b9f56698STomas Novotny 	{ pinmux(7), 8, 0 },
141b9f56698STomas Novotny 	{ pinmux(1), 8, 0 },	/* GP7[0] */
142b9f56698STomas Novotny 	{ pinmux(1), 8, 1 },
143b9f56698STomas Novotny 	{ pinmux(1), 8, 2 },
144b9f56698STomas Novotny 	{ pinmux(1), 8, 3 },
145b9f56698STomas Novotny 	{ pinmux(1), 8, 4 },
146b9f56698STomas Novotny 	{ pinmux(1), 8, 5 },
147b9f56698STomas Novotny 	{ pinmux(1), 8, 6 },
148b9f56698STomas Novotny 	{ pinmux(1), 8, 7 },
149b9f56698STomas Novotny 	{ pinmux(2), 8, 0 },
150b9f56698STomas Novotny 	{ pinmux(2), 8, 1 },
151b9f56698STomas Novotny 	{ pinmux(2), 8, 2 },
152b9f56698STomas Novotny 	{ pinmux(2), 8, 3 },
153b9f56698STomas Novotny 	{ pinmux(2), 8, 4 },
154b9f56698STomas Novotny 	{ pinmux(2), 8, 5 },
155b9f56698STomas Novotny 	{ pinmux(0), 1, 0 },
156b9f56698STomas Novotny 	{ pinmux(0), 1, 1 },
157b9f56698STomas Novotny };
15876b40ab4STom Rini #else /* CONFIG_SOC_DA8XX && CONFIG_SOC_DA850 */
159f517afd5SLaurence Withers static const struct pinmux_config gpio_pinmux[] = {
160f517afd5SLaurence Withers 	{ pinmux(1), 8, 7 },	/* GP0[0] */
161f517afd5SLaurence Withers 	{ pinmux(1), 8, 6 },
162f517afd5SLaurence Withers 	{ pinmux(1), 8, 5 },
163f517afd5SLaurence Withers 	{ pinmux(1), 8, 4 },
164f517afd5SLaurence Withers 	{ pinmux(1), 8, 3 },
165f517afd5SLaurence Withers 	{ pinmux(1), 8, 2 },
166f517afd5SLaurence Withers 	{ pinmux(1), 8, 1 },
167f517afd5SLaurence Withers 	{ pinmux(1), 8, 0 },
168f517afd5SLaurence Withers 	{ pinmux(0), 8, 7 },
169f517afd5SLaurence Withers 	{ pinmux(0), 8, 6 },
170f517afd5SLaurence Withers 	{ pinmux(0), 8, 5 },
171f517afd5SLaurence Withers 	{ pinmux(0), 8, 4 },
172f517afd5SLaurence Withers 	{ pinmux(0), 8, 3 },
173f517afd5SLaurence Withers 	{ pinmux(0), 8, 2 },
174f517afd5SLaurence Withers 	{ pinmux(0), 8, 1 },
175f517afd5SLaurence Withers 	{ pinmux(0), 8, 0 },
176f517afd5SLaurence Withers 	{ pinmux(4), 8, 7 },	/* GP1[0] */
177f517afd5SLaurence Withers 	{ pinmux(4), 8, 6 },
178f517afd5SLaurence Withers 	{ pinmux(4), 8, 5 },
179f517afd5SLaurence Withers 	{ pinmux(4), 8, 4 },
180f517afd5SLaurence Withers 	{ pinmux(4), 8, 3 },
181f517afd5SLaurence Withers 	{ pinmux(4), 8, 2 },
182f517afd5SLaurence Withers 	{ pinmux(4), 4, 1 },
183f517afd5SLaurence Withers 	{ pinmux(4), 4, 0 },
184f517afd5SLaurence Withers 	{ pinmux(3), 4, 0 },
185f517afd5SLaurence Withers 	{ pinmux(2), 4, 6 },
186f517afd5SLaurence Withers 	{ pinmux(2), 4, 5 },
187f517afd5SLaurence Withers 	{ pinmux(2), 4, 4 },
188f517afd5SLaurence Withers 	{ pinmux(2), 4, 3 },
189f517afd5SLaurence Withers 	{ pinmux(2), 4, 2 },
190f517afd5SLaurence Withers 	{ pinmux(2), 4, 1 },
191f517afd5SLaurence Withers 	{ pinmux(2), 8, 0 },
192f517afd5SLaurence Withers 	{ pinmux(6), 8, 7 },	/* GP2[0] */
193f517afd5SLaurence Withers 	{ pinmux(6), 8, 6 },
194f517afd5SLaurence Withers 	{ pinmux(6), 8, 5 },
195f517afd5SLaurence Withers 	{ pinmux(6), 8, 4 },
196f517afd5SLaurence Withers 	{ pinmux(6), 8, 3 },
197f517afd5SLaurence Withers 	{ pinmux(6), 8, 2 },
198f517afd5SLaurence Withers 	{ pinmux(6), 8, 1 },
199f517afd5SLaurence Withers 	{ pinmux(6), 8, 0 },
200f517afd5SLaurence Withers 	{ pinmux(5), 8, 7 },
201f517afd5SLaurence Withers 	{ pinmux(5), 8, 6 },
202f517afd5SLaurence Withers 	{ pinmux(5), 8, 5 },
203f517afd5SLaurence Withers 	{ pinmux(5), 8, 4 },
204f517afd5SLaurence Withers 	{ pinmux(5), 8, 3 },
205f517afd5SLaurence Withers 	{ pinmux(5), 8, 2 },
206f517afd5SLaurence Withers 	{ pinmux(5), 8, 1 },
207f517afd5SLaurence Withers 	{ pinmux(5), 8, 0 },
208f517afd5SLaurence Withers 	{ pinmux(8), 8, 7 },	/* GP3[0] */
209f517afd5SLaurence Withers 	{ pinmux(8), 8, 6 },
210f517afd5SLaurence Withers 	{ pinmux(8), 8, 5 },
211f517afd5SLaurence Withers 	{ pinmux(8), 8, 4 },
212f517afd5SLaurence Withers 	{ pinmux(8), 8, 3 },
213f517afd5SLaurence Withers 	{ pinmux(8), 8, 2 },
214f517afd5SLaurence Withers 	{ pinmux(8), 8, 1 },
215f517afd5SLaurence Withers 	{ pinmux(8), 8, 0 },
216f517afd5SLaurence Withers 	{ pinmux(7), 8, 7 },
217f517afd5SLaurence Withers 	{ pinmux(7), 8, 6 },
218f517afd5SLaurence Withers 	{ pinmux(7), 8, 5 },
219f517afd5SLaurence Withers 	{ pinmux(7), 8, 4 },
220f517afd5SLaurence Withers 	{ pinmux(7), 8, 3 },
221f517afd5SLaurence Withers 	{ pinmux(7), 8, 2 },
222f517afd5SLaurence Withers 	{ pinmux(7), 8, 1 },
223f517afd5SLaurence Withers 	{ pinmux(7), 8, 0 },
224f517afd5SLaurence Withers 	{ pinmux(10), 8, 7 },	/* GP4[0] */
225f517afd5SLaurence Withers 	{ pinmux(10), 8, 6 },
226f517afd5SLaurence Withers 	{ pinmux(10), 8, 5 },
227f517afd5SLaurence Withers 	{ pinmux(10), 8, 4 },
228f517afd5SLaurence Withers 	{ pinmux(10), 8, 3 },
229f517afd5SLaurence Withers 	{ pinmux(10), 8, 2 },
230f517afd5SLaurence Withers 	{ pinmux(10), 8, 1 },
231f517afd5SLaurence Withers 	{ pinmux(10), 8, 0 },
232f517afd5SLaurence Withers 	{ pinmux(9), 8, 7 },
233f517afd5SLaurence Withers 	{ pinmux(9), 8, 6 },
234f517afd5SLaurence Withers 	{ pinmux(9), 8, 5 },
235f517afd5SLaurence Withers 	{ pinmux(9), 8, 4 },
236f517afd5SLaurence Withers 	{ pinmux(9), 8, 3 },
237f517afd5SLaurence Withers 	{ pinmux(9), 8, 2 },
238f517afd5SLaurence Withers 	{ pinmux(9), 8, 1 },
239f517afd5SLaurence Withers 	{ pinmux(9), 8, 0 },
240f517afd5SLaurence Withers 	{ pinmux(12), 8, 7 },	/* GP5[0] */
241f517afd5SLaurence Withers 	{ pinmux(12), 8, 6 },
242f517afd5SLaurence Withers 	{ pinmux(12), 8, 5 },
243f517afd5SLaurence Withers 	{ pinmux(12), 8, 4 },
244f517afd5SLaurence Withers 	{ pinmux(12), 8, 3 },
245f517afd5SLaurence Withers 	{ pinmux(12), 8, 2 },
246f517afd5SLaurence Withers 	{ pinmux(12), 8, 1 },
247f517afd5SLaurence Withers 	{ pinmux(12), 8, 0 },
248f517afd5SLaurence Withers 	{ pinmux(11), 8, 7 },
249f517afd5SLaurence Withers 	{ pinmux(11), 8, 6 },
250f517afd5SLaurence Withers 	{ pinmux(11), 8, 5 },
251f517afd5SLaurence Withers 	{ pinmux(11), 8, 4 },
252f517afd5SLaurence Withers 	{ pinmux(11), 8, 3 },
253f517afd5SLaurence Withers 	{ pinmux(11), 8, 2 },
254f517afd5SLaurence Withers 	{ pinmux(11), 8, 1 },
255f517afd5SLaurence Withers 	{ pinmux(11), 8, 0 },
256f517afd5SLaurence Withers 	{ pinmux(19), 8, 6 },	/* GP6[0] */
257f517afd5SLaurence Withers 	{ pinmux(19), 8, 5 },
258f517afd5SLaurence Withers 	{ pinmux(19), 8, 4 },
259f517afd5SLaurence Withers 	{ pinmux(19), 8, 3 },
260f517afd5SLaurence Withers 	{ pinmux(19), 8, 2 },
261f517afd5SLaurence Withers 	{ pinmux(16), 8, 1 },
262f517afd5SLaurence Withers 	{ pinmux(14), 8, 1 },
263f517afd5SLaurence Withers 	{ pinmux(14), 8, 0 },
264f517afd5SLaurence Withers 	{ pinmux(13), 8, 7 },
265f517afd5SLaurence Withers 	{ pinmux(13), 8, 6 },
266f517afd5SLaurence Withers 	{ pinmux(13), 8, 5 },
267f517afd5SLaurence Withers 	{ pinmux(13), 8, 4 },
268f517afd5SLaurence Withers 	{ pinmux(13), 8, 3 },
269f517afd5SLaurence Withers 	{ pinmux(13), 8, 2 },
270f517afd5SLaurence Withers 	{ pinmux(13), 8, 1 },
271f517afd5SLaurence Withers 	{ pinmux(13), 8, 0 },
272f517afd5SLaurence Withers 	{ pinmux(18), 8, 1 },	/* GP7[0] */
273f517afd5SLaurence Withers 	{ pinmux(18), 8, 0 },
274f517afd5SLaurence Withers 	{ pinmux(17), 8, 7 },
275f517afd5SLaurence Withers 	{ pinmux(17), 8, 6 },
276f517afd5SLaurence Withers 	{ pinmux(17), 8, 5 },
277f517afd5SLaurence Withers 	{ pinmux(17), 8, 4 },
278f517afd5SLaurence Withers 	{ pinmux(17), 8, 3 },
279f517afd5SLaurence Withers 	{ pinmux(17), 8, 2 },
280f517afd5SLaurence Withers 	{ pinmux(17), 8, 1 },
281f517afd5SLaurence Withers 	{ pinmux(17), 8, 0 },
282f517afd5SLaurence Withers 	{ pinmux(16), 8, 7 },
283f517afd5SLaurence Withers 	{ pinmux(16), 8, 6 },
284f517afd5SLaurence Withers 	{ pinmux(16), 8, 5 },
285f517afd5SLaurence Withers 	{ pinmux(16), 8, 4 },
286f517afd5SLaurence Withers 	{ pinmux(16), 8, 3 },
287f517afd5SLaurence Withers 	{ pinmux(16), 8, 2 },
288f517afd5SLaurence Withers 	{ pinmux(19), 8, 0 },	/* GP8[0] */
289f517afd5SLaurence Withers 	{ pinmux(3), 4, 7 },
290f517afd5SLaurence Withers 	{ pinmux(3), 4, 6 },
291f517afd5SLaurence Withers 	{ pinmux(3), 4, 5 },
292f517afd5SLaurence Withers 	{ pinmux(3), 4, 4 },
293f517afd5SLaurence Withers 	{ pinmux(3), 4, 3 },
294f517afd5SLaurence Withers 	{ pinmux(3), 4, 2 },
295f517afd5SLaurence Withers 	{ pinmux(2), 4, 7 },
296f517afd5SLaurence Withers 	{ pinmux(19), 8, 1 },
297f517afd5SLaurence Withers 	{ pinmux(19), 8, 0 },
298f517afd5SLaurence Withers 	{ pinmux(18), 8, 7 },
299f517afd5SLaurence Withers 	{ pinmux(18), 8, 6 },
300f517afd5SLaurence Withers 	{ pinmux(18), 8, 5 },
301f517afd5SLaurence Withers 	{ pinmux(18), 8, 4 },
302f517afd5SLaurence Withers 	{ pinmux(18), 8, 3 },
303f517afd5SLaurence Withers 	{ pinmux(18), 8, 2 },
304f517afd5SLaurence Withers };
30576b40ab4STom Rini #endif /* CONFIG_SOC_DA8XX && !CONFIG_SOC_DA850 */
30676b40ab4STom Rini #else /* !CONFIG_SOC_DA8XX */
30703414ac4SHolger Hans Peter Freyther #define davinci_configure_pin_mux(a, b)
30876b40ab4STom Rini #endif /* CONFIG_SOC_DA8XX */
309f517afd5SLaurence Withers 
3108e51c0f2SAdam Ford int gpio_request(unsigned int gpio, const char *label)
311f517afd5SLaurence Withers {
312365d6070SJoe Hershberger 	if (gpio >= MAX_NUM_GPIOS)
313f517afd5SLaurence Withers 		return -1;
314f517afd5SLaurence Withers 
315365d6070SJoe Hershberger 	if (gpio_registry[gpio].is_registered)
316f517afd5SLaurence Withers 		return -1;
317f517afd5SLaurence Withers 
318365d6070SJoe Hershberger 	gpio_registry[gpio].is_registered = 1;
319365d6070SJoe Hershberger 	strncpy(gpio_registry[gpio].name, label, GPIO_NAME_SIZE);
320365d6070SJoe Hershberger 	gpio_registry[gpio].name[GPIO_NAME_SIZE - 1] = 0;
321f517afd5SLaurence Withers 
322365d6070SJoe Hershberger 	davinci_configure_pin_mux(&gpio_pinmux[gpio], 1);
323f517afd5SLaurence Withers 
324f517afd5SLaurence Withers 	return 0;
325f517afd5SLaurence Withers }
326f517afd5SLaurence Withers 
3278e51c0f2SAdam Ford int gpio_free(unsigned int gpio)
328f517afd5SLaurence Withers {
329365d6070SJoe Hershberger 	if (gpio >= MAX_NUM_GPIOS)
330365d6070SJoe Hershberger 		return -1;
331365d6070SJoe Hershberger 
332365d6070SJoe Hershberger 	if (!gpio_registry[gpio].is_registered)
333365d6070SJoe Hershberger 		return -1;
334365d6070SJoe Hershberger 
335365d6070SJoe Hershberger 	gpio_registry[gpio].is_registered = 0;
336365d6070SJoe Hershberger 	gpio_registry[gpio].name[0] = '\0';
337365d6070SJoe Hershberger 	/* Do not configure as input or change pin mux here */
338365d6070SJoe Hershberger 	return 0;
339f517afd5SLaurence Withers }
3408e51c0f2SAdam Ford #endif
341f517afd5SLaurence Withers 
3428e51c0f2SAdam Ford static int _gpio_direction_output(struct davinci_gpio *bank, unsigned int gpio, int value)
343f517afd5SLaurence Withers {
344365d6070SJoe Hershberger 	clrbits_le32(&bank->dir, 1U << GPIO_BIT(gpio));
345365d6070SJoe Hershberger 	gpio_set_value(gpio, value);
346f517afd5SLaurence Withers 	return 0;
347f517afd5SLaurence Withers }
348f517afd5SLaurence Withers 
3498e51c0f2SAdam Ford static int _gpio_direction_input(struct davinci_gpio *bank, unsigned int gpio)
350f517afd5SLaurence Withers {
3518e51c0f2SAdam Ford 	setbits_le32(&bank->dir, 1U << GPIO_BIT(gpio));
3528e51c0f2SAdam Ford 	return 0;
3538e51c0f2SAdam Ford }
354f517afd5SLaurence Withers 
3558e51c0f2SAdam Ford static int _gpio_get_value(struct davinci_gpio *bank, unsigned int gpio)
3568e51c0f2SAdam Ford {
3578e51c0f2SAdam Ford 	unsigned int ip;
358365d6070SJoe Hershberger 	ip = in_le32(&bank->in_data) & (1U << GPIO_BIT(gpio));
359f517afd5SLaurence Withers 	return ip ? 1 : 0;
360f517afd5SLaurence Withers }
361f517afd5SLaurence Withers 
3628e51c0f2SAdam Ford static int _gpio_set_value(struct davinci_gpio *bank, unsigned int gpio, int value)
363f517afd5SLaurence Withers {
364f517afd5SLaurence Withers 	if (value)
365365d6070SJoe Hershberger 		bank->set_data = 1U << GPIO_BIT(gpio);
366f517afd5SLaurence Withers 	else
367365d6070SJoe Hershberger 		bank->clr_data = 1U << GPIO_BIT(gpio);
368365d6070SJoe Hershberger 
369365d6070SJoe Hershberger 	return 0;
370f517afd5SLaurence Withers }
371f517afd5SLaurence Withers 
3728e51c0f2SAdam Ford static int _gpio_get_dir(struct davinci_gpio *bank, unsigned int gpio)
3738e51c0f2SAdam Ford {
3748e51c0f2SAdam Ford 	return in_le32(&bank->dir) & (1U << GPIO_BIT(gpio));
3758e51c0f2SAdam Ford }
3768e51c0f2SAdam Ford 
3778e51c0f2SAdam Ford #ifndef CONFIG_DM_GPIO
3788e51c0f2SAdam Ford 
379f517afd5SLaurence Withers void gpio_info(void)
380f517afd5SLaurence Withers {
3818e51c0f2SAdam Ford 	unsigned int gpio, dir, val;
382f517afd5SLaurence Withers 	struct davinci_gpio *bank;
383f517afd5SLaurence Withers 
384365d6070SJoe Hershberger 	for (gpio = 0; gpio < MAX_NUM_GPIOS; ++gpio) {
385365d6070SJoe Hershberger 		bank = GPIO_BANK(gpio);
3868e51c0f2SAdam Ford 		dir = _gpio_get_dir(bank, gpio);
387365d6070SJoe Hershberger 		val = gpio_get_value(gpio);
388f517afd5SLaurence Withers 
389f517afd5SLaurence Withers 		printf("% 4d: %s: %d [%c] %s\n",
390365d6070SJoe Hershberger 			gpio, dir ? " in" : "out", val,
391365d6070SJoe Hershberger 			gpio_registry[gpio].is_registered ? 'x' : ' ',
392365d6070SJoe Hershberger 			gpio_registry[gpio].name);
393f517afd5SLaurence Withers 	}
394f517afd5SLaurence Withers }
3958e51c0f2SAdam Ford 
3968e51c0f2SAdam Ford int gpio_direction_input(unsigned int gpio)
3978e51c0f2SAdam Ford {
3988e51c0f2SAdam Ford 	struct davinci_gpio *bank;
3998e51c0f2SAdam Ford 
4008e51c0f2SAdam Ford 	bank = GPIO_BANK(gpio);
4018e51c0f2SAdam Ford 	return _gpio_direction_input(bank, gpio);
4028e51c0f2SAdam Ford }
4038e51c0f2SAdam Ford 
4048e51c0f2SAdam Ford int gpio_direction_output(unsigned int gpio, int value)
4058e51c0f2SAdam Ford {
4068e51c0f2SAdam Ford 	struct davinci_gpio *bank;
4078e51c0f2SAdam Ford 
4088e51c0f2SAdam Ford 	bank = GPIO_BANK(gpio);
4098e51c0f2SAdam Ford 	return _gpio_direction_output(bank, gpio, value);
4108e51c0f2SAdam Ford }
4118e51c0f2SAdam Ford 
4128e51c0f2SAdam Ford int gpio_get_value(unsigned int gpio)
4138e51c0f2SAdam Ford {
4148e51c0f2SAdam Ford 	struct davinci_gpio *bank;
4158e51c0f2SAdam Ford 
4168e51c0f2SAdam Ford 	bank = GPIO_BANK(gpio);
4178e51c0f2SAdam Ford 	return _gpio_get_value(bank, gpio);
4188e51c0f2SAdam Ford }
4198e51c0f2SAdam Ford 
4208e51c0f2SAdam Ford int gpio_set_value(unsigned int gpio, int value)
4218e51c0f2SAdam Ford {
4228e51c0f2SAdam Ford 	struct davinci_gpio *bank;
4238e51c0f2SAdam Ford 
4248e51c0f2SAdam Ford 	bank = GPIO_BANK(gpio);
4258e51c0f2SAdam Ford 	return _gpio_set_value(bank, gpio, value);
4268e51c0f2SAdam Ford }
4278e51c0f2SAdam Ford 
4288e51c0f2SAdam Ford #else /* CONFIG_DM_GPIO */
4298e51c0f2SAdam Ford 
4308e51c0f2SAdam Ford static struct davinci_gpio *davinci_get_gpio_bank(struct udevice *dev, unsigned int offset)
4318e51c0f2SAdam Ford {
4328e51c0f2SAdam Ford 	struct davinci_gpio_bank *bank = dev_get_priv(dev);
4331eddf549SAdam Ford 	unsigned int addr;
4348e51c0f2SAdam Ford 
4351eddf549SAdam Ford 	/*
4361eddf549SAdam Ford 	 * The device tree is not broken into banks but the infrastructure is
4378e51c0f2SAdam Ford 	 * expecting it this way, so we'll first include the 0x10 offset, then
4388e51c0f2SAdam Ford 	 * calculate the bank manually based on the offset.
4391eddf549SAdam Ford 	 * Casting 'addr' as Unsigned long is needed to make the math work.
4408e51c0f2SAdam Ford 	 */
4411eddf549SAdam Ford 	addr = ((unsigned long)(struct davinci_gpio *)bank->base) +
4421eddf549SAdam Ford 			0x10 + (0x28 * (offset >> 5));
4431eddf549SAdam Ford 	return (struct davinci_gpio *)addr;
4448e51c0f2SAdam Ford }
4458e51c0f2SAdam Ford 
4468e51c0f2SAdam Ford static int davinci_gpio_direction_input(struct udevice *dev, unsigned int offset)
4478e51c0f2SAdam Ford {
4488e51c0f2SAdam Ford 	struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
4498e51c0f2SAdam Ford 
4501eddf549SAdam Ford 	/*
4511eddf549SAdam Ford 	 * Fetch the address based on GPIO, but only pass the masked low 32-bits
4521eddf549SAdam Ford 	 */
4531eddf549SAdam Ford 	_gpio_direction_input(base, (offset & 0x1f));
4548e51c0f2SAdam Ford 	return 0;
4558e51c0f2SAdam Ford }
4568e51c0f2SAdam Ford 
4578e51c0f2SAdam Ford static int davinci_gpio_direction_output(struct udevice *dev, unsigned int offset,
4588e51c0f2SAdam Ford 					 int value)
4598e51c0f2SAdam Ford {
4608e51c0f2SAdam Ford 	struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
4618e51c0f2SAdam Ford 
4621eddf549SAdam Ford 	_gpio_direction_output(base, (offset & 0x1f), value);
4638e51c0f2SAdam Ford 	return 0;
4648e51c0f2SAdam Ford }
4658e51c0f2SAdam Ford 
4668e51c0f2SAdam Ford static int davinci_gpio_get_value(struct udevice *dev, unsigned int offset)
4678e51c0f2SAdam Ford {
4688e51c0f2SAdam Ford 	struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
4698e51c0f2SAdam Ford 
4701eddf549SAdam Ford 	return _gpio_get_value(base, (offset & 0x1f));
4718e51c0f2SAdam Ford }
4728e51c0f2SAdam Ford 
4738e51c0f2SAdam Ford static int davinci_gpio_set_value(struct udevice *dev, unsigned int offset,
4748e51c0f2SAdam Ford 				  int value)
4758e51c0f2SAdam Ford {
4768e51c0f2SAdam Ford 	struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
4778e51c0f2SAdam Ford 
4781eddf549SAdam Ford 	_gpio_set_value(base, (offset & 0x1f), value);
4798e51c0f2SAdam Ford 
4808e51c0f2SAdam Ford 	return 0;
4818e51c0f2SAdam Ford }
4828e51c0f2SAdam Ford 
4838e51c0f2SAdam Ford static int davinci_gpio_get_function(struct udevice *dev, unsigned int offset)
4848e51c0f2SAdam Ford {
4858e51c0f2SAdam Ford 	unsigned int dir;
4868e51c0f2SAdam Ford 	struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
4878e51c0f2SAdam Ford 
4888e51c0f2SAdam Ford 	dir = _gpio_get_dir(base, offset);
4898e51c0f2SAdam Ford 
4908e51c0f2SAdam Ford 	if (dir)
4918e51c0f2SAdam Ford 		return GPIOF_INPUT;
4928e51c0f2SAdam Ford 
4938e51c0f2SAdam Ford 	return GPIOF_OUTPUT;
4948e51c0f2SAdam Ford }
4958e51c0f2SAdam Ford 
4969440b3d3SAdam Ford static int davinci_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
4979440b3d3SAdam Ford 			      struct ofnode_phandle_args *args)
4989440b3d3SAdam Ford {
4999440b3d3SAdam Ford 	desc->offset = args->args[0];
5009440b3d3SAdam Ford 
5019440b3d3SAdam Ford 	if (args->args[1] & GPIO_ACTIVE_LOW)
5029440b3d3SAdam Ford 		desc->flags = GPIOD_ACTIVE_LOW;
5039440b3d3SAdam Ford 	else
5049440b3d3SAdam Ford 		desc->flags = 0;
5059440b3d3SAdam Ford 	return 0;
5069440b3d3SAdam Ford }
5079440b3d3SAdam Ford 
5088e51c0f2SAdam Ford static const struct dm_gpio_ops gpio_davinci_ops = {
5098e51c0f2SAdam Ford 	.direction_input	= davinci_gpio_direction_input,
5108e51c0f2SAdam Ford 	.direction_output	= davinci_gpio_direction_output,
5118e51c0f2SAdam Ford 	.get_value		= davinci_gpio_get_value,
5128e51c0f2SAdam Ford 	.set_value		= davinci_gpio_set_value,
5138e51c0f2SAdam Ford 	.get_function		= davinci_gpio_get_function,
5149440b3d3SAdam Ford 	.xlate			= davinci_gpio_xlate,
5158e51c0f2SAdam Ford };
5168e51c0f2SAdam Ford 
5178e51c0f2SAdam Ford static int davinci_gpio_probe(struct udevice *dev)
5188e51c0f2SAdam Ford {
5198e51c0f2SAdam Ford 	struct davinci_gpio_bank *bank = dev_get_priv(dev);
5208e51c0f2SAdam Ford 	struct davinci_gpio_platdata *plat = dev_get_platdata(dev);
5218e51c0f2SAdam Ford 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
5228e51c0f2SAdam Ford 	const void *fdt = gd->fdt_blob;
5238e51c0f2SAdam Ford 	int node = dev_of_offset(dev);
5248e51c0f2SAdam Ford 
5258e51c0f2SAdam Ford 	uc_priv->bank_name = plat->port_name;
5268e51c0f2SAdam Ford 	uc_priv->gpio_count = fdtdec_get_int(fdt, node, "ti,ngpio", -1);
5278e51c0f2SAdam Ford 	bank->base = (struct davinci_gpio *)plat->base;
5288e51c0f2SAdam Ford 	return 0;
5298e51c0f2SAdam Ford }
5308e51c0f2SAdam Ford 
5318e51c0f2SAdam Ford static const struct udevice_id davinci_gpio_ids[] = {
5328e51c0f2SAdam Ford 	{ .compatible = "ti,dm6441-gpio" },
533*401d74cbSKeerthy 	{ .compatible = "ti,k2g-gpio" },
5348e51c0f2SAdam Ford 	{ }
5358e51c0f2SAdam Ford };
5368e51c0f2SAdam Ford 
5378e51c0f2SAdam Ford static int davinci_gpio_ofdata_to_platdata(struct udevice *dev)
5388e51c0f2SAdam Ford {
5398e51c0f2SAdam Ford 	struct davinci_gpio_platdata *plat = dev_get_platdata(dev);
5408e51c0f2SAdam Ford 	fdt_addr_t addr;
5418e51c0f2SAdam Ford 
5428e51c0f2SAdam Ford 	addr = devfdt_get_addr(dev);
5438e51c0f2SAdam Ford 	if (addr == FDT_ADDR_T_NONE)
5448e51c0f2SAdam Ford 		return -EINVAL;
5458e51c0f2SAdam Ford 
5468e51c0f2SAdam Ford 	plat->base = addr;
5478e51c0f2SAdam Ford 	return 0;
5488e51c0f2SAdam Ford }
5498e51c0f2SAdam Ford 
5508e51c0f2SAdam Ford U_BOOT_DRIVER(gpio_davinci) = {
5518e51c0f2SAdam Ford 	.name	= "gpio_davinci",
5528e51c0f2SAdam Ford 	.id	= UCLASS_GPIO,
5538e51c0f2SAdam Ford 	.ops	= &gpio_davinci_ops,
5548e51c0f2SAdam Ford 	.ofdata_to_platdata = of_match_ptr(davinci_gpio_ofdata_to_platdata),
5558e51c0f2SAdam Ford 	.of_match = davinci_gpio_ids,
5568e51c0f2SAdam Ford 	.bind   = dm_scan_fdt_dev,
5578e51c0f2SAdam Ford 	.platdata_auto_alloc_size = sizeof(struct davinci_gpio_platdata),
5588e51c0f2SAdam Ford 	.probe	= davinci_gpio_probe,
5598e51c0f2SAdam Ford 	.priv_auto_alloc_size = sizeof(struct davinci_gpio_bank),
5608e51c0f2SAdam Ford };
5618e51c0f2SAdam Ford 
5628e51c0f2SAdam Ford #endif
563