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.
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
9 #include <linux/module.h>
10 #include <linux/slab.h>
11 #include <linux/gpio.h>
12 #include <linux/ioport.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>
27 #include <linux/uaccess.h>
28 #include <linux/version.h>
29 #include <linux/semaphore.h>
31 #include <lantiq_soc.h>
36 #define DRV_NAME "ifxmips_gpio"
38 int gpio_to_irq(unsigned int gpio
)
42 EXPORT_SYMBOL(gpio_to_irq
);
44 int irq_to_gpio(unsigned int gpio
)
48 EXPORT_SYMBOL(irq_to_gpio
);
50 struct ltq_port_base
{
51 struct svip_reg_port
*base
;
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 }
64 #define MAX_PORTS ARRAY_SIZE(ltq_port_base)
65 #define PINS_PER_PORT(port) (ltq_port_base[port].pins)
68 void ltq_port_set_exintcr0(unsigned int port
, unsigned int pin
)
70 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
73 port_w32(port_r32(ltq_port_base
[port
].base
->exintcr0
) | (1 << pin
),
74 ltq_port_base
[port
].base
->exintcr0
);
78 void ltq_port_clear_exintcr0(unsigned int port
, unsigned int pin
)
80 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
83 port_w32(port_r32(ltq_port_base
[port
].base
->exintcr0
) & ~(1 << pin
),
84 ltq_port_base
[port
].base
->exintcr0
);
88 void ltq_port_set_exintcr1(unsigned int port
, unsigned int pin
)
90 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
93 port_w32(port_r32(ltq_port_base
[port
].base
->exintcr1
) | (1 << pin
),
94 ltq_port_base
[port
].base
->exintcr1
);
98 void ltq_port_clear_exintcr1(unsigned int port
, unsigned int pin
)
100 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
103 port_w32(port_r32(ltq_port_base
[port
].base
->exintcr1
) & ~(1 << pin
),
104 ltq_port_base
[port
].base
->exintcr1
);
108 void ltq_port_set_irncfg(unsigned int port
, unsigned int pin
)
110 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
113 port_w32(port_r32(ltq_port_base
[port
].base
->irncfg
) | (1 << pin
),
114 ltq_port_base
[port
].base
->irncfg
);
118 void ltq_port_clear_irncfg(unsigned int port
, unsigned int pin
)
120 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
123 port_w32(port_r32(ltq_port_base
[port
].base
->irncfg
) & ~(1 << pin
),
124 ltq_port_base
[port
].base
->irncfg
);
128 void ltq_port_set_irnen(unsigned int port
, unsigned int pin
)
130 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
133 port_w32(1 << pin
, ltq_port_base
[port
].base
->irnenset
);
137 void ltq_port_clear_irnen(unsigned int port
, unsigned int pin
)
139 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
142 port_w32(1 << pin
, ltq_port_base
[port
].base
->irnenclr
);
146 void ltq_port_set_dir_out(unsigned int port
, unsigned int pin
)
148 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
151 port_w32(port_r32(ltq_port_base
[port
].base
->dir
) | (1 << pin
),
152 ltq_port_base
[port
].base
->dir
);
156 void ltq_port_set_dir_in(unsigned int port
, unsigned int pin
)
158 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
161 port_w32(port_r32(ltq_port_base
[port
].base
->dir
) & ~(1 << pin
),
162 ltq_port_base
[port
].base
->dir
);
166 void ltq_port_set_output(unsigned int port
, unsigned int pin
)
168 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
171 port_w32(port_r32(ltq_port_base
[port
].base
->out
) | (1 << pin
),
172 ltq_port_base
[port
].base
->out
);
176 void ltq_port_clear_output(unsigned int port
, unsigned int pin
)
178 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
181 port_w32(port_r32(ltq_port_base
[port
].base
->out
) & ~(1 << pin
),
182 ltq_port_base
[port
].base
->out
);
186 int ltq_port_get_input(unsigned int port
, unsigned int pin
)
188 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
191 return (port_r32(ltq_port_base
[port
].base
->in
) & (1 << pin
)) == 0;
195 void ltq_port_set_puen(unsigned int port
, unsigned int pin
)
197 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
200 port_w32(port_r32(ltq_port_base
[port
].base
->puen
) | (1 << pin
),
201 ltq_port_base
[port
].base
->puen
);
205 void ltq_port_clear_puen(unsigned int port
, unsigned int pin
)
207 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
210 port_w32(port_r32(ltq_port_base
[port
].base
->puen
) & ~(1 << pin
),
211 ltq_port_base
[port
].base
->puen
);
215 void ltq_port_set_altsel0(unsigned int port
, unsigned int pin
)
217 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
220 port_w32(port_r32(ltq_port_base
[port
].base
->altsel0
) | (1 << pin
),
221 ltq_port_base
[port
].base
->altsel0
);
225 void ltq_port_clear_altsel0(unsigned int port
, unsigned int pin
)
227 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
230 port_w32(port_r32(ltq_port_base
[port
].base
->altsel0
) & ~(1 << pin
),
231 ltq_port_base
[port
].base
->altsel0
);
235 void ltq_port_set_altsel1(unsigned int port
, unsigned int pin
)
237 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
240 port_w32(port_r32(ltq_port_base
[port
].base
->altsel1
) | (1 << pin
),
241 ltq_port_base
[port
].base
->altsel1
);
245 void ltq_port_clear_altsel1(unsigned int port
, unsigned int pin
)
247 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
250 port_w32(port_r32(ltq_port_base
[port
].base
->altsel1
) & ~(1 << pin
),
251 ltq_port_base
[port
].base
->altsel1
);
254 void ltq_gpio_configure(int port
, int pin
, bool dirin
, bool puen
,
255 bool altsel0
, bool altsel1
)
258 ltq_port_set_dir_in(port
, pin
);
260 ltq_port_set_dir_out(port
, pin
);
263 ltq_port_set_puen(port
, pin
);
265 ltq_port_clear_puen(port
, pin
);
268 ltq_port_set_altsel0(port
, pin
);
270 ltq_port_clear_altsel0(port
, pin
);
273 ltq_port_set_altsel1(port
, pin
);
275 ltq_port_clear_altsel1(port
, pin
);
278 int ltq_port_get_dir(unsigned int port
, unsigned int pin
)
280 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
283 return (port_r32(ltq_port_base
[port
].base
->dir
) & (1 << pin
)) != 0;
286 int ltq_port_get_puden(unsigned int port
, unsigned int pin
)
288 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
291 return (port_r32(ltq_port_base
[port
].base
->puen
) & (1 << pin
)) != 0;
294 int ltq_port_get_altsel0(unsigned int port
, unsigned int pin
)
296 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
299 return (port_r32(ltq_port_base
[port
].base
->altsel0
) & (1 << pin
)) != 0;
302 int ltq_port_get_altsel1(unsigned int port
, unsigned int pin
)
304 if (port
>= MAX_PORTS
|| pin
>= PINS_PER_PORT(port
))
307 return (port_r32(ltq_port_base
[port
].base
->altsel1
) & (1 << pin
)) != 0;
310 struct ltq_gpio_port
{
311 struct gpio_chip gpio_chip
;
312 unsigned int irq_base
;
313 unsigned int chained_irq
;
316 static struct ltq_gpio_port ltq_gpio_port
[MAX_PORTS
];
318 static int gpio_exported
;
319 static int __init
gpio_export_setup(char *str
)
321 get_option(&str
, &gpio_exported
);
324 __setup("gpio_exported=", gpio_export_setup
);
326 static inline unsigned int offset2port(unsigned int offset
)
329 unsigned int prev
= 0;
331 for (i
= 0; i
< ARRAY_SIZE(ltq_port_base
); i
++) {
332 if (offset
>= prev
&&
333 offset
< prev
+ ltq_port_base
[i
].pins
)
336 prev
= ltq_port_base
[i
].pins
;
342 static inline unsigned int offset2pin(unsigned int offset
)
345 unsigned int prev
= 0;
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
;
352 prev
= ltq_port_base
[i
].pins
;
358 static int ltq_gpio_direction_input(struct gpio_chip
*chip
, unsigned int offset
)
360 ltq_port_set_dir_in(offset2port(offset
), offset2pin(offset
));
364 static int ltq_gpio_direction_output(struct gpio_chip
*chip
,
365 unsigned int offset
, int value
)
367 ltq_port_set_dir_out(offset2port(offset
), offset2pin(offset
));
371 static int ltq_gpio_get(struct gpio_chip
*chip
, unsigned int offset
)
373 return ltq_port_get_input(offset2port(offset
), offset2pin(offset
));
376 static void ltq_gpio_set(struct gpio_chip
*chip
, unsigned int offset
, int value
)
379 ltq_port_set_output(offset2port(offset
), offset2pin(offset
));
381 ltq_port_clear_output(offset2port(offset
), offset2pin(offset
));
384 static int svip_gpio_request(struct gpio_chip
*chip
, unsigned offset
)
389 static void ltq_gpio_free(struct gpio_chip
*chip
, unsigned offset
)
393 static int ltq_gpio_probe(struct platform_device
*pdev
)
396 struct ltq_gpio_port
*gpio_port
;
398 if (pdev
->id
>= MAX_PORTS
)
401 gpio_port
= <q_gpio_port
[pdev
->id
];
402 gpio_port
->gpio_chip
.label
= "ltq-gpio";
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
;
415 ret
= gpiochip_add(&gpio_port
->gpio_chip
);
417 dev_err(&pdev
->dev
, "Could not register gpiochip %d, %d\n",
421 platform_set_drvdata(pdev
, gpio_port
);
429 static int ltq_gpio_remove(struct platform_device
*pdev
)
431 struct ltq_gpio_port
*gpio_port
= platform_get_drvdata(pdev
);
434 ret
= gpiochip_remove(&gpio_port
->gpio_chip
);
439 static struct platform_driver ltq_gpio_driver
= {
440 .probe
= ltq_gpio_probe
,
441 .remove
= __devexit_p(ltq_gpio_remove
),
444 .owner
= THIS_MODULE
,
448 int __init
ltq_gpio_init(void)
450 int ret
= platform_driver_register(<q_gpio_driver
);
452 printk(KERN_INFO DRV_NAME
453 ": Error registering platform driver!");
457 postcore_initcall(ltq_gpio_init
);
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.
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
471 static int ltq_exint2port(u32 exint
, int *port
, int *pin
)
473 if ((exint
>= 0) && (exint
<= 10)) {
476 } else if ((exint
>= 11) && (exint
<= 14)) {
478 *pin
= 18 - (exint
- 11) ;
479 } else if (exint
== 15) {
482 } else if (exint
== 16) {
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
502 * \param exint - Number of external interrupt
503 * \param mode - Trigger mode
504 * \return 0 on success
507 int ifx_enable_external_int(u32 exint
, u32 mode
)
512 if ((mode
< 0) || (mode
> 6))
515 if (ltq_exint2port(exint
, &port
, &pin
))
518 ltq_port_clear_exintcr0(port
, pin
);
519 ltq_port_clear_exintcr1(port
, pin
);
520 ltq_port_clear_irncfg(port
, pin
);
523 ltq_port_set_exintcr0(port
, pin
);
525 ltq_port_set_exintcr1(port
, pin
);
527 ltq_port_set_irncfg(port
, pin
);
529 ltq_port_set_irnen(port
, pin
);
532 EXPORT_SYMBOL(ifx_enable_external_int
);
535 * Disable external interrupt.
536 * This function disables an external interrupt and sets mode to 0x00.
538 * \param exint - Number of external interrupt
539 * \return 0 on success
542 int ifx_disable_external_int(u32 exint
)
547 if (ltq_exint2port(exint
, &port
, &pin
))
550 ltq_port_clear_irnen(port
, pin
);
553 EXPORT_SYMBOL(ifx_disable_external_int
);