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

📄 pc110pad.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 2 页
字号:
 */static int read_bytes[3];static int read_byte_count;/** *	sample_raw: *	@d: sample buffer * *	Retrieve a triple of sample data.  */static void sample_raw(int d[3]){	d[0]=raw_data[0];	d[1]=raw_data[1];	d[2]=raw_data[2];}/** *	sample_rare: *	@d: sample buffer * *	Retrieve a triple of sample data and sanitize it. We do the needed *	scaling and masking to get the current status. */static void sample_rare(int d[3]){	int thisd, thisdd, thisx, thisy;	read_raw_pad(&thisd, &thisdd, &thisx, &thisy);	d[0]=(thisd?0x80:0)	   | (thisx/256)<<4	   | (thisdd?0x08:0)	   | (thisy/256)	;	d[1]=thisx%256;	d[2]=thisy%256;}/** *	sample_debug: *	@d: sample buffer * *	Retrieve a triple of sample data and mix it up with the state  *	information in the gesture parser. Not useful for normal users but *	handy when debugging */static void sample_debug(int d[3]){	int thisd, thisdd, thisx, thisy;	int b;	unsigned long flags;		save_flags(flags);	cli();	read_raw_pad(&thisd, &thisdd, &thisx, &thisy);	d[0]=(thisd?0x80:0) | (thisdd?0x40:0) | bounce;	d[1]=(recent_transition?0x80:0)+transition_count;	read_button(&b);	d[2]=(synthesize_tap<<4) | (b?0x01:0);	restore_flags(flags);}/** *	sample_ps2: *	@d: sample buffer * *	Retrieve a triple of sample data and turn the debounced tap and *	stroke information into what appears to be a PS/2 mouse. This means *	the PC110 pad needs no funny application side support. */static void sample_ps2(int d[3]){	static int lastx, lasty, lastd;	int thisd, thisdd, thisx, thisy;	int dx, dy, b;	/*	 * Obtain the current mouse parameters and limit as appropriate for	 * the return data format.  Interrupts are only disabled while 	 * obtaining the parameters, NOT during the puts_fs_byte() calls,	 * so paging in put_user() does not affect mouse tracking.	 */	read_raw_pad(&thisd, &thisdd, &thisx, &thisy);	read_button(&b);	/* Now compare with previous readings.  Note that we use the	 * raw down flag rather than the debounced one.	 */	if( (thisd && !lastd) /* new stroke */	 || (bounce!=NO_BOUNCE) )	{		dx=0;		dy=0;	}	else	{		dx =  (thisx-lastx);		dy = -(thisy-lasty);	}	lastx=thisx;	lasty=thisy;	lastd=thisd;/*	d[0]= ((dy<0)?0x20:0)	    | ((dx<0)?0x10:0)	    | 0x08	    | (b? 0x01:0x00)	;*/	d[0]= ((dy<0)?0x20:0)	    | ((dx<0)?0x10:0)	    | (b? 0x00:0x08)	;	d[1]=dx;	d[2]=dy;}/** *	fasync_pad: *	@fd:	file number for the file  *	@filp:	file handle *	@on:	1 to add, 0 to remove a notifier * *	Update the queue of asynchronous event notifiers. We can use the *	same helper the mice do and that does almost everything we need. */ static int fasync_pad(int fd, struct file *filp, int on){	int retval;	retval = fasync_helper(fd, filp, on, &asyncptr);	if (retval < 0)		return retval;	return 0;}/** *	close_pad: *	@inode: inode of pad *	@file: file handle to pad * *	Close access to the pad. We turn the pad power off if this is the *	last user of the pad. I've not actually measured the power draw but *	the DOS driver is careful to do this so we follow suit. */ static int close_pad(struct inode * inode, struct file * file){	lock_kernel();	fasync_pad(-1, file, 0);	if (!--active)		outb(0x30, current_params.io+2);  /* switch off digitiser */	unlock_kernel();	return 0;}/** *	open_pad: *	@inode: inode of pad *	@file: file handle to pad * *	Open access to the pad. We turn the pad off first (we turned it off *	on close but if this is the first open after a crash the state is *	indeterminate). The device has a small fifo so we empty that before *	we kick it back into action. */ static int open_pad(struct inode * inode, struct file * file){	unsigned long flags;		if (active++)		return 0;	save_flags(flags);	cli();	outb(0x30, current_params.io+2);	/* switch off digitiser */	pad_irq(0,0,0);		/* read to flush any pending bytes */	pad_irq(0,0,0);		/* read to flush any pending bytes */	pad_irq(0,0,0);		/* read to flush any pending bytes */	outb(0x38, current_params.io+2);	/* switch on digitiser */	current_params = default_params;	raw_data_count=0;		/* re-sync input byte counter */	read_byte_count=0;		/* re-sync output byte counter */	button_pending=0;	recent_transition=0;	transition_count=0;	synthesize_tap=0;	del_timer(&bounce_timer);	del_timer(&tap_timer);	restore_flags(flags);	return 0;}/** *	write_pad: *	@file: File handle to the pad *	@buffer: Unused *	@count: Unused *	@ppos: Unused * *	Writes are disallowed. A true PS/2 mouse lets you write stuff. Everyone *	seems happy with this and not faking the write modes. */static ssize_t write_pad(struct file * file, const char * buffer, size_t count, loff_t *ppos){	return -EINVAL;}/* *	new_sample: *	@d: sample buffer * *	Fetch a new sample according the current mouse mode the pad is  *	using. */ void new_sample(int d[3]){	switch(current_params.mode)	{		case PC110PAD_RAW:	sample_raw(d);		break;		case PC110PAD_RARE:	sample_rare(d);		break;		case PC110PAD_DEBUG:	sample_debug(d);	break;		case PC110PAD_PS2:	sample_ps2(d);		break;	}}/** * read_pad: * @file: File handle to pad * @buffer: Target for the mouse data * @count: Buffer length * @ppos: Offset (unused) * * Read data from the pad. We use the reader_lock to avoid mess when there are * two readers. This shouldnt be happening anyway but we play safe. */ static ssize_t read_pad(struct file * file, char * buffer, size_t count, loff_t *ppos){	int r;	down(&reader_lock);	for(r=0; r<count; r++)	{		if(!read_byte_count)			new_sample(read_bytes);		if(put_user(read_bytes[read_byte_count], buffer+r))		{			r = -EFAULT;			break;		}		read_byte_count = (read_byte_count+1)%3;	}	up(&reader_lock);	return r;}/** * pad_poll: * @file: File of the pad device * @wait: Poll table * * The pad is ready to read if there is a button or any position change * pending in the queue. The reading and interrupt routines maintain the * required state for us and do needed wakeups. */static unsigned int pad_poll(struct file *file, poll_table * wait){	poll_wait(file, &queue, wait);    	if(button_pending || xy_pending)		return POLLIN | POLLRDNORM;	return 0;}/** *	pad_ioctl; *	@inode: Inode of the pad *	@file: File handle to the pad *	@cmd: Ioctl command *	@arg: Argument pointer * *	The PC110 pad supports two ioctls both of which use the pc110pad_params *	structure. GETP queries the current pad status. SETP changes the pad *	configuration. Changing configuration during normal mouse operations *	may give momentarily odd results as things like tap gesture state *	may be lost. */ static int pad_ioctl(struct inode *inode, struct file * file,	unsigned int cmd, unsigned long arg){	struct pc110pad_params new;	if (!inode)		return -EINVAL;			switch (cmd) {	case PC110PADIOCGETP:		new = current_params;		if(copy_to_user((void *)arg, &new, sizeof(new)))			return -EFAULT;		return 0;	case PC110PADIOCSETP:		if(copy_from_user(&new, (void *)arg, sizeof(new)))			return -EFAULT;		if( (new.mode<PC110PAD_RAW)		 || (new.mode>PC110PAD_PS2)		 || (new.bounce_interval<0)		 || (new.tap_interval<0)		)			return -EINVAL;		current_params.mode	= new.mode;		current_params.bounce_interval	= new.bounce_interval;		current_params.tap_interval	= new.tap_interval;		return 0;	}	return -ENOTTY;}static struct file_operations pad_fops = {	owner:		THIS_MODULE,	read:		read_pad,	write:		write_pad,	poll:		pad_poll,	ioctl:		pad_ioctl,	open:		open_pad,	release:	close_pad,	fasync:		fasync_pad,};static struct miscdevice pc110_pad = {	minor:		PC110PAD_MINOR,	name:		"pc110 pad",	fops:		&pad_fops,};/** *	pc110pad_init_driver: * *	We configure the pad with the default parameters (that is PS/2  *	emulation mode. We then claim the needed I/O and interrupt resources. *	Finally as a matter of paranoia we turn the pad off until we are *	asked to open it by an application. */static char banner[] __initdata = KERN_INFO "PC110 digitizer pad at 0x%X, irq %d.\n";static int __init pc110pad_init_driver(void){	init_MUTEX(&reader_lock);	current_params = default_params;	if (request_irq(current_params.irq, pad_irq, 0, "pc110pad", 0)) {		printk(KERN_ERR "pc110pad: Unable to get IRQ.\n");		return -EBUSY;	}	if (!request_region(current_params.io, 4, "pc110pad"))	{		printk(KERN_ERR "pc110pad: I/O area in use.\n");		free_irq(current_params.irq,0);		return -EBUSY;	}	init_waitqueue_head(&queue);	printk(banner, current_params.io, current_params.irq);	misc_register(&pc110_pad);	outb(0x30, current_params.io+2);	/* switch off digitiser */	return 0;}/* *	pc110pad_exit_driver: * *	Free the resources we acquired when the module was loaded. We also *	turn the pad off to be sure we don't leave it using power. */static void __exit pc110pad_exit_driver(void){	outb(0x30, current_params.io+2);	/* switch off digitiser */	if (current_params.irq)		free_irq(current_params.irq, 0);	current_params.irq = 0;	release_region(current_params.io, 4);	misc_deregister(&pc110_pad);}module_init(pc110pad_init_driver);module_exit(pc110pad_exit_driver);MODULE_AUTHOR("Alan Cox, Robin O'Leary");MODULE_DESCRIPTION("Driver for the touchpad on the IBM PC110 palmtop");MODULE_LICENSE("GPL");EXPORT_NO_SYMBOLS;

⌨️ 快捷键说明

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