00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <linux/module.h>
00014 #include <linux/sched.h>
00015 #include <linux/slab.h>
00016 #include <linux/ioport.h>
00017 #include <linux/errno.h>
00018 #include <linux/kernel.h>
00019 #include <linux/fs.h>
00020 #include <linux/string.h>
00021 #include <linux/poll.h>
00022 #include <linux/init.h>
00023 #include <linux/interrupt.h>
00024 #include <linux/spinlock.h>
00025
00026 #include <asm/etraxgpio.h>
00027 #include <asm/arch/hwregs/reg_map.h>
00028 #include <asm/arch/hwregs/reg_rdwr.h>
00029 #include <asm/arch/hwregs/gio_defs.h>
00030 #include <asm/arch/hwregs/intr_vect_defs.h>
00031 #include <asm/io.h>
00032 #include <asm/system.h>
00033 #include <asm/irq.h>
00034
00035 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00036 #include "i2c.h"
00037
00038 #define VIRT_I2C_ADDR 0x40
00039 #endif
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #define GPIO_MAJOR 120
00052
00053 #define D(x)
00054
00055 #if 0
00056 static int dp_cnt;
00057 #define DP(x) do { dp_cnt++; if (dp_cnt % 1000 == 0) x; }while(0)
00058 #else
00059 #define DP(x)
00060 #endif
00061
00062 static char gpio_name[] = "etrax gpio";
00063
00064 #if 0
00065 static wait_queue_head_t *gpio_wq;
00066 #endif
00067
00068 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00069 static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
00070 unsigned long arg);
00071 #endif
00072 static int gpio_ioctl(struct inode *inode, struct file *file,
00073 unsigned int cmd, unsigned long arg);
00074 static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
00075 loff_t *off);
00076 static int gpio_open(struct inode *inode, struct file *filp);
00077 static int gpio_release(struct inode *inode, struct file *filp);
00078 static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait);
00079
00080
00081
00082 struct gpio_private {
00083 struct gpio_private *next;
00084
00085 unsigned char clk_mask;
00086 unsigned char data_mask;
00087 unsigned char write_msb;
00088 unsigned char pad1;
00089
00090 unsigned long highalarm, lowalarm;
00091 wait_queue_head_t alarm_wq;
00092 int minor;
00093 };
00094
00095
00096
00097 static struct gpio_private *alarmlist = 0;
00098
00099 static int gpio_some_alarms = 0;
00100 static unsigned long gpio_pa_high_alarms = 0;
00101 static unsigned long gpio_pa_low_alarms = 0;
00102
00103 static DEFINE_SPINLOCK(alarm_lock);
00104
00105 #define NUM_PORTS (GPIO_MINOR_LAST+1)
00106 #define GIO_REG_RD_ADDR(reg) (volatile unsigned long*) (regi_gio + REG_RD_ADDR_gio_##reg )
00107 #define GIO_REG_WR_ADDR(reg) (volatile unsigned long*) (regi_gio + REG_RD_ADDR_gio_##reg )
00108 unsigned long led_dummy;
00109 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00110 static unsigned long virtual_dummy;
00111 static unsigned long virtual_rw_pv_oe = CONFIG_ETRAX_DEF_GIO_PV_OE;
00112 static unsigned short cached_virtual_gpio_read = 0;
00113 #endif
00114
00115 static volatile unsigned long *data_out[NUM_PORTS] = {
00116 GIO_REG_WR_ADDR(rw_pa_dout),
00117 GIO_REG_WR_ADDR(rw_pb_dout),
00118 &led_dummy,
00119 GIO_REG_WR_ADDR(rw_pc_dout),
00120 GIO_REG_WR_ADDR(rw_pd_dout),
00121 GIO_REG_WR_ADDR(rw_pe_dout),
00122 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00123 &virtual_dummy,
00124 #endif
00125 };
00126
00127 static volatile unsigned long *data_in[NUM_PORTS] = {
00128 GIO_REG_RD_ADDR(r_pa_din),
00129 GIO_REG_RD_ADDR(r_pb_din),
00130 &led_dummy,
00131 GIO_REG_RD_ADDR(r_pc_din),
00132 GIO_REG_RD_ADDR(r_pd_din),
00133 GIO_REG_RD_ADDR(r_pe_din),
00134 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00135 &virtual_dummy,
00136 #endif
00137 };
00138
00139 static unsigned long changeable_dir[NUM_PORTS] = {
00140 CONFIG_ETRAX_PA_CHANGEABLE_DIR,
00141 CONFIG_ETRAX_PB_CHANGEABLE_DIR,
00142 0,
00143 CONFIG_ETRAX_PC_CHANGEABLE_DIR,
00144 CONFIG_ETRAX_PD_CHANGEABLE_DIR,
00145 CONFIG_ETRAX_PE_CHANGEABLE_DIR,
00146 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00147 CONFIG_ETRAX_PV_CHANGEABLE_DIR,
00148 #endif
00149 };
00150
00151 static unsigned long changeable_bits[NUM_PORTS] = {
00152 CONFIG_ETRAX_PA_CHANGEABLE_BITS,
00153 CONFIG_ETRAX_PB_CHANGEABLE_BITS,
00154 0,
00155 CONFIG_ETRAX_PC_CHANGEABLE_BITS,
00156 CONFIG_ETRAX_PD_CHANGEABLE_BITS,
00157 CONFIG_ETRAX_PE_CHANGEABLE_BITS,
00158 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00159 CONFIG_ETRAX_PV_CHANGEABLE_BITS,
00160 #endif
00161 };
00162
00163 static volatile unsigned long *dir_oe[NUM_PORTS] = {
00164 GIO_REG_WR_ADDR(rw_pa_oe),
00165 GIO_REG_WR_ADDR(rw_pb_oe),
00166 &led_dummy,
00167 GIO_REG_WR_ADDR(rw_pc_oe),
00168 GIO_REG_WR_ADDR(rw_pd_oe),
00169 GIO_REG_WR_ADDR(rw_pe_oe),
00170 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00171 &virtual_rw_pv_oe,
00172 #endif
00173 };
00174
00175
00176
00177 static unsigned int
00178 gpio_poll(struct file *file,
00179 poll_table *wait)
00180 {
00181 unsigned int mask = 0;
00182 struct gpio_private *priv = (struct gpio_private *)file->private_data;
00183 unsigned long data;
00184 poll_wait(file, &priv->alarm_wq, wait);
00185 if (priv->minor == GPIO_MINOR_A) {
00186 reg_gio_rw_intr_cfg intr_cfg;
00187 unsigned long tmp;
00188 unsigned long flags;
00189
00190 local_irq_save(flags);
00191 data = REG_TYPE_CONV(unsigned long, reg_gio_r_pa_din, REG_RD(gio, regi_gio, r_pa_din));
00192
00193
00194
00195 intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg);
00196
00197 tmp = ~data & priv->highalarm & 0xFF;
00198 if (tmp & (1 << 0)) {
00199 intr_cfg.pa0 = regk_gio_hi;
00200 }
00201 if (tmp & (1 << 1)) {
00202 intr_cfg.pa1 = regk_gio_hi;
00203 }
00204 if (tmp & (1 << 2)) {
00205 intr_cfg.pa2 = regk_gio_hi;
00206 }
00207 if (tmp & (1 << 3)) {
00208 intr_cfg.pa3 = regk_gio_hi;
00209 }
00210 if (tmp & (1 << 4)) {
00211 intr_cfg.pa4 = regk_gio_hi;
00212 }
00213 if (tmp & (1 << 5)) {
00214 intr_cfg.pa5 = regk_gio_hi;
00215 }
00216 if (tmp & (1 << 6)) {
00217 intr_cfg.pa6 = regk_gio_hi;
00218 }
00219 if (tmp & (1 << 7)) {
00220 intr_cfg.pa7 = regk_gio_hi;
00221 }
00222
00223
00224
00225 tmp = data & priv->lowalarm & 0xFF;
00226 if (tmp & (1 << 0)) {
00227 intr_cfg.pa0 = regk_gio_lo;
00228 }
00229 if (tmp & (1 << 1)) {
00230 intr_cfg.pa1 = regk_gio_lo;
00231 }
00232 if (tmp & (1 << 2)) {
00233 intr_cfg.pa2 = regk_gio_lo;
00234 }
00235 if (tmp & (1 << 3)) {
00236 intr_cfg.pa3 = regk_gio_lo;
00237 }
00238 if (tmp & (1 << 4)) {
00239 intr_cfg.pa4 = regk_gio_lo;
00240 }
00241 if (tmp & (1 << 5)) {
00242 intr_cfg.pa5 = regk_gio_lo;
00243 }
00244 if (tmp & (1 << 6)) {
00245 intr_cfg.pa6 = regk_gio_lo;
00246 }
00247 if (tmp & (1 << 7)) {
00248 intr_cfg.pa7 = regk_gio_lo;
00249 }
00250
00251 REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg);
00252 local_irq_restore(flags);
00253 } else if (priv->minor <= GPIO_MINOR_E)
00254 data = *data_in[priv->minor];
00255 else
00256 return 0;
00257
00258 if ((data & priv->highalarm) ||
00259 (~data & priv->lowalarm)) {
00260 mask = POLLIN|POLLRDNORM;
00261 }
00262
00263 DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
00264 return mask;
00265 }
00266
00267 int etrax_gpio_wake_up_check(void)
00268 {
00269 struct gpio_private *priv;
00270 unsigned long data = 0;
00271 unsigned long flags;
00272 int ret = 0;
00273 spin_lock_irqsave(&alarm_lock, flags);
00274 priv = alarmlist;
00275 while (priv) {
00276 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00277 if (priv->minor == GPIO_MINOR_V) {
00278 data = (unsigned long)cached_virtual_gpio_read;
00279 }
00280 else {
00281 data = *data_in[priv->minor];
00282 if (priv->minor == GPIO_MINOR_A) {
00283 priv->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
00284 }
00285 }
00286 #else
00287 data = *data_in[priv->minor];
00288 #endif
00289 if ((data & priv->highalarm) ||
00290 (~data & priv->lowalarm)) {
00291 DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor));
00292 wake_up_interruptible(&priv->alarm_wq);
00293 ret = 1;
00294 }
00295 priv = priv->next;
00296 }
00297 spin_unlock_irqrestore(&alarm_lock, flags);
00298 return ret;
00299 }
00300
00301 static irqreturn_t
00302 gpio_poll_timer_interrupt(int irq, void *dev_id)
00303 {
00304 if (gpio_some_alarms) {
00305 return IRQ_RETVAL(etrax_gpio_wake_up_check());
00306 }
00307 return IRQ_NONE;
00308 }
00309
00310 static irqreturn_t
00311 gpio_pa_interrupt(int irq, void *dev_id)
00312 {
00313 reg_gio_rw_intr_mask intr_mask;
00314 reg_gio_r_masked_intr masked_intr;
00315 reg_gio_rw_ack_intr ack_intr;
00316 unsigned long tmp;
00317 unsigned long tmp2;
00318 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00319 unsigned char enable_gpiov_ack = 0;
00320 #endif
00321
00322
00323 masked_intr = REG_RD(gio, regi_gio, r_masked_intr);
00324 tmp = REG_TYPE_CONV(unsigned long, reg_gio_r_masked_intr, masked_intr);
00325
00326
00327 spin_lock(&alarm_lock);
00328 tmp &= (gpio_pa_high_alarms | gpio_pa_low_alarms);
00329 spin_unlock(&alarm_lock);
00330
00331 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00332
00333
00334
00335 if (tmp & (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN)) {
00336 i2c_read(VIRT_I2C_ADDR, (void *)&cached_virtual_gpio_read,
00337 sizeof(cached_virtual_gpio_read));
00338 enable_gpiov_ack = 1;
00339 }
00340 #endif
00341
00342
00343 ack_intr = REG_TYPE_CONV(reg_gio_rw_ack_intr, unsigned long, tmp);
00344 REG_WR(gio, regi_gio, rw_ack_intr, ack_intr);
00345
00346
00347 intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
00348 tmp2 = REG_TYPE_CONV(unsigned long, reg_gio_rw_intr_mask, intr_mask);
00349 tmp2 &= ~tmp;
00350 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00351
00352
00353
00354 if (enable_gpiov_ack) {
00355 tmp2 |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
00356 }
00357 #endif
00358 intr_mask = REG_TYPE_CONV(reg_gio_rw_intr_mask, unsigned long, tmp2);
00359 REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
00360
00361 if (gpio_some_alarms) {
00362 return IRQ_RETVAL(etrax_gpio_wake_up_check());
00363 }
00364 return IRQ_NONE;
00365 }
00366
00367
00368 static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
00369 loff_t *off)
00370 {
00371 struct gpio_private *priv = (struct gpio_private *)file->private_data;
00372 unsigned char data, clk_mask, data_mask, write_msb;
00373 unsigned long flags;
00374 unsigned long shadow;
00375 volatile unsigned long *port;
00376 ssize_t retval = count;
00377
00378
00379 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00380 if (priv->minor == GPIO_MINOR_V) {
00381 return -EFAULT;
00382 }
00383 #endif
00384 if (priv->minor == GPIO_MINOR_LEDS) {
00385 return -EFAULT;
00386 }
00387
00388 if (!access_ok(VERIFY_READ, buf, count)) {
00389 return -EFAULT;
00390 }
00391 clk_mask = priv->clk_mask;
00392 data_mask = priv->data_mask;
00393
00394
00395 if (clk_mask == 0 || data_mask == 0) {
00396 return -EPERM;
00397 }
00398 write_msb = priv->write_msb;
00399 D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb));
00400 port = data_out[priv->minor];
00401
00402 while (count--) {
00403 int i;
00404 data = *buf++;
00405 if (priv->write_msb) {
00406 for (i = 7; i >= 0;i--) {
00407 local_irq_save(flags);
00408 shadow = *port;
00409 *port = shadow &= ~clk_mask;
00410 if (data & 1<<i)
00411 *port = shadow |= data_mask;
00412 else
00413 *port = shadow &= ~data_mask;
00414
00415 *port = shadow |= clk_mask;
00416 local_irq_restore(flags);
00417 }
00418 } else {
00419 for (i = 0; i <= 7;i++) {
00420 local_irq_save(flags);
00421 shadow = *port;
00422 *port = shadow &= ~clk_mask;
00423 if (data & 1<<i)
00424 *port = shadow |= data_mask;
00425 else
00426 *port = shadow &= ~data_mask;
00427
00428 *port = shadow |= clk_mask;
00429 local_irq_restore(flags);
00430 }
00431 }
00432 }
00433 return retval;
00434 }
00435
00436
00437
00438 static int
00439 gpio_open(struct inode *inode, struct file *filp)
00440 {
00441 struct gpio_private *priv;
00442 int p = iminor(inode);
00443
00444 if (p > GPIO_MINOR_LAST)
00445 return -EINVAL;
00446
00447 priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private),
00448 GFP_KERNEL);
00449
00450 if (!priv)
00451 return -ENOMEM;
00452 memset(priv, 0, sizeof(*priv));
00453
00454 priv->minor = p;
00455
00456
00457
00458 priv->clk_mask = 0;
00459 priv->data_mask = 0;
00460 priv->highalarm = 0;
00461 priv->lowalarm = 0;
00462 init_waitqueue_head(&priv->alarm_wq);
00463
00464 filp->private_data = (void *)priv;
00465
00466
00467 spin_lock_irq(&alarm_lock);
00468 priv->next = alarmlist;
00469 alarmlist = priv;
00470 spin_unlock_irq(&alarm_lock);
00471
00472 return 0;
00473 }
00474
00475 static int
00476 gpio_release(struct inode *inode, struct file *filp)
00477 {
00478 struct gpio_private *p;
00479 struct gpio_private *todel;
00480
00481 unsigned long a_high, a_low;
00482 unsigned long some_alarms;
00483
00484
00485
00486 spin_lock_irq(&alarm_lock);
00487 p = alarmlist;
00488 todel = (struct gpio_private *)filp->private_data;
00489
00490 if (p == todel) {
00491 alarmlist = todel->next;
00492 } else {
00493 while (p->next != todel)
00494 p = p->next;
00495 p->next = todel->next;
00496 }
00497
00498 kfree(todel);
00499
00500 p = alarmlist;
00501 some_alarms = 0;
00502 a_high = 0;
00503 a_low = 0;
00504 while (p) {
00505 if (p->minor == GPIO_MINOR_A) {
00506 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00507 p->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
00508 #endif
00509 a_high |= p->highalarm;
00510 a_low |= p->lowalarm;
00511 }
00512
00513 if (p->highalarm | p->lowalarm) {
00514 some_alarms = 1;
00515 }
00516 p = p->next;
00517 }
00518
00519 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00520
00521
00522
00523 some_alarms = 1;
00524 a_low |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
00525 #endif
00526
00527 gpio_some_alarms = some_alarms;
00528 gpio_pa_high_alarms = a_high;
00529 gpio_pa_low_alarms = a_low;
00530 spin_unlock_irq(&alarm_lock);
00531
00532 return 0;
00533 }
00534
00535
00536
00537
00538
00539 unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
00540 {
00541
00542
00543
00544 unsigned long flags;
00545 unsigned long dir_shadow;
00546
00547 local_irq_save(flags);
00548 dir_shadow = *dir_oe[priv->minor];
00549 dir_shadow &= ~(arg & changeable_dir[priv->minor]);
00550 *dir_oe[priv->minor] = dir_shadow;
00551 local_irq_restore(flags);
00552
00553 if (priv->minor == GPIO_MINOR_A)
00554 dir_shadow ^= 0xFF;
00555 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00556 else if (priv->minor == GPIO_MINOR_V)
00557 dir_shadow ^= 0xFFFF;
00558 #endif
00559 else
00560 dir_shadow ^= 0x3FFFF;
00561 return dir_shadow;
00562
00563 }
00564
00565 unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
00566 {
00567 unsigned long flags;
00568 unsigned long dir_shadow;
00569
00570 local_irq_save(flags);
00571 dir_shadow = *dir_oe[priv->minor];
00572 dir_shadow |= (arg & changeable_dir[priv->minor]);
00573 *dir_oe[priv->minor] = dir_shadow;
00574 local_irq_restore(flags);
00575 return dir_shadow;
00576 }
00577
00578 static int
00579 gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
00580
00581 static int
00582 gpio_ioctl(struct inode *inode, struct file *file,
00583 unsigned int cmd, unsigned long arg)
00584 {
00585 unsigned long flags;
00586 unsigned long val;
00587 unsigned long shadow;
00588 struct gpio_private *priv = (struct gpio_private *)file->private_data;
00589 if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) {
00590 return -EINVAL;
00591 }
00592
00593 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00594 if (priv->minor == GPIO_MINOR_V)
00595 return virtual_gpio_ioctl(file, cmd, arg);
00596 #endif
00597
00598 switch (_IOC_NR(cmd)) {
00599 case IO_READBITS:
00600
00601 return *data_in[priv->minor];
00602 break;
00603 case IO_SETBITS:
00604 local_irq_save(flags);
00605
00606 shadow = *data_out[priv->minor];
00607 shadow |= (arg & changeable_bits[priv->minor]);
00608 *data_out[priv->minor] = shadow;
00609 local_irq_restore(flags);
00610 break;
00611 case IO_CLRBITS:
00612 local_irq_save(flags);
00613
00614 shadow = *data_out[priv->minor];
00615 shadow &= ~(arg & changeable_bits[priv->minor]);
00616 *data_out[priv->minor] = shadow;
00617 local_irq_restore(flags);
00618 break;
00619 case IO_HIGHALARM:
00620
00621 priv->highalarm |= arg;
00622 spin_lock_irqsave(&alarm_lock, flags);
00623 gpio_some_alarms = 1;
00624 if (priv->minor == GPIO_MINOR_A) {
00625 gpio_pa_high_alarms |= arg;
00626 }
00627 spin_unlock_irqrestore(&alarm_lock, flags);
00628 break;
00629 case IO_LOWALARM:
00630
00631 priv->lowalarm |= arg;
00632 spin_lock_irqsave(&alarm_lock, flags);
00633 gpio_some_alarms = 1;
00634 if (priv->minor == GPIO_MINOR_A) {
00635 gpio_pa_low_alarms |= arg;
00636 }
00637 spin_unlock_irqrestore(&alarm_lock, flags);
00638 break;
00639 case IO_CLRALARM:
00640
00641 priv->highalarm &= ~arg;
00642 priv->lowalarm &= ~arg;
00643 spin_lock_irqsave(&alarm_lock, flags);
00644 if (priv->minor == GPIO_MINOR_A) {
00645 if (gpio_pa_high_alarms & arg ||
00646 gpio_pa_low_alarms & arg) {
00647
00648 }
00649 }
00650 spin_unlock_irqrestore(&alarm_lock, flags);
00651 break;
00652 case IO_READDIR:
00653
00654 return *dir_oe[priv->minor];
00655 case IO_SETINPUT:
00656
00657
00658
00659 return setget_input(priv, arg);
00660 break;
00661 case IO_SETOUTPUT:
00662
00663
00664
00665 return setget_output(priv, arg);
00666
00667 case IO_CFG_WRITE_MODE:
00668 {
00669 unsigned long dir_shadow;
00670 dir_shadow = *dir_oe[priv->minor];
00671
00672 priv->clk_mask = arg & 0xFF;
00673 priv->data_mask = (arg >> 8) & 0xFF;
00674 priv->write_msb = (arg >> 16) & 0x01;
00675
00676
00677
00678 if (!((priv->clk_mask & changeable_bits[priv->minor]) &&
00679 (priv->data_mask & changeable_bits[priv->minor]) &&
00680 (priv->clk_mask & dir_shadow) &&
00681 (priv->data_mask & dir_shadow)))
00682 {
00683 priv->clk_mask = 0;
00684 priv->data_mask = 0;
00685 return -EPERM;
00686 }
00687 break;
00688 }
00689 case IO_READ_INBITS:
00690
00691 val = *data_in[priv->minor];
00692 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
00693 return -EFAULT;
00694 return 0;
00695 break;
00696 case IO_READ_OUTBITS:
00697
00698 val = *data_out[priv->minor];
00699 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
00700 return -EFAULT;
00701 break;
00702 case IO_SETGET_INPUT:
00703
00704
00705
00706 if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
00707 return -EFAULT;
00708 val = setget_input(priv, val);
00709 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
00710 return -EFAULT;
00711 break;
00712 case IO_SETGET_OUTPUT:
00713
00714
00715
00716 if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
00717 return -EFAULT;
00718 val = setget_output(priv, val);
00719 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
00720 return -EFAULT;
00721 break;
00722 default:
00723 if (priv->minor == GPIO_MINOR_LEDS)
00724 return gpio_leds_ioctl(cmd, arg);
00725 else
00726 return -EINVAL;
00727 }
00728
00729 return 0;
00730 }
00731
00732 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00733 static int
00734 virtual_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
00735 {
00736 unsigned long flags;
00737 unsigned short val;
00738 unsigned short shadow;
00739 struct gpio_private *priv = (struct gpio_private *)file->private_data;
00740
00741 switch (_IOC_NR(cmd)) {
00742 case IO_SETBITS:
00743 local_irq_save(flags);
00744
00745 i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
00746 shadow |= ~*dir_oe[priv->minor];
00747 shadow |= (arg & changeable_bits[priv->minor]);
00748 i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
00749 local_irq_restore(flags);
00750 break;
00751 case IO_CLRBITS:
00752 local_irq_save(flags);
00753
00754 i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
00755 shadow |= ~*dir_oe[priv->minor];
00756 shadow &= ~(arg & changeable_bits[priv->minor]);
00757 i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
00758 local_irq_restore(flags);
00759 break;
00760 case IO_HIGHALARM:
00761
00762 priv->highalarm |= arg;
00763 spin_lock(&alarm_lock);
00764 gpio_some_alarms = 1;
00765 spin_unlock(&alarm_lock);
00766 break;
00767 case IO_LOWALARM:
00768
00769 priv->lowalarm |= arg;
00770 spin_lock(&alarm_lock);
00771 gpio_some_alarms = 1;
00772 spin_unlock(&alarm_lock);
00773 break;
00774 case IO_CLRALARM:
00775
00776 priv->highalarm &= ~arg;
00777 priv->lowalarm &= ~arg;
00778 spin_lock(&alarm_lock);
00779 spin_unlock(&alarm_lock);
00780 break;
00781 case IO_CFG_WRITE_MODE:
00782 {
00783 unsigned long dir_shadow;
00784 dir_shadow = *dir_oe[priv->minor];
00785
00786 priv->clk_mask = arg & 0xFF;
00787 priv->data_mask = (arg >> 8) & 0xFF;
00788 priv->write_msb = (arg >> 16) & 0x01;
00789
00790
00791
00792 if (!((priv->clk_mask & changeable_bits[priv->minor]) &&
00793 (priv->data_mask & changeable_bits[priv->minor]) &&
00794 (priv->clk_mask & dir_shadow) &&
00795 (priv->data_mask & dir_shadow)))
00796 {
00797 priv->clk_mask = 0;
00798 priv->data_mask = 0;
00799 return -EPERM;
00800 }
00801 break;
00802 }
00803 case IO_READ_INBITS:
00804
00805 val = cached_virtual_gpio_read;
00806 val &= ~*dir_oe[priv->minor];
00807 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
00808 return -EFAULT;
00809 return 0;
00810 break;
00811 case IO_READ_OUTBITS:
00812
00813 i2c_read(VIRT_I2C_ADDR, (void *)&val, sizeof(val));
00814 val &= *dir_oe[priv->minor];
00815 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
00816 return -EFAULT;
00817 break;
00818 case IO_SETGET_INPUT:
00819 {
00820
00821
00822
00823 unsigned short input_mask = ~*dir_oe[priv->minor];
00824 if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
00825 return -EFAULT;
00826 val = setget_input(priv, val);
00827 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
00828 return -EFAULT;
00829 if ((input_mask & val) != input_mask) {
00830
00831
00832
00833 unsigned short change = input_mask ^ val;
00834 i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
00835 shadow &= ~change;
00836 shadow |= val;
00837 i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
00838 }
00839 break;
00840 }
00841 case IO_SETGET_OUTPUT:
00842
00843
00844
00845 if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
00846 return -EFAULT;
00847 val = setget_output(priv, val);
00848 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
00849 return -EFAULT;
00850 break;
00851 default:
00852 return -EINVAL;
00853 }
00854 return 0;
00855 }
00856 #endif
00857
00858 static int
00859 gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
00860 {
00861 unsigned char green;
00862 unsigned char red;
00863
00864 switch (_IOC_NR(cmd)) {
00865 case IO_LEDACTIVE_SET:
00866 green = ((unsigned char) arg) & 1;
00867 red = (((unsigned char) arg) >> 1) & 1;
00868 LED_ACTIVE_SET_G(green);
00869 LED_ACTIVE_SET_R(red);
00870 break;
00871
00872 default:
00873 return -EINVAL;
00874 }
00875
00876 return 0;
00877 }
00878
00879 struct file_operations gpio_fops = {
00880 .owner = THIS_MODULE,
00881 .poll = gpio_poll,
00882 .ioctl = gpio_ioctl,
00883 .write = gpio_write,
00884 .open = gpio_open,
00885 .release = gpio_release,
00886 };
00887
00888 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00889 static void
00890 virtual_gpio_init(void)
00891 {
00892 reg_gio_rw_intr_cfg intr_cfg;
00893 reg_gio_rw_intr_mask intr_mask;
00894 unsigned short shadow;
00895
00896 shadow = ~virtual_rw_pv_oe;
00897 shadow |= CONFIG_ETRAX_DEF_GIO_PV_OUT;
00898 i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
00899
00900
00901
00902
00903 intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg);
00904 intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
00905
00906 switch (CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN) {
00907 case 0:
00908 intr_cfg.pa0 = regk_gio_lo;
00909 intr_mask.pa0 = regk_gio_yes;
00910 break;
00911 case 1:
00912 intr_cfg.pa1 = regk_gio_lo;
00913 intr_mask.pa1 = regk_gio_yes;
00914 break;
00915 case 2:
00916 intr_cfg.pa2 = regk_gio_lo;
00917 intr_mask.pa2 = regk_gio_yes;
00918 break;
00919 case 3:
00920 intr_cfg.pa3 = regk_gio_lo;
00921 intr_mask.pa3 = regk_gio_yes;
00922 break;
00923 case 4:
00924 intr_cfg.pa4 = regk_gio_lo;
00925 intr_mask.pa4 = regk_gio_yes;
00926 break;
00927 case 5:
00928 intr_cfg.pa5 = regk_gio_lo;
00929 intr_mask.pa5 = regk_gio_yes;
00930 break;
00931 case 6:
00932 intr_cfg.pa6 = regk_gio_lo;
00933 intr_mask.pa6 = regk_gio_yes;
00934 break;
00935 case 7:
00936 intr_cfg.pa7 = regk_gio_lo;
00937 intr_mask.pa7 = regk_gio_yes;
00938 break;
00939 }
00940
00941 REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg);
00942 REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
00943
00944 gpio_pa_low_alarms |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
00945 gpio_some_alarms = 1;
00946 }
00947 #endif
00948
00949
00950
00951 static __init int
00952 gpio_init(void)
00953 {
00954 int res;
00955 reg_intr_vect_rw_mask intr_mask;
00956
00957
00958
00959 res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
00960 if (res < 0) {
00961 printk(KERN_ERR "gpio: couldn't get a major number.\n");
00962 return res;
00963 }
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973 printk("ETRAX FS GPIO driver v2.5, (c) 2003-2006 Axis Communications AB\n");
00974
00975
00976
00977
00978
00979 if (request_irq(TIMER_INTR_VECT, gpio_poll_timer_interrupt,
00980 IRQF_SHARED | IRQF_DISABLED,"gpio poll", &alarmlist)) {
00981 printk("err: timer0 irq for gpio\n");
00982 }
00983 if (request_irq(GEN_IO_INTR_VECT, gpio_pa_interrupt,
00984 IRQF_SHARED | IRQF_DISABLED,"gpio PA", &alarmlist)) {
00985 printk("err: PA irq for gpio\n");
00986 }
00987
00988 intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
00989 intr_mask.timer = 1;
00990 intr_mask.gen_io = 1;
00991 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
00992
00993 #ifdef CONFIG_ETRAX_VIRTUAL_GPIO
00994 virtual_gpio_init();
00995 #endif
00996
00997 return res;
00998 }
00999
01000
01001
01002 module_init(gpio_init);