nseekable_open(inode, filp);
if (ret >= 0)
{
init_keybuffer();
enable_irqs();
}
return ret;
}
/*
*功能: 关闭文件, 屏蔽中断
*入口:
*
*/
static int button_release(struct inode *inode,struct file *filp)
{
disable_irqs();
return 0;
}
/*
*功能: 读键盘
*入口:
*
*/
static ssize_t button_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
ssize_t ret = 0;
remove_timeoutkey();
spin_lock_irq(&buffer_lock);
while((g_keyBuffer.head != g_keyBuffer.tail) && (((size_t)ret) < count) )
{
buffer[ret] = (char)(g_keyBuffer.buf[g_keyBuffer.head]);
g_keyBuffer.buf[g_keyBuffer.head] = 0;
g_keyBuffer.jiffy[g_keyBuffer.head] = 0;
g_keyBuffer.head ++;
g_keyBuffer.head &= (MAX_KEY_COUNT -1);
ret ++;
}
spin_unlock_irq(&buffer_lock);
return ret;
}
/*
*功能: 清空键盘缓冲区
*入口:
*
*/
static int button_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
init_keybuffer();
return 1;
}
/*
*初始化并添加结构提struct cdev到系统之中
*/
static void led_setup_cdev(struct cdev *dev,int minor,struct file_operations *fops)
{
int err;
int devno=MKDEV(button_major,minor);
cdev_init(dev,fops);//初始化结构体struct cdev
dev->owner=THIS_MODULE;
dev->ops=fops;//给结构体里的ops成员赋初值,这里是对设备操作的具体的实现函数
err=cdev_add(dev,devno,1);//将结构提struct cdev添加到系统之中
if(err)
printk(KERN_INFO"Error %d adding button %d\n",err,minor);
}
/*
*定义一个file_operations结构体,来实现对设备的具体操作的功能
*/
static struct file_operations button_fops =
{
.owner = THIS_MODULE,
.ioctl = button_ioctl,
.open = button_open,
.read = button_read,
.release = button_release,
};
static struct cdev SimpleDevs; //add by yoyo
/*
*功能: 驱动初始化
*入口:
*
*/
static int button_init(void)
{
int ret;
int result; //add by yoyo
gpecon = ioremap(0x56000040, 0x04);//得到相应IO口的虚拟地址,下同
gpedat = ioremap(0x56000044, 0x04);
gpfcon = ioremap(0x56000050, 0x04);
gpfdat = ioremap(0x56000054, 0x04);
gpgcon = ioremap(0x56000060, 0x04);
gpgdat = ioremap(0x56000064, 0x04);
init_gpio();
ret = request_irqs();
if (ret < 0) return ret;
disable_irqs();
//add by yoyo
dev_t dev=MKDEV(button_major,0);//将主设备号和次设备号定义到一个dev_t数据类型的结构体之中
if(button_major)
result=register_chrdev_region(dev,1,"button");//静态注册一个设备,设备号先前指定好,并得到一个设备名,cat /proc/device来查看信息
else
{
result=alloc_chrdev_region(&dev,0,1,"button");//如果主设备号被占用,则由系统提供一个主设备号给设备驱动程序
button_major=MAJOR(dev);//得到主设备号
}
if(result<0)
{
printk(KERN_WARNING"button:unable to get major %d\n",button_major);
return result;
}
if(button_major==0)
button_major=result;//如果静态分配失败。把动态非配的设备号给设备驱动程序
printk(KERN_INFO"button register ok!!!!!!!!!!\n");
led_setup_cdev(&SimpleDevs,0,&button_fops);//初始化和添加结构体struct cdev到系统之中
//return 0;
printk("button initialized.\n");
return 0;
}
/*
*功能: 驱动释放
*入口:
*
*/
static void __exit button_exit(void)
{
disable_irqs();
free_irqs();
iounmap(gpecon);
iounmap( gpedat);
iounmap(gpfcon);
iounmap(gpfdat);
iounmap(gpgcon);
iounmap(gpgdat);
cdev_del(&SimpleDevs);//删除结构体struct cdev
printk("button_major=%d\n",button_major);
unregister_chrdev_region(MKDEV(button_major,0),1);//卸载设备驱动所占有的资源
printk("button