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