1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * GPIO functions for Au1000, Au1500, Au1100, Au1550, Au1200
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright (c) 2009 Manuel Lauss.
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Licensed under the terms outlined in the file COPYING.
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #ifndef _ALCHEMY_GPIO_AU1000_H_
10*4882a593Smuzhiyun #define _ALCHEMY_GPIO_AU1000_H_
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <asm/mach-au1x00/au1000.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun /* The default GPIO numberspace as documented in the Alchemy manuals.
15*4882a593Smuzhiyun * GPIO0-31 from GPIO1 block, GPIO200-215 from GPIO2 block.
16*4882a593Smuzhiyun */
17*4882a593Smuzhiyun #define ALCHEMY_GPIO1_BASE 0
18*4882a593Smuzhiyun #define ALCHEMY_GPIO2_BASE 200
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun #define ALCHEMY_GPIO1_NUM 32
21*4882a593Smuzhiyun #define ALCHEMY_GPIO2_NUM 16
22*4882a593Smuzhiyun #define ALCHEMY_GPIO1_MAX (ALCHEMY_GPIO1_BASE + ALCHEMY_GPIO1_NUM - 1)
23*4882a593Smuzhiyun #define ALCHEMY_GPIO2_MAX (ALCHEMY_GPIO2_BASE + ALCHEMY_GPIO2_NUM - 1)
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun #define MAKE_IRQ(intc, off) (AU1000_INTC##intc##_INT_BASE + (off))
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun /* GPIO1 registers within SYS_ area */
28*4882a593Smuzhiyun #define AU1000_SYS_TRIOUTRD 0x100
29*4882a593Smuzhiyun #define AU1000_SYS_TRIOUTCLR 0x100
30*4882a593Smuzhiyun #define AU1000_SYS_OUTPUTRD 0x108
31*4882a593Smuzhiyun #define AU1000_SYS_OUTPUTSET 0x108
32*4882a593Smuzhiyun #define AU1000_SYS_OUTPUTCLR 0x10C
33*4882a593Smuzhiyun #define AU1000_SYS_PINSTATERD 0x110
34*4882a593Smuzhiyun #define AU1000_SYS_PININPUTEN 0x110
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun /* register offsets within GPIO2 block */
37*4882a593Smuzhiyun #define AU1000_GPIO2_DIR 0x00
38*4882a593Smuzhiyun #define AU1000_GPIO2_OUTPUT 0x08
39*4882a593Smuzhiyun #define AU1000_GPIO2_PINSTATE 0x0C
40*4882a593Smuzhiyun #define AU1000_GPIO2_INTENABLE 0x10
41*4882a593Smuzhiyun #define AU1000_GPIO2_ENABLE 0x14
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun struct gpio;
44*4882a593Smuzhiyun
au1000_gpio1_to_irq(int gpio)45*4882a593Smuzhiyun static inline int au1000_gpio1_to_irq(int gpio)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun return MAKE_IRQ(1, gpio - ALCHEMY_GPIO1_BASE);
48*4882a593Smuzhiyun }
49*4882a593Smuzhiyun
au1000_gpio2_to_irq(int gpio)50*4882a593Smuzhiyun static inline int au1000_gpio2_to_irq(int gpio)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun return -ENXIO;
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun
au1000_irq_to_gpio(int irq)55*4882a593Smuzhiyun static inline int au1000_irq_to_gpio(int irq)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun if ((irq >= AU1000_GPIO0_INT) && (irq <= AU1000_GPIO31_INT))
58*4882a593Smuzhiyun return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO0_INT) + 0;
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun return -ENXIO;
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun
au1500_gpio1_to_irq(int gpio)63*4882a593Smuzhiyun static inline int au1500_gpio1_to_irq(int gpio)
64*4882a593Smuzhiyun {
65*4882a593Smuzhiyun gpio -= ALCHEMY_GPIO1_BASE;
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun switch (gpio) {
68*4882a593Smuzhiyun case 0 ... 15:
69*4882a593Smuzhiyun case 20:
70*4882a593Smuzhiyun case 23 ... 28: return MAKE_IRQ(1, gpio);
71*4882a593Smuzhiyun }
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun return -ENXIO;
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun
au1500_gpio2_to_irq(int gpio)76*4882a593Smuzhiyun static inline int au1500_gpio2_to_irq(int gpio)
77*4882a593Smuzhiyun {
78*4882a593Smuzhiyun gpio -= ALCHEMY_GPIO2_BASE;
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun switch (gpio) {
81*4882a593Smuzhiyun case 0 ... 3: return MAKE_IRQ(1, 16 + gpio - 0);
82*4882a593Smuzhiyun case 4 ... 5: return MAKE_IRQ(1, 21 + gpio - 4);
83*4882a593Smuzhiyun case 6 ... 7: return MAKE_IRQ(1, 29 + gpio - 6);
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun return -ENXIO;
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun
au1500_irq_to_gpio(int irq)89*4882a593Smuzhiyun static inline int au1500_irq_to_gpio(int irq)
90*4882a593Smuzhiyun {
91*4882a593Smuzhiyun switch (irq) {
92*4882a593Smuzhiyun case AU1500_GPIO0_INT ... AU1500_GPIO15_INT:
93*4882a593Smuzhiyun case AU1500_GPIO20_INT:
94*4882a593Smuzhiyun case AU1500_GPIO23_INT ... AU1500_GPIO28_INT:
95*4882a593Smuzhiyun return ALCHEMY_GPIO1_BASE + (irq - AU1500_GPIO0_INT) + 0;
96*4882a593Smuzhiyun case AU1500_GPIO200_INT ... AU1500_GPIO203_INT:
97*4882a593Smuzhiyun return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO200_INT) + 0;
98*4882a593Smuzhiyun case AU1500_GPIO204_INT ... AU1500_GPIO205_INT:
99*4882a593Smuzhiyun return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO204_INT) + 4;
100*4882a593Smuzhiyun case AU1500_GPIO206_INT ... AU1500_GPIO207_INT:
101*4882a593Smuzhiyun return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO206_INT) + 6;
102*4882a593Smuzhiyun case AU1500_GPIO208_215_INT:
103*4882a593Smuzhiyun return ALCHEMY_GPIO2_BASE + 8;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun return -ENXIO;
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun
au1100_gpio1_to_irq(int gpio)109*4882a593Smuzhiyun static inline int au1100_gpio1_to_irq(int gpio)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun return MAKE_IRQ(1, gpio - ALCHEMY_GPIO1_BASE);
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun
au1100_gpio2_to_irq(int gpio)114*4882a593Smuzhiyun static inline int au1100_gpio2_to_irq(int gpio)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun gpio -= ALCHEMY_GPIO2_BASE;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun if ((gpio >= 8) && (gpio <= 15))
119*4882a593Smuzhiyun return MAKE_IRQ(0, 29); /* shared GPIO208_215 */
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun return -ENXIO;
122*4882a593Smuzhiyun }
123*4882a593Smuzhiyun
au1100_irq_to_gpio(int irq)124*4882a593Smuzhiyun static inline int au1100_irq_to_gpio(int irq)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun switch (irq) {
127*4882a593Smuzhiyun case AU1100_GPIO0_INT ... AU1100_GPIO31_INT:
128*4882a593Smuzhiyun return ALCHEMY_GPIO1_BASE + (irq - AU1100_GPIO0_INT) + 0;
129*4882a593Smuzhiyun case AU1100_GPIO208_215_INT:
130*4882a593Smuzhiyun return ALCHEMY_GPIO2_BASE + 8;
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun return -ENXIO;
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
au1550_gpio1_to_irq(int gpio)136*4882a593Smuzhiyun static inline int au1550_gpio1_to_irq(int gpio)
137*4882a593Smuzhiyun {
138*4882a593Smuzhiyun gpio -= ALCHEMY_GPIO1_BASE;
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun switch (gpio) {
141*4882a593Smuzhiyun case 0 ... 15:
142*4882a593Smuzhiyun case 20 ... 28: return MAKE_IRQ(1, gpio);
143*4882a593Smuzhiyun case 16 ... 17: return MAKE_IRQ(1, 18 + gpio - 16);
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun return -ENXIO;
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun
au1550_gpio2_to_irq(int gpio)149*4882a593Smuzhiyun static inline int au1550_gpio2_to_irq(int gpio)
150*4882a593Smuzhiyun {
151*4882a593Smuzhiyun gpio -= ALCHEMY_GPIO2_BASE;
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun switch (gpio) {
154*4882a593Smuzhiyun case 0: return MAKE_IRQ(1, 16);
155*4882a593Smuzhiyun case 1 ... 5: return MAKE_IRQ(1, 17); /* shared GPIO201_205 */
156*4882a593Smuzhiyun case 6 ... 7: return MAKE_IRQ(1, 29 + gpio - 6);
157*4882a593Smuzhiyun case 8 ... 15: return MAKE_IRQ(1, 31); /* shared GPIO208_215 */
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun return -ENXIO;
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun
au1550_irq_to_gpio(int irq)163*4882a593Smuzhiyun static inline int au1550_irq_to_gpio(int irq)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun switch (irq) {
166*4882a593Smuzhiyun case AU1550_GPIO0_INT ... AU1550_GPIO15_INT:
167*4882a593Smuzhiyun return ALCHEMY_GPIO1_BASE + (irq - AU1550_GPIO0_INT) + 0;
168*4882a593Smuzhiyun case AU1550_GPIO200_INT:
169*4882a593Smuzhiyun case AU1550_GPIO201_205_INT:
170*4882a593Smuzhiyun return ALCHEMY_GPIO2_BASE + (irq - AU1550_GPIO200_INT) + 0;
171*4882a593Smuzhiyun case AU1550_GPIO16_INT ... AU1550_GPIO28_INT:
172*4882a593Smuzhiyun return ALCHEMY_GPIO1_BASE + (irq - AU1550_GPIO16_INT) + 16;
173*4882a593Smuzhiyun case AU1550_GPIO206_INT ... AU1550_GPIO208_215_INT:
174*4882a593Smuzhiyun return ALCHEMY_GPIO2_BASE + (irq - AU1550_GPIO206_INT) + 6;
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun return -ENXIO;
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun
au1200_gpio1_to_irq(int gpio)180*4882a593Smuzhiyun static inline int au1200_gpio1_to_irq(int gpio)
181*4882a593Smuzhiyun {
182*4882a593Smuzhiyun return MAKE_IRQ(1, gpio - ALCHEMY_GPIO1_BASE);
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun
au1200_gpio2_to_irq(int gpio)185*4882a593Smuzhiyun static inline int au1200_gpio2_to_irq(int gpio)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun gpio -= ALCHEMY_GPIO2_BASE;
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun switch (gpio) {
190*4882a593Smuzhiyun case 0 ... 2: return MAKE_IRQ(0, 5 + gpio - 0);
191*4882a593Smuzhiyun case 3: return MAKE_IRQ(0, 22);
192*4882a593Smuzhiyun case 4 ... 7: return MAKE_IRQ(0, 24 + gpio - 4);
193*4882a593Smuzhiyun case 8 ... 15: return MAKE_IRQ(0, 28); /* shared GPIO208_215 */
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun return -ENXIO;
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun
au1200_irq_to_gpio(int irq)199*4882a593Smuzhiyun static inline int au1200_irq_to_gpio(int irq)
200*4882a593Smuzhiyun {
201*4882a593Smuzhiyun switch (irq) {
202*4882a593Smuzhiyun case AU1200_GPIO0_INT ... AU1200_GPIO31_INT:
203*4882a593Smuzhiyun return ALCHEMY_GPIO1_BASE + (irq - AU1200_GPIO0_INT) + 0;
204*4882a593Smuzhiyun case AU1200_GPIO200_INT ... AU1200_GPIO202_INT:
205*4882a593Smuzhiyun return ALCHEMY_GPIO2_BASE + (irq - AU1200_GPIO200_INT) + 0;
206*4882a593Smuzhiyun case AU1200_GPIO203_INT:
207*4882a593Smuzhiyun return ALCHEMY_GPIO2_BASE + 3;
208*4882a593Smuzhiyun case AU1200_GPIO204_INT ... AU1200_GPIO208_215_INT:
209*4882a593Smuzhiyun return ALCHEMY_GPIO2_BASE + (irq - AU1200_GPIO204_INT) + 4;
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun return -ENXIO;
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun /*
216*4882a593Smuzhiyun * GPIO1 block macros for common linux gpio functions.
217*4882a593Smuzhiyun */
alchemy_gpio1_set_value(int gpio,int v)218*4882a593Smuzhiyun static inline void alchemy_gpio1_set_value(int gpio, int v)
219*4882a593Smuzhiyun {
220*4882a593Smuzhiyun unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
221*4882a593Smuzhiyun unsigned long r = v ? AU1000_SYS_OUTPUTSET : AU1000_SYS_OUTPUTCLR;
222*4882a593Smuzhiyun alchemy_wrsys(mask, r);
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun
alchemy_gpio1_get_value(int gpio)225*4882a593Smuzhiyun static inline int alchemy_gpio1_get_value(int gpio)
226*4882a593Smuzhiyun {
227*4882a593Smuzhiyun unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
228*4882a593Smuzhiyun return alchemy_rdsys(AU1000_SYS_PINSTATERD) & mask;
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun
alchemy_gpio1_direction_input(int gpio)231*4882a593Smuzhiyun static inline int alchemy_gpio1_direction_input(int gpio)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
234*4882a593Smuzhiyun alchemy_wrsys(mask, AU1000_SYS_TRIOUTCLR);
235*4882a593Smuzhiyun return 0;
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun
alchemy_gpio1_direction_output(int gpio,int v)238*4882a593Smuzhiyun static inline int alchemy_gpio1_direction_output(int gpio, int v)
239*4882a593Smuzhiyun {
240*4882a593Smuzhiyun /* hardware switches to "output" mode when one of the two
241*4882a593Smuzhiyun * "set_value" registers is accessed.
242*4882a593Smuzhiyun */
243*4882a593Smuzhiyun alchemy_gpio1_set_value(gpio, v);
244*4882a593Smuzhiyun return 0;
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun
alchemy_gpio1_is_valid(int gpio)247*4882a593Smuzhiyun static inline int alchemy_gpio1_is_valid(int gpio)
248*4882a593Smuzhiyun {
249*4882a593Smuzhiyun return ((gpio >= ALCHEMY_GPIO1_BASE) && (gpio <= ALCHEMY_GPIO1_MAX));
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun
alchemy_gpio1_to_irq(int gpio)252*4882a593Smuzhiyun static inline int alchemy_gpio1_to_irq(int gpio)
253*4882a593Smuzhiyun {
254*4882a593Smuzhiyun switch (alchemy_get_cputype()) {
255*4882a593Smuzhiyun case ALCHEMY_CPU_AU1000:
256*4882a593Smuzhiyun return au1000_gpio1_to_irq(gpio);
257*4882a593Smuzhiyun case ALCHEMY_CPU_AU1100:
258*4882a593Smuzhiyun return au1100_gpio1_to_irq(gpio);
259*4882a593Smuzhiyun case ALCHEMY_CPU_AU1500:
260*4882a593Smuzhiyun return au1500_gpio1_to_irq(gpio);
261*4882a593Smuzhiyun case ALCHEMY_CPU_AU1550:
262*4882a593Smuzhiyun return au1550_gpio1_to_irq(gpio);
263*4882a593Smuzhiyun case ALCHEMY_CPU_AU1200:
264*4882a593Smuzhiyun return au1200_gpio1_to_irq(gpio);
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun return -ENXIO;
267*4882a593Smuzhiyun }
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun /* On Au1000, Au1500 and Au1100 GPIOs won't work as inputs before
270*4882a593Smuzhiyun * SYS_PININPUTEN is written to at least once. On Au1550/Au1200/Au1300 this
271*4882a593Smuzhiyun * register enables use of GPIOs as wake source.
272*4882a593Smuzhiyun */
alchemy_gpio1_input_enable(void)273*4882a593Smuzhiyun static inline void alchemy_gpio1_input_enable(void)
274*4882a593Smuzhiyun {
275*4882a593Smuzhiyun void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
276*4882a593Smuzhiyun __raw_writel(0, base + 0x110); /* the write op is key */
277*4882a593Smuzhiyun wmb();
278*4882a593Smuzhiyun }
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun /*
281*4882a593Smuzhiyun * GPIO2 block macros for common linux GPIO functions. The 'gpio'
282*4882a593Smuzhiyun * parameter must be in range of ALCHEMY_GPIO2_BASE..ALCHEMY_GPIO2_MAX.
283*4882a593Smuzhiyun */
__alchemy_gpio2_mod_dir(int gpio,int to_out)284*4882a593Smuzhiyun static inline void __alchemy_gpio2_mod_dir(int gpio, int to_out)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
287*4882a593Smuzhiyun unsigned long mask = 1 << (gpio - ALCHEMY_GPIO2_BASE);
288*4882a593Smuzhiyun unsigned long d = __raw_readl(base + AU1000_GPIO2_DIR);
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun if (to_out)
291*4882a593Smuzhiyun d |= mask;
292*4882a593Smuzhiyun else
293*4882a593Smuzhiyun d &= ~mask;
294*4882a593Smuzhiyun __raw_writel(d, base + AU1000_GPIO2_DIR);
295*4882a593Smuzhiyun wmb();
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun
alchemy_gpio2_set_value(int gpio,int v)298*4882a593Smuzhiyun static inline void alchemy_gpio2_set_value(int gpio, int v)
299*4882a593Smuzhiyun {
300*4882a593Smuzhiyun void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
301*4882a593Smuzhiyun unsigned long mask;
302*4882a593Smuzhiyun mask = ((v) ? 0x00010001 : 0x00010000) << (gpio - ALCHEMY_GPIO2_BASE);
303*4882a593Smuzhiyun __raw_writel(mask, base + AU1000_GPIO2_OUTPUT);
304*4882a593Smuzhiyun wmb();
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun
alchemy_gpio2_get_value(int gpio)307*4882a593Smuzhiyun static inline int alchemy_gpio2_get_value(int gpio)
308*4882a593Smuzhiyun {
309*4882a593Smuzhiyun void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
310*4882a593Smuzhiyun return __raw_readl(base + AU1000_GPIO2_PINSTATE) &
311*4882a593Smuzhiyun (1 << (gpio - ALCHEMY_GPIO2_BASE));
312*4882a593Smuzhiyun }
313*4882a593Smuzhiyun
alchemy_gpio2_direction_input(int gpio)314*4882a593Smuzhiyun static inline int alchemy_gpio2_direction_input(int gpio)
315*4882a593Smuzhiyun {
316*4882a593Smuzhiyun unsigned long flags;
317*4882a593Smuzhiyun local_irq_save(flags);
318*4882a593Smuzhiyun __alchemy_gpio2_mod_dir(gpio, 0);
319*4882a593Smuzhiyun local_irq_restore(flags);
320*4882a593Smuzhiyun return 0;
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun
alchemy_gpio2_direction_output(int gpio,int v)323*4882a593Smuzhiyun static inline int alchemy_gpio2_direction_output(int gpio, int v)
324*4882a593Smuzhiyun {
325*4882a593Smuzhiyun unsigned long flags;
326*4882a593Smuzhiyun alchemy_gpio2_set_value(gpio, v);
327*4882a593Smuzhiyun local_irq_save(flags);
328*4882a593Smuzhiyun __alchemy_gpio2_mod_dir(gpio, 1);
329*4882a593Smuzhiyun local_irq_restore(flags);
330*4882a593Smuzhiyun return 0;
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun
alchemy_gpio2_is_valid(int gpio)333*4882a593Smuzhiyun static inline int alchemy_gpio2_is_valid(int gpio)
334*4882a593Smuzhiyun {
335*4882a593Smuzhiyun return ((gpio >= ALCHEMY_GPIO2_BASE) && (gpio <= ALCHEMY_GPIO2_MAX));
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun
alchemy_gpio2_to_irq(int gpio)338*4882a593Smuzhiyun static inline int alchemy_gpio2_to_irq(int gpio)
339*4882a593Smuzhiyun {
340*4882a593Smuzhiyun switch (alchemy_get_cputype()) {
341*4882a593Smuzhiyun case ALCHEMY_CPU_AU1000:
342*4882a593Smuzhiyun return au1000_gpio2_to_irq(gpio);
343*4882a593Smuzhiyun case ALCHEMY_CPU_AU1100:
344*4882a593Smuzhiyun return au1100_gpio2_to_irq(gpio);
345*4882a593Smuzhiyun case ALCHEMY_CPU_AU1500:
346*4882a593Smuzhiyun return au1500_gpio2_to_irq(gpio);
347*4882a593Smuzhiyun case ALCHEMY_CPU_AU1550:
348*4882a593Smuzhiyun return au1550_gpio2_to_irq(gpio);
349*4882a593Smuzhiyun case ALCHEMY_CPU_AU1200:
350*4882a593Smuzhiyun return au1200_gpio2_to_irq(gpio);
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun return -ENXIO;
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun /**********************************************************************/
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun /* GPIO2 shared interrupts and control */
358*4882a593Smuzhiyun
__alchemy_gpio2_mod_int(int gpio2,int en)359*4882a593Smuzhiyun static inline void __alchemy_gpio2_mod_int(int gpio2, int en)
360*4882a593Smuzhiyun {
361*4882a593Smuzhiyun void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
362*4882a593Smuzhiyun unsigned long r = __raw_readl(base + AU1000_GPIO2_INTENABLE);
363*4882a593Smuzhiyun if (en)
364*4882a593Smuzhiyun r |= 1 << gpio2;
365*4882a593Smuzhiyun else
366*4882a593Smuzhiyun r &= ~(1 << gpio2);
367*4882a593Smuzhiyun __raw_writel(r, base + AU1000_GPIO2_INTENABLE);
368*4882a593Smuzhiyun wmb();
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun /**
372*4882a593Smuzhiyun * alchemy_gpio2_enable_int - Enable a GPIO2 pins' shared irq contribution.
373*4882a593Smuzhiyun * @gpio2: The GPIO2 pin to activate (200...215).
374*4882a593Smuzhiyun *
375*4882a593Smuzhiyun * GPIO208-215 have one shared interrupt line to the INTC. They are
376*4882a593Smuzhiyun * and'ed with a per-pin enable bit and finally or'ed together to form
377*4882a593Smuzhiyun * a single irq request (useful for active-high sources).
378*4882a593Smuzhiyun * With this function, a pins' individual contribution to the int request
379*4882a593Smuzhiyun * can be enabled. As with all other GPIO-based interrupts, the INTC
380*4882a593Smuzhiyun * must be programmed to accept the GPIO208_215 interrupt as well.
381*4882a593Smuzhiyun *
382*4882a593Smuzhiyun * NOTE: Calling this macro is only necessary for GPIO208-215; all other
383*4882a593Smuzhiyun * GPIO2-based interrupts have their own request to the INTC. Please
384*4882a593Smuzhiyun * consult your Alchemy databook for more information!
385*4882a593Smuzhiyun *
386*4882a593Smuzhiyun * NOTE: On the Au1550, GPIOs 201-205 also have a shared interrupt request
387*4882a593Smuzhiyun * line to the INTC, GPIO201_205. This function can be used for those
388*4882a593Smuzhiyun * as well.
389*4882a593Smuzhiyun *
390*4882a593Smuzhiyun * NOTE: 'gpio2' parameter must be in range of the GPIO2 numberspace
391*4882a593Smuzhiyun * (200-215 by default). No sanity checks are made,
392*4882a593Smuzhiyun */
alchemy_gpio2_enable_int(int gpio2)393*4882a593Smuzhiyun static inline void alchemy_gpio2_enable_int(int gpio2)
394*4882a593Smuzhiyun {
395*4882a593Smuzhiyun unsigned long flags;
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun gpio2 -= ALCHEMY_GPIO2_BASE;
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun /* Au1100/Au1500 have GPIO208-215 enable bits at 0..7 */
400*4882a593Smuzhiyun switch (alchemy_get_cputype()) {
401*4882a593Smuzhiyun case ALCHEMY_CPU_AU1100:
402*4882a593Smuzhiyun case ALCHEMY_CPU_AU1500:
403*4882a593Smuzhiyun gpio2 -= 8;
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun local_irq_save(flags);
407*4882a593Smuzhiyun __alchemy_gpio2_mod_int(gpio2, 1);
408*4882a593Smuzhiyun local_irq_restore(flags);
409*4882a593Smuzhiyun }
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun /**
412*4882a593Smuzhiyun * alchemy_gpio2_disable_int - Disable a GPIO2 pins' shared irq contribution.
413*4882a593Smuzhiyun * @gpio2: The GPIO2 pin to activate (200...215).
414*4882a593Smuzhiyun *
415*4882a593Smuzhiyun * see function alchemy_gpio2_enable_int() for more information.
416*4882a593Smuzhiyun */
alchemy_gpio2_disable_int(int gpio2)417*4882a593Smuzhiyun static inline void alchemy_gpio2_disable_int(int gpio2)
418*4882a593Smuzhiyun {
419*4882a593Smuzhiyun unsigned long flags;
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun gpio2 -= ALCHEMY_GPIO2_BASE;
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun /* Au1100/Au1500 have GPIO208-215 enable bits at 0..7 */
424*4882a593Smuzhiyun switch (alchemy_get_cputype()) {
425*4882a593Smuzhiyun case ALCHEMY_CPU_AU1100:
426*4882a593Smuzhiyun case ALCHEMY_CPU_AU1500:
427*4882a593Smuzhiyun gpio2 -= 8;
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun local_irq_save(flags);
431*4882a593Smuzhiyun __alchemy_gpio2_mod_int(gpio2, 0);
432*4882a593Smuzhiyun local_irq_restore(flags);
433*4882a593Smuzhiyun }
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun /**
436*4882a593Smuzhiyun * alchemy_gpio2_enable - Activate GPIO2 block.
437*4882a593Smuzhiyun *
438*4882a593Smuzhiyun * The GPIO2 block must be enabled excplicitly to work. On systems
439*4882a593Smuzhiyun * where this isn't done by the bootloader, this macro can be used.
440*4882a593Smuzhiyun */
alchemy_gpio2_enable(void)441*4882a593Smuzhiyun static inline void alchemy_gpio2_enable(void)
442*4882a593Smuzhiyun {
443*4882a593Smuzhiyun void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
444*4882a593Smuzhiyun __raw_writel(3, base + AU1000_GPIO2_ENABLE); /* reset, clock enabled */
445*4882a593Smuzhiyun wmb();
446*4882a593Smuzhiyun __raw_writel(1, base + AU1000_GPIO2_ENABLE); /* clock enabled */
447*4882a593Smuzhiyun wmb();
448*4882a593Smuzhiyun }
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun /**
451*4882a593Smuzhiyun * alchemy_gpio2_disable - disable GPIO2 block.
452*4882a593Smuzhiyun *
453*4882a593Smuzhiyun * Disable and put GPIO2 block in low-power mode.
454*4882a593Smuzhiyun */
alchemy_gpio2_disable(void)455*4882a593Smuzhiyun static inline void alchemy_gpio2_disable(void)
456*4882a593Smuzhiyun {
457*4882a593Smuzhiyun void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
458*4882a593Smuzhiyun __raw_writel(2, base + AU1000_GPIO2_ENABLE); /* reset, clock disabled */
459*4882a593Smuzhiyun wmb();
460*4882a593Smuzhiyun }
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun /**********************************************************************/
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun /* wrappers for on-chip gpios; can be used before gpio chips have been
465*4882a593Smuzhiyun * registered with gpiolib.
466*4882a593Smuzhiyun */
alchemy_gpio_direction_input(int gpio)467*4882a593Smuzhiyun static inline int alchemy_gpio_direction_input(int gpio)
468*4882a593Smuzhiyun {
469*4882a593Smuzhiyun return (gpio >= ALCHEMY_GPIO2_BASE) ?
470*4882a593Smuzhiyun alchemy_gpio2_direction_input(gpio) :
471*4882a593Smuzhiyun alchemy_gpio1_direction_input(gpio);
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun
alchemy_gpio_direction_output(int gpio,int v)474*4882a593Smuzhiyun static inline int alchemy_gpio_direction_output(int gpio, int v)
475*4882a593Smuzhiyun {
476*4882a593Smuzhiyun return (gpio >= ALCHEMY_GPIO2_BASE) ?
477*4882a593Smuzhiyun alchemy_gpio2_direction_output(gpio, v) :
478*4882a593Smuzhiyun alchemy_gpio1_direction_output(gpio, v);
479*4882a593Smuzhiyun }
480*4882a593Smuzhiyun
alchemy_gpio_get_value(int gpio)481*4882a593Smuzhiyun static inline int alchemy_gpio_get_value(int gpio)
482*4882a593Smuzhiyun {
483*4882a593Smuzhiyun return (gpio >= ALCHEMY_GPIO2_BASE) ?
484*4882a593Smuzhiyun alchemy_gpio2_get_value(gpio) :
485*4882a593Smuzhiyun alchemy_gpio1_get_value(gpio);
486*4882a593Smuzhiyun }
487*4882a593Smuzhiyun
alchemy_gpio_set_value(int gpio,int v)488*4882a593Smuzhiyun static inline void alchemy_gpio_set_value(int gpio, int v)
489*4882a593Smuzhiyun {
490*4882a593Smuzhiyun if (gpio >= ALCHEMY_GPIO2_BASE)
491*4882a593Smuzhiyun alchemy_gpio2_set_value(gpio, v);
492*4882a593Smuzhiyun else
493*4882a593Smuzhiyun alchemy_gpio1_set_value(gpio, v);
494*4882a593Smuzhiyun }
495*4882a593Smuzhiyun
alchemy_gpio_is_valid(int gpio)496*4882a593Smuzhiyun static inline int alchemy_gpio_is_valid(int gpio)
497*4882a593Smuzhiyun {
498*4882a593Smuzhiyun return (gpio >= ALCHEMY_GPIO2_BASE) ?
499*4882a593Smuzhiyun alchemy_gpio2_is_valid(gpio) :
500*4882a593Smuzhiyun alchemy_gpio1_is_valid(gpio);
501*4882a593Smuzhiyun }
502*4882a593Smuzhiyun
alchemy_gpio_cansleep(int gpio)503*4882a593Smuzhiyun static inline int alchemy_gpio_cansleep(int gpio)
504*4882a593Smuzhiyun {
505*4882a593Smuzhiyun return 0; /* Alchemy never gets tired */
506*4882a593Smuzhiyun }
507*4882a593Smuzhiyun
alchemy_gpio_to_irq(int gpio)508*4882a593Smuzhiyun static inline int alchemy_gpio_to_irq(int gpio)
509*4882a593Smuzhiyun {
510*4882a593Smuzhiyun return (gpio >= ALCHEMY_GPIO2_BASE) ?
511*4882a593Smuzhiyun alchemy_gpio2_to_irq(gpio) :
512*4882a593Smuzhiyun alchemy_gpio1_to_irq(gpio);
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun
alchemy_irq_to_gpio(int irq)515*4882a593Smuzhiyun static inline int alchemy_irq_to_gpio(int irq)
516*4882a593Smuzhiyun {
517*4882a593Smuzhiyun switch (alchemy_get_cputype()) {
518*4882a593Smuzhiyun case ALCHEMY_CPU_AU1000:
519*4882a593Smuzhiyun return au1000_irq_to_gpio(irq);
520*4882a593Smuzhiyun case ALCHEMY_CPU_AU1100:
521*4882a593Smuzhiyun return au1100_irq_to_gpio(irq);
522*4882a593Smuzhiyun case ALCHEMY_CPU_AU1500:
523*4882a593Smuzhiyun return au1500_irq_to_gpio(irq);
524*4882a593Smuzhiyun case ALCHEMY_CPU_AU1550:
525*4882a593Smuzhiyun return au1550_irq_to_gpio(irq);
526*4882a593Smuzhiyun case ALCHEMY_CPU_AU1200:
527*4882a593Smuzhiyun return au1200_irq_to_gpio(irq);
528*4882a593Smuzhiyun }
529*4882a593Smuzhiyun return -ENXIO;
530*4882a593Smuzhiyun }
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun #endif /* _ALCHEMY_GPIO_AU1000_H_ */
533