6 * 12-06-2005 Victor Yu. Create it.
7 * 24-05-2006 Jimmy Chen. Fix it.
8 * 02-09-2007 Victor Yu. Porting to kernel verion 2.6.19.
10 #if 1 // add by Victor Yu. 02-09-2007
11 #include <linux/version.h>
13 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) // add by Victor Yu. 02-09-2007
14 #include <linux/config.h>
16 #include <asm/arch/moxa.h>
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/types.h>
20 #include <linux/miscdevice.h>
21 #include <linux/fcntl.h>
22 #include <linux/init.h>
23 #include <linux/poll.h>
24 #include <linux/proc_fs.h>
25 #include <linux/spinlock.h>
26 #include <linux/delay.h>
27 #include <linux/rtc.h>
28 #include <linux/timer.h>
29 #include <linux/ioport.h>
32 #include <asm/uaccess.h>
33 #include <asm/system.h>
34 #include <asm/arch/gpio.h>
36 #define MOXA_PIO_MINOR 104
38 #define GPIO_BASE_SHIFT 10
39 #define GPIO_MASK (0x3ff<<GPIO_BASE_SHIFT)
42 // PIO file operaiton function call
50 #define IOCTL_PIO_GET_MODE 1
51 #define IOCTL_PIO_SET_MODE 2
52 #define IOCTL_PIO_GET_DATA 3
53 #define IOCTL_PIO_SET_DATA 4
54 struct pio_set_struct
{
56 int mode_data
; // 1 for input, 0 for output, 1 for high, 0 for low
59 static int pio_ioctl(struct inode
*inode
, struct file
*file
, unsigned int cmd
, unsigned long arg
)
61 struct pio_set_struct set
;
64 case IOCTL_PIO_SET_MODE
:
65 if ( copy_from_user(&set
, (struct pio_set_struct
*)arg
, sizeof(struct pio_set_struct
)) )
67 if ( set
.io_number
< 0 || set
.io_number
> MAX_PIO
)
69 if ( set
.mode_data
== PIO_INPUT
)
70 mcpu_gpio_inout(1<<(set
.io_number
+GPIO_BASE_SHIFT
), MCPU_GPIO_INPUT
);
71 else if ( set
.mode_data
== PIO_OUTPUT
)
72 mcpu_gpio_inout(1<<(set
.io_number
+GPIO_BASE_SHIFT
), MCPU_GPIO_OUTPUT
);
76 case IOCTL_PIO_GET_MODE
:
77 if ( copy_from_user(&set
, (struct pio_set_struct
*)arg
, sizeof(struct pio_set_struct
)) )
79 if ( set
.io_number
< 0 || set
.io_number
> MAX_PIO
)
81 if ( mcpu_gpio_get_inout(1<<(set
.io_number
+GPIO_BASE_SHIFT
)) == MCPU_GPIO_INPUT
)
82 set
.mode_data
= PIO_INPUT
;
84 set
.mode_data
= PIO_OUTPUT
;
85 if ( copy_to_user((struct pio_set_struct
*)arg
, &set
, sizeof(struct pio_set_struct
)) )
88 case IOCTL_PIO_SET_DATA
:
89 if ( copy_from_user(&set
, (struct pio_set_struct
*)arg
, sizeof(struct pio_set_struct
)) )
91 if ( set
.io_number
< 0 || set
.io_number
> MAX_PIO
)
93 if ( set
.mode_data
== PIO_HIGH
)
94 mcpu_gpio_set(1<<(set
.io_number
+GPIO_BASE_SHIFT
), MCPU_GPIO_HIGH
);
95 else if ( set
.mode_data
== PIO_LOW
)
96 mcpu_gpio_set(1<<(set
.io_number
+GPIO_BASE_SHIFT
), MCPU_GPIO_LOW
);
100 case IOCTL_PIO_GET_DATA
:
101 if ( copy_from_user(&set
, (struct pio_set_struct
*)arg
, sizeof(struct pio_set_struct
)) )
103 if ( set
.io_number
< 0 || set
.io_number
> MAX_PIO
)
105 if ( mcpu_gpio_get(1<<(set
.io_number
+GPIO_BASE_SHIFT
)) )
106 set
.mode_data
= PIO_HIGH
;
108 set
.mode_data
= PIO_LOW
;
109 if ( copy_to_user((struct pio_set_struct
*)arg
, &set
, sizeof(struct pio_set_struct
)) )
118 static int pio_open(struct inode
*inode
, struct file
*file
)
120 if ( MINOR(inode
->i_rdev
) == MOXA_PIO_MINOR
)
125 static int pio_release(struct inode
*inode
, struct file
*file
)
130 static struct file_operations pio_fops
= {
137 static struct miscdevice pio_dev
= {
143 #if 1 // add by Victor Yu. 03-08-2007
144 extern int moxa_gpio_sd_used_flag
; // define on arch/arm/kernel/armksyms.c
146 static void __exit
pio_exit(void)
148 misc_deregister(&pio_dev
);
149 #if 1 // add by Victor Yu. 12-05-2007
152 local_irq_save(flags
);
153 moxa_gpio_sd_used_flag
= 0;
154 local_irq_restore(flags
);
159 static int __init
pio_init(void)
161 printk("Moxa CPU misc: Register PIO misc ver1.0 ");
162 #if 1 // add by Victor Yu. 03-08-2007
165 local_irq_save(flags
);
166 if ( moxa_gpio_sd_used_flag
) {
167 printk("The IO has used by other device driver !\n");
168 local_irq_restore(flags
);
171 moxa_gpio_sd_used_flag
= 1;
172 local_irq_restore(flags
);
175 if ( misc_register(&pio_dev
) ) {
180 // set the CPU for GPIO
181 mcpu_gpio_mp_set(GPIO_MASK
);
183 // default set all GPIO for input
184 mcpu_gpio_inout(GPIO_MASK
, MCPU_GPIO_OUTPUT
);
186 // default set all GPIO data_out high
187 mcpu_gpio_set(GPIO_MASK
, MCPU_GPIO_HIGH
);
192 module_init(pio_init
);
193 module_exit(pio_exit
);
195 MODULE_AUTHOR("Victor Yu");
196 MODULE_LICENSE("GPL");