Linux-2.6.12-rc2
[safe/jmp/linux-2.6] / arch / cris / arch-v10 / drivers / gpio.c
1 /* $Id: gpio.c,v 1.12 2004/08/24 07:19:59 starvik Exp $
2  *
3  * Etrax general port I/O device
4  *
5  * Copyright (c) 1999, 2000, 2001, 2002 Axis Communications AB
6  *
7  * Authors:    Bjorn Wesen      (initial version)
8  *             Ola Knutsson     (LED handling)
9  *             Johan Adolfsson  (read/set directions, write, port G)
10  *
11  * $Log: gpio.c,v $
12  * Revision 1.12  2004/08/24 07:19:59  starvik
13  * Whitespace cleanup
14  *
15  * Revision 1.11  2004/05/14 07:58:03  starvik
16  * Merge of changes from 2.4
17  *
18  * Revision 1.9  2003/09/11 07:29:48  starvik
19  * Merge of Linux 2.6.0-test5
20  *
21  * Revision 1.8  2003/07/04 08:27:37  starvik
22  * Merge of Linux 2.5.74
23  *
24  * Revision 1.7  2003/01/10 07:44:07  starvik
25  * init_ioremap is now called by kernel before drivers are initialized
26  *
27  * Revision 1.6  2002/12/11 13:13:57  starvik
28  * Added arch/ to v10 specific includes
29  * Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer)
30  *
31  * Revision 1.5  2002/11/20 11:56:11  starvik
32  * Merge of Linux 2.5.48
33  *
34  * Revision 1.4  2002/11/18 10:10:05  starvik
35  * Linux 2.5 port of latest gpio.c from Linux 2.4
36  *
37  * Revision 1.20  2002/10/16 21:16:24  johana
38  * Added support for PA high level interrupt.
39  * That gives 2ms response time with iodtest for high levels and 2-12 ms
40  * response time on low levels if the check is not made in
41  * process.c:cpu_idle() as well.
42  *
43  * Revision 1.19  2002/10/14 18:27:33  johana
44  * Implemented alarm handling so select() now works.
45  * Latency is around 6-9 ms with a etrax_gpio_wake_up_check() in
46  * cpu_idle().
47  * Otherwise I get 15-18 ms (same as doing the poll in userspace -
48  * but less overhead).
49  * TODO? Perhaps we should add the check in IMMEDIATE_BH (or whatever it
50  * is in 2.4) as well?
51  * TODO? Perhaps call request_irq()/free_irq() only when needed?
52  * Increased version to 2.5
53  *
54  * Revision 1.18  2002/10/11 15:02:00  johana
55  * Mask inverted 8 bit value in setget_input().
56  *
57  * Revision 1.17  2002/06/17 15:53:01  johana
58  * Added IO_READ_INBITS, IO_READ_OUTBITS, IO_SETGET_INPUT and IO_SETGET_OUTPUT
59  * that take a pointer as argument and thus can handle 32 bit ports (G)
60  * correctly.
61  * These should be used instead of IO_READBITS, IO_SETINPUT and IO_SETOUTPUT.
62  * (especially if Port G bit 31 is used)
63  *
64  * Revision 1.16  2002/06/17 09:59:51  johana
65  * Returning 32 bit values in the ioctl return value doesn't work if bit
66  * 31 is set (could happen for port G), so mask it of with 0x7FFFFFFF.
67  * A new set of ioctl's will be added.
68  *
69  * Revision 1.15  2002/05/06 13:19:13  johana
70  * IO_SETINPUT returns mask with bit set = inputs for PA and PB as well.
71  *
72  * Revision 1.14  2002/04/12 12:01:53  johana
73  * Use global r_port_g_data_shadow.
74  * Moved gpio_init_port_g() closer to gpio_init() and marked it __init.
75  *
76  * Revision 1.13  2002/04/10 12:03:55  johana
77  * Added support for port G /dev/gpiog (minor 3).
78  * Changed indentation on switch cases.
79  * Fixed other spaces to tabs.
80  *
81  * Revision 1.12  2001/11/12 19:42:15  pkj
82  * * Corrected return values from gpio_leds_ioctl().
83  * * Fixed compiler warnings.
84  *
85  * Revision 1.11  2001/10/30 14:39:12  johana
86  * Added D() around gpio_write printk.
87  *
88  * Revision 1.10  2001/10/25 10:24:42  johana
89  * Added IO_CFG_WRITE_MODE ioctl and write method that can do fast
90  * bittoggling in the kernel. (This speeds up programming an FPGA with 450kB
91  * from ~60 seconds to 4 seconds).
92  * Added save_flags/cli/restore_flags in ioctl.
93  *
94  * Revision 1.9  2001/05/04 14:16:07  matsfg
95  * Corrected spelling error
96  *
97  * Revision 1.8  2001/04/27 13:55:26  matsfg
98  * Moved initioremap.
99  * Turns off all LEDS on init.
100  * Added support for shutdown and powerbutton.
101  *
102  * Revision 1.7  2001/04/04 13:30:08  matsfg
103  * Added bitset and bitclear for leds. Calls init_ioremap to set up memmapping
104  *
105  * Revision 1.6  2001/03/26 16:03:06  bjornw
106  * Needs linux/config.h
107  *
108  * Revision 1.5  2001/03/26 14:22:03  bjornw
109  * Namechange of some config options
110  *
111  * Revision 1.4  2001/02/27 13:52:48  bjornw
112  * malloc.h -> slab.h
113  *
114  * Revision 1.3  2001/01/24 15:06:48  bjornw
115  * gpio_wq correct type
116  *
117  * Revision 1.2  2001/01/18 16:07:30  bjornw
118  * 2.4 port
119  *
120  * Revision 1.1  2001/01/18 15:55:16  bjornw
121  * Verbatim copy of etraxgpio.c from elinux 2.0 added
122  *
123  *
124  */
125
126 #include <linux/config.h>
127
128 #include <linux/module.h>
129 #include <linux/sched.h>
130 #include <linux/slab.h>
131 #include <linux/ioport.h>
132 #include <linux/errno.h>
133 #include <linux/kernel.h>
134 #include <linux/fs.h>
135 #include <linux/string.h>
136 #include <linux/poll.h>
137 #include <linux/init.h>
138 #include <linux/interrupt.h>
139
140 #include <asm/etraxgpio.h>
141 #include <asm/arch/svinto.h>
142 #include <asm/io.h>
143 #include <asm/system.h>
144 #include <asm/irq.h>
145
146 #define GPIO_MAJOR 120  /* experimental MAJOR number */
147
148 #define D(x)
149
150 #if 0
151 static int dp_cnt;
152 #define DP(x) do { dp_cnt++; if (dp_cnt % 1000 == 0) x; }while(0)
153 #else
154 #define DP(x)
155 #endif
156         
157 static char gpio_name[] = "etrax gpio";
158
159 #if 0
160 static wait_queue_head_t *gpio_wq;
161 #endif
162
163 static int gpio_ioctl(struct inode *inode, struct file *file,
164                       unsigned int cmd, unsigned long arg);
165 static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
166                           loff_t *off);
167 static int gpio_open(struct inode *inode, struct file *filp);
168 static int gpio_release(struct inode *inode, struct file *filp);
169 static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait);
170
171 /* private data per open() of this driver */
172
173 struct gpio_private {
174         struct gpio_private *next;
175         /* These fields are for PA and PB only */
176         volatile unsigned char *port, *shadow;
177         volatile unsigned char *dir, *dir_shadow;
178         unsigned char changeable_dir;
179         unsigned char changeable_bits;
180         unsigned char clk_mask;
181         unsigned char data_mask;
182         unsigned char write_msb;
183         unsigned char pad1, pad2, pad3;
184         /* These fields are generic */
185         unsigned long highalarm, lowalarm;
186         wait_queue_head_t alarm_wq;
187         int minor;
188 };
189
190 /* linked list of alarms to check for */
191
192 static struct gpio_private *alarmlist = 0;
193
194 static int gpio_some_alarms = 0; /* Set if someone uses alarm */
195 static unsigned long gpio_pa_irq_enabled_mask = 0;
196
197 /* Port A and B use 8 bit access, but Port G is 32 bit */
198 #define NUM_PORTS (GPIO_MINOR_B+1)
199
200 static volatile unsigned char *ports[NUM_PORTS] = { 
201         R_PORT_PA_DATA, 
202         R_PORT_PB_DATA,
203 };
204 static volatile unsigned char *shads[NUM_PORTS] = {
205         &port_pa_data_shadow, 
206         &port_pb_data_shadow
207 };
208
209 /* What direction bits that are user changeable 1=changeable*/
210 #ifndef CONFIG_ETRAX_PA_CHANGEABLE_DIR
211 #define CONFIG_ETRAX_PA_CHANGEABLE_DIR 0x00
212 #endif
213 #ifndef CONFIG_ETRAX_PB_CHANGEABLE_DIR
214 #define CONFIG_ETRAX_PB_CHANGEABLE_DIR 0x00
215 #endif
216
217 #ifndef CONFIG_ETRAX_PA_CHANGEABLE_BITS
218 #define CONFIG_ETRAX_PA_CHANGEABLE_BITS 0xFF
219 #endif
220 #ifndef CONFIG_ETRAX_PB_CHANGEABLE_BITS
221 #define CONFIG_ETRAX_PB_CHANGEABLE_BITS 0xFF
222 #endif
223
224
225 static unsigned char changeable_dir[NUM_PORTS] = { 
226         CONFIG_ETRAX_PA_CHANGEABLE_DIR,
227         CONFIG_ETRAX_PB_CHANGEABLE_DIR 
228 };
229 static unsigned char changeable_bits[NUM_PORTS] = { 
230         CONFIG_ETRAX_PA_CHANGEABLE_BITS,
231         CONFIG_ETRAX_PB_CHANGEABLE_BITS 
232 };
233
234 static volatile unsigned char *dir[NUM_PORTS] = { 
235         R_PORT_PA_DIR, 
236         R_PORT_PB_DIR 
237 };
238
239 static volatile unsigned char *dir_shadow[NUM_PORTS] = {
240         &port_pa_dir_shadow, 
241         &port_pb_dir_shadow 
242 };
243
244 /* Port G is 32 bit, handle it special, some bits are both inputs 
245    and outputs at the same time, only some of the bits can change direction
246    and some of them in groups of 8 bit. */
247 static unsigned long changeable_dir_g;
248 static unsigned long dir_g_in_bits;
249 static unsigned long dir_g_out_bits;
250 static unsigned long dir_g_shadow; /* 1=output */
251
252 #define USE_PORTS(priv) ((priv)->minor <= GPIO_MINOR_B)
253
254
255
256 static unsigned int 
257 gpio_poll(struct file *file,
258           poll_table *wait)
259 {
260         unsigned int mask = 0;
261         struct gpio_private *priv = (struct gpio_private *)file->private_data;
262         unsigned long data;
263         poll_wait(file, &priv->alarm_wq, wait);
264         if (priv->minor == GPIO_MINOR_A) {
265                 unsigned long flags;
266                 unsigned long tmp;
267                 data = *R_PORT_PA_DATA;
268                 /* PA has support for high level interrupt -
269                  * lets activate for those low and with highalarm set
270                  */
271                 tmp = ~data & priv->highalarm & 0xFF;
272                 tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
273                 save_flags(flags); cli();
274                 gpio_pa_irq_enabled_mask |= tmp;
275                 *R_IRQ_MASK1_SET = tmp;
276                 restore_flags(flags);
277
278         } else if (priv->minor == GPIO_MINOR_B)
279                 data = *R_PORT_PB_DATA;
280         else if (priv->minor == GPIO_MINOR_G)
281                 data = *R_PORT_G_DATA;
282         else
283                 return 0;
284         
285         if ((data & priv->highalarm) ||
286             (~data & priv->lowalarm)) {
287                 mask = POLLIN|POLLRDNORM;
288         }
289         
290         DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
291         return mask;
292 }
293
294 int etrax_gpio_wake_up_check(void)
295 {
296         struct gpio_private *priv = alarmlist;
297         unsigned long data = 0;
298         int ret = 0;
299         while (priv) {
300                 if (USE_PORTS(priv)) {
301                         data = *priv->port;
302                 } else if (priv->minor == GPIO_MINOR_G) {
303                         data = *R_PORT_G_DATA;
304                 }
305                 if ((data & priv->highalarm) ||
306                     (~data & priv->lowalarm)) {
307                         DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor));
308                         wake_up_interruptible(&priv->alarm_wq);
309                         ret = 1;
310                 }
311                 priv = priv->next;
312         }
313         return ret;
314 }
315
316 static irqreturn_t
317 gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
318 {
319         if (gpio_some_alarms) {
320                 etrax_gpio_wake_up_check();
321                 return IRQ_HANDLED;
322         }
323         return IRQ_NONE;
324 }
325
326 static irqreturn_t
327 gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
328 {
329         unsigned long tmp;
330         /* Find what PA interrupts are active */
331         tmp = (*R_IRQ_READ1);
332
333         /* Find those that we have enabled */
334         tmp &= gpio_pa_irq_enabled_mask;
335
336         /* Clear them.. */
337         *R_IRQ_MASK1_CLR = tmp;
338         gpio_pa_irq_enabled_mask &= ~tmp;
339
340         if (gpio_some_alarms) {
341                 return IRQ_RETVAL(etrax_gpio_wake_up_check());
342         }
343         return IRQ_NONE;
344 }
345
346
347 static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
348                           loff_t *off)
349 {
350         struct gpio_private *priv = (struct gpio_private *)file->private_data;
351         unsigned char data, clk_mask, data_mask, write_msb;
352         unsigned long flags;
353         ssize_t retval = count;
354         if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) {
355                 return -EFAULT;
356         }
357     
358         if (!access_ok(VERIFY_READ, buf, count)) {
359                 return -EFAULT;
360         }
361         clk_mask = priv->clk_mask;
362         data_mask = priv->data_mask;
363         /* It must have been configured using the IO_CFG_WRITE_MODE */
364         /* Perhaps a better error code? */
365         if (clk_mask == 0 || data_mask == 0) {
366                 return -EPERM;
367         }
368         write_msb = priv->write_msb;
369         D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb));
370         while (count--) {
371                 int i;
372                 data = *buf++;
373                 if (priv->write_msb) {
374                         for (i = 7; i >= 0;i--) {
375                                 local_irq_save(flags); local_irq_disable();
376                                 *priv->port = *priv->shadow &= ~clk_mask;
377                                 if (data & 1<<i)
378                                         *priv->port = *priv->shadow |= data_mask;
379                                 else
380                                         *priv->port = *priv->shadow &= ~data_mask;
381                         /* For FPGA: min 5.0ns (DCC) before CCLK high */
382                                 *priv->port = *priv->shadow |= clk_mask;
383                                 local_irq_restore(flags);
384                         }
385                 } else {
386                         for (i = 0; i <= 7;i++) {
387                                 local_irq_save(flags); local_irq_disable();
388                                 *priv->port = *priv->shadow &= ~clk_mask;
389                                 if (data & 1<<i)
390                                         *priv->port = *priv->shadow |= data_mask;
391                                 else
392                                         *priv->port = *priv->shadow &= ~data_mask;
393                         /* For FPGA: min 5.0ns (DCC) before CCLK high */
394                                 *priv->port = *priv->shadow |= clk_mask;
395                                 local_irq_restore(flags);
396                         }
397                 }
398         }
399         return retval;
400 }
401
402
403
404 static int
405 gpio_open(struct inode *inode, struct file *filp)
406 {
407         struct gpio_private *priv;
408         int p = MINOR(inode->i_rdev);
409
410         if (p > GPIO_MINOR_LAST)
411                 return -EINVAL;
412
413         priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private), 
414                                               GFP_KERNEL);
415
416         if (!priv)
417                 return -ENOMEM;
418
419         priv->minor = p;
420
421         /* initialize the io/alarm struct and link it into our alarmlist */
422
423         priv->next = alarmlist;
424         alarmlist = priv;
425         if (USE_PORTS(priv)) { /* A and B */
426                 priv->port = ports[p];
427                 priv->shadow = shads[p];
428                 priv->dir = dir[p];
429                 priv->dir_shadow = dir_shadow[p];
430                 priv->changeable_dir = changeable_dir[p];
431                 priv->changeable_bits = changeable_bits[p];
432         } else {
433                 priv->port = NULL;
434                 priv->shadow = NULL;
435                 priv->dir = NULL;
436                 priv->dir_shadow = NULL;
437                 priv->changeable_dir = 0;
438                 priv->changeable_bits = 0;
439         }
440
441         priv->highalarm = 0;
442         priv->lowalarm = 0;
443         priv->clk_mask = 0;
444         priv->data_mask = 0;
445         init_waitqueue_head(&priv->alarm_wq);
446
447         filp->private_data = (void *)priv;
448
449         return 0;
450 }
451
452 static int
453 gpio_release(struct inode *inode, struct file *filp)
454 {
455         struct gpio_private *p = alarmlist;
456         struct gpio_private *todel = (struct gpio_private *)filp->private_data;
457         
458         /* unlink from alarmlist and free the private structure */
459
460         if (p == todel) {
461                 alarmlist = todel->next;
462         } else {
463                 while (p->next != todel)
464                         p = p->next;
465                 p->next = todel->next;
466         }
467
468         kfree(todel);
469         /* Check if there are still any alarms set */
470         p = alarmlist;
471         while (p) {
472                 if (p->highalarm | p->lowalarm) {
473                         gpio_some_alarms = 1;
474                         return 0;
475                 }
476                 p = p->next;
477         }
478         gpio_some_alarms = 0;
479                 
480         return 0;
481 }
482
483 /* Main device API. ioctl's to read/set/clear bits, as well as to 
484  * set alarms to wait for using a subsequent select().
485  */
486
487 unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
488 {
489         /* Set direction 0=unchanged 1=input, 
490          * return mask with 1=input 
491          */
492         unsigned long flags;
493         if (USE_PORTS(priv)) {
494                 local_irq_save(flags); local_irq_disable();
495                 *priv->dir = *priv->dir_shadow &= 
496                 ~((unsigned char)arg & priv->changeable_dir);
497                 local_irq_restore(flags);
498                 return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */
499         } else if (priv->minor == GPIO_MINOR_G) {
500                 /* We must fiddle with R_GEN_CONFIG to change dir */
501                 save_flags(flags); cli();
502                 if (((arg & dir_g_in_bits) != arg) && 
503                     (arg & changeable_dir_g)) {
504                         arg &= changeable_dir_g;
505                         /* Clear bits in genconfig to set to input */
506                         if (arg & (1<<0)) {
507                                 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g0dir);
508                                 dir_g_in_bits |= (1<<0);
509                                 dir_g_out_bits &= ~(1<<0);
510                         }
511                         if ((arg & 0x0000FF00) == 0x0000FF00) {
512                                 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g8_15dir);
513                                 dir_g_in_bits |= 0x0000FF00;
514                                 dir_g_out_bits &= ~0x0000FF00;
515                         }
516                         if ((arg & 0x00FF0000) == 0x00FF0000) {
517                                 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g16_23dir);
518                                 dir_g_in_bits |= 0x00FF0000;
519                                 dir_g_out_bits &= ~0x00FF0000;
520                         }
521                         if (arg & (1<<24)) {
522                                 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g24dir);
523                                 dir_g_in_bits |= (1<<24);
524                                 dir_g_out_bits &= ~(1<<24);
525                         }
526                         D(printk(KERN_INFO "gpio: SETINPUT on port G set "
527                                  "genconfig to 0x%08lX "
528                                  "in_bits: 0x%08lX "
529                                  "out_bits: 0x%08lX\n",
530                                  (unsigned long)genconfig_shadow,
531                                  dir_g_in_bits, dir_g_out_bits));
532                         *R_GEN_CONFIG = genconfig_shadow;
533                         /* Must be a >120 ns delay before writing this again */
534                                 
535                 }
536                 restore_flags(flags);
537                 return dir_g_in_bits;
538         }
539         return 0;
540 } /* setget_input */
541
542 unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
543 {
544         unsigned long flags;
545         if (USE_PORTS(priv)) {
546                 local_irq_save(flags); local_irq_disable();
547                 *priv->dir = *priv->dir_shadow |= 
548                   ((unsigned char)arg & priv->changeable_dir);
549                 local_irq_restore(flags);
550                 return *priv->dir_shadow;
551         } else if (priv->minor == GPIO_MINOR_G) {
552                 /* We must fiddle with R_GEN_CONFIG to change dir */                    
553                 save_flags(flags); cli();
554                 if (((arg & dir_g_out_bits) != arg) &&
555                     (arg & changeable_dir_g)) {
556                         /* Set bits in genconfig to set to output */
557                         if (arg & (1<<0)) {
558                                 genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g0dir);
559                                 dir_g_out_bits |= (1<<0);
560                                 dir_g_in_bits &= ~(1<<0);
561                         }
562                         if ((arg & 0x0000FF00) == 0x0000FF00) {
563                                 genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir);
564                                 dir_g_out_bits |= 0x0000FF00;
565                                 dir_g_in_bits &= ~0x0000FF00;
566                         }
567                         if ((arg & 0x00FF0000) == 0x00FF0000) {
568                                 genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir);
569                                 dir_g_out_bits |= 0x00FF0000;
570                                 dir_g_in_bits &= ~0x00FF0000;
571                         }
572                         if (arg & (1<<24)) {
573                                 genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g24dir);
574                                 dir_g_out_bits |= (1<<24);
575                                 dir_g_in_bits &= ~(1<<24);
576                         }
577                         D(printk(KERN_INFO "gpio: SETOUTPUT on port G set "
578                                  "genconfig to 0x%08lX "
579                                  "in_bits: 0x%08lX "
580                                  "out_bits: 0x%08lX\n",
581                                  (unsigned long)genconfig_shadow,
582                                  dir_g_in_bits, dir_g_out_bits));
583                         *R_GEN_CONFIG = genconfig_shadow;
584                         /* Must be a >120 ns delay before writing this again */
585                 }
586                 restore_flags(flags);
587                 return dir_g_out_bits & 0x7FFFFFFF;
588         }
589         return 0;
590 } /* setget_output */
591
592 static int
593 gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
594
595 static int
596 gpio_ioctl(struct inode *inode, struct file *file,
597            unsigned int cmd, unsigned long arg)
598 {
599         unsigned long flags;
600         unsigned long val;
601         struct gpio_private *priv = (struct gpio_private *)file->private_data;
602         if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) {
603                 return -EINVAL;
604         }
605
606         switch (_IOC_NR(cmd)) {
607         case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
608                 // read the port
609                 if (USE_PORTS(priv)) {
610                         return *priv->port;
611                 } else if (priv->minor == GPIO_MINOR_G) {
612                         return (*R_PORT_G_DATA) & 0x7FFFFFFF;
613                 }
614                 break;
615         case IO_SETBITS:
616                 local_irq_save(flags); local_irq_disable();
617                 // set changeable bits with a 1 in arg
618                 if (USE_PORTS(priv)) {
619                         *priv->port = *priv->shadow |= 
620                           ((unsigned char)arg & priv->changeable_bits);
621                 } else if (priv->minor == GPIO_MINOR_G) {
622                         *R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits);
623                 }
624                 local_irq_restore(flags);
625                 break;
626         case IO_CLRBITS:
627                 local_irq_save(flags); local_irq_disable();
628                 // clear changeable bits with a 1 in arg
629                 if (USE_PORTS(priv)) {
630                         *priv->port = *priv->shadow &= 
631                          ~((unsigned char)arg & priv->changeable_bits);
632                 } else if (priv->minor == GPIO_MINOR_G) {
633                         *R_PORT_G_DATA = port_g_data_shadow &= ~((unsigned long)arg & dir_g_out_bits);
634                 }
635                 local_irq_restore(flags);
636                 break;
637         case IO_HIGHALARM:
638                 // set alarm when bits with 1 in arg go high
639                 priv->highalarm |= arg;
640                 gpio_some_alarms = 1;
641                 break;
642         case IO_LOWALARM:
643                 // set alarm when bits with 1 in arg go low
644                 priv->lowalarm |= arg;
645                 gpio_some_alarms = 1;
646                 break;
647         case IO_CLRALARM:
648                 // clear alarm for bits with 1 in arg
649                 priv->highalarm &= ~arg;
650                 priv->lowalarm  &= ~arg;
651                 {
652                         /* Must update gpio_some_alarms */
653                         struct gpio_private *p = alarmlist;
654                         int some_alarms;
655                         some_alarms = 0;
656                         while (p) {
657                                 if (p->highalarm | p->lowalarm) {
658                                         some_alarms = 1;
659                                         break;
660                                 }
661                                 p = p->next;
662                         }
663                         gpio_some_alarms = some_alarms;
664                 }
665                 break;
666         case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
667                 /* Read direction 0=input 1=output */
668                 if (USE_PORTS(priv)) {
669                         return *priv->dir_shadow;
670                 } else if (priv->minor == GPIO_MINOR_G) {
671                         /* Note: Some bits are both in and out,
672                          * Those that are dual is set here as well.
673                          */
674                         return (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
675                 }
676         case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
677                 /* Set direction 0=unchanged 1=input, 
678                  * return mask with 1=input 
679                  */
680                 return setget_input(priv, arg) & 0x7FFFFFFF;
681                 break;
682         case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
683                 /* Set direction 0=unchanged 1=output, 
684                  * return mask with 1=output 
685                  */
686                 return setget_output(priv, arg) & 0x7FFFFFFF;
687
688         case IO_SHUTDOWN:
689                 SOFT_SHUTDOWN();
690                 break;
691         case IO_GET_PWR_BT:
692 #if defined (CONFIG_ETRAX_SOFT_SHUTDOWN)
693                 return (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
694 #else
695                 return 0;
696 #endif
697                 break;
698         case IO_CFG_WRITE_MODE:
699                 priv->clk_mask = arg & 0xFF;
700                 priv->data_mask = (arg >> 8) & 0xFF;
701                 priv->write_msb = (arg >> 16) & 0x01;
702                 /* Check if we're allowed to change the bits and
703                  * the direction is correct
704                  */
705                 if (!((priv->clk_mask & priv->changeable_bits) &&
706                       (priv->data_mask & priv->changeable_bits) &&
707                       (priv->clk_mask & *priv->dir_shadow) &&
708                       (priv->data_mask & *priv->dir_shadow)))
709                 {
710                         priv->clk_mask = 0;
711                         priv->data_mask = 0;
712                         return -EPERM;
713                 }
714                 break;
715         case IO_READ_INBITS: 
716                 /* *arg is result of reading the input pins */
717                 if (USE_PORTS(priv)) {
718                         val = *priv->port;
719                 } else if (priv->minor == GPIO_MINOR_G) {
720                         val = *R_PORT_G_DATA;
721                 }
722                 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
723                         return -EFAULT;
724                 return 0;
725                 break;
726         case IO_READ_OUTBITS:
727                  /* *arg is result of reading the output shadow */
728                 if (USE_PORTS(priv)) {
729                         val = *priv->shadow;
730                 } else if (priv->minor == GPIO_MINOR_G) {
731                         val = port_g_data_shadow;
732                 }
733                 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
734                         return -EFAULT;
735                 break;
736         case IO_SETGET_INPUT: 
737                 /* bits set in *arg is set to input,
738                  * *arg updated with current input pins.
739                  */
740                 if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
741                         return -EFAULT;
742                 val = setget_input(priv, val);
743                 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
744                         return -EFAULT;
745                 break;
746         case IO_SETGET_OUTPUT:
747                 /* bits set in *arg is set to output,
748                  * *arg updated with current output pins.
749                  */
750                 if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
751                         return -EFAULT;
752                 val = setget_output(priv, val);
753                 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
754                         return -EFAULT;
755                 break;
756         default:
757                 if (priv->minor == GPIO_MINOR_LEDS)
758                         return gpio_leds_ioctl(cmd, arg);
759                 else
760                         return -EINVAL;
761         } /* switch */
762         
763         return 0;
764 }
765
766 static int
767 gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
768 {
769         unsigned char green;
770         unsigned char red;
771
772         switch (_IOC_NR(cmd)) {
773         case IO_LEDACTIVE_SET:
774                 green = ((unsigned char) arg) & 1;
775                 red   = (((unsigned char) arg) >> 1) & 1;
776                 LED_ACTIVE_SET_G(green);
777                 LED_ACTIVE_SET_R(red);
778                 break;
779
780         case IO_LED_SETBIT:
781                 LED_BIT_SET(arg);
782                 break;
783
784         case IO_LED_CLRBIT:
785                 LED_BIT_CLR(arg);
786                 break;
787
788         default:
789                 return -EINVAL;
790         } /* switch */
791
792         return 0;
793 }
794
795 struct file_operations gpio_fops = {
796         .owner       = THIS_MODULE,
797         .poll        = gpio_poll,
798         .ioctl       = gpio_ioctl,
799         .write       = gpio_write,
800         .open        = gpio_open,
801         .release     = gpio_release,
802 };
803
804
805 static void __init gpio_init_port_g(void)
806 {
807 #define GROUPA (0x0000FF3F)
808 #define GROUPB (1<<6 | 1<<7)
809 #define GROUPC (1<<30 | 1<<31)
810 #define GROUPD (0x3FFF0000)
811 #define GROUPD_LOW (0x00FF0000)
812         unsigned long used_in_bits = 0;
813         unsigned long used_out_bits = 0;
814         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi0, select)){
815                 used_in_bits  |= GROUPA | GROUPB | 0 | 0;
816                 used_out_bits |= GROUPA | GROUPB | 0 | 0;
817         }
818         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ata, select)) {
819                 used_in_bits  |= GROUPA | GROUPB | GROUPC | (GROUPD & ~(1<<25|1<<26));
820                 used_out_bits |= GROUPA | GROUPB | GROUPC | GROUPD;
821         }
822
823         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, par0, select)) {
824                 used_in_bits  |= (GROUPA & ~(1<<0)) | 0 | 0 | 0;
825                 used_out_bits |= (GROUPA & ~(1<<0)) | 0 | 0 | 0;
826         }
827         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ser2, select)) {
828                 used_in_bits  |= 0 | GROUPB | 0 | 0;
829                 used_out_bits |= 0 | GROUPB | 0 | 0;
830         }
831         /* mio same as shared RAM ? */
832         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, mio, select)) {
833                 used_in_bits  |= (GROUPA & ~(1<<0)) | 0 |0 |GROUPD_LOW;
834                 used_out_bits |= (GROUPA & ~(1<<0|1<<1|1<<2)) | 0 |0 |GROUPD_LOW;
835         }
836         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi1, select)) {
837                 used_in_bits  |= 0 | 0 | GROUPC | GROUPD;
838                 used_out_bits |= 0 | 0 | GROUPC | GROUPD;
839         }
840         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi0w, select)) {
841                 used_in_bits  |= GROUPA | GROUPB | 0 | (GROUPD_LOW | 1<<24);
842                 used_out_bits |= GROUPA | GROUPB | 0 | (GROUPD_LOW | 1<<24 | 1<<25|1<<26);
843         }
844
845         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, par1, select)) {
846                 used_in_bits  |= 0 | 0 | 0 | (GROUPD & ~(1<<24));
847                 used_out_bits |= 0 | 0 | 0 | (GROUPD & ~(1<<24));
848         }
849         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ser3, select)) {
850                 used_in_bits  |= 0 | 0 | GROUPC | 0;
851                 used_out_bits |= 0 | 0 | GROUPC | 0;
852         }
853         /* mio same as shared RAM-W? */
854         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, mio_w, select)) {
855                 used_in_bits  |= (GROUPA & ~(1<<0)) | 0 | 0 |GROUPD_LOW;
856                 used_out_bits |= (GROUPA & ~(1<<0|1<<1|1<<2)) | 0 | 0 |GROUPD_LOW;
857         }
858         /* TODO: USB p2, parw, sync ser3? */
859
860         /* Initialise the dir_g_shadow etc. depending on genconfig */
861         /* 0=input 1=output */
862         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g0dir, out)) 
863                 dir_g_shadow |= (1 << 0);
864         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g8_15dir, out))
865                 dir_g_shadow |= 0x0000FF00;
866         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g16_23dir, out))
867                 dir_g_shadow |= 0x00FF0000;
868         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g24dir, out))
869                 dir_g_shadow |= (1 << 24);
870
871         dir_g_in_bits = ~used_in_bits;
872         dir_g_out_bits = ~used_out_bits;
873
874         changeable_dir_g = 0x01FFFF01; /* all that can change dir */
875         changeable_dir_g &= dir_g_out_bits;
876         changeable_dir_g &= dir_g_in_bits;
877         /* Correct the bits that can change direction */ 
878         dir_g_out_bits &= ~changeable_dir_g;
879         dir_g_out_bits |= dir_g_shadow;
880         dir_g_in_bits &= ~changeable_dir_g;
881         dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g);
882
883
884         printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n",
885                dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA);
886         printk(KERN_INFO "GPIO port G: dir: %08lX changeable: %08lX\n",
887                dir_g_shadow, changeable_dir_g);
888 }
889
890 /* main driver initialization routine, called from mem.c */
891
892 static __init int
893 gpio_init(void)
894 {
895         int res;
896 #if defined (CONFIG_ETRAX_CSP0_LEDS)
897         int i;
898 #endif
899
900         /* do the formalities */
901
902         res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
903         if (res < 0) {
904                 printk(KERN_ERR "gpio: couldn't get a major number.\n");
905                 return res;
906         }
907
908         /* Clear all leds */
909 #if defined (CONFIG_ETRAX_CSP0_LEDS) ||  defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS)
910         LED_NETWORK_SET(0);
911         LED_ACTIVE_SET(0);
912         LED_DISK_READ(0);
913         LED_DISK_WRITE(0);
914
915 #if defined (CONFIG_ETRAX_CSP0_LEDS)
916         for (i = 0; i < 32; i++) {
917                 LED_BIT_SET(i);
918         }
919 #endif
920
921 #endif
922         gpio_init_port_g();
923         printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002 Axis Communications AB\n");
924         /* We call etrax_gpio_wake_up_check() from timer interrupt and
925          * from cpu_idle() in kernel/process.c
926          * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
927          * in some tests.
928          */  
929         if (request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
930                         SA_SHIRQ | SA_INTERRUPT,"gpio poll", NULL)) {
931                 printk(KERN_CRIT "err: timer0 irq for gpio\n");
932         }
933         if (request_irq(PA_IRQ_NBR, gpio_pa_interrupt,
934                         SA_SHIRQ | SA_INTERRUPT,"gpio PA", NULL)) {
935                 printk(KERN_CRIT "err: PA irq for gpio\n");
936         }
937         
938
939         return res;
940 }
941
942 /* this makes sure that gpio_init is called during kernel boot */
943
944 module_init(gpio_init);