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

📄 s3c2440_kb.c

📁 键盘驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
		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 + -