⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fgpio.c

📁 一个在arm linux下的soc的gpio的驱动程序
💻 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 + -