input: touchscreen: add touch screen of gslx680 for rk3399-firefly-edp
[firefly-linux-kernel-4.4.55.git] / drivers / input / touchscreen / largenum_ts.c
1 /*\r
2  * drivers/input/touchscreen/largenum_ts.c - largenum 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 \r
17 #include "largenum_ts.h"\r
18 \r
19 unsigned int\r
20 LargeNumSignedFormat(\r
21     PLARGENUM   pNum\r
22     );\r
23 \r
24 PLARGENUM\r
25 LargeNumSet(\r
26     PLARGENUM   pNum,\r
27     int       n\r
28     )\r
29 {\r
30     int i;\r
31 \r
32     if(n < 0){\r
33         pNum->u.s32.u[0] = -n;\r
34         pNum->fNegative = 1;\r
35     } else{\r
36         pNum->u.s32.u[0] = n;\r
37         pNum->fNegative=0;\r
38     }\r
39     for(i=1; i<SIZE_OF_LARGENUM; i++){\r
40         pNum->u.s32.u[i] = 0;\r
41     }\r
42     return pNum;\r
43 }\r
44 \r
45 unsigned char\r
46 IsLargeNumNotZero(\r
47     PLARGENUM   pNum\r
48     )\r
49 {\r
50     int i;\r
51 \r
52     for(i=0; i<SIZE_OF_LARGENUM; i++){\r
53         if(pNum->u.s32.u[i]){\r
54             return 1;\r
55         }\r
56     }\r
57     return 0;\r
58 }\r
59 \r
60 unsigned char\r
61 IsLargeNumNegative(\r
62     PLARGENUM   pNum\r
63     )\r
64 {\r
65     return (pNum->fNegative ? 1 : 0);\r
66 \r
67 }\r
68 \r
69 unsigned char\r
70 IsLargeNumMagGreaterThan(\r
71     PLARGENUM   pNum1,\r
72     PLARGENUM   pNum2\r
73     )\r
74 {\r
75     int i;\r
76 \r
77     for(i=SIZE_OF_LARGENUM-1; i>=0; i--){\r
78         if(pNum1->u.s32.u[i] > pNum2->u.s32.u[i]){\r
79             return 1;\r
80         } else if(pNum1->u.s32.u[i] < pNum2->u.s32.u[i]){\r
81             return 0;\r
82         }\r
83     }\r
84     return 0;\r
85 }\r
86 \r
87 unsigned char\r
88 IsLargeNumMagLessThan(\r
89     PLARGENUM   pNum1,\r
90     PLARGENUM   pNum2\r
91     )\r
92 {\r
93     int i;\r
94 \r
95     for(i=SIZE_OF_LARGENUM-1; i>=0; i--){\r
96         if(pNum1->u.s32.u[i] < pNum2->u.s32.u[i]){\r
97             return 1;\r
98         } else if(pNum1->u.s32.u[i] > pNum2->u.s32.u[i]){\r
99             return 0;\r
100         }\r
101     }\r
102     return 0;\r
103 }\r
104 \r
105 PLARGENUM\r
106 LargeNumMagInc(\r
107     PLARGENUM   pNum\r
108     )\r
109 {\r
110     unsigned int  c;\r
111     int     i;\r
112 \r
113     c = 1;\r
114     for(i=0; i<SIZE_OF_LARGENUM; i++){\r
115         pNum->u.s32.u[i] += c;\r
116         if(pNum->u.s32.u[i]){\r
117             c = 0;\r
118         }\r
119     }\r
120     return pNum;\r
121 }\r
122 \r
123 PLARGENUM\r
124 LargeNumMagAdd(\r
125     PLARGENUM   pNum1,\r
126     PLARGENUM   pNum2,\r
127     PLARGENUM   pResult\r
128     )\r
129 {\r
130     unsigned int      c;\r
131     unsigned int      i;\r
132     unsigned int      a;\r
133     unsigned int      b;\r
134 \r
135     c = 0;\r
136     for(i=0; i<SIZE_OF_LARGENUM; i++){\r
137         a = pNum1->u.s32.u[i];\r
138         b = pNum2->u.s32.u[i];\r
139         pResult->u.s32.u[i] = a + b + c;\r
140         if(c){\r
141             if(pResult->u.s32.u[i] <= a){\r
142                 c = 1;\r
143             } else {\r
144                 c = 0;\r
145             }\r
146 \r
147         } else {\r
148             if(pResult->u.s32.u[i] < a){\r
149                 c = 1;\r
150             } else {\r
151                 c = 0;\r
152             }\r
153 \r
154         }\r
155     }\r
156     return pResult;\r
157 }\r
158 \r
159 PLARGENUM\r
160 LargeNumMagSub(\r
161     PLARGENUM   pNum1,\r
162     PLARGENUM   pNum2,\r
163     PLARGENUM   pResult\r
164     )\r
165 {\r
166     unsigned int      c;\r
167     unsigned int      i;\r
168     unsigned int      a;\r
169     unsigned int      b;\r
170 \r
171     c = 1;\r
172     for(i=0; i<SIZE_OF_LARGENUM; i++){\r
173         a = pNum1->u.s32.u[i];\r
174         b = ~(pNum2->u.s32.u[i]);\r
175         pResult->u.s32.u[i] = a + b + c;\r
176         if(c){\r
177             if(pResult->u.s32.u[i] <= a){\r
178                 c = 1;\r
179             } else {\r
180                 c = 0;\r
181             }\r
182 \r
183         } else {\r
184             if(pResult->u.s32.u[i] < a){\r
185                 c = 1;\r
186             } else {\r
187                 c = 0;\r
188             }\r
189 \r
190         }\r
191     }\r
192     return pResult;\r
193 }\r
194 \r
195 PLARGENUM\r
196 LargeNumAdd(\r
197     PLARGENUM   pNum1,\r
198     PLARGENUM   pNum2,\r
199     PLARGENUM   pResult\r
200     )\r
201 {\r
202     unsigned char    fNegative1;\r
203     unsigned char    fNegative2;\r
204 \r
205     fNegative1 = IsLargeNumNegative(pNum1);\r
206     fNegative2 = IsLargeNumNegative(pNum2);\r
207 \r
208     if(fNegative1 != fNegative2){\r
209         if(IsLargeNumMagGreaterThan(pNum1, pNum2)){\r
210             LargeNumMagSub(pNum1, pNum2, pResult);\r
211         } else {\r
212             LargeNumMagSub(pNum2, pNum1, pResult);\r
213             fNegative1 = !fNegative1;\r
214         }\r
215     } else {\r
216         LargeNumMagAdd(pNum1, pNum2, pResult);\r
217     }\r
218     if(!IsLargeNumNotZero(pResult)){\r
219         pResult->fNegative = 0;\r
220     } else {\r
221         pResult->fNegative = fNegative1;\r
222     }\r
223     return pResult;\r
224 }\r
225 \r
226 PLARGENUM\r
227 LargeNumSub(\r
228     PLARGENUM   pNum1,\r
229     PLARGENUM   pNum2,\r
230     PLARGENUM   pResult\r
231     )\r
232 {\r
233     unsigned char    fNegative1;\r
234     unsigned char    fNegative2;\r
235 \r
236     fNegative1 = IsLargeNumNegative(pNum1);\r
237     fNegative2 = IsLargeNumNegative(pNum2);\r
238 \r
239     if(fNegative1 == fNegative2){\r
240         if(IsLargeNumMagGreaterThan(pNum1, pNum2)){\r
241             LargeNumMagSub(pNum1, pNum2, pResult);\r
242         } else {\r
243             LargeNumMagSub(pNum2, pNum1, pResult);\r
244             fNegative1 = !fNegative1;\r
245         }\r
246     } else {\r
247         LargeNumMagAdd(pNum1, pNum2, pResult);\r
248     }\r
249     if(!IsLargeNumNotZero(pResult)){\r
250         pResult->fNegative = 0;\r
251     } else {\r
252         pResult->fNegative = fNegative1;\r
253     }\r
254     return pResult;\r
255 }\r
256 \r
257 PLARGENUM\r
258 LargeNumMulUint32(\r
259     unsigned int      a,\r
260     unsigned int      b,\r
261     PLARGENUM   pResult\r
262     )\r
263 {\r
264     unsigned int  a1, a0;\r
265     unsigned int  b1, b0;\r
266     unsigned int  r0;\r
267     unsigned int  r1;\r
268     unsigned int  r2;\r
269     unsigned int  c;\r
270     int     i;\r
271 \r
272     a1 = a >> 16;\r
273     a0 = a & 0xffff;\r
274     b1 = b >> 16;\r
275     b0 = b & 0xffff;\r
276 \r
277     r0 = a0 * b0;\r
278     r1 = a1 * b0 + a0 * b1;\r
279     r2 = a1 * b1;\r
280 \r
281     pResult->u.s32.u[0] = (r1 << 16) + r0;\r
282     if(pResult->u.s32.u[0] < r0){\r
283         c = 1;\r
284     } else {\r
285         c = 0;\r
286     }\r
287     pResult->u.s32.u[1] = r2 + (r1 >> 16) + c;\r
288     for(i=2; i<SIZE_OF_LARGENUM; i++){\r
289         pResult->u.s32.u[i] = 0;\r
290     }\r
291     pResult->fNegative = 0;\r
292 \r
293     return pResult;\r
294 }\r
295 \r
296 PLARGENUM\r
297 LargeNumMulInt32(\r
298     int       a,\r
299     int       b,\r
300     PLARGENUM   pResult\r
301     )\r
302 {\r
303     unsigned char        fNegativeA;\r
304     unsigned char        fNegativeB;\r
305 \r
306     if(a < 0){\r
307         fNegativeA = 1;\r
308         a = -a;\r
309     } else {\r
310         fNegativeA = 0;\r
311     }\r
312 \r
313     if(b < 0){\r
314         fNegativeB = 1;\r
315         b = -b;\r
316     } else {\r
317         fNegativeB = 0;\r
318     }\r
319 \r
320     LargeNumMulUint32(a, b, pResult);\r
321 \r
322     if(!IsLargeNumNotZero(pResult)){\r
323         pResult->fNegative = 0;\r
324     } else {\r
325         if(fNegativeA != fNegativeB){\r
326             pResult->fNegative = 1;\r
327         }\r
328     }\r
329     return pResult;\r
330 }\r
331 \r
332 PLARGENUM\r
333 LargeNumMult(\r
334     PLARGENUM   pNum1,\r
335     PLARGENUM   pNum2,\r
336     PLARGENUM   pResult\r
337     )\r
338 {\r
339     LARGENUM    lNumTemp;\r
340     LARGENUM    lNumSum;\r
341     LARGENUM    lNumCarry;\r
342     int         i;\r
343     int         j;\r
344 \r
345     LargeNumSet(&lNumCarry, 0);\r
346     for(i=0; i<SIZE_OF_LARGENUM; i++){\r
347         LargeNumSet(&lNumSum, 0);\r
348         for(j=0; j<=i; j++){\r
349             LargeNumMulUint32(pNum1->u.s32.u[j], pNum2->u.s32.u[i-j], &lNumTemp);\r
350             LargeNumMagAdd(&lNumTemp, &lNumSum, &lNumSum);\r
351         }\r
352         LargeNumMagAdd(&lNumCarry, &lNumSum, &lNumSum);\r
353         for(j=0; j<SIZE_OF_LARGENUM-1; j++){\r
354             lNumCarry.u.s32.u[j] = lNumSum.u.s32.u[j+1];\r
355         }\r
356         pResult->u.s32.u[i] = lNumSum.u.s32.u[0];\r
357     }\r
358 \r
359     if(!IsLargeNumNotZero(pResult)){\r
360         pResult->fNegative = 0;\r
361     } else {\r
362         pResult->fNegative = (pNum1->fNegative != pNum2->fNegative);\r
363     }\r
364     return pResult;\r
365 }\r
366 \r
367 unsigned int\r
368 LargeNumSignedFormat(\r
369     PLARGENUM   pNum\r
370     )\r
371 {\r
372     int     i;\r
373     unsigned int  c;\r
374 \r
375     if(IsLargeNumNegative(pNum)){\r
376         c = 1;\r
377         for(i=0; i<SIZE_OF_LARGENUM; i++){\r
378             pNum->u.s32.u[i] = ~(pNum->u.s32.u[i]) + c;\r
379             if(pNum->u.s32.u[i]){\r
380                 c = 0;\r
381             }\r
382         }\r
383         return 0xffffffff;\r
384     } else {\r
385         return 0;\r
386     }\r
387 }\r
388 \r
389 void\r
390 LargeNumRAShift(\r
391     PLARGENUM   pNum,\r
392     int       count\r
393     )\r
394 {\r
395     int   shift32;\r
396     int   countLeft;\r
397     unsigned int  filler;\r
398     int     i;\r
399     int     j;\r
400 \r
401     filler = LargeNumSignedFormat(pNum);\r
402 \r
403     shift32 = count / 32;\r
404 \r
405     if(shift32 > (SIZE_OF_LARGENUM - 1)){\r
406         for(i=0; i<SIZE_OF_LARGENUM; i++){\r
407             pNum->u.s32.u[i] = filler;\r
408         }\r
409         return;\r
410     }\r
411 \r
412     count %= 32;\r
413     countLeft = 32 - count;\r
414     for(i=0, j=shift32;;){\r
415         pNum->u.s32.u[i] = (pNum->u.s32.u[j] >> count);\r
416         if(j<(SIZE_OF_LARGENUM-1)){\r
417             j++;            \r
418             if (countLeft < 32) {\r
419                 // Shifting by >= 32 is undefined.\r
420                 pNum->u.s32.u[i] |= pNum->u.s32.u[j] << countLeft;\r
421             }\r
422             i++;\r
423         } else {\r
424             if (countLeft < 32) {\r
425                 // Shifting by >= 32 is undefined.\r
426                 pNum->u.s32.u[i] |= filler << countLeft;\r
427             }\r
428             i++;\r
429             break;\r
430         }\r
431     }\r
432 \r
433     for(; i<SIZE_OF_LARGENUM; i++){\r
434         pNum->u.s32.u[i] = filler;\r
435     }\r
436 }\r
437 \r
438 unsigned int\r
439 LargeNumDivInt32(\r
440     PLARGENUM   pNum,\r
441     int       divisor,\r
442     PLARGENUM   pResult\r
443     )\r
444 {\r
445     unsigned int  s[2*SIZE_OF_LARGENUM];\r
446     unsigned int  r;\r
447     unsigned int  q;\r
448     unsigned int  d;\r
449     unsigned char    sd;\r
450     int     i;\r
451 \r
452     for(i=0; i<2*SIZE_OF_LARGENUM; i++){\r
453         s[i] = pNum->u.s16.s[i];\r
454     }\r
455 \r
456     if(divisor < 0){\r
457         divisor = -divisor;\r
458         sd = 1;\r
459     } else if(divisor == 0){\r
460         //\r
461         // This is a divide-by-zero error\r
462         //\r
463         for(i=0; i<SIZE_OF_LARGENUM; i++){\r
464             pResult->u.s32.u[i] = 0xffffffff;\r
465         }\r
466         return 0xffffffff;\r
467     } else {\r
468         sd = 0;\r
469     }\r
470 \r
471     r = 0;\r
472     for(i=(2*SIZE_OF_LARGENUM-1); i>=0; i--){\r
473         d = (r << 16) + s[i];\r
474         q = d / divisor;\r
475         r = d - q * divisor;\r
476         s[i] = q;\r
477     }\r
478 \r
479     for(i=0; i<2*SIZE_OF_LARGENUM; i++){\r
480         pResult->u.s16.s[i] = s[i];\r
481     }\r
482 \r
483     if(pNum->fNegative){\r
484         LargeNumMagInc(pResult);\r
485         r = divisor - r;\r
486         if(sd == 0 && IsLargeNumNotZero(pResult)){\r
487             pResult->fNegative = 1;\r
488         } else {\r
489             pResult->fNegative = 0;\r
490         }\r
491 \r
492     } else {\r
493         if(sd && IsLargeNumNotZero(pResult)){\r
494             pResult->fNegative = 1;\r
495         } else {\r
496             pResult->fNegative = 0;\r
497         }\r
498     }\r
499 \r
500     return r;\r
501 }\r
502 \r
503 int\r
504 LargeNumBits(\r
505     PLARGENUM   pNum\r
506     )\r
507 {\r
508     static  unsigned int LargeNumMask[32] = {\r
509         0x00000001,\r
510         0x00000002,\r
511         0x00000004,\r
512         0x00000008,\r
513         0x00000010,\r
514         0x00000020,\r
515         0x00000040,\r
516         0x00000080,\r
517         0x00000100,\r
518         0x00000200,\r
519         0x00000400,\r
520         0x00000800,\r
521         0x00001000,\r
522         0x00002000,\r
523         0x00004000,\r
524         0x00008000,\r
525         0x00010000,\r
526         0x00020000,\r
527         0x00040000,\r
528         0x00080000,\r
529         0x00100000,\r
530         0x00200000,\r
531         0x00400000,\r
532         0x00800000,\r
533         0x01000000,\r
534         0x02000000,\r
535         0x04000000,\r
536         0x08000000,\r
537         0x10000000,\r
538         0x20000000,\r
539         0x40000000,\r
540         0x80000000,\r
541         };\r
542 \r
543     int     i;\r
544     int     j;\r
545     unsigned int  u;\r
546 \r
547     for(i=(SIZE_OF_LARGENUM-1); i>=0; i--){\r
548         u = pNum->u.s32.u[i];\r
549         if(u){\r
550             for(j=31; j>=0; j--){\r
551                 if(u & (LargeNumMask[j])){\r
552                     return i * 32 + j + 1;\r
553                 }\r
554             }\r
555         }\r
556     }\r
557     return 0;\r
558 }\r
559 \r
560 char *\r
561 LargeNumToAscii(\r
562     PLARGENUM   pNum\r
563     )\r
564 {\r
565     static  char    buf[SIZE_OF_LARGENUM * 10 + 2];\r
566     LARGENUM        lNum;\r
567     char            *p;\r
568     char            *q;\r
569     unsigned int          r;\r
570     int             s;\r
571 \r
572     p = buf + sizeof(buf) - 1;\r
573     *p= 0;\r
574 \r
575     lNum = *pNum;\r
576 \r
577     s = pNum->fNegative;\r
578     lNum.fNegative = 0;\r
579 \r
580     while(IsLargeNumNotZero(&lNum)){\r
581         r = LargeNumDivInt32(&lNum, 10, &lNum);\r
582         p--;\r
583         *p = r + '0';\r
584     }\r
585 \r
586     q = buf;\r
587 \r
588     if(s){\r
589         *q++='-';\r
590     }\r
591     while(*p){\r
592         //ASSERT(q <= p);\r
593         //PREFAST_SUPPRESS(394, "q is <= p");\r
594         *q++ = *p++;\r
595     }\r
596 \r
597     if((q == buf) || (s && q == &(buf[1]))){\r
598         *q++ = '0';\r
599     }\r
600     *q = 0;\r
601     return buf;\r
602 }\r