📄 gpio.c.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 + -