#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MEMDEV_IOC_MAGIC 'y' #define IOCTRL_GPIO_IN _IO(MEMDEV_IOC_MAGIC,1) #define IOCTRL_GPIO_OUT _IO(MEMDEV_IOC_MAGIC,2) #define IOCTRL_GPIO_REQ _IO(MEMDEV_IOC_MAGIC,3) #define IOCTRL_GPIO_FRE _IO(MEMDEV_IOC_MAGIC,4) #define SYS_MOD_CTL0 0xBC04A008 #define GPIO_EN (1<<27) #define SYS_IOMUX_CFG0 0xBC04A0B0 #define GPIO_BASE 0xBC110000 #define GPIO_SWPORTA_DR (0x0 + GPIO_BASE) #define GPIO_SWPORTA_DDR (0x04 + GPIO_BASE) #define GPIO_SWPORTB_DR (0x0c + GPIO_BASE) #define GPIO_SWPORTB_DDR (0x10 + GPIO_BASE) #define GPIO_SWPORTC_DR (0x18 + GPIO_BASE) #define GPIO_SWPORTC_DDR (0x1C + GPIO_BASE) struct gsc3280_gpio{ short int pin; short int data; }; static int special_gpio_open(struct inode *inode, struct file *file) { return 0; } static int special_gpio_close(struct inode *inode, struct file *file){ return 0; } static ssize_t special_gpio_read(struct file *file, char __user *buf, size_t count, loff_t *ptr){ return 0; } static ssize_t special_gpio_write(struct file *filp, const char __user *buf, size_t count, loff_t *ptr){ return 0; } static long special_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg){ struct gsc3280_gpio *dev ; dev = (struct gsc3280_gpio *)arg; *(volatile unsigned int*)SYS_MOD_CTL0 |= GPIO_EN; switch(cmd){ case IOCTRL_GPIO_REQ: if((dev->pin > 0 || 0 == dev->pin ) && dev->pin <88 ){ gpio_request(dev->pin,NULL); } break; case IOCTRL_GPIO_OUT: if((dev->pin > 0 || 0 == dev->pin ) && dev->pin <88 ) { if(dev->data > 0) gpio_direction_output(dev->pin,1); else gpio_direction_output(dev->pin,0); } break; case IOCTRL_GPIO_IN: if((dev->pin > 0 || 0 == dev->pin ) && dev->pin <88 ) { gpio_direction_input(dev->pin); dev->data=gpio_get_value(dev->pin); } break; case IOCTRL_GPIO_FRE: if((dev->pin > 0 || 0 == dev->pin ) && dev->pin <88 ){ gpio_free(dev->pin); } break; default: printk(KERN_INFO"cmd error!!!\n"); break; } return 0; } static const struct file_operations special_gpio_ops = { .owner = THIS_MODULE, .open = special_gpio_open, .read = special_gpio_read, .write = special_gpio_write, .release = special_gpio_close, .unlocked_ioctl = special_gpio_ioctl, }; static struct miscdevice special_gpio_miscdev = { .minor = MISC_DYNAMIC_MINOR, .name = "3280_GPIO", .fops = &special_gpio_ops, }; static int special_gpio_init(void){ printk(KERN_INFO"%s\n",__func__); if (misc_register(&special_gpio_miscdev)){ printk(KERN_ALERT"Couldn't register device 0, %d.\n", 255); return -EBUSY; } return 0; } static void special_gpio_exit(void){ printk(KERN_INFO"%s\n",__func__); misc_deregister(&special_gpio_miscdev); } module_init(special_gpio_init); module_exit(special_gpio_exit); MODULE_LICENSE("GPL");