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

📄 lirc_serial.c

📁 很少见的linux下的红外口的工具
💻 C
📖 第 1 页 / 共 3 页
字号:
		printk(KERN_INFO LIRC_DRIVER_NAME		       ": Interrupt %d, port %04x obtained\n", irq, io);#               endif		break;	};	/* finally enable interrupts. */	save_flags(flags);cli();		/* Set DLAB 0. */	soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));		soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI);		restore_flags(flags);		/* Init read buffer pointers. */	rbh = rbt = 0;		MOD_INC_USE_COUNT;#       ifdef KERNEL_2_1	spin_unlock(&lirc_lock);#       endif	return 0;}#ifdef KERNEL_2_1static int lirc_close(struct inode *node, struct file *file)#elsestatic void lirc_close(struct inode *node, struct file *file)#endif{	unsigned long flags;		save_flags(flags);cli();		/* Set DLAB 0. */	soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));		/* First of all, disable all interrupts */	soutp(UART_IER, sinp(UART_IER)&	      (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI)));	restore_flags(flags);		free_irq(irq, NULL);#       ifdef DEBUG	printk(KERN_INFO  LIRC_DRIVER_NAME  ": freed IRQ %d\n", irq);#       endif		MOD_DEC_USE_COUNT;	#       ifdef KERNEL_2_1	return 0;#       endif}#ifdef KERNEL_2_1static unsigned int lirc_poll(struct file *file, poll_table * wait){	poll_wait(file, &lirc_wait_in, wait);	if (rbh != rbt)		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 (rbh != rbt)		return 1;	select_wait(&lirc_wait_in, wait);	return 0;}#endif#ifdef KERNEL_2_1static ssize_t lirc_read(struct file *file, char *buf,			 size_t count, loff_t * ppos)#elsestatic int lirc_read(struct inode *node, struct file *file, char *buf,		     int count)#endif{	int n=0,retval=0;#ifdef KERNEL_2_3	DECLARE_WAITQUEUE(wait,current);#else	struct wait_queue wait={current,NULL};#endif		if(n%sizeof(lirc_t)) return(-EINVAL);		add_wait_queue(&lirc_wait_in,&wait);	current->state=TASK_INTERRUPTIBLE;	while (n < count)	{		if (rbt != rbh) {#                       ifdef KERNEL_2_1			copy_to_user((void *) buf+n,				     (void *) &rbuf[rbh],sizeof(lirc_t));#                       else			memcpy_tofs((void *) buf+n,				    (void *) &rbuf[rbh],sizeof(lirc_t));#                       endif			rbh = (rbh + 1) & (RBUF_LEN - 1);			n+=sizeof(lirc_t);		} else {			if (file->f_flags & O_NONBLOCK) {				retval = -EAGAIN;				break;			}#                       ifdef KERNEL_2_1			if (signal_pending(current)) {				retval = -ERESTARTSYS;				break;			}#                       else			if (current->signal & ~current->blocked) {				retval = -EINTR;				break;			}#                       endif			schedule();			current->state=TASK_INTERRUPTIBLE;		}	}	remove_wait_queue(&lirc_wait_in,&wait);	current->state=TASK_RUNNING;	return (n ? n : retval);}#ifdef KERNEL_2_1static ssize_t lirc_write(struct file *file, const char *buf,			 size_t n, loff_t * ppos)#elsestatic int lirc_write(struct inode *node, struct file *file, const char *buf,                     int n)#endif{	int retval,i,count;	unsigned long flags;	long delta=0;		if(!(hardware[type].features&LIRC_CAN_SEND_PULSE))	{		return(-EBADF);	}		if(n%sizeof(lirc_t)) return(-EINVAL);	retval=verify_area(VERIFY_READ,buf,n);	if(retval) return(retval);	count=n/sizeof(lirc_t);	if(count>WBUF_LEN || count%2==0) return(-EINVAL);#       ifdef KERNEL_2_1	copy_from_user(wbuf,buf,n);#       else	memcpy_fromfs(wbuf,buf,n);#       endif	save_flags(flags);cli();	if(hardware[type].type==LIRC_IRDEO)	{		/* DTR, RTS down */		on();	}	for(i=0;i<count;i++)	{		if(i%2) hardware[type].send_space(wbuf[i]-delta);		else delta=hardware[type].send_pulse(wbuf[i]);	}	off();	restore_flags(flags);	return(n);}static int lirc_ioctl(struct inode *node,struct file *filep,unsigned int cmd,		      unsigned long arg){        int result;	unsigned long value;	unsigned int ivalue;		switch(cmd)	{	case LIRC_GET_FEATURES:#               ifdef KERNEL_2_1		result=put_user(hardware[type].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(hardware[type].features,(unsigned long *) arg);#               endif		break;			case LIRC_GET_SEND_MODE:		if(!(hardware[type].features&LIRC_CAN_SEND_MASK))		{			return(-ENOIOCTLCMD);		}		#               ifdef KERNEL_2_1		result=put_user(LIRC_SEND2MODE				(hardware[type].features&LIRC_CAN_SEND_MASK),				(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_SEND2MODE			 (hardware[type].features&LIRC_CAN_SEND_MASK),			 (unsigned long *) arg);#               endif		break;			case LIRC_GET_REC_MODE:		if(!(hardware[type].features&LIRC_CAN_REC_MASK))		{			return(-ENOIOCTLCMD);		}		#               ifdef KERNEL_2_1		result=put_user(LIRC_REC2MODE				(hardware[type].features&LIRC_CAN_REC_MASK),				(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_REC2MODE			 (hardware[type].features&LIRC_CAN_REC_MASK),			 (unsigned long *) arg);#               endif		break;			case LIRC_SET_SEND_MODE:		if(!(hardware[type].features&LIRC_CAN_SEND_MASK))		{			return(-ENOIOCTLCMD);		}		#               ifdef KERNEL_2_1		result=get_user(value,(unsigned long *) arg);		if(result) return(result);#               else		result=verify_area(VERIFY_READ,(unsigned long *) arg,				   sizeof(unsigned long));		if(result) return(result);		value=get_user((unsigned long *) arg);#               endif		/* only LIRC_MODE_PULSE supported */		if(value!=LIRC_MODE_PULSE) return(-ENOSYS);		break;			case LIRC_SET_REC_MODE:		if(!(hardware[type].features&LIRC_CAN_REC_MASK))		{			return(-ENOIOCTLCMD);		}		#               ifdef KERNEL_2_1		result=get_user(value,(unsigned long *) arg);		if(result) return(result);#               else		result=verify_area(VERIFY_READ,(unsigned long *) arg,				   sizeof(unsigned long));		if(result) return(result);		value=get_user((unsigned long *) arg);#               endif		/* only LIRC_MODE_MODE2 supported */		if(value!=LIRC_MODE_MODE2) return(-ENOSYS);		break;			case LIRC_SET_SEND_DUTY_CYCLE:		if(!(hardware[type].features&LIRC_CAN_SET_SEND_DUTY_CYCLE))		{			return(-ENOIOCTLCMD);		}		#               ifdef KERNEL_2_1		result=get_user(ivalue,(unsigned int *) arg);		if(result) return(result);#               else		result=verify_area(VERIFY_READ,(unsigned int *) arg,				   sizeof(unsigned int));		if(result) return(result);		ivalue=get_user((unsigned int *) arg);#               endif		if(ivalue<=0 || ivalue>100) return(-EINVAL);#               ifdef USE_RDTSC		duty_cycle=ivalue;		calc_pulse_lengths_in_clocks();#               else /* ! USE_RDTSC */		if(256*1000000L/freq*ivalue/100<=		   LIRC_SERIAL_TRANSMITTER_LATENCY) return(-EINVAL);		if(256*1000000L/freq*(100-ivalue)/100<=		   LIRC_SERIAL_TRANSMITTER_LATENCY) return(-EINVAL);		duty_cycle=ivalue;		period=256*1000000L/freq;		pulse_width=period*duty_cycle/100;		space_width=period-pulse_width;#               endif /* USE_RDTSC */#               ifdef DEBUG		printk(KERN_WARNING LIRC_DRIVER_NAME		       ": after SET_SEND_DUTY_CYCLE, freq=%d pulse=%ld, "		       "space=%ld, conv_us_to_clocks=%ld\n",		       freq, pulse_width, space_width, conv_us_to_clocks);#               endif		break;			case LIRC_SET_SEND_CARRIER:		if(!(hardware[type].features&LIRC_CAN_SET_SEND_CARRIER))		{			return(-ENOIOCTLCMD);		}		#               ifdef KERNEL_2_1		result=get_user(ivalue,(unsigned int *) arg);		if(result) return(result);#               else		result=verify_area(VERIFY_READ,(unsigned int *) arg,				   sizeof(unsigned int));		if(result) return(result);		ivalue=get_user((unsigned int *) arg);#               endif		if(ivalue>500000 || ivalue<20000) return(-EINVAL);#               ifdef USE_RDTSC		freq=ivalue;		calc_pulse_lengths_in_clocks();#               else /* !USE_RDTSC */		if(256*1000000L/freq*ivalue/100<=		   LIRC_SERIAL_TRANSMITTER_LATENCY) return(-EINVAL);		if(256*1000000L/freq*(100-ivalue)/100<=		   LIRC_SERIAL_TRANSMITTER_LATENCY) return(-EINVAL);		freq=ivalue;		period=256*1000000L/freq;		pulse_width=period*duty_cycle/100;		space_width=period-pulse_width;#               endif /* USE_RDTSC */#               ifdef DEBUG		printk(KERN_WARNING LIRC_DRIVER_NAME		       ": after SET_SEND_CARRIER, freq=%d pulse=%ld, "		       "space=%ld, conv_us_to_clocks=%ld\n",		       freq, pulse_width, space_width, conv_us_to_clocks);#               endif		break;			default:		return(-ENOIOCTLCMD);	}	return(0);}static struct file_operations lirc_fops ={	read:    lirc_read,	write:   lirc_write,#       ifdef KERNEL_2_1	poll:    lirc_poll,#       else	select:  lirc_select,#       endif	ioctl:   lirc_ioctl,	open:    lirc_open,	release: lirc_close};#ifdef MODULE#if LINUX_VERSION_CODE >= 0x020100MODULE_AUTHOR("Ralph Metzler, Trent Piepho, Ben Pfaff, Christoph Bartelmus");MODULE_DESCRIPTION("Infra-red receiver driver for serial ports.");#ifdef MODULE_LICENSEMODULE_LICENSE("GPL");#endifMODULE_PARM(type, "i");MODULE_PARM_DESC(type, "Hardware type (0 = home-brew, 1 = IRdeo,"		 " 2 = IRdeo Remote, 3 = AnimaX");MODULE_PARM(io, "i");MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)");MODULE_PARM(irq, "i");MODULE_PARM_DESC(irq, "Interrupt (4 or 3)");MODULE_PARM(sense, "i");MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit"		 " (0 = active high, 1 = active low )");MODULE_PARM(softcarrier, "i");MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on)");EXPORT_NO_SYMBOLS;#endifint init_module(void){	int result;		switch(type)	{	case LIRC_HOMEBREW:	case LIRC_IRDEO:	case LIRC_IRDEO_REMOTE:	case LIRC_ANIMAX:		break;	default:		return(-EINVAL);	}	if(!softcarrier && hardware[type].type==LIRC_HOMEBREW)	{		hardware[type].features&=~(LIRC_CAN_SET_SEND_DUTY_CYCLE|					   LIRC_CAN_SET_SEND_CARRIER);	}	if ((result = init_port()) < 0)		return result;	if (register_chrdev(major, LIRC_DRIVER_NAME, &lirc_fops) < 0) {		printk(KERN_ERR  LIRC_DRIVER_NAME  		       ": register_chrdev failed!\n");		release_region(io, 8);		return -EIO;	}	return 0;}void cleanup_module(void){	release_region(io, 8);	unregister_chrdev(major, LIRC_DRIVER_NAME);#       ifdef DEBUG	printk(KERN_INFO  LIRC_DRIVER_NAME  ": cleaned up module\n");#       endif}#endif

⌨️ 快捷键说明

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