summaryrefslogtreecommitdiff
path: root/drivers/input/touchscreen/ssd253x_ts/ssd253x-ts.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen/ssd253x_ts/ssd253x-ts.c')
-rwxr-xr-xdrivers/input/touchscreen/ssd253x_ts/ssd253x-ts.c1827
1 files changed, 1827 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/ssd253x_ts/ssd253x-ts.c b/drivers/input/touchscreen/ssd253x_ts/ssd253x-ts.c
new file mode 100755
index 00000000..c02392cb
--- /dev/null
+++ b/drivers/input/touchscreen/ssd253x_ts/ssd253x-ts.c
@@ -0,0 +1,1827 @@
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+//#include <asm/gpio.h>
+#include <asm/irq.h>
+#include <linux/irq.h>
+#include <asm/io.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <mach/hardware.h>
+#include <linux/platform_device.h>
+#include <linux/suspend.h>
+#include <linux/slab.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif /* CONFIG_HAS_EARLYSUSPEND */
+
+
+#include "ssd253x-ts.h"
+#include "wmt_ts.h"
+
+//#define CONFIG_TOUCHSCREEN_SSL_DEBUG
+#undef CONFIG_TOUCHSCREEN_SSL_DEBUG
+
+#define DEVICE_ID_REG 2
+#define VERSION_ID_REG 3
+#define AUTO_INIT_RST_REG 68
+#define EVENT_STATUS 121
+#define EVENT_MSK_REG 122
+#define IRQ_MSK_REG 123
+#define FINGER01_REG 124
+#define EVENT_STACK 128
+#define EVENT_FIFO_SCLR 135
+#define TIMESTAMP_REG 136
+#define SELFCAP_STATUS_REG 185
+
+#define ON_TOUCH_INT INT_EI11 //GPIO :set the interrupt
+#define DEVICE_NAME "touch_ssd253x"
+#define SSD253X_I2C_ADDR 0x48 //0x48
+
+// SSD2533 Setting
+// Touch Panel Example
+static struct ChipSetting* ssd253xcfgTable = NULL;
+static int l_cfglen = 0;
+
+static struct ChipSetting ssd253xcfgTable_default[]={
+{2,0x06,0x1B,0x28},
+{2,0xd7,0x00,0x00},
+{2,0xd8,0x00,0x07},
+{2,0xdb,0x00,0x01},
+{2,0x30,0x03,0x08},
+{2,0x34,0xd4,0x1e},
+{2,0x57,0x00,0x06},
+{2,0x40,0x00,0xc8},
+{2,0x41,0x00,0x30},
+{2,0x42,0x00,0xc0},
+{2,0x43,0x00,0x30},
+{2,0x44,0x00,0xc0},
+{2,0x45,0x00,0xc0},
+{2,0x46,0x00,0x0f},
+{2,0x5f,0x00,0x00},
+{2,0x2d,0x00,0x00},
+{2,0x66,0x1F,0x38},
+{2,0x67,0x1c,0x92},
+{2,0x25,0x00,0x02},
+};
+
+
+// For SSD2533 Bug Version Only //
+//#define SSD2533FIXEDCODE
+ struct ChipSetting ssd253xcfgTable1[]={
+{ 1, 0xA4, 0x00, 0x00}, //MCU prescaler default=01
+{ 1, 0xD4, 0x08, 0x00}, //Dummy Code
+{ 1, 0xD4, 0x08, 0x00}, //Set Osc frequency default=8, range 0 to F
+};
+
+ struct ChipSetting Reset[]={
+{ 0, 0x04, 0x00, 0x00}, // SSD2533
+};
+
+ struct ChipSetting Resume[]={
+{ 0, 0x04, 0x00, 0x00}, // SSD2533
+{ 1, 0x25, 0x12, 0x00}, // Set Operation Mode //Set from int setting
+};
+
+ struct ChipSetting Suspend[] ={
+{ 1, 0x25, 0x00, 0x00}, // Set Operation Mode
+{ 0, 0x05, 0x00, 0x00}, // SSD2533
+};
+
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void ssd253x_ts_early_suspend(struct early_suspend *h);
+static void ssd253x_ts_late_resume(struct early_suspend *h);
+#endif /* CONFIG_HAS_EARLYSUSPEND */
+
+static irqreturn_t ssd253x_ts_isr(int irq, void *dev_id);
+static enum hrtimer_restart ssd253x_ts_timer(struct hrtimer *timer);
+//extern int wmt_i2c_xfer_continue_if_4(struct i2c_msg *msg, unsigned int num,int bus_id);
+
+
+static int SSDS53X_SCREEN_MAX_X = 800;
+static int SSDS53X_SCREEN_MAX_Y = 480;
+
+
+
+enum{
+ IC_SSD2533 = 1,
+ IC_SSD2543,
+ IC_SSD2531
+};
+
+static int ic_flag;
+
+static struct workqueue_struct *ssd253x_wq;
+
+int Ssd_Timer1,Ssd_Timer2,Ssd_Timer_flag;
+
+struct ssl_ts_priv {
+ struct input_dev *input;
+ struct hrtimer timer;
+ struct work_struct ssl_work;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend early_suspend;
+#endif
+
+ int irq;
+ int use_irq;
+ int FingerNo;
+ int earlysus;
+
+ int FingerX[FINGERNO];
+ int FingerY[FINGERNO];
+ int FingerP[FINGERNO];
+
+ int Resolution;
+ int EventStatus;
+ int FingerDetect;
+
+ int sFingerX[FINGERNO];
+ int sFingerY[FINGERNO];
+ int pFingerX[FINGERNO];
+ int pFingerY[FINGERNO];
+};
+
+static struct ssl_ts_priv* l_ts = NULL;
+struct wmtts_device ssd253x_tsdev;
+static DECLARE_WAIT_QUEUE_HEAD(ts_penup_wait_queue);
+
+#define SD_INIT
+#ifdef SD_INIT
+#define TP_CHR "tp_chr"
+
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <asm/uaccess.h>
+
+static long tp_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+static int tp_open(struct inode *inode, struct file *file);
+static int tp_release(struct inode *inode, struct file *file);
+static ssize_t tp_read(struct file *file, char __user *buf, size_t count,loff_t *offset);
+static ssize_t tp_write(struct file *file, const char __user *buf,size_t count, loff_t *offset);
+
+//void InitFromSD(struct i2c_client *client);
+
+//struct ChipSetting _ssd253xcfgTable[200];
+//int sd_init_size=0;
+
+
+//struct i2c_client *g_tp_client;
+
+#endif
+
+
+
+static int ReadRegister(/*struct i2c_client *client,*/uint8_t reg,int ByteNo)
+{
+ unsigned char buf[4];
+ struct i2c_msg msg[2];
+ int ret;
+ struct i2c_client* client = ts_get_i2c_client();
+
+ memset(buf, 0xFF, sizeof(buf));
+ msg[0].addr = SSD253X_I2C_ADDR;
+ msg[0].flags = 0 | I2C_M_NOSTART;
+ msg[0].len = 1;
+ msg[0].buf = &reg;
+
+ msg[1].addr = SSD253X_I2C_ADDR;
+ msg[1].flags = I2C_M_RD;
+ msg[1].len = ByteNo;
+ msg[1].buf = buf;
+
+ ret = i2c_transfer(client->adapter, msg, 2);
+ if (ret <= 0)
+ {
+ printk("read the address (0x%x) of the ssd253x fail, ret=%d.\n", reg, ret);
+ return -1;
+ }
+
+ if(ByteNo==1) return (int)((unsigned int)buf[0]<<0);
+ if(ByteNo==2) return (int)((unsigned int)buf[1]<<0)|((unsigned int)buf[0]<<8);
+ if(ByteNo==3) return (int)((unsigned int)buf[2]<<0)|((unsigned int)buf[1]<<8)|((unsigned int)buf[0]<<16);
+ if(ByteNo==4) return (int)((unsigned int)buf[3]<<0)|((unsigned int)buf[2]<<8)|((unsigned int)buf[1]<<16)|(buf[0]<<24);
+ return 0;
+}
+
+static int WriteRegister(/*struct i2c_client *client,*/uint8_t Reg,unsigned char Data1,unsigned char Data2,int ByteNo)
+{
+ struct i2c_msg msg;
+ unsigned char buf[4];
+ int ret;
+ struct i2c_client* client = ts_get_i2c_client();
+
+ buf[0]=Reg;
+ buf[1]=Data1;
+ buf[2]=Data2;
+ buf[3]=0;
+
+ msg.addr = SSD253X_I2C_ADDR;
+ msg.flags = 0;
+ msg.len = ByteNo+1;
+ msg.buf = (char *)buf;
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret <= 0)
+ {
+ printk(KERN_ERR "write the address (0x%x) of the ssd25xx fail, ret=%d.\n", buf[0], ret);
+ return -1;
+ }
+ return 0;
+
+}
+
+int SSD253xdeviceInit1(void)
+{
+#ifdef SSD2533FIXEDCODE
+ int i;
+ mdelay(600); //SSD2533 ESD2 EEPROM VERSION
+ for(i=0;i<sizeof(ssd253xcfgTable1)/sizeof(ssd253xcfgTable1[0]);i++)
+ {
+ if (WriteRegister(ssd253xcfgTable1[i].Reg,
+ ssd253xcfgTable1[i].Data1,ssd253xcfgTable1[i].Data2,
+ ssd253xcfgTable1[i].No))
+ {
+ return -1;
+ }
+ }
+#endif
+ return 0;
+}
+
+int SSD253xdeviceInit(void)
+{
+ int i;
+
+ for(i=0;i<l_cfglen/*sizeof(ssd253xcfgTable)/sizeof(ssd253xcfgTable[0])*/;i++)
+ {
+ if (WriteRegister(ssd253xcfgTable[i].Reg,
+ ssd253xcfgTable[i].Data1,ssd253xcfgTable[i].Data2,
+ ssd253xcfgTable[i].No))
+ {
+ return -1;
+ }
+ if (0 == i)
+ {
+ msleep(300);
+ }
+ }
+ msleep(300);
+ return 0;
+}
+
+int deviceReset(void)
+{
+ int i;
+
+ i = 0;//just for remove warning message
+ wmt_rst_output(1);
+ mdelay(5);
+ wmt_rst_output(0);
+ mdelay(10);
+ wmt_rst_output(1);
+ msleep(200);
+
+ //if(ic_flag == IC_SSD2533){
+ for(i=0;i<sizeof(Reset)/sizeof(Reset[0]);i++)
+ {
+ if (WriteRegister(Reset[i].Reg,
+ Reset[i].Data1,Reset[i].Data2,
+ Reset[i].No))
+ {
+ return -1;
+ }
+ }
+ //}
+
+ mdelay(100);
+ if (SSD253xdeviceInit1())
+ {
+ return -1;
+ }
+ return 0;
+}
+
+int deviceResume(void)
+{
+ int i;
+ for(i=0;i<sizeof(Resume)/sizeof(Resume[0]);i++)
+ {
+ if (WriteRegister(Resume[i].Reg,
+ Resume[i].Data1,Resume[i].Data2,
+ Resume[i].No))
+ {
+ return -1;
+ }
+ mdelay(100);
+ }
+ return 0;
+}
+
+int deviceSuspend(void)
+{
+ int i;
+ //int timeout=10;
+ //int status;
+
+ for(i=0;i<sizeof(Suspend)/sizeof(Suspend[0]);i++)
+ {
+ if (WriteRegister(Suspend[i].Reg,
+ Suspend[i].Data1,Suspend[i].Data2,
+ Suspend[i].No))
+ {
+ return -1;
+ }
+ mdelay(100);
+ }
+ return 0;
+}
+
+#define Mode RunningAverageMode
+#define Dist RunningAverageDist
+void RunningAverage(unsigned short *xpos,unsigned short *ypos,int No,struct ssl_ts_priv *ssl_priv)
+{
+ int FilterMode[4][2]={{0,8},{5,3},{6,2},{7,1}};
+ int dx,dy;
+ int X,Y;
+
+ X=*xpos;
+ Y=*ypos;
+ if((ssl_priv->pFingerX[No]!=0x0FFF)&&(X!=0x0FFF))
+ {
+ dx=abs(ssl_priv->pFingerX[No]-X);
+ dy=abs(ssl_priv->pFingerY[No]-Y);
+ if(dx+dy<Dist*64)
+ {
+ ssl_priv->pFingerX[No]=(FilterMode[Mode][0]*ssl_priv->pFingerX[No]+FilterMode[Mode][1]*X)/8;
+ ssl_priv->pFingerY[No]=(FilterMode[Mode][0]*ssl_priv->pFingerY[No]+FilterMode[Mode][1]*Y)/8;
+ }
+ else
+ {
+ ssl_priv->pFingerX[No]=X;
+ ssl_priv->pFingerY[No]=Y;
+ }
+ }
+ else
+ {
+ ssl_priv->pFingerX[No]=X;
+ ssl_priv->pFingerY[No]=Y;
+ }
+ *xpos=ssl_priv->pFingerX[No];
+ *ypos=ssl_priv->pFingerY[No];
+}
+
+void FingerCheckSwap(int *FingerX,int *FingerY,int *FingerP,int FingerNo,int *sFingerX,int *sFingerY)
+{
+ int i,j;
+ int index1,index2;
+ int Vx,Vy;
+ int Ux,Uy;
+ int R1x,R1y;
+ int R2x,R2y;
+ for(i=0;i<FingerNo;i++)
+ {
+ index1=i;
+ if( FingerX[index1]!=0xFFF)
+ if(sFingerX[index1]!=0xFFF)
+ {
+ for(j=i+1;j<FingerNo+3;j++)
+ {
+ index2=j%FingerNo;
+ if( FingerX[index2]!=0xFFF)
+ if(sFingerX[index2]!=0xFFF)
+ {
+ Ux=sFingerX[index1]-sFingerX[index2];
+ Uy=sFingerY[index1]-sFingerY[index2];
+ Vx= FingerX[index1]- FingerX[index2];
+ Vy= FingerY[index1]- FingerY[index2];
+
+ R1x=Ux-Vx;
+ R1y=Uy-Vy;
+ R2x=Ux+Vx;
+ R2y=Uy+Vy;
+
+ R1x=R1x*R1x;
+ R1y=R1y*R1y;
+ R2x=R2x*R2x;
+ R2y=R2y*R2y;
+
+ if(R1x+R1y>R2x+R2y)
+ {
+ Ux=FingerX[index1];
+ Uy=FingerY[index1];
+ Vx=FingerP[index1];
+
+ FingerX[index1]=FingerX[index2];
+ FingerY[index1]=FingerY[index2];
+ FingerP[index1]=FingerP[index2];
+
+ FingerX[index2]=Ux;
+ FingerY[index2]=Uy;
+ FingerP[index2]=Vx;
+ }
+ break;
+ }
+ }
+ }
+ }
+ for(i=0;i<FingerNo;i++)
+ {
+ sFingerX[i]=FingerX[i];
+ sFingerY[i]=FingerY[i];
+ }
+}
+
+#ifdef USE_TOUCH_KEY
+static void ssd2533_ts_send_keyevent(struct ssl_ts_priv *ssl_priv,u8 btn_status, int downup)
+{
+
+ switch(btn_status & 0x0f)
+ {
+ case 0x01:
+ input_report_key(ssl_priv->input, KEY_SEARCH, downup);
+ break;
+ case 0x02:
+ input_report_key(ssl_priv->input, KEY_BACK, downup);
+ break;
+ case 0x04:
+ input_report_key(ssl_priv->input, KEY_HOME, downup);
+ break;
+ case 0x08:
+ input_report_key(ssl_priv->input, KEY_MENU, downup);
+ break;
+ default:
+ break;
+ }
+ dbg("send %x %x\n", btn_status, downup);
+}
+#endif
+
+// for ssd2533(no test)
+static int ssd253x_ts_cut_edge0(unsigned short pos,unsigned short x_y)
+{
+ u8 cut_value = 26; //26 cut_value < 32
+ if(pos == 0xfff)
+ {
+ return pos;
+ }
+ //printk("X: rude data %d\n",pos);
+ if(x_y) //xpos
+ {
+
+ if(pos < 16)
+ pos = cut_value + pos*(48 - cut_value) / 16;
+ else if(pos > (XPOS_MAX - 16) )
+ pos = XPOS_MAX + 16 + (pos - (XPOS_MAX -16))*(48 - cut_value) / 16;
+ else
+ pos = pos + 32;
+
+ pos = SSDS53X_SCREEN_MAX_X * pos / (DRIVENO * 64);
+ //printk("X: changed data %d\n",pos);
+ return pos;
+ }
+ else //ypos
+ {
+ if(pos < 16)
+ pos = cut_value + pos*(48 - cut_value) / 16;
+ else if(pos > (YPOS_MAX - 16) )
+ pos = YPOS_MAX + 16 + (pos - (YPOS_MAX -16))*(48 - cut_value) / 16;
+ else
+ pos = pos + 32;
+ //printk("Y: rude data %d\n",pos);
+ pos = SSDS53X_SCREEN_MAX_Y* pos / (SENSENO * 64);
+ //printk("Y: changed data %d\n",pos);
+ return pos;
+ }
+
+
+}
+
+// for ssd2532
+static int ssd253x_ts_cut_edge1(unsigned short pos,unsigned short x_y)
+{
+ u8 cut_value = 15; //cut_value < 32
+
+ if(pos == 0xfff){
+ return pos;
+ }
+
+ if(x_y){ //xpos 64-->96 //MAX=896
+ pos = pos + cut_value;//????????Ե
+ pos = SSDS53X_SCREEN_MAX_X * pos / (790+cut_value*2);//SSDS53X_SCREEN_MAX_X?????ұ?Ե
+ return pos;
+ }else{ //ypos //MAX=576
+ pos = pos + cut_value;//?????ϱ?Ե
+ pos = SSDS53X_SCREEN_MAX_Y* pos / (470+cut_value*2);//SSDS53X_SCREEN_MAX_Y?????±?Ե
+ return pos;
+ }
+}
+
+// for ssd2532,8" ssd253x_pydctp80a1.ts
+// x_y:1--x,0--y
+static int ssd253x_ts_cut_edge2(unsigned short pos,unsigned short x_y)
+{
+ int tpos;
+
+ if (pos == 0xfff){
+ return pos;
+ }
+
+ tpos = pos;
+ if (x_y)
+ {
+ if (tpos<20)
+ {
+ tpos= tpos+18;
+ } else if (tpos>585)
+ {
+ tpos = tpos-18;
+ } else {
+ tpos = (tpos-20)*565/575+30;
+ }
+ pos = tpos;
+ return pos;
+ } else {
+ if (tpos <10)
+ {
+ tpos = tpos+10;
+ } else if (tpos >795)
+ {
+ tpos = 795;
+ } else {
+ tpos = (tpos-10)*775/785+20;
+ }
+ pos = tpos;
+ return pos;
+ }
+
+}
+// for ssd2532
+static int ssd253x_ts_cut_edge3(unsigned short pos,unsigned short x_y)
+{
+ u8 cut_value = 15;
+
+ if(pos == 0xfff){
+ return pos;
+ }
+
+ if(x_y){
+ pos = pos + cut_value;
+ pos = SSDS53X_SCREEN_MAX_X * pos / (896+cut_value*2);
+ return pos;
+ }else{
+ pos = pos + cut_value;
+ pos = SSDS53X_SCREEN_MAX_Y* pos / (576+cut_value*2);
+ return pos;
+ }
+}
+
+// for jun feng TP
+static int ssd253x_ts_cut_edge4(unsigned short pos,unsigned short x_y)
+{
+ unsigned short Cut_Edge_XLeft[64]={
+ 0x0008,0x0009,0x000B,0x000C,0x000D,0x000E,0x0010,0x0011,
+ 0x0012,0x0013,0x0015,0x0016,0x0017,0x0018,0x001A,0x001B,
+ 0x001C,0x001D,0x001F,0x0020,0x0021,0x0022,0x0024,0x0025,
+ 0x0026,0x0026,0x0027,0x0028,0x0029,0x002A,0x002B,0x002C,
+ 0x002C,0x002D,0x002E,0x002F,0x0030,0x0031,0x0032,0x0032,
+ 0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0038,0x0039,
+ 0x003A,0x003B,0x003C,0x003D,0x003E,0x003E,0x003F,0x0040,
+ 0x0041,0x0042,0x0043,0x0044,0x0044,0x0045,0x0046,0x0047
+ };
+
+ unsigned short Cut_Edge_XRight[64]={
+ 0x0318,0x0317,0x0315,0x0314,0x0313,0x0312,0x0310,0x030F,
+ 0x030E,0x030D,0x030B,0x030A,0x0309,0x0308,0x0306,0x0305,
+ 0x0304,0x0303,0x0301,0x0300,0x02FF,0x02FE,0x02FC,0x02FB,
+ 0x02FA,0x02FA,0x02F9,0x02F8,0x02F7,0x02F6,0x02F5,0x02F4,
+ 0x02F4,0x02F3,0x02F2,0x02F1,0x02F0,0x02EF,0x02EE,0x02EE,
+ 0x02ED,0x02EC,0x02EB,0x02EA,0x02E9,0x02E8,0x02E8,0x02E7,
+ 0x02E6,0x02E5,0x02E4,0x02E3,0x02E2,0x02E2,0x02E1,0x02E0,
+ 0x02DF,0x02DE,0x02DD,0x02DC,0x02DC,0x02DB,0x02DA,0x02D9
+ };
+
+ unsigned short Cut_Edge_YUp[64]={
+ 0x0006,0x0007,0x0008,0x000A,0x000B,0x000C,0x000D,0x000F,
+ 0x0010,0x0011,0x0012,0x0014,0x0015,0x0016,0x0017,0x0018,
+ 0x001A,0x001B,0x001C,0x001D,0x001F,0x0020,0x0021,0x0022,
+ 0x0022,0x0023,0x0024,0x0025,0x0025,0x0026,0x0027,0x0028,
+ 0x0029,0x0029,0x002A,0x002B,0x002C,0x002C,0x002D,0x002E,
+ 0x002F,0x0030,0x0030,0x0031,0x0032,0x0033,0x0033,0x0034,
+ 0x0035,0x0036,0x0037,0x0037,0x0038,0x0039,0x003A,0x003A,
+ 0x003B,0x003C,0x003D,0x003E,0x003E,0x003F,0x0040,0x0041
+ };
+
+ unsigned short Cut_Edge_YDown[64]={
+ 0x01DA,0x01D9,0x01D8,0x01D6,0x01D5,0x01D4,0x01D3,0x01D1,
+ 0x01D0,0x01CF,0x01CE,0x01CC,0x01CB,0x01CA,0x01C9,0x01C8,
+ 0x01C6,0x01C5,0x01C4,0x01C3,0x01C1,0x01C0,0x01BF,0x01BE,
+ 0x01BE,0x01BD,0x01BC,0x01BB,0x01BB,0x01BA,0x01B9,0x01B8,
+ 0x01B7,0x01B7,0x01B6,0x01B5,0x01B4,0x01B4,0x01B3,0x01B2,
+ 0x01B1,0x01B0,0x01B0,0x01AF,0x01AE,0x01AD,0x01AD,0x01AC,
+ 0x01AB,0x01AA,0x01A9,0x01A9,0x01A8,0x01A7,0x01A6,0x01A6,
+ 0x01A5,0x01A4,0x01A3,0x01A2,0x01A2,0x01A1,0x01A0,0x019F
+ };
+ int cut_value = 5; //cut_value < 32
+ if(pos == 0xfff)
+ {
+ return pos;
+ }
+ if(x_y) //xpos
+ {
+ dbg("X: Raw data %d\n",pos);
+ if (pos >=XPOS_MAX)
+ {
+ pos = XPOS_MAX;
+ }
+ if (pos<64)
+ {
+ pos = Cut_Edge_XLeft[pos]; //Left cut edge
+ }
+ else
+ if ((XPOS_MAX - pos) <64)
+ {
+ pos = Cut_Edge_XRight[XPOS_MAX - pos]; //Right cut edge
+ }
+ else
+ {
+ pos = pos + cut_value; //
+ pos = SSDS53X_SCREEN_MAX_X* pos / (790 + cut_value*2);//SSD253X_SCREEN_MAX_X|?????2????????|?
+ }
+ dbg("X: Cut edge data %d\n",pos);
+ return pos;
+ }
+ else //ypos
+ {
+
+ dbg("Y: Raw data %d\n",pos);
+ if (pos >=YPOS_MAX)
+ {
+ pos = YPOS_MAX;
+ }
+ if (pos<64)
+ {
+ pos = Cut_Edge_YUp[pos]; //Up cut edge
+ }
+ else
+ if ((YPOS_MAX - pos) <64)
+ {
+ pos = Cut_Edge_YDown[YPOS_MAX - pos]; //Down cut edge
+ }
+ else
+ {
+ pos = pos + cut_value; //
+ pos = SSDS53X_SCREEN_MAX_Y* pos / (470 + cut_value*2);//SSD253X_SCREEN_MAX_X|?????2????????|?
+ //tpos = pos;
+ //tpos = /*SSDS53X_SCREEN_MAX_Y*/ (800* pos) / (470 + cut_value*2);
+ dbg("XPOS_MAX=%d,\n", XPOS_MAX);
+ dbg("YPOS_MAX=%d,\n",YPOS_MAX);
+ dbg("Y: Cut edge data pos= %d,tpos=%d\n",pos,tpos);
+ }
+
+ return pos;
+ }
+
+
+}
+
+static int ssd253x_ts_cut_edge5(unsigned short pos,unsigned short x_y)
+{
+ unsigned short Cut_Edge_XLeft[64]={
+ 0x0008,0x0009,0x000B,0x000C,0x000D,0x000E,0x0010,0x0011,
+ 0x0012,0x0013,0x0015,0x0016,0x0017,0x0018,0x001A,0x001B,
+ 0x001C,0x001D,0x001F,0x0020,0x0021,0x0022,0x0024,0x0025,
+ 0x0026,0x0026,0x0027,0x0028,0x0029,0x002A,0x002B,0x002C,
+ 0x002C,0x002D,0x002E,0x002F,0x0030,0x0031,0x0032,0x0032,
+ 0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0038,0x0039,
+ 0x003A,0x003B,0x003C,0x003D,0x003E,0x003E,0x003F,0x0040,
+ 0x0041,0x0042,0x0043,0x0044,0x0044,0x0045,0x0046,0x0047
+ };
+
+ unsigned short Cut_Edge_XRight[64]={
+ 0x0318,0x0317,0x0315,0x0314,0x0313,0x0312,0x0310,0x030F,
+ 0x030E,0x030D,0x030B,0x030A,0x0309,0x0308,0x0306,0x0305,
+ 0x0304,0x0303,0x0301,0x0300,0x02FF,0x02FE,0x02FC,0x02FB,
+ 0x02FA,0x02FA,0x02F9,0x02F8,0x02F7,0x02F6,0x02F5,0x02F4,
+ 0x02F4,0x02F3,0x02F2,0x02F1,0x02F0,0x02EF,0x02EE,0x02EE,
+ 0x02ED,0x02EC,0x02EB,0x02EA,0x02E9,0x02E8,0x02E8,0x02E7,
+ 0x02E6,0x02E5,0x02E4,0x02E3,0x02E2,0x02E2,0x02E1,0x02E0,
+ 0x02DF,0x02DE,0x02DD,0x02DC,0x02DC,0x02DB,0x02DA,0x02D9
+ };
+
+ unsigned short Cut_Edge_YUp[64]={
+ 0x0006,0x0007,0x0008,0x000A,0x000B,0x000C,0x000D,0x000F,
+ 0x0010,0x0011,0x0012,0x0014,0x0015,0x0016,0x0017,0x0018,
+ 0x001A,0x001B,0x001C,0x001D,0x001F,0x0020,0x0021,0x0022,
+ 0x0022,0x0023,0x0024,0x0025,0x0025,0x0026,0x0027,0x0028,
+ 0x0029,0x0029,0x002A,0x002B,0x002C,0x002C,0x002D,0x002E,
+ 0x002F,0x0030,0x0030,0x0031,0x0032,0x0033,0x0033,0x0034,
+ 0x0035,0x0036,0x0037,0x0037,0x0038,0x0039,0x003A,0x003A,
+ 0x003B,0x003C,0x003D,0x003E,0x003E,0x003F,0x0040,0x0041
+ };
+
+ unsigned short Cut_Edge_YDown[64]={
+ 0x01DA,0x01D9,0x01D8,0x01D6,0x01D5,0x01D4,0x01D3,0x01D1,
+ 0x01D0,0x01CF,0x01CE,0x01CC,0x01CB,0x01CA,0x01C9,0x01C8,
+ 0x01C6,0x01C5,0x01C4,0x01C3,0x01C1,0x01C0,0x01BF,0x01BE,
+ 0x01BE,0x01BD,0x01BC,0x01BB,0x01BB,0x01BA,0x01B9,0x01B8,
+ 0x01B7,0x01B7,0x01B6,0x01B5,0x01B4,0x01B4,0x01B3,0x01B2,
+ 0x01B1,0x01B0,0x01B0,0x01AF,0x01AE,0x01AD,0x01AD,0x01AC,
+ 0x01AB,0x01AA,0x01A9,0x01A9,0x01A8,0x01A7,0x01A6,0x01A6,
+ 0x01A5,0x01A4,0x01A3,0x01A2,0x01A2,0x01A1,0x01A0,0x019F
+ };
+ u8 cut_value = 20; //cut_value < 32
+ if(pos == 0xfff)
+ {
+ return pos;
+ }
+ if(x_y) //xpos
+ {
+ dbg("X: Raw data %d\n",pos);
+ if (pos >=XPOS_MAX)
+ {
+ pos = XPOS_MAX;
+ }
+ if (pos<64)
+ {
+ pos = Cut_Edge_XLeft[pos]; //Left cut edge
+ }
+ else
+ if ((XPOS_MAX - pos) <64)
+ {
+ pos = Cut_Edge_XRight[XPOS_MAX - pos]; //Right cut edge
+ }
+ else
+ {
+ pos = pos + cut_value; //
+ pos = SSDS53X_SCREEN_MAX_X * pos / (XPOS_MAX + cut_value*2);//SSD253X_SCREEN_MAX_X|??????????|? }
+ dbg("X: Cut edge data %d\n",pos);
+ return pos;
+ }
+ }
+ else //ypos
+ {
+
+ dbg("Y: Raw data %d\n",pos);
+ if (pos >=YPOS_MAX)
+ {
+ pos = YPOS_MAX;
+ }
+ if (pos<64)
+ {
+ pos = Cut_Edge_YUp[pos]; //Up cut edge
+ }
+ else
+ if ((YPOS_MAX - pos) <64)
+ {
+ pos = Cut_Edge_YDown[YPOS_MAX - pos]; //Down cut edge
+ }
+ else
+ {
+ pos = pos + cut_value; //
+ pos = SSDS53X_SCREEN_MAX_Y * pos / (YPOS_MAX + cut_value*2);//SSD253X_SCREEN_MAX_X|??????????|? }
+ dbg("Y: Cut edge data %d\n",pos);
+ return pos;
+ }
+ }
+ return -1;
+}
+
+static int ssd253x_ts_cut_edge6(unsigned short pos,unsigned short x_y)
+{
+
+ #define XPOS_MAX_D (DRIVENO -EdgeDisable) *64
+ #define YPOS_MAX_D (SENSENO -EdgeDisable) *64
+ #undef SSD253X_SCREEN_MAX_X
+ #define SSD253X_SCREEN_MAX_X 800
+ #define SSD253X_SCREEN_MAX_Y 480
+
+ u8 cut_value = 20; //cut_value < 32
+ unsigned short Cut_Edge_XLeft[64]={
+ 0x0008,0x0009,0x000B,0x000C,0x000D,0x000E,0x0010,0x0011,
+ 0x0012,0x0013,0x0015,0x0016,0x0017,0x0018,0x001A,0x001B,
+ 0x001C,0x001D,0x001F,0x0020,0x0021,0x0022,0x0024,0x0025,
+ 0x0026,0x0026,0x0027,0x0028,0x0029,0x002A,0x002B,0x002C,
+ 0x002C,0x002D,0x002E,0x002F,0x0030,0x0031,0x0032,0x0032,
+ 0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0038,0x0039,
+ 0x003A,0x003B,0x003C,0x003D,0x003E,0x003E,0x003F,0x0040,
+ 0x0041,0x0042,0x0043,0x0044,0x0044,0x0045,0x0046,0x0047
+ };
+
+ unsigned short Cut_Edge_XRight[64]={
+ 0x0318,0x0317,0x0315,0x0314,0x0313,0x0312,0x0310,0x030F,
+ 0x030E,0x030D,0x030B,0x030A,0x0309,0x0308,0x0306,0x0305,
+ 0x0304,0x0303,0x0301,0x0300,0x02FF,0x02FE,0x02FC,0x02FB,
+ 0x02FA,0x02FA,0x02F9,0x02F8,0x02F7,0x02F6,0x02F5,0x02F4,
+ 0x02F4,0x02F3,0x02F2,0x02F1,0x02F0,0x02EF,0x02EE,0x02EE,
+ 0x02ED,0x02EC,0x02EB,0x02EA,0x02E9,0x02E8,0x02E8,0x02E7,
+ 0x02E6,0x02E5,0x02E4,0x02E3,0x02E2,0x02E2,0x02E1,0x02E0,
+ 0x02DF,0x02DE,0x02DD,0x02DC,0x02DC,0x02DB,0x02DA,0x02D9
+ };
+
+ unsigned short Cut_Edge_YUp[64]={
+ 0x0006,0x0007,0x0008,0x000A,0x000B,0x000C,0x000D,0x000F,
+ 0x0010,0x0011,0x0012,0x0014,0x0015,0x0016,0x0017,0x0018,
+ 0x001A,0x001B,0x001C,0x001D,0x001F,0x0020,0x0021,0x0022,
+ 0x0022,0x0023,0x0024,0x0025,0x0025,0x0026,0x0027,0x0028,
+ 0x0029,0x0029,0x002A,0x002B,0x002C,0x002C,0x002D,0x002E,
+ 0x002F,0x0030,0x0030,0x0031,0x0032,0x0033,0x0033,0x0034,
+ 0x0035,0x0036,0x0037,0x0037,0x0038,0x0039,0x003A,0x003A,
+ 0x003B,0x003C,0x003D,0x003E,0x003E,0x003F,0x0040,0x0041
+ };
+
+ unsigned short Cut_Edge_YDown[64]={
+ 0x01DA,0x01D9,0x01D8,0x01D6,0x01D5,0x01D4,0x01D3,0x01D1,
+ 0x01D0,0x01CF,0x01CE,0x01CC,0x01CB,0x01CA,0x01C9,0x01C8,
+ 0x01C6,0x01C5,0x01C4,0x01C3,0x01C1,0x01C0,0x01BF,0x01BE,
+ 0x01BE,0x01BD,0x01BC,0x01BB,0x01BB,0x01BA,0x01B9,0x01B8,
+ 0x01B7,0x01B7,0x01B6,0x01B5,0x01B4,0x01B4,0x01B3,0x01B2,
+ 0x01B1,0x01B0,0x01B0,0x01AF,0x01AE,0x01AD,0x01AD,0x01AC,
+ 0x01AB,0x01AA,0x01A9,0x01A9,0x01A8,0x01A7,0x01A6,0x01A6,
+ 0x01A5,0x01A4,0x01A3,0x01A2,0x01A2,0x01A1,0x01A0,0x019F
+ };
+
+
+ if(pos == 0xfff)
+ {
+ return pos;
+ }
+ if(x_y) //xpos
+ {
+ //#ifdef CONFIG_TS_CUTEDGE_DEBUG
+ dbg("X: Raw data %d\n",pos);
+ //#endif
+ if (pos >=XPOS_MAX_D)
+ {
+ pos = XPOS_MAX_D;
+ }
+ if (pos<64)
+ {
+ pos = Cut_Edge_XLeft[pos]; //Left cut edge
+ }
+ else
+ if ((XPOS_MAX_D - pos) <64)
+ {
+ pos = Cut_Edge_XRight[XPOS_MAX_D - pos]; //Right cut edge
+ }
+ else
+ {
+ pos = pos + cut_value; //
+ pos = SSD253X_SCREEN_MAX_X * pos / (XPOS_MAX_D + cut_value*2);//SSD253X_SCREEN_MAX_X|?????2????????|?
+ }
+ //#ifdef CONFIG_TS_CUTEDGE_DEBUG
+ dbg("X: Cut edge data %d\n",pos);
+ //#endif
+ return pos;
+ }
+ else //ypos
+ {
+
+ //#ifdef CONFIG_TS_CUTEDGE_DEBUG
+ dbg("Y: Raw data %d\n",pos);
+ //#endif
+ if (pos >=YPOS_MAX_D)
+ {
+ pos = YPOS_MAX_D;
+ }
+ if (pos<64)
+ {
+ pos = Cut_Edge_YUp[pos]; //Up cut edge
+ }
+ else
+ if ((YPOS_MAX_D - pos) <64)
+ {
+ pos = Cut_Edge_YDown[YPOS_MAX_D - pos]; //Down cut edge
+ }
+ else
+ {
+ pos = pos + cut_value; //
+ pos = SSD253X_SCREEN_MAX_Y * pos / (YPOS_MAX_D + cut_value*2);//SSD253X_SCREEN_MAX_X|?????2????????|?
+ }
+ //#ifdef CONFIG_TS_CUTEDGE_DEBUG
+ dbg("Y: Cut edge data %d\n",pos);
+ //#endif
+ return pos;
+ }
+ return -1;
+}
+
+static int ssd253x_ts_cut_edge8(unsigned short pos,unsigned short x_y)
+{
+
+ #define XPOS_MAX_D (DRIVENO -EdgeDisable) *64
+ #define YPOS_MAX_D (SENSENO -EdgeDisable) *64
+ #undef SSD253X_SCREEN_MAX_X
+ #define SSD253X_SCREEN_MAX_X 780
+ #undef SSD253X_SCREEN_MAX_Y
+ #define SSD253X_SCREEN_MAX_Y 470
+
+ u8 cut_value = 10;//30; //cut_value < 32
+ unsigned short Cut_Edge_XLeft[64]={
+ 0x0008,0x0009,0x000B,0x000C,0x000D,0x000E,0x0010,0x0011,
+ 0x0012,0x0013,0x0015,0x0016,0x0017,0x0018,0x001A,0x001B,
+ 0x001C,0x001D,0x001F,0x0020,0x0021,0x0022,0x0024,0x0025,
+ 0x0026,0x0026,0x0027,0x0028,0x0029,0x002A,0x002B,0x002C,
+ 0x002C,0x002D,0x002E,0x002F,0x0030,0x0031,0x0032,0x0032,
+ 0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0038,0x0039,
+ 0x003A,0x003B,0x003C,0x003D,0x003E,0x003E,0x003F,0x0040,
+ 0x0041,0x0042,0x0043,0x0044,0x0044,0x0045,0x0046,0x0047
+ };
+
+ unsigned short Cut_Edge_XRight[64]={
+ 0x0318,0x0317,0x0315,0x0314,0x0313,0x0312,0x0310,0x030F,
+ 0x030E,0x030D,0x030B,0x030A,0x0309,0x0308,0x0306,0x0305,
+ 0x0304,0x0303,0x0301,0x0300,0x02FF,0x02FE,0x02FC,0x02FB,
+ 0x02FA,0x02FA,0x02F9,0x02F8,0x02F7,0x02F6,0x02F5,0x02F4,
+ 0x02F4,0x02F3,0x02F2,0x02F1,0x02F0,0x02EF,0x02EE,0x02EE,
+ 0x02ED,0x02EC,0x02EB,0x02EA,0x02E9,0x02E8,0x02E8,0x02E7,
+ 0x02E6,0x02E5,0x02E4,0x02E3,0x02E2,0x02E2,0x02E1,0x02E0,
+ 0x02DF,0x02DE,0x02DD,0x02DC,0x02DC,0x02DB,0x02DA,0x02D9
+ };
+
+ unsigned short Cut_Edge_YUp[64]={
+ 0x0006,0x0007,0x0008,0x000A,0x000B,0x000C,0x000D,0x000F,
+ 0x0010,0x0011,0x0012,0x0014,0x0015,0x0016,0x0017,0x0018,
+ 0x001A,0x001B,0x001C,0x001D,0x001F,0x0020,0x0021,0x0022,
+ 0x0022,0x0023,0x0024,0x0025,0x0025,0x0026,0x0027,0x0028,
+ 0x0029,0x0029,0x002A,0x002B,0x002C,0x002C,0x002D,0x002E,
+ 0x002F,0x0030,0x0030,0x0031,0x0032,0x0033,0x0033,0x0034,
+ 0x0035,0x0036,0x0037,0x0037,0x0038,0x0039,0x003A,0x003A,
+ 0x003B,0x003C,0x003D,0x003E,0x003E,0x003F,0x0040,0x0041
+ };
+
+ unsigned short Cut_Edge_YDown[64]={
+ 0x01DA,0x01D9,0x01D8,0x01D6,0x01D5,0x01D4,0x01D3,0x01D1,
+ 0x01D0,0x01CF,0x01CE,0x01CC,0x01CB,0x01CA,0x01C9,0x01C8,
+ 0x01C6,0x01C5,0x01C4,0x01C3,0x01C1,0x01C0,0x01BF,0x01BE,
+ 0x01BE,0x01BD,0x01BC,0x01BB,0x01BB,0x01BA,0x01B9,0x01B8,
+ 0x01B7,0x01B7,0x01B6,0x01B5,0x01B4,0x01B4,0x01B3,0x01B2,
+ 0x01B1,0x01B0,0x01B0,0x01AF,0x01AE,0x01AD,0x01AD,0x01AC,
+ 0x01AB,0x01AA,0x01A9,0x01A9,0x01A8,0x01A7,0x01A6,0x01A6,
+ 0x01A5,0x01A4,0x01A3,0x01A2,0x01A2,0x01A1,0x01A0,0x019F
+ };
+
+
+ if(pos == 0xfff)
+ {
+ return pos;
+ }
+ if(x_y) //xpos
+ {
+ //#ifdef CONFIG_TS_CUTEDGE_DEBUG
+ dbg("X: Raw data %d\n",pos);
+ //#endif
+ if (pos >=XPOS_MAX_D)
+ {
+ pos = XPOS_MAX_D;
+ }
+ if (pos<64)
+ {
+ pos = Cut_Edge_XLeft[pos]; //Left cut edge
+ }
+ else
+ if ((XPOS_MAX_D - pos) <64)
+ {
+ pos = Cut_Edge_XRight[XPOS_MAX_D - pos]; //Right cut edge
+ }
+ else
+ {
+ pos = pos + cut_value; //
+ pos = SSD253X_SCREEN_MAX_X * pos / (XPOS_MAX_D + cut_value*2);//SSD253X_SCREEN_MAX_X|?????2????????|?
+ }
+ //#ifdef CONFIG_TS_CUTEDGE_DEBUG
+ dbg("X: Cut edge data %d\n",pos);
+ //#endif
+ return pos;
+ }
+ else //ypos
+ {
+
+ //#ifdef CONFIG_TS_CUTEDGE_DEBUG
+ dbg("Y: Raw data %d\n",pos);
+ //#endif
+ if (pos >=YPOS_MAX_D)
+ {
+ pos = YPOS_MAX_D;
+ }
+ if (pos<64)
+ {
+ pos = Cut_Edge_YUp[pos]; //Up cut edge
+ }
+ else
+ if ((YPOS_MAX_D - pos) <64)
+ {
+ pos = Cut_Edge_YDown[YPOS_MAX_D - pos]; //Down cut edge
+ }
+ else
+ {
+ pos = pos + cut_value; //
+ pos = SSD253X_SCREEN_MAX_Y * pos / (YPOS_MAX_D + cut_value*2);//SSD253X_SCREEN_MAX_X|?????2????????|?
+ }
+ //#ifdef CONFIG_TS_CUTEDGE_DEBUG
+ dbg("Y: Cut edge data %d\n",pos);
+ //#endif
+ return pos;
+ }
+}
+
+static int ssd253x_ts_cut_edge7(unsigned short pos,unsigned short x_y)
+{
+ unsigned short SENSENO_7 = 15;
+ unsigned short DRIVENO_7 = 20;
+ unsigned short EdgeDisable_7 = 1; // if Edge Disable, set it to 1, else reset to 0, OR SSD2533 set 0
+ unsigned short XPOS_MAX_7 = (DRIVENO_7 -EdgeDisable_7) *64;
+ unsigned short YPOS_MAX_7 = (SENSENO_7 -EdgeDisable_7) *64;
+
+ u8 cut_value = 10; //cut_value < 32
+ dbg("enter...\n");
+
+ if(pos == 0xfff)
+ {
+ return pos;
+ }
+ if(x_y) //xpos
+ {
+ if(pos < 16)
+ pos = cut_value + pos*(48 - cut_value) / 16;
+ else if(pos > (XPOS_MAX_7 - 16) )
+ pos = XPOS_MAX_7 + 16 + (pos - (XPOS_MAX_7 -16))*(48 - cut_value) / 16;
+ else
+ pos = pos + 32;
+ dbg("xpos_b:%d\n", pos);
+ pos = SSDS53X_SCREEN_MAX_X * pos / (DRIVENO_7 * 64);
+ dbg("xpos_a:%d\n", pos);
+ return pos;
+ }
+ else //ypos
+ {
+ if(pos < 16)
+ pos = cut_value + pos*(48 - cut_value) / 16;
+ else if(pos > (YPOS_MAX_7 - 16) )
+ pos = YPOS_MAX_7 + 16 + (pos - (YPOS_MAX_7 -16))*(48 - cut_value) / 16;
+ else
+ pos = pos + 32;
+ dbg("ypos_b:%d\n", pos);
+ pos = SSDS53X_SCREEN_MAX_Y* pos / (SENSENO_7 * 64);
+ dbg("ypos_a:%d\n", pos);
+ return pos;
+ }
+
+
+}
+
+
+static int ssd253x_ts_cut_edge(unsigned short pos,unsigned short x_y)
+{
+ switch (wmt_ts_get_cutedge())
+ {
+ case 0:
+ return ssd253x_ts_cut_edge0(pos,x_y);
+ break;
+ case 1:
+ return ssd253x_ts_cut_edge1(pos,x_y);
+ break;
+ case 2:
+ return ssd253x_ts_cut_edge2(pos,x_y);
+ break;
+ case 3:
+ return ssd253x_ts_cut_edge3(pos,x_y);
+ break;
+ case 4:
+ return ssd253x_ts_cut_edge4(pos,x_y);
+ break;
+ case 5:
+ return ssd253x_ts_cut_edge5(pos,x_y);
+ break;
+ case 6:
+ return ssd253x_ts_cut_edge6(pos,x_y);
+ break;
+ case 7:
+ return ssd253x_ts_cut_edge7(pos,x_y);
+ break;
+ case 8:
+ return ssd253x_ts_cut_edge8(pos,x_y);
+ break;
+ default:
+ return -1;
+ };
+}
+
+#ifdef USE_TOUCH_KEY
+static u8 btn_status_last = 0;
+#endif
+
+static void ssd253x_ts_work(struct work_struct *work)
+{
+ int i;
+ unsigned short xpos=0, ypos=0;
+ int tx,ty;
+ //width=0;
+ int FingerInfo;
+ int EventStatus;
+ int FingerX[FINGERNO];
+ int FingerY[FINGERNO];
+ int FingerP[FINGERNO];
+ int clrFlag=0;
+ int Ssd_Timer;
+ #ifdef USE_TOUCH_KEY
+ u8 btn_status;
+ u8 btn_status_last = 0;
+ #endif
+
+ struct ssl_ts_priv *ssl_priv = l_ts;
+
+ #ifdef USE_TOUCH_KEY
+ btn_status = ReadRegister(ssl_priv->client,SELFCAP_STATUS_REG, 1);
+ //#ifdef CONFIG_TOUCHSCREEN_SSL_DEBUG
+ dbg("btn pressed:%x\n", btn_status & 0x0f);
+ //#endif
+ if (btn_status_last != btn_status){
+ if(btn_status){
+ btn_status_last = btn_status;
+ ssd2533_ts_send_keyevent(ssl_priv,btn_status, 1);
+ dbg("send %x btn_status_last%d \n", btn_status,btn_status_last);
+ }
+ else{
+ ssd2533_ts_send_keyevent(ssl_priv,btn_status_last, 0);
+ btn_status_last = 0;
+ dbg("btn_status_last %x \n", btn_status_last);
+ }
+ return ;
+ }
+ #endif
+
+ Ssd_Timer = 0;
+ if(ic_flag == IC_SSD2533){
+ if(!Ssd_Timer_flag){
+ Ssd_Timer = ReadRegister(TIMESTAMP_REG,2);
+ if(!Ssd_Timer1){
+ Ssd_Timer1 = Ssd_Timer/1000;
+ }
+
+ Ssd_Timer2 = Ssd_Timer/1000;
+
+
+ if((Ssd_Timer2 - Ssd_Timer1) > 10){
+ WriteRegister(AUTO_INIT_RST_REG,0x00,0x00,1);
+ Ssd_Timer_flag = 1;
+ }
+ }
+ }
+
+ EventStatus = ReadRegister(EVENT_STATUS,2)>>4;
+ ssl_priv->FingerDetect=0;
+ for(i=0;i<ssl_priv->FingerNo;i++){
+ if((EventStatus>>i)&0x1){
+ FingerInfo=ReadRegister(FINGER01_REG+i,4);
+ xpos = ((FingerInfo>>4)&0xF00)|((FingerInfo>>24)&0xFF);
+ ypos = ((FingerInfo>>0)&0xF00)|((FingerInfo>>16)&0xFF);
+ dbg("raw data before cut, F%d:(%d,%d)\n",i,xpos,ypos);
+ if(xpos!=0xFFF){
+ ssl_priv->FingerDetect++;
+ if (wmt_ts_get_cutedge()>=0){
+ xpos = ssd253x_ts_cut_edge(xpos, 1);
+ ypos = ssd253x_ts_cut_edge(ypos, 0);
+ }
+ }else {
+ EventStatus=EventStatus&~(1<<i);
+ clrFlag=1;
+ }
+ }else{
+ xpos=ypos=0xFFF;
+ clrFlag=1;
+ }
+ FingerX[i]=xpos;
+ FingerY[i]=ypos;
+ }
+
+ if(ssl_priv->use_irq==1) wmt_enable_gpirq();
+ if(ssl_priv->use_irq==2)
+ {
+ if(ssl_priv->FingerDetect==0)
+ {
+ wmt_enable_gpirq();
+ } else {
+ hrtimer_start(&ssl_priv->timer, ktime_set(0, MicroTimeTInterupt), HRTIMER_MODE_REL);
+ }
+ }
+ if(ic_flag == IC_SSD2533){
+ if(clrFlag) WriteRegister(EVENT_FIFO_SCLR,0x01,0x00,1);
+ }
+
+ if(ssl_priv->input->id.product==0x2533)
+ if(ssl_priv->input->id.version==0x0101)
+ FingerCheckSwap(FingerX,FingerY,FingerP,ssl_priv->FingerNo,ssl_priv->sFingerX,ssl_priv->sFingerY);
+
+ // report data
+ for(i=0;i<ssl_priv->FingerNo;i++)
+ {
+ xpos=FingerX[i];
+ ypos=FingerY[i];
+ if(ssl_priv->input->id.product==0x2533){
+ if(ssl_priv->input->id.version==0x0101) RunningAverage(&xpos,&ypos,i,ssl_priv);
+ if(ssl_priv->input->id.version==0x0102) RunningAverage(&xpos,&ypos,i,ssl_priv);
+ }
+
+ if(xpos!=0xFFF)
+ {
+ dbg("raw data after cut, F%d:(%d,%d)\n",i,xpos,ypos);
+ switch (wmt_ts_get_xaxis())
+ {
+ case 1:
+ tx = ypos;
+ break;
+ case 0:
+ default:
+ tx = xpos;
+ break;
+ }
+
+ switch (wmt_ts_get_xdir())
+ {
+ case 1:
+ break;
+ case -1:
+ tx = SSDS53X_SCREEN_MAX_Y - tx;
+ break;
+ default:
+ break;
+ };
+
+ if (tx <0){
+ tx = 0;
+ } else if (tx >= SSDS53X_SCREEN_MAX_Y){
+ tx = SSDS53X_SCREEN_MAX_Y-1;
+ }
+ switch (wmt_ts_get_yaxis())
+ {
+
+ case 0:
+ ty = xpos;
+ break;
+ case 1:
+ default:
+ ty = ypos;
+ break;
+ }
+
+ switch (wmt_ts_get_ydir())
+ {
+ case 1:
+ break;
+ case -1:
+ ty = SSDS53X_SCREEN_MAX_X - ty;
+ default:
+ break;
+ }
+
+ if (ty < 0){
+ ty = 0;
+ } else if (ty >=SSDS53X_SCREEN_MAX_X){
+ ty = SSDS53X_SCREEN_MAX_X-1;
+ }
+
+ if (wmt_ts_get_lcdexchg()) {
+ int tmp;
+ tmp = tx;
+ tx = ty;
+ ty = wmt_ts_get_resolvX() - tmp;
+ }
+
+ ssd253x_tsdev.penup = 0;
+ input_report_abs(ssl_priv->input, ABS_MT_POSITION_X, tx);
+ input_report_abs(ssl_priv->input, ABS_MT_POSITION_Y, ty);
+ /*input_report_abs(ssl_priv->input, ABS_MT_POSITION_X, ty);
+ input_report_abs(ssl_priv->input, ABS_MT_POSITION_Y, tx);*/
+ input_mt_sync(ssl_priv->input);
+ dbg("report data x=%d,y=%d\n", tx, ty);
+
+ }
+ else if(ssl_priv->FingerX[i]!=0xFFF){
+ input_mt_sync(ssl_priv->input);
+ //printk("pen up...\n");
+ ssd253x_tsdev.penup = 1;
+ }
+
+ ssl_priv->FingerX[i]=FingerX[i];
+ ssl_priv->FingerY[i]=FingerY[i];
+ }
+
+ ssl_priv->EventStatus=EventStatus;
+ input_sync(ssl_priv->input);
+ if (1 == ssd253x_tsdev.penup){
+ wake_up(&ts_penup_wait_queue);
+ }
+
+}
+
+
+#define TPIC_INT_PLLLING 0
+#define TPIC_INT_INTERUPT 1
+#define TPIC_INT_HYBRID 2
+
+
+static int ssd253x_probe(struct platform_device *pdev)
+{
+ struct ssl_ts_priv *ssl_priv;
+ struct input_dev *ssl_input;
+ int error;
+ int i;
+ //unsigned int prescale;
+
+ //#ifdef SD_INIT
+ // g_tp_client = l_client;
+ //#endif
+
+ SSDS53X_SCREEN_MAX_X = wmt_ts_get_resolvY();
+ SSDS53X_SCREEN_MAX_Y = wmt_ts_get_resolvX();
+
+ ssl_priv = kzalloc(sizeof(*ssl_priv), GFP_KERNEL);
+ if (!ssl_priv)
+ {
+ errlog(" kzalloc Error!\n");
+ error=-ENODEV;
+ goto err0;
+ }
+ l_ts = ssl_priv;
+
+ ssl_input = input_allocate_device();
+ if (!ssl_input)
+ {
+ errlog(" ssd253x_ts_probe: input_allocate_device Error\n");
+ error=-ENODEV;
+ goto freealloc;
+ }
+ ssl_input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) | BIT_MASK(EV_SYN) ;
+ set_bit(INPUT_PROP_DIRECT,ssl_input->propbit);
+ ssl_input->name = DEVICE_NAME;
+ ssl_input->id.bustype = BUS_I2C;
+ ssl_input->id.vendor = 0x2878; // Modify for Vendor ID
+
+ ssl_priv->input = ssl_input;
+
+ ssl_priv->FingerNo=wmt_ts_get_fingernum();//FINGERNO;
+ ssl_priv->Resolution=64;
+
+ for(i=0;i<ssl_priv->FingerNo;i++)
+ {
+ ssl_priv->sFingerX[i]=0xFFF;
+ ssl_priv->sFingerY[i]=0xFFF;
+
+ // For Adaptive Running Average
+ ssl_priv->pFingerX[i]=0xFFF;
+ ssl_priv->pFingerY[i]=0xFFF;
+ }
+
+ deviceReset();
+ ssl_input->id.product = ReadRegister(DEVICE_ID_REG,2);
+ ssl_input->id.version = ReadRegister(VERSION_ID_REG,2);
+ ssl_input->id.product = ReadRegister(DEVICE_ID_REG,2);
+
+ ssl_input->id.version = ReadRegister(VERSION_ID_REG,2);
+ klog("SSL Touchscreen Device ID : 0x%04X\n",ssl_input->id.product);
+ klog("SSL Touchscreen Version ID : 0x%04X\n",ssl_input->id.version);
+
+ if(ssl_input->id.product == 0x2531){
+ ic_flag = IC_SSD2531;
+ }else if(ssl_input->id.product == 0x2533) {
+ ic_flag = IC_SSD2533;
+ }else if(ssl_input->id.product == 0x2543) {
+ ic_flag = IC_SSD2543;
+ }
+
+ if(ic_flag == IC_SSD2533) {
+ ssl_priv->use_irq = TPIC_INT_HYBRID;
+ }else if(ic_flag == IC_SSD2543) {
+ ssl_priv->use_irq = TPIC_INT_INTERUPT;
+ }
+
+ SSD253xdeviceInit();
+ if(ic_flag == IC_SSD2533) {
+ WriteRegister(EVENT_FIFO_SCLR,0x01,0x00,1); // clear Event FiFo
+ }
+
+
+ if(ssl_priv->input->id.product==0x2531)
+ ssl_priv->Resolution=32;
+ else if(ssl_priv->input->id.product==0x2533)
+ ssl_priv->Resolution=64;
+
+
+ if (wmt_ts_get_lcdexchg()) {
+ input_set_abs_params(ssl_input, ABS_MT_POSITION_X, 0,wmt_ts_get_resolvY(), 0, 0);
+ input_set_abs_params(ssl_input, ABS_MT_POSITION_Y, 0,wmt_ts_get_resolvX(), 0, 0);
+ } else {
+ input_set_abs_params(ssl_input, ABS_MT_POSITION_X, 0,wmt_ts_get_resolvX(), 0, 0);
+ input_set_abs_params(ssl_input, ABS_MT_POSITION_Y, 0,wmt_ts_get_resolvY(), 0, 0);
+ }
+
+#ifdef USE_TOUCH_KEY
+ set_bit(KEY_MENU, ssl_input->keybit);
+ set_bit(KEY_HOME, ssl_input->keybit);
+ set_bit(KEY_BACK, ssl_input->keybit);
+ set_bit(KEY_SEARCH, ssl_input->keybit);
+ #endif
+ error = input_register_device(ssl_input);
+ if(error)
+ {
+ errlog("input_register_device input Error!\n");
+ error=-ENODEV;
+ goto panel_init_fail;
+ }
+ if((ssl_priv->use_irq==0)||(ssl_priv->use_irq==2))
+ {
+ hrtimer_init(&ssl_priv->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ ssl_priv->timer.function = ssd253x_ts_timer;
+ //#ifdef CONFIG_TOUCHSCREEN_SSL_DEBUG
+ dbg(" ssd253x_ts_probe: timer_init OK!\n");
+ //#endif
+ }
+
+ ssd253x_wq = create_singlethread_workqueue("ssd253x_wq");
+ INIT_WORK(&ssl_priv->ssl_work, ssd253x_ts_work);
+ error = request_irq(wmt_get_tsirqnum(), ssd253x_ts_isr, IRQF_SHARED, "ssd253x_ts_q", l_ts);
+ if(error){
+ errlog("request_irq Error!\n");
+ error=-ENODEV;
+ goto freeque;
+ }
+
+ wmt_set_gpirq(IRQ_TYPE_EDGE_FALLING);
+ wmt_disable_gpirq();
+
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ ssl_priv->early_suspend.suspend = ssd253x_ts_early_suspend;
+ ssl_priv->early_suspend.resume = ssd253x_ts_late_resume;
+ ssl_priv->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN+2;
+ register_early_suspend(&ssl_priv->early_suspend);
+#endif
+ deviceResume();
+ wmt_enable_gpirq();
+ dbg("SSD253X init ok!\n");
+ return 0;
+
+freeque:
+ destroy_workqueue(ssd253x_wq);
+ input_unregister_device(ssl_input);
+panel_init_fail:
+ input_free_device(ssl_input);
+freealloc:
+ kfree(ssl_priv);
+err0:
+ //dev_set_drvdata(&client->dev, NULL);
+ return error;
+}
+
+static int ssd253x_remove(struct platform_device *pdev)
+{
+ struct ssl_ts_priv *ssl_priv = l_ts;
+
+ if((ssl_priv->use_irq==0)||(ssl_priv->use_irq==2)) hrtimer_cancel(&ssl_priv->timer);
+
+ //disable int
+ wmt_disable_gpirq();
+ //free irq
+ free_irq(wmt_get_tsirqnum(), l_ts);
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&ssl_priv->early_suspend);
+#endif
+ // free queue
+ cancel_work_sync (&ssl_priv->ssl_work);
+ flush_workqueue(ssd253x_wq);
+ destroy_workqueue(ssd253x_wq);
+ input_unregister_device(ssl_priv->input);
+ input_free_device(ssl_priv->input);
+ kfree(ssl_priv);
+ l_ts = NULL;
+ return 0;
+}
+
+
+/*
+static int ssd253x_ts_open(struct input_dev *dev)
+{
+ struct ssl_ts_priv *ssl_priv = l_ts;
+
+ deviceResume();
+ if(ssl_priv->use_irq)
+ {
+ wmt_enable_gpirq(); //(ssl_priv->irq);
+ } else {
+ hrtimer_start(&ssl_priv->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
+ }
+ return 0;
+}
+
+
+static void ssd253x_ts_close(struct input_dev *dev)
+{
+ struct ssl_ts_priv *ssl_priv = l_ts;
+
+ // disable interrupt
+ deviceSuspend();
+ if((ssl_priv->use_irq==0)||(ssl_priv->use_irq==2))
+ hrtimer_cancel(&ssl_priv->timer);
+ if((ssl_priv->use_irq==1)||(ssl_priv->use_irq==2))
+ wmt_disable_gpirq();//(ssl_priv->irq);
+}
+*/
+static int ssd253x_resume(struct platform_device *pdev)
+{
+ struct ssl_ts_priv *ssl_priv = l_ts;
+
+ wmt_disable_gpirq();
+ Ssd_Timer_flag = 0;
+ deviceReset();
+ SSD253xdeviceInit();
+ if(ic_flag == IC_SSD2533){
+ WriteRegister(EVENT_FIFO_SCLR,0x01,0x00,1); // clear Event FiFo
+ }
+ deviceResume();
+ wmt_set_gpirq(IRQ_TYPE_EDGE_FALLING);
+ wmt_enable_gpirq();
+
+ if(! ssl_priv->use_irq)
+ {
+ hrtimer_start(&ssl_priv->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
+ }
+ ssl_priv->earlysus = 0;
+ return 0;
+}
+
+static int ssd253x_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct ssl_ts_priv *ssl_priv = l_ts;
+
+ if((ssl_priv->use_irq==0)||(ssl_priv->use_irq==2)) hrtimer_cancel(&ssl_priv->timer);
+ // disable irq
+ wmt_disable_gpirq();
+ Ssd_Timer_flag = 0;
+ if(ic_flag == IC_SSD2533){
+ deviceSuspend();
+ }else if(ic_flag == IC_SSD2543){
+ deviceReset();
+ }
+ return 0;
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void ssd253x_ts_late_resume(struct early_suspend *h)
+{
+ struct ssl_ts_priv *ssl_priv = l_ts;
+
+ dbg("...\n");
+ if (ssl_priv->earlysus != 0)
+ {
+ wmt_disable_gpirq();
+ Ssd_Timer_flag = 0;
+ deviceReset();
+ SSD253xdeviceInit();
+ WriteRegister(EVENT_FIFO_SCLR,0x01,0x00,1); // clear Event FiFo
+ deviceResume();
+ wmt_set_gpirq(IRQ_TYPE_EDGE_FALLING);
+ wmt_enable_gpirq();
+
+ if(! ssl_priv->use_irq)
+ {
+ hrtimer_start(&ssl_priv->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
+ }
+ ssl_priv->earlysus = 0;
+ }
+}
+static void ssd253x_ts_early_suspend(struct early_suspend *h)
+{
+ struct ssl_ts_priv *ssl_priv = l_ts;
+
+ ssl_priv->earlysus = 1;
+ if((ssl_priv->use_irq==0)||(ssl_priv->use_irq==2)) hrtimer_cancel(&ssl_priv->timer);
+ // disable irq
+ wmt_disable_gpirq();
+ Ssd_Timer_flag = 0;
+ deviceSuspend();
+
+ return;
+}
+#endif
+
+
+static irqreturn_t ssd253x_ts_isr(int irq, void *dev_id)
+{
+ struct ssl_ts_priv *ssl_priv = l_ts;
+
+ if (wmt_is_tsint())
+ {
+ wmt_clr_int();
+ if (wmt_is_tsirq_enable())
+ {
+ wmt_disable_gpirq();
+ dbg("begin..\n");
+ if(!ssl_priv->earlysus)
+ {
+ queue_work(ssd253x_wq, &ssl_priv->ssl_work);
+ }
+ }
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static enum hrtimer_restart ssd253x_ts_timer(struct hrtimer *timer)
+{
+ struct ssl_ts_priv *ssl_priv = container_of(timer, struct ssl_ts_priv, timer);
+ #ifdef CONFIG_TOUCHSCREEN_SSL_DEBUG
+ printk("+-----------------------------------------+\n");
+ printk("| ssd253x_ts_timer! |\n");
+ printk("+-----------------------------------------+\n");
+ #endif
+ queue_work(ssd253x_wq, &ssl_priv->ssl_work);
+ if(ssl_priv->use_irq==0) hrtimer_start(&ssl_priv->timer, ktime_set(0, MicroTimeTInterupt), HRTIMER_MODE_REL);
+ return HRTIMER_NORESTART;
+}
+
+#ifdef SD_INIT
+static const struct file_operations tp_fops = {
+ .owner = THIS_MODULE,
+ .read = tp_read,
+ .write = tp_write,
+ .unlocked_ioctl = tp_ioctl,
+ .open = tp_open,
+ .release = tp_release,
+};
+
+static struct miscdevice misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = TP_CHR,
+ .fops = &tp_fops,
+};
+#endif
+
+
+static int ssd253x_init(void)
+{
+ char firmwname[60];
+ int i;
+
+ if (deviceReset() != 0)
+ return -1;
+ memset(firmwname,0,sizeof(firmwname));
+ wmt_ts_get_firmwname(firmwname);
+ i = read_firmwarefile(firmwname,&ssd253xcfgTable,0x100);
+ if (i <= 0)
+ {
+ l_cfglen = sizeof(ssd253xcfgTable_default)/sizeof(ssd253xcfgTable_default[0]);
+ ssd253xcfgTable = ssd253xcfgTable_default;
+ dbg("Using the default configure!\n");
+ } else {
+ l_cfglen = i;
+ }
+ Resume[1].No = ssd253xcfgTable[l_cfglen-1].No;
+ Resume[1].Reg = ssd253xcfgTable[l_cfglen-1].Reg;
+ Resume[1].Data1 = ssd253xcfgTable[l_cfglen-1].Data1;
+ Resume[1].Data2 = ssd253xcfgTable[l_cfglen-1].Data2;
+ if (SSD253xdeviceInit()!= 0)
+ {
+ if (i > 0)
+ {
+ kfree(ssd253xcfgTable);
+ }
+ return -1;
+ }
+ // init hardware
+
+#ifdef SD_INIT
+ misc_register(&misc);
+#endif
+
+
+ return 0;
+}
+
+static void ssd253x_exit(void)
+{
+ klog("remove the module\n");
+
+#ifdef SD_INIT
+ misc_deregister(&misc);
+#endif
+
+
+ if (ssd253xcfgTable != ssd253xcfgTable_default)
+ {
+ kfree(ssd253xcfgTable);
+ }
+
+}
+
+static int ssd253x_wait_penup(struct wmtts_device*tsdev)
+{
+ int ret = wait_event_interruptible(
+ ts_penup_wait_queue,
+ (1==tsdev->penup));
+ return ret;
+}
+
+
+struct wmtts_device raysen_tsdev = {
+ .driver_name = "ssd253x_ts",
+ .ts_id = "SSD253X",
+ .init = ssd253x_init,
+ .exit = ssd253x_exit,
+ .probe = ssd253x_probe,
+ .remove = ssd253x_remove,
+ .suspend = ssd253x_suspend,
+ .resume = ssd253x_resume,
+ .wait_penup = ssd253x_wait_penup,
+ .penup = 1,
+};
+
+#ifdef SD_INIT
+static long tp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ return 0;
+}
+
+static int tp_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+static int tp_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static ssize_t tp_read(struct file *file, char __user *buf, size_t count,loff_t *offset)
+{
+ char *kbuf;
+ uint8_t reg;
+ int ByteNo;
+ int readValue;
+ int i;
+
+ kbuf = kmalloc(count,GFP_KERNEL);
+
+ if(copy_from_user(kbuf,buf,1)) {
+ printk("no enough memory!\n");
+ return -1;
+ }
+
+ reg = (uint8_t)kbuf[0];
+ ByteNo = count;
+
+ readValue = ReadRegister( /*g_tp_client, */reg, ByteNo);
+
+ for(i = 0;i < ByteNo;i++){
+ kbuf[i] = (readValue>>(8*i)) & 0xff;
+ }
+
+ if(copy_to_user(buf,kbuf,count)) {
+ printk("no enough memory!\n");
+ return -1;
+ }
+
+ kfree(kbuf);
+
+ return count;
+}
+
+static ssize_t tp_write(struct file *file, const char __user *buf,size_t count, loff_t *offset)
+{
+ char *kbuf;
+
+ kbuf = kmalloc(count,GFP_KERNEL);
+
+ if(copy_from_user(kbuf,buf,count)) {
+ printk("no enough memory!\n");
+ return -1;
+ }
+
+ if(kbuf[1] == 0x01){
+ wmt_rst_output(0);
+ mdelay(5);
+ wmt_rst_output(1);
+ mdelay(20);
+ }
+ else
+ {
+ WriteRegister(/*g_tp_client,*/kbuf[1],kbuf[2],kbuf[3],kbuf[0]);
+ }
+
+ kfree(kbuf);
+
+ return count;
+}
+
+#endif
+
+
+
+
+MODULE_AUTHOR("Solomon Systech Ltd - Design Technology, Icarus Choi");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("ssd253x Touchscreen Driver 1.3");