• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/src/linux/linux-2.6/arch/cris/arch-v10/drivers/
1/* $Id: gpio.c,v 1.1.1.1 2007-08-03 18:51:41 $
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: not supported by cvs2svn $
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#define DP(x)
163
164static char gpio_name[] = "etrax gpio";
165
166
167static int gpio_ioctl(struct inode *inode, struct file *file,
168		      unsigned int cmd, unsigned long arg);
169static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
170                          loff_t *off);
171static int gpio_open(struct inode *inode, struct file *filp);
172static int gpio_release(struct inode *inode, struct file *filp);
173static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait);
174
175/* private data per open() of this driver */
176
177struct gpio_private {
178	struct gpio_private *next;
179	/* These fields are for PA and PB only */
180	volatile unsigned char *port, *shadow;
181	volatile unsigned char *dir, *dir_shadow;
182	unsigned char changeable_dir;
183	unsigned char changeable_bits;
184	unsigned char clk_mask;
185	unsigned char data_mask;
186	unsigned char write_msb;
187	unsigned char pad1, pad2, pad3;
188	/* These fields are generic */
189	unsigned long highalarm, lowalarm;
190	wait_queue_head_t alarm_wq;
191	int minor;
192};
193
194/* linked list of alarms to check for */
195
196static struct gpio_private *alarmlist = 0;
197
198static int gpio_some_alarms = 0; /* Set if someone uses alarm */
199static unsigned long gpio_pa_irq_enabled_mask = 0;
200
201static DEFINE_SPINLOCK(gpio_lock); /* Protect directions etc */
202
203/* Port A and B use 8 bit access, but Port G is 32 bit */
204#define NUM_PORTS (GPIO_MINOR_B+1)
205
206static volatile unsigned char *ports[NUM_PORTS] = {
207	R_PORT_PA_DATA,
208	R_PORT_PB_DATA,
209};
210static volatile unsigned char *shads[NUM_PORTS] = {
211	&port_pa_data_shadow,
212	&port_pb_data_shadow
213};
214
215/* What direction bits that are user changeable 1=changeable*/
216#ifndef CONFIG_ETRAX_PA_CHANGEABLE_DIR
217#define CONFIG_ETRAX_PA_CHANGEABLE_DIR 0x00
218#endif
219#ifndef CONFIG_ETRAX_PB_CHANGEABLE_DIR
220#define CONFIG_ETRAX_PB_CHANGEABLE_DIR 0x00
221#endif
222
223#ifndef CONFIG_ETRAX_PA_CHANGEABLE_BITS
224#define CONFIG_ETRAX_PA_CHANGEABLE_BITS 0xFF
225#endif
226#ifndef CONFIG_ETRAX_PB_CHANGEABLE_BITS
227#define CONFIG_ETRAX_PB_CHANGEABLE_BITS 0xFF
228#endif
229
230
231static unsigned char changeable_dir[NUM_PORTS] = {
232	CONFIG_ETRAX_PA_CHANGEABLE_DIR,
233	CONFIG_ETRAX_PB_CHANGEABLE_DIR
234};
235static unsigned char changeable_bits[NUM_PORTS] = {
236	CONFIG_ETRAX_PA_CHANGEABLE_BITS,
237	CONFIG_ETRAX_PB_CHANGEABLE_BITS
238};
239
240static volatile unsigned char *dir[NUM_PORTS] = {
241	R_PORT_PA_DIR,
242	R_PORT_PB_DIR
243};
244
245static volatile unsigned char *dir_shadow[NUM_PORTS] = {
246	&port_pa_dir_shadow,
247	&port_pb_dir_shadow
248};
249
250/* All bits in port g that can change dir. */
251static const unsigned long int changeable_dir_g_mask = 0x01FFFF01;
252
253/* Port G is 32 bit, handle it special, some bits are both inputs
254   and outputs at the same time, only some of the bits can change direction
255   and some of them in groups of 8 bit. */
256static unsigned long changeable_dir_g;
257static unsigned long dir_g_in_bits;
258static unsigned long dir_g_out_bits;
259static unsigned long dir_g_shadow; /* 1=output */
260
261#define USE_PORTS(priv) ((priv)->minor <= GPIO_MINOR_B)
262
263
264
265static unsigned int
266gpio_poll(struct file *file,
267	  poll_table *wait)
268{
269	unsigned int mask = 0;
270	struct gpio_private *priv = (struct gpio_private *)file->private_data;
271	unsigned long data;
272	spin_lock(&gpio_lock);
273	poll_wait(file, &priv->alarm_wq, wait);
274	if (priv->minor == GPIO_MINOR_A) {
275		unsigned long flags;
276		unsigned long tmp;
277		data = *R_PORT_PA_DATA;
278		/* PA has support for high level interrupt -
279		 * lets activate for those low and with highalarm set
280		 */
281		tmp = ~data & priv->highalarm & 0xFF;
282		tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
283		local_irq_save(flags);
284		gpio_pa_irq_enabled_mask |= tmp;
285		*R_IRQ_MASK1_SET = tmp;
286		local_irq_restore(flags);
287
288	} else if (priv->minor == GPIO_MINOR_B)
289		data = *R_PORT_PB_DATA;
290	else if (priv->minor == GPIO_MINOR_G)
291		data = *R_PORT_G_DATA;
292	else
293		return 0;
294
295	if ((data & priv->highalarm) ||
296	    (~data & priv->lowalarm)) {
297		mask = POLLIN|POLLRDNORM;
298	}
299
300	spin_unlock(&gpio_lock);
301
302	DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
303
304	return mask;
305}
306
307int etrax_gpio_wake_up_check(void)
308{
309	struct gpio_private *priv = alarmlist;
310	unsigned long data = 0;
311        int ret = 0;
312	spin_lock(&gpio_lock);
313	while (priv) {
314		if (USE_PORTS(priv)) {
315			data = *priv->port;
316		} else if (priv->minor == GPIO_MINOR_G) {
317			data = *R_PORT_G_DATA;
318		}
319		if ((data & priv->highalarm) ||
320		    (~data & priv->lowalarm)) {
321			DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor));
322			wake_up_interruptible(&priv->alarm_wq);
323                        ret = 1;
324		}
325		priv = priv->next;
326	}
327	spin_unlock(&gpio_lock);
328        return ret;
329}
330
331static irqreturn_t
332gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
333{
334	if (gpio_some_alarms) {
335		etrax_gpio_wake_up_check();
336                return IRQ_HANDLED;
337	}
338        return IRQ_NONE;
339}
340
341static irqreturn_t
342gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
343{
344	unsigned long tmp;
345	spin_lock(&gpio_lock);
346	/* Find what PA interrupts are active */
347	tmp = (*R_IRQ_READ1);
348
349	/* Find those that we have enabled */
350	tmp &= gpio_pa_irq_enabled_mask;
351
352	/* Clear them.. */
353	*R_IRQ_MASK1_CLR = tmp;
354	gpio_pa_irq_enabled_mask &= ~tmp;
355
356	spin_unlock(&gpio_lock);
357
358	if (gpio_some_alarms) {
359		return IRQ_RETVAL(etrax_gpio_wake_up_check());
360	}
361        return IRQ_NONE;
362}
363
364
365static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
366                          loff_t *off)
367{
368	struct gpio_private *priv = (struct gpio_private *)file->private_data;
369	unsigned char data, clk_mask, data_mask, write_msb;
370	unsigned long flags;
371
372	spin_lock(&gpio_lock);
373
374	ssize_t retval = count;
375	if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) {
376		return -EFAULT;
377	}
378
379	if (!access_ok(VERIFY_READ, buf, count)) {
380		return -EFAULT;
381	}
382	clk_mask = priv->clk_mask;
383	data_mask = priv->data_mask;
384	/* It must have been configured using the IO_CFG_WRITE_MODE */
385	/* Perhaps a better error code? */
386	if (clk_mask == 0 || data_mask == 0) {
387		return -EPERM;
388	}
389	write_msb = priv->write_msb;
390	D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb));
391	while (count--) {
392		int i;
393		data = *buf++;
394		if (priv->write_msb) {
395			for (i = 7; i >= 0;i--) {
396				local_irq_save(flags);
397				*priv->port = *priv->shadow &= ~clk_mask;
398				if (data & 1<<i)
399					*priv->port = *priv->shadow |= data_mask;
400				else
401					*priv->port = *priv->shadow &= ~data_mask;
402			/* For FPGA: min 5.0ns (DCC) before CCLK high */
403				*priv->port = *priv->shadow |= clk_mask;
404				local_irq_restore(flags);
405			}
406		} else {
407			for (i = 0; i <= 7;i++) {
408				local_irq_save(flags);
409				*priv->port = *priv->shadow &= ~clk_mask;
410				if (data & 1<<i)
411					*priv->port = *priv->shadow |= data_mask;
412				else
413					*priv->port = *priv->shadow &= ~data_mask;
414			/* For FPGA: min 5.0ns (DCC) before CCLK high */
415				*priv->port = *priv->shadow |= clk_mask;
416				local_irq_restore(flags);
417			}
418		}
419	}
420	spin_unlock(&gpio_lock);
421	return retval;
422}
423
424
425
426static int
427gpio_open(struct inode *inode, struct file *filp)
428{
429	struct gpio_private *priv;
430	int p = iminor(inode);
431
432	if (p > GPIO_MINOR_LAST)
433		return -EINVAL;
434
435	priv = kmalloc(sizeof(struct gpio_private),
436					      GFP_KERNEL);
437
438	if (!priv)
439		return -ENOMEM;
440
441	priv->minor = p;
442
443	/* initialize the io/alarm struct and link it into our alarmlist */
444
445	priv->next = alarmlist;
446	alarmlist = priv;
447	if (USE_PORTS(priv)) { /* A and B */
448		priv->port = ports[p];
449		priv->shadow = shads[p];
450		priv->dir = dir[p];
451		priv->dir_shadow = dir_shadow[p];
452		priv->changeable_dir = changeable_dir[p];
453		priv->changeable_bits = changeable_bits[p];
454	} else {
455		priv->port = NULL;
456		priv->shadow = NULL;
457		priv->dir = NULL;
458		priv->dir_shadow = NULL;
459		priv->changeable_dir = 0;
460		priv->changeable_bits = 0;
461	}
462
463	priv->highalarm = 0;
464	priv->lowalarm = 0;
465	priv->clk_mask = 0;
466	priv->data_mask = 0;
467	init_waitqueue_head(&priv->alarm_wq);
468
469	filp->private_data = (void *)priv;
470
471	return 0;
472}
473
474static int
475gpio_release(struct inode *inode, struct file *filp)
476{
477	struct gpio_private *p;
478	struct gpio_private *todel;
479
480	spin_lock(&gpio_lock);
481
482        p = alarmlist;
483        todel = (struct gpio_private *)filp->private_data;
484
485	/* unlink from alarmlist and free the private structure */
486
487	if (p == todel) {
488		alarmlist = todel->next;
489	} else {
490		while (p->next != todel)
491			p = p->next;
492		p->next = todel->next;
493	}
494
495	kfree(todel);
496	/* Check if there are still any alarms set */
497	p = alarmlist;
498	while (p) {
499		if (p->highalarm | p->lowalarm) {
500			gpio_some_alarms = 1;
501			return 0;
502		}
503		p = p->next;
504	}
505	gpio_some_alarms = 0;
506	spin_unlock(&gpio_lock);
507	return 0;
508}
509
510/* Main device API. ioctl's to read/set/clear bits, as well as to
511 * set alarms to wait for using a subsequent select().
512 */
513
514unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
515{
516	/* Set direction 0=unchanged 1=input,
517	 * return mask with 1=input
518	 */
519	unsigned long flags;
520	if (USE_PORTS(priv)) {
521		local_irq_save(flags);
522		*priv->dir = *priv->dir_shadow &=
523		~((unsigned char)arg & priv->changeable_dir);
524		local_irq_restore(flags);
525		return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */
526	} else if (priv->minor == GPIO_MINOR_G) {
527		/* We must fiddle with R_GEN_CONFIG to change dir */
528		local_irq_save(flags);
529		if (((arg & dir_g_in_bits) != arg) &&
530		    (arg & changeable_dir_g)) {
531			arg &= changeable_dir_g;
532			/* Clear bits in genconfig to set to input */
533			if (arg & (1<<0)) {
534				genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g0dir);
535				dir_g_in_bits |= (1<<0);
536				dir_g_out_bits &= ~(1<<0);
537			}
538			if ((arg & 0x0000FF00) == 0x0000FF00) {
539				genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g8_15dir);
540				dir_g_in_bits |= 0x0000FF00;
541				dir_g_out_bits &= ~0x0000FF00;
542			}
543			if ((arg & 0x00FF0000) == 0x00FF0000) {
544				genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g16_23dir);
545				dir_g_in_bits |= 0x00FF0000;
546				dir_g_out_bits &= ~0x00FF0000;
547			}
548			if (arg & (1<<24)) {
549				genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g24dir);
550				dir_g_in_bits |= (1<<24);
551				dir_g_out_bits &= ~(1<<24);
552			}
553			D(printk(KERN_INFO "gpio: SETINPUT on port G set "
554				 "genconfig to 0x%08lX "
555				 "in_bits: 0x%08lX "
556				 "out_bits: 0x%08lX\n",
557			         (unsigned long)genconfig_shadow,
558			         dir_g_in_bits, dir_g_out_bits));
559			*R_GEN_CONFIG = genconfig_shadow;
560			/* Must be a >120 ns delay before writing this again */
561
562		}
563		local_irq_restore(flags);
564		return dir_g_in_bits;
565	}
566	return 0;
567} /* setget_input */
568
569unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
570{
571	unsigned long flags;
572	if (USE_PORTS(priv)) {
573		local_irq_save(flags);
574		*priv->dir = *priv->dir_shadow |=
575		  ((unsigned char)arg & priv->changeable_dir);
576		local_irq_restore(flags);
577		return *priv->dir_shadow;
578	} else if (priv->minor == GPIO_MINOR_G) {
579		/* We must fiddle with R_GEN_CONFIG to change dir */
580		local_irq_save(flags);
581		if (((arg & dir_g_out_bits) != arg) &&
582		    (arg & changeable_dir_g)) {
583			/* Set bits in genconfig to set to output */
584			if (arg & (1<<0)) {
585				genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g0dir);
586				dir_g_out_bits |= (1<<0);
587				dir_g_in_bits &= ~(1<<0);
588			}
589			if ((arg & 0x0000FF00) == 0x0000FF00) {
590				genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir);
591				dir_g_out_bits |= 0x0000FF00;
592				dir_g_in_bits &= ~0x0000FF00;
593			}
594			if ((arg & 0x00FF0000) == 0x00FF0000) {
595				genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir);
596				dir_g_out_bits |= 0x00FF0000;
597				dir_g_in_bits &= ~0x00FF0000;
598			}
599			if (arg & (1<<24)) {
600				genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g24dir);
601				dir_g_out_bits |= (1<<24);
602				dir_g_in_bits &= ~(1<<24);
603			}
604			D(printk(KERN_INFO "gpio: SETOUTPUT on port G set "
605				 "genconfig to 0x%08lX "
606				 "in_bits: 0x%08lX "
607				 "out_bits: 0x%08lX\n",
608			         (unsigned long)genconfig_shadow,
609			         dir_g_in_bits, dir_g_out_bits));
610			*R_GEN_CONFIG = genconfig_shadow;
611			/* Must be a >120 ns delay before writing this again */
612		}
613		local_irq_restore(flags);
614		return dir_g_out_bits & 0x7FFFFFFF;
615	}
616	return 0;
617} /* setget_output */
618
619static int
620gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
621
622static int
623gpio_ioctl(struct inode *inode, struct file *file,
624	   unsigned int cmd, unsigned long arg)
625{
626	unsigned long flags;
627	unsigned long val;
628        int ret = 0;
629
630	struct gpio_private *priv = (struct gpio_private *)file->private_data;
631	if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) {
632		return -EINVAL;
633	}
634
635	spin_lock(&gpio_lock);
636
637	switch (_IOC_NR(cmd)) {
638	case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
639		// read the port
640		if (USE_PORTS(priv)) {
641			ret =  *priv->port;
642		} else if (priv->minor == GPIO_MINOR_G) {
643			ret =  (*R_PORT_G_DATA) & 0x7FFFFFFF;
644		}
645		break;
646	case IO_SETBITS:
647		local_irq_save(flags);
648		// set changeable bits with a 1 in arg
649		if (USE_PORTS(priv)) {
650			*priv->port = *priv->shadow |=
651			  ((unsigned char)arg & priv->changeable_bits);
652		} else if (priv->minor == GPIO_MINOR_G) {
653			*R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits);
654		}
655		local_irq_restore(flags);
656		break;
657	case IO_CLRBITS:
658		local_irq_save(flags);
659		// clear changeable bits with a 1 in arg
660		if (USE_PORTS(priv)) {
661			*priv->port = *priv->shadow &=
662			 ~((unsigned char)arg & priv->changeable_bits);
663		} else if (priv->minor == GPIO_MINOR_G) {
664			*R_PORT_G_DATA = port_g_data_shadow &= ~((unsigned long)arg & dir_g_out_bits);
665		}
666		local_irq_restore(flags);
667		break;
668	case IO_HIGHALARM:
669		// set alarm when bits with 1 in arg go high
670		priv->highalarm |= arg;
671		gpio_some_alarms = 1;
672		break;
673	case IO_LOWALARM:
674		// set alarm when bits with 1 in arg go low
675		priv->lowalarm |= arg;
676		gpio_some_alarms = 1;
677		break;
678	case IO_CLRALARM:
679		// clear alarm for bits with 1 in arg
680		priv->highalarm &= ~arg;
681		priv->lowalarm  &= ~arg;
682		{
683			/* Must update gpio_some_alarms */
684			struct gpio_private *p = alarmlist;
685			int some_alarms;
686			some_alarms = 0;
687			while (p) {
688				if (p->highalarm | p->lowalarm) {
689					some_alarms = 1;
690					break;
691				}
692				p = p->next;
693			}
694			gpio_some_alarms = some_alarms;
695		}
696		break;
697	case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
698		/* Read direction 0=input 1=output */
699		if (USE_PORTS(priv)) {
700			ret = *priv->dir_shadow;
701		} else if (priv->minor == GPIO_MINOR_G) {
702			/* Note: Some bits are both in and out,
703			 * Those that are dual is set here as well.
704			 */
705			ret = (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
706		}
707		break;
708	case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
709		/* Set direction 0=unchanged 1=input,
710		 * return mask with 1=input
711		 */
712		ret = setget_input(priv, arg) & 0x7FFFFFFF;
713		break;
714	case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
715		/* Set direction 0=unchanged 1=output,
716		 * return mask with 1=output
717		 */
718		ret =  setget_output(priv, arg) & 0x7FFFFFFF;
719		break;
720	case IO_SHUTDOWN:
721		SOFT_SHUTDOWN();
722		break;
723	case IO_GET_PWR_BT:
724#if defined(CONFIG_ETRAX_SOFT_SHUTDOWN)
725		ret = (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
726#else
727		ret = 0;
728#endif
729		break;
730	case IO_CFG_WRITE_MODE:
731		priv->clk_mask = arg & 0xFF;
732		priv->data_mask = (arg >> 8) & 0xFF;
733		priv->write_msb = (arg >> 16) & 0x01;
734		/* Check if we're allowed to change the bits and
735		 * the direction is correct
736		 */
737		if (!((priv->clk_mask & priv->changeable_bits) &&
738		      (priv->data_mask & priv->changeable_bits) &&
739		      (priv->clk_mask & *priv->dir_shadow) &&
740		      (priv->data_mask & *priv->dir_shadow)))
741		{
742			priv->clk_mask = 0;
743			priv->data_mask = 0;
744			ret = -EPERM;
745		}
746		break;
747	case IO_READ_INBITS:
748		/* *arg is result of reading the input pins */
749		if (USE_PORTS(priv)) {
750			val = *priv->port;
751		} else if (priv->minor == GPIO_MINOR_G) {
752			val = *R_PORT_G_DATA;
753		}
754		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
755			ret = -EFAULT;
756		break;
757	case IO_READ_OUTBITS:
758		 /* *arg is result of reading the output shadow */
759		if (USE_PORTS(priv)) {
760			val = *priv->shadow;
761		} else if (priv->minor == GPIO_MINOR_G) {
762			val = port_g_data_shadow;
763		}
764		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
765			ret = -EFAULT;
766		break;
767	case IO_SETGET_INPUT:
768		/* bits set in *arg is set to input,
769		 * *arg updated with current input pins.
770		 */
771		if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
772		{
773			ret = -EFAULT;
774			break;
775		}
776		val = setget_input(priv, val);
777		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
778			ret = -EFAULT;
779		break;
780	case IO_SETGET_OUTPUT:
781		/* bits set in *arg is set to output,
782		 * *arg updated with current output pins.
783		 */
784		if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
785		{
786			ret = -EFAULT;
787			break;
788		}
789		val = setget_output(priv, val);
790		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
791			ret = -EFAULT;
792		break;
793	default:
794		if (priv->minor == GPIO_MINOR_LEDS)
795			ret = gpio_leds_ioctl(cmd, arg);
796		else
797			ret = -EINVAL;
798	} /* switch */
799
800	spin_unlock(&gpio_lock);
801	return ret;
802}
803
804static int
805gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
806{
807	unsigned char green;
808	unsigned char red;
809
810	switch (_IOC_NR(cmd)) {
811	case IO_LEDACTIVE_SET:
812		green = ((unsigned char) arg) & 1;
813		red   = (((unsigned char) arg) >> 1) & 1;
814		LED_ACTIVE_SET_G(green);
815		LED_ACTIVE_SET_R(red);
816		break;
817
818	case IO_LED_SETBIT:
819		LED_BIT_SET(arg);
820		break;
821
822	case IO_LED_CLRBIT:
823		LED_BIT_CLR(arg);
824		break;
825
826	default:
827		return -EINVAL;
828	} /* switch */
829
830	return 0;
831}
832
833const struct file_operations gpio_fops = {
834	.owner       = THIS_MODULE,
835	.poll        = gpio_poll,
836	.ioctl       = gpio_ioctl,
837	.write       = gpio_write,
838	.open        = gpio_open,
839	.release     = gpio_release,
840};
841
842
843void ioif_watcher(const unsigned int gpio_in_available,
844		  const unsigned int gpio_out_available,
845		  const unsigned char pa_available,
846		  const unsigned char pb_available)
847{
848	unsigned long int flags;
849	D(printk("gpio.c: ioif_watcher called\n"));
850	D(printk("gpio.c: G in: 0x%08x G out: 0x%08x PA: 0x%02x PB: 0x%02x\n",
851		 gpio_in_available, gpio_out_available, pa_available, pb_available));
852
853	spin_lock_irqsave(&gpio_lock, flags);
854
855	dir_g_in_bits = gpio_in_available;
856	dir_g_out_bits = gpio_out_available;
857
858	/* Initialise the dir_g_shadow etc. depending on genconfig */
859	/* 0=input 1=output */
860	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g0dir, out))
861		dir_g_shadow |= (1 << 0);
862	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g8_15dir, out))
863		dir_g_shadow |= 0x0000FF00;
864	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g16_23dir, out))
865		dir_g_shadow |= 0x00FF0000;
866	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g24dir, out))
867		dir_g_shadow |= (1 << 24);
868
869	changeable_dir_g = changeable_dir_g_mask;
870	changeable_dir_g &= dir_g_out_bits;
871	changeable_dir_g &= dir_g_in_bits;
872	/* Correct the bits that can change direction */
873	dir_g_out_bits &= ~changeable_dir_g;
874	dir_g_out_bits |= dir_g_shadow;
875	dir_g_in_bits &= ~changeable_dir_g;
876	dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g);
877
878	spin_unlock_irqrestore(&gpio_lock, flags);
879
880	printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n",
881	       dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA);
882	printk(KERN_INFO "GPIO port G: dir: %08lX changeable: %08lX\n",
883	       dir_g_shadow, changeable_dir_g);
884}
885
886/* main driver initialization routine, called from mem.c */
887
888static __init int
889gpio_init(void)
890{
891	int res;
892#if defined(CONFIG_ETRAX_CSP0_LEDS)
893	int i;
894#endif
895        printk("gpio init\n");
896
897	/* do the formalities */
898
899	res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
900	if (res < 0) {
901		printk(KERN_ERR "gpio: couldn't get a major number.\n");
902		return res;
903	}
904
905	/* Clear all leds */
906#if defined(CONFIG_ETRAX_CSP0_LEDS) ||  defined(CONFIG_ETRAX_PA_LEDS) || \
907	defined(CONFIG_ETRAX_PB_LEDS)
908	LED_NETWORK_SET(0);
909	LED_ACTIVE_SET(0);
910	LED_DISK_READ(0);
911	LED_DISK_WRITE(0);
912
913#if defined(CONFIG_ETRAX_CSP0_LEDS)
914	for (i = 0; i < 32; i++) {
915		LED_BIT_SET(i);
916	}
917#endif
918
919#endif
920	/* The I/O interface allocation watcher will be called when
921	 * registering it. */
922	if (cris_io_interface_register_watcher(ioif_watcher)){
923		printk(KERN_WARNING "gpio_init: Failed to install IO if allocator watcher\n");
924	}
925
926	printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002, 2003, 2004 Axis Communications AB\n");
927	/* We call etrax_gpio_wake_up_check() from timer interrupt and
928	 * from cpu_idle() in kernel/process.c
929	 * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
930	 * in some tests.
931	 */
932	if (request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
933			IRQF_SHARED | IRQF_DISABLED,"gpio poll", NULL)) {
934		printk(KERN_CRIT "err: timer0 irq for gpio\n");
935	}
936	if (request_irq(PA_IRQ_NBR, gpio_pa_interrupt,
937			IRQF_SHARED | IRQF_DISABLED,"gpio PA", NULL)) {
938		printk(KERN_CRIT "err: PA irq for gpio\n");
939	}
940
941
942	return res;
943}
944
945/* this makes sure that gpio_init is called during kernel boot */
946
947module_init(gpio_init);
948