cris: update comments for generic idle conversion
[deliverable/linux.git] / arch / cris / arch-v10 / drivers / gpio.c
CommitLineData
45a4127c 1/*
1da177e4
LT
2 * Etrax general port I/O device
3 *
45a4127c 4 * Copyright (c) 1999-2007 Axis Communications AB
1da177e4
LT
5 *
6 * Authors: Bjorn Wesen (initial version)
7 * Ola Knutsson (LED handling)
8 * Johan Adolfsson (read/set directions, write, port G)
1da177e4
LT
9 */
10
1da177e4
LT
11
12#include <linux/module.h>
13#include <linux/sched.h>
14#include <linux/slab.h>
15#include <linux/ioport.h>
16#include <linux/errno.h>
17#include <linux/kernel.h>
18#include <linux/fs.h>
19#include <linux/string.h>
20#include <linux/poll.h>
21#include <linux/init.h>
22#include <linux/interrupt.h>
23
24#include <asm/etraxgpio.h>
556dcee7 25#include <arch/svinto.h>
1da177e4 26#include <asm/io.h>
1da177e4 27#include <asm/irq.h>
556dcee7 28#include <arch/io_interface_mux.h>
1da177e4
LT
29
30#define GPIO_MAJOR 120 /* experimental MAJOR number */
31
32#define D(x)
33
34#if 0
35static int dp_cnt;
36#define DP(x) do { dp_cnt++; if (dp_cnt % 1000 == 0) x; }while(0)
37#else
38#define DP(x)
39#endif
45a4127c 40
1da177e4
LT
41static char gpio_name[] = "etrax gpio";
42
43#if 0
44static wait_queue_head_t *gpio_wq;
45#endif
46
60362158 47static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
ad433f23
JN
48static ssize_t gpio_write(struct file *file, const char __user *buf,
49 size_t count, loff_t *off);
1da177e4
LT
50static int gpio_open(struct inode *inode, struct file *filp);
51static int gpio_release(struct inode *inode, struct file *filp);
52static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait);
53
54/* private data per open() of this driver */
55
56struct gpio_private {
57 struct gpio_private *next;
58 /* These fields are for PA and PB only */
59 volatile unsigned char *port, *shadow;
60 volatile unsigned char *dir, *dir_shadow;
61 unsigned char changeable_dir;
62 unsigned char changeable_bits;
63 unsigned char clk_mask;
64 unsigned char data_mask;
65 unsigned char write_msb;
66 unsigned char pad1, pad2, pad3;
67 /* These fields are generic */
68 unsigned long highalarm, lowalarm;
69 wait_queue_head_t alarm_wq;
70 int minor;
71};
72
73/* linked list of alarms to check for */
74
ad433f23 75static struct gpio_private *alarmlist;
1da177e4 76
ad433f23
JN
77static int gpio_some_alarms; /* Set if someone uses alarm */
78static unsigned long gpio_pa_irq_enabled_mask;
1da177e4 79
7e920426
MS
80static DEFINE_SPINLOCK(gpio_lock); /* Protect directions etc */
81
1da177e4
LT
82/* Port A and B use 8 bit access, but Port G is 32 bit */
83#define NUM_PORTS (GPIO_MINOR_B+1)
84
45a4127c
JN
85static volatile unsigned char *ports[NUM_PORTS] = {
86 R_PORT_PA_DATA,
1da177e4
LT
87 R_PORT_PB_DATA,
88};
89static volatile unsigned char *shads[NUM_PORTS] = {
45a4127c 90 &port_pa_data_shadow,
1da177e4
LT
91 &port_pb_data_shadow
92};
93
94/* What direction bits that are user changeable 1=changeable*/
95#ifndef CONFIG_ETRAX_PA_CHANGEABLE_DIR
96#define CONFIG_ETRAX_PA_CHANGEABLE_DIR 0x00
97#endif
98#ifndef CONFIG_ETRAX_PB_CHANGEABLE_DIR
99#define CONFIG_ETRAX_PB_CHANGEABLE_DIR 0x00
100#endif
101
102#ifndef CONFIG_ETRAX_PA_CHANGEABLE_BITS
103#define CONFIG_ETRAX_PA_CHANGEABLE_BITS 0xFF
104#endif
105#ifndef CONFIG_ETRAX_PB_CHANGEABLE_BITS
106#define CONFIG_ETRAX_PB_CHANGEABLE_BITS 0xFF
107#endif
108
109
45a4127c 110static unsigned char changeable_dir[NUM_PORTS] = {
1da177e4 111 CONFIG_ETRAX_PA_CHANGEABLE_DIR,
45a4127c 112 CONFIG_ETRAX_PB_CHANGEABLE_DIR
1da177e4 113};
45a4127c 114static unsigned char changeable_bits[NUM_PORTS] = {
1da177e4 115 CONFIG_ETRAX_PA_CHANGEABLE_BITS,
45a4127c 116 CONFIG_ETRAX_PB_CHANGEABLE_BITS
1da177e4
LT
117};
118
45a4127c
JN
119static volatile unsigned char *dir[NUM_PORTS] = {
120 R_PORT_PA_DIR,
121 R_PORT_PB_DIR
1da177e4
LT
122};
123
124static volatile unsigned char *dir_shadow[NUM_PORTS] = {
45a4127c
JN
125 &port_pa_dir_shadow,
126 &port_pb_dir_shadow
1da177e4
LT
127};
128
7e920426
MS
129/* All bits in port g that can change dir. */
130static const unsigned long int changeable_dir_g_mask = 0x01FFFF01;
131
45a4127c 132/* Port G is 32 bit, handle it special, some bits are both inputs
1da177e4
LT
133 and outputs at the same time, only some of the bits can change direction
134 and some of them in groups of 8 bit. */
135static unsigned long changeable_dir_g;
136static unsigned long dir_g_in_bits;
137static unsigned long dir_g_out_bits;
138static unsigned long dir_g_shadow; /* 1=output */
139
140#define USE_PORTS(priv) ((priv)->minor <= GPIO_MINOR_B)
141
142
45a4127c 143static unsigned int gpio_poll(struct file *file, poll_table *wait)
1da177e4
LT
144{
145 unsigned int mask = 0;
ad433f23 146 struct gpio_private *priv = file->private_data;
1da177e4 147 unsigned long data;
45a4127c
JN
148 unsigned long flags;
149
150 spin_lock_irqsave(&gpio_lock, flags);
151
1da177e4
LT
152 poll_wait(file, &priv->alarm_wq, wait);
153 if (priv->minor == GPIO_MINOR_A) {
1da177e4
LT
154 unsigned long tmp;
155 data = *R_PORT_PA_DATA;
156 /* PA has support for high level interrupt -
157 * lets activate for those low and with highalarm set
158 */
159 tmp = ~data & priv->highalarm & 0xFF;
160 tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
45a4127c 161
1da177e4
LT
162 gpio_pa_irq_enabled_mask |= tmp;
163 *R_IRQ_MASK1_SET = tmp;
1da177e4
LT
164 } else if (priv->minor == GPIO_MINOR_B)
165 data = *R_PORT_PB_DATA;
166 else if (priv->minor == GPIO_MINOR_G)
167 data = *R_PORT_G_DATA;
5c6ff79d 168 else {
45a4127c
JN
169 mask = 0;
170 goto out;
5c6ff79d 171 }
45a4127c 172
1da177e4
LT
173 if ((data & priv->highalarm) ||
174 (~data & priv->lowalarm)) {
175 mask = POLLIN|POLLRDNORM;
176 }
7e920426 177
45a4127c
JN
178out:
179 spin_unlock_irqrestore(&gpio_lock, flags);
1da177e4 180 DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
7e920426 181
1da177e4
LT
182 return mask;
183}
184
185int etrax_gpio_wake_up_check(void)
186{
45a4127c 187 struct gpio_private *priv;
1da177e4
LT
188 unsigned long data = 0;
189 int ret = 0;
45a4127c
JN
190 unsigned long flags;
191
192 spin_lock_irqsave(&gpio_lock, flags);
193 priv = alarmlist;
1da177e4 194 while (priv) {
45a4127c 195 if (USE_PORTS(priv))
1da177e4 196 data = *priv->port;
45a4127c 197 else if (priv->minor == GPIO_MINOR_G)
1da177e4 198 data = *R_PORT_G_DATA;
45a4127c 199
1da177e4
LT
200 if ((data & priv->highalarm) ||
201 (~data & priv->lowalarm)) {
202 DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor));
203 wake_up_interruptible(&priv->alarm_wq);
204 ret = 1;
205 }
206 priv = priv->next;
207 }
45a4127c 208 spin_unlock_irqrestore(&gpio_lock, flags);
1da177e4
LT
209 return ret;
210}
211
212static irqreturn_t
45a4127c 213gpio_poll_timer_interrupt(int irq, void *dev_id)
1da177e4
LT
214{
215 if (gpio_some_alarms) {
216 etrax_gpio_wake_up_check();
217 return IRQ_HANDLED;
218 }
219 return IRQ_NONE;
220}
221
222static irqreturn_t
ad433f23 223gpio_interrupt(int irq, void *dev_id)
1da177e4
LT
224{
225 unsigned long tmp;
45a4127c
JN
226 unsigned long flags;
227
228 spin_lock_irqsave(&gpio_lock, flags);
229
1da177e4
LT
230 /* Find what PA interrupts are active */
231 tmp = (*R_IRQ_READ1);
232
233 /* Find those that we have enabled */
234 tmp &= gpio_pa_irq_enabled_mask;
235
236 /* Clear them.. */
237 *R_IRQ_MASK1_CLR = tmp;
238 gpio_pa_irq_enabled_mask &= ~tmp;
239
45a4127c 240 spin_unlock_irqrestore(&gpio_lock, flags);
7e920426 241
45a4127c 242 if (gpio_some_alarms)
1da177e4 243 return IRQ_RETVAL(etrax_gpio_wake_up_check());
45a4127c 244
1da177e4
LT
245 return IRQ_NONE;
246}
247
45a4127c
JN
248static void gpio_write_bit(struct gpio_private *priv,
249 unsigned char data, int bit)
250{
251 *priv->port = *priv->shadow &= ~(priv->clk_mask);
252 if (data & 1 << bit)
253 *priv->port = *priv->shadow |= priv->data_mask;
254 else
255 *priv->port = *priv->shadow &= ~(priv->data_mask);
256
257 /* For FPGA: min 5.0ns (DCC) before CCLK high */
258 *priv->port = *priv->shadow |= priv->clk_mask;
259}
260
261static void gpio_write_byte(struct gpio_private *priv, unsigned char data)
262{
263 int i;
264
265 if (priv->write_msb)
266 for (i = 7; i >= 0; i--)
267 gpio_write_bit(priv, data, i);
268 else
269 for (i = 0; i <= 7; i++)
270 gpio_write_bit(priv, data, i);
271}
1da177e4 272
ad433f23
JN
273static ssize_t gpio_write(struct file *file, const char __user *buf,
274 size_t count, loff_t *off)
1da177e4 275{
ad433f23 276 struct gpio_private *priv = file->private_data;
1da177e4 277 unsigned long flags;
45a4127c 278 ssize_t retval = count;
7e920426 279
45a4127c
JN
280 if (priv->minor != GPIO_MINOR_A && priv->minor != GPIO_MINOR_B)
281 return -EFAULT;
282
283 if (!access_ok(VERIFY_READ, buf, count))
284 return -EFAULT;
285
286 spin_lock_irqsave(&gpio_lock, flags);
7e920426 287
1da177e4
LT
288 /* It must have been configured using the IO_CFG_WRITE_MODE */
289 /* Perhaps a better error code? */
45a4127c 290 if (priv->clk_mask == 0 || priv->data_mask == 0) {
5c6ff79d
RK
291 retval = -EPERM;
292 goto out;
1da177e4 293 }
45a4127c
JN
294
295 D(printk(KERN_DEBUG "gpio_write: %02X to data 0x%02X "
296 "clk 0x%02X msb: %i\n",
297 count, priv->data_mask, priv->clk_mask, priv->write_msb));
298
299 while (count--)
300 gpio_write_byte(priv, *buf++);
301
5c6ff79d 302out:
45a4127c 303 spin_unlock_irqrestore(&gpio_lock, flags);
1da177e4
LT
304 return retval;
305}
306
307
308
309static int
310gpio_open(struct inode *inode, struct file *filp)
311{
312 struct gpio_private *priv;
32ea086b 313 int p = iminor(inode);
45a4127c 314 unsigned long flags;
1da177e4
LT
315
316 if (p > GPIO_MINOR_LAST)
317 return -EINVAL;
318
ad433f23 319 priv = kzalloc(sizeof(struct gpio_private), GFP_KERNEL);
1da177e4
LT
320
321 if (!priv)
322 return -ENOMEM;
323
324 priv->minor = p;
325
45a4127c 326 /* initialize the io/alarm struct */
1da177e4 327
1da177e4
LT
328 if (USE_PORTS(priv)) { /* A and B */
329 priv->port = ports[p];
330 priv->shadow = shads[p];
331 priv->dir = dir[p];
332 priv->dir_shadow = dir_shadow[p];
333 priv->changeable_dir = changeable_dir[p];
334 priv->changeable_bits = changeable_bits[p];
335 } else {
336 priv->port = NULL;
337 priv->shadow = NULL;
338 priv->dir = NULL;
339 priv->dir_shadow = NULL;
340 priv->changeable_dir = 0;
341 priv->changeable_bits = 0;
342 }
343
344 priv->highalarm = 0;
345 priv->lowalarm = 0;
346 priv->clk_mask = 0;
347 priv->data_mask = 0;
348 init_waitqueue_head(&priv->alarm_wq);
349
ad433f23 350 filp->private_data = priv;
1da177e4 351
45a4127c
JN
352 /* link it into our alarmlist */
353 spin_lock_irqsave(&gpio_lock, flags);
354 priv->next = alarmlist;
355 alarmlist = priv;
356 spin_unlock_irqrestore(&gpio_lock, flags);
357
1da177e4
LT
358 return 0;
359}
360
361static int
362gpio_release(struct inode *inode, struct file *filp)
363{
7e920426
MS
364 struct gpio_private *p;
365 struct gpio_private *todel;
45a4127c 366 unsigned long flags;
7e920426 367
45a4127c 368 spin_lock_irqsave(&gpio_lock, flags);
7e920426 369
45a4127c 370 p = alarmlist;
ad433f23 371 todel = filp->private_data;
7e920426 372
1da177e4
LT
373 /* unlink from alarmlist and free the private structure */
374
375 if (p == todel) {
376 alarmlist = todel->next;
377 } else {
378 while (p->next != todel)
379 p = p->next;
380 p->next = todel->next;
381 }
382
383 kfree(todel);
384 /* Check if there are still any alarms set */
385 p = alarmlist;
386 while (p) {
387 if (p->highalarm | p->lowalarm) {
388 gpio_some_alarms = 1;
45a4127c 389 goto out;
1da177e4
LT
390 }
391 p = p->next;
392 }
393 gpio_some_alarms = 0;
45a4127c
JN
394out:
395 spin_unlock_irqrestore(&gpio_lock, flags);
1da177e4
LT
396 return 0;
397}
398
45a4127c 399/* Main device API. ioctl's to read/set/clear bits, as well as to
1da177e4
LT
400 * set alarms to wait for using a subsequent select().
401 */
1da177e4
LT
402unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
403{
45a4127c
JN
404 /* Set direction 0=unchanged 1=input,
405 * return mask with 1=input */
1da177e4 406 if (USE_PORTS(priv)) {
45a4127c 407 *priv->dir = *priv->dir_shadow &=
1da177e4 408 ~((unsigned char)arg & priv->changeable_dir);
1da177e4 409 return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */
45a4127c
JN
410 }
411
412 if (priv->minor != GPIO_MINOR_G)
413 return 0;
414
415 /* We must fiddle with R_GEN_CONFIG to change dir */
416 if (((arg & dir_g_in_bits) != arg) &&
417 (arg & changeable_dir_g)) {
418 arg &= changeable_dir_g;
419 /* Clear bits in genconfig to set to input */
420 if (arg & (1<<0)) {
421 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g0dir);
422 dir_g_in_bits |= (1<<0);
423 dir_g_out_bits &= ~(1<<0);
424 }
425 if ((arg & 0x0000FF00) == 0x0000FF00) {
426 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g8_15dir);
427 dir_g_in_bits |= 0x0000FF00;
428 dir_g_out_bits &= ~0x0000FF00;
429 }
430 if ((arg & 0x00FF0000) == 0x00FF0000) {
431 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g16_23dir);
432 dir_g_in_bits |= 0x00FF0000;
433 dir_g_out_bits &= ~0x00FF0000;
434 }
435 if (arg & (1<<24)) {
436 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g24dir);
437 dir_g_in_bits |= (1<<24);
438 dir_g_out_bits &= ~(1<<24);
1da177e4 439 }
45a4127c
JN
440 D(printk(KERN_DEBUG "gpio: SETINPUT on port G set "
441 "genconfig to 0x%08lX "
442 "in_bits: 0x%08lX "
443 "out_bits: 0x%08lX\n",
444 (unsigned long)genconfig_shadow,
445 dir_g_in_bits, dir_g_out_bits));
446 *R_GEN_CONFIG = genconfig_shadow;
447 /* Must be a >120 ns delay before writing this again */
448
1da177e4 449 }
45a4127c 450 return dir_g_in_bits;
1da177e4
LT
451} /* setget_input */
452
453unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
454{
1da177e4 455 if (USE_PORTS(priv)) {
45a4127c
JN
456 *priv->dir = *priv->dir_shadow |=
457 ((unsigned char)arg & priv->changeable_dir);
1da177e4 458 return *priv->dir_shadow;
45a4127c
JN
459 }
460 if (priv->minor != GPIO_MINOR_G)
461 return 0;
462
463 /* We must fiddle with R_GEN_CONFIG to change dir */
464 if (((arg & dir_g_out_bits) != arg) &&
465 (arg & changeable_dir_g)) {
466 /* Set bits in genconfig to set to output */
467 if (arg & (1<<0)) {
468 genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g0dir);
469 dir_g_out_bits |= (1<<0);
470 dir_g_in_bits &= ~(1<<0);
471 }
472 if ((arg & 0x0000FF00) == 0x0000FF00) {
473 genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g8_15dir);
474 dir_g_out_bits |= 0x0000FF00;
475 dir_g_in_bits &= ~0x0000FF00;
476 }
477 if ((arg & 0x00FF0000) == 0x00FF0000) {
478 genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g16_23dir);
479 dir_g_out_bits |= 0x00FF0000;
480 dir_g_in_bits &= ~0x00FF0000;
1da177e4 481 }
45a4127c
JN
482 if (arg & (1<<24)) {
483 genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g24dir);
484 dir_g_out_bits |= (1<<24);
485 dir_g_in_bits &= ~(1<<24);
486 }
487 D(printk(KERN_INFO "gpio: SETOUTPUT on port G set "
488 "genconfig to 0x%08lX "
489 "in_bits: 0x%08lX "
490 "out_bits: 0x%08lX\n",
491 (unsigned long)genconfig_shadow,
492 dir_g_in_bits, dir_g_out_bits));
493 *R_GEN_CONFIG = genconfig_shadow;
494 /* Must be a >120 ns delay before writing this again */
1da177e4 495 }
45a4127c 496 return dir_g_out_bits & 0x7FFFFFFF;
1da177e4
LT
497} /* setget_output */
498
499static int
500gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
501
60362158 502static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1da177e4
LT
503{
504 unsigned long flags;
505 unsigned long val;
7e920426
MS
506 int ret = 0;
507
ad433f23 508 struct gpio_private *priv = file->private_data;
45a4127c 509 if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE)
1da177e4 510 return -EINVAL;
1da177e4
LT
511
512 switch (_IOC_NR(cmd)) {
513 case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
514 // read the port
60362158 515 spin_lock_irqsave(&gpio_lock, flags);
1da177e4 516 if (USE_PORTS(priv)) {
7e920426 517 ret = *priv->port;
1da177e4 518 } else if (priv->minor == GPIO_MINOR_G) {
7e920426 519 ret = (*R_PORT_G_DATA) & 0x7FFFFFFF;
1da177e4 520 }
60362158
JN
521 spin_unlock_irqrestore(&gpio_lock, flags);
522
1da177e4
LT
523 break;
524 case IO_SETBITS:
1da177e4 525 // set changeable bits with a 1 in arg
60362158
JN
526 spin_lock_irqsave(&gpio_lock, flags);
527
1da177e4 528 if (USE_PORTS(priv)) {
60362158 529 *priv->port = *priv->shadow |=
1da177e4
LT
530 ((unsigned char)arg & priv->changeable_bits);
531 } else if (priv->minor == GPIO_MINOR_G) {
532 *R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits);
533 }
60362158
JN
534 spin_unlock_irqrestore(&gpio_lock, flags);
535
1da177e4
LT
536 break;
537 case IO_CLRBITS:
1da177e4 538 // clear changeable bits with a 1 in arg
60362158 539 spin_lock_irqsave(&gpio_lock, flags);
1da177e4 540 if (USE_PORTS(priv)) {
60362158 541 *priv->port = *priv->shadow &=
1da177e4
LT
542 ~((unsigned char)arg & priv->changeable_bits);
543 } else if (priv->minor == GPIO_MINOR_G) {
544 *R_PORT_G_DATA = port_g_data_shadow &= ~((unsigned long)arg & dir_g_out_bits);
545 }
60362158 546 spin_unlock_irqrestore(&gpio_lock, flags);
1da177e4
LT
547 break;
548 case IO_HIGHALARM:
549 // set alarm when bits with 1 in arg go high
60362158 550 spin_lock_irqsave(&gpio_lock, flags);
1da177e4
LT
551 priv->highalarm |= arg;
552 gpio_some_alarms = 1;
60362158 553 spin_unlock_irqrestore(&gpio_lock, flags);
1da177e4
LT
554 break;
555 case IO_LOWALARM:
556 // set alarm when bits with 1 in arg go low
60362158 557 spin_lock_irqsave(&gpio_lock, flags);
1da177e4
LT
558 priv->lowalarm |= arg;
559 gpio_some_alarms = 1;
60362158 560 spin_unlock_irqrestore(&gpio_lock, flags);
1da177e4
LT
561 break;
562 case IO_CLRALARM:
60362158
JN
563 /* clear alarm for bits with 1 in arg */
564 spin_lock_irqsave(&gpio_lock, flags);
1da177e4
LT
565 priv->highalarm &= ~arg;
566 priv->lowalarm &= ~arg;
567 {
568 /* Must update gpio_some_alarms */
569 struct gpio_private *p = alarmlist;
570 int some_alarms;
45a4127c 571 p = alarmlist;
1da177e4
LT
572 some_alarms = 0;
573 while (p) {
574 if (p->highalarm | p->lowalarm) {
575 some_alarms = 1;
576 break;
577 }
578 p = p->next;
579 }
580 gpio_some_alarms = some_alarms;
581 }
60362158 582 spin_unlock_irqrestore(&gpio_lock, flags);
1da177e4
LT
583 break;
584 case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
585 /* Read direction 0=input 1=output */
60362158 586 spin_lock_irqsave(&gpio_lock, flags);
1da177e4 587 if (USE_PORTS(priv)) {
7e920426 588 ret = *priv->dir_shadow;
1da177e4
LT
589 } else if (priv->minor == GPIO_MINOR_G) {
590 /* Note: Some bits are both in and out,
591 * Those that are dual is set here as well.
592 */
7e920426 593 ret = (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
1da177e4 594 }
60362158 595 spin_unlock_irqrestore(&gpio_lock, flags);
7e920426 596 break;
1da177e4 597 case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
60362158
JN
598 /* Set direction 0=unchanged 1=input,
599 * return mask with 1=input
1da177e4 600 */
60362158 601 spin_lock_irqsave(&gpio_lock, flags);
7e920426 602 ret = setget_input(priv, arg) & 0x7FFFFFFF;
60362158 603 spin_unlock_irqrestore(&gpio_lock, flags);
1da177e4
LT
604 break;
605 case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
60362158
JN
606 /* Set direction 0=unchanged 1=output,
607 * return mask with 1=output
1da177e4 608 */
60362158 609 spin_lock_irqsave(&gpio_lock, flags);
7e920426 610 ret = setget_output(priv, arg) & 0x7FFFFFFF;
60362158 611 spin_unlock_irqrestore(&gpio_lock, flags);
7e920426 612 break;
1da177e4 613 case IO_SHUTDOWN:
60362158 614 spin_lock_irqsave(&gpio_lock, flags);
1da177e4 615 SOFT_SHUTDOWN();
60362158 616 spin_unlock_irqrestore(&gpio_lock, flags);
1da177e4
LT
617 break;
618 case IO_GET_PWR_BT:
60362158 619 spin_lock_irqsave(&gpio_lock, flags);
1da177e4 620#if defined (CONFIG_ETRAX_SOFT_SHUTDOWN)
7e920426 621 ret = (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
1da177e4 622#else
7e920426 623 ret = 0;
1da177e4 624#endif
60362158 625 spin_unlock_irqrestore(&gpio_lock, flags);
1da177e4
LT
626 break;
627 case IO_CFG_WRITE_MODE:
60362158 628 spin_lock_irqsave(&gpio_lock, flags);
1da177e4
LT
629 priv->clk_mask = arg & 0xFF;
630 priv->data_mask = (arg >> 8) & 0xFF;
631 priv->write_msb = (arg >> 16) & 0x01;
632 /* Check if we're allowed to change the bits and
633 * the direction is correct
634 */
635 if (!((priv->clk_mask & priv->changeable_bits) &&
636 (priv->data_mask & priv->changeable_bits) &&
637 (priv->clk_mask & *priv->dir_shadow) &&
638 (priv->data_mask & *priv->dir_shadow)))
639 {
640 priv->clk_mask = 0;
641 priv->data_mask = 0;
7e920426 642 ret = -EPERM;
1da177e4 643 }
60362158 644 spin_unlock_irqrestore(&gpio_lock, flags);
1da177e4 645 break;
60362158 646 case IO_READ_INBITS:
1da177e4 647 /* *arg is result of reading the input pins */
60362158 648 spin_lock_irqsave(&gpio_lock, flags);
1da177e4
LT
649 if (USE_PORTS(priv)) {
650 val = *priv->port;
651 } else if (priv->minor == GPIO_MINOR_G) {
652 val = *R_PORT_G_DATA;
653 }
60362158 654 spin_unlock_irqrestore(&gpio_lock, flags);
ad433f23 655 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
7e920426 656 ret = -EFAULT;
1da177e4
LT
657 break;
658 case IO_READ_OUTBITS:
659 /* *arg is result of reading the output shadow */
60362158 660 spin_lock_irqsave(&gpio_lock, flags);
1da177e4
LT
661 if (USE_PORTS(priv)) {
662 val = *priv->shadow;
663 } else if (priv->minor == GPIO_MINOR_G) {
664 val = port_g_data_shadow;
665 }
60362158 666 spin_unlock_irqrestore(&gpio_lock, flags);
ad433f23 667 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
7e920426 668 ret = -EFAULT;
1da177e4 669 break;
60362158 670 case IO_SETGET_INPUT:
1da177e4
LT
671 /* bits set in *arg is set to input,
672 * *arg updated with current input pins.
673 */
ad433f23 674 if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
7e920426
MS
675 {
676 ret = -EFAULT;
677 break;
678 }
60362158 679 spin_lock_irqsave(&gpio_lock, flags);
1da177e4 680 val = setget_input(priv, val);
60362158 681 spin_unlock_irqrestore(&gpio_lock, flags);
ad433f23 682 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
7e920426 683 ret = -EFAULT;
1da177e4
LT
684 break;
685 case IO_SETGET_OUTPUT:
686 /* bits set in *arg is set to output,
687 * *arg updated with current output pins.
688 */
ad433f23 689 if (copy_from_user(&val, (void __user *)arg, sizeof(val))) {
7e920426
MS
690 ret = -EFAULT;
691 break;
692 }
60362158 693 spin_lock_irqsave(&gpio_lock, flags);
1da177e4 694 val = setget_output(priv, val);
60362158 695 spin_unlock_irqrestore(&gpio_lock, flags);
ad433f23 696 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
7e920426 697 ret = -EFAULT;
1da177e4
LT
698 break;
699 default:
60362158 700 spin_lock_irqsave(&gpio_lock, flags);
1da177e4 701 if (priv->minor == GPIO_MINOR_LEDS)
7e920426 702 ret = gpio_leds_ioctl(cmd, arg);
1da177e4 703 else
7e920426 704 ret = -EINVAL;
60362158 705 spin_unlock_irqrestore(&gpio_lock, flags);
1da177e4 706 } /* switch */
7e920426 707
7e920426 708 return ret;
1da177e4
LT
709}
710
711static int
712gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
713{
714 unsigned char green;
715 unsigned char red;
716
717 switch (_IOC_NR(cmd)) {
718 case IO_LEDACTIVE_SET:
45a4127c
JN
719 green = ((unsigned char)arg) & 1;
720 red = (((unsigned char)arg) >> 1) & 1;
721 CRIS_LED_ACTIVE_SET_G(green);
722 CRIS_LED_ACTIVE_SET_R(red);
1da177e4
LT
723 break;
724
725 case IO_LED_SETBIT:
45a4127c 726 CRIS_LED_BIT_SET(arg);
1da177e4
LT
727 break;
728
729 case IO_LED_CLRBIT:
45a4127c 730 CRIS_LED_BIT_CLR(arg);
1da177e4
LT
731 break;
732
733 default:
734 return -EINVAL;
735 } /* switch */
736
737 return 0;
738}
739
ad433f23 740static const struct file_operations gpio_fops = {
90276a1a
JN
741 .owner = THIS_MODULE,
742 .poll = gpio_poll,
743 .unlocked_ioctl = gpio_ioctl,
744 .write = gpio_write,
745 .open = gpio_open,
746 .release = gpio_release,
6038f373 747 .llseek = noop_llseek,
1da177e4
LT
748};
749
ad433f23
JN
750static void ioif_watcher(const unsigned int gpio_in_available,
751 const unsigned int gpio_out_available,
752 const unsigned char pa_available,
753 const unsigned char pb_available)
1da177e4 754{
7e920426 755 unsigned long int flags;
45a4127c
JN
756
757 D(printk(KERN_DEBUG "gpio.c: ioif_watcher called\n"));
758 D(printk(KERN_DEBUG "gpio.c: G in: 0x%08x G out: 0x%08x "
759 "PA: 0x%02x PB: 0x%02x\n",
760 gpio_in_available, gpio_out_available,
761 pa_available, pb_available));
1da177e4 762
7e920426 763 spin_lock_irqsave(&gpio_lock, flags);
1da177e4 764
7e920426
MS
765 dir_g_in_bits = gpio_in_available;
766 dir_g_out_bits = gpio_out_available;
1da177e4
LT
767
768 /* Initialise the dir_g_shadow etc. depending on genconfig */
769 /* 0=input 1=output */
45a4127c 770 if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g0dir, out))
1da177e4
LT
771 dir_g_shadow |= (1 << 0);
772 if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g8_15dir, out))
773 dir_g_shadow |= 0x0000FF00;
774 if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g16_23dir, out))
775 dir_g_shadow |= 0x00FF0000;
776 if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g24dir, out))
777 dir_g_shadow |= (1 << 24);
778
7e920426 779 changeable_dir_g = changeable_dir_g_mask;
1da177e4
LT
780 changeable_dir_g &= dir_g_out_bits;
781 changeable_dir_g &= dir_g_in_bits;
45a4127c
JN
782
783 /* Correct the bits that can change direction */
1da177e4
LT
784 dir_g_out_bits &= ~changeable_dir_g;
785 dir_g_out_bits |= dir_g_shadow;
786 dir_g_in_bits &= ~changeable_dir_g;
787 dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g);
788
7e920426 789 spin_unlock_irqrestore(&gpio_lock, flags);
1da177e4 790
45a4127c
JN
791 printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX "
792 "val: %08lX\n",
1da177e4
LT
793 dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA);
794 printk(KERN_INFO "GPIO port G: dir: %08lX changeable: %08lX\n",
795 dir_g_shadow, changeable_dir_g);
796}
797
798/* main driver initialization routine, called from mem.c */
799
ad433f23 800static int __init gpio_init(void)
1da177e4
LT
801{
802 int res;
803#if defined (CONFIG_ETRAX_CSP0_LEDS)
804 int i;
805#endif
1da177e4
LT
806
807 res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
808 if (res < 0) {
809 printk(KERN_ERR "gpio: couldn't get a major number.\n");
810 return res;
811 }
812
813 /* Clear all leds */
814#if defined (CONFIG_ETRAX_CSP0_LEDS) || defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS)
45a4127c
JN
815 CRIS_LED_NETWORK_SET(0);
816 CRIS_LED_ACTIVE_SET(0);
817 CRIS_LED_DISK_READ(0);
818 CRIS_LED_DISK_WRITE(0);
1da177e4
LT
819
820#if defined (CONFIG_ETRAX_CSP0_LEDS)
45a4127c
JN
821 for (i = 0; i < 32; i++)
822 CRIS_LED_BIT_SET(i);
1da177e4
LT
823#endif
824
825#endif
7e920426
MS
826 /* The I/O interface allocation watcher will be called when
827 * registering it. */
828 if (cris_io_interface_register_watcher(ioif_watcher)){
45a4127c
JN
829 printk(KERN_WARNING "gpio_init: Failed to install IO "
830 "if allocator watcher\n");
7e920426
MS
831 }
832
45a4127c
JN
833 printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001-2008 "
834 "Axis Communications AB\n");
1da177e4 835 /* We call etrax_gpio_wake_up_check() from timer interrupt and
835eeeed
GU
836 * from default_idle() in kernel/process.c
837 * The check in default_idle() reduces latency from ~15 ms to ~6 ms
1da177e4 838 * in some tests.
45a4127c
JN
839 */
840 res = request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
64d8ad93 841 IRQF_SHARED, "gpio poll", gpio_name);
45a4127c 842 if (res) {
1da177e4 843 printk(KERN_CRIT "err: timer0 irq for gpio\n");
45a4127c 844 return res;
1da177e4 845 }
ad433f23 846 res = request_irq(PA_IRQ_NBR, gpio_interrupt,
64d8ad93 847 IRQF_SHARED, "gpio PA", gpio_name);
45a4127c 848 if (res)
1da177e4 849 printk(KERN_CRIT "err: PA irq for gpio\n");
1da177e4
LT
850
851 return res;
852}
853
854/* this makes sure that gpio_init is called during kernel boot */
1da177e4 855module_init(gpio_init);
ad433f23 856
This page took 1.003538 seconds and 5 git commands to generate.