2 * This is Moxa CPU DIO device driver.
3 * It is from misc interface. So the device node major number is 10.
4 * The device node minor number is following:
9 * 12-06-2005 Victor Yu. Create it.
11 #include <linux/config.h>
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/types.h>
15 #include <linux/miscdevice.h>
16 #include <linux/fcntl.h>
17 #include <linux/init.h>
18 #include <linux/poll.h>
19 #include <linux/proc_fs.h>
20 #include <linux/spinlock.h>
21 #include <linux/delay.h>
22 #include <linux/rtc.h>
23 #include <linux/timer.h>
24 #include <linux/ioport.h>
25 #include <linux/proc_fs.h>
28 #include <asm/uaccess.h>
29 #include <asm/system.h>
30 #include <asm/arch/cpe/cpe.h>
31 #include <asm/arch/gpio.h>
34 #define MOXA_DIO_MINOR 104
36 #if defined(CONFIG_ARCH_W341) || defined(CONFIG_ARCH_W345) || defined(CONFIG_ARCH_W345_IMP1)
37 #define DO_BASE_SHIFT 22
38 #define DO_MASK (0x01<<DO_BASE_SHIFT)
39 #define GPIO_MASK (DO_MASK)
41 #define DI_BASE_SHIFT 4
42 #define DO_BASE_SHIFT 18
43 #define DI_MASK (0x0f<<DI_BASE_SHIFT)
44 #define DO_MASK (0x0f<<DO_BASE_SHIFT)
45 #define GPIO_MASK (DI_MASK|DO_MASK)
49 // DIO file operaiton function call
51 #if defined(CONFIG_ARCH_W341) || defined(CONFIG_ARCH_W345) || defined(CONFIG_ARCH_W345_IMP1)
52 #define MAX_DIO 1 // just only DO
53 #elif defined(CONFIG_ARCH_W321) || defined(CONFIG_ARCH_W311) || defined(CONFIG_ARCH_w325) || defined(CONFIG_ARCH_W315) || defined(CONFIG_UC_7112_LX_PLUS)
63 #define IOCTL_DIO_GET_MODE 1
64 #define IOCTL_DIO_SET_MODE 2
65 #define IOCTL_DIO_GET_DATA 3
66 #define IOCTL_DIO_SET_DATA 4
67 #define IOCTL_SET_DOUT 15
68 #define IOCTL_GET_DOUT 16
69 #define IOCTL_GET_DIN 17
70 struct dio_set_struct
{
72 int mode_data
; // 1 for input, 0 for output, 1 for high, 0 for low
76 struct proc_dir_entry
* dio_proc
;
77 #define dio_proc_name "driver/dio"
79 int dio_read_proc(char *page
, char **start
, off_t off
, int count
, int *eof
, void *data
)
84 for ( pin_count
= 0 ; pin_count
< MAX_GPIO
; pin_count
++ )
85 out
+= sprintf( out
,"PIN%d:%s:%s\n",pin_count
, mcpu_gpio_get_inout(1<<pin_count
)?"OUT":"IN", mcpu_gpio_get(1<<pin_count
)?"HIGH":"LOW");
87 len
= out
-page
- off
;
99 int dio_write_proc(struct file
*file
, const char __user
*buffer
, unsigned long count
, void *data
)
101 char kbuffer
[64], in_out_mode
[2], mode
[2], pin
[3];
102 int num_count
, var_num
, byte_count
;
104 if ( copy_from_user(kbuffer
, (char*)buffer
, count
) )
107 kbuffer
[count
+1] = '\0';
109 memset(in_out_mode
,0,2);
111 num_count
= var_num
= 0 ;
113 for ( byte_count
= 0 ; byte_count
< count
; byte_count
++ ) {
114 if ( kbuffer
[byte_count
] != ' ' && kbuffer
[byte_count
] != '\0' && kbuffer
[byte_count
] != '\n' ) {
115 if ( var_num
== 0 ) {
117 if ( num_count
> 2 ) {
118 printk("The max pin number is %d !!\n",MAX_GPIO
);
121 pin
[num_count
-1] = kbuffer
[byte_count
];
122 pin
[num_count
] = '\0';
125 if ( var_num
== 1 ) {
127 if ( num_count
> 1 ) {
128 printk("The in mode = 1 out mode = 0 !!\n");
131 in_out_mode
[num_count
-1] = kbuffer
[byte_count
];
132 in_out_mode
[num_count
] = '\0';
135 if ( var_num
== 2 ) {
137 if ( num_count
> 1 ) {
138 printk("The in mode = 1 out mode = 0 !!\n");
141 mode
[num_count
-1] = kbuffer
[byte_count
];
142 mode
[num_count
] = '\0';
146 if ( pin
[0] != 0 && in_out_mode
[0] == 0 ) {
150 if ( pin
[0]!= 0 && in_out_mode
[0] != 0 && mode
[0] == 0 ) {
157 num_count
= simple_strtol(pin
, NULL
, 0); // to keep pin number
158 var_num
= simple_strtol(in_out_mode
, NULL
, 0); // to keep in/out setting
159 byte_count
= simple_strtol(mode
, NULL
, 0); // to keep state setting
161 if ( num_count
>= MAX_GPIO
) {
162 //printk("The max pin number is %d !!\n",MAX_GPIO-1);
163 goto error_write_proc
;
166 if ( var_num
== MCPU_GPIO_OUTPUT
) {
167 mcpu_gpio_inout(1<<num_count
, MCPU_GPIO_OUTPUT
);
168 if ( byte_count
== DIO_HIGH
)
169 mcpu_gpio_set(1<<num_count
, MCPU_GPIO_HIGH
);
170 else if ( byte_count
== DIO_LOW
)
171 mcpu_gpio_set(1<<num_count
, MCPU_GPIO_LOW
);
173 goto error_write_proc
;
174 } else if ( var_num
== MCPU_GPIO_INPUT
) {
175 mcpu_gpio_inout(1<<num_count
, MCPU_GPIO_INPUT
);
177 //printk("OUTPUT = 1, INPUT = 0 !!\n");
178 goto error_write_proc
;
187 static int dio_ioctl(struct inode
*inode
, struct file
*file
, unsigned int cmd
, unsigned long arg
)
189 struct dio_set_struct set
;
191 #if defined(CONFIG_ARCH_W341) || defined(CONFIG_ARCH_W345) || defined(CONFIG_ARCH_W345_IMP1)
193 case IOCTL_SET_DOUT
:
194 if ( copy_from_user(&set
, (struct dio_set_struct
*)arg
, sizeof(struct dio_set_struct
)) )
196 if ( set
.io_number
< 0 || set
.io_number
>= MAX_DIO
)
198 if ( set
.mode_data
== DIO_HIGH
)
199 mcpu_gpio_set(1<<(set
.io_number
+DO_BASE_SHIFT
), MCPU_GPIO_HIGH
);
200 else if ( set
.mode_data
== DIO_LOW
)
201 mcpu_gpio_set(1<<(set
.io_number
+DO_BASE_SHIFT
), MCPU_GPIO_LOW
);
205 case IOCTL_GET_DOUT
:
206 if ( copy_from_user(&set
, (struct dio_set_struct
*)arg
, sizeof(struct dio_set_struct
)) )
208 if ( set
.io_number
< 0 || set
.io_number
>= MAX_DIO
)
210 if ( mcpu_gpio_get(1<<(set
.io_number
+DO_BASE_SHIFT
)) )
214 if ( copy_to_user((struct dio_set_struct
*)arg
, &set
, sizeof(struct dio_set_struct
)) )
221 #elif defined(CONFIG_ARCH_W321) || defined(CONFIG_ARCH_W311) || defined(CONFIG_ARCH_w325) || defined(CONFIG_ARCH_W315) || defined(CONFIG_UC_7112_LX_PLUS)
225 case IOCTL_SET_DOUT
:
226 if ( copy_from_user(&set
, (struct dio_set_struct
*)arg
, sizeof(struct dio_set_struct
)) )
228 if ( set
.io_number
< 0 || set
.io_number
>= MAX_DIO
)
230 if ( set
.mode_data
== DIO_HIGH
)
231 mcpu_gpio_set(1<<(set
.io_number
+DO_BASE_SHIFT
), MCPU_GPIO_HIGH
);
232 else if ( set
.mode_data
== DIO_LOW
)
233 mcpu_gpio_set(1<<(set
.io_number
+DO_BASE_SHIFT
), MCPU_GPIO_LOW
);
237 case IOCTL_GET_DOUT
:
239 if ( copy_from_user(&set
, (struct dio_set_struct
*)arg
, sizeof(struct dio_set_struct
)) )
241 if ( set
.io_number
< 0 || set
.io_number
>= MAX_DIO
)
243 if ( cmd
== IOCTL_GET_DOUT
) {
244 if ( mcpu_gpio_get(1<<(set
.io_number
+DO_BASE_SHIFT
)) )
249 if ( mcpu_gpio_get(1<<(set
.io_number
+DI_BASE_SHIFT
)) )
254 if ( copy_to_user((struct dio_set_struct
*)arg
, &set
, sizeof(struct dio_set_struct
)) )
264 static int dio_open(struct inode
*inode
, struct file
*file
)
266 if ( MINOR(inode
->i_rdev
) == MOXA_DIO_MINOR
)
272 static int dio_release(struct inode
*inode
, struct file
*file
)
277 static struct file_operations dio_fops
= {
285 static struct miscdevice dio_dev
= {
291 static void __exit
dio_exit(void)
293 remove_proc_entry(dio_proc_name
,0);
294 misc_deregister(&dio_dev
);
297 static int __init
dio_init(void)
299 printk("Register IO misc ver1.0 ");
300 if ( misc_register(&dio_dev
) ) {
305 // set the CPU for GPIO
306 #if defined(CONFIG_ARCH_W341) || defined(CONFIG_ARCH_W345) || defined(CONFIG_ARCH_W345_IMP1)
307 mcpu_gpio_mp_set(GPIO_MASK
);
308 #elif defined(CONFIG_ARCH_W321) || defined(CONFIG_ARCH_W311) || defined(CONFIG_ARCH_w325) || defined(CONFIG_ARCH_W315) || defined(CONFIG_UC_7112_LX_PLUS)
311 mcpu_gpio_mp_set(GPIO_MASK
);
314 // default set all GPIO for input/ouput
315 #if defined(CONFIG_ARCH_W341) || defined(CONFIG_ARCH_W345) || defined(CONFIG_ARCH_W345_IMP1)
316 mcpu_gpio_inout(DO_MASK
, MCPU_GPIO_OUTPUT
);
317 #elif defined(CONFIG_ARCH_W321) || defined(CONFIG_ARCH_W311) || defined(CONFIG_ARCH_w325) || defined(CONFIG_ARCH_W315) || defined(CONFIG_UC_7112_LX_PLUS)
320 mcpu_gpio_inout(DI_MASK
, MCPU_GPIO_INPUT
);
321 mcpu_gpio_inout(DO_MASK
, MCPU_GPIO_OUTPUT
);
324 dio_proc
= create_proc_entry(dio_proc_name
, 0, NULL
);
325 dio_proc
->read_proc
= dio_read_proc
;
326 dio_proc
->write_proc
= dio_write_proc
;
332 module_init(dio_init
);
333 module_exit(dio_exit
);
335 MODULE_AUTHOR("Victor Yu");
336 MODULE_LICENSE("GPL");