1 /* $Id: gpio.c,v 1.17 2005/06/19 17:06:46 starvik Exp $
3 * Etrax general port I/O device
5 * Copyright (c) 1999, 2000, 2001, 2002 Axis Communications AB
7 * Authors: Bjorn Wesen (initial version)
8 * Ola Knutsson (LED handling)
9 * Johan Adolfsson (read/set directions, write, port G)
12 * Revision 1.17 2005/06/19 17:06:46 starvik
13 * Merge of Linux 2.6.12.
15 * Revision 1.16 2005/03/07 13:02:29 starvik
16 * Protect driver global states with spinlock
18 * Revision 1.15 2005/01/05 06:08:55 starvik
19 * No need to do local_irq_disable after local_irq_save.
21 * Revision 1.14 2004/12/13 12:21:52 starvik
22 * Added I/O and DMA allocators from Linux 2.4
24 * Revision 1.12 2004/08/24 07:19:59 starvik
27 * Revision 1.11 2004/05/14 07:58:03 starvik
28 * Merge of changes from 2.4
30 * Revision 1.9 2003/09/11 07:29:48 starvik
31 * Merge of Linux 2.6.0-test5
33 * Revision 1.8 2003/07/04 08:27:37 starvik
34 * Merge of Linux 2.5.74
36 * Revision 1.7 2003/01/10 07:44:07 starvik
37 * init_ioremap is now called by kernel before drivers are initialized
39 * Revision 1.6 2002/12/11 13:13:57 starvik
40 * Added arch/ to v10 specific includes
41 * Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer)
43 * Revision 1.5 2002/11/20 11:56:11 starvik
44 * Merge of Linux 2.5.48
46 * Revision 1.4 2002/11/18 10:10:05 starvik
47 * Linux 2.5 port of latest gpio.c from Linux 2.4
49 * Revision 1.20 2002/10/16 21:16:24 johana
50 * Added support for PA high level interrupt.
51 * That gives 2ms response time with iodtest for high levels and 2-12 ms
52 * response time on low levels if the check is not made in
53 * process.c:cpu_idle() as well.
55 * Revision 1.19 2002/10/14 18:27:33 johana
56 * Implemented alarm handling so select() now works.
57 * Latency is around 6-9 ms with a etrax_gpio_wake_up_check() in
59 * Otherwise I get 15-18 ms (same as doing the poll in userspace -
61 * TODO? Perhaps we should add the check in IMMEDIATE_BH (or whatever it
63 * TODO? Perhaps call request_irq()/free_irq() only when needed?
64 * Increased version to 2.5
66 * Revision 1.18 2002/10/11 15:02:00 johana
67 * Mask inverted 8 bit value in setget_input().
69 * Revision 1.17 2002/06/17 15:53:01 johana
70 * Added IO_READ_INBITS, IO_READ_OUTBITS, IO_SETGET_INPUT and IO_SETGET_OUTPUT
71 * that take a pointer as argument and thus can handle 32 bit ports (G)
73 * These should be used instead of IO_READBITS, IO_SETINPUT and IO_SETOUTPUT.
74 * (especially if Port G bit 31 is used)
76 * Revision 1.16 2002/06/17 09:59:51 johana
77 * Returning 32 bit values in the ioctl return value doesn't work if bit
78 * 31 is set (could happen for port G), so mask it of with 0x7FFFFFFF.
79 * A new set of ioctl's will be added.
81 * Revision 1.15 2002/05/06 13:19:13 johana
82 * IO_SETINPUT returns mask with bit set = inputs for PA and PB as well.
84 * Revision 1.14 2002/04/12 12:01:53 johana
85 * Use global r_port_g_data_shadow.
86 * Moved gpio_init_port_g() closer to gpio_init() and marked it __init.
88 * Revision 1.13 2002/04/10 12:03:55 johana
89 * Added support for port G /dev/gpiog (minor 3).
90 * Changed indentation on switch cases.
91 * Fixed other spaces to tabs.
93 * Revision 1.12 2001/11/12 19:42:15 pkj
94 * * Corrected return values from gpio_leds_ioctl().
95 * * Fixed compiler warnings.
97 * Revision 1.11 2001/10/30 14:39:12 johana
98 * Added D() around gpio_write printk.
100 * Revision 1.10 2001/10/25 10:24:42 johana
101 * Added IO_CFG_WRITE_MODE ioctl and write method that can do fast
102 * bittoggling in the kernel. (This speeds up programming an FPGA with 450kB
103 * from ~60 seconds to 4 seconds).
104 * Added save_flags/cli/restore_flags in ioctl.
106 * Revision 1.9 2001/05/04 14:16:07 matsfg
107 * Corrected spelling error
109 * Revision 1.8 2001/04/27 13:55:26 matsfg
111 * Turns off all LEDS on init.
112 * Added support for shutdown and powerbutton.
114 * Revision 1.7 2001/04/04 13:30:08 matsfg
115 * Added bitset and bitclear for leds. Calls init_ioremap to set up memmapping
117 * Revision 1.6 2001/03/26 16:03:06 bjornw
118 * Needs linux/config.h
120 * Revision 1.5 2001/03/26 14:22:03 bjornw
121 * Namechange of some config options
123 * Revision 1.4 2001/02/27 13:52:48 bjornw
126 * Revision 1.3 2001/01/24 15:06:48 bjornw
127 * gpio_wq correct type
129 * Revision 1.2 2001/01/18 16:07:30 bjornw
132 * Revision 1.1 2001/01/18 15:55:16 bjornw
133 * Verbatim copy of etraxgpio.c from elinux 2.0 added
138 #include <linux/config.h>
140 #include <linux/module.h>
141 #include <linux/sched.h>
142 #include <linux/slab.h>
143 #include <linux/ioport.h>
144 #include <linux/errno.h>
145 #include <linux/kernel.h>
146 #include <linux/fs.h>
147 #include <linux/string.h>
148 #include <linux/poll.h>
149 #include <linux/init.h>
150 #include <linux/interrupt.h>
152 #include <asm/etraxgpio.h>
153 #include <asm/arch/svinto.h>
155 #include <asm/system.h>
157 #include <asm/arch/io_interface_mux.h>
159 #define GPIO_MAJOR 120 /* experimental MAJOR number */
165 #define DP(x) do { dp_cnt++; if (dp_cnt % 1000 == 0) x; }while(0)
170 static char gpio_name[] = "etrax gpio";
173 static wait_queue_head_t *gpio_wq;
176 static int gpio_ioctl(struct inode *inode, struct file *file,
177 unsigned int cmd, unsigned long arg);
178 static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
180 static int gpio_open(struct inode *inode, struct file *filp);
181 static int gpio_release(struct inode *inode, struct file *filp);
182 static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait);
184 /* private data per open() of this driver */
186 struct gpio_private {
187 struct gpio_private *next;
188 /* These fields are for PA and PB only */
189 volatile unsigned char *port, *shadow;
190 volatile unsigned char *dir, *dir_shadow;
191 unsigned char changeable_dir;
192 unsigned char changeable_bits;
193 unsigned char clk_mask;
194 unsigned char data_mask;
195 unsigned char write_msb;
196 unsigned char pad1, pad2, pad3;
197 /* These fields are generic */
198 unsigned long highalarm, lowalarm;
199 wait_queue_head_t alarm_wq;
203 /* linked list of alarms to check for */
205 static struct gpio_private *alarmlist = 0;
207 static int gpio_some_alarms = 0; /* Set if someone uses alarm */
208 static unsigned long gpio_pa_irq_enabled_mask = 0;
210 static DEFINE_SPINLOCK(gpio_lock); /* Protect directions etc */
212 /* Port A and B use 8 bit access, but Port G is 32 bit */
213 #define NUM_PORTS (GPIO_MINOR_B+1)
215 static volatile unsigned char *ports[NUM_PORTS] = {
219 static volatile unsigned char *shads[NUM_PORTS] = {
220 &port_pa_data_shadow,
224 /* What direction bits that are user changeable 1=changeable*/
225 #ifndef CONFIG_ETRAX_PA_CHANGEABLE_DIR
226 #define CONFIG_ETRAX_PA_CHANGEABLE_DIR 0x00
228 #ifndef CONFIG_ETRAX_PB_CHANGEABLE_DIR
229 #define CONFIG_ETRAX_PB_CHANGEABLE_DIR 0x00
232 #ifndef CONFIG_ETRAX_PA_CHANGEABLE_BITS
233 #define CONFIG_ETRAX_PA_CHANGEABLE_BITS 0xFF
235 #ifndef CONFIG_ETRAX_PB_CHANGEABLE_BITS
236 #define CONFIG_ETRAX_PB_CHANGEABLE_BITS 0xFF
240 static unsigned char changeable_dir[NUM_PORTS] = {
241 CONFIG_ETRAX_PA_CHANGEABLE_DIR,
242 CONFIG_ETRAX_PB_CHANGEABLE_DIR
244 static unsigned char changeable_bits[NUM_PORTS] = {
245 CONFIG_ETRAX_PA_CHANGEABLE_BITS,
246 CONFIG_ETRAX_PB_CHANGEABLE_BITS
249 static volatile unsigned char *dir[NUM_PORTS] = {
254 static volatile unsigned char *dir_shadow[NUM_PORTS] = {
259 /* All bits in port g that can change dir. */
260 static const unsigned long int changeable_dir_g_mask = 0x01FFFF01;
262 /* Port G is 32 bit, handle it special, some bits are both inputs
263 and outputs at the same time, only some of the bits can change direction
264 and some of them in groups of 8 bit. */
265 static unsigned long changeable_dir_g;
266 static unsigned long dir_g_in_bits;
267 static unsigned long dir_g_out_bits;
268 static unsigned long dir_g_shadow; /* 1=output */
270 #define USE_PORTS(priv) ((priv)->minor <= GPIO_MINOR_B)
275 gpio_poll(struct file *file,
278 unsigned int mask = 0;
279 struct gpio_private *priv = (struct gpio_private *)file->private_data;
281 spin_lock(&gpio_lock);
282 poll_wait(file, &priv->alarm_wq, wait);
283 if (priv->minor == GPIO_MINOR_A) {
286 data = *R_PORT_PA_DATA;
287 /* PA has support for high level interrupt -
288 * lets activate for those low and with highalarm set
290 tmp = ~data & priv->highalarm & 0xFF;
291 tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
292 local_irq_save(flags);
293 gpio_pa_irq_enabled_mask |= tmp;
294 *R_IRQ_MASK1_SET = tmp;
295 local_irq_restore(flags);
297 } else if (priv->minor == GPIO_MINOR_B)
298 data = *R_PORT_PB_DATA;
299 else if (priv->minor == GPIO_MINOR_G)
300 data = *R_PORT_G_DATA;
304 if ((data & priv->highalarm) ||
305 (~data & priv->lowalarm)) {
306 mask = POLLIN|POLLRDNORM;
309 spin_unlock(&gpio_lock);
311 DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
316 int etrax_gpio_wake_up_check(void)
318 struct gpio_private *priv = alarmlist;
319 unsigned long data = 0;
321 spin_lock(&gpio_lock);
323 if (USE_PORTS(priv)) {
325 } else if (priv->minor == GPIO_MINOR_G) {
326 data = *R_PORT_G_DATA;
328 if ((data & priv->highalarm) ||
329 (~data & priv->lowalarm)) {
330 DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor));
331 wake_up_interruptible(&priv->alarm_wq);
336 spin_unlock(&gpio_lock);
341 gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
343 if (gpio_some_alarms) {
344 etrax_gpio_wake_up_check();
351 gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
354 spin_lock(&gpio_lock);
355 /* Find what PA interrupts are active */
356 tmp = (*R_IRQ_READ1);
358 /* Find those that we have enabled */
359 tmp &= gpio_pa_irq_enabled_mask;
362 *R_IRQ_MASK1_CLR = tmp;
363 gpio_pa_irq_enabled_mask &= ~tmp;
365 spin_unlock(&gpio_lock);
367 if (gpio_some_alarms) {
368 return IRQ_RETVAL(etrax_gpio_wake_up_check());
374 static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
377 struct gpio_private *priv = (struct gpio_private *)file->private_data;
378 unsigned char data, clk_mask, data_mask, write_msb;
381 spin_lock(&gpio_lock);
383 ssize_t retval = count;
384 if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) {
388 if (!access_ok(VERIFY_READ, buf, count)) {
391 clk_mask = priv->clk_mask;
392 data_mask = priv->data_mask;
393 /* It must have been configured using the IO_CFG_WRITE_MODE */
394 /* Perhaps a better error code? */
395 if (clk_mask == 0 || data_mask == 0) {
398 write_msb = priv->write_msb;
399 D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb));
403 if (priv->write_msb) {
404 for (i = 7; i >= 0;i--) {
405 local_irq_save(flags);
406 *priv->port = *priv->shadow &= ~clk_mask;
408 *priv->port = *priv->shadow |= data_mask;
410 *priv->port = *priv->shadow &= ~data_mask;
411 /* For FPGA: min 5.0ns (DCC) before CCLK high */
412 *priv->port = *priv->shadow |= clk_mask;
413 local_irq_restore(flags);
416 for (i = 0; i <= 7;i++) {
417 local_irq_save(flags);
418 *priv->port = *priv->shadow &= ~clk_mask;
420 *priv->port = *priv->shadow |= data_mask;
422 *priv->port = *priv->shadow &= ~data_mask;
423 /* For FPGA: min 5.0ns (DCC) before CCLK high */
424 *priv->port = *priv->shadow |= clk_mask;
425 local_irq_restore(flags);
429 spin_unlock(&gpio_lock);
436 gpio_open(struct inode *inode, struct file *filp)
438 struct gpio_private *priv;
439 int p = MINOR(inode->i_rdev);
441 if (p > GPIO_MINOR_LAST)
444 priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private),
452 /* initialize the io/alarm struct and link it into our alarmlist */
454 priv->next = alarmlist;
456 if (USE_PORTS(priv)) { /* A and B */
457 priv->port = ports[p];
458 priv->shadow = shads[p];
460 priv->dir_shadow = dir_shadow[p];
461 priv->changeable_dir = changeable_dir[p];
462 priv->changeable_bits = changeable_bits[p];
467 priv->dir_shadow = NULL;
468 priv->changeable_dir = 0;
469 priv->changeable_bits = 0;
476 init_waitqueue_head(&priv->alarm_wq);
478 filp->private_data = (void *)priv;
484 gpio_release(struct inode *inode, struct file *filp)
486 struct gpio_private *p;
487 struct gpio_private *todel;
489 spin_lock(&gpio_lock);
492 todel = (struct gpio_private *)filp->private_data;
494 /* unlink from alarmlist and free the private structure */
497 alarmlist = todel->next;
499 while (p->next != todel)
501 p->next = todel->next;
505 /* Check if there are still any alarms set */
508 if (p->highalarm | p->lowalarm) {
509 gpio_some_alarms = 1;
514 gpio_some_alarms = 0;
515 spin_unlock(&gpio_lock);
519 /* Main device API. ioctl's to read/set/clear bits, as well as to
520 * set alarms to wait for using a subsequent select().
523 unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
525 /* Set direction 0=unchanged 1=input,
526 * return mask with 1=input
529 if (USE_PORTS(priv)) {
530 local_irq_save(flags);
531 *priv->dir = *priv->dir_shadow &=
532 ~((unsigned char)arg & priv->changeable_dir);
533 local_irq_restore(flags);
534 return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */
535 } else if (priv->minor == GPIO_MINOR_G) {
536 /* We must fiddle with R_GEN_CONFIG to change dir */
537 local_irq_save(flags);
538 if (((arg & dir_g_in_bits) != arg) &&
539 (arg & changeable_dir_g)) {
540 arg &= changeable_dir_g;
541 /* Clear bits in genconfig to set to input */
543 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g0dir);
544 dir_g_in_bits |= (1<<0);
545 dir_g_out_bits &= ~(1<<0);
547 if ((arg & 0x0000FF00) == 0x0000FF00) {
548 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g8_15dir);
549 dir_g_in_bits |= 0x0000FF00;
550 dir_g_out_bits &= ~0x0000FF00;
552 if ((arg & 0x00FF0000) == 0x00FF0000) {
553 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g16_23dir);
554 dir_g_in_bits |= 0x00FF0000;
555 dir_g_out_bits &= ~0x00FF0000;
558 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g24dir);
559 dir_g_in_bits |= (1<<24);
560 dir_g_out_bits &= ~(1<<24);
562 D(printk(KERN_INFO "gpio: SETINPUT on port G set "
563 "genconfig to 0x%08lX "
565 "out_bits: 0x%08lX\n",
566 (unsigned long)genconfig_shadow,
567 dir_g_in_bits, dir_g_out_bits));
568 *R_GEN_CONFIG = genconfig_shadow;
569 /* Must be a >120 ns delay before writing this again */
572 local_irq_restore(flags);
573 return dir_g_in_bits;
578 unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
581 if (USE_PORTS(priv)) {
582 local_irq_save(flags);
583 *priv->dir = *priv->dir_shadow |=
584 ((unsigned char)arg & priv->changeable_dir);
585 local_irq_restore(flags);
586 return *priv->dir_shadow;
587 } else if (priv->minor == GPIO_MINOR_G) {
588 /* We must fiddle with R_GEN_CONFIG to change dir */
589 local_irq_save(flags);
590 if (((arg & dir_g_out_bits) != arg) &&
591 (arg & changeable_dir_g)) {
592 /* Set bits in genconfig to set to output */
594 genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g0dir);
595 dir_g_out_bits |= (1<<0);
596 dir_g_in_bits &= ~(1<<0);
598 if ((arg & 0x0000FF00) == 0x0000FF00) {
599 genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir);
600 dir_g_out_bits |= 0x0000FF00;
601 dir_g_in_bits &= ~0x0000FF00;
603 if ((arg & 0x00FF0000) == 0x00FF0000) {
604 genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir);
605 dir_g_out_bits |= 0x00FF0000;
606 dir_g_in_bits &= ~0x00FF0000;
609 genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g24dir);
610 dir_g_out_bits |= (1<<24);
611 dir_g_in_bits &= ~(1<<24);
613 D(printk(KERN_INFO "gpio: SETOUTPUT on port G set "
614 "genconfig to 0x%08lX "
616 "out_bits: 0x%08lX\n",
617 (unsigned long)genconfig_shadow,
618 dir_g_in_bits, dir_g_out_bits));
619 *R_GEN_CONFIG = genconfig_shadow;
620 /* Must be a >120 ns delay before writing this again */
622 local_irq_restore(flags);
623 return dir_g_out_bits & 0x7FFFFFFF;
626 } /* setget_output */
629 gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
632 gpio_ioctl(struct inode *inode, struct file *file,
633 unsigned int cmd, unsigned long arg)
639 struct gpio_private *priv = (struct gpio_private *)file->private_data;
640 if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) {
644 spin_lock(&gpio_lock);
646 switch (_IOC_NR(cmd)) {
647 case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
649 if (USE_PORTS(priv)) {
651 } else if (priv->minor == GPIO_MINOR_G) {
652 ret = (*R_PORT_G_DATA) & 0x7FFFFFFF;
656 local_irq_save(flags);
657 // set changeable bits with a 1 in arg
658 if (USE_PORTS(priv)) {
659 *priv->port = *priv->shadow |=
660 ((unsigned char)arg & priv->changeable_bits);
661 } else if (priv->minor == GPIO_MINOR_G) {
662 *R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits);
664 local_irq_restore(flags);
667 local_irq_save(flags);
668 // clear changeable bits with a 1 in arg
669 if (USE_PORTS(priv)) {
670 *priv->port = *priv->shadow &=
671 ~((unsigned char)arg & priv->changeable_bits);
672 } else if (priv->minor == GPIO_MINOR_G) {
673 *R_PORT_G_DATA = port_g_data_shadow &= ~((unsigned long)arg & dir_g_out_bits);
675 local_irq_restore(flags);
678 // set alarm when bits with 1 in arg go high
679 priv->highalarm |= arg;
680 gpio_some_alarms = 1;
683 // set alarm when bits with 1 in arg go low
684 priv->lowalarm |= arg;
685 gpio_some_alarms = 1;
688 // clear alarm for bits with 1 in arg
689 priv->highalarm &= ~arg;
690 priv->lowalarm &= ~arg;
692 /* Must update gpio_some_alarms */
693 struct gpio_private *p = alarmlist;
697 if (p->highalarm | p->lowalarm) {
703 gpio_some_alarms = some_alarms;
706 case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
707 /* Read direction 0=input 1=output */
708 if (USE_PORTS(priv)) {
709 ret = *priv->dir_shadow;
710 } else if (priv->minor == GPIO_MINOR_G) {
711 /* Note: Some bits are both in and out,
712 * Those that are dual is set here as well.
714 ret = (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
717 case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
718 /* Set direction 0=unchanged 1=input,
719 * return mask with 1=input
721 ret = setget_input(priv, arg) & 0x7FFFFFFF;
723 case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
724 /* Set direction 0=unchanged 1=output,
725 * return mask with 1=output
727 ret = setget_output(priv, arg) & 0x7FFFFFFF;
733 #if defined (CONFIG_ETRAX_SOFT_SHUTDOWN)
734 ret = (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
739 case IO_CFG_WRITE_MODE:
740 priv->clk_mask = arg & 0xFF;
741 priv->data_mask = (arg >> 8) & 0xFF;
742 priv->write_msb = (arg >> 16) & 0x01;
743 /* Check if we're allowed to change the bits and
744 * the direction is correct
746 if (!((priv->clk_mask & priv->changeable_bits) &&
747 (priv->data_mask & priv->changeable_bits) &&
748 (priv->clk_mask & *priv->dir_shadow) &&
749 (priv->data_mask & *priv->dir_shadow)))
757 /* *arg is result of reading the input pins */
758 if (USE_PORTS(priv)) {
760 } else if (priv->minor == GPIO_MINOR_G) {
761 val = *R_PORT_G_DATA;
763 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
766 case IO_READ_OUTBITS:
767 /* *arg is result of reading the output shadow */
768 if (USE_PORTS(priv)) {
770 } else if (priv->minor == GPIO_MINOR_G) {
771 val = port_g_data_shadow;
773 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
776 case IO_SETGET_INPUT:
777 /* bits set in *arg is set to input,
778 * *arg updated with current input pins.
780 if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
785 val = setget_input(priv, val);
786 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
789 case IO_SETGET_OUTPUT:
790 /* bits set in *arg is set to output,
791 * *arg updated with current output pins.
793 if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
798 val = setget_output(priv, val);
799 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
803 if (priv->minor == GPIO_MINOR_LEDS)
804 ret = gpio_leds_ioctl(cmd, arg);
809 spin_unlock(&gpio_lock);
814 gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
819 switch (_IOC_NR(cmd)) {
820 case IO_LEDACTIVE_SET:
821 green = ((unsigned char) arg) & 1;
822 red = (((unsigned char) arg) >> 1) & 1;
823 LED_ACTIVE_SET_G(green);
824 LED_ACTIVE_SET_R(red);
842 struct file_operations gpio_fops = {
843 .owner = THIS_MODULE,
848 .release = gpio_release,
852 void ioif_watcher(const unsigned int gpio_in_available,
853 const unsigned int gpio_out_available,
854 const unsigned char pa_available,
855 const unsigned char pb_available)
857 unsigned long int flags;
858 D(printk("gpio.c: ioif_watcher called\n"));
859 D(printk("gpio.c: G in: 0x%08x G out: 0x%08x PA: 0x%02x PB: 0x%02x\n",
860 gpio_in_available, gpio_out_available, pa_available, pb_available));
862 spin_lock_irqsave(&gpio_lock, flags);
864 dir_g_in_bits = gpio_in_available;
865 dir_g_out_bits = gpio_out_available;
867 /* Initialise the dir_g_shadow etc. depending on genconfig */
868 /* 0=input 1=output */
869 if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g0dir, out))
870 dir_g_shadow |= (1 << 0);
871 if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g8_15dir, out))
872 dir_g_shadow |= 0x0000FF00;
873 if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g16_23dir, out))
874 dir_g_shadow |= 0x00FF0000;
875 if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g24dir, out))
876 dir_g_shadow |= (1 << 24);
878 changeable_dir_g = changeable_dir_g_mask;
879 changeable_dir_g &= dir_g_out_bits;
880 changeable_dir_g &= dir_g_in_bits;
881 /* Correct the bits that can change direction */
882 dir_g_out_bits &= ~changeable_dir_g;
883 dir_g_out_bits |= dir_g_shadow;
884 dir_g_in_bits &= ~changeable_dir_g;
885 dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g);
887 spin_unlock_irqrestore(&gpio_lock, flags);
889 printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n",
890 dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA);
891 printk(KERN_INFO "GPIO port G: dir: %08lX changeable: %08lX\n",
892 dir_g_shadow, changeable_dir_g);
895 /* main driver initialization routine, called from mem.c */
901 #if defined (CONFIG_ETRAX_CSP0_LEDS)
904 printk("gpio init\n");
906 /* do the formalities */
908 res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
910 printk(KERN_ERR "gpio: couldn't get a major number.\n");
915 #if defined (CONFIG_ETRAX_CSP0_LEDS) || defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS)
921 #if defined (CONFIG_ETRAX_CSP0_LEDS)
922 for (i = 0; i < 32; i++) {
928 /* The I/O interface allocation watcher will be called when
930 if (cris_io_interface_register_watcher(ioif_watcher)){
931 printk(KERN_WARNING "gpio_init: Failed to install IO if allocator watcher\n");
934 printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002, 2003, 2004 Axis Communications AB\n");
935 /* We call etrax_gpio_wake_up_check() from timer interrupt and
936 * from cpu_idle() in kernel/process.c
937 * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
940 if (request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
941 SA_SHIRQ | SA_INTERRUPT,"gpio poll", NULL)) {
942 printk(KERN_CRIT "err: timer0 irq for gpio\n");
944 if (request_irq(PA_IRQ_NBR, gpio_pa_interrupt,
945 SA_SHIRQ | SA_INTERRUPT,"gpio PA", NULL)) {
946 printk(KERN_CRIT "err: PA irq for gpio\n");
953 /* this makes sure that gpio_init is called during kernel boot */
955 module_init(gpio_init);