📄 s3c2440_kb.c
字号:
if(key_changed()) { pre_keyboard_code = curr_keyboard_code; save_key_to_queue(pre_keyboard_code); //printk("KEY_DOWN:%d x=%d y =%d\n",timeCount,x,y); //设置自动重复开始延时定时器 /*repeat_timer.expires = jiffies + REPEAT_START_DELAY; add_timer(&repeat_timer);*/ } timeCount=1; memset(snap_keyboard_code,0,12*sizeof(u_short)); //curr_keyboard_code =0; kb_timer.expires = jiffies + KB_TIMER_DELAY; add_timer(&kb_timer); } else { //printk("snap_keyboard_code=%d, %d, %d, %d\n", snap_keyboard_code[3][0],snap_keyboard_code[3][1],snap_keyboard_code[3][2],snap_keyboard_code[3][3]); kb_timer.expires = jiffies + KB_TIMER_DELAY; add_timer(&kb_timer); //printk("timeCount:%d\n",timeCount); if (timeCount==TIME_OUT) //扫描5次后仍然没有得到稳定键值 { //复位计数器 timeCount=1; kbdev.keyStatus =KEY_UP; //使能中断 enableIrq(); //关闭定时器 del_timer(&kb_timer); del_timer(&repeat_timer); //printk("enable irq \n\n\n"); curr_keyboard_code = 0; pre_keyboard_code= 0 ; memset(snap_keyboard_code,0,12*sizeof(u_short)); } else timeCount++; } spin_unlock_irq(&(kbdev.lock)); }/*----------------------------------------------------* func: 从循环队列中读取按键的键码* param: * return: 按键的键码* ------------------------------------------------------*/static inline int kbRead(){ u_short keyvalue; spin_lock_irq(&(kbdev.lock)); keyvalue = BUF_TAIL; INCBUF(kbdev.tail ); spin_unlock_irq(&(tsdev.lock)); return keyvalue;}/*----------------------------------------------------* func: 对应文件读的函数,如果循环队列中有键码, 则将键码拷贝到用户空间的buffer中* param: * * return: * 返回从循环队列中读取的键码的字节数** ------------------------------------------------------*/static ssize_tS3C2440_kb_read(struct file *filp, char *buffer, size_t count, loff_t * ppos){ u_short keyvalue; if(kbdev.head == kbdev.tail) { return 0; } else { keyvalue = kbRead(); count = sizeof(keyvalue); /*将数据拷贝到用户空间*/ copy_to_user(buffer,&(keyvalue),count); return count; } }/*----------------------------------------------------* func: 与打开文件对应的open函数,初始化全局变量和定* 时器以及请求中断* param: * ** return: * ------------------------------------------------------*/static int S3C2440_kb_open(struct inode *inode, struct file *filp){ kbdev.keyStatus = KEY_UP; kbdev.head=kbdev.tail = 0; kbdev.lock = SPIN_LOCK_UNLOCKED; repeat_lock = SPIN_LOCK_UNLOCKED; output_giop(0); //初始化定时器 init_timer(&kb_timer); kb_timer.function = kb_timer_handler; //初始化重复按键定时器 init_timer(&repeat_timer); repeat_timer.function = repeat_timer_handler; /*if(requestIrq() !=0) return -1;*/ enableIrq(); MOD_INC_USE_COUNT; return 0;}static struct file_operations kb_fops = { owner: THIS_MODULE, open: S3C2440_kb_open, read: S3C2440_kb_read, release: s3c2440_kb_release,};/*----------------------------------------------------* func: 中断处理程序,关闭中断开启键盘扫描定时器* param: * ** return: * ------------------------------------------------------*/static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs){ spin_lock_irq(&kbdev.lock); //禁止所有中断 disable_irq(IRQ_EINT1); disable_irq(IRQ_EINT3); disable_irq(IRQ_EINT8); kbdev.irq = irq; //printk("irq=%d\n",kbdev.irq); //启动定时器 kb_timer.expires = jiffies + KB_TIMER_DELAY; add_timer(&kb_timer); repeat_timer.expires = jiffies + REPEAT_START_DELAY; add_timer(&repeat_timer); spin_unlock_irq(&kbdev.lock);}/*----------------------------------------------------* func: 初始化eint中断相关寄存器,安装中断处理程序* param: * ** return: * ------------------------------------------------------*/static int requestIrq(){ int ret; /* Enable interrupt */ //================================================== // irq: Linux中断号,与硬件中断号不同 // handle: 中断处理程序 // flag: SA_INTERRUPT指示这是个快速中断处理程序 // dev_id: 用于共享的中断信号线,通常设置成NULL //=================================================== ret = set_external_irq(IRQ_EINT1,EXT_FALLING_EDGE,GPIO_PULLUP_DIS); if(ret) goto eint_failed ; ret = request_irq(IRQ_EINT1, keyboard_interrupt, SA_INTERRUPT, DEVICE_NAME, NULL); if(ret) goto eint1_failed; ret = set_external_irq(IRQ_EINT8,EXT_FALLING_EDGE,GPIO_PULLUP_DIS); //EXT_LOWLEVEL if(ret) goto eint_failed; ret = request_irq(IRQ_EINT8, keyboard_interrupt, SA_INTERRUPT, DEVICE_NAME, NULL); if(ret) goto eint8_failed; ret = set_external_irq(IRQ_EINT3,EXT_FALLING_EDGE,GPIO_PULLUP_DIS); if(ret) goto eint_failed; ret = request_irq(IRQ_EINT3, keyboard_interrupt, SA_INTERRUPT, DEVICE_NAME, NULL); if(ret) goto eint3_failed; return 0;eint3_failed: free_irq(IRQ_EINT3, keyboard_interrupt);eint8_failed: free_irq(IRQ_EINT8, keyboard_interrupt);eint1_failed: free_irq(IRQ_EINT1, keyboard_interrupt);eint_failed: printk(DEVICE_NAME ": IRQ Requeset Error\n"); return ret;}static int s3c2440_kb_release(struct inode *inode, struct file *filp){ /*注销设备*/// unregister_chrdev(kbMajor, DEVICE_NAME); /*释放中断*//* free_irq(IRQ_EINT1,NULL); free_irq(IRQ_EINT8,NULL); free_irq(IRQ_EINT3,NULL); MOD_DEC_USE_COUNT;*/ return 0;}/*----------------------------------------------------* func: 初始化键盘驱动,注册字符设备* param: * ** return: >=0 : 初始化键盘驱动成功 <0: 失败* ------------------------------------------------------*/static int __init s3c2440_kb_init(void){ int ret; /*初始化管腿配置*/ init_gpjcon(); output_giop(0); /*注册设备*/ ret = register_chrdev(99, DEVICE_NAME, &kb_fops); if(ret < 0) { printk(DEVICE_NAME " can't get major number\n"); return ret; } kbMajor = ret; printk("%s: major number=99\n",DEVICE_NAME); requestIrq(); //暂时禁止所有中断,等到open时再打开 disable_irq(IRQ_EINT1); disable_irq(IRQ_EINT3); disable_irq(IRQ_EINT8); return 0;}/*----------------------------------------------------* func: 注销字符设备,释放中断* param: * ** return: * ------------------------------------------------------*/static void __exit s3c2440_kb_exit(void){ /*注销设备*/ unregister_chrdev(kbMajor, DEVICE_NAME); printk("exit\n"); /*释放中断*/ free_irq(IRQ_EINT1,NULL); free_irq(IRQ_EINT8,NULL); free_irq(IRQ_EINT3,NULL);}module_init(s3c2440_kb_init);module_exit(s3c2440_kb_exit);//EXPORT_SYMBOL(s3c2440_kb_init);//EXPORT_SYMBOL(s3c2440_kb_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -