2 * drivers/input/touchscreen/largenum_ts.c - largenum for rk2818 spi xpt2046 device and console
\r
4 * Copyright (C) 2010 ROCKCHIP, Inc.
\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
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
15 #include <linux/kernel.h>
\r
17 #include "largenum_ts.h"
\r
20 LargeNumSignedFormat(
\r
33 pNum->u.s32.u[0] = -n;
\r
34 pNum->fNegative = 1;
\r
36 pNum->u.s32.u[0] = n;
\r
39 for(i=1; i<SIZE_OF_LARGENUM; i++){
\r
40 pNum->u.s32.u[i] = 0;
\r
52 for(i=0; i<SIZE_OF_LARGENUM; i++){
\r
53 if(pNum->u.s32.u[i]){
\r
65 return (pNum->fNegative ? 1 : 0);
\r
70 IsLargeNumMagGreaterThan(
\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
80 } else if(pNum1->u.s32.u[i] < pNum2->u.s32.u[i]){
\r
88 IsLargeNumMagLessThan(
\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
98 } else if(pNum1->u.s32.u[i] > pNum2->u.s32.u[i]){
\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
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
141 if(pResult->u.s32.u[i] <= a){
\r
148 if(pResult->u.s32.u[i] < a){
\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
177 if(pResult->u.s32.u[i] <= a){
\r
184 if(pResult->u.s32.u[i] < a){
\r
202 unsigned char fNegative1;
\r
203 unsigned char fNegative2;
\r
205 fNegative1 = IsLargeNumNegative(pNum1);
\r
206 fNegative2 = IsLargeNumNegative(pNum2);
\r
208 if(fNegative1 != fNegative2){
\r
209 if(IsLargeNumMagGreaterThan(pNum1, pNum2)){
\r
210 LargeNumMagSub(pNum1, pNum2, pResult);
\r
212 LargeNumMagSub(pNum2, pNum1, pResult);
\r
213 fNegative1 = !fNegative1;
\r
216 LargeNumMagAdd(pNum1, pNum2, pResult);
\r
218 if(!IsLargeNumNotZero(pResult)){
\r
219 pResult->fNegative = 0;
\r
221 pResult->fNegative = fNegative1;
\r
233 unsigned char fNegative1;
\r
234 unsigned char fNegative2;
\r
236 fNegative1 = IsLargeNumNegative(pNum1);
\r
237 fNegative2 = IsLargeNumNegative(pNum2);
\r
239 if(fNegative1 == fNegative2){
\r
240 if(IsLargeNumMagGreaterThan(pNum1, pNum2)){
\r
241 LargeNumMagSub(pNum1, pNum2, pResult);
\r
243 LargeNumMagSub(pNum2, pNum1, pResult);
\r
244 fNegative1 = !fNegative1;
\r
247 LargeNumMagAdd(pNum1, pNum2, pResult);
\r
249 if(!IsLargeNumNotZero(pResult)){
\r
250 pResult->fNegative = 0;
\r
252 pResult->fNegative = fNegative1;
\r
264 unsigned int a1, a0;
\r
265 unsigned int b1, b0;
\r
278 r1 = a1 * b0 + a0 * b1;
\r
281 pResult->u.s32.u[0] = (r1 << 16) + r0;
\r
282 if(pResult->u.s32.u[0] < r0){
\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
291 pResult->fNegative = 0;
\r
303 unsigned char fNegativeA;
\r
304 unsigned char fNegativeB;
\r
320 LargeNumMulUint32(a, b, pResult);
\r
322 if(!IsLargeNumNotZero(pResult)){
\r
323 pResult->fNegative = 0;
\r
325 if(fNegativeA != fNegativeB){
\r
326 pResult->fNegative = 1;
\r
341 LARGENUM lNumCarry;
\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
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
356 pResult->u.s32.u[i] = lNumSum.u.s32.u[0];
\r
359 if(!IsLargeNumNotZero(pResult)){
\r
360 pResult->fNegative = 0;
\r
362 pResult->fNegative = (pNum1->fNegative != pNum2->fNegative);
\r
368 LargeNumSignedFormat(
\r
375 if(IsLargeNumNegative(pNum)){
\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
397 unsigned int filler;
\r
401 filler = LargeNumSignedFormat(pNum);
\r
403 shift32 = count / 32;
\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
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
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
424 if (countLeft < 32) {
\r
425 // Shifting by >= 32 is undefined.
\r
426 pNum->u.s32.u[i] |= filler << countLeft;
\r
433 for(; i<SIZE_OF_LARGENUM; i++){
\r
434 pNum->u.s32.u[i] = filler;
\r
445 unsigned int s[2*SIZE_OF_LARGENUM];
\r
452 for(i=0; i<2*SIZE_OF_LARGENUM; i++){
\r
453 s[i] = pNum->u.s16.s[i];
\r
457 divisor = -divisor;
\r
459 } else if(divisor == 0){
\r
461 // This is a divide-by-zero error
\r
463 for(i=0; i<SIZE_OF_LARGENUM; i++){
\r
464 pResult->u.s32.u[i] = 0xffffffff;
\r
472 for(i=(2*SIZE_OF_LARGENUM-1); i>=0; i--){
\r
473 d = (r << 16) + s[i];
\r
475 r = d - q * divisor;
\r
479 for(i=0; i<2*SIZE_OF_LARGENUM; i++){
\r
480 pResult->u.s16.s[i] = s[i];
\r
483 if(pNum->fNegative){
\r
484 LargeNumMagInc(pResult);
\r
486 if(sd == 0 && IsLargeNumNotZero(pResult)){
\r
487 pResult->fNegative = 1;
\r
489 pResult->fNegative = 0;
\r
493 if(sd && IsLargeNumNotZero(pResult)){
\r
494 pResult->fNegative = 1;
\r
496 pResult->fNegative = 0;
\r
508 static unsigned int LargeNumMask[32] = {
\r
547 for(i=(SIZE_OF_LARGENUM-1); i>=0; i--){
\r
548 u = pNum->u.s32.u[i];
\r
550 for(j=31; j>=0; j--){
\r
551 if(u & (LargeNumMask[j])){
\r
552 return i * 32 + j + 1;
\r
565 static char buf[SIZE_OF_LARGENUM * 10 + 2];
\r
572 p = buf + sizeof(buf) - 1;
\r
577 s = pNum->fNegative;
\r
578 lNum.fNegative = 0;
\r
580 while(IsLargeNumNotZero(&lNum)){
\r
581 r = LargeNumDivInt32(&lNum, 10, &lNum);
\r
593 //PREFAST_SUPPRESS(394, "q is <= p");
\r
597 if((q == buf) || (s && q == &(buf[1]))){
\r