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