input: touchscreen: add touch screen of gslx680 for rk3399-firefly-edp
[firefly-linux-kernel-4.4.55.git] / drivers / input / touchscreen / calibration_ts.c
1 /*\r
2  * drivers/input/touchscreen/calibration_ts.c - calibration for rk2818 spi xpt2046 device and console\r
3  *\r
4  * Copyright (C) 2010 ROCKCHIP, Inc.\r
5  *\r
6  * This software is licensed under the terms of the GNU General Public\r
7  * License version 2, as published by the Free Software Foundation, and\r
8  * may be copied, distributed, and modified under those terms.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  */\r
15 #include <linux/kernel.h>\r
16 #include <linux/string.h>\r
17 \r
18 #include "calibration_ts.h"\r
19 #include "largenum_ts.h"\r
20 \r
21 #define MAX_POINT_ERROR 6\r
22 \r
23 typedef struct {\r
24     PLARGENUM   pa11, pa12, pa13;\r
25     PLARGENUM   pa21, pa22, pa23;\r
26     PLARGENUM   pa31, pa32, pa33;\r
27 }   MATRIX33, *PMATRIX33;\r
28 \r
29 typedef struct {\r
30     int   a1;\r
31     int   b1;\r
32     int   c1;\r
33     int   a2;\r
34     int   b2;\r
35     int   c2;\r
36     int   delta;\r
37 }   \r
38 CALIBRATION_PARAMETER, *PCALIBRATION_PARAMETER;\r
39 \r
40 static unsigned char            v_Calibrated = 0;\r
41 static CALIBRATION_PARAMETER    v_CalcParam ={\r
42         .a1             =18670 ,\r
43         .b1             =98,\r
44         .c1             = -2230109,\r
45         .a2     = 291,\r
46         .b2             = 12758,\r
47         .c2             = -5118934,\r
48         .delta  = 91931,\r
49 };\r
50 static CALIBRATION_PARAMETER v_CalcParam_bak = {\r
51         .a1=17704 ,\r
52         .b1=-20,\r
53         .c1= -1460283,\r
54         .a2   = 382,\r
55         .b2  = 12685,\r
56         .c2  = -5595261,\r
57         .delta   = 88403,\r
58 };\r
59 unsigned char\r
60 ErrorAnalysis(\r
61     int   cCalibrationPoints,     //@PARM The number of calibration points\r
62     int   *pScreenXBuffer,        //@PARM List of screen X coords displayed\r
63     int   *pScreenYBuffer,        //@PARM List of screen Y coords displayed\r
64     int   *pUncalXBuffer,         //@PARM List of X coords collected\r
65     int   *pUncalYBuffer          //@PARM List of Y coords collected\r
66     );\r
67 \r
68 void\r
69 ComputeMatrix33(\r
70     PLARGENUM   pResult,\r
71     PMATRIX33   pMatrix\r
72     );\r
73 \r
74 unsigned char\r
75 TouchPanelSetCalibration(\r
76     int   cCalibrationPoints,     //@PARM The number of calibration points\r
77     int   *pScreenXBuffer,        //@PARM List of screen X coords displayed\r
78     int   *pScreenYBuffer,        //@PARM List of screen Y coords displayed\r
79     int   *pUncalXBuffer,         //@PARM List of X coords collected\r
80     int   *pUncalYBuffer          //@PARM List of Y coords collected\r
81     )\r
82 {\r
83     LARGENUM    a11;\r
84     LARGENUM    a21, a22;\r
85     LARGENUM    a31, a32, a33;\r
86     LARGENUM    b11, b12, b13;\r
87     LARGENUM    b21, b22, b23;\r
88     LARGENUM    lnScreenX;\r
89     LARGENUM    lnScreenY;\r
90     LARGENUM    lnTouchX;\r
91     LARGENUM    lnTouchY;\r
92     LARGENUM    lnTemp;\r
93     LARGENUM    delta;\r
94     LARGENUM    a1, b1, c1;\r
95     LARGENUM    a2, b2, c2;\r
96     MATRIX33    Matrix;\r
97     int       cShift;\r
98     int       minShift;\r
99     int         i;\r
100 \r
101 \r
102     //DEBUGMSG(1,(__TEXT("calibrating %d point set\r\n"), cCalibrationPoints));\r
103 \r
104      //\r
105      // If the calibration data is being cleared, set the flag so\r
106      // that the conversion operation is a noop.\r
107      //\r
108 \r
109     if ( cCalibrationPoints == 0 )\r
110     {\r
111         v_Calibrated = 0;\r
112         return 1;\r
113     }\r
114 \r
115     //\r
116     // Compute these large numbers\r
117     //\r
118     LargeNumSet(&a11, 0);\r
119     LargeNumSet(&a21, 0);\r
120     LargeNumSet(&a31, 0);\r
121     LargeNumSet(&a22, 0);\r
122     LargeNumSet(&a32, 0);\r
123     LargeNumSet(&a33, cCalibrationPoints);\r
124     LargeNumSet(&b11, 0);\r
125     LargeNumSet(&b12, 0);\r
126     LargeNumSet(&b13, 0);\r
127     LargeNumSet(&b21, 0);\r
128     LargeNumSet(&b22, 0);\r
129     LargeNumSet(&b23, 0);\r
130     for(i=0; i<cCalibrationPoints; i++){\r
131         LargeNumSet(&lnTouchX, pUncalXBuffer[i]);\r
132         LargeNumSet(&lnTouchY, pUncalYBuffer[i]);\r
133         LargeNumSet(&lnScreenX, pScreenXBuffer[i]);\r
134         LargeNumSet(&lnScreenY, pScreenYBuffer[i]);\r
135         LargeNumMult(&lnTouchX, &lnTouchX, &lnTemp);\r
136         LargeNumAdd(&a11, &lnTemp, &a11);\r
137         LargeNumMult(&lnTouchX, &lnTouchY, &lnTemp);\r
138         LargeNumAdd(&a21, &lnTemp, &a21);\r
139         LargeNumAdd(&a31, &lnTouchX, &a31);\r
140         LargeNumMult(&lnTouchY, &lnTouchY, &lnTemp);\r
141         LargeNumAdd(&a22, &lnTemp, &a22);\r
142         LargeNumAdd(&a32, &lnTouchY, &a32);\r
143         LargeNumMult(&lnTouchX, &lnScreenX, &lnTemp);\r
144         LargeNumAdd(&b11, &lnTemp, &b11);\r
145         LargeNumMult(&lnTouchY, &lnScreenX, &lnTemp);\r
146         LargeNumAdd(&b12, &lnTemp, &b12);\r
147         LargeNumAdd(&b13, &lnScreenX, &b13);\r
148         LargeNumMult(&lnTouchX, &lnScreenY, &lnTemp);\r
149         LargeNumAdd(&b21, &lnTemp, &b21);\r
150         LargeNumMult(&lnTouchY, &lnScreenY, &lnTemp);\r
151         LargeNumAdd(&b22, &lnTemp, &b22);\r
152         LargeNumAdd(&b23, &lnScreenY, &b23);\r
153     }\r
154 \r
155     Matrix.pa11 = &a11;\r
156     Matrix.pa21 = &a21;\r
157     Matrix.pa31 = &a31;\r
158     Matrix.pa12 = &a21;\r
159     Matrix.pa22 = &a22;\r
160     Matrix.pa32 = &a32;\r
161     Matrix.pa13 = &a31;\r
162     Matrix.pa23 = &a32;\r
163     Matrix.pa33 = &a33;\r
164     ComputeMatrix33(&delta, &Matrix);\r
165 \r
166     Matrix.pa11 = &b11;\r
167     Matrix.pa21 = &b12;\r
168     Matrix.pa31 = &b13;\r
169     ComputeMatrix33(&a1, &Matrix);\r
170 \r
171     Matrix.pa11 = &a11;\r
172     Matrix.pa21 = &a21;\r
173     Matrix.pa31 = &a31;\r
174     Matrix.pa12 = &b11;\r
175     Matrix.pa22 = &b12;\r
176     Matrix.pa32 = &b13;\r
177     ComputeMatrix33(&b1, &Matrix);\r
178 \r
179     Matrix.pa12 = &a21;\r
180     Matrix.pa22 = &a22;\r
181     Matrix.pa32 = &a32;\r
182     Matrix.pa13 = &b11;\r
183     Matrix.pa23 = &b12;\r
184     Matrix.pa33 = &b13;\r
185     ComputeMatrix33(&c1, &Matrix);\r
186 \r
187     Matrix.pa13 = &a31;\r
188     Matrix.pa23 = &a32;\r
189     Matrix.pa33 = &a33;\r
190     Matrix.pa11 = &b21;\r
191     Matrix.pa21 = &b22;\r
192     Matrix.pa31 = &b23;\r
193     ComputeMatrix33(&a2, &Matrix);\r
194 \r
195     Matrix.pa11 = &a11;\r
196     Matrix.pa21 = &a21;\r
197     Matrix.pa31 = &a31;\r
198     Matrix.pa12 = &b21;\r
199     Matrix.pa22 = &b22;\r
200     Matrix.pa32 = &b23;\r
201     ComputeMatrix33(&b2, &Matrix);\r
202 \r
203     Matrix.pa12 = &a21;\r
204     Matrix.pa22 = &a22;\r
205     Matrix.pa32 = &a32;\r
206     Matrix.pa13 = &b21;\r
207     Matrix.pa23 = &b22;\r
208     Matrix.pa33 = &b23;\r
209     ComputeMatrix33(&c2, &Matrix);\r
210 \r
211 #if 1\r
212     {\r
213         LARGENUM    halfDelta;\r
214         //\r
215         // Take care of possible truncation error in later mapping operations\r
216         //\r
217         if(IsLargeNumNegative(&delta)){\r
218             LargeNumDivInt32(&delta, -2, &halfDelta);\r
219         } else {\r
220             LargeNumDivInt32(&delta, 2, &halfDelta);\r
221         }\r
222         LargeNumAdd(&c1, &halfDelta, &c1);\r
223         LargeNumAdd(&c2, &halfDelta, &c2);\r
224     }\r
225 #endif\r
226 \r
227     //\r
228     // All the numbers are determined now.\r
229     // Let's scale them back to 32 bit world\r
230     //\r
231     minShift = 0;\r
232     cShift = LargeNumBits(&a1) - MAX_COEFF_PRECISION;\r
233     if(cShift > minShift){\r
234         minShift = cShift;\r
235     }\r
236     cShift = LargeNumBits(&b1) - MAX_COEFF_PRECISION;\r
237     if(cShift > minShift){\r
238         minShift = cShift;\r
239     }\r
240     cShift = LargeNumBits(&a2) - MAX_COEFF_PRECISION;\r
241     if(cShift > minShift){\r
242         minShift = cShift;\r
243     }\r
244     cShift = LargeNumBits(&b2) - MAX_COEFF_PRECISION;\r
245     if(cShift > minShift){\r
246         minShift = cShift;\r
247     }\r
248     cShift = LargeNumBits(&c1) - MAX_TERM_PRECISION;\r
249     if(cShift > minShift){\r
250         minShift = cShift;\r
251     }\r
252     cShift = LargeNumBits(&c2) - MAX_TERM_PRECISION;\r
253     if(cShift > minShift){\r
254         minShift = cShift;\r
255     }\r
256     cShift = LargeNumBits(&delta) - 31;\r
257     if(cShift > minShift){\r
258         minShift = cShift;\r
259     }\r
260 \r
261     //\r
262     // Now, shift count is determined, shift all the numbers\r
263     //  right to obtain the 32-bit signed values\r
264     //\r
265     if(minShift){\r
266         LargeNumRAShift(&a1, minShift);\r
267         LargeNumRAShift(&a2, minShift);\r
268         LargeNumRAShift(&b1, minShift);\r
269         LargeNumRAShift(&b2, minShift);\r
270         LargeNumRAShift(&c1, minShift);\r
271         LargeNumRAShift(&c2, minShift);\r
272         LargeNumRAShift(&delta, minShift);\r
273     }\r
274     v_CalcParam.a1      = a1.u.s32.u[0];\r
275     v_CalcParam.b1      = b1.u.s32.u[0];\r
276     v_CalcParam.c1      = c1.u.s32.u[0];\r
277     v_CalcParam.a2      = a2.u.s32.u[0];\r
278     v_CalcParam.b2      = b2.u.s32.u[0];\r
279     v_CalcParam.c2      = c2.u.s32.u[0];\r
280     v_CalcParam.delta   = delta.u.s32.u[0];\r
281 \r
282      // Don't allow delta to be zero, since it gets used as a divisor\r
283     if( ! v_CalcParam.delta )\r
284     {\r
285         //RETAILMSG(1,(__TEXT("TouchPanelSetCalibration: delta of 0 invalid\r\n")));\r
286         //RETAILMSG(1,(__TEXT("\tCalibration failed.\r\n")));\r
287         v_CalcParam.delta = 1;  // any non-zero value to prevents DivByZero traps later\r
288         v_Calibrated = 0;\r
289     }\r
290     else\r
291         v_Calibrated = 1;\r
292 \r
293     return ErrorAnalysis(\r
294                     cCalibrationPoints,\r
295                     pScreenXBuffer,\r
296                     pScreenYBuffer,\r
297                     pUncalXBuffer,\r
298                     pUncalYBuffer\r
299                 );\r
300 }\r
301 \r
302 void\r
303 ComputeMatrix33(\r
304     PLARGENUM   pResult,\r
305     PMATRIX33   pMatrix\r
306     )\r
307 {\r
308     LARGENUM    lnTemp;\r
309 \r
310     LargeNumMult(pMatrix->pa11, pMatrix->pa22, &lnTemp);\r
311     LargeNumMult(pMatrix->pa33, &lnTemp, pResult);\r
312     LargeNumMult(pMatrix->pa21, pMatrix->pa32, &lnTemp);\r
313     LargeNumMult(pMatrix->pa13, &lnTemp, &lnTemp);\r
314     LargeNumAdd(pResult, &lnTemp, pResult);\r
315     LargeNumMult(pMatrix->pa12, pMatrix->pa23, &lnTemp);\r
316     LargeNumMult(pMatrix->pa31, &lnTemp, &lnTemp);\r
317     LargeNumAdd(pResult, &lnTemp, pResult);\r
318     LargeNumMult(pMatrix->pa13, pMatrix->pa22, &lnTemp);\r
319     LargeNumMult(pMatrix->pa31, &lnTemp, &lnTemp);\r
320     LargeNumSub(pResult, &lnTemp, pResult);\r
321     LargeNumMult(pMatrix->pa12, pMatrix->pa21, &lnTemp);\r
322     LargeNumMult(pMatrix->pa33, &lnTemp, &lnTemp);\r
323     LargeNumSub(pResult, &lnTemp, pResult);\r
324     LargeNumMult(pMatrix->pa23, pMatrix->pa32, &lnTemp);\r
325     LargeNumMult(pMatrix->pa11, &lnTemp, &lnTemp);\r
326     LargeNumSub(pResult, &lnTemp, pResult);\r
327 }\r
328 \r
329 void\r
330 TouchPanelCalibrateAPoint(\r
331     int   UncalX,     //@PARM The uncalibrated X coordinate\r
332     int   UncalY,     //@PARM The uncalibrated Y coordinate\r
333     int   *pCalX,     //@PARM The calibrated X coordinate\r
334     int   *pCalY      //@PARM The calibrated Y coordinate\r
335     )\r
336 {\r
337     int   x, y;\r
338 \r
339     if ( v_Calibrated )\r
340     {\r
341 \r
342      //\r
343      // Note the *4 in the expression below.  This is a workaround\r
344      // on behalf of gwe.  It provides a form of\r
345      // sub-pixel accuracy desirable for inking\r
346      //\r
347         x = (v_CalcParam.a1 * UncalX + v_CalcParam.b1 * UncalY +\r
348                 v_CalcParam.c1) * 4 / v_CalcParam.delta;\r
349         y = (v_CalcParam.a2 * UncalX + v_CalcParam.b2 * UncalY +\r
350                 v_CalcParam.c2) * 4 / v_CalcParam.delta;\r
351      }\r
352      else{\r
353                 x = (v_CalcParam_bak.a1 * UncalX + v_CalcParam_bak.b1 * UncalY +\r
354                         v_CalcParam_bak.c1) * 4 / v_CalcParam_bak.delta;\r
355                 y = (v_CalcParam_bak.a2 * UncalX + v_CalcParam_bak.b2 * UncalY +\r
356                         v_CalcParam_bak.c2) * 4 / v_CalcParam_bak.delta;\r
357      }\r
358     if ( x < 0 ){\r
359         x = 0;\r
360     }\r
361 \r
362     if  (y < 0 ){\r
363         y = 0;\r
364     }\r
365 \r
366     *pCalX = x;\r
367     *pCalY = y;\r
368 }\r
369 \r
370 unsigned char\r
371 ErrorAnalysis(\r
372     int   cCalibrationPoints,     //@PARM The number of calibration points\r
373     int   *pScreenXBuffer,        //@PARM List of screen X coords displayed\r
374     int   *pScreenYBuffer,        //@PARM List of screen Y coords displayed\r
375     int   *pUncalXBuffer,         //@PARM List of X coords collected\r
376     int   *pUncalYBuffer          //@PARM List of Y coords collected\r
377     )\r
378 {\r
379     int     i;\r
380     unsigned int  maxErr, err;\r
381     int   x,y;\r
382     int   dx,dy;\r
383     unsigned int  errThreshold = MAX_POINT_ERROR;  // Can be overridden by registry entry\r
384 #if 0\r
385     unsigned int  status, ValType, ValLen;\r
386 \r
387     //HKEY    regKey;\r
388 \r
389 \r
390     // See if there is a Maximum Calibration Error specified in the registry\r
391     //status = RegOpenKeyEx(\r
392     //                     HKEY_LOCAL_MACHINE,\r
393      //                    __TEXT("HARDWARE\\DEVICEMAP\\TOUCH"),\r
394     //                     0,\r
395     //                     0,\r
396     //                     &regKey);\r
397     if ( status == ERROR_SUCCESS ) {\r
398         ValLen = sizeof(errThreshold);\r
399         status = RegQueryValueEx(\r
400                                 regKey,\r
401                                 __TEXT("MaxCalError"),\r
402                                 NULL,\r
403                                 &ValType,\r
404                                 (PUCHAR)&errThreshold,\r
405                                 &ValLen);\r
406         // We don't care what happened.  Either we have a new value or we have the default value.\r
407         RegCloseKey(regKey);        \r
408     }\r
409 \r
410     RETAILMSG(1,(__TEXT("Maximum Allowed Error %d:\r\n"),\r
411                 errThreshold));\r
412     DEBUGMSG(1,(__TEXT("Calibration Results:\r\n")));\r
413 #endif\r
414 \r
415     maxErr = 0;\r
416     //DEBUGMSG(1,(__TEXT("   Screen    =>    Mapped\r\n")));\r
417     for(i=0; i<cCalibrationPoints; i++){\r
418         TouchPanelCalibrateAPoint(  pUncalXBuffer[i],\r
419                                     pUncalYBuffer[i],\r
420                                     &x,\r
421                                     &y\r
422                                     );\r
423         x /= 4;\r
424         y /= 4;\r
425         printk("(%4d, %4d) => (%4d, %4d)\n",\r
426         //DEBUGMSG(1,(__TEXT("(%4d, %4d) => (%4d, %4d)\r\n"),\r
427                 pScreenXBuffer[i],\r
428                 pScreenYBuffer[i],\r
429                 x,\r
430                 y\r
431                 );\r
432          \r
433         dx = x - pScreenXBuffer[i];\r
434         dy = y - pScreenYBuffer[i];\r
435         err = dx * dx + dy * dy;\r
436         if(err > maxErr){\r
437             maxErr = err;\r
438         }\r
439     }\r
440     //DEBUGMSG(1,(__TEXT("Maximum error (square of Euclidean distance in screen units) = %u\r\n"),\r
441      //       maxErr\r
442     //        ));\r
443 \r
444     if (maxErr < (errThreshold * errThreshold))\r
445     {\r
446                  printk(" v_CalcParam.a1=%d \n"  \r
447                         "v_CalcParam.b1=%d\n"   \r
448                         "v_CalcParam.c1= %d\n"   \r
449                          " v_CalcParam.a2   = %d\n" \r
450                         " v_CalcParam.b2  = %d\n"       \r
451                         " v_CalcParam.c2  = %d\n"\r
452                         "v_CalcParam.delta   = %d\n",    \r
453                          v_CalcParam.a1 , \\r
454                         v_CalcParam.b1 ,        \\r
455                         v_CalcParam.c1 ,        \\r
456                         v_CalcParam.a2 ,        \\r
457                         v_CalcParam.b2, \\r
458                         v_CalcParam.c2 ,        \\r
459                         v_CalcParam.delta);\r
460         return 1;\r
461     }\r
462     else\r
463     {\r
464        memset(&v_CalcParam, 0, sizeof(v_CalcParam));\r
465        v_Calibrated = 0;\r
466        v_CalcParam.a1 =  v_CalcParam_bak.a1;\r
467         v_CalcParam.b1 = v_CalcParam_bak.b1 ;\r
468         v_CalcParam.c1=  v_CalcParam_bak.c1;\r
469         v_CalcParam.a2 = v_CalcParam_bak.a2;\r
470         v_CalcParam.b2  = v_CalcParam_bak.b2;\r
471         v_CalcParam.c2 =  v_CalcParam_bak.c2;\r
472         v_CalcParam.delta=  v_CalcParam_bak.delta;\r
473         return 0;\r
474     }\r
475 }\r
476 \r
477 #define FILTER_BUF_LEN 8\r
478 typedef struct \r
479 {\r
480         unsigned short x;\r
481         unsigned short y;\r
482 }P;\r
483 static P sTouchFilterBuff[FILTER_BUF_LEN];\r
484 static int sBuffIndex = 0;\r
485 static P sReportFilter = {0,0};\r
486 void ClearBuff(void)\r
487 {\r
488         memset(sTouchFilterBuff,0,FILTER_BUF_LEN*sizeof(P));\r
489         sReportFilter.x = 0;\r
490         sReportFilter.y = 0;\r
491         sBuffIndex = 0;\r
492 }\r
493 void addToBuff(int* x,int* y)\r
494 {       \r
495         int index;\r
496         index=sBuffIndex++%FILTER_BUF_LEN;\r
497         sTouchFilterBuff[index].x = *x;\r
498         sTouchFilterBuff[index].y = *y;\r
499 }\r
500 #define TS_ERR_TDOWN -1\r
501 #define TS_ERR_LOWBUF -2\r
502 //#define TS_MINX       138\r
503 //#define TS_MINY       375\r
504 //#define TS_MAXX       3935\r
505 //#define TS_MAXY       3920\r
506 //#define TS_xISVALID(x) (x>=TS_MINX&&x<=TS_MAXX)\r
507 #define TS_isINVALID(X,Y) (X==4095||Y==4095||X==0||Y==0)\r
508 #define ABS(x) ((x)>0?(x):-(x))\r
509 static P spoint;\r
510 int TouchFilter(unsigned short* x,unsigned short* y,bool isdown)\r
511 {\r
512 #if 1\r
513         int ret = 0;\r
514         if(isdown==0&&sBuffIndex==0)\r
515                 {\r
516                 spoint.x = *x;\r
517                 spoint.y = *y;\r
518                 ClearBuff();\r
519                 ret=TS_ERR_TDOWN;\r
520                 }\r
521         if(!TS_isINVALID(*x,*y))\r
522                 addToBuff(x,y);\r
523         if(sBuffIndex<FILTER_BUF_LEN)\r
524                 ret=TS_ERR_LOWBUF;\r
525         if(ret==0)\r
526                 {\r
527                 P *p = sTouchFilterBuff;\r
528                 P *p1 = p+1;\r
529                 int index =0;\r
530                 while(1)\r
531                         {\r
532                         if(ABS(p->x-p1->x)<60||ABS(p->y-p1->y)<60)\r
533                                 {\r
534                                 *x=spoint.x;\r
535                                 *y=spoint.y;\r
536                                 //printk("p(%d,%d)      p1(%d,%d)\n",p->x,p->y,p1->x,p1->y);\r
537                                 //ret=-3;\r
538                                 break;\r
539                                 }\r
540                         p++;\r
541                         p1++;\r
542                         if(++index>=FILTER_BUF_LEN-1)break;\r
543                         }\r
544                 spoint.x=*x;\r
545                 spoint.y=*y;\r
546                 }\r
547         \r
548 #else   \r
549         int ret = 0;\r
550         if(isdown==0&&sBuffIndex==0)\r
551                 {\r
552                 ClearBuff();\r
553                 ret=TS_ERR_TDOWN;\r
554                 }\r
555         if(!TS_isINVALID(x,y))\r
556                 addToBuff(x,y);\r
557         if(sBuffIndex<FILTER_BUF_LEN)\r
558                 ret=TS_ERR_LOWBUF;\r
559         if(ret==0)\r
560                 {\r
561                 P adp;\r
562                 int index =0;\r
563                 while(1)\r
564                         {\r
565                         adp.x+=sTouchFilterBuff[index].x;\r
566                         adp.y+=sTouchFilterBuff[index].y;\r
567                         if(++index>=FILTER_BUF_LEN)break;\r
568                         }\r
569                 *x = adp.x/FILTER_BUF_LEN;\r
570                 *y = adp.y/FILTER_BUF_LEN;\r
571                 }\r
572 #endif\r
573         return ret;\r
574         \r
575 }\r
576 \r
577 #define SLAP_X 2\r
578 #define SLAP_Y 0\r
579 void TouchReportFilter(unsigned short* x,unsigned short* y)\r
580 {\r
581         if((sReportFilter.x==0&&sReportFilter.y==0)||\r
582                 (ABS(sReportFilter.x - *x)>SLAP_X&&ABS(sReportFilter.y - *y)>SLAP_Y))\r
583                 {\r
584                 sReportFilter.x = *x;\r
585                 sReportFilter.y = *y;\r
586                 }\r
587         *x = sReportFilter.x;\r
588         *y = sReportFilter.y;\r
589 }\r
590 #if 0\r
591 int main(void)\r
592 {\r
593     unsigned char ret;\r
594     int cali_num = 4;\r
595     int screen_x[4], screen_y[4];\r
596     int uncali_x[4], uncali_y[4];\r
597     int tst_uncali_x, tst_uncali_y, tst_cali_x, tst_cali_y;\r
598     \r
599     screen_x[0] = 15; screen_y[0] = 15;\r
600     screen_x[1] = 15; screen_y[1] = 465;\r
601     screen_x[2] = 785; screen_y[2] = 15;\r
602     screen_x[3] = 785; screen_y[3] = 465;\r
603     \r
604     uncali_x[0] = 173; uncali_y[0] = 417;\r
605     uncali_x[1] = 148; uncali_y[1] = 3867;\r
606     uncali_x[2] = 3903; uncali_y[2] = 365;\r
607     uncali_x[3] = 3924; uncali_y[3] = 3863;\r
608     \r
609     ret = TouchPanelSetCalibration(4, screen_x, \r
610             screen_y, uncali_x, uncali_y);\r
611     if (ret == 1)\r
612         printf("TouchPanelSetCalibration OK.\n");\r
613     else\r
614         printf("TouchPanelSetCalibration FAIL.\n");\r
615 \r
616     tst_uncali_x = 2033;\r
617     tst_uncali_y = 2132;\r
618     \r
619     TouchPanelCalibrateAPoint(tst_uncali_x, tst_uncali_y,\r
620                               &tst_cali_x, &tst_cali_y);\r
621     \r
622     printf("(%d, %d) >> (%d, %d)\n", tst_uncali_x, tst_uncali_y,\r
623                                      tst_cali_x/4, tst_cali_y/4);\r
624     \r
625     tst_uncali_x = 170;\r
626     tst_uncali_y = 418;\r
627     \r
628     TouchPanelCalibrateAPoint(tst_uncali_x, tst_uncali_y,\r
629                               &tst_cali_x, &tst_cali_y);\r
630     \r
631     printf("(%d, %d) >> (%d, %d)\n", tst_uncali_x, tst_uncali_y,\r
632                                      tst_cali_x/4, tst_cali_y/4);\r
633 \r
634     tst_uncali_x = 500;\r
635     tst_uncali_y = 707;\r
636     \r
637     TouchPanelCalibrateAPoint(tst_uncali_x, tst_uncali_y,\r
638                               &tst_cali_x, &tst_cali_y);\r
639     \r
640     printf("(%d, %d) >> (%d, %d)\n", tst_uncali_x, tst_uncali_y,\r
641                                      tst_cali_x/4, tst_cali_y/4);\r
642 \r
643     tst_uncali_x = 3636;\r
644     tst_uncali_y = 2150;\r
645     \r
646     TouchPanelCalibrateAPoint(tst_uncali_x, tst_uncali_y,\r
647                               &tst_cali_x, &tst_cali_y);\r
648     \r
649     printf("(%d, %d) >> (%d, %d)\n", tst_uncali_x, tst_uncali_y,\r
650                                      tst_cali_x/4, tst_cali_y/4);\r
651                                                   \r
652     return 0;    \r
653 }\r
654 #endif\r
655 \r