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

📄 digi.c

📁 触摸屏的开发
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 get_block(ts_event_t * * block, int size){	int cnt, rd;	unsigned long flags;	ts_event_t *p;	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);	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();	g_Digi_Status &= ~DIGI_OPEN_STATUS;	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();		pen_timer_status = 0;	g_Digi_Status = DIGI_OPEN_STATUS;    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);	if ( minor == - 1)	{//		printk("<1>spi_fasyn:bad device minor\n");		return -ENODEV;	}	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)	{		TRACE("bad minor\n");		return -ENODEV;	}		TRACE("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){       	int nonBlocking = 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;		if( nonBlocking )	{		if( !NODATA() ) 		{			/* returns length to be copied otherwise errno -Exxx */			cnt = get_block(&ev, count) ;			if(cnt > count){				TRACE(KERN_ERR"Error read spi buffer\n");				return -EINVAL;			}			__copy_to_user(buf, (char*)ev, cnt );			return cnt;		}		else			return -EINVAL;	}    else	{ 		/* check , when woken, there is a complete event to read */		while(1){			if( !NODATA() )			{				cnt = get_block(&ev, count);				if(cnt > count){					TRACE(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;			}		}	}}/*** power management callback function, will disable the clk from PCCR0 register*/int digi_pm_handler(struct pm_dev *dev, pm_request_t rqst, void *data){	switch(rqst){		case PM_RESUME:			if((g_Digi_Status & DIGI_SUSPEND_STATUS)!=0)			{				#ifdef CONFIG_ARCH_MX2ADS				_reg_CRM_PCCR0 |= 0x00000010;				#endif				g_Digi_Status &= ~DIGI_SUSPEND_STATUS;			}			break;		case PM_SUSPEND:			if((g_Digi_Status & DIGI_OPEN_STATUS)!=0)			{				#ifdef CONFIG_ARCH_MX2ADS				_reg_CRM_PCCR0 &= ~0x00000010;				#endif				g_Digi_Status |= DIGI_SUSPEND_STATUS;			}			break;		default:			break;		}	return 0;}/********************************************************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********************************************************/signed short __init digi_init(void){	int tmp;	int i;	INFO("Pen Driver 0.4.0\n");	init_timer(&pen_timer);	pen_timer.function = digi_sam_callback;		tasklet_init(&digi_tasklet, digi_tasklet_action,(unsigned long)0);	    g_digi_major = devfs_register_chrdev(0, MODULE_NAME, &g_digi_fops); 	if ( g_digi_major < 0 ) 	{		TRACE("%s driver: Unable to register driver\n",MODULE_NAME);		return -ENODEV;	}	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);   					       /*    g_proc_dir=create_proc_entry(MODULE_NAME, 0, NULL);	g_proc_dir->read_proc=get_proc_list;	g_proc_dir->data=NULL;				      */	tmp = request_irq(TPNL_IRQ,			(void * )digi_isr,			TPNL_INTR_MODE,			MODULE_NAME,			MODULE_NAME);	if (tmp)	{		TRACE("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);		return -1;	}	//init SPI buffer	if(-1 == init_buf()){		TRACE("digi_init: cannot init spi buffer, exit\n");		free_irq(TPNL_IRQ,MODULE_NAME);        devfs_unregister_chrdev(g_digi_major, MODULE_NAME);        devfs_unregister(g_devfs_handle);		disable_irq(TPNL_IRQ);		return -1;	}	init_waitqueue_head(&digi_wait);		//first init touch pannel	touch_pan_set_inter();//set pen IRQ 	touch_pan_disable_inter();//mask pen interrupt	//init pen touch pannel in GPIO,disabled	//init SPI module	spi_flush_fifo();	spi_init();	touch_pan_init();	touch_pan_enable();//enable touch pannel    spi_exchange_data(0x90);    spi_exchange_data(0x00);    spi_exchange_data(0xD0);    spi_exchange_data(0x00);    spi_exchange_data(0x00);        touch_pan_disable();        /* Delay for A/D Converter to be stable */    for(i=0;i<50000;i++);      g_digi_pm = pm_register(PM_SYS_DEV, PM_SYS_VGA, digi_pm_handler);    g_Digi_Status = 0;	return 0;}void __exit digi_cleanup(void){	/*Do some cleanup work*///	disable_irq(TPNL_IRQ);	free_irq(TPNL_IRQ, MODULE_NAME);	tasklet_kill(&digi_tasklet);    if(g_digi_major>0)    {        devfs_unregister_chrdev(g_digi_major, MODULE_NAME);        devfs_unregister(g_devfs_handle);    }	    pm_unregister(g_digi_pm);}int init_module(void){	digi_init();	return 0;}void cleanup_module(void){	digi_cleanup();}MODULE_PARM(irq_mask, "i");MODULE_PARM(irq_list, "1-4i");MODULE_LICENSE("GPL");//>>>>>Body

⌨️ 快捷键说明

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