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

📄 lirc_parallel.c

📁 很少见的linux下的红外口的工具
💻 C
📖 第 1 页 / 共 2 页
字号:
			schedule();			current->state=TASK_INTERRUPTIBLE;		}	}	remove_wait_queue(&lirc_wait,&wait);	current->state=TASK_RUNNING;	return(count ? count:result);}#ifdef KERNEL_2_2static ssize_t lirc_write(struct file *filep,const char *buf,size_t n,			  loff_t *ppos)#elsestatic int lirc_write(struct inode *node,struct file *filep,const char *buf,		      int n)#endif{	int result,count;	unsigned int i;	unsigned int level,newlevel;	unsigned long flags;	lirc_t counttimer;	#ifdef KERNEL_2_2	if(!is_claimed)	{		return(-EBUSY);	}#endif	if(n%sizeof(lirc_t)) return(-EINVAL);	result=verify_area(VERIFY_READ,buf,n);	if(result) return(result);		count=n/sizeof(lirc_t);		if(count>WBUF_SIZE || count%2==0) return(-EINVAL);	#ifdef KERNEL_2_2	copy_from_user(wbuf,buf,n);#else	memcpy_fromfs(wbuf,buf,n);	/*	  if(check_region(io,LIRC_PORT_LEN)!=0) return(-EBUSY);	*/#endif	#ifdef LIRC_TIMER	if(timer==0) /* try again if device is ready */	{		timer=init_lirc_timer();		if(timer==0) return(-EIO);	}	/* ajust values from usecs */	for(i=0;i<count;i++)	{		wbuf[i]=(lirc_t) (((double) wbuf[i])*timer/1000000);	}		save_flags(flags);cli();	i=0;	while(i<count)	{		level=lirc_get_timer();		counttimer=0;		lirc_on();		do		{			newlevel=lirc_get_timer();			if(level==0 && newlevel!=0) counttimer++;			level=newlevel;			if(in(1)&LP_PSELECD)			{				lirc_off();				restore_flags(flags); /* sti(); */				return(-EIO);			}		}		while(counttimer<wbuf[i]);i++;				lirc_off();		if(i==count) break;		counttimer=0;		do		{			newlevel=lirc_get_timer();			if(level==0 && newlevel!=0) counttimer++;			level=newlevel;			if(in(1)&LP_PSELECD)			{				restore_flags(flags); /* sti(); */				return(-EIO);			}		}		while(counttimer<wbuf[i]);i++;	}	restore_flags(flags); /* sti(); */#else	/* 	   place code that handles write	   without extarnal timer here	*/#endif	return(n);}#ifdef KERNEL_2_2static unsigned int lirc_poll(struct file *file, poll_table * wait){	poll_wait(file, &lirc_wait,wait);	if (rptr!=wptr)		return(POLLIN|POLLRDNORM);	return(0);}#elsestatic int lirc_select(struct inode *node,struct file *file,int sel_type,		       select_table *wait){	if(sel_type!=SEL_IN)		return 0;	if(rptr!=wptr)		return(1);	select_wait(&lirc_wait,wait);	return(0);}#endifstatic int lirc_ioctl(struct inode *node,struct file *filep,unsigned int cmd,		      unsigned long arg){        int result;	unsigned long features=LIRC_CAN_SEND_PULSE|LIRC_CAN_REC_MODE2,mode;		switch(cmd)	{	case LIRC_GET_FEATURES:#               ifdef KERNEL_2_2		result=put_user(features,(unsigned long *) arg);		if(result) return(result); #               else		result=verify_area(VERIFY_WRITE,(unsigned long*) arg,				   sizeof(unsigned long));		if(result) return(result);		put_user(features,(unsigned long *) arg);#               endif		break;	case LIRC_GET_SEND_MODE:#               ifdef KERNEL_2_2		result=put_user(LIRC_MODE_PULSE,(unsigned long *) arg);		if(result) return(result); #               else		result=verify_area(VERIFY_WRITE,(unsigned long *) arg,				   sizeof(unsigned long));		if(result) return(result);		put_user(LIRC_MODE_PULSE,(unsigned long *) arg);#               endif		break;	case LIRC_GET_REC_MODE:#               ifdef KERNEL_2_2		result=put_user(LIRC_MODE_MODE2,(unsigned long *) arg);		if(result) return(result); #               else		result=verify_area(VERIFY_WRITE,(unsigned long *) arg,				   sizeof(unsigned long));		if(result) return(result);		put_user(LIRC_MODE_MODE2,(unsigned long *) arg);#               endif		break;	case LIRC_SET_SEND_MODE:#               ifdef KERNEL_2_2		result=get_user(mode,(unsigned long *) arg);		if(result) return(result);#               else		result=verify_area(VERIFY_READ,(unsigned long *) arg,				   sizeof(unsigned long));		if(result) return(result);		mode=get_user((unsigned long *) arg);#               endif		if(mode!=LIRC_MODE_PULSE) return(-EINVAL);		break;	case LIRC_SET_REC_MODE:#               ifdef KERNEL_2_2		result=get_user(mode,(unsigned long *) arg);		if(result) return(result);#               else		result=verify_area(VERIFY_READ,(unsigned long *) arg,				   sizeof(unsigned long));		if(result) return(result);		mode=get_user((unsigned long *) arg);#               endif		if(mode!=LIRC_MODE_MODE2) return(-ENOSYS);		break;	default:		return(-ENOIOCTLCMD);	}	return(0);}static int lirc_open(struct inode* node,struct file* filep){#ifndef KERNEL_2_2	int result;#endif		if(MOD_IN_USE)	{		return(-EBUSY);	}#ifdef KERNEL_2_2	if(!lirc_claim())	{		return(-EBUSY);	}	pport->ops->enable_irq(pport);#else	result=request_irq(irq,irq_handler,SA_INTERRUPT,			   LIRC_DRIVER_NAME,NULL);	switch(result)	{	case -EBUSY:		printk(KERN_NOTICE "%s: IRQ %u busy\n",LIRC_DRIVER_NAME,irq);		return(-EBUSY);	case -EINVAL:		printk(KERN_NOTICE "%s: bad irq number or handler\n",		       LIRC_DRIVER_NAME);		return(-EINVAL);	}	/* enable interrupt */	out(LIRC_PORT_IRQ,LP_PINITP|LP_PSELECP|LP_PINTEN);#endif	/* init read ptr */	rptr=wptr=0;	lost_irqs=0;	MOD_INC_USE_COUNT;	is_open=1;	return(0);}#ifdef KERNEL_2_2static int lirc_close(struct inode* node,struct file* filep)#elsestatic void lirc_close(struct inode* node,struct file* filep)#endif{#ifdef KERNEL_2_2	if(is_claimed)	{		is_claimed=0;		parport_release(ppdevice);	}#else	free_irq(irq,NULL);		/* disable interrupt */	/*	  FIXME	  out(LIRC_PORT_IRQ,LP_PINITP|LP_PSELECP);	*/#endif	is_open=0;	MOD_DEC_USE_COUNT;#ifdef KERNEL_2_2	return(0);#endif}static struct file_operations lirc_fops = {#ifdef KERNEL_2_2	llseek:  lirc_lseek,#else	lseek:   lirc_lseek,#endif	read:    lirc_read,	write:   lirc_write,#ifdef KERNEL_2_2	poll:    lirc_poll,#else	select:  lirc_select,#endif	ioctl:   lirc_ioctl,	open:    lirc_open,	release: lirc_close};#ifdef MODULE#if LINUX_VERSION_CODE >= 0x020200MODULE_AUTHOR("Christoph Bartelmus");MODULE_DESCRIPTION("Infrared receiver driver for parallel ports.");#ifdef MODULE_LICENSEMODULE_LICENSE("GPL");#endifMODULE_PARM(io, "i");MODULE_PARM_DESC(io, "I/O address base (0x3bc, 0x378 or 0x278)");MODULE_PARM(irq, "i");MODULE_PARM_DESC(irq, "Interrupt (7 or 5)");EXPORT_NO_SYMBOLS;#endif#ifdef KERNEL_2_2int pf(void *handle);void kf(void *handle);static struct timer_list poll_timer;static void poll_state(unsigned long ignored);static void poll_state(unsigned long ignored){	printk(KERN_NOTICE "%s: time\n",	       LIRC_DRIVER_NAME);	del_timer(&poll_timer);	if(is_claimed)		return;	kf(NULL);	if(!is_claimed)	{		printk(KERN_NOTICE "%s: could not claim port, giving up\n",		       LIRC_DRIVER_NAME);		init_timer(&poll_timer);		poll_timer.expires=jiffies+HZ;		poll_timer.data=(unsigned long) current;		poll_timer.function=poll_state;		add_timer(&poll_timer);	}}int pf(void *handle){	pport->ops->disable_irq(pport);	is_claimed=0;	return(0);}void kf(void *handle){	if(!is_open)		return;	if(!lirc_claim())		return;	pport->ops->enable_irq(pport);	/* this is a bit annoying when you actually print...*/	/*	printk(KERN_INFO "%s: reclaimed port\n",LIRC_DRIVER_NAME);	*/}#endif/*********************************************************************** ******************   init_module()/cleanup_module()  ****************** ***********************************************************************/int init_module(void){#ifdef KERNEL_2_2	pport=parport_enumerate();	while(pport!=NULL)	{		if(pport->base==io)		{			break;		}		pport=pport->next;	}	if(pport==NULL)	{		printk(KERN_NOTICE "%s: no port at %x found\n",		       LIRC_DRIVER_NAME,io);		return(-ENXIO);	}	ppdevice=parport_register_device(pport,LIRC_DRIVER_NAME,					 pf,kf,irq_handler,0,NULL);	if(ppdevice==NULL)	{		printk(KERN_NOTICE "%s: parport_register_device() failed\n",		       LIRC_DRIVER_NAME);		return(-ENXIO);	}	if(parport_claim(ppdevice)!=0)		goto skip_init;	is_claimed=1;	out(LIRC_LP_CONTROL,LP_PSELECP|LP_PINITP);#else	if(check_region(io,LIRC_PORT_LEN)!=0)	{		printk(KERN_NOTICE "%s: port already in use\n",LIRC_DRIVER_NAME);		return(-EBUSY);	}	request_region(io,LIRC_PORT_LEN,LIRC_DRIVER_NAME);#endif#ifdef LIRC_TIMER#       ifdef DEBUG	out(LIRC_PORT_DATA,LIRC_PORT_DATA_BIT);#       endif		timer=init_lirc_timer();#       if 0 	/* continue even if device is offline */	if(timer==0) 	{#       ifdef KERNEL_2_2		is_claimed=0;		parport_release(pport);		parport_unregister_device(ppdevice);#       else		release_region(io,LIRC_PORT_LEN);#       endif		return(-EIO);	}	#       endif#       ifdef DEBUG	out(LIRC_PORT_DATA,0);#       endif#endif #ifdef KERNEL_2_2	is_claimed=0;	parport_release(ppdevice); skip_init:#endif	if(register_chrdev(LIRC_MAJOR, LIRC_DRIVER_NAME, &lirc_fops)<0)	{		printk(KERN_NOTICE "%s: register_chrdev() failed\n",LIRC_DRIVER_NAME);#ifdef KERNEL_2_2		parport_unregister_device(ppdevice);#else		release_region(io,LIRC_PORT_LEN);#endif		return(-EIO);	}	printk(KERN_INFO "%s: installed using port 0x%04x irq %d\n",LIRC_DRIVER_NAME,io,irq);	return(0);}  void cleanup_module(void){	if(MOD_IN_USE) return;#ifdef KERNEL_2_2	parport_unregister_device(ppdevice);#else	release_region(io,LIRC_PORT_LEN);#endif	unregister_chrdev(LIRC_MAJOR,LIRC_DRIVER_NAME);}#endif

⌨️ 快捷键说明

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