📄 touchscreen.c
字号:
/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Copyright (C) 2002, 2003 Motorola Semiconductors HK Ltd * */#if 0#ifndef __KERNEL__# define __KERNEL__#endif#ifndef MODULE# define MODULE#endif#endif#include <linux/module.h>#include <linux/version.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/delay.h>#include <linux/poll.h>#include <asm/uaccess.h> /* get_user,copy_to_user */#include <linux/miscdevice.h>#include <linux/string.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/types.h>#include <linux/fcntl.h>#include <linux/interrupt.h>#include <linux/ptrace.h>#include <linux/ioport.h>#include <linux/in.h>#include <linux/slab.h>#include <linux/vmalloc.h>#include <linux/string.h>#include <linux/init.h>#include <asm/bitops.h>#include <asm/io.h>#include <linux/errno.h>#include <linux/wait.h>#include <asm/arch/pxa-regs.h>//////////////////////////////////////////lyk add hhtech it///////////#include "touchscreen.h"////////////////////////////////////////#define MODULE_NAME "digi"//#define DBMX_DEBUG 1#ifdef DBMX_DEBUG# define TRACE(fmt, args...) \ { \ printk("\n %s:%d:%s:",__FILE__, __LINE__,__FUNCTION__); \ printk(fmt, ## args);\ }#else# define TRACE(fmt, args...)#endif# define FAILED(fmt, args...) \ { \ printk("\n %s:%d:%s:",__FILE__, __LINE__,__FUNCTION__); \ printk(fmt, ## args);\ }# define INFO(fmt, args...) \ { \ printk("\n"); \ printk(fmt, ## args);\ }//<<<<<Private Function Declearationstatic int digi_open(struct inode * inode, struct file * filp);static int digi_release(struct inode * inode, struct file * filp);static int digi_fasync(int fd, struct file *filp, int mode);static int digi_ioctl(struct inode * inode,struct file *filp,unsigned int cmd,unsigned long arg);static ssize_t digi_read(struct file * filp, char * buf, size_t count, loff_t * l);static unsigned int digi_poll(struct file * filp, struct poll_table_struct * wait);static int check_device(struct inode *pInode);static ts_event_t* get_data(void);static void spi_tx_data(u8 data);static u8 spi_rx_data(void);static int get_block(ts_event_t* * block, int size);static void digi_sam_callback(unsigned long data);static void add_x_y(unsigned x, unsigned y, unsigned flag);static int init_buf(void);static void spi_flush_fifo(void);//>>>>>Private Function Declearation//<<<<<< Global Variablestatic int g_digi_major=0;//static struct proc_dir_entry * g_proc_dir;//static devfs_handle_t g_devfs_handle;static wait_queue_head_t digi_wait;struct fasync_struct *ts_fasync=0;static u16 rptr, wptr;static struct timer_list pen_timer; u8 pen_timer_status; spinlock_t pen_lock;static spinlock_t digi_lock;static struct tasklet_struct digi_tasklet; struct file_operations g_digi_fops = { open: digi_open, release: digi_release, read: digi_read, poll: digi_poll, ioctl: digi_ioctl, fasync: digi_fasync, }; //>>>>>> Global Variable//<<<<<Body#undef MX21_ADS_BOARD#undef MX1_ADS_BOARD#define PXA270#undef TASK_DEBUG//#define TASK_DEBUG#undef K_1;#define K_1;#undef PR_DEBUG //define printk or not in __FUNC__ digi_isr#define NODATA() (rptr==wptr)/************************************///Misc functions for touch pannel/*************************************/static int testcount=0,delcount=0;static int newsX1,newsY1;u32 testx=-999,testy=-999;static void send_high(void){ GPSR0 |= 1 << 25 ; // set tx high GPCR0 |= 1 << 23 ; // send a clk period udelay(4); GPSR0 |= 1 << 23 ; udelay(4); GPCR0 |= 1 << 23 ; udelay(4);}static void send_low(void){ GPCR0 |= 1 << 25 ; // set tx low GPCR0 |= 1 << 23 ; // send a clk period udelay(4); GPSR0 |= 1 << 23 ; udelay(4); GPCR0 |= 1 << 23 ; udelay(4);}static void touch_pan_enable(void){#ifdef MX21_ADS_BOARD //set cspi1_ss0 to be low effective //cspi1_ss0 --pd28, it connect with pen_cs_b _reg_GPIO_DR(3) &= (~0x10000000);#endif#ifdef MX1_ADS_BOARD rGPGDAT &=(~0x0004); //REG_PC_DR &= (~0x00008000); #endif #ifdef PXA270// GAFR0_U &= ~(0x3 << 16) ; // set pio24 as a gpio// GPDR0 |= (0x1 << 24) ; // set cs as output GPCR0 |= 1 << 24 ; // set cs low// GAFR0_U |= (0x1 << 16) ; // set pio24 fun1// GRER2 &= ~(0x1 << 31); // GFER2 |= (0x1 << 31);// GEDR2 |= (0x1 << 31);#endif}static void touch_pan_disable(void){#ifdef MX21_ADS_BOARD //set the cspi1_ss0 to be high _reg_GPIO_DR(3) |= 0x10000000;#endif#ifdef MX1_ADS_BOARD //set the output [15] to be high rGPGDAT |=0x0004; //REG_PC_DR |= 0x00008000;#endif #ifdef PXA270 GPSR0 |= 1 << 24; // set cs high// GAFR0_U |= (0x1 << 16) ; // set pio24 fun1#endif}static void touch_pan_set_inter(void){ int temp;#ifdef MX21_ADS_BOARD printk("MX21_ADS_BOARD error\n"); //pe10, uart3_cts pin connect to penIrq _reg_GPIO_GIUS(4) |= 0x00000400; _reg_GPIO_IMR(4) &= ~(0x00000400); _reg_GPIO_DDIR(4) &= ~(0x00000400); temp = _reg_GPIO_SSR(4);#endif#ifdef MX1_ADS_BOARD set_external_irq(IRQ_EINT1,EXT_FALLING_EDGE, GPIO_PULLUP_DIS);#endif #ifdef PXA270 GPDR2 &= ~(0x1 << 31); // set 95 input GAFR2_U &= ~(0x3 << 30); // set 95 use GPIO GRER2 &= ~(0x1 << 31); // rising edge disable GFER2 |= (0x1 << 31); // falling edge disable ICLR &= ~(0x1 << 10); // set int10 as a irq// GEDR2 |= (0x1 << 31); // clear detect bit#endif}static void touch_pan_enable_inter(void){#ifdef MX21_ADS_BOARD _reg_GPIO_IMR(4) |= 0x00000400; #endif#ifdef MX1_ADS_BOARD //unmask the Pen interrupt in PD[31] //REG_PD_IMR |= ~TOUCH_INT_MASK; //*(volatile U32*)PTB_IMR |= 0x1<<16; // enable pin 14~17 enable_irq(IRQ_EINT1);#endif #ifdef PXA270 ICMR |= (0x1 << 10); // GEDR2 |= (0x1 << 31); // clear detect bit// GFER2 |= (0x1 << 31); // falling edge enable#endif}static void touch_pan_disable_inter(void){#ifdef MX21_ADS_BOARD _reg_GPIO_IMR(4) &= ~(0x00000400);#endif#ifdef MX1_ADS_BOARD //mask the Pen interrupt in PD[31] //REG_PD_IMR &= TOUCH_INT_MASK; //*(volatile U32*)PTB_IMR &= ~(0x1<<16); //all 14~17 interrupts masked disable_irq(IRQ_EINT1);#endif #ifdef PXA270 ICMR &= ~(0x1 << 10); // GFER2 &= ~(0x1 << 31); // falling edge disable// GEDR2 |= (0x1 << 31); // clear detect bit#endif}static void touch_pan_clear_inter(void){#ifdef MX21_ADS_BOARD _reg_GPIO_ISR(4) = 0x00000400;#endif#ifdef MX1_ADS_BOARD //REG_PD_ISR = ~TOUCH_INT_MASK; // *(volatile U32*)PTB_ISR |= 0x1<<16; //clear all 14~17 interrupts(wri SRCPND &= (~0x0000000c); INTPND = INTPND; EINTPEND &= (~0x00800000);#endif #ifdef PXA270 GEDR2 |= (0x1 << 31); // clear detect bit#endif}void touch_pan_init(void)//chip select for ADC{#ifdef MX21_ADS_BOARD //cspi1_ss0 --pd28, it connect with pen_cs_b _reg_GPIO_GIUS(3) |= 0x10000000; _reg_GPIO_OCR2(3) |= 0x03000000; _reg_GPIO_DR(3) |= 0x10000000; _reg_GPIO_DDIR(3) |= 0x10000000;#endif#ifdef MX1_ADS_BOARD rGPGCON |= 0x00000010; rGPGCON &= (~0x00000020); rGPGUP &= (~0x0004); rGPGDAT |=0x0004; #endif#ifdef PXA270 GAFR0_U &= ~(0x3 << 16) ; // set pio24 as a gpio// GAFR0_U |= (0x10 << 16) ; // set 24 func 2 GPDR0 |= (0x1 << 24) ; // set cs as output GPSR0 |= (0x1 << 24) ; // set cs high#endif}//read data from Touch Pannelvoid touch_pan_read_dev(u32* x, u32* y){ u32 x_upper, x_lower, y_upper, y_lower; u32 temp;#ifdef MX21_ADS_BOARD temp = _reg_GPIO_ISR(4);#endif#ifdef MX1_ADS_BOARD/// temp = REG_PB_ISR;#endif //hhtech lyk add it //printk("TP read dev 1\n"); //touch_pan_disable_inter(); touch_pan_enable(); //printk("TP read dev 2\n");#ifdef MX21_ADS_BOARD spi_tx_data(0xd0); x_upper = _reg_CSPI_RXDATAREG(1); spi_tx_data(0x0); x_upper = _reg_CSPI_RXDATAREG(1); spi_tx_data(0x90); x_lower = _reg_CSPI_RXDATAREG(1); spi_tx_data(0x0); y_upper = _reg_CSPI_RXDATAREG(1); spi_tx_data(0x0); y_lower = _reg_CSPI_RXDATAREG(1);#endif#ifdef MX1_ADS_BOARD /*spi_tx_data(0xD0); x_upper = REG_SPI_RXDATA;// this should be the dummy data spi_tx_data(0x00); x_upper = REG_SPI_RXDATA; spi_tx_data(0x90); x_lower = REG_SPI_RXDATA; spi_tx_data(0x00); y_upper = REG_SPI_RXDATA; spi_tx_data(0x00); y_lower = REG_SPI_RXDATA; */ spi_tx_data(0xD0); x_upper = rSPRDAT0;//REG_SPI_RXDATA;// this should be the dummy data spi_tx_data(0x00); x_upper = rSPRDAT0;//REG_SPI_RXDATA; spi_tx_data(0x90); x_lower = rSPRDAT0;//REG_SPI_RXDATA; spi_tx_data(0x00); y_upper = rSPRDAT0;//REG_SPI_RXDATA; spi_tx_data(0x00); y_lower = rSPRDAT0;//REG_SPI_RXDATA;#endif#ifdef PXA270 spi_tx_data(0xD0); x_upper = (U32 )spi_rx_data(); x_lower = (U32 )spi_rx_data(); spi_tx_data(0x90); y_upper = (U32 )spi_rx_data(); y_lower = (U32 )spi_rx_data();#endif *x=( ((x_upper<<5) & 0xFE0) | ((x_lower>>3) & 0x1F) ); *y=( ((y_upper<<5) & 0xFE0) | ((y_lower>>3) & 0x1F) ); touch_pan_disable();// printk("x = %d y = %d\n",*x,*y);#ifdef MX21_ADS_BOARD _reg_CSPI_CONTROLREG(1) &= ~0x00000400; //disable spi _reg_GPIO_ISR(4) = temp;#endif //printk("TP read dev 3\n");#ifdef MX1_ADS_BOARD //REG_SPI_CONTRL &= (~SPI_EN_BIT);//disable SPI// REG_PB_ISR = temp;#endif //printk("TP read dev 4\n"); //touch_pan_enable_inter(); //printk("TP read dev 5\n"); }void touch_pan_read_data(u32* x,u32* y){//HHTECH wk#define NUM_OF_SAMPLE (8)#define MAX_POS_DIFF (2) u32 xPos[NUM_OF_SAMPLE], yPos[NUM_OF_SAMPLE]; u32 midx,midy; int diffx,diffy,ic;#if 0if(testcount == 1) { for(ic=0;ic<200;ic++) touch_pan_read_dev(&xPos[0], &yPos[0]); testcount = 0; delcount = 0;}#endif touch_pan_read_dev(&xPos[0], &yPos[0]); if ((xPos[0]<100)||(xPos[0]>5000) || (yPos[0]<100)||(yPos[0]>5000)) { *x = TPNL_PEN_UPVALUE; *y = TPNL_PEN_UPVALUE; return; } touch_pan_read_dev(&xPos[1], &yPos[1]); if ((xPos[1]<100)||(xPos[1]>5000) || (yPos[1]<100)||(yPos[1]>5000)) { *x = TPNL_PEN_UPVALUE; *y = TPNL_PEN_UPVALUE; return; }#if 0 touch_pan_read_dev(&xPos[2], &yPos[2]); if ((xPos[2]<100)||(xPos[2]>5000) || (yPos[2]<100)||(yPos[2]>5000)) { *x = TPNL_PEN_UPVALUE; *y = TPNL_PEN_UPVALUE; return; } touch_pan_read_dev(&xPos[3], &yPos[3]); if ((xPos[3]<100)||(xPos[3]>5000) || (yPos[3]<100)||(yPos[3]>5000)) { *x = TPNL_PEN_UPVALUE; *y = TPNL_PEN_UPVALUE; return; } touch_pan_read_dev(&xPos[4], &yPos[4]); if ((xPos[4]<100)||(xPos[4]>5000) || (yPos[4]<100)||(yPos[4]>5000)) { *x = TPNL_PEN_UPVALUE; *y = TPNL_PEN_UPVALUE; return; } touch_pan_read_dev(&xPos[5], &yPos[5]); if ((xPos[5]<100)||(xPos[5]>5000) || (yPos[5]<100)||(yPos[5]>5000)) { *x = TPNL_PEN_UPVALUE; *y = TPNL_PEN_UPVALUE; return; } touch_pan_read_dev(&xPos[6], &yPos[6]); if ((xPos[6]<100)||(xPos[6]>5000) || (yPos[6]<100)||(yPos[6]>5000)) { *x = TPNL_PEN_UPVALUE; *y = TPNL_PEN_UPVALUE; return; } touch_pan_read_dev(&xPos[7], &yPos[7]); if ((xPos[7]<100)||(xPos[7]>5000) || (yPos[7]<100)||(yPos[7]>5000)) { *x = TPNL_PEN_UPVALUE; *y = TPNL_PEN_UPVALUE; return; } midx=(xPos[0]+xPos[1]+xPos[2]+xPos[3]+xPos[4]+xPos[5]+xPos[6]+xPos[7])>>3; midy=(yPos[0]+yPos[1]+yPos[2]+yPos[3]+yPos[4]+yPos[5]+yPos[6]+yPos[7])>>3;#else midx = (xPos[0] + xPos[1])>>1; midy = (yPos[0] + yPos[1])>>1;#endif#if 0if(delcount) { diffx = midx - testx; diffy = midy - testy; diffx = diffx > 0 ? diffx : -diffx;diffy = diffy > 0 ? diffy : -diffy; if(diffx > 80 || diffy > 80) { midx = testx;midy = testy;// printk("del point\n"); }}#endif *x = midx; *y = midy;// testx = midx; testy = midy; delcount++; //printk("x %d y %d \n",*x,*y); return;}/******************************************************************************* Function Name: digi_isr** Input: filp :* wait : * Value Returned: * * Description: support touch pannel interrupt * *****************************************************************************/#if 0static void coordinate_conversion(U32 sX,U32 sY){ int x,y; unsigned int i; /* X 240 Y 320 X min 337 max 3702 each inch 14 Y min 305 max 3763 each inch 11 */ i=sX; x= (i-421 )/((3430-421)/220); i=sY; y= (i-419 )/((3665-419)/300); newsX1=(int)x; if (newsX1<0) newsX1=0; if (newsX1>240) newsX1=240; newsY1=(int)y; if (newsY1<0) newsY1=0; if (newsY1>320) newsY1=320;}#endifstatic void wait_inter_high(){ spin_lock_irq(&pen_lock); pen_timer.expires = jiffies + HZ/200; add_timer(&pen_timer); pen_timer_status = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -