[lantiq] prepare Makefile for 3.6
[openwrt.git] / target / linux / lantiq / files / arch / mips / lantiq / svip / gpio.c
1 /*
2  *  This program is free software; you can redistribute it and/or modify it
3  *  under the terms of the GNU General Public License version 2 as published
4  *  by the Free Software Foundation.
5  *
6  *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7  */
8
9 #include <linux/module.h>
10 #include <linux/slab.h>
11 #include <linux/gpio.h>
12 #include <linux/ioport.h>
13 #include <linux/io.h>
14 #include <linux/types.h>
15 #include <linux/errno.h>
16 #include <linux/proc_fs.h>
17 #include <linux/init.h>
18 #include <linux/ioctl.h>
19 #include <linux/timer.h>
20 #include <linux/interrupt.h>
21 #include <linux/kobject.h>
22 #include <linux/workqueue.h>
23 #include <linux/skbuff.h>
24 #include <linux/netlink.h>
25 #include <linux/platform_device.h>
26 #include <net/sock.h>
27 #include <linux/uaccess.h>
28 #include <linux/version.h>
29 #include <linux/semaphore.h>
30
31 #include <lantiq_soc.h>
32 #include <svip_mux.h>
33 #include <base_reg.h>
34 #include <port_reg.h>
35
36 #define DRV_NAME                        "ifxmips_gpio"
37
38 int gpio_to_irq(unsigned int gpio)
39 {
40         return -EINVAL;
41 }
42 EXPORT_SYMBOL(gpio_to_irq);
43
44 int irq_to_gpio(unsigned int gpio)
45 {
46         return -EINVAL;
47 }
48 EXPORT_SYMBOL(irq_to_gpio);
49
50 struct ltq_port_base {
51         struct svip_reg_port *base;
52         u32 pins;
53 };
54
55 /* Base addresses for ports */
56 static const struct ltq_port_base ltq_port_base[] = {
57         { (struct svip_reg_port *)LTQ_PORT_P0_BASE, 20 },
58         { (struct svip_reg_port *)LTQ_PORT_P1_BASE, 20 },
59         { (struct svip_reg_port *)LTQ_PORT_P2_BASE, 19 },
60         { (struct svip_reg_port *)LTQ_PORT_P3_BASE, 20 },
61         { (struct svip_reg_port *)LTQ_PORT_P4_BASE, 24 }
62 };
63
64 #define MAX_PORTS               ARRAY_SIZE(ltq_port_base)
65 #define PINS_PER_PORT(port)     (ltq_port_base[port].pins)
66
67 static inline
68 void ltq_port_set_exintcr0(unsigned int port, unsigned int pin)
69 {
70         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
71                 return;
72
73         port_w32(port_r32(ltq_port_base[port].base->exintcr0) | (1 << pin),
74                  ltq_port_base[port].base->exintcr0);
75 }
76
77 static inline
78 void ltq_port_clear_exintcr0(unsigned int port, unsigned int pin)
79 {
80         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
81                 return;
82
83         port_w32(port_r32(ltq_port_base[port].base->exintcr0) & ~(1 << pin),
84                  ltq_port_base[port].base->exintcr0);
85 }
86
87 static inline
88 void ltq_port_set_exintcr1(unsigned int port, unsigned int pin)
89 {
90         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
91                 return;
92
93         port_w32(port_r32(ltq_port_base[port].base->exintcr1) | (1 << pin),
94                  ltq_port_base[port].base->exintcr1);
95 }
96
97 static inline
98 void ltq_port_clear_exintcr1(unsigned int port, unsigned int pin)
99 {
100         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
101                 return;
102
103         port_w32(port_r32(ltq_port_base[port].base->exintcr1) & ~(1 << pin),
104                  ltq_port_base[port].base->exintcr1);
105 }
106
107 static inline
108 void ltq_port_set_irncfg(unsigned int port, unsigned int pin)
109 {
110         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
111                 return;
112
113         port_w32(port_r32(ltq_port_base[port].base->irncfg) | (1 << pin),
114                  ltq_port_base[port].base->irncfg);
115 }
116
117 static inline
118 void ltq_port_clear_irncfg(unsigned int port, unsigned int pin)
119 {
120         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
121                 return;
122
123         port_w32(port_r32(ltq_port_base[port].base->irncfg) & ~(1 << pin),
124                  ltq_port_base[port].base->irncfg);
125 }
126
127 static inline
128 void ltq_port_set_irnen(unsigned int port, unsigned int pin)
129 {
130         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
131                 return;
132
133         port_w32(1 << pin, ltq_port_base[port].base->irnenset);
134 }
135
136 static inline
137 void ltq_port_clear_irnen(unsigned int port, unsigned int pin)
138 {
139         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
140                 return;
141
142         port_w32(1 << pin, ltq_port_base[port].base->irnenclr);
143 }
144
145 static inline
146 void ltq_port_set_dir_out(unsigned int port, unsigned int pin)
147 {
148         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
149                 return;
150
151         port_w32(port_r32(ltq_port_base[port].base->dir) | (1 << pin),
152                  ltq_port_base[port].base->dir);
153 }
154
155 static inline
156 void ltq_port_set_dir_in(unsigned int port, unsigned int pin)
157 {
158         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
159                 return;
160
161         port_w32(port_r32(ltq_port_base[port].base->dir) & ~(1 << pin),
162                  ltq_port_base[port].base->dir);
163 }
164
165 static inline
166 void ltq_port_set_output(unsigned int port, unsigned int pin)
167 {
168         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
169                 return;
170
171         port_w32(port_r32(ltq_port_base[port].base->out) | (1 << pin),
172                  ltq_port_base[port].base->out);
173 }
174
175 static inline
176 void ltq_port_clear_output(unsigned int port, unsigned int pin)
177 {
178         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
179                 return;
180
181         port_w32(port_r32(ltq_port_base[port].base->out) & ~(1 << pin),
182                  ltq_port_base[port].base->out);
183 }
184
185 static inline
186 int ltq_port_get_input(unsigned int port, unsigned int pin)
187 {
188         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
189                 return -EINVAL;
190
191         return (port_r32(ltq_port_base[port].base->in) & (1 << pin)) == 0;
192 }
193
194 static inline
195 void ltq_port_set_puen(unsigned int port, unsigned int pin)
196 {
197         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
198                 return;
199
200         port_w32(port_r32(ltq_port_base[port].base->puen) | (1 << pin),
201                  ltq_port_base[port].base->puen);
202 }
203
204 static inline
205 void ltq_port_clear_puen(unsigned int port, unsigned int pin)
206 {
207         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
208                 return;
209
210         port_w32(port_r32(ltq_port_base[port].base->puen) & ~(1 << pin),
211                  ltq_port_base[port].base->puen);
212 }
213
214 static inline
215 void ltq_port_set_altsel0(unsigned int port, unsigned int pin)
216 {
217         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
218                 return;
219
220         port_w32(port_r32(ltq_port_base[port].base->altsel0) | (1 << pin),
221                  ltq_port_base[port].base->altsel0);
222 }
223
224 static inline
225 void ltq_port_clear_altsel0(unsigned int port, unsigned int pin)
226 {
227         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
228                 return;
229
230         port_w32(port_r32(ltq_port_base[port].base->altsel0) & ~(1 << pin),
231                  ltq_port_base[port].base->altsel0);
232 }
233
234 static inline
235 void ltq_port_set_altsel1(unsigned int port, unsigned int pin)
236 {
237         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
238                 return;
239
240         port_w32(port_r32(ltq_port_base[port].base->altsel1) | (1 << pin),
241                  ltq_port_base[port].base->altsel1);
242 }
243
244 static inline
245 void ltq_port_clear_altsel1(unsigned int port, unsigned int pin)
246 {
247         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
248                 return;
249
250         port_w32(port_r32(ltq_port_base[port].base->altsel1) & ~(1 << pin),
251                  ltq_port_base[port].base->altsel1);
252 }
253
254 void ltq_gpio_configure(int port, int pin, bool dirin, bool puen,
255                         bool altsel0, bool altsel1)
256 {
257         if (dirin)
258                 ltq_port_set_dir_in(port, pin);
259         else
260                 ltq_port_set_dir_out(port, pin);
261
262         if (puen)
263                 ltq_port_set_puen(port, pin);
264         else
265                 ltq_port_clear_puen(port, pin);
266
267         if (altsel0)
268                 ltq_port_set_altsel0(port, pin);
269         else
270                 ltq_port_clear_altsel0(port, pin);
271
272         if (altsel1)
273                 ltq_port_set_altsel1(port, pin);
274         else
275                 ltq_port_clear_altsel1(port, pin);
276 }
277
278 int ltq_port_get_dir(unsigned int port, unsigned int pin)
279 {
280         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
281                 return -EINVAL;
282
283         return (port_r32(ltq_port_base[port].base->dir) & (1 << pin)) != 0;
284 }
285
286 int ltq_port_get_puden(unsigned int port, unsigned int pin)
287 {
288         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
289                 return -EINVAL;
290
291         return (port_r32(ltq_port_base[port].base->puen) & (1 << pin)) != 0;
292 }
293
294 int ltq_port_get_altsel0(unsigned int port, unsigned int pin)
295 {
296         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
297                 return -EINVAL;
298
299         return (port_r32(ltq_port_base[port].base->altsel0) & (1 << pin)) != 0;
300 }
301
302 int ltq_port_get_altsel1(unsigned int port, unsigned int pin)
303 {
304         if (port >= MAX_PORTS || pin >= PINS_PER_PORT(port))
305                 return -EINVAL;
306
307         return (port_r32(ltq_port_base[port].base->altsel1) & (1 << pin)) != 0;
308 }
309
310 struct ltq_gpio_port {
311         struct gpio_chip gpio_chip;
312         unsigned int irq_base;
313         unsigned int chained_irq;
314 };
315
316 static struct ltq_gpio_port ltq_gpio_port[MAX_PORTS];
317
318 static int gpio_exported;
319 static int __init gpio_export_setup(char *str)
320 {
321         get_option(&str, &gpio_exported);
322         return 1;
323 }
324 __setup("gpio_exported=", gpio_export_setup);
325
326 static inline unsigned int offset2port(unsigned int offset)
327 {
328         unsigned int i;
329         unsigned int prev = 0;
330
331         for (i = 0; i < ARRAY_SIZE(ltq_port_base); i++) {
332                 if (offset >= prev &&
333                     offset < prev + ltq_port_base[i].pins)
334                         return i;
335
336                 prev = ltq_port_base[i].pins;
337         }
338
339         return 0;
340 }
341
342 static inline unsigned int offset2pin(unsigned int offset)
343 {
344         unsigned int i;
345         unsigned int prev = 0;
346
347         for (i = 0; i < ARRAY_SIZE(ltq_port_base); i++) {
348                 if (offset >= prev &&
349                     offset < prev + ltq_port_base[i].pins)
350                         return offset - prev;
351
352                 prev = ltq_port_base[i].pins;
353         }
354
355         return 0;
356 }
357
358 static int ltq_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
359 {
360         ltq_port_set_dir_in(offset2port(offset), offset2pin(offset));
361         return 0;
362 }
363
364 static int ltq_gpio_direction_output(struct gpio_chip *chip,
365                                      unsigned int offset, int value)
366 {
367         ltq_port_set_dir_out(offset2port(offset), offset2pin(offset));
368         return 0;
369 }
370
371 static int ltq_gpio_get(struct gpio_chip *chip, unsigned int offset)
372 {
373         return ltq_port_get_input(offset2port(offset), offset2pin(offset));
374 }
375
376 static void ltq_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
377 {
378         if (value)
379                 ltq_port_set_output(offset2port(offset), offset2pin(offset));
380         else
381                 ltq_port_clear_output(offset2port(offset), offset2pin(offset));
382 }
383
384 static int svip_gpio_request(struct gpio_chip *chip, unsigned offset)
385 {
386         return 0;
387 }
388
389 static void ltq_gpio_free(struct gpio_chip *chip, unsigned offset)
390 {
391 }
392
393 static int ltq_gpio_probe(struct platform_device *pdev)
394 {
395         int ret = 0;
396         struct ltq_gpio_port *gpio_port;
397
398         if (pdev->id >= MAX_PORTS)
399                 return -ENODEV;
400
401         gpio_port = &ltq_gpio_port[pdev->id];
402         gpio_port->gpio_chip.label = "ltq-gpio";
403
404         gpio_port->gpio_chip.direction_input = ltq_gpio_direction_input;
405         gpio_port->gpio_chip.direction_output = ltq_gpio_direction_output;
406         gpio_port->gpio_chip.get = ltq_gpio_get;
407         gpio_port->gpio_chip.set = ltq_gpio_set;
408         gpio_port->gpio_chip.request = svip_gpio_request;
409         gpio_port->gpio_chip.free = ltq_gpio_free;
410         gpio_port->gpio_chip.base = 100 * pdev->id;
411         gpio_port->gpio_chip.ngpio = 32;
412         gpio_port->gpio_chip.dev = &pdev->dev;
413         gpio_port->gpio_chip.exported = gpio_exported;
414
415         ret = gpiochip_add(&gpio_port->gpio_chip);
416         if (ret < 0) {
417                 dev_err(&pdev->dev, "Could not register gpiochip %d, %d\n",
418                         pdev->id, ret);
419                 goto err;
420         }
421         platform_set_drvdata(pdev, gpio_port);
422
423         return 0;
424
425 err:
426         return ret;
427 }
428
429 static int ltq_gpio_remove(struct platform_device *pdev)
430 {
431         struct ltq_gpio_port *gpio_port = platform_get_drvdata(pdev);
432         int ret;
433
434         ret = gpiochip_remove(&gpio_port->gpio_chip);
435
436         return ret;
437 }
438
439 static struct platform_driver ltq_gpio_driver = {
440         .probe = ltq_gpio_probe,
441         .remove = __devexit_p(ltq_gpio_remove),
442         .driver = {
443                 .name = DRV_NAME,
444                 .owner = THIS_MODULE,
445         },
446 };
447
448 int __init ltq_gpio_init(void)
449 {
450         int ret = platform_driver_register(&ltq_gpio_driver);
451         if (ret)
452                 printk(KERN_INFO DRV_NAME
453                        ": Error registering platform driver!");
454         return ret;
455 }
456
457 postcore_initcall(ltq_gpio_init);
458
459 /**
460  * Convert interrupt number to corresponding port/pin pair
461  * Returns the port/pin pair serving the selected external interrupt;
462  * needed since mapping not linear.
463  *
464  * \param exint     External interrupt number
465  * \param port      Pointer for resulting port
466  * \param pin       Pointer for resutling pin
467  * \return -EINVAL  Invalid exint
468  * \return 0        port/pin updated
469  * \ingroup API
470  */
471 static int ltq_exint2port(u32 exint, int *port, int *pin)
472 {
473         if ((exint >= 0) && (exint <= 10)) {
474                 *port = 0;
475                 *pin  = exint + 7;
476         } else if ((exint >= 11) && (exint <= 14)) {
477                 *port = 1;
478                 *pin  = 18 - (exint - 11) ;
479         } else if (exint == 15) {
480                 *port = 1;
481                 *pin  = 19;
482         } else if (exint == 16) {
483                 *port = 0;
484                 *pin  = 19;
485         } else {
486                 return -EINVAL;
487         }
488         return 0;
489 }
490
491 /**
492  * Enable external interrupt.
493  * This function enables an external interrupt and sets the given mode.
494  * valid values for mode are:
495  *   - 0 = Interrupt generation disabled
496  *   - 1 = Interrupt on rising edge
497  *   - 2 = Interrupt on falling edge
498  *   - 3 = Interrupt on rising and falling edge
499  *   - 5 = Interrupt on high level detection
500  *   - 6 = Interrupt on low level detection
501  *
502  * \param   exint - Number of external interrupt
503  * \param   mode  - Trigger mode
504  * \return  0 on success
505  * \ingroup API
506  */
507 int ifx_enable_external_int(u32 exint, u32 mode)
508 {
509         int port;
510         int pin;
511
512         if ((mode < 0) || (mode > 6))
513                 return -EINVAL;
514
515         if (ltq_exint2port(exint, &port, &pin))
516                 return -EINVAL;
517
518         ltq_port_clear_exintcr0(port, pin);
519         ltq_port_clear_exintcr1(port, pin);
520         ltq_port_clear_irncfg(port, pin);
521
522         if (mode & 0x1)
523                 ltq_port_set_exintcr0(port, pin);
524         if (mode & 0x2)
525                 ltq_port_set_exintcr1(port, pin);
526         if (mode & 0x4)
527                 ltq_port_set_irncfg(port, pin);
528
529         ltq_port_set_irnen(port, pin);
530         return 0;
531 }
532 EXPORT_SYMBOL(ifx_enable_external_int);
533
534 /**
535  * Disable external interrupt.
536  * This function disables an external interrupt and sets mode to 0x00.
537  *
538  * \param   exint - Number of external interrupt
539  * \return  0 on success
540  * \ingroup API
541  */
542 int ifx_disable_external_int(u32 exint)
543 {
544         int port;
545         int pin;
546
547         if (ltq_exint2port(exint, &port, &pin))
548                 return -EINVAL;
549
550         ltq_port_clear_irnen(port, pin);
551         return 0;
552 }
553 EXPORT_SYMBOL(ifx_disable_external_int);