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
139 #include <linux/module.h>
140 #include <linux/sched.h>
141 #include <linux/slab.h>
142 #include <linux/ioport.h>
143 #include <linux/errno.h>
144 #include <linux/kernel.h>
145 #include <linux/fs.h>
146 #include <linux/string.h>
147 #include <linux/poll.h>
148 #include <linux/init.h>
149 #include <linux/interrupt.h>
151 #include <asm/etraxgpio.h>
152 #include <asm/arch/svinto.h>
154 #include <asm/system.h>
156 #include <asm/arch/io_interface_mux.h>
158 #define GPIO_MAJOR 120 /* experimental MAJOR number */
164 #define DP(x) do { dp_cnt++; if (dp_cnt % 1000 == 0) x; }while(0)
169 static char gpio_name[] = "etrax gpio";
172 static wait_queue_head_t *gpio_wq;
175 static int gpio_ioctl(struct inode *inode, struct file *file,
176 unsigned int cmd, unsigned long arg);
177 static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
179 static int gpio_open(struct inode *inode, struct file *filp);
180 static int gpio_release(struct inode *inode, struct file *filp);
181 static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait);
183 /* private data per open() of this driver */
185 struct gpio_private {
186 struct gpio_private *next;
187 /* These fields are for PA and PB only */
188 volatile unsigned char *port, *shadow;
189 volatile unsigned char *dir, *dir_shadow;
190 unsigned char changeable_dir;
191 unsigned char changeable_bits;
192 unsigned char clk_mask;
193 unsigned char data_mask;
194 unsigned char write_msb;
195 unsigned char pad1, pad2, pad3;
196 /* These fields are generic */
197 unsigned long highalarm, lowalarm;
198 wait_queue_head_t alarm_wq;
202 /* linked list of alarms to check for */
204 static struct gpio_private *alarmlist = 0;
206 static int gpio_some_alarms = 0; /* Set if someone uses alarm */
207 static unsigned long gpio_pa_irq_enabled_mask = 0;
209 static DEFINE_SPINLOCK(gpio_lock); /* Protect directions etc */
211 /* Port A and B use 8 bit access, but Port G is 32 bit */
212 #define NUM_PORTS (GPIO_MINOR_B+1)
214 static volatile unsigned char *ports[NUM_PORTS] = {
218 static volatile unsigned char *shads[NUM_PORTS] = {
219 &port_pa_data_shadow,
223 /* What direction bits that are user changeable 1=changeable*/
224 #ifndef CONFIG_ETRAX_PA_CHANGEABLE_DIR
225 #define CONFIG_ETRAX_PA_CHANGEABLE_DIR 0x00
227 #ifndef CONFIG_ETRAX_PB_CHANGEABLE_DIR
228 #define CONFIG_ETRAX_PB_CHANGEABLE_DIR 0x00
231 #ifndef CONFIG_ETRAX_PA_CHANGEABLE_BITS
232 #define CONFIG_ETRAX_PA_CHANGEABLE_BITS 0xFF
234 #ifndef CONFIG_ETRAX_PB_CHANGEABLE_BITS
235 #define CONFIG_ETRAX_PB_CHANGEABLE_BITS 0xFF
239 static unsigned char changeable_dir[NUM_PORTS] = {
240 CONFIG_ETRAX_PA_CHANGEABLE_DIR,
241 CONFIG_ETRAX_PB_CHANGEABLE_DIR
243 static unsigned char changeable_bits[NUM_PORTS] = {
244 CONFIG_ETRAX_PA_CHANGEABLE_BITS,
245 CONFIG_ETRAX_PB_CHANGEABLE_BITS
248 static volatile unsigned char *dir[NUM_PORTS] = {
253 static volatile unsigned char *dir_shadow[NUM_PORTS] = {
258 /* All bits in port g that can change dir. */
259 static const unsigned long int changeable_dir_g_mask = 0x01FFFF01;
261 /* Port G is 32 bit, handle it special, some bits are both inputs
262 and outputs at the same time, only some of the bits can change direction
263 and some of them in groups of 8 bit. */
264 static unsigned long changeable_dir_g;
265 static unsigned long dir_g_in_bits;
266 static unsigned long dir_g_out_bits;
267 static unsigned long dir_g_shadow; /* 1=output */
269 #define USE_PORTS(priv) ((priv)->minor <= GPIO_MINOR_B)
274 gpio_poll(struct file *file,
277 unsigned int mask = 0;
278 struct gpio_private *priv = (struct gpio_private *)file->private_data;
280 spin_lock(&gpio_lock);
281 poll_wait(file, &priv->alarm_wq, wait);
282 if (priv->minor == GPIO_MINOR_A) {
285 data = *R_PORT_PA_DATA;
286 /* PA has support for high level interrupt -
287 * lets activate for those low and with highalarm set
289 tmp = ~data & priv->highalarm & 0xFF;
290 tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
291 local_irq_save(flags);
292 gpio_pa_irq_enabled_mask |= tmp;
293 *R_IRQ_MASK1_SET = tmp;
294 local_irq_restore(flags);
296 } else if (priv->minor == GPIO_MINOR_B)
297 data = *R_PORT_PB_DATA;
298 else if (priv->minor == GPIO_MINOR_G)
299 data = *R_PORT_G_DATA;
301 spin_unlock(&gpio_lock);
305 if ((data & priv->highalarm) ||
306 (~data & priv->lowalarm)) {
307 mask = POLLIN|POLLRDNORM;
310 spin_unlock(&gpio_lock);
312 DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
317 int etrax_gpio_wake_up_check(void)
319 struct gpio_private *priv = alarmlist;
320 unsigned long data = 0;
322 spin_lock(&gpio_lock);
324 if (USE_PORTS(priv)) {
326 } else if (priv->minor == GPIO_MINOR_G) {
327 data = *R_PORT_G_DATA;
329 if ((data & priv->highalarm) ||
330 (~data & priv->lowalarm)) {
331 DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor));
332 wake_up_interruptible(&priv->alarm_wq);
337 spin_unlock(&gpio_lock);
342 gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
344 if (gpio_some_alarms) {
345 etrax_gpio_wake_up_check();
352 gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
355 spin_lock(&gpio_lock);
356 /* Find what PA interrupts are active */
357 tmp = (*R_IRQ_READ1);
359 /* Find those that we have enabled */
360 tmp &= gpio_pa_irq_enabled_mask;
363 *R_IRQ_MASK1_CLR = tmp;
364 gpio_pa_irq_enabled_mask &= ~tmp;
366 spin_unlock(&gpio_lock);
368 if (gpio_some_alarms) {
369 return IRQ_RETVAL(etrax_gpio_wake_up_check());
375 static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
378 struct gpio_private *priv = (struct gpio_private *)file->private_data;
379 unsigned char data, clk_mask, data_mask, write_msb;
382 spin_lock(&gpio_lock);
384 ssize_t retval = count;
385 if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) {
390 if (!access_ok(VERIFY_READ, buf, count)) {
394 clk_mask = priv->clk_mask;
395 data_mask = priv->data_mask;
396 /* It must have been configured using the IO_CFG_WRITE_MODE */
397 /* Perhaps a better error code? */
398 if (clk_mask == 0 || data_mask == 0) {
402 write_msb = priv->write_msb;
403 D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb));
407 if (priv->write_msb) {
408 for (i = 7; i >= 0;i--) {
409 local_irq_save(flags);
410 *priv->port = *priv->shadow &= ~clk_mask;
412 *priv->port = *priv->shadow |= data_mask;
414 *priv->port = *priv->shadow &= ~data_mask;
415 /* For FPGA: min 5.0ns (DCC) before CCLK high */
416 *priv->port = *priv->shadow |= clk_mask;
417 local_irq_restore(flags);
420 for (i = 0; i <= 7;i++) {
421 local_irq_save(flags);
422 *priv->port = *priv->shadow &= ~clk_mask;
424 *priv->port = *priv->shadow |= data_mask;
426 *priv->port = *priv->shadow &= ~data_mask;
427 /* For FPGA: min 5.0ns (DCC) before CCLK high */
428 *priv->port = *priv->shadow |= clk_mask;
429 local_irq_restore(flags);
434 spin_unlock(&gpio_lock);
441 gpio_open(struct inode *inode, struct file *filp)
443 struct gpio_private *priv;
444 int p = iminor(inode);
446 if (p > GPIO_MINOR_LAST)
449 priv = kmalloc(sizeof(struct gpio_private),
457 /* initialize the io/alarm struct and link it into our alarmlist */
459 priv->next = alarmlist;
461 if (USE_PORTS(priv)) { /* A and B */
462 priv->port = ports[p];
463 priv->shadow = shads[p];
465 priv->dir_shadow = dir_shadow[p];
466 priv->changeable_dir = changeable_dir[p];
467 priv->changeable_bits = changeable_bits[p];
472 priv->dir_shadow = NULL;
473 priv->changeable_dir = 0;
474 priv->changeable_bits = 0;
481 init_waitqueue_head(&priv->alarm_wq);
483 filp->private_data = (void *)priv;
489 gpio_release(struct inode *inode, struct file *filp)
491 struct gpio_private *p;
492 struct gpio_private *todel;
494 spin_lock(&gpio_lock);
497 todel = (struct gpio_private *)filp->private_data;
499 /* unlink from alarmlist and free the private structure */
502 alarmlist = todel->next;
504 while (p->next != todel)
506 p->next = todel->next;
510 /* Check if there are still any alarms set */
513 if (p->highalarm | p->lowalarm) {
514 gpio_some_alarms = 1;
515 spin_unlock(&gpio_lock);
520 gpio_some_alarms = 0;
521 spin_unlock(&gpio_lock);
525 /* Main device API. ioctl's to read/set/clear bits, as well as to
526 * set alarms to wait for using a subsequent select().
529 unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
531 /* Set direction 0=unchanged 1=input,
532 * return mask with 1=input
535 if (USE_PORTS(priv)) {
536 local_irq_save(flags);
537 *priv->dir = *priv->dir_shadow &=
538 ~((unsigned char)arg & priv->changeable_dir);
539 local_irq_restore(flags);
540 return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */
541 } else if (priv->minor == GPIO_MINOR_G) {
542 /* We must fiddle with R_GEN_CONFIG to change dir */
543 local_irq_save(flags);
544 if (((arg & dir_g_in_bits) != arg) &&
545 (arg & changeable_dir_g)) {
546 arg &= changeable_dir_g;
547 /* Clear bits in genconfig to set to input */
549 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g0dir);
550 dir_g_in_bits |= (1<<0);
551 dir_g_out_bits &= ~(1<<0);
553 if ((arg & 0x0000FF00) == 0x0000FF00) {
554 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g8_15dir);
555 dir_g_in_bits |= 0x0000FF00;
556 dir_g_out_bits &= ~0x0000FF00;
558 if ((arg & 0x00FF0000) == 0x00FF0000) {
559 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g16_23dir);
560 dir_g_in_bits |= 0x00FF0000;
561 dir_g_out_bits &= ~0x00FF0000;
564 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g24dir);
565 dir_g_in_bits |= (1<<24);
566 dir_g_out_bits &= ~(1<<24);
568 D(printk(KERN_INFO "gpio: SETINPUT on port G set "
569 "genconfig to 0x%08lX "
571 "out_bits: 0x%08lX\n",
572 (unsigned long)genconfig_shadow,
573 dir_g_in_bits, dir_g_out_bits));
574 *R_GEN_CONFIG = genconfig_shadow;
575 /* Must be a >120 ns delay before writing this again */
578 local_irq_restore(flags);
579 return dir_g_in_bits;
584 unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
587 if (USE_PORTS(priv)) {
588 local_irq_save(flags);
589 *priv->dir = *priv->dir_shadow |=
590 ((unsigned char)arg & priv->changeable_dir);
591 local_irq_restore(flags);
592 return *priv->dir_shadow;
593 } else if (priv->minor == GPIO_MINOR_G) {
594 /* We must fiddle with R_GEN_CONFIG to change dir */
595 local_irq_save(flags);
596 if (((arg & dir_g_out_bits) != arg) &&
597 (arg & changeable_dir_g)) {
598 /* Set bits in genconfig to set to output */
600 genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g0dir);
601 dir_g_out_bits |= (1<<0);
602 dir_g_in_bits &= ~(1<<0);
604 if ((arg & 0x0000FF00) == 0x0000FF00) {
605 genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir);
606 dir_g_out_bits |= 0x0000FF00;
607 dir_g_in_bits &= ~0x0000FF00;
609 if ((arg & 0x00FF0000) == 0x00FF0000) {
610 genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir);
611 dir_g_out_bits |= 0x00FF0000;
612 dir_g_in_bits &= ~0x00FF0000;
615 genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g24dir);
616 dir_g_out_bits |= (1<<24);
617 dir_g_in_bits &= ~(1<<24);
619 D(printk(KERN_INFO "gpio: SETOUTPUT on port G set "
620 "genconfig to 0x%08lX "
622 "out_bits: 0x%08lX\n",
623 (unsigned long)genconfig_shadow,
624 dir_g_in_bits, dir_g_out_bits));
625 *R_GEN_CONFIG = genconfig_shadow;
626 /* Must be a >120 ns delay before writing this again */
628 local_irq_restore(flags);
629 return dir_g_out_bits & 0x7FFFFFFF;
632 } /* setget_output */
635 gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
638 gpio_ioctl(struct inode *inode, struct file *file,
639 unsigned int cmd, unsigned long arg)
645 struct gpio_private *priv = (struct gpio_private *)file->private_data;
646 if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) {
650 spin_lock(&gpio_lock);
652 switch (_IOC_NR(cmd)) {
653 case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
655 if (USE_PORTS(priv)) {
657 } else if (priv->minor == GPIO_MINOR_G) {
658 ret = (*R_PORT_G_DATA) & 0x7FFFFFFF;
662 local_irq_save(flags);
663 // set changeable bits with a 1 in arg
664 if (USE_PORTS(priv)) {
665 *priv->port = *priv->shadow |=
666 ((unsigned char)arg & priv->changeable_bits);
667 } else if (priv->minor == GPIO_MINOR_G) {
668 *R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits);
670 local_irq_restore(flags);
673 local_irq_save(flags);
674 // clear changeable bits with a 1 in arg
675 if (USE_PORTS(priv)) {
676 *priv->port = *priv->shadow &=
677 ~((unsigned char)arg & priv->changeable_bits);
678 } else if (priv->minor == GPIO_MINOR_G) {
679 *R_PORT_G_DATA = port_g_data_shadow &= ~((unsigned long)arg & dir_g_out_bits);
681 local_irq_restore(flags);
684 // set alarm when bits with 1 in arg go high
685 priv->highalarm |= arg;
686 gpio_some_alarms = 1;
689 // set alarm when bits with 1 in arg go low
690 priv->lowalarm |= arg;
691 gpio_some_alarms = 1;
694 // clear alarm for bits with 1 in arg
695 priv->highalarm &= ~arg;
696 priv->lowalarm &= ~arg;
698 /* Must update gpio_some_alarms */
699 struct gpio_private *p = alarmlist;
703 if (p->highalarm | p->lowalarm) {
709 gpio_some_alarms = some_alarms;
712 case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
713 /* Read direction 0=input 1=output */
714 if (USE_PORTS(priv)) {
715 ret = *priv->dir_shadow;
716 } else if (priv->minor == GPIO_MINOR_G) {
717 /* Note: Some bits are both in and out,
718 * Those that are dual is set here as well.
720 ret = (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
723 case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
724 /* Set direction 0=unchanged 1=input,
725 * return mask with 1=input
727 ret = setget_input(priv, arg) & 0x7FFFFFFF;
729 case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
730 /* Set direction 0=unchanged 1=output,
731 * return mask with 1=output
733 ret = setget_output(priv, arg) & 0x7FFFFFFF;
739 #if defined (CONFIG_ETRAX_SOFT_SHUTDOWN)
740 ret = (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
745 case IO_CFG_WRITE_MODE:
746 priv->clk_mask = arg & 0xFF;
747 priv->data_mask = (arg >> 8) & 0xFF;
748 priv->write_msb = (arg >> 16) & 0x01;
749 /* Check if we're allowed to change the bits and
750 * the direction is correct
752 if (!((priv->clk_mask & priv->changeable_bits) &&
753 (priv->data_mask & priv->changeable_bits) &&
754 (priv->clk_mask & *priv->dir_shadow) &&
755 (priv->data_mask & *priv->dir_shadow)))
763 /* *arg is result of reading the input pins */
764 if (USE_PORTS(priv)) {
766 } else if (priv->minor == GPIO_MINOR_G) {
767 val = *R_PORT_G_DATA;
769 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
772 case IO_READ_OUTBITS:
773 /* *arg is result of reading the output shadow */
774 if (USE_PORTS(priv)) {
776 } else if (priv->minor == GPIO_MINOR_G) {
777 val = port_g_data_shadow;
779 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
782 case IO_SETGET_INPUT:
783 /* bits set in *arg is set to input,
784 * *arg updated with current input pins.
786 if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
791 val = setget_input(priv, val);
792 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
795 case IO_SETGET_OUTPUT:
796 /* bits set in *arg is set to output,
797 * *arg updated with current output pins.
799 if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
804 val = setget_output(priv, val);
805 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
809 if (priv->minor == GPIO_MINOR_LEDS)
810 ret = gpio_leds_ioctl(cmd, arg);
815 spin_unlock(&gpio_lock);
820 gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
825 switch (_IOC_NR(cmd)) {
826 case IO_LEDACTIVE_SET:
827 green = ((unsigned char) arg) & 1;
828 red = (((unsigned char) arg) >> 1) & 1;
829 LED_ACTIVE_SET_G(green);
830 LED_ACTIVE_SET_R(red);
848 const struct file_operations gpio_fops = {
849 .owner = THIS_MODULE,
854 .release = gpio_release,
858 void ioif_watcher(const unsigned int gpio_in_available,
859 const unsigned int gpio_out_available,
860 const unsigned char pa_available,
861 const unsigned char pb_available)
863 unsigned long int flags;
864 D(printk("gpio.c: ioif_watcher called\n"));
865 D(printk("gpio.c: G in: 0x%08x G out: 0x%08x PA: 0x%02x PB: 0x%02x\n",
866 gpio_in_available, gpio_out_available, pa_available, pb_available));
868 spin_lock_irqsave(&gpio_lock, flags);
870 dir_g_in_bits = gpio_in_available;
871 dir_g_out_bits = gpio_out_available;
873 /* Initialise the dir_g_shadow etc. depending on genconfig */
874 /* 0=input 1=output */
875 if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g0dir, out))
876 dir_g_shadow |= (1 << 0);
877 if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g8_15dir, out))
878 dir_g_shadow |= 0x0000FF00;
879 if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g16_23dir, out))
880 dir_g_shadow |= 0x00FF0000;
881 if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g24dir, out))
882 dir_g_shadow |= (1 << 24);
884 changeable_dir_g = changeable_dir_g_mask;
885 changeable_dir_g &= dir_g_out_bits;
886 changeable_dir_g &= dir_g_in_bits;
887 /* Correct the bits that can change direction */
888 dir_g_out_bits &= ~changeable_dir_g;
889 dir_g_out_bits |= dir_g_shadow;
890 dir_g_in_bits &= ~changeable_dir_g;
891 dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g);
893 spin_unlock_irqrestore(&gpio_lock, flags);
895 printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n",
896 dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA);
897 printk(KERN_INFO "GPIO port G: dir: %08lX changeable: %08lX\n",
898 dir_g_shadow, changeable_dir_g);
901 /* main driver initialization routine, called from mem.c */
907 #if defined (CONFIG_ETRAX_CSP0_LEDS)
910 printk("gpio init\n");
912 /* do the formalities */
914 res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
916 printk(KERN_ERR "gpio: couldn't get a major number.\n");
921 #if defined (CONFIG_ETRAX_CSP0_LEDS) || defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS)
927 #if defined (CONFIG_ETRAX_CSP0_LEDS)
928 for (i = 0; i < 32; i++) {
934 /* The I/O interface allocation watcher will be called when
936 if (cris_io_interface_register_watcher(ioif_watcher)){
937 printk(KERN_WARNING "gpio_init: Failed to install IO if allocator watcher\n");
940 printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002, 2003, 2004 Axis Communications AB\n");
941 /* We call etrax_gpio_wake_up_check() from timer interrupt and
942 * from cpu_idle() in kernel/process.c
943 * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
946 if (request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
947 IRQF_SHARED | IRQF_DISABLED,"gpio poll", NULL)) {
948 printk(KERN_CRIT "err: timer0 irq for gpio\n");
950 if (request_irq(PA_IRQ_NBR, gpio_pa_interrupt,
951 IRQF_SHARED | IRQF_DISABLED,"gpio PA", NULL)) {
952 printk(KERN_CRIT "err: PA irq for gpio\n");
959 /* this makes sure that gpio_init is called during kernel boot */
961 module_init(gpio_init);