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			= "PIRQ",
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			= "ADDR",
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			= 13,
50 			.ngpio			= 3,
51 		},
52 		.pddr				= (void __iomem *) MCFGPIO_PDDR_ADDR,
53 		.podr				= (void __iomem *) MCFGPIO_PODR_ADDR,
54 		.ppdr				= (void __iomem *) MCFGPIO_PPDSDR_ADDR,
55 		.setr				= (void __iomem *) MCFGPIO_PPDSDR_ADDR,
56 		.clrr				= (void __iomem *) MCFGPIO_PCLRR_ADDR,
57 	},
58 	{
59 		.gpio_chip			= {
60 			.label			= "DATAH",
61 			.request		= mcf_gpio_request,
62 			.free			= mcf_gpio_free,
63 			.direction_input	= mcf_gpio_direction_input,
64 			.direction_output	= mcf_gpio_direction_output,
65 			.get			= mcf_gpio_get_value,
66 			.set			= mcf_gpio_set_value_fast,
67 			.base			= 16,
68 			.ngpio			= 8,
69 		},
70 		.pddr				= (void __iomem *) MCFGPIO_PDDR_DATAH,
71 		.podr				= (void __iomem *) MCFGPIO_PODR_DATAH,
72 		.ppdr				= (void __iomem *) MCFGPIO_PPDSDR_DATAH,
73 		.setr				= (void __iomem *) MCFGPIO_PPDSDR_DATAH,
74 		.clrr				= (void __iomem *) MCFGPIO_PCLRR_DATAH,
75 	},
76 	{
77 		.gpio_chip			= {
78 			.label			= "DATAL",
79 			.request		= mcf_gpio_request,
80 			.free			= mcf_gpio_free,
81 			.direction_input	= mcf_gpio_direction_input,
82 			.direction_output	= mcf_gpio_direction_output,
83 			.get			= mcf_gpio_get_value,
84 			.set			= mcf_gpio_set_value_fast,
85 			.base			= 24,
86 			.ngpio			= 8,
87 		},
88 		.pddr				= (void __iomem *) MCFGPIO_PDDR_DATAL,
89 		.podr				= (void __iomem *) MCFGPIO_PODR_DATAL,
90 		.ppdr				= (void __iomem *) MCFGPIO_PPDSDR_DATAL,
91 		.setr				= (void __iomem *) MCFGPIO_PPDSDR_DATAL,
92 		.clrr				= (void __iomem *) MCFGPIO_PCLRR_DATAL,
93 	},
94 	{
95 		.gpio_chip			= {
96 			.label			= "BUSCTL",
97 			.request		= mcf_gpio_request,
98 			.free			= mcf_gpio_free,
99 			.direction_input	= mcf_gpio_direction_input,
100 			.direction_output	= mcf_gpio_direction_output,
101 			.get			= mcf_gpio_get_value,
102 			.set			= mcf_gpio_set_value_fast,
103 			.base			= 32,
104 			.ngpio			= 8,
105 		},
106 		.pddr				= (void __iomem *) MCFGPIO_PDDR_BUSCTL,
107 		.podr				= (void __iomem *) MCFGPIO_PODR_BUSCTL,
108 		.ppdr				= (void __iomem *) MCFGPIO_PPDSDR_BUSCTL,
109 		.setr				= (void __iomem *) MCFGPIO_PPDSDR_BUSCTL,
110 		.clrr				= (void __iomem *) MCFGPIO_PCLRR_BUSCTL,
111 	},
112 	{
113 		.gpio_chip			= {
114 			.label			= "BS",
115 			.request		= mcf_gpio_request,
116 			.free			= mcf_gpio_free,
117 			.direction_input	= mcf_gpio_direction_input,
118 			.direction_output	= mcf_gpio_direction_output,
119 			.get			= mcf_gpio_get_value,
120 			.set			= mcf_gpio_set_value_fast,
121 			.base			= 40,
122 			.ngpio			= 4,
123 		},
124 		.pddr				= (void __iomem *) MCFGPIO_PDDR_BS,
125 		.podr				= (void __iomem *) MCFGPIO_PODR_BS,
126 		.ppdr				= (void __iomem *) MCFGPIO_PPDSDR_BS,
127 		.setr				= (void __iomem *) MCFGPIO_PPDSDR_BS,
128 		.clrr				= (void __iomem *) MCFGPIO_PCLRR_BS,
129 	},
130 	{
131 		.gpio_chip			= {
132 			.label			= "CS",
133 			.request		= mcf_gpio_request,
134 			.free			= mcf_gpio_free,
135 			.direction_input	= mcf_gpio_direction_input,
136 			.direction_output	= mcf_gpio_direction_output,
137 			.get			= mcf_gpio_get_value,
138 			.set			= mcf_gpio_set_value_fast,
139 			.base			= 49,
140 			.ngpio			= 7,
141 		},
142 		.pddr				= (void __iomem *) MCFGPIO_PDDR_CS,
143 		.podr				= (void __iomem *) MCFGPIO_PODR_CS,
144 		.ppdr				= (void __iomem *) MCFGPIO_PPDSDR_CS,
145 		.setr				= (void __iomem *) MCFGPIO_PPDSDR_CS,
146 		.clrr				= (void __iomem *) MCFGPIO_PCLRR_CS,
147 	},
148 	{
149 		.gpio_chip			= {
150 			.label			= "SDRAM",
151 			.request		= mcf_gpio_request,
152 			.free			= mcf_gpio_free,
153 			.direction_input	= mcf_gpio_direction_input,
154 			.direction_output	= mcf_gpio_direction_output,
155 			.get			= mcf_gpio_get_value,
156 			.set			= mcf_gpio_set_value_fast,
157 			.base			= 56,
158 			.ngpio			= 6,
159 		},
160 		.pddr				= (void __iomem *) MCFGPIO_PDDR_SDRAM,
161 		.podr				= (void __iomem *) MCFGPIO_PODR_SDRAM,
162 		.ppdr				= (void __iomem *) MCFGPIO_PPDSDR_SDRAM,
163 		.setr				= (void __iomem *) MCFGPIO_PPDSDR_SDRAM,
164 		.clrr				= (void __iomem *) MCFGPIO_PCLRR_SDRAM,
165 	},
166 	{
167 		.gpio_chip			= {
168 			.label			= "FECI2C",
169 			.request		= mcf_gpio_request,
170 			.free			= mcf_gpio_free,
171 			.direction_input	= mcf_gpio_direction_input,
172 			.direction_output	= mcf_gpio_direction_output,
173 			.get			= mcf_gpio_get_value,
174 			.set			= mcf_gpio_set_value_fast,
175 			.base			= 64,
176 			.ngpio			= 4,
177 		},
178 		.pddr				= (void __iomem *) MCFGPIO_PDDR_FECI2C,
179 		.podr				= (void __iomem *) MCFGPIO_PODR_FECI2C,
180 		.ppdr				= (void __iomem *) MCFGPIO_PPDSDR_FECI2C,
181 		.setr				= (void __iomem *) MCFGPIO_PPDSDR_FECI2C,
182 		.clrr				= (void __iomem *) MCFGPIO_PCLRR_FECI2C,
183 	},
184 	{
185 		.gpio_chip			= {
186 			.label			= "UARTH",
187 			.request		= mcf_gpio_request,
188 			.free			= mcf_gpio_free,
189 			.direction_input	= mcf_gpio_direction_input,
190 			.direction_output	= mcf_gpio_direction_output,
191 			.get			= mcf_gpio_get_value,
192 			.set			= mcf_gpio_set_value_fast,
193 			.base			= 72,
194 			.ngpio			= 2,
195 		},
196 		.pddr				= (void __iomem *) MCFGPIO_PDDR_UARTH,
197 		.podr				= (void __iomem *) MCFGPIO_PODR_UARTH,
198 		.ppdr				= (void __iomem *) MCFGPIO_PPDSDR_UARTH,
199 		.setr				= (void __iomem *) MCFGPIO_PPDSDR_UARTH,
200 		.clrr				= (void __iomem *) MCFGPIO_PCLRR_UARTH,
201 	},
202 	{
203 		.gpio_chip			= {
204 			.label			= "UARTL",
205 			.request		= mcf_gpio_request,
206 			.free			= mcf_gpio_free,
207 			.direction_input	= mcf_gpio_direction_input,
208 			.direction_output	= mcf_gpio_direction_output,
209 			.get			= mcf_gpio_get_value,
210 			.set			= mcf_gpio_set_value_fast,
211 			.base			= 80,
212 			.ngpio			= 8,
213 		},
214 		.pddr				= (void __iomem *) MCFGPIO_PDDR_UARTL,
215 		.podr				= (void __iomem *) MCFGPIO_PODR_UARTL,
216 		.ppdr				= (void __iomem *) MCFGPIO_PPDSDR_UARTL,
217 		.setr				= (void __iomem *) MCFGPIO_PPDSDR_UARTL,
218 		.clrr				= (void __iomem *) MCFGPIO_PCLRR_UARTL,
219 	},
220 	{
221 		.gpio_chip			= {
222 			.label			= "QSPI",
223 			.request		= mcf_gpio_request,
224 			.free			= mcf_gpio_free,
225 			.direction_input	= mcf_gpio_direction_input,
226 			.direction_output	= mcf_gpio_direction_output,
227 			.get			= mcf_gpio_get_value,
228 			.set			= mcf_gpio_set_value_fast,
229 			.base			= 88,
230 			.ngpio			= 5,
231 		},
232 		.pddr				= (void __iomem *) MCFGPIO_PDDR_QSPI,
233 		.podr				= (void __iomem *) MCFGPIO_PODR_QSPI,
234 		.ppdr				= (void __iomem *) MCFGPIO_PPDSDR_QSPI,
235 		.setr				= (void __iomem *) MCFGPIO_PPDSDR_QSPI,
236 		.clrr				= (void __iomem *) MCFGPIO_PCLRR_QSPI,
237 	},
238 	{
239 		.gpio_chip			= {
240 			.label			= "TIMER",
241 			.request		= mcf_gpio_request,
242 			.free			= mcf_gpio_free,
243 			.direction_input	= mcf_gpio_direction_input,
244 			.direction_output	= mcf_gpio_direction_output,
245 			.get			= mcf_gpio_get_value,
246 			.set			= mcf_gpio_set_value_fast,
247 			.base			= 96,
248 			.ngpio			= 8,
249 		},
250 		.pddr				= (void __iomem *) MCFGPIO_PDDR_TIMER,
251 		.podr				= (void __iomem *) MCFGPIO_PODR_TIMER,
252 		.ppdr				= (void __iomem *) MCFGPIO_PPDSDR_TIMER,
253 		.setr				= (void __iomem *) MCFGPIO_PPDSDR_TIMER,
254 		.clrr				= (void __iomem *) MCFGPIO_PCLRR_TIMER,
255 	},
256 	{
257 		.gpio_chip			= {
258 			.label			= "ETPU",
259 			.request		= mcf_gpio_request,
260 			.free			= mcf_gpio_free,
261 			.direction_input	= mcf_gpio_direction_input,
262 			.direction_output	= mcf_gpio_direction_output,
263 			.get			= mcf_gpio_get_value,
264 			.set			= mcf_gpio_set_value_fast,
265 			.base			= 104,
266 			.ngpio			= 3,
267 		},
268 		.pddr				= (void __iomem *) MCFGPIO_PDDR_ETPU,
269 		.podr				= (void __iomem *) MCFGPIO_PODR_ETPU,
270 		.ppdr				= (void __iomem *) MCFGPIO_PPDSDR_ETPU,
271 		.setr				= (void __iomem *) MCFGPIO_PPDSDR_ETPU,
272 		.clrr				= (void __iomem *) MCFGPIO_PCLRR_ETPU,
273 	},
274 };
275 
mcf_gpio_init(void)276 static int __init mcf_gpio_init(void)
277 {
278 	unsigned i = 0;
279 	while (i < ARRAY_SIZE(mcf_gpio_chips))
280 		(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
281 	return 0;
282 }
283 
284 core_initcall(mcf_gpio_init);
285