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

📄 interrupt.c

📁 键盘驱动程序
💻 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-Ring" //键盘设备名static int kbMajor = 0; //默认的主设备号static u_short Eint19_Value = 1;static int TimeOut = 0; //超时标志#define TIMER_DELAY  (6*HZ) /* 自动重复开始延时:1秒*/static struct timer_list ring_timer;static  wait_queue_head_t wq ; //声明等待队列//spinlock_t repeat_lock;spinlock_t lock;static u_int FileMode;#define BLOCK	1#define NONBLOCK	0#define USE_ASYNC	1#ifdef USE_ASYNCstatic 	struct fasync_struct *AsyncQueue =NULL;#endifstatic int requestIrq();#ifdef USE_ASYNCstatic int s3c2440_Ring_fasync(struct inode *inode, struct file *filp, int mode){	return fasync_helper(inode, filp, mode, &AsyncQueue);}#endif/*----------------------------------------------------*  func:  读取eint19当前值*  param: *        *  return: *        ------------------------------------------------------*//*int get_eint19_value(){	u_int IOValue;	IOValue = GPGDAT ;	IOValue &= 0xF7FF;	IOValue >>= 11;	return IOValue;	}*/static inline void	timer_handler(unsigned long data){#ifdef USE_ASYNC	if(AsyncQueue)	{		if(Eint19_Value ==0)			kill_fasync(&(AsyncQueue), SIGIO, POLL_HUP);	}#endif	Eint19_Value = 1;	TimeOut = 1;}/*----------------------------------------------------*  func:  使能中断*  param: *  return: *                   ------------------------------------------------------*///使能中断static  void enableIrq(){	//清除SRCPND寄存器中eint19相应位	SRCPND = 0x00000002;	//SRCPND= 0x00000020;	//使能中断	//enable_irq(IRQ_EINT1);	enable_irq(IRQ_EINT1);	}/*----------------------------------------------------*  func:  对应文件读的函数,如果循环队列中有键码,		  则将键码拷贝到用户空间的buffer中*  param: *        *  return: *         返回从循环队列中读取的键码的字节数**                   ------------------------------------------------------*/static ssize_tS3C2440_Ring_read(struct file *filp, char *buffer, size_t count, loff_t * ppos){			if(FileMode == BLOCK)	{		if (Eint19_Value ==1)		{			interruptible_sleep_on(&wq);						if(signal_pending(current))				return -ERESTARTSYS;		}	}	count = sizeof(Eint19_Value);	copy_to_user(buffer,&Eint19_Value,count);	return count;	}/*----------------------------------------------------*  func:  与打开文件对应的open函数,初始化全局变量和定*         时器以及请求中断*  param: *        **  return: *                   ------------------------------------------------------*/static int S3C2440_Ring_open(struct inode *inode, struct file *filp){	lock = SPIN_LOCK_UNLOCKED;  printk("<0> open\n");	if(filp->f_flags & O_NONBLOCK)	{		FileMode = BLOCK;	}	else	{		FileMode = NONBLOCK;	}	//初始化定时器	init_timer(&ring_timer);	ring_timer.function = timer_handler;	enableIrq();	MOD_INC_USE_COUNT;	return 0;}static int s3c2440_Ring_release(struct inode *inode, struct file *filp){	disable_irq(IRQ_EINT1);		s3c2440_Ring_fasync(inode,filp,0);		MOD_DEC_USE_COUNT;	return 0;}static struct file_operations ring_fops = {      owner:	THIS_MODULE,      open:	    S3C2440_Ring_open,      read:	    S3C2440_Ring_read,      release:	s3c2440_Ring_release,#ifdef USE_ASYNC      fasync:	s3c2440_Ring_fasync,#endif};/*----------------------------------------------------*  func:  中断处理程序,关闭中断,开启键盘扫描定时器*  param: *        **  return: *                   ------------------------------------------------------*/static void Ring_interrupt(int irq, void *dev_id, struct pt_regs *regs){   		//spin_lock_irq(&lock);	 printk("<0> interrupt\n");#ifdef USE_ASYNC	if(AsyncQueue)	{		  if(Eint19_Value ==1)			kill_fasync(&(AsyncQueue), SIGIO, POLL_IN);	}	#endif	Eint19_Value = -1;	if(FileMode == BLOCK)		wake_up_interruptible(&wq);	if(!TimeOut)	{		del_timer(&ring_timer);	}	//启动定时器	TimeOut = 0;	ring_timer.expires = jiffies + TIMER_DELAY;	add_timer(&ring_timer);	//spin_unlock_irq(&lock);}/*----------------------------------------------------*  func:  初始化eint19中断相关寄存器,安装中断处理程序*  param: *        **  return: *                   ------------------------------------------------------*/static int requestIrq(){	int ret;		ret = set_external_irq(IRQ_EINT1,EXT_FALLING_EDGE,GPIO_PULLUP_DIS);	if(ret)		goto eint_failed ;	ret = request_irq(IRQ_EINT1, Ring_interrupt, SA_INTERRUPT,			  DEVICE_NAME, NULL);    	if(ret)		goto eint19_failed;		printk("requestIrq\n");	return 0;eint19_failed:	free_irq(IRQ_EINT1, NULL);eint_failed:	printk(DEVICE_NAME ": IRQ Requeset Error\n");	return ret;}/*----------------------------------------------------*  func: 初始化键盘驱动,注册字符设备*  param: *        **  return: 			>=0 : 初始化键盘驱动成功			<0: 失败*                   ------------------------------------------------------*/static int __init s3c2440_Ring_init(void){	int ret;	/*注册设备*/	ret = register_chrdev(98, DEVICE_NAME, &ring_fops);	if(ret < 0) {		printk(DEVICE_NAME " can't get major number\n");		return ret;	}	printk("%s: major number=98\n",DEVICE_NAME);		kbMajor = ret;	if(requestIrq() !=0)	{		unregister_chrdev(kbMajor, DEVICE_NAME);		return -1;	}		//暂时禁止所有中断,等到open时再打开	//disable_irq(IRQ_EINT1);	return 0;}/*----------------------------------------------------*  func: 注销字符设备,释放中断*  param: *        **  return: 			*                   ------------------------------------------------------*/static void __exit s3c2440_Ring_exit(void){		/*注销设备*/	unregister_chrdev(kbMajor, DEVICE_NAME);    /*释放中断*/		free_irq(IRQ_EINT1, NULL);}module_init(s3c2440_Ring_init);module_exit(s3c2440_Ring_exit);

⌨️ 快捷键说明

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