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