Commit | Line | Data |
---|---|---|
7d30e8b3 | 1 | /* linux/arch/arm/mach-exynos4/gpiolib.c |
d2e7eca3 | 2 | * |
7d30e8b3 | 3 | * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. |
d2e7eca3 JL |
4 | * http://www.samsung.com |
5 | * | |
7d30e8b3 | 6 | * EXYNOS4 - GPIOlib support |
d2e7eca3 JL |
7 | * |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License version 2 as | |
10 | * published by the Free Software Foundation. | |
11 | */ | |
12 | ||
13 | #include <linux/kernel.h> | |
14 | #include <linux/irq.h> | |
15 | #include <linux/io.h> | |
16 | #include <linux/gpio.h> | |
17 | ||
18 | #include <mach/map.h> | |
19 | ||
20 | #include <plat/gpio-core.h> | |
21 | #include <plat/gpio-cfg.h> | |
22 | #include <plat/gpio-cfg-helpers.h> | |
23 | ||
24 | static struct s3c_gpio_cfg gpio_cfg = { | |
25 | .set_config = s3c_gpio_setcfg_s3c64xx_4bit, | |
26 | .set_pull = s3c_gpio_setpull_updown, | |
27 | .get_pull = s3c_gpio_getpull_updown, | |
28 | }; | |
29 | ||
30 | static struct s3c_gpio_cfg gpio_cfg_noint = { | |
31 | .set_config = s3c_gpio_setcfg_s3c64xx_4bit, | |
32 | .set_pull = s3c_gpio_setpull_updown, | |
33 | .get_pull = s3c_gpio_getpull_updown, | |
34 | }; | |
35 | ||
36 | /* | |
37 | * Following are the gpio banks in v310. | |
38 | * | |
39 | * The 'config' member when left to NULL, is initialized to the default | |
40 | * structure gpio_cfg in the init function below. | |
41 | * | |
42 | * The 'base' member is also initialized in the init function below. | |
43 | * Note: The initialization of 'base' member of s3c_gpio_chip structure | |
44 | * uses the above macro and depends on the banks being listed in order here. | |
45 | */ | |
7d30e8b3 | 46 | static struct s3c_gpio_chip exynos4_gpio_part1_4bit[] = { |
d2e7eca3 JL |
47 | { |
48 | .chip = { | |
7d30e8b3 KK |
49 | .base = EXYNOS4_GPA0(0), |
50 | .ngpio = EXYNOS4_GPIO_A0_NR, | |
d2e7eca3 JL |
51 | .label = "GPA0", |
52 | }, | |
53 | }, { | |
54 | .chip = { | |
7d30e8b3 KK |
55 | .base = EXYNOS4_GPA1(0), |
56 | .ngpio = EXYNOS4_GPIO_A1_NR, | |
d2e7eca3 JL |
57 | .label = "GPA1", |
58 | }, | |
59 | }, { | |
60 | .chip = { | |
7d30e8b3 KK |
61 | .base = EXYNOS4_GPB(0), |
62 | .ngpio = EXYNOS4_GPIO_B_NR, | |
d2e7eca3 JL |
63 | .label = "GPB", |
64 | }, | |
65 | }, { | |
66 | .chip = { | |
7d30e8b3 KK |
67 | .base = EXYNOS4_GPC0(0), |
68 | .ngpio = EXYNOS4_GPIO_C0_NR, | |
d2e7eca3 JL |
69 | .label = "GPC0", |
70 | }, | |
71 | }, { | |
72 | .chip = { | |
7d30e8b3 KK |
73 | .base = EXYNOS4_GPC1(0), |
74 | .ngpio = EXYNOS4_GPIO_C1_NR, | |
d2e7eca3 JL |
75 | .label = "GPC1", |
76 | }, | |
77 | }, { | |
78 | .chip = { | |
7d30e8b3 KK |
79 | .base = EXYNOS4_GPD0(0), |
80 | .ngpio = EXYNOS4_GPIO_D0_NR, | |
d2e7eca3 JL |
81 | .label = "GPD0", |
82 | }, | |
83 | }, { | |
84 | .chip = { | |
7d30e8b3 KK |
85 | .base = EXYNOS4_GPD1(0), |
86 | .ngpio = EXYNOS4_GPIO_D1_NR, | |
d2e7eca3 JL |
87 | .label = "GPD1", |
88 | }, | |
89 | }, { | |
90 | .chip = { | |
7d30e8b3 KK |
91 | .base = EXYNOS4_GPE0(0), |
92 | .ngpio = EXYNOS4_GPIO_E0_NR, | |
d2e7eca3 JL |
93 | .label = "GPE0", |
94 | }, | |
95 | }, { | |
96 | .chip = { | |
7d30e8b3 KK |
97 | .base = EXYNOS4_GPE1(0), |
98 | .ngpio = EXYNOS4_GPIO_E1_NR, | |
d2e7eca3 JL |
99 | .label = "GPE1", |
100 | }, | |
101 | }, { | |
102 | .chip = { | |
7d30e8b3 KK |
103 | .base = EXYNOS4_GPE2(0), |
104 | .ngpio = EXYNOS4_GPIO_E2_NR, | |
d2e7eca3 JL |
105 | .label = "GPE2", |
106 | }, | |
107 | }, { | |
108 | .chip = { | |
7d30e8b3 KK |
109 | .base = EXYNOS4_GPE3(0), |
110 | .ngpio = EXYNOS4_GPIO_E3_NR, | |
d2e7eca3 JL |
111 | .label = "GPE3", |
112 | }, | |
113 | }, { | |
114 | .chip = { | |
7d30e8b3 KK |
115 | .base = EXYNOS4_GPE4(0), |
116 | .ngpio = EXYNOS4_GPIO_E4_NR, | |
d2e7eca3 JL |
117 | .label = "GPE4", |
118 | }, | |
119 | }, { | |
120 | .chip = { | |
7d30e8b3 KK |
121 | .base = EXYNOS4_GPF0(0), |
122 | .ngpio = EXYNOS4_GPIO_F0_NR, | |
d2e7eca3 JL |
123 | .label = "GPF0", |
124 | }, | |
125 | }, { | |
126 | .chip = { | |
7d30e8b3 KK |
127 | .base = EXYNOS4_GPF1(0), |
128 | .ngpio = EXYNOS4_GPIO_F1_NR, | |
d2e7eca3 JL |
129 | .label = "GPF1", |
130 | }, | |
131 | }, { | |
132 | .chip = { | |
7d30e8b3 KK |
133 | .base = EXYNOS4_GPF2(0), |
134 | .ngpio = EXYNOS4_GPIO_F2_NR, | |
d2e7eca3 JL |
135 | .label = "GPF2", |
136 | }, | |
137 | }, { | |
138 | .chip = { | |
7d30e8b3 KK |
139 | .base = EXYNOS4_GPF3(0), |
140 | .ngpio = EXYNOS4_GPIO_F3_NR, | |
d2e7eca3 JL |
141 | .label = "GPF3", |
142 | }, | |
143 | }, | |
144 | }; | |
145 | ||
7d30e8b3 | 146 | static struct s3c_gpio_chip exynos4_gpio_part2_4bit[] = { |
d2e7eca3 JL |
147 | { |
148 | .chip = { | |
7d30e8b3 KK |
149 | .base = EXYNOS4_GPJ0(0), |
150 | .ngpio = EXYNOS4_GPIO_J0_NR, | |
d2e7eca3 JL |
151 | .label = "GPJ0", |
152 | }, | |
153 | }, { | |
154 | .chip = { | |
7d30e8b3 KK |
155 | .base = EXYNOS4_GPJ1(0), |
156 | .ngpio = EXYNOS4_GPIO_J1_NR, | |
d2e7eca3 JL |
157 | .label = "GPJ1", |
158 | }, | |
159 | }, { | |
160 | .chip = { | |
7d30e8b3 KK |
161 | .base = EXYNOS4_GPK0(0), |
162 | .ngpio = EXYNOS4_GPIO_K0_NR, | |
d2e7eca3 JL |
163 | .label = "GPK0", |
164 | }, | |
165 | }, { | |
166 | .chip = { | |
7d30e8b3 KK |
167 | .base = EXYNOS4_GPK1(0), |
168 | .ngpio = EXYNOS4_GPIO_K1_NR, | |
d2e7eca3 JL |
169 | .label = "GPK1", |
170 | }, | |
171 | }, { | |
172 | .chip = { | |
7d30e8b3 KK |
173 | .base = EXYNOS4_GPK2(0), |
174 | .ngpio = EXYNOS4_GPIO_K2_NR, | |
d2e7eca3 JL |
175 | .label = "GPK2", |
176 | }, | |
177 | }, { | |
178 | .chip = { | |
7d30e8b3 KK |
179 | .base = EXYNOS4_GPK3(0), |
180 | .ngpio = EXYNOS4_GPIO_K3_NR, | |
d2e7eca3 JL |
181 | .label = "GPK3", |
182 | }, | |
183 | }, { | |
184 | .chip = { | |
7d30e8b3 KK |
185 | .base = EXYNOS4_GPL0(0), |
186 | .ngpio = EXYNOS4_GPIO_L0_NR, | |
d2e7eca3 JL |
187 | .label = "GPL0", |
188 | }, | |
189 | }, { | |
190 | .chip = { | |
7d30e8b3 KK |
191 | .base = EXYNOS4_GPL1(0), |
192 | .ngpio = EXYNOS4_GPIO_L1_NR, | |
d2e7eca3 JL |
193 | .label = "GPL1", |
194 | }, | |
195 | }, { | |
196 | .chip = { | |
7d30e8b3 KK |
197 | .base = EXYNOS4_GPL2(0), |
198 | .ngpio = EXYNOS4_GPIO_L2_NR, | |
d2e7eca3 JL |
199 | .label = "GPL2", |
200 | }, | |
47a9c0ee MS |
201 | }, { |
202 | .config = &gpio_cfg_noint, | |
203 | .chip = { | |
204 | .base = EXYNOS4_GPY0(0), | |
205 | .ngpio = EXYNOS4_GPIO_Y0_NR, | |
206 | .label = "GPY0", | |
207 | }, | |
208 | }, { | |
209 | .config = &gpio_cfg_noint, | |
210 | .chip = { | |
211 | .base = EXYNOS4_GPY1(0), | |
212 | .ngpio = EXYNOS4_GPIO_Y1_NR, | |
213 | .label = "GPY1", | |
214 | }, | |
215 | }, { | |
216 | .config = &gpio_cfg_noint, | |
217 | .chip = { | |
218 | .base = EXYNOS4_GPY2(0), | |
219 | .ngpio = EXYNOS4_GPIO_Y2_NR, | |
220 | .label = "GPY2", | |
221 | }, | |
222 | }, { | |
223 | .config = &gpio_cfg_noint, | |
224 | .chip = { | |
225 | .base = EXYNOS4_GPY3(0), | |
226 | .ngpio = EXYNOS4_GPIO_Y3_NR, | |
227 | .label = "GPY3", | |
228 | }, | |
229 | }, { | |
230 | .config = &gpio_cfg_noint, | |
231 | .chip = { | |
232 | .base = EXYNOS4_GPY4(0), | |
233 | .ngpio = EXYNOS4_GPIO_Y4_NR, | |
234 | .label = "GPY4", | |
235 | }, | |
236 | }, { | |
237 | .config = &gpio_cfg_noint, | |
238 | .chip = { | |
239 | .base = EXYNOS4_GPY5(0), | |
240 | .ngpio = EXYNOS4_GPIO_Y5_NR, | |
241 | .label = "GPY5", | |
242 | }, | |
243 | }, { | |
244 | .config = &gpio_cfg_noint, | |
245 | .chip = { | |
246 | .base = EXYNOS4_GPY6(0), | |
247 | .ngpio = EXYNOS4_GPIO_Y6_NR, | |
248 | .label = "GPY6", | |
249 | }, | |
d2e7eca3 JL |
250 | }, { |
251 | .base = (S5P_VA_GPIO2 + 0xC00), | |
252 | .config = &gpio_cfg_noint, | |
253 | .irq_base = IRQ_EINT(0), | |
254 | .chip = { | |
7d30e8b3 KK |
255 | .base = EXYNOS4_GPX0(0), |
256 | .ngpio = EXYNOS4_GPIO_X0_NR, | |
d2e7eca3 JL |
257 | .label = "GPX0", |
258 | .to_irq = samsung_gpiolib_to_irq, | |
259 | }, | |
260 | }, { | |
261 | .base = (S5P_VA_GPIO2 + 0xC20), | |
262 | .config = &gpio_cfg_noint, | |
263 | .irq_base = IRQ_EINT(8), | |
264 | .chip = { | |
7d30e8b3 KK |
265 | .base = EXYNOS4_GPX1(0), |
266 | .ngpio = EXYNOS4_GPIO_X1_NR, | |
d2e7eca3 JL |
267 | .label = "GPX1", |
268 | .to_irq = samsung_gpiolib_to_irq, | |
269 | }, | |
270 | }, { | |
271 | .base = (S5P_VA_GPIO2 + 0xC40), | |
272 | .config = &gpio_cfg_noint, | |
273 | .irq_base = IRQ_EINT(16), | |
274 | .chip = { | |
7d30e8b3 KK |
275 | .base = EXYNOS4_GPX2(0), |
276 | .ngpio = EXYNOS4_GPIO_X2_NR, | |
d2e7eca3 JL |
277 | .label = "GPX2", |
278 | .to_irq = samsung_gpiolib_to_irq, | |
279 | }, | |
280 | }, { | |
281 | .base = (S5P_VA_GPIO2 + 0xC60), | |
282 | .config = &gpio_cfg_noint, | |
283 | .irq_base = IRQ_EINT(24), | |
284 | .chip = { | |
7d30e8b3 KK |
285 | .base = EXYNOS4_GPX3(0), |
286 | .ngpio = EXYNOS4_GPIO_X3_NR, | |
d2e7eca3 JL |
287 | .label = "GPX3", |
288 | .to_irq = samsung_gpiolib_to_irq, | |
289 | }, | |
290 | }, | |
291 | }; | |
292 | ||
7d30e8b3 | 293 | static struct s3c_gpio_chip exynos4_gpio_part3_4bit[] = { |
d2e7eca3 JL |
294 | { |
295 | .chip = { | |
7d30e8b3 KK |
296 | .base = EXYNOS4_GPZ(0), |
297 | .ngpio = EXYNOS4_GPIO_Z_NR, | |
d2e7eca3 JL |
298 | .label = "GPZ", |
299 | }, | |
300 | }, | |
301 | }; | |
302 | ||
7d30e8b3 | 303 | static __init int exynos4_gpiolib_init(void) |
d2e7eca3 JL |
304 | { |
305 | struct s3c_gpio_chip *chip; | |
306 | int i; | |
721bbd4a | 307 | int group = 0; |
d2e7eca3 JL |
308 | int nr_chips; |
309 | ||
310 | /* GPIO part 1 */ | |
311 | ||
7d30e8b3 KK |
312 | chip = exynos4_gpio_part1_4bit; |
313 | nr_chips = ARRAY_SIZE(exynos4_gpio_part1_4bit); | |
d2e7eca3 JL |
314 | |
315 | for (i = 0; i < nr_chips; i++, chip++) { | |
721bbd4a | 316 | if (chip->config == NULL) { |
d2e7eca3 | 317 | chip->config = &gpio_cfg; |
721bbd4a MS |
318 | /* Assign the GPIO interrupt group */ |
319 | chip->group = group++; | |
320 | } | |
d2e7eca3 JL |
321 | if (chip->base == NULL) |
322 | chip->base = S5P_VA_GPIO1 + (i) * 0x20; | |
323 | } | |
324 | ||
7d30e8b3 | 325 | samsung_gpiolib_add_4bit_chips(exynos4_gpio_part1_4bit, nr_chips); |
d2e7eca3 JL |
326 | |
327 | /* GPIO part 2 */ | |
328 | ||
7d30e8b3 KK |
329 | chip = exynos4_gpio_part2_4bit; |
330 | nr_chips = ARRAY_SIZE(exynos4_gpio_part2_4bit); | |
d2e7eca3 JL |
331 | |
332 | for (i = 0; i < nr_chips; i++, chip++) { | |
721bbd4a | 333 | if (chip->config == NULL) { |
d2e7eca3 | 334 | chip->config = &gpio_cfg; |
721bbd4a MS |
335 | /* Assign the GPIO interrupt group */ |
336 | chip->group = group++; | |
337 | } | |
d2e7eca3 JL |
338 | if (chip->base == NULL) |
339 | chip->base = S5P_VA_GPIO2 + (i) * 0x20; | |
340 | } | |
341 | ||
7d30e8b3 | 342 | samsung_gpiolib_add_4bit_chips(exynos4_gpio_part2_4bit, nr_chips); |
d2e7eca3 JL |
343 | |
344 | /* GPIO part 3 */ | |
345 | ||
7d30e8b3 KK |
346 | chip = exynos4_gpio_part3_4bit; |
347 | nr_chips = ARRAY_SIZE(exynos4_gpio_part3_4bit); | |
d2e7eca3 JL |
348 | |
349 | for (i = 0; i < nr_chips; i++, chip++) { | |
721bbd4a | 350 | if (chip->config == NULL) { |
d2e7eca3 | 351 | chip->config = &gpio_cfg; |
721bbd4a MS |
352 | /* Assign the GPIO interrupt group */ |
353 | chip->group = group++; | |
354 | } | |
d2e7eca3 JL |
355 | if (chip->base == NULL) |
356 | chip->base = S5P_VA_GPIO3 + (i) * 0x20; | |
357 | } | |
358 | ||
7d30e8b3 | 359 | samsung_gpiolib_add_4bit_chips(exynos4_gpio_part3_4bit, nr_chips); |
721bbd4a MS |
360 | s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS); |
361 | s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS); | |
d2e7eca3 JL |
362 | |
363 | return 0; | |
364 | } | |
7d30e8b3 | 365 | core_initcall(exynos4_gpiolib_init); |