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

📄 gpio.c.bak

📁 DM355的GPIO驱动
💻 BAK
字号:
/* Authors:Lijialin
 *
 * Description:
 *				GPIO的实现
 *
 * Modification History:
 *        
 *
 */
 

#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/init.h>

#include <linux/ioctl.h>


#include <linux/string.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/major.h>
#include <linux/miscdevice.h>
#include <linux/devfs_fs_kernel.h>

#include <asm/io.h>
#include <asm/system.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <linux/kmydebug.h>

#include "gpio.h"


#define DM355_GPIO_NR		125    //主设备编号(待定)


#define GPIO_DIR_IN 1

static unsigned long gpio_reg_base; //GPIO的虚拟地址空间

/*打开函数*/
static int dm355_gpio_dev_open(struct inode *inode, struct file *file)
{
	MOD_INC_USE_COUNT; //是一条必须的语句(待考)
	return 0;	 /*success*/
}


/*关闭函数*/
static int dm355_gpio_dev_release(struct inode *inode, struct file *file)
{
	MOD_DEC_USE_COUNT; //和open函数中的相对应
	return 0;	
}

/*ioctl函数*/
static int gpio_dev_ioctl(struct inode *inode, struct file *file,	unsinged int cmd, unsingned long arg)
{
	int num;
	volatile u32 *Reg; //存放没个BANK段的基址
	//u32 temp1, temp2;
	
	
	num = MINOR(inode->i_rdev); //打开文件所对应的i节点,对驱动程序来说是获取从设备号
															//num其实范围是0,1,2,3
															//         bank01,23,45,6
	
	/*计算4个BANK段的基址*/
	//**这个的变量需要改动,这个很重要
	Reg = (volatile u32 *)(GPIO_ADDR_BASE + GPIO_PORT_ADD * num);
	
	switch(cmd)
	{
		
		case GPIO_SET_PIN: //SET_DATAn
				if(arg < 32)
				 {
				 	Reg[GPIO_SET_OFFSET] = 1u << arg; //这里是按一个偏移量计算的
				 }
				break;
				
		case GPIO_CLR_PIN: //CLR_DATAn
				if(arg < 32)
					{
						Reg[GPIO_CLR_OFFSET] = 1u << arg;
					}
				break;
					
		case GPIO_SET_PIN_OUT: //OUT_DATAn
				if(arg < 32)
					{
						Reg[GPIO_DIR_OFFSET] &= ~(1u << arg);    //置0
					}
				break;
		case GPIO_SET_PIN_IN:  //IN_DATAn
				if(arg < 32)
					{
						Reg[GPIO_DIR_OFFSET] |= 1u << arg;      //置1
					}
				break;
		
		
		
		
		
		
		default:
				return -ENOTTY;
				break;
		
				
	}
	return 0;
}


/*file_operation结构体*/
static struct file_operations gpio_fops = {
	.owner = NULL,
	.llseek = no_llseek,
	.ioctl = dm355_gpio_dev_ioctl,	
	.open = dm355_gpio_dev_open,
	.release = dm355_gpio_dev_release,
};
//定义结构体miscdevice
static struct miscdevice gpio_miscdev  = {
	.minor=GPIO_MINOR,
	.name="dm355 gpio",
	.fops=&gpio_fops,
};


static int gpio_register_dev(void)
{	int ret;		ret = misc_register(&gpio_miscdev);
	if (ret) {		mydbg(1, "cannot register miscdev on minor=%d (err=%d)\n", gpio_miscdev .minor, ret);
		return ret;
	}
	
	devfs_mk_dir("misc");	devfs_mk_cdev(MKDEV(MISC_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR, "misc/gpio-%d", GPIO_MINOR);
	
	return ret;}

//注销GPIO设备寄存器
static void gpio_unregister_dev(void)
{	misc_deregister(&gpio_miscdev );
}

/*初始化函数*/
static int __init dm355_gpio_init(void)
{
	mydbg(2, "misc: gpio support init\n");

	// ioremap GPIO registers	
	//GPIO寄存器的IO地址	
	gpio_reg_base = (unsigned long) ioremap(GPIO_BASE, GPIO_SPACE_LEN);
	if (!gpio_reg_base) {
		mydbg(2, "fail to ioremap\n");
		return -ENOMEM;
	}
	
	gpio_register_dev();
	
	// todo: put this elsewhere???
	/*
	mydbg(8, "set pin28 as uart\n");
	gpio_function_select(28, GPIO_AS_ALT);
	*/

	return 0;
}

/*退出函数*/
static void __exit dm355_gpio_exit(void)
{
	gpio_unregister_dev();
	// iounmap GPIO registers
	//释放GPIO寄存器的IO
	if(gpio_reg_base)
		iounmap((void*)gpio_reg_base);	
}

core_initcall(dm355_gpio_init);



/*void __init dm355_init_gpio(int gpio_nr)
{
	
}*/






MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -