add gpio support to atheros, fixes #1861, thanks Othello
[openwrt.git] / target / linux / atheros / files / arch / mips / atheros / gpio.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2003 Atheros Communications, Inc.,  All Rights Reserved.
7  * Copyright (C) 2006 FON Technology, SL.
8  * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
9  * Copyright (C) 2007 Othello <bach_ag@hotmail.com>
10  */
11
12 /*
13  * Support for AR531X GPIO -- General Purpose Input/Output Pins
14  */
15
16 #include <linux/autoconf.h>
17 #include <linux/init.h>
18 #include <linux/interrupt.h>
19 #include <linux/types.h>
20 #include <linux/module.h>
21 #include <linux/delay.h>
22 #include <linux/platform_device.h>
23 #include <linux/irq.h>
24
25 #include <asm/addrspace.h>
26 #include <asm/io.h>
27 #include <asm/irq_cpu.h>
28 #include <asm/gpio.h>
29 #include "ar531x.h"
30 /* 
31    GPIO Interrupt Support
32       Make use of request_irq() and the function gpio_to_irq() to trap gpio events
33  */
34
35 /* Global variables */
36 static u32 ar531x_gpio_intr_Mask = 0;
37 /*
38     AR5312: I don't have any devices with this chip. Assumed to be similar to AR5215
39     will someone who has one try the code and remove this message if it works?
40  */
41
42 #ifdef CONFIG_ATHEROS_AR5315
43 /*
44     AR5315: Up to 2 GPIO pins may be monitored simultaneously
45     specifying more pins if you already have 2 will not have any effect
46         however, the excess gpio irqs will also be triggered if a valid gpio being monitored triggers
47     only high, low or edge triggered interrupt supported
48  */
49 static unsigned int ar5315_gpio_set_type_gpio = 0;
50 static unsigned int ar5315_gpio_set_type_lvl = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
51 #endif
52
53 #ifdef CONFIG_ATHEROS_AR5312
54 /* Enable the specified AR5312_GPIO_IRQ interrupt */
55 static void ar5312_gpio_intr_enable(unsigned int irq) {
56         u32 reg;
57         unsigned int gpio;
58         unsigned int imr;
59
60         gpio = irq - (AR531X_GPIO_IRQ(0));
61         if (gpio >= AR531X_NUM_GPIO)
62                 return;
63         ar531x_gpio_intr_Mask |= (1<<gpio);
64
65         reg = sysRegRead(AR531X_GPIO_CR);
66         reg &= ~(AR531X_GPIO_CR_M(gpio) | AR531X_GPIO_CR_UART(gpio) | AR531X_GPIO_CR_INT(gpio));
67         reg |= AR531X_GPIO_CR_I(gpio);
68         reg |= AR531X_GPIO_CR_INT(gpio);
69
70         sysRegWrite(AR531X_GPIO_CR, reg);
71         (void)sysRegRead(AR531X_GPIO_CR); /* flush to hardware */
72
73         imr = sysRegRead(AR531X_IMR);
74         imr |= AR531X_ISR_GPIO;
75         sysRegWrite(AR531X_IMR, imr);
76         imr = sysRegRead(AR531X_IMR); /* flush write buffer */
77 }
78
79 /* Disable the specified AR5312_GPIO_IRQ interrupt */
80 static void ar5312_gpio_intr_disable(unsigned int irq) {
81         u32 reg;
82         unsigned int gpio;
83         gpio = irq - (AR531X_GPIO_IRQ(0));
84         if (gpio >= AR531X_NUM_GPIO)
85                 return;
86
87         reg = sysRegRead(AR531X_GPIO_CR);
88         reg &= ~(AR531X_GPIO_CR_M(gpio) | AR531X_GPIO_CR_UART(gpio) | AR531X_GPIO_CR_INT(gpio));
89         reg |= AR531X_GPIO_CR_I(gpio);
90         /* No GPIO_CR_INT bit */
91
92         sysRegWrite(AR531X_GPIO_CR, reg);
93         (void)sysRegRead(AR531X_GPIO_CR); /* flush to hardware */
94
95         /* Disable Interrupt if no gpio needs triggering */
96         if (ar531x_gpio_intr_Mask != 0) {
97                 unsigned int imr;
98
99                 imr = sysRegRead(AR531X_IMR);
100                 imr &= ~AR531X_ISR_GPIO;
101                 sysRegWrite(AR531X_IMR, imr);
102                 imr = sysRegRead(AR531X_IMR); /* flush write buffer */
103         }
104
105         ar531x_gpio_intr_Mask &= ~(1<<gpio);
106 }
107
108 /* Turn on the specified AR5312_GPIO_IRQ interrupt */
109 static unsigned int ar5312_gpio_intr_startup(unsigned int irq) {
110         ar5312_gpio_intr_enable(irq);
111         return 0;
112 }
113
114 static void ar5312_gpio_intr_end(unsigned int irq) {
115         if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
116                 ar5312_gpio_intr_enable(irq);
117 }
118
119 asmlinkage void ar5312_gpio_irq_dispatch(void) {
120         int i;
121         u32 gpioIntPending;
122         gpioIntPending = sysRegRead(AR531X_GPIO_DI) & ar531x_gpio_intr_Mask;
123         sysRegWrite(AR531X_ISR, sysRegRead(AR531X_IMR) | ~AR531X_ISR_GPIO);
124         for (i=0; i<AR531X_GPIO_IRQ_COUNT; i++) {
125         if (gpioIntPending & (1 << i))
126                 do_IRQ(AR531X_GPIO_IRQ(i));
127         }
128 }
129 #endif  /* #ifdef CONFIG_ATHEROS_AR5312 */
130
131 #ifdef CONFIG_ATHEROS_AR5315
132 /* Enable the specified AR5315_GPIO_IRQ interrupt */
133 static void ar5315_gpio_intr_enable(unsigned int irq) {
134         u32 reg;
135         unsigned int gpio;
136         unsigned int imr;
137         unsigned int i;
138
139         gpio = irq - (AR531X_GPIO_IRQ(0));
140         if (gpio >= AR5315_NUM_GPIO)
141                 return;
142         ar531x_gpio_intr_Mask |= (1<<gpio);
143
144         reg = sysRegRead(AR5315_GPIO_CR);
145         reg &= ~(AR5315_GPIO_CR_M(gpio));
146         reg |= AR5315_GPIO_CR_I(gpio);
147         sysRegWrite(AR5315_GPIO_CR, reg);
148         (void)sysRegRead(AR5315_GPIO_CR); /* flush write to hardware */
149
150         /* Locate a free register slot to enable gpio intr 
151            will fail silently if no more slots are available
152          */
153         reg = sysRegRead(AR5315_GPIO_INT);
154         for (i=0 ; i<=AR5315_GPIO_INT_MAX_Y ; i++) {
155                 /* Free slot means trigger level = 0 */
156                 if ( AR5315_GPIO_INT_LVL_OFF ==
157                     (reg & AR5315_GPIO_INT_LVL_M) ) {
158
159                         unsigned int def_lvl = AR5315_GPIO_INT_LVL_EDGE;
160                         if (ar5315_gpio_set_type_gpio == gpio)
161                                 def_lvl = ar5315_gpio_set_type_lvl;
162
163                         /* Set the gpio level trigger mode */
164 /*                      reg &= ~(AR5315_GPIO_INT_LVL_M(i)); */
165                         reg |= AR5315_GPIO_INT_LVL(i);
166
167                         /* Enable the gpio pin */
168                         reg &= ~(AR5315_GPIO_INT_M);
169                         reg |= AR5315_GPIO_INT_S(i);
170
171                         sysRegWrite(AR5315_GPIO_INT, reg);
172                         (void)sysRegRead(AR5315_GPIO_INT); /* flush write to hardware */
173
174                         /* break out of for loop */
175                         break;
176                 } /* end if trigger level for slot i is 0 */
177         } /* end for each slot */
178
179         imr = sysRegRead(AR5315_IMR);
180         imr |= AR5315_ISR_GPIO;
181         sysRegWrite(AR5315_IMR, imr);
182         imr = sysRegRead(AR5315_IMR); /* flush write buffer */
183 }
184
185
186 /* Disable the specified AR5315_GPIO_IRQ interrupt */
187 static void ar5315_gpio_intr_disable(unsigned int irq) {
188         u32 reg;
189         unsigned int gpio;
190         unsigned int i;
191
192         gpio = irq - (AR531X_GPIO_IRQ(0));
193         if (gpio >= AR5315_NUM_GPIO)
194                 return;
195
196         reg = sysRegRead(AR5315_GPIO_CR);
197         reg &= ~(AR5315_GPIO_CR_M(gpio));
198         reg |= AR5315_GPIO_CR_I(gpio);
199         sysRegWrite(AR5315_GPIO_CR, reg);
200         (void)sysRegRead(AR5315_GPIO_CR); /* flush write to hardware */
201
202         /* Locate a the correct register slot to disable gpio intr */
203         reg = sysRegRead(AR5315_GPIO_INT);
204         for (i=0 ; i<=AR5315_GPIO_INT_MAX_Y ; i++) {
205                 /* If this correct  */
206                 if ( AR5315_GPIO_INT_S(i) ==
207                     (reg & AR5315_GPIO_INT_M) ) {
208                         /* Clear the gpio level trigger mode */
209                         reg &= ~(AR5315_GPIO_INT_LVL_M);
210
211                         sysRegWrite(AR5315_GPIO_INT, reg);
212                         (void)sysRegRead(AR5315_GPIO_INT); /* flush write to hardware */
213                         break;
214                 } /* end if trigger level for slot i is 0 */
215         } /* end for each slot */
216
217         /* Disable interrupt only if no gpio needs triggering */
218         if (ar531x_gpio_intr_Mask != 0) {
219                 unsigned int imr;
220
221                 imr = sysRegRead(AR5315_IMR);
222                 imr &= ~AR5315_ISR_GPIO;
223                 sysRegWrite(AR5315_IMR, imr);
224                 imr = sysRegRead(AR5315_IMR); /* flush write buffer */
225         }
226
227         ar531x_gpio_intr_Mask &= ~(1<<gpio);
228 }
229
230 /* Turn on the specified AR5315_GPIO_IRQ interrupt */
231 static unsigned int ar5315_gpio_intr_startup(unsigned int irq) {
232         ar5315_gpio_intr_enable(irq);
233         return 0;
234 }
235
236 static void ar5315_gpio_intr_end(unsigned int irq) {
237         if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
238                 ar5315_gpio_intr_enable(irq);
239 }
240
241 static int ar5315_gpio_intr_set_type(unsigned int irq, unsigned int flow_type) {
242         ar5315_gpio_set_type_gpio = irq - (AR531X_GPIO_IRQ(0));
243         if (ar5315_gpio_set_type_gpio > AR5315_NUM_GPIO)
244                 return -EINVAL;
245         switch (flow_type & IRQF_TRIGGER_MASK) {
246                 case IRQF_TRIGGER_RISING:
247                 case IRQF_TRIGGER_FALLING:
248                         printk(KERN_WARNING "AR5315 GPIO %u falling back to edge triggered\n", ar5315_gpio_set_type_gpio);
249                 case IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING:
250                         ar5315_gpio_set_type_lvl = AR5315_GPIO_INT_LVL_EDGE;
251                         break;
252                 case IRQF_TRIGGER_LOW:
253                         ar5315_gpio_set_type_lvl = AR5315_GPIO_INT_LVL_LOW;
254                         break;
255                 case IRQF_TRIGGER_HIGH:
256                         ar5315_gpio_set_type_lvl = AR5315_GPIO_INT_LVL_HIGH;
257                         break;
258                 default:
259                         return -EINVAL;
260         }
261         return 0;
262 }
263
264 asmlinkage void ar5315_gpio_irq_dispatch(void){
265         int i;
266         u32 gpioIntPending;
267         gpioIntPending = sysRegRead(AR5315_GPIO_DI) & ar531x_gpio_intr_Mask;
268         sysRegWrite(AR5315_ISR, sysRegRead(AR5315_IMR) | ~AR5315_ISR_GPIO);
269         for (i=0; i<AR531X_GPIO_IRQ_COUNT; i++) {
270         if (gpioIntPending & (1 << i))
271                 do_IRQ(AR531X_GPIO_IRQ(i));
272         }
273 }
274 #endif /* #ifdef CONFIG_ATHEROS_AR5315  */
275
276 /* Common Code */
277 static struct irq_chip ar531x_gpio_intr_controller = {
278         .typename       = "AR531X GPIO",
279 };
280
281 /* ARGSUSED */
282 irqreturn_t
283 spurious_gpio_handler(int cpl, void *dev_id)
284 {
285         u32 gpioDataIn;
286         DO_AR5312(gpioDataIn = sysRegRead(AR531X_GPIO_DI);)
287         DO_AR5315(gpioDataIn = sysRegRead(AR5315_GPIO_DI);)
288
289         printk("spurious_gpio_handler: 0x%08x dev=%p DI=0x%08x gpioIntMask=0x%08x\n",
290                 cpl, dev_id, gpioDataIn, ar531x_gpio_intr_Mask);
291
292         return IRQ_NONE;
293 }
294
295 static struct irqaction spurious_gpio  = {
296         .handler        = spurious_gpio_handler,
297         .name           = "spurious_gpio",
298 };
299
300 /* Initialize AR531X GPIO interrupts */
301 static int __init ar531x_gpio_init(void)
302 {
303         int i;
304
305         DO_AR5312( \
306                 ar531x_gpio_intr_controller.startup = ar5312_gpio_intr_startup; \
307                 ar531x_gpio_intr_controller.shutdown = ar5312_gpio_intr_disable; \
308                 ar531x_gpio_intr_controller.enable = ar5312_gpio_intr_enable; \
309                 ar531x_gpio_intr_controller.disable = ar5312_gpio_intr_disable; \
310                 ar531x_gpio_intr_controller.ack = ar5312_gpio_intr_disable; \
311                 ar531x_gpio_intr_controller.end = ar5312_gpio_intr_end; \
312         )
313
314         DO_AR5315( \
315                 ar531x_gpio_intr_controller.startup = ar5315_gpio_intr_startup; \
316                 ar531x_gpio_intr_controller.shutdown = ar5315_gpio_intr_disable; \
317                 ar531x_gpio_intr_controller.enable = ar5315_gpio_intr_enable; \
318                 ar531x_gpio_intr_controller.disable = ar5315_gpio_intr_disable; \
319                 ar531x_gpio_intr_controller.ack = ar5315_gpio_intr_disable; \
320                 ar531x_gpio_intr_controller.end = ar5315_gpio_intr_end; \
321                 ar531x_gpio_intr_controller.set_type = ar5315_gpio_intr_set_type; \
322         )
323
324         for (i = AR531X_GPIO_IRQ_BASE;
325              i < AR531X_GPIO_IRQ_BASE + AR531X_GPIO_IRQ_COUNT;
326              i++) {
327                 irq_desc[i].status = IRQ_DISABLED;
328                 irq_desc[i].action = NULL;
329                 irq_desc[i].depth = 1;
330                 irq_desc[i].chip = &ar531x_gpio_intr_controller;
331         }
332
333         setup_irq(AR531X_GPIO_IRQ_NONE, &spurious_gpio);
334
335         return 0;
336 }
337
338 subsys_initcall(ar531x_gpio_init);
339