1 /*
2  * Coldfire generic GPIO support
3  *
4  * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14 */
15 
16 #include <linux/kernel.h>
17 #include <linux/init.h>
18 
19 #include <asm/coldfire.h>
20 #include <asm/mcfsim.h>
21 #include <asm/mcfgpio.h>
22 
23 static struct mcf_gpio_chip mcf_gpio_chips[] = {
24 	{
25 		.gpio_chip			= {
26 			.label			= "NQ",
27 			.request		= mcf_gpio_request,
28 			.free			= mcf_gpio_free,
29 			.direction_input	= mcf_gpio_direction_input,
30 			.direction_output	= mcf_gpio_direction_output,
31 			.get			= mcf_gpio_get_value,
32 			.set			= mcf_gpio_set_value,
33 			.base			= 1,
34 			.ngpio			= 7,
35 		},
36 		.pddr				= (void __iomem *)MCFEPORT_EPDDR,
37 		.podr				= (void __iomem *)MCFEPORT_EPDR,
38 		.ppdr				= (void __iomem *)MCFEPORT_EPPDR,
39 	},
40 	{
41 		.gpio_chip			= {
42 			.label			= "TA",
43 			.request		= mcf_gpio_request,
44 			.free			= mcf_gpio_free,
45 			.direction_input	= mcf_gpio_direction_input,
46 			.direction_output	= mcf_gpio_direction_output,
47 			.get			= mcf_gpio_get_value,
48 			.set			= mcf_gpio_set_value_fast,
49 			.base			= 8,
50 			.ngpio			= 4,
51 		},
52 		.pddr				= (void __iomem *)MCFGPTA_GPTDDR,
53 		.podr				= (void __iomem *)MCFGPTA_GPTPORT,
54 		.ppdr				= (void __iomem *)MCFGPTB_GPTPORT,
55 	},
56 	{
57 		.gpio_chip			= {
58 			.label			= "TB",
59 			.request		= mcf_gpio_request,
60 			.free			= mcf_gpio_free,
61 			.direction_input	= mcf_gpio_direction_input,
62 			.direction_output	= mcf_gpio_direction_output,
63 			.get			= mcf_gpio_get_value,
64 			.set			= mcf_gpio_set_value_fast,
65 			.base			= 16,
66 			.ngpio			= 4,
67 		},
68 		.pddr				= (void __iomem *)MCFGPTB_GPTDDR,
69 		.podr				= (void __iomem *)MCFGPTB_GPTPORT,
70 		.ppdr				= (void __iomem *)MCFGPTB_GPTPORT,
71 	},
72 	{
73 		.gpio_chip			= {
74 			.label			= "QA",
75 			.request		= mcf_gpio_request,
76 			.free			= mcf_gpio_free,
77 			.direction_input	= mcf_gpio_direction_input,
78 			.direction_output	= mcf_gpio_direction_output,
79 			.get			= mcf_gpio_get_value,
80 			.set			= mcf_gpio_set_value_fast,
81 			.base			= 24,
82 			.ngpio			= 4,
83 		},
84 		.pddr				= (void __iomem *)MCFQADC_DDRQA,
85 		.podr				= (void __iomem *)MCFQADC_PORTQA,
86 		.ppdr				= (void __iomem *)MCFQADC_PORTQA,
87 	},
88 	{
89 		.gpio_chip			= {
90 			.label			= "QB",
91 			.request		= mcf_gpio_request,
92 			.free			= mcf_gpio_free,
93 			.direction_input	= mcf_gpio_direction_input,
94 			.direction_output	= mcf_gpio_direction_output,
95 			.get			= mcf_gpio_get_value,
96 			.set			= mcf_gpio_set_value_fast,
97 			.base			= 32,
98 			.ngpio			= 4,
99 		},
100 		.pddr				= (void __iomem *)MCFQADC_DDRQB,
101 		.podr				= (void __iomem *)MCFQADC_PORTQB,
102 		.ppdr				= (void __iomem *)MCFQADC_PORTQB,
103 	},
104 	{
105 		.gpio_chip			= {
106 			.label			= "A",
107 			.request		= mcf_gpio_request,
108 			.free			= mcf_gpio_free,
109 			.direction_input	= mcf_gpio_direction_input,
110 			.direction_output	= mcf_gpio_direction_output,
111 			.get			= mcf_gpio_get_value,
112 			.set			= mcf_gpio_set_value_fast,
113 			.base			= 40,
114 			.ngpio			= 8,
115 		},
116 		.pddr				= (void __iomem *)MCFGPIO_DDRA,
117 		.podr				= (void __iomem *)MCFGPIO_PORTA,
118 		.ppdr				= (void __iomem *)MCFGPIO_PORTAP,
119 		.setr				= (void __iomem *)MCFGPIO_SETA,
120 		.clrr				= (void __iomem *)MCFGPIO_CLRA,
121 	},
122 	{
123 		.gpio_chip			= {
124 			.label			= "B",
125 			.request		= mcf_gpio_request,
126 			.free			= mcf_gpio_free,
127 			.direction_input	= mcf_gpio_direction_input,
128 			.direction_output	= mcf_gpio_direction_output,
129 			.get			= mcf_gpio_get_value,
130 			.set			= mcf_gpio_set_value_fast,
131 			.base			= 48,
132 			.ngpio			= 8,
133 		},
134 		.pddr				= (void __iomem *)MCFGPIO_DDRB,
135 		.podr				= (void __iomem *)MCFGPIO_PORTB,
136 		.ppdr				= (void __iomem *)MCFGPIO_PORTBP,
137 		.setr				= (void __iomem *)MCFGPIO_SETB,
138 		.clrr				= (void __iomem *)MCFGPIO_CLRB,
139 	},
140 	{
141 		.gpio_chip			= {
142 			.label			= "C",
143 			.request		= mcf_gpio_request,
144 			.free			= mcf_gpio_free,
145 			.direction_input	= mcf_gpio_direction_input,
146 			.direction_output	= mcf_gpio_direction_output,
147 			.get			= mcf_gpio_get_value,
148 			.set			= mcf_gpio_set_value_fast,
149 			.base			= 56,
150 			.ngpio			= 8,
151 		},
152 		.pddr				= (void __iomem *)MCFGPIO_DDRC,
153 		.podr				= (void __iomem *)MCFGPIO_PORTC,
154 		.ppdr				= (void __iomem *)MCFGPIO_PORTCP,
155 		.setr				= (void __iomem *)MCFGPIO_SETC,
156 		.clrr				= (void __iomem *)MCFGPIO_CLRC,
157 	},
158 	{
159 		.gpio_chip			= {
160 			.label			= "D",
161 			.request		= mcf_gpio_request,
162 			.free			= mcf_gpio_free,
163 			.direction_input	= mcf_gpio_direction_input,
164 			.direction_output	= mcf_gpio_direction_output,
165 			.get			= mcf_gpio_get_value,
166 			.set			= mcf_gpio_set_value_fast,
167 			.base			= 64,
168 			.ngpio			= 8,
169 		},
170 		.pddr				= (void __iomem *)MCFGPIO_DDRD,
171 		.podr				= (void __iomem *)MCFGPIO_PORTD,
172 		.ppdr				= (void __iomem *)MCFGPIO_PORTDP,
173 		.setr				= (void __iomem *)MCFGPIO_SETD,
174 		.clrr				= (void __iomem *)MCFGPIO_CLRD,
175 	},
176 	{
177 		.gpio_chip			= {
178 			.label			= "E",
179 			.request		= mcf_gpio_request,
180 			.free			= mcf_gpio_free,
181 			.direction_input	= mcf_gpio_direction_input,
182 			.direction_output	= mcf_gpio_direction_output,
183 			.get			= mcf_gpio_get_value,
184 			.set			= mcf_gpio_set_value_fast,
185 			.base			= 72,
186 			.ngpio			= 8,
187 		},
188 		.pddr				= (void __iomem *)MCFGPIO_DDRE,
189 		.podr				= (void __iomem *)MCFGPIO_PORTE,
190 		.ppdr				= (void __iomem *)MCFGPIO_PORTEP,
191 		.setr				= (void __iomem *)MCFGPIO_SETE,
192 		.clrr				= (void __iomem *)MCFGPIO_CLRE,
193 	},
194 	{
195 		.gpio_chip			= {
196 			.label			= "F",
197 			.request		= mcf_gpio_request,
198 			.free			= mcf_gpio_free,
199 			.direction_input	= mcf_gpio_direction_input,
200 			.direction_output	= mcf_gpio_direction_output,
201 			.get			= mcf_gpio_get_value,
202 			.set			= mcf_gpio_set_value_fast,
203 			.base			= 80,
204 			.ngpio			= 8,
205 		},
206 		.pddr				= (void __iomem *)MCFGPIO_DDRF,
207 		.podr				= (void __iomem *)MCFGPIO_PORTF,
208 		.ppdr				= (void __iomem *)MCFGPIO_PORTFP,
209 		.setr				= (void __iomem *)MCFGPIO_SETF,
210 		.clrr				= (void __iomem *)MCFGPIO_CLRF,
211 	},
212 	{
213 		.gpio_chip			= {
214 			.label			= "G",
215 			.request		= mcf_gpio_request,
216 			.free			= mcf_gpio_free,
217 			.direction_input	= mcf_gpio_direction_input,
218 			.direction_output	= mcf_gpio_direction_output,
219 			.get			= mcf_gpio_get_value,
220 			.set			= mcf_gpio_set_value_fast,
221 			.base			= 88,
222 			.ngpio			= 8,
223 		},
224 		.pddr				= (void __iomem *)MCFGPIO_DDRG,
225 		.podr				= (void __iomem *)MCFGPIO_PORTG,
226 		.ppdr				= (void __iomem *)MCFGPIO_PORTGP,
227 		.setr				= (void __iomem *)MCFGPIO_SETG,
228 		.clrr				= (void __iomem *)MCFGPIO_CLRG,
229 	},
230 	{
231 		.gpio_chip			= {
232 			.label			= "H",
233 			.request		= mcf_gpio_request,
234 			.free			= mcf_gpio_free,
235 			.direction_input	= mcf_gpio_direction_input,
236 			.direction_output	= mcf_gpio_direction_output,
237 			.get			= mcf_gpio_get_value,
238 			.set			= mcf_gpio_set_value_fast,
239 			.base			= 96,
240 			.ngpio			= 8,
241 		},
242 		.pddr				= (void __iomem *)MCFGPIO_DDRH,
243 		.podr				= (void __iomem *)MCFGPIO_PORTH,
244 		.ppdr				= (void __iomem *)MCFGPIO_PORTHP,
245 		.setr				= (void __iomem *)MCFGPIO_SETH,
246 		.clrr				= (void __iomem *)MCFGPIO_CLRH,
247 	},
248 	{
249 		.gpio_chip			= {
250 			.label			= "J",
251 			.request		= mcf_gpio_request,
252 			.free			= mcf_gpio_free,
253 			.direction_input	= mcf_gpio_direction_input,
254 			.direction_output	= mcf_gpio_direction_output,
255 			.get			= mcf_gpio_get_value,
256 			.set			= mcf_gpio_set_value_fast,
257 			.base			= 104,
258 			.ngpio			= 8,
259 		},
260 		.pddr				= (void __iomem *)MCFGPIO_DDRJ,
261 		.podr				= (void __iomem *)MCFGPIO_PORTJ,
262 		.ppdr				= (void __iomem *)MCFGPIO_PORTJP,
263 		.setr				= (void __iomem *)MCFGPIO_SETJ,
264 		.clrr				= (void __iomem *)MCFGPIO_CLRJ,
265 	},
266 	{
267 		.gpio_chip			= {
268 			.label			= "DD",
269 			.request		= mcf_gpio_request,
270 			.free			= mcf_gpio_free,
271 			.direction_input	= mcf_gpio_direction_input,
272 			.direction_output	= mcf_gpio_direction_output,
273 			.get			= mcf_gpio_get_value,
274 			.set			= mcf_gpio_set_value_fast,
275 			.base			= 112,
276 			.ngpio			= 8,
277 		},
278 		.pddr				= (void __iomem *)MCFGPIO_DDRDD,
279 		.podr				= (void __iomem *)MCFGPIO_PORTDD,
280 		.ppdr				= (void __iomem *)MCFGPIO_PORTDDP,
281 		.setr				= (void __iomem *)MCFGPIO_SETDD,
282 		.clrr				= (void __iomem *)MCFGPIO_CLRDD,
283 	},
284 	{
285 		.gpio_chip			= {
286 			.label			= "EH",
287 			.request		= mcf_gpio_request,
288 			.free			= mcf_gpio_free,
289 			.direction_input	= mcf_gpio_direction_input,
290 			.direction_output	= mcf_gpio_direction_output,
291 			.get			= mcf_gpio_get_value,
292 			.set			= mcf_gpio_set_value_fast,
293 			.base			= 120,
294 			.ngpio			= 8,
295 		},
296 		.pddr				= (void __iomem *)MCFGPIO_DDREH,
297 		.podr				= (void __iomem *)MCFGPIO_PORTEH,
298 		.ppdr				= (void __iomem *)MCFGPIO_PORTEHP,
299 		.setr				= (void __iomem *)MCFGPIO_SETEH,
300 		.clrr				= (void __iomem *)MCFGPIO_CLREH,
301 	},
302 	{
303 		.gpio_chip			= {
304 			.label			= "EL",
305 			.request		= mcf_gpio_request,
306 			.free			= mcf_gpio_free,
307 			.direction_input	= mcf_gpio_direction_input,
308 			.direction_output	= mcf_gpio_direction_output,
309 			.get			= mcf_gpio_get_value,
310 			.set			= mcf_gpio_set_value_fast,
311 			.base			= 128,
312 			.ngpio			= 8,
313 		},
314 		.pddr				= (void __iomem *)MCFGPIO_DDREL,
315 		.podr				= (void __iomem *)MCFGPIO_PORTEL,
316 		.ppdr				= (void __iomem *)MCFGPIO_PORTELP,
317 		.setr				= (void __iomem *)MCFGPIO_SETEL,
318 		.clrr				= (void __iomem *)MCFGPIO_CLREL,
319 	},
320 	{
321 		.gpio_chip			= {
322 			.label			= "AS",
323 			.request		= mcf_gpio_request,
324 			.free			= mcf_gpio_free,
325 			.direction_input	= mcf_gpio_direction_input,
326 			.direction_output	= mcf_gpio_direction_output,
327 			.get			= mcf_gpio_get_value,
328 			.set			= mcf_gpio_set_value_fast,
329 			.base			= 136,
330 			.ngpio			= 6,
331 		},
332 		.pddr				= (void __iomem *)MCFGPIO_DDRAS,
333 		.podr				= (void __iomem *)MCFGPIO_PORTAS,
334 		.ppdr				= (void __iomem *)MCFGPIO_PORTASP,
335 		.setr				= (void __iomem *)MCFGPIO_SETAS,
336 		.clrr				= (void __iomem *)MCFGPIO_CLRAS,
337 	},
338 	{
339 		.gpio_chip			= {
340 			.label			= "QS",
341 			.request		= mcf_gpio_request,
342 			.free			= mcf_gpio_free,
343 			.direction_input	= mcf_gpio_direction_input,
344 			.direction_output	= mcf_gpio_direction_output,
345 			.get			= mcf_gpio_get_value,
346 			.set			= mcf_gpio_set_value_fast,
347 			.base			= 144,
348 			.ngpio			= 7,
349 		},
350 		.pddr				= (void __iomem *)MCFGPIO_DDRQS,
351 		.podr				= (void __iomem *)MCFGPIO_PORTQS,
352 		.ppdr				= (void __iomem *)MCFGPIO_PORTQSP,
353 		.setr				= (void __iomem *)MCFGPIO_SETQS,
354 		.clrr				= (void __iomem *)MCFGPIO_CLRQS,
355 	},
356 	{
357 		.gpio_chip			= {
358 			.label			= "SD",
359 			.request		= mcf_gpio_request,
360 			.free			= mcf_gpio_free,
361 			.direction_input	= mcf_gpio_direction_input,
362 			.direction_output	= mcf_gpio_direction_output,
363 			.get			= mcf_gpio_get_value,
364 			.set			= mcf_gpio_set_value_fast,
365 			.base			= 152,
366 			.ngpio			= 6,
367 		},
368 		.pddr				= (void __iomem *)MCFGPIO_DDRSD,
369 		.podr				= (void __iomem *)MCFGPIO_PORTSD,
370 		.ppdr				= (void __iomem *)MCFGPIO_PORTSDP,
371 		.setr				= (void __iomem *)MCFGPIO_SETSD,
372 		.clrr				= (void __iomem *)MCFGPIO_CLRSD,
373 	},
374 	{
375 		.gpio_chip			= {
376 			.label			= "TC",
377 			.request		= mcf_gpio_request,
378 			.free			= mcf_gpio_free,
379 			.direction_input	= mcf_gpio_direction_input,
380 			.direction_output	= mcf_gpio_direction_output,
381 			.get			= mcf_gpio_get_value,
382 			.set			= mcf_gpio_set_value_fast,
383 			.base			= 160,
384 			.ngpio			= 4,
385 		},
386 		.pddr				= (void __iomem *)MCFGPIO_DDRTC,
387 		.podr				= (void __iomem *)MCFGPIO_PORTTC,
388 		.ppdr				= (void __iomem *)MCFGPIO_PORTTCP,
389 		.setr				= (void __iomem *)MCFGPIO_SETTC,
390 		.clrr				= (void __iomem *)MCFGPIO_CLRTC,
391 	},
392 	{
393 		.gpio_chip			= {
394 			.label			= "TD",
395 			.request		= mcf_gpio_request,
396 			.free			= mcf_gpio_free,
397 			.direction_input	= mcf_gpio_direction_input,
398 			.direction_output	= mcf_gpio_direction_output,
399 			.get			= mcf_gpio_get_value,
400 			.set			= mcf_gpio_set_value_fast,
401 			.base			= 168,
402 			.ngpio			= 4,
403 		},
404 		.pddr				= (void __iomem *)MCFGPIO_DDRTD,
405 		.podr				= (void __iomem *)MCFGPIO_PORTTD,
406 		.ppdr				= (void __iomem *)MCFGPIO_PORTTDP,
407 		.setr				= (void __iomem *)MCFGPIO_SETTD,
408 		.clrr				= (void __iomem *)MCFGPIO_CLRTD,
409 	},
410 	{
411 		.gpio_chip			= {
412 			.label			= "UA",
413 			.request		= mcf_gpio_request,
414 			.free			= mcf_gpio_free,
415 			.direction_input	= mcf_gpio_direction_input,
416 			.direction_output	= mcf_gpio_direction_output,
417 			.get			= mcf_gpio_get_value,
418 			.set			= mcf_gpio_set_value_fast,
419 			.base			= 176,
420 			.ngpio			= 4,
421 		},
422 		.pddr				= (void __iomem *)MCFGPIO_DDRUA,
423 		.podr				= (void __iomem *)MCFGPIO_PORTUA,
424 		.ppdr				= (void __iomem *)MCFGPIO_PORTUAP,
425 		.setr				= (void __iomem *)MCFGPIO_SETUA,
426 		.clrr				= (void __iomem *)MCFGPIO_CLRUA,
427 	},
428 };
429 
mcf_gpio_init(void)430 static int __init mcf_gpio_init(void)
431 {
432 	unsigned i = 0;
433 	while (i < ARRAY_SIZE(mcf_gpio_chips))
434 		(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
435 	return 0;
436 }
437 
438 core_initcall(mcf_gpio_init);
439