]>
Commit | Line | Data |
---|---|---|
51e02b02 ML |
1 | /* |
2 | * GPIO functions for Au1000, Au1500, Au1100, Au1550, Au1200 | |
3 | * | |
4 | * Copyright (c) 2009 Manuel Lauss. | |
5 | * | |
6 | * Licensed under the terms outlined in the file COPYING. | |
7 | */ | |
8 | ||
9 | #ifndef _ALCHEMY_GPIO_AU1000_H_ | |
10 | #define _ALCHEMY_GPIO_AU1000_H_ | |
11 | ||
12 | #include <asm/mach-au1x00/au1000.h> | |
13 | ||
14 | /* The default GPIO numberspace as documented in the Alchemy manuals. | |
70342287 | 15 | * GPIO0-31 from GPIO1 block, GPIO200-215 from GPIO2 block. |
51e02b02 ML |
16 | */ |
17 | #define ALCHEMY_GPIO1_BASE 0 | |
18 | #define ALCHEMY_GPIO2_BASE 200 | |
19 | ||
20 | #define ALCHEMY_GPIO1_NUM 32 | |
21 | #define ALCHEMY_GPIO2_NUM 16 | |
70342287 | 22 | #define ALCHEMY_GPIO1_MAX (ALCHEMY_GPIO1_BASE + ALCHEMY_GPIO1_NUM - 1) |
51e02b02 ML |
23 | #define ALCHEMY_GPIO2_MAX (ALCHEMY_GPIO2_BASE + ALCHEMY_GPIO2_NUM - 1) |
24 | ||
25 | #define MAKE_IRQ(intc, off) (AU1000_INTC##intc##_INT_BASE + (off)) | |
26 | ||
b7f720d6 ML |
27 | /* GPIO1 registers within SYS_ area */ |
28 | #define SYS_TRIOUTRD 0x100 | |
29 | #define SYS_TRIOUTCLR 0x100 | |
30 | #define SYS_OUTPUTRD 0x108 | |
31 | #define SYS_OUTPUTSET 0x108 | |
32 | #define SYS_OUTPUTCLR 0x10C | |
33 | #define SYS_PINSTATERD 0x110 | |
34 | #define SYS_PININPUTEN 0x110 | |
35 | ||
36 | /* register offsets within GPIO2 block */ | |
37 | #define GPIO2_DIR 0x00 | |
38 | #define GPIO2_OUTPUT 0x08 | |
39 | #define GPIO2_PINSTATE 0x0C | |
40 | #define GPIO2_INTENABLE 0x10 | |
41 | #define GPIO2_ENABLE 0x14 | |
42 | ||
c1e58a31 | 43 | struct gpio; |
51e02b02 ML |
44 | |
45 | static inline int au1000_gpio1_to_irq(int gpio) | |
46 | { | |
47 | return MAKE_IRQ(1, gpio - ALCHEMY_GPIO1_BASE); | |
48 | } | |
49 | ||
50 | static inline int au1000_gpio2_to_irq(int gpio) | |
51 | { | |
52 | return -ENXIO; | |
53 | } | |
54 | ||
51e02b02 ML |
55 | static inline int au1000_irq_to_gpio(int irq) |
56 | { | |
78814465 ML |
57 | if ((irq >= AU1000_GPIO0_INT) && (irq <= AU1000_GPIO31_INT)) |
58 | return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO0_INT) + 0; | |
51e02b02 ML |
59 | |
60 | return -ENXIO; | |
61 | } | |
51e02b02 ML |
62 | |
63 | static inline int au1500_gpio1_to_irq(int gpio) | |
64 | { | |
65 | gpio -= ALCHEMY_GPIO1_BASE; | |
66 | ||
67 | switch (gpio) { | |
68 | case 0 ... 15: | |
69 | case 20: | |
70342287 | 70 | case 23 ... 28: return MAKE_IRQ(1, gpio); |
51e02b02 ML |
71 | } |
72 | ||
73 | return -ENXIO; | |
74 | } | |
75 | ||
76 | static inline int au1500_gpio2_to_irq(int gpio) | |
77 | { | |
78 | gpio -= ALCHEMY_GPIO2_BASE; | |
79 | ||
80 | switch (gpio) { | |
81 | case 0 ... 3: return MAKE_IRQ(1, 16 + gpio - 0); | |
82 | case 4 ... 5: return MAKE_IRQ(1, 21 + gpio - 4); | |
83 | case 6 ... 7: return MAKE_IRQ(1, 29 + gpio - 6); | |
84 | } | |
85 | ||
86 | return -ENXIO; | |
87 | } | |
88 | ||
51e02b02 ML |
89 | static inline int au1500_irq_to_gpio(int irq) |
90 | { | |
91 | switch (irq) { | |
78814465 ML |
92 | case AU1500_GPIO0_INT ... AU1500_GPIO15_INT: |
93 | case AU1500_GPIO20_INT: | |
94 | case AU1500_GPIO23_INT ... AU1500_GPIO28_INT: | |
95 | return ALCHEMY_GPIO1_BASE + (irq - AU1500_GPIO0_INT) + 0; | |
96 | case AU1500_GPIO200_INT ... AU1500_GPIO203_INT: | |
97 | return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO200_INT) + 0; | |
98 | case AU1500_GPIO204_INT ... AU1500_GPIO205_INT: | |
99 | return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO204_INT) + 4; | |
100 | case AU1500_GPIO206_INT ... AU1500_GPIO207_INT: | |
101 | return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO206_INT) + 6; | |
102 | case AU1500_GPIO208_215_INT: | |
51e02b02 ML |
103 | return ALCHEMY_GPIO2_BASE + 8; |
104 | } | |
105 | ||
106 | return -ENXIO; | |
107 | } | |
51e02b02 ML |
108 | |
109 | static inline int au1100_gpio1_to_irq(int gpio) | |
110 | { | |
111 | return MAKE_IRQ(1, gpio - ALCHEMY_GPIO1_BASE); | |
112 | } | |
113 | ||
114 | static inline int au1100_gpio2_to_irq(int gpio) | |
115 | { | |
116 | gpio -= ALCHEMY_GPIO2_BASE; | |
117 | ||
118 | if ((gpio >= 8) && (gpio <= 15)) | |
119 | return MAKE_IRQ(0, 29); /* shared GPIO208_215 */ | |
e85843a1 FF |
120 | |
121 | return -ENXIO; | |
51e02b02 ML |
122 | } |
123 | ||
51e02b02 ML |
124 | static inline int au1100_irq_to_gpio(int irq) |
125 | { | |
126 | switch (irq) { | |
78814465 ML |
127 | case AU1100_GPIO0_INT ... AU1100_GPIO31_INT: |
128 | return ALCHEMY_GPIO1_BASE + (irq - AU1100_GPIO0_INT) + 0; | |
129 | case AU1100_GPIO208_215_INT: | |
51e02b02 ML |
130 | return ALCHEMY_GPIO2_BASE + 8; |
131 | } | |
132 | ||
133 | return -ENXIO; | |
134 | } | |
51e02b02 ML |
135 | |
136 | static inline int au1550_gpio1_to_irq(int gpio) | |
137 | { | |
138 | gpio -= ALCHEMY_GPIO1_BASE; | |
139 | ||
140 | switch (gpio) { | |
141 | case 0 ... 15: | |
70342287 RB |
142 | case 20 ... 28: return MAKE_IRQ(1, gpio); |
143 | case 16 ... 17: return MAKE_IRQ(1, 18 + gpio - 16); | |
51e02b02 ML |
144 | } |
145 | ||
146 | return -ENXIO; | |
147 | } | |
148 | ||
149 | static inline int au1550_gpio2_to_irq(int gpio) | |
150 | { | |
151 | gpio -= ALCHEMY_GPIO2_BASE; | |
152 | ||
153 | switch (gpio) { | |
154 | case 0: return MAKE_IRQ(1, 16); | |
70342287 | 155 | case 1 ... 5: return MAKE_IRQ(1, 17); /* shared GPIO201_205 */ |
51e02b02 | 156 | case 6 ... 7: return MAKE_IRQ(1, 29 + gpio - 6); |
70342287 | 157 | case 8 ... 15: return MAKE_IRQ(1, 31); /* shared GPIO208_215 */ |
51e02b02 ML |
158 | } |
159 | ||
160 | return -ENXIO; | |
161 | } | |
162 | ||
51e02b02 ML |
163 | static inline int au1550_irq_to_gpio(int irq) |
164 | { | |
165 | switch (irq) { | |
78814465 ML |
166 | case AU1550_GPIO0_INT ... AU1550_GPIO15_INT: |
167 | return ALCHEMY_GPIO1_BASE + (irq - AU1550_GPIO0_INT) + 0; | |
168 | case AU1550_GPIO200_INT: | |
169 | case AU1550_GPIO201_205_INT: | |
170 | return ALCHEMY_GPIO2_BASE + (irq - AU1550_GPIO200_INT) + 0; | |
171 | case AU1550_GPIO16_INT ... AU1550_GPIO28_INT: | |
172 | return ALCHEMY_GPIO1_BASE + (irq - AU1550_GPIO16_INT) + 16; | |
173 | case AU1550_GPIO206_INT ... AU1550_GPIO208_215_INT: | |
174 | return ALCHEMY_GPIO2_BASE + (irq - AU1550_GPIO206_INT) + 6; | |
51e02b02 ML |
175 | } |
176 | ||
177 | return -ENXIO; | |
178 | } | |
51e02b02 ML |
179 | |
180 | static inline int au1200_gpio1_to_irq(int gpio) | |
181 | { | |
182 | return MAKE_IRQ(1, gpio - ALCHEMY_GPIO1_BASE); | |
183 | } | |
184 | ||
185 | static inline int au1200_gpio2_to_irq(int gpio) | |
186 | { | |
187 | gpio -= ALCHEMY_GPIO2_BASE; | |
188 | ||
189 | switch (gpio) { | |
190 | case 0 ... 2: return MAKE_IRQ(0, 5 + gpio - 0); | |
191 | case 3: return MAKE_IRQ(0, 22); | |
192 | case 4 ... 7: return MAKE_IRQ(0, 24 + gpio - 4); | |
70342287 | 193 | case 8 ... 15: return MAKE_IRQ(0, 28); /* shared GPIO208_215 */ |
51e02b02 ML |
194 | } |
195 | ||
196 | return -ENXIO; | |
197 | } | |
198 | ||
51e02b02 ML |
199 | static inline int au1200_irq_to_gpio(int irq) |
200 | { | |
201 | switch (irq) { | |
78814465 ML |
202 | case AU1200_GPIO0_INT ... AU1200_GPIO31_INT: |
203 | return ALCHEMY_GPIO1_BASE + (irq - AU1200_GPIO0_INT) + 0; | |
204 | case AU1200_GPIO200_INT ... AU1200_GPIO202_INT: | |
205 | return ALCHEMY_GPIO2_BASE + (irq - AU1200_GPIO200_INT) + 0; | |
206 | case AU1200_GPIO203_INT: | |
51e02b02 | 207 | return ALCHEMY_GPIO2_BASE + 3; |
78814465 ML |
208 | case AU1200_GPIO204_INT ... AU1200_GPIO208_215_INT: |
209 | return ALCHEMY_GPIO2_BASE + (irq - AU1200_GPIO204_INT) + 4; | |
51e02b02 ML |
210 | } |
211 | ||
212 | return -ENXIO; | |
213 | } | |
51e02b02 ML |
214 | |
215 | /* | |
216 | * GPIO1 block macros for common linux gpio functions. | |
217 | */ | |
218 | static inline void alchemy_gpio1_set_value(int gpio, int v) | |
219 | { | |
b7f720d6 | 220 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); |
51e02b02 ML |
221 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); |
222 | unsigned long r = v ? SYS_OUTPUTSET : SYS_OUTPUTCLR; | |
b7f720d6 ML |
223 | __raw_writel(mask, base + r); |
224 | wmb(); | |
51e02b02 ML |
225 | } |
226 | ||
227 | static inline int alchemy_gpio1_get_value(int gpio) | |
228 | { | |
b7f720d6 | 229 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); |
51e02b02 | 230 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); |
b7f720d6 | 231 | return __raw_readl(base + SYS_PINSTATERD) & mask; |
51e02b02 ML |
232 | } |
233 | ||
234 | static inline int alchemy_gpio1_direction_input(int gpio) | |
235 | { | |
b7f720d6 | 236 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); |
51e02b02 | 237 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); |
b7f720d6 ML |
238 | __raw_writel(mask, base + SYS_TRIOUTCLR); |
239 | wmb(); | |
51e02b02 ML |
240 | return 0; |
241 | } | |
242 | ||
243 | static inline int alchemy_gpio1_direction_output(int gpio, int v) | |
244 | { | |
245 | /* hardware switches to "output" mode when one of the two | |
246 | * "set_value" registers is accessed. | |
247 | */ | |
248 | alchemy_gpio1_set_value(gpio, v); | |
249 | return 0; | |
250 | } | |
251 | ||
252 | static inline int alchemy_gpio1_is_valid(int gpio) | |
253 | { | |
254 | return ((gpio >= ALCHEMY_GPIO1_BASE) && (gpio <= ALCHEMY_GPIO1_MAX)); | |
255 | } | |
256 | ||
257 | static inline int alchemy_gpio1_to_irq(int gpio) | |
258 | { | |
70f82f2c ML |
259 | switch (alchemy_get_cputype()) { |
260 | case ALCHEMY_CPU_AU1000: | |
261 | return au1000_gpio1_to_irq(gpio); | |
262 | case ALCHEMY_CPU_AU1100: | |
263 | return au1100_gpio1_to_irq(gpio); | |
264 | case ALCHEMY_CPU_AU1500: | |
265 | return au1500_gpio1_to_irq(gpio); | |
266 | case ALCHEMY_CPU_AU1550: | |
267 | return au1550_gpio1_to_irq(gpio); | |
268 | case ALCHEMY_CPU_AU1200: | |
269 | return au1200_gpio1_to_irq(gpio); | |
270 | } | |
51e02b02 | 271 | return -ENXIO; |
51e02b02 ML |
272 | } |
273 | ||
274 | /* | |
275 | * GPIO2 block macros for common linux GPIO functions. The 'gpio' | |
276 | * parameter must be in range of ALCHEMY_GPIO2_BASE..ALCHEMY_GPIO2_MAX. | |
277 | */ | |
278 | static inline void __alchemy_gpio2_mod_dir(int gpio, int to_out) | |
279 | { | |
b7f720d6 | 280 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
51e02b02 | 281 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO2_BASE); |
b7f720d6 ML |
282 | unsigned long d = __raw_readl(base + GPIO2_DIR); |
283 | ||
51e02b02 ML |
284 | if (to_out) |
285 | d |= mask; | |
286 | else | |
287 | d &= ~mask; | |
b7f720d6 ML |
288 | __raw_writel(d, base + GPIO2_DIR); |
289 | wmb(); | |
51e02b02 ML |
290 | } |
291 | ||
292 | static inline void alchemy_gpio2_set_value(int gpio, int v) | |
293 | { | |
b7f720d6 | 294 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
51e02b02 ML |
295 | unsigned long mask; |
296 | mask = ((v) ? 0x00010001 : 0x00010000) << (gpio - ALCHEMY_GPIO2_BASE); | |
b7f720d6 ML |
297 | __raw_writel(mask, base + GPIO2_OUTPUT); |
298 | wmb(); | |
51e02b02 ML |
299 | } |
300 | ||
301 | static inline int alchemy_gpio2_get_value(int gpio) | |
302 | { | |
b7f720d6 ML |
303 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
304 | return __raw_readl(base + GPIO2_PINSTATE) & (1 << (gpio - ALCHEMY_GPIO2_BASE)); | |
51e02b02 ML |
305 | } |
306 | ||
307 | static inline int alchemy_gpio2_direction_input(int gpio) | |
308 | { | |
309 | unsigned long flags; | |
310 | local_irq_save(flags); | |
311 | __alchemy_gpio2_mod_dir(gpio, 0); | |
312 | local_irq_restore(flags); | |
313 | return 0; | |
314 | } | |
315 | ||
316 | static inline int alchemy_gpio2_direction_output(int gpio, int v) | |
317 | { | |
318 | unsigned long flags; | |
319 | alchemy_gpio2_set_value(gpio, v); | |
320 | local_irq_save(flags); | |
321 | __alchemy_gpio2_mod_dir(gpio, 1); | |
322 | local_irq_restore(flags); | |
323 | return 0; | |
324 | } | |
325 | ||
326 | static inline int alchemy_gpio2_is_valid(int gpio) | |
327 | { | |
328 | return ((gpio >= ALCHEMY_GPIO2_BASE) && (gpio <= ALCHEMY_GPIO2_MAX)); | |
329 | } | |
330 | ||
331 | static inline int alchemy_gpio2_to_irq(int gpio) | |
332 | { | |
70f82f2c ML |
333 | switch (alchemy_get_cputype()) { |
334 | case ALCHEMY_CPU_AU1000: | |
335 | return au1000_gpio2_to_irq(gpio); | |
336 | case ALCHEMY_CPU_AU1100: | |
337 | return au1100_gpio2_to_irq(gpio); | |
338 | case ALCHEMY_CPU_AU1500: | |
339 | return au1500_gpio2_to_irq(gpio); | |
340 | case ALCHEMY_CPU_AU1550: | |
341 | return au1550_gpio2_to_irq(gpio); | |
342 | case ALCHEMY_CPU_AU1200: | |
343 | return au1200_gpio2_to_irq(gpio); | |
344 | } | |
51e02b02 | 345 | return -ENXIO; |
51e02b02 ML |
346 | } |
347 | ||
348 | /**********************************************************************/ | |
349 | ||
51e02b02 ML |
350 | /* GPIO2 shared interrupts and control */ |
351 | ||
352 | static inline void __alchemy_gpio2_mod_int(int gpio2, int en) | |
353 | { | |
b7f720d6 ML |
354 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
355 | unsigned long r = __raw_readl(base + GPIO2_INTENABLE); | |
51e02b02 ML |
356 | if (en) |
357 | r |= 1 << gpio2; | |
358 | else | |
359 | r &= ~(1 << gpio2); | |
b7f720d6 ML |
360 | __raw_writel(r, base + GPIO2_INTENABLE); |
361 | wmb(); | |
51e02b02 ML |
362 | } |
363 | ||
364 | /** | |
365 | * alchemy_gpio2_enable_int - Enable a GPIO2 pins' shared irq contribution. | |
366 | * @gpio2: The GPIO2 pin to activate (200...215). | |
367 | * | |
368 | * GPIO208-215 have one shared interrupt line to the INTC. They are | |
369 | * and'ed with a per-pin enable bit and finally or'ed together to form | |
370 | * a single irq request (useful for active-high sources). | |
371 | * With this function, a pins' individual contribution to the int request | |
372 | * can be enabled. As with all other GPIO-based interrupts, the INTC | |
373 | * must be programmed to accept the GPIO208_215 interrupt as well. | |
374 | * | |
375 | * NOTE: Calling this macro is only necessary for GPIO208-215; all other | |
376 | * GPIO2-based interrupts have their own request to the INTC. Please | |
377 | * consult your Alchemy databook for more information! | |
378 | * | |
379 | * NOTE: On the Au1550, GPIOs 201-205 also have a shared interrupt request | |
380 | * line to the INTC, GPIO201_205. This function can be used for those | |
381 | * as well. | |
382 | * | |
383 | * NOTE: 'gpio2' parameter must be in range of the GPIO2 numberspace | |
384 | * (200-215 by default). No sanity checks are made, | |
385 | */ | |
386 | static inline void alchemy_gpio2_enable_int(int gpio2) | |
387 | { | |
388 | unsigned long flags; | |
389 | ||
390 | gpio2 -= ALCHEMY_GPIO2_BASE; | |
391 | ||
51e02b02 | 392 | /* Au1100/Au1500 have GPIO208-215 enable bits at 0..7 */ |
70f82f2c ML |
393 | switch (alchemy_get_cputype()) { |
394 | case ALCHEMY_CPU_AU1100: | |
395 | case ALCHEMY_CPU_AU1500: | |
396 | gpio2 -= 8; | |
397 | } | |
398 | ||
51e02b02 ML |
399 | local_irq_save(flags); |
400 | __alchemy_gpio2_mod_int(gpio2, 1); | |
401 | local_irq_restore(flags); | |
402 | } | |
403 | ||
404 | /** | |
405 | * alchemy_gpio2_disable_int - Disable a GPIO2 pins' shared irq contribution. | |
406 | * @gpio2: The GPIO2 pin to activate (200...215). | |
407 | * | |
408 | * see function alchemy_gpio2_enable_int() for more information. | |
409 | */ | |
410 | static inline void alchemy_gpio2_disable_int(int gpio2) | |
411 | { | |
412 | unsigned long flags; | |
413 | ||
414 | gpio2 -= ALCHEMY_GPIO2_BASE; | |
415 | ||
51e02b02 | 416 | /* Au1100/Au1500 have GPIO208-215 enable bits at 0..7 */ |
70f82f2c ML |
417 | switch (alchemy_get_cputype()) { |
418 | case ALCHEMY_CPU_AU1100: | |
419 | case ALCHEMY_CPU_AU1500: | |
420 | gpio2 -= 8; | |
421 | } | |
422 | ||
51e02b02 ML |
423 | local_irq_save(flags); |
424 | __alchemy_gpio2_mod_int(gpio2, 0); | |
425 | local_irq_restore(flags); | |
426 | } | |
427 | ||
428 | /** | |
429 | * alchemy_gpio2_enable - Activate GPIO2 block. | |
430 | * | |
70342287 | 431 | * The GPIO2 block must be enabled excplicitly to work. On systems |
51e02b02 ML |
432 | * where this isn't done by the bootloader, this macro can be used. |
433 | */ | |
434 | static inline void alchemy_gpio2_enable(void) | |
435 | { | |
b7f720d6 ML |
436 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
437 | __raw_writel(3, base + GPIO2_ENABLE); /* reset, clock enabled */ | |
438 | wmb(); | |
439 | __raw_writel(1, base + GPIO2_ENABLE); /* clock enabled */ | |
440 | wmb(); | |
51e02b02 ML |
441 | } |
442 | ||
443 | /** | |
444 | * alchemy_gpio2_disable - disable GPIO2 block. | |
445 | * | |
446 | * Disable and put GPIO2 block in low-power mode. | |
447 | */ | |
448 | static inline void alchemy_gpio2_disable(void) | |
449 | { | |
b7f720d6 ML |
450 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
451 | __raw_writel(2, base + GPIO2_ENABLE); /* reset, clock disabled */ | |
452 | wmb(); | |
51e02b02 ML |
453 | } |
454 | ||
455 | /**********************************************************************/ | |
456 | ||
457 | /* wrappers for on-chip gpios; can be used before gpio chips have been | |
458 | * registered with gpiolib. | |
459 | */ | |
460 | static inline int alchemy_gpio_direction_input(int gpio) | |
461 | { | |
462 | return (gpio >= ALCHEMY_GPIO2_BASE) ? | |
463 | alchemy_gpio2_direction_input(gpio) : | |
464 | alchemy_gpio1_direction_input(gpio); | |
465 | } | |
466 | ||
467 | static inline int alchemy_gpio_direction_output(int gpio, int v) | |
468 | { | |
469 | return (gpio >= ALCHEMY_GPIO2_BASE) ? | |
470 | alchemy_gpio2_direction_output(gpio, v) : | |
471 | alchemy_gpio1_direction_output(gpio, v); | |
472 | } | |
473 | ||
474 | static inline int alchemy_gpio_get_value(int gpio) | |
475 | { | |
476 | return (gpio >= ALCHEMY_GPIO2_BASE) ? | |
477 | alchemy_gpio2_get_value(gpio) : | |
478 | alchemy_gpio1_get_value(gpio); | |
479 | } | |
480 | ||
481 | static inline void alchemy_gpio_set_value(int gpio, int v) | |
482 | { | |
483 | if (gpio >= ALCHEMY_GPIO2_BASE) | |
484 | alchemy_gpio2_set_value(gpio, v); | |
485 | else | |
486 | alchemy_gpio1_set_value(gpio, v); | |
487 | } | |
488 | ||
489 | static inline int alchemy_gpio_is_valid(int gpio) | |
490 | { | |
491 | return (gpio >= ALCHEMY_GPIO2_BASE) ? | |
492 | alchemy_gpio2_is_valid(gpio) : | |
493 | alchemy_gpio1_is_valid(gpio); | |
494 | } | |
495 | ||
496 | static inline int alchemy_gpio_cansleep(int gpio) | |
497 | { | |
498 | return 0; /* Alchemy never gets tired */ | |
499 | } | |
500 | ||
501 | static inline int alchemy_gpio_to_irq(int gpio) | |
502 | { | |
503 | return (gpio >= ALCHEMY_GPIO2_BASE) ? | |
504 | alchemy_gpio2_to_irq(gpio) : | |
505 | alchemy_gpio1_to_irq(gpio); | |
506 | } | |
507 | ||
508 | static inline int alchemy_irq_to_gpio(int irq) | |
509 | { | |
70f82f2c ML |
510 | switch (alchemy_get_cputype()) { |
511 | case ALCHEMY_CPU_AU1000: | |
512 | return au1000_irq_to_gpio(irq); | |
513 | case ALCHEMY_CPU_AU1100: | |
514 | return au1100_irq_to_gpio(irq); | |
515 | case ALCHEMY_CPU_AU1500: | |
516 | return au1500_irq_to_gpio(irq); | |
517 | case ALCHEMY_CPU_AU1550: | |
518 | return au1550_irq_to_gpio(irq); | |
519 | case ALCHEMY_CPU_AU1200: | |
520 | return au1200_irq_to_gpio(irq); | |
521 | } | |
51e02b02 | 522 | return -ENXIO; |
51e02b02 ML |
523 | } |
524 | ||
525 | /**********************************************************************/ | |
526 | ||
527 | /* Linux gpio framework integration. | |
528 | * | |
529 | * 4 use cases of Au1000-Au1200 GPIOS: | |
530 | *(1) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=y: | |
531 | * Board must register gpiochips. | |
532 | *(2) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=n: | |
533 | * 2 (1 for Au1000) gpio_chips are registered. | |
534 | * | |
535 | *(3) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=y: | |
70342287 | 536 | * the boards' gpio.h must provide the linux gpio wrapper functions, |
51e02b02 ML |
537 | * |
538 | *(4) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=n: | |
539 | * inlinable gpio functions are provided which enable access to the | |
540 | * Au1000 gpios only by using the numbers straight out of the data- | |
541 | * sheets. | |
542 | ||
543 | * Cases 1 and 3 are intended for boards which want to provide their own | |
544 | * GPIO namespace and -operations (i.e. for example you have 8 GPIOs | |
545 | * which are in part provided by spare Au1000 GPIO pins and in part by | |
546 | * an external FPGA but you still want them to be accssible in linux | |
547 | * as gpio0-7. The board can of course use the alchemy_gpioX_* functions | |
548 | * as required). | |
549 | */ | |
550 | ||
551 | #ifndef CONFIG_GPIOLIB | |
552 | ||
ce1d43b9 | 553 | #ifdef CONFIG_ALCHEMY_GPIOINT_AU1000 |
51e02b02 ML |
554 | |
555 | #ifndef CONFIG_ALCHEMY_GPIO_INDIRECT /* case (4) */ | |
556 | ||
557 | static inline int gpio_direction_input(int gpio) | |
558 | { | |
559 | return alchemy_gpio_direction_input(gpio); | |
560 | } | |
561 | ||
562 | static inline int gpio_direction_output(int gpio, int v) | |
563 | { | |
564 | return alchemy_gpio_direction_output(gpio, v); | |
565 | } | |
566 | ||
567 | static inline int gpio_get_value(int gpio) | |
568 | { | |
569 | return alchemy_gpio_get_value(gpio); | |
570 | } | |
571 | ||
572 | static inline void gpio_set_value(int gpio, int v) | |
573 | { | |
574 | alchemy_gpio_set_value(gpio, v); | |
575 | } | |
576 | ||
c1e58a31 ML |
577 | static inline int gpio_get_value_cansleep(unsigned gpio) |
578 | { | |
579 | return gpio_get_value(gpio); | |
580 | } | |
581 | ||
582 | static inline void gpio_set_value_cansleep(unsigned gpio, int value) | |
583 | { | |
584 | gpio_set_value(gpio, value); | |
585 | } | |
586 | ||
51e02b02 ML |
587 | static inline int gpio_is_valid(int gpio) |
588 | { | |
589 | return alchemy_gpio_is_valid(gpio); | |
590 | } | |
591 | ||
592 | static inline int gpio_cansleep(int gpio) | |
593 | { | |
594 | return alchemy_gpio_cansleep(gpio); | |
595 | } | |
596 | ||
597 | static inline int gpio_to_irq(int gpio) | |
598 | { | |
599 | return alchemy_gpio_to_irq(gpio); | |
600 | } | |
601 | ||
602 | static inline int irq_to_gpio(int irq) | |
603 | { | |
604 | return alchemy_irq_to_gpio(irq); | |
605 | } | |
606 | ||
75f45316 ML |
607 | static inline int gpio_request(unsigned gpio, const char *label) |
608 | { | |
609 | return 0; | |
610 | } | |
611 | ||
c1e58a31 ML |
612 | static inline int gpio_request_one(unsigned gpio, |
613 | unsigned long flags, const char *label) | |
614 | { | |
615 | return 0; | |
616 | } | |
617 | ||
618 | static inline int gpio_request_array(struct gpio *array, size_t num) | |
619 | { | |
620 | return 0; | |
621 | } | |
622 | ||
75f45316 ML |
623 | static inline void gpio_free(unsigned gpio) |
624 | { | |
625 | } | |
626 | ||
c1e58a31 ML |
627 | static inline void gpio_free_array(struct gpio *array, size_t num) |
628 | { | |
629 | } | |
630 | ||
631 | static inline int gpio_set_debounce(unsigned gpio, unsigned debounce) | |
632 | { | |
633 | return -ENOSYS; | |
634 | } | |
635 | ||
636 | static inline int gpio_export(unsigned gpio, bool direction_may_change) | |
637 | { | |
638 | return -ENOSYS; | |
639 | } | |
640 | ||
641 | static inline int gpio_export_link(struct device *dev, const char *name, | |
642 | unsigned gpio) | |
643 | { | |
644 | return -ENOSYS; | |
645 | } | |
646 | ||
647 | static inline int gpio_sysfs_set_active_low(unsigned gpio, int value) | |
648 | { | |
649 | return -ENOSYS; | |
650 | } | |
651 | ||
652 | static inline void gpio_unexport(unsigned gpio) | |
653 | { | |
654 | } | |
655 | ||
51e02b02 ML |
656 | #endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */ |
657 | ||
ce1d43b9 | 658 | #endif /* CONFIG_ALCHEMY_GPIOINT_AU1000 */ |
51e02b02 ML |
659 | |
660 | #endif /* !CONFIG_GPIOLIB */ | |
661 | ||
662 | #endif /* _ALCHEMY_GPIO_AU1000_H_ */ |