📄 touchscreen.c
字号:
spin_unlock_irq (&pen_lock);}static irqreturn_t digi_isr(int irq, void *dev_id, struct pt_regs *regs){ U32 sX,sY; unsigned long digiflags,maxDelay; save_flags(digiflags);// cli();// printk("digi isr --->\n");// printk("GEDR2 %x GEDR3 %x\n",GEDR2,GEDR3);// if((GEDR2 &(0x1 << 31))==0)// return;#ifdef PXA270// touch_pan_clear_inter(); if(GEDR2 & (0x1 << 31)) //hhte { touch_pan_clear_inter();#ifdef PR_DEBUG printk("touch pan interrupt --->\n");#endif maxDelay=0;#ifdef TASK_DEBUG touch_pan_clear_inter(); touch_pan_disable_inter(); tasklet_schedule(&digi_tasklet); //touch_pan_enable_inter(); restore_flags(digiflags); printk("leave interrupt\n"); return;#else touch_pan_read_data(&sX,&sY);#ifdef K_1 while((sX == TPNL_PEN_UPVALUE)&&(maxDelay <= 3)) { touch_pan_read_data(&sX, &sY); maxDelay++; } if(sX == TPNL_PEN_UPVALUE) { // touch_pan_enable_inter(); // printk("TouchPanIsr: error always PEN_UP \n"); touch_pan_clear_inter();#ifdef PR_DEBUG printk("leave interrupt\n");#endif restore_flags(digiflags); return; } //disable interrupt touch_pan_disable_inter(); //add by Kenan add_x_y(sX, sY, PENDOWN1);#endif if (sX!=TPNL_PEN_UPVALUE) { // originality coordinate X,Y // printk("x= %d, y=%d \n",sX,sY);// coordinate_conversion(sX,sY);// printk("new x=%d,new y=%d \n",newsX1,newsY1); wait_inter_high(); }#if 0 spin_lock_irq(&pen_lock); pen_timer.expires = jiffies + HZ/100; add_timer(&pen_timer); pen_timer_status = 1; spin_unlock_irq (&pen_lock);#endif#endif touch_pan_clear_inter();#ifdef PR_DEBUG printk("leave interrupt\n");#endif }#endif restore_flags(digiflags); return;}static void digi_tasklet_action(unsigned long data){#if 0 //lyk u32 newX; u32 newY; u32 oldx,oldy; u32 maxDelay; newX = TPNL_PEN_UPVALUE; maxDelay = 0; int i; disable_irq(IRQ_GPIO_2_x);// save_flags(touchflags);// cli(); { //printk("TP: pen down\n");#ifdef PXA270// if(!(AT91_SYS->PIOA_ISR & AT91C_PIO_PA3)) //hhte#if 0 if(!(GEDR2 & (0x1 <<31))) //hhte { touch_pan_enable_inter(); printk("Not digi's interrupt\n"); return; }#endif #endif { //read data with MAX delay from ADC// printk("TP:touch_pan_read_data\n");// testcount = 1; touch_pan_read_data(&newX, &newY); //while((newX == TPNL_PEN_UPVALUE)&&(maxDelay <= 100)) while((newX == TPNL_PEN_UPVALUE)&&(maxDelay <= 3)) { // printk("maxdelay=%d\n",maxDelay); touch_pan_read_data(&newX, &newY); maxDelay++; } if(newX == TPNL_PEN_UPVALUE) { touch_pan_enable_inter(); printk("TouchPanIsr: error always PEN_UP \n"); enable_irq(IRQ_GPIO_2_x); return; }// printk("TP:before add\n"); //add by Kenan printk("TouchPanIsr:get pendata x= %d, y=%d \n",newX,newY); add_x_y(newX, newY, PENDOWN); wake_up_interruptible(&digi_wait); spin_lock_irq(&pen_lock); //pen_timer.expires = jiffies + HZ/50 + 2*HZ/100; pen_timer.expires = jiffies + HZ/100; add_timer(&pen_timer); pen_timer_status = 1; spin_unlock_irq (&pen_lock);// printk("TP this time pen down over\n"); enable_irq(IRQ_GPIO_2_x); return; } } //hhtech lyk deleted it //else//pen up interrupt { //check if the pen sampling timer is in usei printk("pen_timer_status=%08x\n",pen_timer_status); if(pen_timer_status!=0)//in use { //disable pen down interrupt //get Pen up TRACE("TouchPanIsr:get pen up 0,0,penup \n"); add_x_y(0, 0, PENUP); // if there is a pen up, shall tell apps to handle the event, and it shall // be data there if (!NODATA()) { wake_up_interruptible(&digi_wait); if(ts_fasync) kill_fasync(&ts_fasync, SIGIO, POLL_IN); } //release timer spin_lock_irq(&pen_lock); pen_timer_status = 0; del_timer(&pen_timer); spin_unlock_irq(&pen_lock); //touch_pan_set_pos_inter();//set polarity to detach pen down } else //no timer { ////////////////////////////////////// //lyk hhtech added it //touch_pan_set_pos_inter(); //////////////////////////////////// printk("TP:do nothing here\n"); FAILED("TouchPanIsr :pen up, no timer \n"); } printk("TP: all over here\n"); return; }#endif }/****************************************************************************** * Function Name: digi_sam_callback * * Input: : * * Value Returned: * * Description: spi sampling timer call back * *****************************************************************************/static void digi_sam_callback(unsigned long data){ u32 newX,newY,sX,sY; u32 maxDelay; unsigned long ss1; maxDelay = 0; newX = TPNL_PEN_UPVALUE;/**************************written by Kenan**********************************/ save_flags(ss1); cli(); mod_timer(&pen_timer, jiffies + HZ/200);/* printk("enter digi_sam_callback\n");*/if ( (GPLR2 & (0x1 << 31))==0 ) {#ifdef PR_DEBUG printk("callback:low\n");#endif touch_pan_read_data(&sX,&sY); if(sX == TPNL_PEN_UPVALUE) { touch_pan_clear_inter(); goto out; } if (sX!=TPNL_PEN_UPVALUE) { // originality coordinate X,Y // printk("x= %d, y=%d \n",sX,sY);// coordinate_conversion(sX,sY);// printk("new x=%d,new y=%d \n",newsX1,newsY1); add_x_y(sX, sY, PENDOWN); }}else {#ifdef PR_DEBUG printk("callback:high\n");#endif add_x_y(0,0,PENUP); //release the timer spin_lock_irq(&pen_lock); pen_timer_status = 0; del_timer(&pen_timer); spin_unlock_irq(&pen_lock); touch_pan_enable_inter(); } out: restore_flags(ss1); return; /*******************************End******************************************/ printk("TP: digi_sam_callback function is called \n"); mod_timer(&pen_timer, jiffies + HZ/200);#ifdef PXA270 if(!(GEDR2 & (0x1 << 31))) #endif { { add_x_y_line: //get Pen up add_x_y(0, 0, PENUP); // if there is a pen up, shall tell apps to handle the event, and it shall be data there if (!NODATA()) { wake_up_interruptible(&digi_wait); if(ts_fasync) kill_fasync(&ts_fasync, SIGIO, POLL_IN); } //release timer spin_lock_irq(&pen_lock); pen_timer_status = 0; del_timer(&pen_timer); spin_unlock_irq(&pen_lock); //touch_pan_set_pos_inter();//set polarity to detach pen down //hhtech added by lyk //touch_pan_enable_inter(); touch_pan_clear_inter(); } return; }else //if(!touch_pan_check_int_pol())//positive,it is pen down { //read data with MAX delay from ADC while((newX == TPNL_PEN_UPVALUE)&&(maxDelay <= 100)) { touch_pan_read_data(&newX, &newY); maxDelay++; } if(newX == TPNL_PEN_UPVALUE) { goto add_x_y_line; return; } //add element into buffer add_x_y(newX, newY, PENDOWN); wake_up_interruptible(&digi_wait); if(ts_fasync) kill_fasync(&ts_fasync, SIGIO, POLL_IN); return; }}/************************************************Misc functions for SPI *************************************************/void spi_init(void){ int i;#ifdef MX21_ADS_BOARD int datarate; int cs; datarate = 0x0111;//512// datarate = 0x1000;//1024 cs = 0x0;//ss0// cs = 0x1;//ss1 //cspi1_mosi--pd31 output //cspi1_miso--pd30 input //cspi1_sclk--pd29 output //cspi1_ss0 --pd28,output it connect with pen_cs_b _reg_GPIO_GIUS(3) &= 0x0fffffff; _reg_GPIO_GPR(3) &= 0x0fffffff; _reg_GPIO_DDIR(3) |= 0xb0000000; _reg_GPIO_DDIR(3) &= 0xbfffffff; //reset spi1 _reg_CSPI_RESETREG(1) = 0x00000001; sleep(2);//wait //bit19,18 CS[1:0], bit 17~14 datarate[3:0] _reg_CSPI_CONTROLREG(1) |= (cs<<18); _reg_CSPI_CONTROLREG(1) |= (datarate<<14); _reg_CSPI_CONTROLREG(1) |= 0x00000c07;//ss low active, 8 bit transfer,master mode#endif#ifdef MX1_ADS_BOARD //lyk hhtech edited it. rSPPRE0 = 0xff;//2410SPI_BAUD; who know how is right here? rSPCON0 = 0x18;//58 is dma mode, polling mode is used here! for(i=0;i<10;i++) rSPTDAT0 = 0xff; rGPECON |= 0x0a800000; rGPECON &= (~0x05400000); rGPEUP |= 0x3800; #endif #ifdef PXA270// PSSR |= PSSR_PH; GPDR0 |= (0x5 << 23) ; //set 23,25 output GPDR0 &= ~(0x1 << 26) ; //set 26 input GAFR0_U &= ~(0xf3 << 14) ; // set 23 25 26 use GPIO// GPSR0 |= (0x1 << 24) ; // set cs high#endif}//To polling when Spi transfer is not finishedstatic void spi_poll_done(void){ int nCount=0;#ifdef MX21_ADS_BOARD //here should poll the IRQ bit in IRQ reg to see while(!(_reg_CSPI_INTREG(1) & SPI_TE_INT_BIT));//transfer FIFO is empty /* Reset SPI IRQ bit */ _reg_CSPI_INTREG(1) &= SPI_TE_INT_BIT; //wait until XCH bit is clear, hence exchange is complete while(!(_reg_CSPI_CONTROLREG(1) & SPI_XCH_BIT));#endif#ifdef MX1_ADS_BOARD //here should poll the IRQ bit in IRQ reg to see //hhtech lyk add it while(!(rSPSTA0 & 0x01) ){ nCount++; if(nCount>=5000){ printk("TP spi state poll failed\n"); break; } } /* while(!(REG_SPI_INTER & SPI_TE_INT)){//transfer FIFO is empty nCount++; if(nCount>=5000){ //printk("TP::::::::::::::::::::::::::::::::::::::::spi_poll_done:REG_SPI_INTER:nCount=%d\n",nCount); break; } }*/ /* Reset SPI IRQ bit */ /*REG_SPI_INTER &= SPI_TE_INT; //wait until XCH bit is clear, hence exchange is complete nCount=0; //hhtech lyk add it while(!(REG_SPI_CONTRL & SPI_XCH_BIT)){ nCount++; if(nCount>=5000){ //printk("TP:;;;;;;;;;;;;;;;;;;;;;;;;;;;;spi_poll_done:REG_SPI_INTER:nCount=%d\n",nCount); break; } }*/#endif }static void spi_tx_data(u8 data){ int i; /* ensure data will not be transmitted while writing to SPI */#ifdef MX21_ADS_BOARD _reg_CSPI_CONTROLREG(1) &= SPI_XCH_MASK; _reg_CSPI_CONTROLREG(1) |= SPI_EN_BIT; _reg_CSPI_TXDATAREG(1) = data;//transfer data /* exchange data */ _reg_CSPI_CONTROLREG(1) |= SPI_XCH_BIT; spi_poll_done(); _reg_CSPI_CONTROLREG(1) &= SPI_XCH_MASK;#endif#ifdef MX1_ADS_BOARD //lyk hhtech add it //REG_SPI_CONTRL &= 0xffff3fff; spi_poll_done(); rSPTDAT0=data; spi_poll_done(); /* REG_SPI_CONTRL &= SPI_XCH_MASK; REG_SPI_CONTRL |= SPI_EN_BIT; REG_SPI_TXDATA = data;//transfer data // exchange data REG_SPI_CONTRL |= SPI_XCH_BIT; spi_poll_done(); REG_SPI_CONTRL &= SPI_XCH_MASK; */#endif #ifdef PXA270 for(i=8;i>=0;i--) { if(data & (1<<i)) send_high(); else send_low(); }#endif}static u8 spi_rx_data(void){ unsigned char val; int i,tmp=0; for(i=7;i>=0;i--) { GPCR0 |= (0x1 << 25) ; GPCR0 |= (0x1 << 23) ; udelay(4); GPSR0 |= (0x1 << 23) ; udelay(4); tmp |= (((GPLR0 & (0x1 << 26)) >> 26) << i); GPCR0 |= (0x1 << 23) ; udelay(4); } val = tmp & 0xff; return val;}/****************************************************************************** * Function Name: check_device * * Input: inode : * Value Returned: int : Return status.If no error, return 0. * * Description: verify if the inode is a correct inode * *****************************************************************************/static int check_device(struct inode *pInode){ int minor; //lyk hhtech modified it// kdev_t dev = pInode->i_rdev; //hhte dev_t dev = pInode->i_rdev; return 0; #if 0 if( MAJOR(dev) != g_digi_major) { printk("DIGI: check_device bad major = %d,g_digi_major=%d\n",MAJOR(dev),g_digi_major ); return -1; } minor = MINOR(dev); if ( minor < MAX_ID ) return minor; else { printk("DIGI: check_device bad minor = %d\n",minor ); return -1; }#endif}/**************************************************Misc functions for buffer***************************************************//* local buffer for store data * a new feature is read block, assume the buffer is a continuous buffer * so, if there is enough data, read data from current position to * buffer end, then next time, from buffer head to data end. -- the buffer * is a loop buffer. */ts_event_t * buffer;#define BUFLEN 500#define BUFSIZE ((BUFLEN+1)*sizeof(ts_event_t))#define NEXTI(i) {i=((i==BUFLEN-1)?0:i+1);}#define GETNEXTI(i) ((i==BUFLEN-1)?0:i+1)#define BLKEND(i) ((i)==0)#if 1#define DSIZE() ((wptr<rptr)?(BUFLEN-rptr):(wptr-rptr))#else#define DSIZE() ((wptr<rptr)?(BUFLEN-rptr+wptr):(wptr-rptr))#endifvoid spi_flush_fifo(void){ u32 i,j; for(i=0;i<8;i++) {#ifdef MX21_ADS_BOARD if(_reg_CSPI_INTREG(1)&SPI_RR_INT_BIT) j = _reg_CSPI_RXDATAREG(1);#endif#ifdef MX1_ADS_BOARD //if(REG_SPI_INTER&SPI_RR_INT) //j = REG_SPI_RXDATA;#endif }}/****************************************************************************** * Function Name: init_buf *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -