MOXA linux-2.6.x / linux-2.6.19-uc1 from UC-7110-LX-BOOTLOADER-1.9_VERSION-4.2.tgz
[linux-2.6.19-moxart.git] / drivers / char / gpio.c-bak-07312007
blob4db0b6c0db7110ecc89f25535046adc24ba6618b
1 /*
2  * pio:         104
3  *
4  * History:
5  * Date         Aurhor                  Comment
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.
9  */
10 #if 1   // add by Victor Yu. 02-09-2007
11 #include <linux/version.h>
12 #endif
13 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) // add by Victor Yu. 02-09-2007
14 #include <linux/config.h>
15 #endif
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>
31 #include <asm/io.h>
32 #include <asm/uaccess.h>
33 #include <asm/system.h>
35 #define MOXA_PIO_MINOR          104
37 static spinlock_t               pio_lock=SPIN_LOCK_UNLOCKED;
39 // GPIO register offset on Moxa CPU
40 #define GPIO_DATA_OUT           0
41 #define GPIO_DATA_IN            4
42 #define GPIO_PIN_DIR            8
43 #define GPIO_DATA_SET           0x10
44 #define GPIO_DATA_CLEAR         0x14
45 #define GPIO_PIN_PULL_ENABLE    0x18
46 #define GPIO_PIN_PULL_TYPE      0x1C
47 #define GPIO_INT_ENABLE         0x20
48 #define GPIO_INT_RAW_STATE      0x24
49 #define GPIO_INT_MASKED_STATE   0x28
50 #define GPIO_INT_MASK           0x2C
51 #define GPIO_INT_CLEAR          0x30
52 #define GPIO_INT_TRIGGER        0x34
53 #define GPIO_INT_BOTH           0x38
54 #define GPIO_INT_RISE_NEG       0x3C
55 #define GPIO_BOUNCE_ENABLE      0x40
56 #define GPIO_BOUNCE_PRE_SCALE   0x44
58 #define GPIO_BASE_SHIFT         10
59 //#define GPIO_MASK             (0xffff<<GPIO_BASE_SHIFT)
60 #define GPIO_MASK               (0x3ff<<GPIO_BASE_SHIFT)
62 typedef struct _gpio_reg_struct {
63         unsigned int    data_out;
64         unsigned int    data_in;
65         unsigned int    pin_dir;
66         unsigned int    reserved;
67         unsigned int    data_set;
68         unsigned int    data_clear;
69         unsigned int    pin_pull_enable;
70         unsigned int    pin_pull_type;
71         unsigned int    int_enable;
72         unsigned int    int_raw_state;
73         unsigned int    int_masked_state;
74         unsigned int    int_mask;
75         unsigned int    int_clear;
76         unsigned int    int_trigger;
77         unsigned int    int_both;
78         unsigned int    int_rise_neg;
79         unsigned int    bounce_enable;
80         unsigned int    bounce_pre_scale;
81 } gpio_reg_struct;
82 static gpio_reg_struct  *gpio_reg=(gpio_reg_struct *)CPE_GPIO_BASE;
85 // PIO file operaiton function call
87 #define MAX_PIO                 10
88 #define PIO_INPUT               1
89 #define PIO_OUTPUT              0
90 #define PIO_HIGH                1
91 #define PIO_LOW                 0
92 #define PIO_BASE                3
93 #define IOCTL_PIO_GET_MODE      1
94 #define IOCTL_PIO_SET_MODE      2
95 #define IOCTL_PIO_GET_DATA      3
96 #define IOCTL_PIO_SET_DATA      4
97 struct pio_set_struct {
98         int     io_number;
99         int     mode_data;      // 1 for input, 0 for output, 1 for high, 0 for low
102 static int pio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
104         struct pio_set_struct   set;
106         switch ( cmd ) {
107         case IOCTL_PIO_SET_MODE :
108                 if ( copy_from_user(&set, (struct pio_set_struct *)arg, sizeof(struct pio_set_struct)) )
109                         return -EFAULT;
110                 if ( set.io_number < 0 || set.io_number > MAX_PIO )
111                         return -EINVAL;
112                 if ( set.mode_data == PIO_INPUT )
113                         writel(readl(&gpio_reg->pin_dir)&~(1<<(set.io_number+GPIO_BASE_SHIFT)), &gpio_reg->pin_dir);
114                 else if ( set.mode_data == PIO_OUTPUT )
115                         writel(readl(&gpio_reg->pin_dir)|(1<<(set.io_number+GPIO_BASE_SHIFT)), &gpio_reg->pin_dir);
116                 else
117                         return -EINVAL;
118                 break;
119         case IOCTL_PIO_GET_MODE :
120                 if ( copy_from_user(&set, (struct pio_set_struct *)arg, sizeof(struct pio_set_struct)) )
121                         return -EFAULT;
122                 if ( set.io_number < 0 || set.io_number > MAX_PIO )
123                         return -EINVAL;
124                 if ( readl(&gpio_reg->pin_dir) & (1<<(set.io_number+GPIO_BASE_SHIFT)) )
125                         set.mode_data = 0;
126                 else
127                         set.mode_data = 1;
128                 if ( copy_to_user((struct pio_set_struct *)arg, &set, sizeof(struct pio_set_struct)) )
129                         return -EFAULT;
130                 break;
131         case IOCTL_PIO_SET_DATA :
132                 if ( copy_from_user(&set, (struct pio_set_struct *)arg, sizeof(struct pio_set_struct)) )
133                         return -EFAULT;
134                 if ( set.io_number < 0 || set.io_number > MAX_PIO )
135                         return -EINVAL;
136                 if ( set.mode_data == PIO_HIGH )
137                         writel(readl(&gpio_reg->data_out)|(1<<(set.io_number+GPIO_BASE_SHIFT)), &gpio_reg->data_out);
138                 else if ( set.mode_data == PIO_LOW )
139                         writel(readl(&gpio_reg->data_out)&~(1<<(set.io_number+GPIO_BASE_SHIFT)), &gpio_reg->data_out);
140                 else
141                         return -EINVAL;
142                 break;
143         case IOCTL_PIO_GET_DATA :
144                 if ( copy_from_user(&set, (struct pio_set_struct *)arg, sizeof(struct pio_set_struct)) )
145                         return -EFAULT;
146                 if ( set.io_number < 0 || set.io_number > MAX_PIO )
147                         return -EINVAL;
148                 if ( readl(&gpio_reg->data_in) & (1<<(set.io_number+GPIO_BASE_SHIFT)) )
149                         set.mode_data = 1;
150                 else
151                         set.mode_data = 0;
152                 if ( copy_to_user((struct pio_set_struct *)arg, &set, sizeof(struct pio_set_struct)) )
153                         return -EFAULT;
154                 break;
155         default:
156                 return -EINVAL;
157         }
158         return 0;
161 static int pio_open(struct inode *inode, struct file *file)
163         if ( MINOR(inode->i_rdev) == MOXA_PIO_MINOR )
164                 return 0;
165         return -ENODEV;
168 static int pio_release(struct inode *inode, struct file *file)
170         return 0;
173 static struct file_operations pio_fops = {
174         owner:THIS_MODULE,
175         llseek:NULL,
176         ioctl:pio_ioctl,
177         open:pio_open,
178         release:pio_release,
180 static struct miscdevice pio_dev = {
181         MOXA_PIO_MINOR,
182         "pio",
183         &pio_fops
186 static void __exit pio_exit(void)
188         spin_lock(&pio_lock);
189         misc_deregister(&pio_dev);
190         spin_unlock(&pio_lock);
193 #if 1   // add by Victor Yu. 03-08-2007
194 extern int      moxa_gpio_sd_used_flag; // define on arch/arm/kernel/armksyms.c
195 #endif
196 static int __init pio_init(void)
198         printk("Moxa CPU misc: Register PIO misc ver1.0 ");
199 #if 1   // add by Victor Yu. 03-08-2007
200         {
201         unsigned long   flags;
202         local_irq_save(flags);
203         if ( moxa_gpio_sd_used_flag ) {
204                 printk("The IO has used by other device driver !\n");
205                 local_irq_restore(flags);
206                 return -ENODEV;
207         }
208         moxa_gpio_sd_used_flag = 1;
209         local_irq_restore(flags);
210         }
211 #endif
212         if ( misc_register(&pio_dev) ) {
213                 printk("fail !\n");
214                 return -ENOMEM;
215         }
216         
217         // set the CPU for GPIO
218         *(volatile unsigned int *)(CPE_PMU_BASE+0x100) |= GPIO_MASK;
220         // default set all GPIO for input
221         writel(readl(&gpio_reg->pin_dir)&~GPIO_MASK, &gpio_reg->pin_dir);
223         // default set all GPIO interrupt disable
224         //writel(readl(&gpio_reg->int_enable)&~GPIO_MASK, &gpio_reg->int_enable);
226         // default set all GPIO pin pull disable 
227         writel(readl(&gpio_reg->pin_pull_enable)|GPIO_MASK, &gpio_reg->pin_pull_enable);
229         // default set all GPIO data_out high
230         writel(readl(&gpio_reg->data_out)|GPIO_MASK, &gpio_reg->data_out);
231         printk("OK.\n");
232         return 0;
235 module_init(pio_init);
236 module_exit(pio_exit);
238 MODULE_AUTHOR("Victor Yu");
239 MODULE_LICENSE("GPL");