📄 fgpio.c
字号:
/* GPIO Push Button driver by ivan wang */#include <linux/module.h>#include <linux/config.h>#include <linux/sched.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/spinlock.h>#include <linux/proc_fs.h>#include <linux/synclink.h>#include <asm/uaccess.h>#include <linux/miscdevice.h>#include "gpio.h"MODULE_AUTHOR("GM Corp.");MODULE_LICENSE("GM License");int GPIO_VA_BASE = GPIO_FTGPIO010_0_VA_BASE;static int gpio_open(struct inode *inode, struct file *file){ return 0;}static int gpio_release(struct inode *inode, struct file *file){ return 0;}void set_data_output(u_int group, u_int ctrl_pin, u_int data){ unsigned int tmp1=0; if(group) GPIO_VA_BASE = GPIO_FTGPIO010_1_VA_BASE; else GPIO_VA_BASE = GPIO_FTGPIO010_0_VA_BASE; tmp1 = *(volatile unsigned int *)(GPIO_VA_BASE); *(volatile unsigned int *)(GPIO_VA_BASE)= data | (tmp1 & (~ctrl_pin));}EXPORT_SYMBOL(set_data_output);u_int read_data_output(u_int group, u_int ctrl_pin){ if(group) GPIO_VA_BASE = GPIO_FTGPIO010_1_VA_BASE; else GPIO_VA_BASE = GPIO_FTGPIO010_0_VA_BASE; return (*(volatile unsigned int *)(GPIO_VA_BASE) & ctrl_pin);}EXPORT_SYMBOL(read_data_output);u_int read_data_input(u_int group, u_int ctrl_pin){ if(group) GPIO_VA_BASE = GPIO_FTGPIO010_1_VA_BASE; else GPIO_VA_BASE = GPIO_FTGPIO010_0_VA_BASE; return (*(volatile unsigned int *)(GPIO_VA_BASE + 0x4) & ctrl_pin);}EXPORT_SYMBOL(read_data_input);void set_data_direct(u_int group, u_int ctrl_pin, u_int data){ unsigned int tmp1=0; if(group) GPIO_VA_BASE = GPIO_FTGPIO010_1_VA_BASE; else GPIO_VA_BASE = GPIO_FTGPIO010_0_VA_BASE; tmp1 = *(volatile unsigned int *)(GPIO_VA_BASE + 0x8); *(volatile unsigned int *)(GPIO_VA_BASE + 0x8)= data | (tmp1 & (~ctrl_pin));}EXPORT_SYMBOL(set_data_direct);u_int read_data_direct(u_int group, u_int ctrl_pin){ if(group) GPIO_VA_BASE = GPIO_FTGPIO010_1_VA_BASE; else GPIO_VA_BASE = GPIO_FTGPIO010_0_VA_BASE; return (*(volatile unsigned int *)(GPIO_VA_BASE + 0x8) & ctrl_pin);}EXPORT_SYMBOL(read_data_direct);void int_clear(u_int group, u_int data){ if(group) GPIO_VA_BASE = GPIO_FTGPIO010_1_VA_BASE; else GPIO_VA_BASE = GPIO_FTGPIO010_0_VA_BASE; *(volatile unsigned int *)(GPIO_VA_BASE + 0x30)= data;}EXPORT_SYMBOL(int_clear);void set_int(u_int group, u_int ctrl_pin, u_int data){ unsigned int tmp1=0; if(group) GPIO_VA_BASE = GPIO_FTGPIO010_1_VA_BASE; else GPIO_VA_BASE = GPIO_FTGPIO010_0_VA_BASE; #ifdef CONFIG_PLATFORM_GM8185 //pin mux with PCI slot 3 issue if((group == 0) && ((ctrl_pin & BIT6) != 0)) * (volatile unsigned int *) (PMU_FTPMU010_VA_BASE+0x100) &= 0xFFFFCFFF; if((group == 0) && ((ctrl_pin & BIT7) != 0)) * (volatile unsigned int *) (PMU_FTPMU010_VA_BASE+0x104) &= 0xFFFF3FFF; #endif tmp1 = *(volatile unsigned int *)(GPIO_VA_BASE + 0x20); *(volatile unsigned int *)(GPIO_VA_BASE + 0x20)= data | (tmp1 & (~ctrl_pin));}EXPORT_SYMBOL(set_int);void set_int_func(void *tmp){ unsigned int tmp1=0,tmp2=0,tmp3=0; gpio_params *gm; gm=tmp; if(gm->group) GPIO_VA_BASE = GPIO_FTGPIO010_1_VA_BASE; else GPIO_VA_BASE = GPIO_FTGPIO010_0_VA_BASE; tmp1 = *(volatile unsigned int *)(GPIO_VA_BASE + 0x34); tmp2 = *(volatile unsigned int *)(GPIO_VA_BASE + 0x38); tmp3 = *(volatile unsigned int *)(GPIO_VA_BASE + 0x3C); *(volatile unsigned int *)(GPIO_VA_BASE + 0x34)= (gm->int_trigger) | (tmp1 & (~gm->ctrl_pin)); *(volatile unsigned int *)(GPIO_VA_BASE + 0x38)= (gm->int_both) | (tmp1 & (~gm->ctrl_pin)); *(volatile unsigned int *)(GPIO_VA_BASE + 0x3C)= (gm->int_riseneg) | (tmp1 & (~gm->ctrl_pin)); }EXPORT_SYMBOL(set_int_func);static int gpio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ gpio_params gm; switch (cmd) { case GPIO_SET_DATA_OUTPUT: if (copy_from_user (&gm, (struct rtc_time*)arg, 3*sizeof(u_int))) return -EFAULT; set_data_output(gm.group,gm.ctrl_pin,gm.data_out); return 0; case GPIO_READ_DATA_INPUT: if (copy_from_user (&gm, (struct rtc_time*)arg, sizeof(u_int))) return -EFAULT; gm.data_in = read_data_input(gm.group,gm.ctrl_pin); copy_to_user ((void *)arg, &gm, 4*sizeof(u_int)); return 0; case GPIO_SET_DATA_DIRECT: if (copy_from_user (&gm, (struct rtc_time*)arg, 6*sizeof(u_int))) return -EFAULT; set_data_direct(gm.group,gm.ctrl_pin,gm.data_direct); return 0; case GPIO_SET_INT: if (copy_from_user (&gm, (struct rtc_time*)arg, 7*sizeof(u_int))) return -EFAULT; set_int(gm.group,gm.ctrl_pin,gm.int_enable); return 0; case GPIO_SET_INT_FUNC: if (copy_from_user (&gm, (struct rtc_time*)arg, sizeof(gm))) return -EFAULT; set_int_func(&gm); return 0; case GPIO_CLEAR_INT: if (copy_from_user (&gm, (struct rtc_time*)arg, 5*sizeof(u_int))) return -EFAULT; int_clear(gm.group,gm.int_clear); return 0; default: printk("GPIO ioctl function error\n"); return -EINVAL; }}static const struct file_operations gpio_fops = { .owner=THIS_MODULE, .ioctl=gpio_ioctl, .open=gpio_open,};static struct miscdevice fgpio_miscdev = { .minor = MISC_DYNAMIC_MINOR, .name = "gpio", .fops = &gpio_fops,};static int __init fgpio_init(void){ int ret; ret = misc_register(&fgpio_miscdev); if (ret < 0) { printk(KERN_ERR "tlclk: misc_register returns %d.\n", ret); return ret; } return 0;}static void __exit fgpio_exit(void){ misc_deregister (&fgpio_miscdev);}module_init(fgpio_init);module_exit(fgpio_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -