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

📄 s3c2410-ts.c

📁 本程序为基于创维特触摸屏及相应测试程序
💻 C
📖 第 1 页 / 共 2 页
字号:
		return;	case PEN_SAMPLE:	        for ( index_ret  = 0; index_ret < 4; index_ret++) {		     ADCTSC = (ADCTSC&~(7))|(4);/* Auto Conversion Mode &  No Operation Mode */		     ADCCON |= 0x1;	          		     while(ADCCON&0x1);          /* sure that Enable_start is low  */		     while(!(ADCCON&0x8000))     /* End of A/D Conversion  */		                                 /* Reading DATA */		     if(index_ret != 0)		     {		     	dev->samples[index_ret-1].y = 0x3ff&ADCDAT0;		     	dev->samples[index_ret-1].x = 0x3ff&ADCDAT1;		     }	        }		ADCTSC = (ADCTSC&~(7))|(3); /*Normal ADC Conversion & Waiting for Interrupt Mode */		break;	default:	}		if (pen_data.state==PEN_SAMPLE){	  index_ret = data_processing();	  if ( index_ret) {				/* discard the data  */	        ts_timer_operation(TTIMER_START);		return;	  }	  else {	        ts_timer_operation(TTIMER_START);		/* Store the character only if there is room */		dev->d.total++;		if ( nhead != dev->d.tail ) {	              event->x = dev->cur_data.x;		      event->y = dev->cur_data.y;		      event->pressure = DOWN_PRESS;		      dev->d.head = nhead;		      if ( dev->d.async_queue )			kill_fasync( &dev->d.async_queue, SIGIO, POLL_IN );		      wake_up_interruptible( &dev->d.waitq );		      dev->d.processed++;		}		else {		      dev->d.dropped++;		}	  }	}	/*	 *  conform to Specification for Generic Touch Screen Driver	 */	else {			/* pen_data.state == PEN_UP */		dev->d.total++;		if ( nhead != dev->d.tail ) {		      event->x = dev->last_data.x;                      event->y = dev->last_data.y;		      event->pressure = UP_PRESS;		      dev->d.head = nhead;		      if ( dev->d.async_queue )			kill_fasync( &dev->d.async_queue, SIGIO, POLL_IN );		      wake_up_interruptible( &dev->d.waitq );		      dev->d.processed++;		}		else {		      dev->d.dropped++;		}	  }}static ssize_t s3c2410_ts_read(struct file *filp, char *buf, size_t count, loff_t *l){	struct s3c2410_ts_device *dev = (struct s3c2410_ts_device *) filp->private_data;		if (count < sizeof(struct s3c2410_ts_event))		return -EINVAL;	do { 	    if (down_interruptible(&dev->d.lock))      	         return -ERESTARTSYS;               	    while ( dev->d.head == dev->d.tail ) {   	         up(&dev->d.lock);                		 if ( filp->f_flags & O_NONBLOCK )		        return -EAGAIN;          		 if ( wait_event_interruptible( dev->d.waitq, (dev->d.head != dev->d.tail) ) )  		        return -ERESTARTSYS;                		 if ( down_interruptible(&dev->d.lock))    			return -ERESTARTSYS;              	    } 	} while (0);	if ( copy_to_user(buf, &dev->buf[dev->d.tail], sizeof(struct s3c2410_ts_event)) ) {		up(&dev->d.lock);		return -EFAULT;	}	dev->d.tail = INCBUF(dev->d.tail, MOUSEBUF_SIZE);		up(&dev->d.lock);	return sizeof(struct s3c2410_ts_event);}static unsigned int s3c2410_ts_poll(struct file *filp, poll_table *wait){	struct s3c2410_ts_general *dev = (struct s3c2410_ts_general *) filp->private_data;	poll_wait(filp, &dev->waitq, wait);	return (dev->head == dev->tail ? 0 : (POLLIN | POLLRDNORM));}/* * */static int s3c2410_ts_ioctl(struct inode *inode, struct file *filp,		unsigned int cmd, unsigned long arg){       	int RetVal = 0;        if (0) printk(__FUNCTION__ ": cmd=%x\n",cmd);        switch (cmd) {	case TS_GET_CAL:                if ( copy_to_user((void *)arg, &global_ts.cal, 				  sizeof(struct s3c2410_ts_calibration)))			RetVal = -EFAULT;                break;	case TS_SET_CAL:		if ( copy_from_user(&global_ts.cal, (void *) arg, 				    sizeof(struct s3c2410_ts_calibration)))			RetVal = -EFAULT;		break;        case 0xaa:  /* get the ts justified data from user */                if ( copy_from_user(&cfg_data, (void *) arg, sizeof(struct config_data)))                        RetVal = -EFAULT;                break;        case 0xbb: /* put the ts justified data to user */                if ( copy_to_user((void *)arg, &cfg_data, sizeof(struct config_data)))                        RetVal = -EFAULT;                break;        case 0xcc: /* set the ts to begin justify */                global_ts_justified = 0;                break;        case 0xdd: /* get the ts justify status, 1 -- ok, 0 -- justifing */                if ( copy_to_user((void *)arg, &global_ts_justified,                                  sizeof(int)))                        RetVal = -EFAULT;                break;        default:	       printk(__FUNCTION__ ": UNKNOWN IOCTL COMMAND=0x%08X\n",cmd);	}	/*	 * Future ioctl goes here	 */	return RetVal;}static int s3c2410_ts_open(struct inode *inode, struct file *filp){	struct s3c2410_ts_general *dev ;	filp->private_data = &global_ts;	dev = (struct s3c2410_ts_general *) filp->private_data;	if ( dev->usage_count++ == 0 )  /* We're the first open - clear the buffer */		dev->tail = dev->head;	if (0) printk(__FUNCTION__ " usage=%d\n", dev->usage_count);	MOD_INC_USE_COUNT;	return 0;}/* * invoked to add files to or remove files from the list of * interested processes when the FASYNC flag changes for an open file *  */static int s3c2410_ts_fasync(int fd, struct file *filp, int mode){	/*  Private * dev = filp->private_data;	 *  fasyhc_helper(fd,filp,on,&dev->async_queue)	 *	 */	struct s3c2410_ts_general *dev = (struct s3c2410_ts_general *) filp->private_data;	if (0) printk(__FUNCTION__ ": mode %x\n", mode );	return fasync_helper(fd, filp, mode, &dev->async_queue);}static int s3c2410_ts_release(struct inode *inode, struct file *filp){	struct s3c2410_ts_general *dev = (struct s3c2410_ts_general *) filp->private_data;	dev->usage_count--;	if (0) printk(__FUNCTION__ " usage=%d\n", dev->usage_count);	filp->f_op->fasync( -1, filp, 0 );  /* Remove ourselves from the async list */	MOD_DEC_USE_COUNT;	return 0;}static struct file_operations s3c2410_ts_fops = {	owner:		THIS_MODULE,	read:		s3c2410_ts_read,	poll:		s3c2410_ts_poll,	ioctl:		s3c2410_ts_ioctl,	open:		s3c2410_ts_open,	release:	s3c2410_ts_release,	fasync:		s3c2410_ts_fasync,};static int ts_timer_operation(enum ts_timer tt){	int RetVal=0;	switch(tt) {	  case TTIMER_SETUP:	       TCFG0  |= SYS_TIMER01_PRESCALER;	       TCFG1  = (TCFG1&~(0xf<<4))|(SYS_TIMER1_MUX<<4);	       TCNTB1  = (TOUCH_RESCHED_PERIOD*PCLK)/		  ((SYS_TIMER01_PRESCALER +1)*(SYS_TIMER1_DIVIDER)*1000);	       TCMPB1 = 0;	       TCON   = (TCON&~(0xf00))|(0xA<<8); /* the auto reload ,manual update for Timer 1 */	       TCON   = (TCON&~(0xf00))|(0<<8); /* Stop and clear manual update  for Timer1  */	       if ((RetVal = request_irq(IRQ_TIMER1,touch_timer_irq ,SA_INTERRUPT,g_ts_timer_id,NULL))) {		      printk(KERN_WARNING "s3c2410_ts timer : failed to get IRQ\n");		      return RetVal;	       }	       return RetVal;	  case TTIMER_START:    	       TCON   = (TCON&~(0xf00))|(0xA<<8); 	       TCON   = (TCON&~(0xf00))|(1<<8); /* Start */	    break;	  case TTIMER_STOP:    	       TCON   = (TCON&~(0xf00))|(0<<8); /* Stop */	    break;	}	return RetVal; /* success */}static int gMajor;		/* Dynamic major for now */int __init s3c2410_ts_init_module(void){	int retval;	struct s3c2410_ts_general *dev;	dev = (struct s3c2410_ts_general *)&global_ts;	                                                                                                               	/* Duplicated Code Sorry *^^*         * Setup GPIOs for touch          * GPGCON/GPGUP  see include/asm/arch-s3c2410/uncomress.h         * GPG15,14,13,12         */        //laputa append for AD converting freq calculate        retval = s3c2410_get_bus_clk(GET_PCLK);        PreScale_n = (int)( retval / ADC_FREQ ) - 1 ;	printk("Prescale = %d\n", PreScale_n);        //laputa end 030918        /* set gpio to XP, YM, YP and  YM */        set_gpio_ctrl(GPIO_YPON);        set_gpio_ctrl(GPIO_YMON);        set_gpio_ctrl(GPIO_XPON);        set_gpio_ctrl(GPIO_XMON);	/* 	 * Down,YM:GND,YP:AIN5,XM:Hi-z,XP:AIN7,XP pullup En,Auto,Waiting for interrupt mode          * If auto mode, the SEL_MUX don't care	 */	ADCTSC=(0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3);	/* ADC Start or Interval Delay */	ADCDLY=ADC_DELAY_TIME;		/* Enable Prescaler,Prescaler,AIN5/7 fix,Normal,Disable read start,No operation */	ADCCON = (1<<14)|(/*ADCPRS*/PreScale_n<<6)|(7<<3)|(0<<2)|(0<<1)|(0);	   	if ((retval = request_irq(IRQ_ADC_DONE, ts_down_interrupt ,SA_INTERRUPT,g_ts_id, ts_down_interrupt))) {		printk(KERN_WARNING "s3c2410_ts: failed to get IRQ\n");		return retval;	}        retval = request_irq(IRQ_TC, ts_up_interrupt, SA_INTERRUPT,                          g_ts_id, ts_up_interrupt);        if (retval) return retval;        gMajor = devfs_register_chrdev(0, H3600_TS_MODULE_NAME, &s3c2410_ts_fops);        if (gMajor < 0) {                printk(__FUNCTION__ ": can't get major number\n");                return gMajor;	}	/*----------------------------------------*/	dev->head = 0;	dev->tail = 0;	init_waitqueue_head( &dev->waitq );	init_MUTEX( &dev->lock );	dev->async_queue = NULL;	pen_data.state = PEN_DOWN;	/*----------------------------------------*/		if(ts_timer_operation(TTIMER_SETUP))             	  printk(KERN_NOTICE "  !!!!! TOUCH TIMER SETUP FAILED   \n");	printk(KERN_NOTICE "Loading S3C2410 Touch Screen Driver, major = %d          \n", gMajor);	return 0;}void __exit s3c2410_ts_cleanup_module(void){	printk(__FUNCTION__ ": S3C2410 Touch Screen Exit !!! \n");        free_irq(IRQ_TIMER1,g_ts_id);	free_irq(IRQ_ADC_DONE,g_ts_id);        free_irq(IRQ_TC,g_ts_timer_id);	/*         * Direct Disable IRQ ADC rINTMSK<= IRQ_ADC         */	devfs_unregister_chrdev(gMajor, H3600_TS_MODULE_NAME);}module_init(s3c2410_ts_init_module);module_exit(s3c2410_ts_cleanup_module);MODULE_AUTHOR("SW.LEE <hitchcar@sec.samsung.com>");MODULE_DESCRIPTION("S3c2410 touchscreen driver");MODULE_SUPPORTED_DEVICE("touchscreen/s3c2410");

⌨️ 快捷键说明

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