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

📄 irint2.c

📁 2440 下的5*5按键驱动程序.请参看具体代码内容.
💻 C
字号:
/********************************************************** * s3c2440-ts.c * * keyboard driver for S3C2440 based PDA * * * History: * * ***********************************************************/#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/miscdevice.h>#include <linux/sched.h>#include <linux/delay.h>#include <linux/poll.h>#include <linux/spinlock.h>#include <asm/irq.h>#include <asm/arch/irq.h>#include <asm/arch/irqs.h>#include <asm/arch/clocks.h>#include <asm/hardware.h>#include <asm/arch/S3C2440.h>#define DEVICE_NAME	"s3c2440-irint" //键盘设备名#define IRINT_MAJOR 96static int kbMajor = IRINT_MAJOR; //默认的主设备号static u_short eint2_value = 0;static u_short eint_number = 0;static int TimerCount = 0; //超时标志#define TIMER_DELAY  (HZ/50) /* 消都延时:1秒*/#define TIMEOUT 3static struct timer_list ring_timer;static  wait_queue_head_t wq ; //声明等待队列//spinlock_t repeat_lock;spinlock_t lock;  //声明自旋锁#define BLOCK	1#define NONBLOCK	0static u_int FileMode=NONBLOCK;//#define USE_ASYNC	1#undef USE_ASYNC#ifdef USE_ASYNCstatic 	struct fasync_struct *AsyncQueue =NULL;#endifstatic int requestIrq();#ifdef USE_ASYNCstatic int s3c2440_irint_fasync(struct inode *inode, struct file *filp, int mode){	return fasync_helper(inode, filp, mode, &AsyncQueue);}#endif/*----------------------------------------------------*  func:  读取eint2当前值*  param: *        *  return: if key is down, return 1; else 0*        ------------------------------------------------------*/int get_eint2_value(){		unsigned long IOValue;	  IOValue = GPFDAT ;		  if ( IOValue & 0x00000004)                 				return 0;		else			 	return 1;	}static inline void	timer_handler(unsigned long data){		if (!get_eint2_value())  /* if key is not down*/		{			  TimerCount=0;			  del_timer(&ring_timer);			  enableIrq();		}					TimerCount++;				if (TimerCount==TIMEOUT)		{					#ifdef USE_ASYNC						if(AsyncQueue)								kill_fasync(&(AsyncQueue), SIGIO, POLL_IN);				#endif 										eint2_value =1;  //来了中断,将其值置为1;				eint_number=eint_number+1;										printk("int coming %d\n",eint_number);				if(FileMode == BLOCK)  //如果是阻塞方式,唤醒在wq上的事件						wake_up_interruptible(&wq);				del_timer(&ring_timer);			  TimerCount=0;			  enableIrq();    }    else    {    	 	ring_timer.expires = jiffies + TIMER_DELAY;				add_timer(&ring_timer);    }	}/*static inline void	timer_handler(unsigned long data){#ifdef USE_ASYNC	if(AsyncQueue)	{//		if(eint2_value ==0)			kill_fasync(&(AsyncQueue), SIGIO, POLL_IN);	}#endif	eint2_value = 1;	TimeOut = 1;}*//*----------------------------------------------------*  func:  使能中断*  param: *  return: *                   ------------------------------------------------------*///使能中断static  void enableIrq(){	//清除SRCPND寄存器中eint2相应位	SRCPND= 0x00000004;		//使能中断	enable_irq(IRQ_EINT2);	}/*----------------------------------------------------*  func:  对应文件读的函数,如果循环队列中有键码,		  则将键码拷贝到用户空间的buffer中*  param: *        *  return: *         返回从循环队列中读取的键码的字节数**                   ------------------------------------------------------*/static ssize_tS3C2440_irint_read(struct file *filp, char *buffer, size_t count, loff_t * ppos){		//	printk("<0>,eint_number %d\n",eint_number);	if(FileMode == BLOCK)  //如果是阻塞方式	{		if (eint2_value ==0)    //如果没有数据		{			interruptible_sleep_on(&wq);   //一直睡眠等待			//			if(signal_pending(current))//				return -ERESTARTSYS;		}	}	count = sizeof(eint_number); 	copy_to_user(buffer,&eint_number,count); //将按键的值eint_number拷贝到用户空间	eint2_value =0; //数据读完后,再次清除	return count;	}/*----------------------------------------------------*  func:  与打开文件对应的open函数,初始化全局变量和定*         时器以及请求中断*  param: *        **  return: *                   ------------------------------------------------------*/static int S3C2440_irint_open(struct inode *inode, struct file *filp){	//  printk("<0> open\n");	if(filp->f_flags & O_NONBLOCK)	{		FileMode = NONBLOCK;	}	else	{		FileMode = BLOCK;	}	//初始化定时器//	init_timer(&ring_timer);//	ring_timer.function = timer_handler;//	lock = SPIN_LOCK_UNLOCKED;//	init_waitqueue_head(&wq);  //sjw//	enableIrq();	MOD_INC_USE_COUNT;	return 0;}static int s3c2440_irint_release(struct inode *inode, struct file *filp){//	disable_irq(IRQ_EINT2);	#ifdef  USE_ASYNC	s3c2440_irint_fasync(inode,filp,0);	#endif	printk("release device\n");	MOD_DEC_USE_COUNT;	return 0;}static struct file_operations ring_fops = {      owner:	THIS_MODULE,      open:	    S3C2440_irint_open,      read:	    S3C2440_irint_read,      release:	s3c2440_irint_release,#ifdef USE_ASYNC      fasync:	s3c2440_irint_fasync,#endif};/*----------------------------------------------------*  func:  中断处理程序,关闭中断,开启键盘扫描定时器*  param: *        **  return: *                   ------------------------------------------------------*/static void irint_interrupt(int irq, void *dev_id, struct pt_regs *regs){   		spin_lock_irq(&lock);	disable_irq(IRQ_EINT2);//	printk("<0>,interrupt is coming\n");/*#ifdef USE_ASYNC	if(AsyncQueue)	{	//	  if(eint2_value ==0)			kill_fasync(&(AsyncQueue), SIGIO, POLL_IN);	}	#endif*/	//	eint2_value =1;  //来了中断,将其值置为1;//	eint_number=eint_number+1;////	if(FileMode == BLOCK)  //如果是阻塞方式,唤醒在wq上的事件//		wake_up_interruptible(&wq);/*	if(!TimeOut)	{		//printk("<0> interrupt\n");		del_timer(&ring_timer);	}*/		//启动定时器	TimerCount = 0;	ring_timer.expires = jiffies + TIMER_DELAY;	add_timer(&ring_timer);//  enableIrq();	spin_unlock_irq(&lock);}/*----------------------------------------------------*  func:  初始化eint2中断相关寄存器,安装中断处理程序*  param: *        **  return: *                   ------------------------------------------------------*/static int requestIrq(){	int ret;		ret = set_external_irq(IRQ_EINT2,EXT_FALLING_EDGE,GPIO_PULLUP_DIS);	if(ret)		goto eint_failed ;	ret = request_irq(IRQ_EINT2, irint_interrupt, SA_INTERRUPT,			  DEVICE_NAME, NULL);    	if(ret)		goto eint2_failed;		printk("requestIrq\n");	return 0;eint2_failed:	free_irq(IRQ_EINT2, NULL);eint_failed:	printk(DEVICE_NAME ": IRQ Requeset Error\n");	return ret;}/*----------------------------------------------------*  func: 初始化键盘驱动,注册字符设备*  param: *        **  return: 			>=0 : 初始化键盘驱动成功			<0: 失败*                   ------------------------------------------------------*/static int __init s3c2440_irint_init(void){	int ret;		/*注册设备*/	ret = register_chrdev(kbMajor, DEVICE_NAME, &ring_fops);	if(ret < 0) {		printk(DEVICE_NAME " can't get major number\n");		return ret;	}	eint_number=0;		printk("%s: major number=%d\n",DEVICE_NAME,kbMajor);		if(requestIrq() !=0)	{		unregister_chrdev(kbMajor, DEVICE_NAME);		return -1;	}		init_timer(&ring_timer);	ring_timer.function = timer_handler;	lock = SPIN_LOCK_UNLOCKED;	init_waitqueue_head(&wq);  //sjw	enableIrq();		//暂时禁止所有中断,等到open时再打开//	disable_irq(IRQ_EINT2);	return 0;}/*----------------------------------------------------*  func: 注销字符设备,释放中断*  param: *        **  return: 			*                   ------------------------------------------------------*/static void __exit s3c2440_irint_exit(void){		/*注销设备*/	unregister_chrdev(kbMajor, DEVICE_NAME);    /*释放中断*/  free_irq(IRQ_EINT2, NULL);}module_init(s3c2440_irint_init);module_exit(s3c2440_irint_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -