1
2
3
4
5
6
7
8
9
10
11
12
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>
19#include <linux/fs.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>
26
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>
32#include <asm/io.h>
33#include <asm/system.h>
34#include <asm/irq.h>
35
36#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
37#include "../i2c.h"
38
39#define VIRT_I2C_ADDR 0x40
40#endif
41
42
43
44
45
46
47
48
49
50
51#define GPIO_MAJOR 120
52
53#define D(x)
54
55#if 0
56static int dp_cnt;
57#define DP(x) \
58 do { \
59 dp_cnt++; \
60 if (dp_cnt % 1000 == 0) \
61 x; \
62 } while (0)
63#else
64#define DP(x)
65#endif
66
67static char gpio_name[] = "etrax gpio";
68
69#if 0
70static wait_queue_head_t *gpio_wq;
71#endif
72
73#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
74static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
75 unsigned long arg);
76#endif
77static int gpio_ioctl(struct inode *inode, struct file *file,
78 unsigned int cmd, unsigned long arg);
79static ssize_t gpio_write(struct file *file, const char *buf, size_t count,
80 loff_t *off);
81static int gpio_open(struct inode *inode, struct file *filp);
82static int gpio_release(struct inode *inode, struct file *filp);
83static unsigned int gpio_poll(struct file *filp,
84 struct poll_table_struct *wait);
85
86
87
88struct gpio_private {
89 struct gpio_private *next;
90
91 unsigned char clk_mask;
92 unsigned char data_mask;
93 unsigned char write_msb;
94 unsigned char pad1;
95
96 unsigned long highalarm, lowalarm;
97 wait_queue_head_t alarm_wq;
98 int minor;
99};
100
101
102
103static struct gpio_private *alarmlist;
104
105static int gpio_some_alarms;
106static unsigned long gpio_pa_high_alarms;
107static unsigned long gpio_pa_low_alarms;
108
109static DEFINE_SPINLOCK(alarm_lock);
110
111#define NUM_PORTS (GPIO_MINOR_LAST+1)
112#define GIO_REG_RD_ADDR(reg) \
113 (volatile unsigned long *)(regi_gio + REG_RD_ADDR_gio_##reg)
114#define GIO_REG_WR_ADDR(reg) \
115 (volatile unsigned long *)(regi_gio + REG_RD_ADDR_gio_##reg)
116unsigned long led_dummy;
117#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
118static unsigned long virtual_dummy;
119static unsigned long virtual_rw_pv_oe = CONFIG_ETRAX_DEF_GIO_PV_OE;
120static unsigned short cached_virtual_gpio_read;
121#endif
122
123static volatile unsigned long *data_out[NUM_PORTS] = {
124 GIO_REG_WR_ADDR(rw_pa_dout),
125 GIO_REG_WR_ADDR(rw_pb_dout),
126 &led_dummy,
127 GIO_REG_WR_ADDR(rw_pc_dout),
128 GIO_REG_WR_ADDR(rw_pd_dout),
129 GIO_REG_WR_ADDR(rw_pe_dout),
130#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
131 &virtual_dummy,
132#endif
133};
134
135static volatile unsigned long *data_in[NUM_PORTS] = {
136 GIO_REG_RD_ADDR(r_pa_din),
137 GIO_REG_RD_ADDR(r_pb_din),
138 &led_dummy,
139 GIO_REG_RD_ADDR(r_pc_din),
140 GIO_REG_RD_ADDR(r_pd_din),
141 GIO_REG_RD_ADDR(r_pe_din),
142#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
143 &virtual_dummy,
144#endif
145};
146
147static unsigned long changeable_dir[NUM_PORTS] = {
148 CONFIG_ETRAX_PA_CHANGEABLE_DIR,
149 CONFIG_ETRAX_PB_CHANGEABLE_DIR,
150 0,
151 CONFIG_ETRAX_PC_CHANGEABLE_DIR,
152 CONFIG_ETRAX_PD_CHANGEABLE_DIR,
153 CONFIG_ETRAX_PE_CHANGEABLE_DIR,
154#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
155 CONFIG_ETRAX_PV_CHANGEABLE_DIR,
156#endif
157};
158
159static unsigned long changeable_bits[NUM_PORTS] = {
160 CONFIG_ETRAX_PA_CHANGEABLE_BITS,
161 CONFIG_ETRAX_PB_CHANGEABLE_BITS,
162 0,
163 CONFIG_ETRAX_PC_CHANGEABLE_BITS,
164 CONFIG_ETRAX_PD_CHANGEABLE_BITS,
165 CONFIG_ETRAX_PE_CHANGEABLE_BITS,
166#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
167 CONFIG_ETRAX_PV_CHANGEABLE_BITS,
168#endif
169};
170
171static volatile unsigned long *dir_oe[NUM_PORTS] = {
172 GIO_REG_WR_ADDR(rw_pa_oe),
173 GIO_REG_WR_ADDR(rw_pb_oe),
174 &led_dummy,
175 GIO_REG_WR_ADDR(rw_pc_oe),
176 GIO_REG_WR_ADDR(rw_pd_oe),
177 GIO_REG_WR_ADDR(rw_pe_oe),
178#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
179 &virtual_rw_pv_oe,
180#endif
181};
182
183
184
185static unsigned int gpio_poll(struct file *file, struct poll_table_struct *wait)
186{
187 unsigned int mask = 0;
188 struct gpio_private *priv = (struct gpio_private *)file->private_data;
189 unsigned long data;
190 poll_wait(file, &priv->alarm_wq, wait);
191 if (priv->minor == GPIO_MINOR_A) {
192 reg_gio_rw_intr_cfg intr_cfg;
193 unsigned long tmp;
194 unsigned long flags;
195
196 local_irq_save(flags);
197 data = REG_TYPE_CONV(unsigned long, reg_gio_r_pa_din,
198 REG_RD(gio, regi_gio, r_pa_din));
199
200
201
202 intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg);
203
204 tmp = ~data & priv->highalarm & 0xFF;
205 if (tmp & (1 << 0))
206 intr_cfg.pa0 = regk_gio_hi;
207 if (tmp & (1 << 1))
208 intr_cfg.pa1 = regk_gio_hi;
209 if (tmp & (1 << 2))
210 intr_cfg.pa2 = regk_gio_hi;
211 if (tmp & (1 << 3))
212 intr_cfg.pa3 = regk_gio_hi;
213 if (tmp & (1 << 4))
214 intr_cfg.pa4 = regk_gio_hi;
215 if (tmp & (1 << 5))
216 intr_cfg.pa5 = regk_gio_hi;
217 if (tmp & (1 << 6))
218 intr_cfg.pa6 = regk_gio_hi;
219 if (tmp & (1 << 7))
220 intr_cfg.pa7 = regk_gio_hi;
221
222
223
224 tmp = data & priv->lowalarm & 0xFF;
225 if (tmp & (1 << 0))
226 intr_cfg.pa0 = regk_gio_lo;
227 if (tmp & (1 << 1))
228 intr_cfg.pa1 = regk_gio_lo;
229 if (tmp & (1 << 2))
230 intr_cfg.pa2 = regk_gio_lo;
231 if (tmp & (1 << 3))
232 intr_cfg.pa3 = regk_gio_lo;
233 if (tmp & (1 << 4))
234 intr_cfg.pa4 = regk_gio_lo;
235 if (tmp & (1 << 5))
236 intr_cfg.pa5 = regk_gio_lo;
237 if (tmp & (1 << 6))
238 intr_cfg.pa6 = regk_gio_lo;
239 if (tmp & (1 << 7))
240 intr_cfg.pa7 = regk_gio_lo;
241
242 REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg);
243 local_irq_restore(flags);
244 } else if (priv->minor <= GPIO_MINOR_E)
245 data = *data_in[priv->minor];
246 else
247 return 0;
248
249 if ((data & priv->highalarm) || (~data & priv->lowalarm))
250 mask = POLLIN|POLLRDNORM;
251
252 DP(printk(KERN_DEBUG "gpio_poll ready: mask 0x%08X\n", mask));
253 return mask;
254}
255
256int etrax_gpio_wake_up_check(void)
257{
258 struct gpio_private *priv;
259 unsigned long data = 0;
260 unsigned long flags;
261 int ret = 0;
262 spin_lock_irqsave(&alarm_lock, flags);
263 priv = alarmlist;
264 while (priv) {
265#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
266 if (priv->minor == GPIO_MINOR_V)
267 data = (unsigned long)cached_virtual_gpio_read;
268 else {
269 data = *data_in[priv->minor];
270 if (priv->minor == GPIO_MINOR_A)
271 priv->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
272 }
273#else
274 data = *data_in[priv->minor];
275#endif
276 if ((data & priv->highalarm) ||
277 (~data & priv->lowalarm)) {
278 DP(printk(KERN_DEBUG
279 "etrax_gpio_wake_up_check %i\n", priv->minor));
280 wake_up_interruptible(&priv->alarm_wq);
281 ret = 1;
282 }
283 priv = priv->next;
284 }
285 spin_unlock_irqrestore(&alarm_lock, flags);
286 return ret;
287}
288
289static irqreturn_t
290gpio_poll_timer_interrupt(int irq, void *dev_id)
291{
292 if (gpio_some_alarms)
293 return IRQ_RETVAL(etrax_gpio_wake_up_check());
294 return IRQ_NONE;
295}
296
297static irqreturn_t
298gpio_pa_interrupt(int irq, void *dev_id)
299{
300 reg_gio_rw_intr_mask intr_mask;
301 reg_gio_r_masked_intr masked_intr;
302 reg_gio_rw_ack_intr ack_intr;
303 unsigned long tmp;
304 unsigned long tmp2;
305#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
306 unsigned char enable_gpiov_ack = 0;
307#endif
308
309
310 masked_intr = REG_RD(gio, regi_gio, r_masked_intr);
311 tmp = REG_TYPE_CONV(unsigned long, reg_gio_r_masked_intr, masked_intr);
312
313
314 spin_lock(&alarm_lock);
315 tmp &= (gpio_pa_high_alarms | gpio_pa_low_alarms);
316 spin_unlock(&alarm_lock);
317
318#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
319
320
321
322 if (tmp & (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN)) {
323 i2c_read(VIRT_I2C_ADDR, (void *)&cached_virtual_gpio_read,
324 sizeof(cached_virtual_gpio_read));
325 enable_gpiov_ack = 1;
326 }
327#endif
328
329
330 ack_intr = REG_TYPE_CONV(reg_gio_rw_ack_intr, unsigned long, tmp);
331 REG_WR(gio, regi_gio, rw_ack_intr, ack_intr);
332
333
334 intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
335 tmp2 = REG_TYPE_CONV(unsigned long, reg_gio_rw_intr_mask, intr_mask);
336 tmp2 &= ~tmp;
337#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
338
339
340
341 if (enable_gpiov_ack)
342 tmp2 |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
343#endif
344 intr_mask = REG_TYPE_CONV(reg_gio_rw_intr_mask, unsigned long, tmp2);
345 REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
346
347 if (gpio_some_alarms)
348 return IRQ_RETVAL(etrax_gpio_wake_up_check());
349 return IRQ_NONE;
350}
351
352
353static ssize_t gpio_write(struct file *file, const char *buf, size_t count,
354 loff_t *off)
355{
356 struct gpio_private *priv = (struct gpio_private *)file->private_data;
357 unsigned char data, clk_mask, data_mask, write_msb;
358 unsigned long flags;
359 unsigned long shadow;
360 volatile unsigned long *port;
361 ssize_t retval = count;
362
363
364#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
365 if (priv->minor == GPIO_MINOR_V)
366 return -EFAULT;
367#endif
368 if (priv->minor == GPIO_MINOR_LEDS)
369 return -EFAULT;
370
371 if (!access_ok(VERIFY_READ, buf, count))
372 return -EFAULT;
373 clk_mask = priv->clk_mask;
374 data_mask = priv->data_mask;
375
376
377 if (clk_mask == 0 || data_mask == 0)
378 return -EPERM;
379 write_msb = priv->write_msb;
380 D(printk(KERN_DEBUG "gpio_write: %lu to data 0x%02X clk 0x%02X "
381 "msb: %i\n", count, data_mask, clk_mask, write_msb));
382 port = data_out[priv->minor];
383
384 while (count--) {
385 int i;
386 data = *buf++;
387 if (priv->write_msb) {
388 for (i = 7; i >= 0; i--) {
389 local_irq_save(flags);
390 shadow = *port;
391 *port = shadow &= ~clk_mask;
392 if (data & 1<<i)
393 *port = shadow |= data_mask;
394 else
395 *port = shadow &= ~data_mask;
396
397 *port = shadow |= clk_mask;
398 local_irq_restore(flags);
399 }
400 } else {
401 for (i = 0; i <= 7; i++) {
402 local_irq_save(flags);
403 shadow = *port;
404 *port = shadow &= ~clk_mask;
405 if (data & 1<<i)
406 *port = shadow |= data_mask;
407 else
408 *port = shadow &= ~data_mask;
409
410 *port = shadow |= clk_mask;
411 local_irq_restore(flags);
412 }
413 }
414 }
415 return retval;
416}
417
418
419
420static int
421gpio_open(struct inode *inode, struct file *filp)
422{
423 struct gpio_private *priv;
424 int p = iminor(inode);
425
426 if (p > GPIO_MINOR_LAST)
427 return -EINVAL;
428
429 priv = kmalloc(sizeof(struct gpio_private), GFP_KERNEL);
430 if (!priv)
431 return -ENOMEM;
432
433 lock_kernel();
434 memset(priv, 0, sizeof(*priv));
435
436 priv->minor = p;
437
438
439
440 priv->clk_mask = 0;
441 priv->data_mask = 0;
442 priv->highalarm = 0;
443 priv->lowalarm = 0;
444 init_waitqueue_head(&priv->alarm_wq);
445
446 filp->private_data = (void *)priv;
447
448
449 spin_lock_irq(&alarm_lock);
450 priv->next = alarmlist;
451 alarmlist = priv;
452 spin_unlock_irq(&alarm_lock);
453
454 unlock_kernel();
455 return 0;
456}
457
458static int
459gpio_release(struct inode *inode, struct file *filp)
460{
461 struct gpio_private *p;
462 struct gpio_private *todel;
463
464 unsigned long a_high, a_low;
465 unsigned long some_alarms;
466
467
468
469 spin_lock_irq(&alarm_lock);
470 p = alarmlist;
471 todel = (struct gpio_private *)filp->private_data;
472
473 if (p == todel) {
474 alarmlist = todel->next;
475 } else {
476 while (p->next != todel)
477 p = p->next;
478 p->next = todel->next;
479 }
480
481 kfree(todel);
482
483 p = alarmlist;
484 some_alarms = 0;
485 a_high = 0;
486 a_low = 0;
487 while (p) {
488 if (p->minor == GPIO_MINOR_A) {
489#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
490 p->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
491#endif
492 a_high |= p->highalarm;
493 a_low |= p->lowalarm;
494 }
495
496 if (p->highalarm | p->lowalarm)
497 some_alarms = 1;
498 p = p->next;
499 }
500
501#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
502
503
504
505 some_alarms = 1;
506 a_low |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
507#endif
508
509 gpio_some_alarms = some_alarms;
510 gpio_pa_high_alarms = a_high;
511 gpio_pa_low_alarms = a_low;
512 spin_unlock_irq(&alarm_lock);
513
514 return 0;
515}
516
517
518
519
520
521inline unsigned long setget_input(struct gpio_private *priv, unsigned long arg)
522{
523
524
525
526 unsigned long flags;
527 unsigned long dir_shadow;
528
529 local_irq_save(flags);
530 dir_shadow = *dir_oe[priv->minor];
531 dir_shadow &= ~(arg & changeable_dir[priv->minor]);
532 *dir_oe[priv->minor] = dir_shadow;
533 local_irq_restore(flags);
534
535 if (priv->minor == GPIO_MINOR_A)
536 dir_shadow ^= 0xFF;
537#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
538 else if (priv->minor == GPIO_MINOR_V)
539 dir_shadow ^= 0xFFFF;
540#endif
541 else
542 dir_shadow ^= 0x3FFFF;
543 return dir_shadow;
544
545}
546
547inline unsigned long setget_output(struct gpio_private *priv, unsigned long arg)
548{
549 unsigned long flags;
550 unsigned long dir_shadow;
551
552 local_irq_save(flags);
553 dir_shadow = *dir_oe[priv->minor];
554 dir_shadow |= (arg & changeable_dir[priv->minor]);
555 *dir_oe[priv->minor] = dir_shadow;
556 local_irq_restore(flags);
557 return dir_shadow;
558}
559
560static int
561gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
562
563static int
564gpio_ioctl(struct inode *inode, struct file *file,
565 unsigned int cmd, unsigned long arg)
566{
567 unsigned long flags;
568 unsigned long val;
569 unsigned long shadow;
570 struct gpio_private *priv = (struct gpio_private *)file->private_data;
571 if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE)
572 return -EINVAL;
573
574#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
575 if (priv->minor == GPIO_MINOR_V)
576 return virtual_gpio_ioctl(file, cmd, arg);
577#endif
578
579 switch (_IOC_NR(cmd)) {
580 case IO_READBITS:
581
582 return *data_in[priv->minor];
583 break;
584 case IO_SETBITS:
585 local_irq_save(flags);
586
587 shadow = *data_out[priv->minor];
588 shadow |= (arg & changeable_bits[priv->minor]);
589 *data_out[priv->minor] = shadow;
590 local_irq_restore(flags);
591 break;
592 case IO_CLRBITS:
593 local_irq_save(flags);
594
595 shadow = *data_out[priv->minor];
596 shadow &= ~(arg & changeable_bits[priv->minor]);
597 *data_out[priv->minor] = shadow;
598 local_irq_restore(flags);
599 break;
600 case IO_HIGHALARM:
601
602 priv->highalarm |= arg;
603 spin_lock_irqsave(&alarm_lock, flags);
604 gpio_some_alarms = 1;
605 if (priv->minor == GPIO_MINOR_A)
606 gpio_pa_high_alarms |= arg;
607 spin_unlock_irqrestore(&alarm_lock, flags);
608 break;
609 case IO_LOWALARM:
610
611 priv->lowalarm |= arg;
612 spin_lock_irqsave(&alarm_lock, flags);
613 gpio_some_alarms = 1;
614 if (priv->minor == GPIO_MINOR_A)
615 gpio_pa_low_alarms |= arg;
616 spin_unlock_irqrestore(&alarm_lock, flags);
617 break;
618 case IO_CLRALARM:
619
620 priv->highalarm &= ~arg;
621 priv->lowalarm &= ~arg;
622 spin_lock_irqsave(&alarm_lock, flags);
623 if (priv->minor == GPIO_MINOR_A) {
624 if (gpio_pa_high_alarms & arg ||
625 gpio_pa_low_alarms & arg)
626
627 ;
628 }
629 spin_unlock_irqrestore(&alarm_lock, flags);
630 break;
631 case IO_READDIR:
632
633 return *dir_oe[priv->minor];
634 case IO_SETINPUT:
635
636
637
638 return setget_input(priv, arg);
639 break;
640 case IO_SETOUTPUT:
641
642
643
644 return setget_output(priv, arg);
645
646 case IO_CFG_WRITE_MODE:
647 {
648 unsigned long dir_shadow;
649 dir_shadow = *dir_oe[priv->minor];
650
651 priv->clk_mask = arg & 0xFF;
652 priv->data_mask = (arg >> 8) & 0xFF;
653 priv->write_msb = (arg >> 16) & 0x01;
654
655
656
657 if (!((priv->clk_mask & changeable_bits[priv->minor]) &&
658 (priv->data_mask & changeable_bits[priv->minor]) &&
659 (priv->clk_mask & dir_shadow) &&
660 (priv->data_mask & dir_shadow))) {
661 priv->clk_mask = 0;
662 priv->data_mask = 0;
663 return -EPERM;
664 }
665 break;
666 }
667 case IO_READ_INBITS:
668
669 val = *data_in[priv->minor];
670 if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
671 return -EFAULT;
672 return 0;
673 break;
674 case IO_READ_OUTBITS:
675
676 val = *data_out[priv->minor];
677 if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
678 return -EFAULT;
679 break;
680 case IO_SETGET_INPUT:
681
682
683
684 if (copy_from_user(&val, (unsigned long *)arg, sizeof(val)))
685 return -EFAULT;
686 val = setget_input(priv, val);
687 if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
688 return -EFAULT;
689 break;
690 case IO_SETGET_OUTPUT:
691
692
693
694 if (copy_from_user(&val, (unsigned long *)arg, sizeof(val)))
695 return -EFAULT;
696 val = setget_output(priv, val);
697 if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
698 return -EFAULT;
699 break;
700 default:
701 if (priv->minor == GPIO_MINOR_LEDS)
702 return gpio_leds_ioctl(cmd, arg);
703 else
704 return -EINVAL;
705 }
706
707 return 0;
708}
709
710#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
711static int
712virtual_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
713{
714 unsigned long flags;
715 unsigned short val;
716 unsigned short shadow;
717 struct gpio_private *priv = (struct gpio_private *)file->private_data;
718
719 switch (_IOC_NR(cmd)) {
720 case IO_SETBITS:
721 local_irq_save(flags);
722
723 i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
724 shadow |= ~*dir_oe[priv->minor];
725 shadow |= (arg & changeable_bits[priv->minor]);
726 i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
727 local_irq_restore(flags);
728 break;
729 case IO_CLRBITS:
730 local_irq_save(flags);
731
732 i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
733 shadow |= ~*dir_oe[priv->minor];
734 shadow &= ~(arg & changeable_bits[priv->minor]);
735 i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
736 local_irq_restore(flags);
737 break;
738 case IO_HIGHALARM:
739
740 priv->highalarm |= arg;
741 spin_lock(&alarm_lock);
742 gpio_some_alarms = 1;
743 spin_unlock(&alarm_lock);
744 break;
745 case IO_LOWALARM:
746
747 priv->lowalarm |= arg;
748 spin_lock(&alarm_lock);
749 gpio_some_alarms = 1;
750 spin_unlock(&alarm_lock);
751 break;
752 case IO_CLRALARM:
753
754 priv->highalarm &= ~arg;
755 priv->lowalarm &= ~arg;
756 spin_lock(&alarm_lock);
757 spin_unlock(&alarm_lock);
758 break;
759 case IO_CFG_WRITE_MODE:
760 {
761 unsigned long dir_shadow;
762 dir_shadow = *dir_oe[priv->minor];
763
764 priv->clk_mask = arg & 0xFF;
765 priv->data_mask = (arg >> 8) & 0xFF;
766 priv->write_msb = (arg >> 16) & 0x01;
767
768
769
770 if (!((priv->clk_mask & changeable_bits[priv->minor]) &&
771 (priv->data_mask & changeable_bits[priv->minor]) &&
772 (priv->clk_mask & dir_shadow) &&
773 (priv->data_mask & dir_shadow))) {
774 priv->clk_mask = 0;
775 priv->data_mask = 0;
776 return -EPERM;
777 }
778 break;
779 }
780 case IO_READ_INBITS:
781
782 val = cached_virtual_gpio_read;
783 val &= ~*dir_oe[priv->minor];
784 if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
785 return -EFAULT;
786 return 0;
787 break;
788 case IO_READ_OUTBITS:
789
790 i2c_read(VIRT_I2C_ADDR, (void *)&val, sizeof(val));
791 val &= *dir_oe[priv->minor];
792 if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
793 return -EFAULT;
794 break;
795 case IO_SETGET_INPUT:
796 {
797
798
799
800 unsigned short input_mask = ~*dir_oe[priv->minor];
801 if (copy_from_user(&val, (unsigned long *)arg, sizeof(val)))
802 return -EFAULT;
803 val = setget_input(priv, val);
804 if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
805 return -EFAULT;
806 if ((input_mask & val) != input_mask) {
807
808
809
810 unsigned short change = input_mask ^ val;
811 i2c_read(VIRT_I2C_ADDR, (void *)&shadow,
812 sizeof(shadow));
813 shadow &= ~change;
814 shadow |= val;
815 i2c_write(VIRT_I2C_ADDR, (void *)&shadow,
816 sizeof(shadow));
817 }
818 break;
819 }
820 case IO_SETGET_OUTPUT:
821
822
823
824 if (copy_from_user(&val, (unsigned long *)arg, sizeof(val)))
825 return -EFAULT;
826 val = setget_output(priv, val);
827 if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
828 return -EFAULT;
829 break;
830 default:
831 return -EINVAL;
832 }
833 return 0;
834}
835#endif
836
837static int
838gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
839{
840 unsigned char green;
841 unsigned char red;
842
843 switch (_IOC_NR(cmd)) {
844 case IO_LEDACTIVE_SET:
845 green = ((unsigned char) arg) & 1;
846 red = (((unsigned char) arg) >> 1) & 1;
847 CRIS_LED_ACTIVE_SET_G(green);
848 CRIS_LED_ACTIVE_SET_R(red);
849 break;
850
851 default:
852 return -EINVAL;
853 }
854
855 return 0;
856}
857
858static const struct file_operations gpio_fops = {
859 .owner = THIS_MODULE,
860 .poll = gpio_poll,
861 .ioctl = gpio_ioctl,
862 .write = gpio_write,
863 .open = gpio_open,
864 .release = gpio_release,
865};
866
867#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
868static void
869virtual_gpio_init(void)
870{
871 reg_gio_rw_intr_cfg intr_cfg;
872 reg_gio_rw_intr_mask intr_mask;
873 unsigned short shadow;
874
875 shadow = ~virtual_rw_pv_oe;
876 shadow |= CONFIG_ETRAX_DEF_GIO_PV_OUT;
877 i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
878
879
880
881
882 intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg);
883 intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
884
885 switch (CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN) {
886 case 0:
887 intr_cfg.pa0 = regk_gio_lo;
888 intr_mask.pa0 = regk_gio_yes;
889 break;
890 case 1:
891 intr_cfg.pa1 = regk_gio_lo;
892 intr_mask.pa1 = regk_gio_yes;
893 break;
894 case 2:
895 intr_cfg.pa2 = regk_gio_lo;
896 intr_mask.pa2 = regk_gio_yes;
897 break;
898 case 3:
899 intr_cfg.pa3 = regk_gio_lo;
900 intr_mask.pa3 = regk_gio_yes;
901 break;
902 case 4:
903 intr_cfg.pa4 = regk_gio_lo;
904 intr_mask.pa4 = regk_gio_yes;
905 break;
906 case 5:
907 intr_cfg.pa5 = regk_gio_lo;
908 intr_mask.pa5 = regk_gio_yes;
909 break;
910 case 6:
911 intr_cfg.pa6 = regk_gio_lo;
912 intr_mask.pa6 = regk_gio_yes;
913 break;
914 case 7:
915 intr_cfg.pa7 = regk_gio_lo;
916 intr_mask.pa7 = regk_gio_yes;
917 break;
918 }
919
920 REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg);
921 REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
922
923 gpio_pa_low_alarms |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
924 gpio_some_alarms = 1;
925}
926#endif
927
928
929
930static __init int
931gpio_init(void)
932{
933 int res;
934
935
936
937 res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
938 if (res < 0) {
939 printk(KERN_ERR "gpio: couldn't get a major number.\n");
940 return res;
941 }
942
943
944 CRIS_LED_NETWORK_GRP0_SET(0);
945 CRIS_LED_NETWORK_GRP1_SET(0);
946 CRIS_LED_ACTIVE_SET(0);
947 CRIS_LED_DISK_READ(0);
948 CRIS_LED_DISK_WRITE(0);
949
950 printk(KERN_INFO "ETRAX FS GPIO driver v2.5, (c) 2003-2007 "
951 "Axis Communications AB\n");
952
953
954
955
956
957 if (request_irq(TIMER0_INTR_VECT, gpio_poll_timer_interrupt,
958 IRQF_SHARED | IRQF_DISABLED, "gpio poll", &alarmlist))
959 printk(KERN_ERR "timer0 irq for gpio\n");
960
961 if (request_irq(GIO_INTR_VECT, gpio_pa_interrupt,
962 IRQF_SHARED | IRQF_DISABLED, "gpio PA", &alarmlist))
963 printk(KERN_ERR "PA irq for gpio\n");
964
965#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
966 virtual_gpio_init();
967#endif
968
969 return res;
970}
971
972
973
974module_init(gpio_init);
975