📄 kbdriver.c~
字号:
#define __KERNEL__
#define MODULE
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <asm/uaccess.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/string.h>
#include <asm/bitops.h>
#include <asm/io.h>
#include <linux/errno.h>
#include <linux/tqueue.h>
#include <linux/wait.h>
#include <asm/irq.h>
#include <asm/arch/hardware.h>
#include <asm/arch/irqs.h>
#include <linux/devfs_fs_kernel.h>
#include "kbDriver.h"void cleanup_module(void);
int kbDriver_open(struct inode * inode, struct file * filp);
int kbDriver_release(struct inode * inode, struct file * filp);
ssize_t kbDriver_read(struct file * filp, char * buf, size_t count, loff_t * l);
ssize_t kbDriver_write(struct file * filp,const char * buf,size_t count,loff_t * l);unsigned int kbDriver_select(struct file *filp,struct poll_table_struct *wait);DECLARE_WAIT_QUEUE_HEAD(kb_wait);struct file_operations kbDriver_fops = {
open: kbDriver_open,
release: kbDriver_release,
poll: kbDriver_select, read: kbDriver_read,
write: kbDriver_write,};
int kbDriver_open(struct inode * inode, struct file * filp)
{
gpioc_base=ioremap_nocache(GPIOC,GPIOLEN); //get virtual address
BWSCON=((BWSCON&(0xfffff0ff))|(0x0));
BANKCON2=0x7ff0;
//键盘时钟初始化
GPECON = (GPECON)&(0x0fffffff);
GPEUP = (GPECON)&(0xffff3fff);
GPECON = (GPECON)|(0xa0000000);
GPEUP = (GPECON)|(0x0000c000);
CLKCON = (CLKCON)& (0xfffeffff);
CLKCON = (CLKCON)| (0x00010000);
__REG(0x54000000) = 0x4f;
__REG(0x54000004) = 0xf0;
// IICCON = 0x4f;
// IICSTAT = 0xf0;
MOD_INC_USE_COUNT;
return 0;
}
int kbDriver_release(struct inode * inode,struct file * filp)
{
iounmap(gpioc_base);
MOD_DEC_USE_COUNT; cleanup_module();
return 0;
}
ssize_t kbDriver_read(struct file * filp, char * buf, size_t count, loff_t * l)
{
if(!keyIntFlag) return -EAGAIN; *buf=*(gpioc_base);
keyIntFlag=0;
return 0;
}
ssize_t kbDriver_write(struct file * filp, const char * buf, size_t count, loff_t * l)
{
return 0;
}unsigned int kbDriver_select(struct file *filp,struct poll_table_struct *wait)
{
if(keyIntFlag)
return 1;
poll_wait(filp, &kb_wait, wait);
return 0;
}
void key_irq_handler(int irq,void *dev_id,struct pt_regs *regs){
disable_irq(2);
keyIntFlag=1; wake_up_interruptible(&kb_wait);
enable_irq(2);
}
int init_module(void){
unsigned int result = 0;
result = register_chrdev(CHARDRIVER_MAJOR, CHARDRIVER_NAME, &kbDriver_fops);
if (result < 0){
unregister_chrdev(CHARDRIVER_MAJOR,CHARDRIVER_NAME);
return result;
}else{
if(set_external_irq(2,2,1)){
return -1;
}
if(request_irq(
2,
key_irq_handler,
SA_INTERRUPT,
"key_irq_handler",
NULL)
){
return -1;
} printk(KERN_INFO "kb driver is ok!\n");
}
return 0;
}
void cleanup_module(void)
{
disable_irq(2);
free_irq(2,NULL);
unregister_chrdev(CHARDRIVER_MAJOR, CHARDRIVER_NAME);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -