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

📄 touchscreen.c

📁 触摸屏的驱动源代码!! 在pxa270平台上好用
💻 C
📖 第 1 页 / 共 3 页
字号:
 * Input: 		void	: * Value Returned:	int	: Return status.If no error, return 0. * * Description: init the loop buffer for store data read out from spi FIFO * 	and shall be copied to user * *****************************************************************************/static int init_buf(void){	buffer = (ts_event_t*) vmalloc(BUFSIZE);	if(!buffer){		printk(KERN_ERR"no enough kernel memory for spi data buffer\n");		return -1;	}	rptr = wptr = 0;	return 1;}/****************************************************************************** * Function Name: add_x_y * * Input: 		i	: * Value Returned:	void	:  * * Description: add pen data to buffer * *****************************************************************************/static void add_x_y(unsigned x, unsigned y, unsigned flag){#ifdef PR_DEBUG	printk("*****add_x_y:x=%d y=%d flag=%d *****\n",x,y,flag);	#endif	if (GETNEXTI(wptr) == rptr)		return;	buffer[wptr].x = x;	buffer[wptr].y = y;	buffer[wptr].pressure = flag;	NEXTI(wptr);	// goto next wptr}/****************************************************************************** * Function Name: get_block * * Input: 		block: 				size: * Value Returned:	int	: count of data size * * Description: read a block of 'touch' data from buffer, read count shall less *	than size,but shall be as more as possible. the data shall not really copy *  to upper layer,untill copy_to_user is invoked. *****************************************************************************///assume continuous bufferstatic int xxx=0,judge_pre;static int xx_x=0,xx_y=0;static int get_block(ts_event_t * * block, int size){	int cnt, rd,x,y;	unsigned long flags;	ts_event_t *p,*pTmp;	if(NODATA())		return 0;			cnt = 0;		save_flags(flags);	cli();	//critical section	//get the actual size of data need read	if(DSIZE()*sizeof(ts_event_t) >= size)	{		rd = size/sizeof(ts_event_t);	}	else	{		rd = DSIZE();	}	*block= p=get_data();	cnt++;		while(p && (cnt < rd))	{		if(rptr == 0)			break;		p=get_data();		cnt ++;	}		restore_flags(flags);	////////////////////////////////add by lyk hhtech	pTmp=*block;//printk("flag %x\n",pTmp->pressure);	if(pTmp->pressure!=0){		if (pTmp->pressure==PENDOWN) {			judge_pre=1;		}		else {			judge_pre=0;		}#if 0	if(xxx < 50){		xx_x += pTmp->x;		xx_y += pTmp->y;		xxx++;	}	if(xxx == 50) {		printk(" x : %d y : %d --->\n",xx_x/50,xx_y/50); // HHTECH		xxx = 0;		xx_x =0;xx_y=0;	}#endif/*		pTmp->x=40+(pTmp->x-575)*(760-40)/(3450-575);		pTmp->y=40+(pTmp->y-808)*(560-40)/(3405-808);		pTmp->y=600 - pTmp->y;*/		pTmp->x= 20+(pTmp->x-542)*(220-20)/(3472-542);		pTmp->y= 20+(pTmp->y-520)*(300-20)/(3517-520);//		pTmp->y=320-pTmp->y;/*		if (!judge_pre) {			printk("*");		}*///		printk("pTmp x=%d y=%d\n",pTmp->x,pTmp->y);//		pTmp->x=x;pTmp->y=y;//		printk("**pTmp x=%d y=%d\n",pTmp->x,pTmp->y);	}	//////////////////////////////////////////////////////	return (cnt)*sizeof(ts_event_t);	}/****************************************************************************** * Function Name: get_data * * Input: 		void	: * Value Returned:	ts_event_t	: a 'touch' event data format * * Description: read a 'touch' event from data buffer * *****************************************************************************/// no really read out the data, so no copystatic ts_event_t* get_data(void){	ts_event_t *data;		if(NODATA())		return NULL;	data = & (buffer[rptr]);	TRACE("*** Read - x: 0x%04x, y: 0x%04x, rptr: 0x%04x, wptr: 0x%04x\n", data->x, data->y, (int)rptr, (int)wptr);		NEXTI(rptr);	return data;}/****************************************************************************** * Function Name: digi_release * * Input: 		inode	: * 			filp	: * Value Returned:	int	: Return status.If no error, return 0. * * Description: release resource when close the inode * *****************************************************************************/int digi_release(struct inode * inode, struct file * filp){	//printk("digi_release: ----\n");	digi_fasync(-1, filp, 0);	//disable the ADC interrupt	//disable_pen_interrupt();	touch_pan_disable_inter();	touch_pan_enable_inter();//	MOD_DEC_USE_COUNT;	return 0;}/****************************************************************************** * Function Name: digi_open * * Input: 		inode	: * 			filp	: * Value Returned:	int	: Return status.If no error, return 0. * * Description: allocate resource when open the inode * *****************************************************************************/int digi_open(struct inode * inode, struct file * filp){	//printk("digi_open: ----\n");//        MOD_INC_USE_COUNT;	//spi_flush_fifo();	//enable ADC interrupt	touch_pan_disable_inter();	//touch_pan_set_pos_inter();//set default polarity	touch_pan_clear_inter();	touch_pan_enable_inter();	//touch_pan_set_neg_inter();		pen_timer_status = 0;    return 0;}/****************************************************************************** * Function Name: digi_fasync * * Input: 		fd	: * 			filp	: * 			mode	: * Value Returned:	int	: Return status.If no error, return 0. * * Description: provide fasync functionality for select system call  *****************************************************************************/static int digi_fasync(int fd, struct file *filp, int mode){	/* TODO TODO put this data into file private data */	int minor = check_device( filp->f_dentry->d_inode);	//lyk changed it	//int minor = 0;//check_device( filp->f_dentry->d_inode);	if ( minor == - 1)	{		printk("<1>spi_fasyn:bad device minor\n");		return -ENODEV;	}	//hhtech lyk add it	/*if(fd!=-1){		return 0;	}else{		return 1;	*/	return( fasync_helper(fd, filp, mode, &ts_fasync) );//}}/****************************************************************************** * Function Name: digi_ioctl * * Input: 		inode	: * 			filp	: * 			cmd	: command for ioctl * 			arg	: parameter for command * Value Returned:	int	: Return status.If no error, return 0. * * Description: ioctl for this device driver * *****************************************************************************/int digi_ioctl(struct inode * inode, 		struct file *filp,		unsigned int cmd , 		unsigned long arg){	int ret = -EIO;	int minor;			minor = check_device( inode );	if ( minor == - 1)	{		printk("<1>spi_ioctl:bad minor\n");		return -ENODEV;	}		printk("<1>digi_ioctl:minor=%08x cmd=%d\n",minor,cmd);		return ret;}/****************************************************************************** * Function Name: spi_poll * * Input: 		filp	: * 			wait	:  * Value Returned:	int	: Return status.If no error, return 0. * * Description: support poll and select * *****************************************************************************/unsigned int digi_poll(struct file * filp, struct poll_table_struct * wait){	int minor;	minor = check_device( filp->f_dentry->d_inode);	if ( minor == - 1)		return -ENODEV;	poll_wait(filp, &digi_wait, wait);		return ( NODATA() ) ? 0 : (POLLIN | POLLRDNORM);}/****************************************************************************** * Function Name: digi_read * * Input: 		filp	: the file  * 			buf	: data buffer * 			count	: number of chars to be readed * 			l	: offset of file * Value Returned:	int	: Return status.If no error, return 0. * * Description: read device driver * *****************************************************************************/ssize_t digi_read(struct file * filp, char * buf, size_t count, loff_t * l){       //lyk hhtech add it	//int nonBlocking = filp->f_flags & O_NONBLOCK;#if 1 	int nonBlocking = 1;//filp->f_flags & O_NONBLOCK;	int minor;	ts_event_t *ev;	int cnt=0;	minor = check_device( filp->f_dentry->d_inode );	if ( minor == - 1)		return -ENODEV;//	printk("rptr=%d,wptr=%d\n",rptr,wptr);	if( nonBlocking )	{		if( !NODATA() ) 		{			/* returns length to be copied otherwise errno -Exxx *///			printk("before get_block\n");			cnt = get_block(&ev, count) ;			if(cnt > count){				printk(KERN_ERR"Error read spi buffer\n");				return -EINVAL;			}			//printk("After get_block,rptr=%d,wptr=%d\n",rptr,wptr);			__copy_to_user(buf, (char*)ev, cnt );			return cnt;		}		else			return -EINVAL;	}    else	{ 		//for us,block =0; so change here.		/* check , when woken, there is a complete event to read */		while(1){			if( !NODATA() )			{				cnt = get_block(&ev, count);				if(cnt > count){					printk(KERN_ERR"Error read spi buffer\n");					return -EINVAL;				}				/* returns length to be copied otherwise errno -Exxx */				__copy_to_user(buf, (char*)ev, cnt);				return cnt;			}			else			{				interruptible_sleep_on(&digi_wait);				if(signal_pending(current))					return -ERESTARTSYS;			}		}	}#endif}/********************************************************digitizer init function*Parameters:None*Return	*	0	indicates SUCCESS* 	-1	indicates FAILURE*Description: in this function should initialize the SPI device as well as the external touch pannel hardware********************************************************/#define TOUCH_MAJOR 210static int __init digi_init(void){	int tmp;	int i;	PSSR 	|=  PSSR_PH;	init_timer(&pen_timer);	pen_timer.function = digi_sam_callback;#ifdef TASK_DEBUG	tasklet_init(&digi_tasklet, digi_tasklet_action,(unsigned long)0);#endif	#if 0    g_digi_major = devfs_register_chrdev(0, MODULE_NAME, &g_digi_fops);    // devfs_register_chrdev(g_digi_major, MODULE_NAME, &g_digi_fops); 	if ( g_digi_major < 0 ) 	{		TRACE("%s driver: Unable to register driver\n",MODULE_NAME);		return -ENODEV;	}	//printk("g_digi_major=%d\n",g_digi_major);	g_devfs_handle = devfs_register(NULL, MODULE_NAME, DEVFS_FL_DEFAULT,				      g_digi_major, 0,				      S_IFCHR | S_IRUSR | S_IWUSR,				      &g_digi_fops, NULL);   	#endif				      	g_digi_major=register_chrdev(TOUCH_MAJOR,MODULE_NAME,&g_digi_fops);	if(g_digi_major < 0)	{		TRACE("%s driver: Unable to register driver\n",MODULE_NAME);		return -ENODEV;	}//	printk("Touch Screen Device Register OK --->\n");	touch_pan_set_inter();//set pen IRQ  #if 1	tmp = request_irq(10,			digi_isr,			SA_SHIRQ,			(const char *)"digi"/*MODULE_NAME*/,			(void *)1);	if (tmp)	{		//printk("digi_init:cannot init major= %d irq=%d\n", g_digi_major, TPNL_IRQ);//        devfs_unregister_chrdev(g_digi_major, MODULE_NAME);//        devfs_unregister(g_devfs_handle);		unregister_chrdev(TOUCH_MAJOR,MODULE_NAME);		return -1;	}#endif	//init SPI buffer	if(-1 == init_buf()){		printk("digi_init: cannot init spi buffer, exit\n");		free_irq(IRQ_GPIO_2_x,MODULE_NAME);		//free_irq(IRQ_EINT1,MODULE_NAME);//        devfs_unregister_chrdev(g_digi_major, MODULE_NAME);//        devfs_unregister(g_devfs_handle);		unregister_chrdev(TOUCH_MAJOR,MODULE_NAME);		//disable_irq(IRQ_EINT1);//		AT91_SYS->PIOA_IDR |= AT91C_PIO_PA3;	//hhte		return -1;	}else		printk("init spi buff success\n");	init_waitqueue_head(&digi_wait);	//printk("after register device\n");	//first init touch pannel	//address_map();		//printk("after set inter\n");	touch_pan_disable_inter();//mask pen interrupt	//printk("after disable inter\n");	//init pen touch pannel in GPIO,disabled	//init SPI module	spi_init();	//printk("after spi_init\n");		touch_pan_init();	//printk("after pan init\n");// added by Kenan	touch_pan_enable();//enable touch pannel	//touch_pan_set_neg_inter();	//printk("before spi_tx_data\n");	//d000 at first,I change to     spi_tx_data(0xd0);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x90);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0xD0);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x90);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x00);    spi_tx_data(0x00);    touch_pan_disable();	//printk("all ok\n");    /* Delay for A/D Converter to be stable */    for(i=0;i<50000;i++);	return 0;}static void __exit digi_cleanup(void){	/*Do some cleanup work*/	printk("clean up\n");//	disable_irq(IRQ_EINT1);//	free_irq(IRQ_EINT1, MODULE_NAME);//	AT91_SYS->PIOA_IDR |= AT91C_PIO_PA3; //hhte	free_irq(IRQ_GPIO_2_x, MODULE_NAME);	tasklet_kill(&digi_tasklet);    if(g_digi_major>0)    {//        devfs_unregister_chrdev(g_digi_major, MODULE_NAME);//        devfs_unregister(g_devfs_handle);	unregister_chrdev(TOUCH_MAJOR,MODULE_NAME);    }	}MODULE_AUTHOR("HHTECH");MODULE_DESCRIPTION("Touch Screen Device Driver");module_init(digi_init);module_exit(digi_cleanup);//>>>>>Body

⌨️ 快捷键说明

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