2 * ETRAX CRISv32 general port I/O device
4 * Copyright (c) 1999-2006 Axis Communications AB
6 * Authors: Bjorn Wesen (initial version)
7 * Ola Knutsson (LED handling)
8 * Johan Adolfsson (read/set directions, write, port G,
13 #include <linux/module.h>
14 #include <linux/sched.h>
15 #include <linux/slab.h>
16 #include <linux/ioport.h>
17 #include <linux/errno.h>
18 #include <linux/kernel.h>
20 #include <linux/string.h>
21 #include <linux/poll.h>
22 #include <linux/init.h>
23 #include <linux/interrupt.h>
24 #include <linux/spinlock.h>
25 #include <linux/smp_lock.h>
27 #include <asm/etraxgpio.h>
28 #include <hwregs/reg_map.h>
29 #include <hwregs/reg_rdwr.h>
30 #include <hwregs/gio_defs.h>
31 #include <hwregs/intr_vect_defs.h>
33 #include <asm/system.h>
36 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
39 #define VIRT_I2C_ADDR 0x40
42 /* The following gio ports on ETRAX FS is available:
43 * pa 8 bits, supports interrupts off, hi, low, set, posedge, negedge anyedge
48 * each port has a rw_px_dout, r_px_din and rw_px_oe register.
51 #define GPIO_MAJOR 120 /* experimental MAJOR number */
57 static char gpio_name
[] = "etrax gpio";
60 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
61 static int virtual_gpio_ioctl(struct file
*file
, unsigned int cmd
,
64 static long gpio_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
);
65 static ssize_t
gpio_write(struct file
*file
, const char *buf
, size_t count
,
67 static int gpio_open(struct inode
*inode
, struct file
*filp
);
68 static int gpio_release(struct inode
*inode
, struct file
*filp
);
69 static unsigned int gpio_poll(struct file
*filp
,
70 struct poll_table_struct
*wait
);
72 /* private data per open() of this driver */
75 struct gpio_private
*next
;
76 /* The IO_CFG_WRITE_MODE_VALUE only support 8 bits: */
77 unsigned char clk_mask
;
78 unsigned char data_mask
;
79 unsigned char write_msb
;
81 /* These fields are generic */
82 unsigned long highalarm
, lowalarm
;
83 wait_queue_head_t alarm_wq
;
87 /* linked list of alarms to check for */
89 static struct gpio_private
*alarmlist
;
91 static int gpio_some_alarms
; /* Set if someone uses alarm */
92 static unsigned long gpio_pa_high_alarms
;
93 static unsigned long gpio_pa_low_alarms
;
95 static DEFINE_SPINLOCK(alarm_lock
);
97 #define NUM_PORTS (GPIO_MINOR_LAST+1)
98 #define GIO_REG_RD_ADDR(reg) \
99 (volatile unsigned long *)(regi_gio + REG_RD_ADDR_gio_##reg)
100 #define GIO_REG_WR_ADDR(reg) \
101 (volatile unsigned long *)(regi_gio + REG_RD_ADDR_gio_##reg)
102 unsigned long led_dummy
;
103 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
104 static unsigned long virtual_dummy
;
105 static unsigned long virtual_rw_pv_oe
= CONFIG_ETRAX_DEF_GIO_PV_OE
;
106 static unsigned short cached_virtual_gpio_read
;
109 static volatile unsigned long *data_out
[NUM_PORTS
] = {
110 GIO_REG_WR_ADDR(rw_pa_dout
),
111 GIO_REG_WR_ADDR(rw_pb_dout
),
113 GIO_REG_WR_ADDR(rw_pc_dout
),
114 GIO_REG_WR_ADDR(rw_pd_dout
),
115 GIO_REG_WR_ADDR(rw_pe_dout
),
116 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
121 static volatile unsigned long *data_in
[NUM_PORTS
] = {
122 GIO_REG_RD_ADDR(r_pa_din
),
123 GIO_REG_RD_ADDR(r_pb_din
),
125 GIO_REG_RD_ADDR(r_pc_din
),
126 GIO_REG_RD_ADDR(r_pd_din
),
127 GIO_REG_RD_ADDR(r_pe_din
),
128 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
133 static unsigned long changeable_dir
[NUM_PORTS
] = {
134 CONFIG_ETRAX_PA_CHANGEABLE_DIR
,
135 CONFIG_ETRAX_PB_CHANGEABLE_DIR
,
137 CONFIG_ETRAX_PC_CHANGEABLE_DIR
,
138 CONFIG_ETRAX_PD_CHANGEABLE_DIR
,
139 CONFIG_ETRAX_PE_CHANGEABLE_DIR
,
140 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
141 CONFIG_ETRAX_PV_CHANGEABLE_DIR
,
145 static unsigned long changeable_bits
[NUM_PORTS
] = {
146 CONFIG_ETRAX_PA_CHANGEABLE_BITS
,
147 CONFIG_ETRAX_PB_CHANGEABLE_BITS
,
149 CONFIG_ETRAX_PC_CHANGEABLE_BITS
,
150 CONFIG_ETRAX_PD_CHANGEABLE_BITS
,
151 CONFIG_ETRAX_PE_CHANGEABLE_BITS
,
152 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
153 CONFIG_ETRAX_PV_CHANGEABLE_BITS
,
157 static volatile unsigned long *dir_oe
[NUM_PORTS
] = {
158 GIO_REG_WR_ADDR(rw_pa_oe
),
159 GIO_REG_WR_ADDR(rw_pb_oe
),
161 GIO_REG_WR_ADDR(rw_pc_oe
),
162 GIO_REG_WR_ADDR(rw_pd_oe
),
163 GIO_REG_WR_ADDR(rw_pe_oe
),
164 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
171 static unsigned int gpio_poll(struct file
*file
, struct poll_table_struct
*wait
)
173 unsigned int mask
= 0;
174 struct gpio_private
*priv
= file
->private_data
;
176 poll_wait(file
, &priv
->alarm_wq
, wait
);
177 if (priv
->minor
== GPIO_MINOR_A
) {
178 reg_gio_rw_intr_cfg intr_cfg
;
182 local_irq_save(flags
);
183 data
= REG_TYPE_CONV(unsigned long, reg_gio_r_pa_din
,
184 REG_RD(gio
, regi_gio
, r_pa_din
));
185 /* PA has support for interrupt
186 * lets activate high for those low and with highalarm set
188 intr_cfg
= REG_RD(gio
, regi_gio
, rw_intr_cfg
);
190 tmp
= ~data
& priv
->highalarm
& 0xFF;
192 intr_cfg
.pa0
= regk_gio_hi
;
194 intr_cfg
.pa1
= regk_gio_hi
;
196 intr_cfg
.pa2
= regk_gio_hi
;
198 intr_cfg
.pa3
= regk_gio_hi
;
200 intr_cfg
.pa4
= regk_gio_hi
;
202 intr_cfg
.pa5
= regk_gio_hi
;
204 intr_cfg
.pa6
= regk_gio_hi
;
206 intr_cfg
.pa7
= regk_gio_hi
;
208 * lets activate low for those high and with lowalarm set
210 tmp
= data
& priv
->lowalarm
& 0xFF;
212 intr_cfg
.pa0
= regk_gio_lo
;
214 intr_cfg
.pa1
= regk_gio_lo
;
216 intr_cfg
.pa2
= regk_gio_lo
;
218 intr_cfg
.pa3
= regk_gio_lo
;
220 intr_cfg
.pa4
= regk_gio_lo
;
222 intr_cfg
.pa5
= regk_gio_lo
;
224 intr_cfg
.pa6
= regk_gio_lo
;
226 intr_cfg
.pa7
= regk_gio_lo
;
228 REG_WR(gio
, regi_gio
, rw_intr_cfg
, intr_cfg
);
229 local_irq_restore(flags
);
230 } else if (priv
->minor
<= GPIO_MINOR_E
)
231 data
= *data_in
[priv
->minor
];
235 if ((data
& priv
->highalarm
) || (~data
& priv
->lowalarm
))
236 mask
= POLLIN
|POLLRDNORM
;
238 DP(printk(KERN_DEBUG
"gpio_poll ready: mask 0x%08X\n", mask
));
242 int etrax_gpio_wake_up_check(void)
244 struct gpio_private
*priv
;
245 unsigned long data
= 0;
248 spin_lock_irqsave(&alarm_lock
, flags
);
251 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
252 if (priv
->minor
== GPIO_MINOR_V
)
253 data
= (unsigned long)cached_virtual_gpio_read
;
255 data
= *data_in
[priv
->minor
];
256 if (priv
->minor
== GPIO_MINOR_A
)
257 priv
->lowalarm
|= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN
);
260 data
= *data_in
[priv
->minor
];
262 if ((data
& priv
->highalarm
) ||
263 (~data
& priv
->lowalarm
)) {
265 "etrax_gpio_wake_up_check %i\n", priv
->minor
));
266 wake_up_interruptible(&priv
->alarm_wq
);
271 spin_unlock_irqrestore(&alarm_lock
, flags
);
276 gpio_poll_timer_interrupt(int irq
, void *dev_id
)
278 if (gpio_some_alarms
)
279 return IRQ_RETVAL(etrax_gpio_wake_up_check());
284 gpio_pa_interrupt(int irq
, void *dev_id
)
286 reg_gio_rw_intr_mask intr_mask
;
287 reg_gio_r_masked_intr masked_intr
;
288 reg_gio_rw_ack_intr ack_intr
;
291 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
292 unsigned char enable_gpiov_ack
= 0;
295 /* Find what PA interrupts are active */
296 masked_intr
= REG_RD(gio
, regi_gio
, r_masked_intr
);
297 tmp
= REG_TYPE_CONV(unsigned long, reg_gio_r_masked_intr
, masked_intr
);
299 /* Find those that we have enabled */
300 spin_lock(&alarm_lock
);
301 tmp
&= (gpio_pa_high_alarms
| gpio_pa_low_alarms
);
302 spin_unlock(&alarm_lock
);
304 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
305 /* Something changed on virtual GPIO. Interrupt is acked by
306 * reading the device.
308 if (tmp
& (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN
)) {
309 i2c_read(VIRT_I2C_ADDR
, (void *)&cached_virtual_gpio_read
,
310 sizeof(cached_virtual_gpio_read
));
311 enable_gpiov_ack
= 1;
316 ack_intr
= REG_TYPE_CONV(reg_gio_rw_ack_intr
, unsigned long, tmp
);
317 REG_WR(gio
, regi_gio
, rw_ack_intr
, ack_intr
);
319 /* Disable those interrupts.. */
320 intr_mask
= REG_RD(gio
, regi_gio
, rw_intr_mask
);
321 tmp2
= REG_TYPE_CONV(unsigned long, reg_gio_rw_intr_mask
, intr_mask
);
323 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
324 /* Do not disable interrupt on virtual GPIO. Changes on virtual
325 * pins are only noticed by an interrupt.
327 if (enable_gpiov_ack
)
328 tmp2
|= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN
);
330 intr_mask
= REG_TYPE_CONV(reg_gio_rw_intr_mask
, unsigned long, tmp2
);
331 REG_WR(gio
, regi_gio
, rw_intr_mask
, intr_mask
);
333 if (gpio_some_alarms
)
334 return IRQ_RETVAL(etrax_gpio_wake_up_check());
339 static ssize_t
gpio_write(struct file
*file
, const char *buf
, size_t count
,
342 struct gpio_private
*priv
= file
->private_data
;
343 unsigned char data
, clk_mask
, data_mask
, write_msb
;
345 unsigned long shadow
;
346 volatile unsigned long *port
;
347 ssize_t retval
= count
;
348 /* Only bits 0-7 may be used for write operations but allow all
349 devices except leds... */
350 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
351 if (priv
->minor
== GPIO_MINOR_V
)
354 if (priv
->minor
== GPIO_MINOR_LEDS
)
357 if (!access_ok(VERIFY_READ
, buf
, count
))
359 clk_mask
= priv
->clk_mask
;
360 data_mask
= priv
->data_mask
;
361 /* It must have been configured using the IO_CFG_WRITE_MODE */
362 /* Perhaps a better error code? */
363 if (clk_mask
== 0 || data_mask
== 0)
365 write_msb
= priv
->write_msb
;
366 D(printk(KERN_DEBUG
"gpio_write: %lu to data 0x%02X clk 0x%02X "
367 "msb: %i\n", count
, data_mask
, clk_mask
, write_msb
));
368 port
= data_out
[priv
->minor
];
373 if (priv
->write_msb
) {
374 for (i
= 7; i
>= 0; i
--) {
375 local_irq_save(flags
);
377 *port
= shadow
&= ~clk_mask
;
379 *port
= shadow
|= data_mask
;
381 *port
= shadow
&= ~data_mask
;
382 /* For FPGA: min 5.0ns (DCC) before CCLK high */
383 *port
= shadow
|= clk_mask
;
384 local_irq_restore(flags
);
387 for (i
= 0; i
<= 7; i
++) {
388 local_irq_save(flags
);
390 *port
= shadow
&= ~clk_mask
;
392 *port
= shadow
|= data_mask
;
394 *port
= shadow
&= ~data_mask
;
395 /* For FPGA: min 5.0ns (DCC) before CCLK high */
396 *port
= shadow
|= clk_mask
;
397 local_irq_restore(flags
);
407 gpio_open(struct inode
*inode
, struct file
*filp
)
409 struct gpio_private
*priv
;
410 int p
= iminor(inode
);
412 if (p
> GPIO_MINOR_LAST
)
415 priv
= kmalloc(sizeof(struct gpio_private
), GFP_KERNEL
);
420 memset(priv
, 0, sizeof(*priv
));
424 /* initialize the io/alarm struct */
430 init_waitqueue_head(&priv
->alarm_wq
);
432 filp
->private_data
= (void *)priv
;
434 /* link it into our alarmlist */
435 spin_lock_irq(&alarm_lock
);
436 priv
->next
= alarmlist
;
438 spin_unlock_irq(&alarm_lock
);
445 gpio_release(struct inode
*inode
, struct file
*filp
)
447 struct gpio_private
*p
;
448 struct gpio_private
*todel
;
449 /* local copies while updating them: */
450 unsigned long a_high
, a_low
;
451 unsigned long some_alarms
;
453 /* unlink from alarmlist and free the private structure */
455 spin_lock_irq(&alarm_lock
);
457 todel
= filp
->private_data
;
460 alarmlist
= todel
->next
;
462 while (p
->next
!= todel
)
464 p
->next
= todel
->next
;
468 /* Check if there are still any alarms set */
474 if (p
->minor
== GPIO_MINOR_A
) {
475 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
476 p
->lowalarm
|= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN
);
478 a_high
|= p
->highalarm
;
479 a_low
|= p
->lowalarm
;
482 if (p
->highalarm
| p
->lowalarm
)
487 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
488 /* Variables 'some_alarms' and 'a_low' needs to be set here again
489 * to ensure that interrupt for virtual GPIO is handled.
492 a_low
|= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN
);
495 gpio_some_alarms
= some_alarms
;
496 gpio_pa_high_alarms
= a_high
;
497 gpio_pa_low_alarms
= a_low
;
498 spin_unlock_irq(&alarm_lock
);
503 /* Main device API. ioctl's to read/set/clear bits, as well as to
504 * set alarms to wait for using a subsequent select().
507 inline unsigned long setget_input(struct gpio_private
*priv
, unsigned long arg
)
509 /* Set direction 0=unchanged 1=input,
510 * return mask with 1=input
513 unsigned long dir_shadow
;
515 local_irq_save(flags
);
516 dir_shadow
= *dir_oe
[priv
->minor
];
517 dir_shadow
&= ~(arg
& changeable_dir
[priv
->minor
]);
518 *dir_oe
[priv
->minor
] = dir_shadow
;
519 local_irq_restore(flags
);
521 if (priv
->minor
== GPIO_MINOR_A
)
522 dir_shadow
^= 0xFF; /* Only 8 bits */
523 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
524 else if (priv
->minor
== GPIO_MINOR_V
)
525 dir_shadow
^= 0xFFFF; /* Only 16 bits */
528 dir_shadow
^= 0x3FFFF; /* Only 18 bits */
533 inline unsigned long setget_output(struct gpio_private
*priv
, unsigned long arg
)
536 unsigned long dir_shadow
;
538 local_irq_save(flags
);
539 dir_shadow
= *dir_oe
[priv
->minor
];
540 dir_shadow
|= (arg
& changeable_dir
[priv
->minor
]);
541 *dir_oe
[priv
->minor
] = dir_shadow
;
542 local_irq_restore(flags
);
544 } /* setget_output */
546 static int gpio_leds_ioctl(unsigned int cmd
, unsigned long arg
);
549 gpio_ioctl_unlocked(struct file
*file
, unsigned int cmd
, unsigned long arg
)
553 unsigned long shadow
;
554 struct gpio_private
*priv
= file
->private_data
;
555 if (_IOC_TYPE(cmd
) != ETRAXGPIO_IOCTYPE
)
558 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
559 if (priv
->minor
== GPIO_MINOR_V
)
560 return virtual_gpio_ioctl(file
, cmd
, arg
);
563 switch (_IOC_NR(cmd
)) {
564 case IO_READBITS
: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
566 return *data_in
[priv
->minor
];
569 local_irq_save(flags
);
570 /* Set changeable bits with a 1 in arg. */
571 shadow
= *data_out
[priv
->minor
];
572 shadow
|= (arg
& changeable_bits
[priv
->minor
]);
573 *data_out
[priv
->minor
] = shadow
;
574 local_irq_restore(flags
);
577 local_irq_save(flags
);
578 /* Clear changeable bits with a 1 in arg. */
579 shadow
= *data_out
[priv
->minor
];
580 shadow
&= ~(arg
& changeable_bits
[priv
->minor
]);
581 *data_out
[priv
->minor
] = shadow
;
582 local_irq_restore(flags
);
585 /* Set alarm when bits with 1 in arg go high. */
586 priv
->highalarm
|= arg
;
587 spin_lock_irqsave(&alarm_lock
, flags
);
588 gpio_some_alarms
= 1;
589 if (priv
->minor
== GPIO_MINOR_A
)
590 gpio_pa_high_alarms
|= arg
;
591 spin_unlock_irqrestore(&alarm_lock
, flags
);
594 /* Set alarm when bits with 1 in arg go low. */
595 priv
->lowalarm
|= arg
;
596 spin_lock_irqsave(&alarm_lock
, flags
);
597 gpio_some_alarms
= 1;
598 if (priv
->minor
== GPIO_MINOR_A
)
599 gpio_pa_low_alarms
|= arg
;
600 spin_unlock_irqrestore(&alarm_lock
, flags
);
603 /* Clear alarm for bits with 1 in arg. */
604 priv
->highalarm
&= ~arg
;
605 priv
->lowalarm
&= ~arg
;
606 spin_lock_irqsave(&alarm_lock
, flags
);
607 if (priv
->minor
== GPIO_MINOR_A
) {
608 if (gpio_pa_high_alarms
& arg
||
609 gpio_pa_low_alarms
& arg
)
610 /* Must update the gpio_pa_*alarms masks */
613 spin_unlock_irqrestore(&alarm_lock
, flags
);
615 case IO_READDIR
: /* Use IO_SETGET_INPUT/OUTPUT instead! */
616 /* Read direction 0=input 1=output */
617 return *dir_oe
[priv
->minor
];
618 case IO_SETINPUT
: /* Use IO_SETGET_INPUT instead! */
619 /* Set direction 0=unchanged 1=input,
620 * return mask with 1=input
622 return setget_input(priv
, arg
);
624 case IO_SETOUTPUT
: /* Use IO_SETGET_OUTPUT instead! */
625 /* Set direction 0=unchanged 1=output,
626 * return mask with 1=output
628 return setget_output(priv
, arg
);
630 case IO_CFG_WRITE_MODE
:
632 unsigned long dir_shadow
;
633 dir_shadow
= *dir_oe
[priv
->minor
];
635 priv
->clk_mask
= arg
& 0xFF;
636 priv
->data_mask
= (arg
>> 8) & 0xFF;
637 priv
->write_msb
= (arg
>> 16) & 0x01;
638 /* Check if we're allowed to change the bits and
639 * the direction is correct
641 if (!((priv
->clk_mask
& changeable_bits
[priv
->minor
]) &&
642 (priv
->data_mask
& changeable_bits
[priv
->minor
]) &&
643 (priv
->clk_mask
& dir_shadow
) &&
644 (priv
->data_mask
& dir_shadow
))) {
652 /* *arg is result of reading the input pins */
653 val
= *data_in
[priv
->minor
];
654 if (copy_to_user((unsigned long *)arg
, &val
, sizeof(val
)))
658 case IO_READ_OUTBITS
:
659 /* *arg is result of reading the output shadow */
660 val
= *data_out
[priv
->minor
];
661 if (copy_to_user((unsigned long *)arg
, &val
, sizeof(val
)))
664 case IO_SETGET_INPUT
:
665 /* bits set in *arg is set to input,
666 * *arg updated with current input pins.
668 if (copy_from_user(&val
, (unsigned long *)arg
, sizeof(val
)))
670 val
= setget_input(priv
, val
);
671 if (copy_to_user((unsigned long *)arg
, &val
, sizeof(val
)))
674 case IO_SETGET_OUTPUT
:
675 /* bits set in *arg is set to output,
676 * *arg updated with current output pins.
678 if (copy_from_user(&val
, (unsigned long *)arg
, sizeof(val
)))
680 val
= setget_output(priv
, val
);
681 if (copy_to_user((unsigned long *)arg
, &val
, sizeof(val
)))
685 if (priv
->minor
== GPIO_MINOR_LEDS
)
686 return gpio_leds_ioctl(cmd
, arg
);
694 static long gpio_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
699 ret
= gpio_ioctl_unlocked(file
, cmd
, arg
);
705 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
707 virtual_gpio_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
711 unsigned short shadow
;
712 struct gpio_private
*priv
= file
->private_data
;
714 switch (_IOC_NR(cmd
)) {
716 local_irq_save(flags
);
717 /* Set changeable bits with a 1 in arg. */
718 i2c_read(VIRT_I2C_ADDR
, (void *)&shadow
, sizeof(shadow
));
719 shadow
|= ~*dir_oe
[priv
->minor
];
720 shadow
|= (arg
& changeable_bits
[priv
->minor
]);
721 i2c_write(VIRT_I2C_ADDR
, (void *)&shadow
, sizeof(shadow
));
722 local_irq_restore(flags
);
725 local_irq_save(flags
);
726 /* Clear changeable bits with a 1 in arg. */
727 i2c_read(VIRT_I2C_ADDR
, (void *)&shadow
, sizeof(shadow
));
728 shadow
|= ~*dir_oe
[priv
->minor
];
729 shadow
&= ~(arg
& changeable_bits
[priv
->minor
]);
730 i2c_write(VIRT_I2C_ADDR
, (void *)&shadow
, sizeof(shadow
));
731 local_irq_restore(flags
);
734 /* Set alarm when bits with 1 in arg go high. */
735 priv
->highalarm
|= arg
;
736 spin_lock(&alarm_lock
);
737 gpio_some_alarms
= 1;
738 spin_unlock(&alarm_lock
);
741 /* Set alarm when bits with 1 in arg go low. */
742 priv
->lowalarm
|= arg
;
743 spin_lock(&alarm_lock
);
744 gpio_some_alarms
= 1;
745 spin_unlock(&alarm_lock
);
748 /* Clear alarm for bits with 1 in arg. */
749 priv
->highalarm
&= ~arg
;
750 priv
->lowalarm
&= ~arg
;
751 spin_lock(&alarm_lock
);
752 spin_unlock(&alarm_lock
);
754 case IO_CFG_WRITE_MODE
:
756 unsigned long dir_shadow
;
757 dir_shadow
= *dir_oe
[priv
->minor
];
759 priv
->clk_mask
= arg
& 0xFF;
760 priv
->data_mask
= (arg
>> 8) & 0xFF;
761 priv
->write_msb
= (arg
>> 16) & 0x01;
762 /* Check if we're allowed to change the bits and
763 * the direction is correct
765 if (!((priv
->clk_mask
& changeable_bits
[priv
->minor
]) &&
766 (priv
->data_mask
& changeable_bits
[priv
->minor
]) &&
767 (priv
->clk_mask
& dir_shadow
) &&
768 (priv
->data_mask
& dir_shadow
))) {
776 /* *arg is result of reading the input pins */
777 val
= cached_virtual_gpio_read
;
778 val
&= ~*dir_oe
[priv
->minor
];
779 if (copy_to_user((unsigned long *)arg
, &val
, sizeof(val
)))
783 case IO_READ_OUTBITS
:
784 /* *arg is result of reading the output shadow */
785 i2c_read(VIRT_I2C_ADDR
, (void *)&val
, sizeof(val
));
786 val
&= *dir_oe
[priv
->minor
];
787 if (copy_to_user((unsigned long *)arg
, &val
, sizeof(val
)))
790 case IO_SETGET_INPUT
:
792 /* bits set in *arg is set to input,
793 * *arg updated with current input pins.
795 unsigned short input_mask
= ~*dir_oe
[priv
->minor
];
796 if (copy_from_user(&val
, (unsigned long *)arg
, sizeof(val
)))
798 val
= setget_input(priv
, val
);
799 if (copy_to_user((unsigned long *)arg
, &val
, sizeof(val
)))
801 if ((input_mask
& val
) != input_mask
) {
802 /* Input pins changed. All ports desired as input
803 * should be set to logic 1.
805 unsigned short change
= input_mask
^ val
;
806 i2c_read(VIRT_I2C_ADDR
, (void *)&shadow
,
810 i2c_write(VIRT_I2C_ADDR
, (void *)&shadow
,
815 case IO_SETGET_OUTPUT
:
816 /* bits set in *arg is set to output,
817 * *arg updated with current output pins.
819 if (copy_from_user(&val
, (unsigned long *)arg
, sizeof(val
)))
821 val
= setget_output(priv
, val
);
822 if (copy_to_user((unsigned long *)arg
, &val
, sizeof(val
)))
830 #endif /* CONFIG_ETRAX_VIRTUAL_GPIO */
833 gpio_leds_ioctl(unsigned int cmd
, unsigned long arg
)
838 switch (_IOC_NR(cmd
)) {
839 case IO_LEDACTIVE_SET
:
840 green
= ((unsigned char) arg
) & 1;
841 red
= (((unsigned char) arg
) >> 1) & 1;
842 CRIS_LED_ACTIVE_SET_G(green
);
843 CRIS_LED_ACTIVE_SET_R(red
);
853 static const struct file_operations gpio_fops
= {
854 .owner
= THIS_MODULE
,
856 .unlocked_ioctl
= gpio_ioctl
,
859 .release
= gpio_release
,
862 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
864 virtual_gpio_init(void)
866 reg_gio_rw_intr_cfg intr_cfg
;
867 reg_gio_rw_intr_mask intr_mask
;
868 unsigned short shadow
;
870 shadow
= ~virtual_rw_pv_oe
; /* Input ports should be set to logic 1 */
871 shadow
|= CONFIG_ETRAX_DEF_GIO_PV_OUT
;
872 i2c_write(VIRT_I2C_ADDR
, (void *)&shadow
, sizeof(shadow
));
874 /* Set interrupt mask and on what state the interrupt shall trigger.
875 * For virtual gpio the interrupt shall trigger on logic '0'.
877 intr_cfg
= REG_RD(gio
, regi_gio
, rw_intr_cfg
);
878 intr_mask
= REG_RD(gio
, regi_gio
, rw_intr_mask
);
880 switch (CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN
) {
882 intr_cfg
.pa0
= regk_gio_lo
;
883 intr_mask
.pa0
= regk_gio_yes
;
886 intr_cfg
.pa1
= regk_gio_lo
;
887 intr_mask
.pa1
= regk_gio_yes
;
890 intr_cfg
.pa2
= regk_gio_lo
;
891 intr_mask
.pa2
= regk_gio_yes
;
894 intr_cfg
.pa3
= regk_gio_lo
;
895 intr_mask
.pa3
= regk_gio_yes
;
898 intr_cfg
.pa4
= regk_gio_lo
;
899 intr_mask
.pa4
= regk_gio_yes
;
902 intr_cfg
.pa5
= regk_gio_lo
;
903 intr_mask
.pa5
= regk_gio_yes
;
906 intr_cfg
.pa6
= regk_gio_lo
;
907 intr_mask
.pa6
= regk_gio_yes
;
910 intr_cfg
.pa7
= regk_gio_lo
;
911 intr_mask
.pa7
= regk_gio_yes
;
915 REG_WR(gio
, regi_gio
, rw_intr_cfg
, intr_cfg
);
916 REG_WR(gio
, regi_gio
, rw_intr_mask
, intr_mask
);
918 gpio_pa_low_alarms
|= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN
);
919 gpio_some_alarms
= 1;
923 /* main driver initialization routine, called from mem.c */
930 /* do the formalities */
932 res
= register_chrdev(GPIO_MAJOR
, gpio_name
, &gpio_fops
);
934 printk(KERN_ERR
"gpio: couldn't get a major number.\n");
939 CRIS_LED_NETWORK_GRP0_SET(0);
940 CRIS_LED_NETWORK_GRP1_SET(0);
941 CRIS_LED_ACTIVE_SET(0);
942 CRIS_LED_DISK_READ(0);
943 CRIS_LED_DISK_WRITE(0);
945 printk(KERN_INFO
"ETRAX FS GPIO driver v2.5, (c) 2003-2007 "
946 "Axis Communications AB\n");
947 /* We call etrax_gpio_wake_up_check() from timer interrupt and
948 * from cpu_idle() in kernel/process.c
949 * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
952 if (request_irq(TIMER0_INTR_VECT
, gpio_poll_timer_interrupt
,
953 IRQF_SHARED
| IRQF_DISABLED
, "gpio poll", &alarmlist
))
954 printk(KERN_ERR
"timer0 irq for gpio\n");
956 if (request_irq(GIO_INTR_VECT
, gpio_pa_interrupt
,
957 IRQF_SHARED
| IRQF_DISABLED
, "gpio PA", &alarmlist
))
958 printk(KERN_ERR
"PA irq for gpio\n");
960 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
967 /* this makes sure that gpio_init is called during kernel boot */
969 module_init(gpio_init
);