12 #include <linux/module.h>
13 #include <linux/sched.h>
14 #include <linux/slab.h>
16 #include <linux/errno.h>
17 #include <linux/kernel.h>
19 #include <linux/string.h>
20 #include <linux/poll.h>
30 #define GPIO_MAJOR 120
36 #define DP(x) do { dp_cnt++; if (dp_cnt % 1000 == 0) x; }while(0)
41 static char gpio_name[] =
"etrax gpio";
47 static long gpio_ioctl(
struct file *
file,
unsigned int cmd,
unsigned long arg);
49 size_t count, loff_t *off);
77 static int gpio_some_alarms;
78 static unsigned long gpio_pa_irq_enabled_mask;
83 #define NUM_PORTS (GPIO_MINOR_B+1)
85 static volatile unsigned char *ports[
NUM_PORTS] = {
89 static volatile unsigned char *shads[
NUM_PORTS] = {
95 #ifndef CONFIG_ETRAX_PA_CHANGEABLE_DIR
96 #define CONFIG_ETRAX_PA_CHANGEABLE_DIR 0x00
98 #ifndef CONFIG_ETRAX_PB_CHANGEABLE_DIR
99 #define CONFIG_ETRAX_PB_CHANGEABLE_DIR 0x00
102 #ifndef CONFIG_ETRAX_PA_CHANGEABLE_BITS
103 #define CONFIG_ETRAX_PA_CHANGEABLE_BITS 0xFF
105 #ifndef CONFIG_ETRAX_PB_CHANGEABLE_BITS
106 #define CONFIG_ETRAX_PB_CHANGEABLE_BITS 0xFF
130 static const unsigned long int changeable_dir_g_mask = 0x01FFFF01;
135 static unsigned long changeable_dir_g;
136 static unsigned long dir_g_in_bits;
137 static unsigned long dir_g_out_bits;
138 static unsigned long dir_g_shadow;
140 #define USE_PORTS(priv) ((priv)->minor <= GPIO_MINOR_B)
145 unsigned int mask = 0;
152 poll_wait(file, &priv->
alarm_wq, wait);
153 if (priv->
minor == GPIO_MINOR_A) {
155 data = *R_PORT_PA_DATA;
160 tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
162 gpio_pa_irq_enabled_mask |=
tmp;
163 *R_IRQ_MASK1_SET =
tmp;
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;
179 spin_unlock_irqrestore(&gpio_lock, flags);
180 DP(
printk(
"gpio_poll ready: mask 0x%08X\n", mask));
188 unsigned long data = 0;
197 else if (priv->
minor == GPIO_MINOR_G)
198 data = *R_PORT_G_DATA;
208 spin_unlock_irqrestore(&gpio_lock, flags);
213 gpio_poll_timer_interrupt(
int irq,
void *
dev_id)
215 if (gpio_some_alarms) {
223 gpio_interrupt(
int irq,
void *dev_id)
231 tmp = (*R_IRQ_READ1);
234 tmp &= gpio_pa_irq_enabled_mask;
237 *R_IRQ_MASK1_CLR =
tmp;
238 gpio_pa_irq_enabled_mask &= ~tmp;
240 spin_unlock_irqrestore(&gpio_lock, flags);
242 if (gpio_some_alarms)
261 static void gpio_write_byte(
struct gpio_private *priv,
unsigned char data)
266 for (i = 7; i >= 0; i--)
267 gpio_write_bit(priv, data, i);
269 for (i = 0; i <= 7; i++)
270 gpio_write_bit(priv, data, i);
274 size_t count, loff_t *off)
280 if (priv->
minor != GPIO_MINOR_A && priv->
minor != GPIO_MINOR_B)
296 "clk 0x%02X msb: %i\n",
300 gpio_write_byte(priv, *buf++);
303 spin_unlock_irqrestore(&gpio_lock, flags);
310 gpio_open(
struct inode *
inode,
struct file *filp)
313 int p = iminor(inode);
316 if (p > GPIO_MINOR_LAST)
329 priv->
port = ports[
p];
354 priv->
next = alarmlist;
356 spin_unlock_irqrestore(&gpio_lock, flags);
362 gpio_release(
struct inode *inode,
struct file *filp)
376 alarmlist = todel->
next;
378 while (p->
next != todel)
388 gpio_some_alarms = 1;
393 gpio_some_alarms = 0;
395 spin_unlock_irqrestore(&gpio_lock, flags);
412 if (priv->
minor != GPIO_MINOR_G)
416 if (((arg & dir_g_in_bits) !=
arg) &&
417 (arg & changeable_dir_g)) {
418 arg &= changeable_dir_g;
422 dir_g_in_bits |= (1<<0);
423 dir_g_out_bits &= ~(1<<0);
425 if ((arg & 0x0000FF00) == 0x0000FF00) {
427 dir_g_in_bits |= 0x0000FF00;
428 dir_g_out_bits &= ~0x0000FF00;
430 if ((arg & 0x00FF0000) == 0x00FF0000) {
432 dir_g_in_bits |= 0x00FF0000;
433 dir_g_out_bits &= ~0x00FF0000;
437 dir_g_in_bits |= (1<<24);
438 dir_g_out_bits &= ~(1<<24);
441 "genconfig to 0x%08lX "
443 "out_bits: 0x%08lX\n",
445 dir_g_in_bits, dir_g_out_bits));
450 return dir_g_in_bits;
460 if (priv->
minor != GPIO_MINOR_G)
464 if (((arg & dir_g_out_bits) !=
arg) &&
465 (arg & changeable_dir_g)) {
469 dir_g_out_bits |= (1<<0);
470 dir_g_in_bits &= ~(1<<0);
472 if ((arg & 0x0000FF00) == 0x0000FF00) {
474 dir_g_out_bits |= 0x0000FF00;
475 dir_g_in_bits &= ~0x0000FF00;
477 if ((arg & 0x00FF0000) == 0x00FF0000) {
479 dir_g_out_bits |= 0x00FF0000;
480 dir_g_in_bits &= ~0x00FF0000;
484 dir_g_out_bits |= (1<<24);
485 dir_g_in_bits &= ~(1<<24);
488 "genconfig to 0x%08lX "
490 "out_bits: 0x%08lX\n",
492 dir_g_in_bits, dir_g_out_bits));
496 return dir_g_out_bits & 0x7FFFFFFF;
500 gpio_leds_ioctl(
unsigned int cmd,
unsigned long arg);
502 static long gpio_ioctl(
struct file *file,
unsigned int cmd,
unsigned long arg)
518 }
else if (priv->
minor == GPIO_MINOR_G) {
519 ret = (*R_PORT_G_DATA) & 0x7FFFFFFF;
521 spin_unlock_irqrestore(&gpio_lock, flags);
531 }
else if (priv->
minor == GPIO_MINOR_G) {
534 spin_unlock_irqrestore(&gpio_lock, flags);
543 }
else if (priv->
minor == GPIO_MINOR_G) {
546 spin_unlock_irqrestore(&gpio_lock, flags);
552 gpio_some_alarms = 1;
553 spin_unlock_irqrestore(&gpio_lock, flags);
559 gpio_some_alarms = 1;
560 spin_unlock_irqrestore(&gpio_lock, flags);
580 gpio_some_alarms = some_alarms;
582 spin_unlock_irqrestore(&gpio_lock, flags);
589 }
else if (priv->
minor == GPIO_MINOR_G) {
593 ret = (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
595 spin_unlock_irqrestore(&gpio_lock, flags);
603 spin_unlock_irqrestore(&gpio_lock, flags);
611 spin_unlock_irqrestore(&gpio_lock, flags);
616 spin_unlock_irqrestore(&gpio_lock, flags);
620 #if defined (CONFIG_ETRAX_SOFT_SHUTDOWN)
621 ret = (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
625 spin_unlock_irqrestore(&gpio_lock, flags);
644 spin_unlock_irqrestore(&gpio_lock, flags);
651 }
else if (priv->
minor == GPIO_MINOR_G) {
652 val = *R_PORT_G_DATA;
654 spin_unlock_irqrestore(&gpio_lock, flags);
655 if (
copy_to_user((
void __user *)arg, &val,
sizeof(val)))
663 }
else if (priv->
minor == GPIO_MINOR_G) {
666 spin_unlock_irqrestore(&gpio_lock, flags);
667 if (
copy_to_user((
void __user *)arg, &val,
sizeof(val)))
681 spin_unlock_irqrestore(&gpio_lock, flags);
682 if (
copy_to_user((
void __user *)arg, &val,
sizeof(val)))
695 spin_unlock_irqrestore(&gpio_lock, flags);
696 if (
copy_to_user((
void __user *)arg, &val,
sizeof(val)))
701 if (priv->
minor == GPIO_MINOR_LEDS)
702 ret = gpio_leds_ioctl(cmd, arg);
705 spin_unlock_irqrestore(&gpio_lock, flags);
712 gpio_leds_ioctl(
unsigned int cmd,
unsigned long arg)
719 green = ((
unsigned char)arg) & 1;
720 red = (((
unsigned char)arg) >> 1) & 1;
743 .unlocked_ioctl = gpio_ioctl,
746 .release = gpio_release,
750 static 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)
755 unsigned long int flags;
759 "PA: 0x%02x PB: 0x%02x\n",
760 gpio_in_available, gpio_out_available,
761 pa_available, pb_available));
765 dir_g_in_bits = gpio_in_available;
766 dir_g_out_bits = gpio_out_available;
771 dir_g_shadow |= (1 << 0);
773 dir_g_shadow |= 0x0000FF00;
775 dir_g_shadow |= 0x00FF0000;
777 dir_g_shadow |= (1 << 24);
779 changeable_dir_g = changeable_dir_g_mask;
780 changeable_dir_g &= dir_g_out_bits;
781 changeable_dir_g &= dir_g_in_bits;
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);
789 spin_unlock_irqrestore(&gpio_lock, flags);
793 dir_g_in_bits, dir_g_out_bits, (
unsigned long)*R_PORT_G_DATA);
795 dir_g_shadow, changeable_dir_g);
803 #if defined (CONFIG_ETRAX_CSP0_LEDS)
807 res = register_chrdev(
GPIO_MAJOR, gpio_name, &gpio_fops);
814 #if defined (CONFIG_ETRAX_CSP0_LEDS) || defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS)
820 #if defined (CONFIG_ETRAX_CSP0_LEDS)
821 for (i = 0; i < 32; i++)
830 "if allocator watcher\n");
834 "Axis Communications AB\n");