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

📄 ucb1x00-ts.c~

📁 基于pxa270的touch screen的源码
💻 C~
📖 第 1 页 / 共 2 页
字号:
	    b=c;	    udelay(26);	    c=ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);		  }else{	    break;	  }//printk(KERN_EMERG "d:%d\n",d);	  		}        //printk(KERN_EMERG "n:%d\n",n);	//while(((b-a)>5)||((b-a)<-5)||((c-a)>5)||((c-a)<-5)||((d-a)>5)||((d-a)<-5)){	//a=ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);	//b=ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);	//c=ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);	//d=ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);	  	//}        	d=c;	//printk(KERN_EMERG "x:%d\n",d);	return d;	  //return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);}/* * Switch to Y position mode and measure X plate.  We switch the plate * configuration in pressure mode, then switch to position mode.  This * gives a faster response time.  Even so, we need to wait about 55us * for things to stabilise. */static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts){  //bruce  int a,b,c;  unsigned int d;  int m=10000;	        ucb1x00_reg_write(ts->ucb, UCB_TS_CR,			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);	ucb1x00_reg_write(ts->ucb, UCB_TS_CR,			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);	ucb1x00_reg_write(ts->ucb, UCB_TS_CR,			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |			UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);	udelay(55);	//bruce		//return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);	a=ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);	udelay(30);	b=ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);	udelay(30);	c=ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);	//d=ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);	//printk(KERN_EMERG "a:%d\n",a);	//printk(KERN_EMERG "b:%d\n",b);	//printk(KERN_EMERG "c:%d\n",c);	//printk(KERN_EMERG "d:%d\n",d);	//while(((b-a)>2)||((b-a)<-2)){	//a=(a+b)/2;	//printk(KERN_EMERG "a:%d\n",a);	//b=ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);	//printk(KERN_EMERG "b:%d\n",b);		//}		//c=(a+b)/2;		//while(((b-a)>1)||((b-a)<-1)){	//a=b;	//b=ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);	  //printk(KERN_EMERG "b:%d\n",b);		//}	//c=b;	while(((b-a)>4)||((b-a)<-4)||((c-a)>4)||((c-a)<-4)){	  if(m>0){ 	    m--;	    a=b;	    b=c;	    udelay(26);	    c=ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);	  }else{	    break;	  }	  //printk(KERN_EMERG "c:%d\n",c);			}	//printk(KERN_EMERG "m:%d\n",m);	//while(((b-a)>5)||((b-a)<-5)||((c-a)>5)||((c-a)<-5)||((d-a)>5)||((d-a)<-5)){	//a=ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);	//b=ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);	//c=ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);	//d=ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);	//}	d=c;	//printk(KERN_EMERG "y:%d\n",d);	return d;}/* * Switch to X plate resistance mode.  Set MX to ground, PX to * supply.  Measure current. */static inline unsigned int ucb1x00_ts_read_xres(struct ucb1x00_ts *ts){	ucb1x00_reg_write(ts->ucb, UCB_TS_CR,			UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);	return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);}/* * Switch to Y plate resistance mode.  Set MY to ground, PY to * supply.  Measure current. */static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts){	ucb1x00_reg_write(ts->ucb, UCB_TS_CR,			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);	return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);}/* * This is a RT kernel thread that handles the ADC accesses * (mainly so we can use semaphores in the UCB1200 core code * to serialise accesses to the ADC).  The UCB1400 access * functions are expected to be able to sleep as well. */static int ucb1x00_thread(void *_ts){	struct ucb1x00_ts *ts = _ts;	struct task_struct *tsk = current;	int valid;	ts->rtask = tsk;	daemonize();	reparent_to_init();	strcpy(tsk->comm, "ktsd");	tsk->tty = NULL;	/*	 * We could run as a real-time thread.  However, thus far	 * this doesn't seem to be necessary.	 *///	tsk->policy = SCHED_FIFO;//	tsk->rt_priority = 1;	/* only want to receive SIGKILL */	spin_lock_irq(&tsk->sigmask_lock);	siginitsetinv(&tsk->blocked, sigmask(SIGKILL));	recalc_sigpending(tsk);	spin_unlock_irq(&tsk->sigmask_lock);	complete(&ts->init_exit);	valid = 0;	for (;;) {		unsigned int x, y, p, val;		ts->restart = 0;		ucb1x00_adc_enable(ts->ucb);		x = ucb1x00_ts_read_xpos(ts);		y = ucb1x00_ts_read_ypos(ts);		p = ucb1x00_ts_read_pressure(ts);		/*		 * Switch back to interrupt mode.		 */		ucb1x00_ts_mode_int(ts);		ucb1x00_adc_disable(ts->ucb);		set_task_state(tsk, TASK_UNINTERRUPTIBLE);		schedule_timeout(HZ / 100);		if (signal_pending(tsk))			break;		ucb1x00_enable(ts->ucb);		val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);		if (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW)) {			ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);			ucb1x00_disable(ts->ucb);			/*			 * If we spat out a valid sample set last time,			 * spit out a "pen off" sample here.			 */			if (valid) {				ucb1x00_ts_event_release(ts);				valid = 0;			}			/*			 * Since ucb1x00_enable_irq() might sleep due			 * to the way the UCB1400 regs are accessed, we			 * can't use set_task_state() before that call,			 * and not changing state before enabling the			 * interrupt is racy.  A semaphore solves all			 * those issues quite nicely.			 */			down_interruptible(&ts->irq_wait);		} else {			ucb1x00_disable(ts->ucb);			/*			 * Filtering is policy.  Policy belongs in user			 * space.  We therefore leave it to user space			 * to do any filtering they please.			 */			if (!ts->restart) {				ucb1x00_ts_evt_add(ts, p, x, y);				valid = 1;			}			set_task_state(tsk, TASK_INTERRUPTIBLE);			schedule_timeout(HZ / 100);		}		if (signal_pending(tsk))			break;	}	ts->rtask = NULL;	ucb1x00_ts_evt_clear(ts);	complete_and_exit(&ts->init_exit, 0);}/* * We only detect touch screen _touches_ with this interrupt * handler, and even then we just schedule our task. */static void ucb1x00_ts_irq(int idx, void *id){	struct ucb1x00_ts *ts = id;	ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);#if defined( CONFIG_PM )	pm_updatetimer(0);#endif	up(&ts->irq_wait);}static int ucb1x00_ts_startup(struct ucb1x00_ts *ts){	int ret = 0;	if (down_interruptible(&ts->sem))		return -EINTR;	if (ts->use_count++ != 0)		goto out;	if (ts->rtask)		panic("ucb1x00: rtask running?");	sema_init(&ts->irq_wait, 0);	ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts);	if (ret < 0)		goto out;	/*	 * If we do this at all, we should allow the user to	 * measure and read the X and Y resistance at any time.	 */	ucb1x00_adc_enable(ts->ucb);	ts->x_res = ucb1x00_ts_read_xres(ts);	ts->y_res = ucb1x00_ts_read_yres(ts);	ucb1x00_adc_disable(ts->ucb);	init_completion(&ts->init_exit);	ret = kernel_thread(ucb1x00_thread, ts, 0);	if (ret >= 0) {		wait_for_completion(&ts->init_exit);		ret = 0;	} else {		ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);	} out:	if (ret)		ts->use_count--;	up(&ts->sem);	return ret;}/* * Release touchscreen resources.  Disable IRQs. */static void ucb1x00_ts_shutdown(struct ucb1x00_ts *ts){	if (--ts->use_count == 0) {		if (ts->rtask) {			send_sig(SIGKILL, ts->rtask, 1);			wait_for_completion(&ts->init_exit);		}		ucb1x00_enable(ts->ucb);		ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);		ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 0);		ucb1x00_disable(ts->ucb);	}}#ifdef CONFIG_PMstatic int ucb1x00_ts_pm (struct pm_dev *dev, pm_request_t rqst, void *data){	struct ucb1x00_ts *ts = (struct ucb1x00_ts *) (dev->data);	if (rqst == PM_RESUME && ts->rtask != NULL) {		/*		 * Restart the TS thread to ensure the		 * TS interrupt mode is set up again		 * after sleep.		 */		ts->restart = 1;		up(&ts->irq_wait);	}	return 0;}#endif/* * Initialisation. */static int __init ucb1x00_ts_init(void){	struct ucb1x00_ts *ts = &ucbts;	ts->ucb = ucb1x00_get();	if (!ts->ucb)		return -ENODEV;	ts->adcsync = adcsync;	init_MUTEX(&ts->sem);#ifdef CONFIG_PM	ts->pmdev = pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, ucb1x00_ts_pm);	if (ts->pmdev == NULL)		printk("ucb1x00_ts: unable to register in PM.\n");	else		ts->pmdev->data = ts;#endif	return ucb1x00_ts_register(ts);}static void __exit ucb1x00_ts_exit(void){	struct ucb1x00_ts *ts = &ucbts;	ucb1x00_ts_deregister(ts);#ifdef CONFIG_PM	if (ts->pmdev)		pm_unregister(ts->pmdev);#endif}#ifndef MODULE/* * Parse kernel command-line options. * * syntax : ucbts=[sync|nosync],... */static int __init ucb1x00_ts_setup(char *str){	char *p;	while ((p = strsep(&str, ",")) != NULL) {		if (strcmp(p, "sync") == 0)			adcsync = UCB_SYNC;	}	return 1;}__setup("ucbts=", ucb1x00_ts_setup);#elseMODULE_PARM(adcsync, "i");MODULE_PARM_DESC(adcsync, "Enable use of ADCSYNC signal");#endifmodule_init(ucb1x00_ts_init);module_exit(ucb1x00_ts_exit);MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");MODULE_DESCRIPTION("UCB1x00 touchscreen driver");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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