aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen/wacom/wacom_i2c_func.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen/wacom/wacom_i2c_func.c')
-rw-r--r--drivers/input/touchscreen/wacom/wacom_i2c_func.c380
1 files changed, 274 insertions, 106 deletions
diff --git a/drivers/input/touchscreen/wacom/wacom_i2c_func.c b/drivers/input/touchscreen/wacom/wacom_i2c_func.c
index a24a41b..18a7900 100644
--- a/drivers/input/touchscreen/wacom/wacom_i2c_func.c
+++ b/drivers/input/touchscreen/wacom/wacom_i2c_func.c
@@ -498,71 +498,182 @@ void wacom_i2c_coord_offset(u16 *coordX, u16 *coordY)
#endif
#ifdef WACOM_USE_AVERAGING
-void wacom_i2c_coord_average(unsigned short *CoordX, unsigned short *CoordY,
- int bFirstLscan)
+#define STEP 32
+void wacom_i2c_coord_average(short *CoordX, short *CoordY,
+ int bFirstLscan, int aveStrength)
{
unsigned char i;
unsigned int work;
unsigned char ave_step = 4, ave_shift = 2;
- static unsigned short Sum_X, Sum_Y;
- static unsigned short AveBuffX[4], AveBuffY[4];
+ static int Sum_X, Sum_Y;
+ static int AveBuffX[STEP], AveBuffY[STEP];
static unsigned char AvePtr;
static unsigned char bResetted;
-
- if (bFirstLscan == 0)
+#ifdef WACOM_USE_AVE_TRANSITION
+ static int tmpBuffX[STEP], tmpBuffY[STEP];
+ static unsigned char last_step, last_shift;
+ static bool transition;
+ static int tras_counter;
+#endif
+ if (bFirstLscan == 0) {
bResetted = 0;
- else {
- if (bFirstLscan && (bResetted == 0)) {
- AvePtr = 0;
+#ifdef WACOM_USE_AVE_TRANSITION
+ transition = false;
+ tras_counter = 0;
+ last_step = 4;
+ last_shift = 2;
+#endif
+ return ;
+ }
+#ifdef WACOM_USE_AVE_TRANSITION
+ if (bResetted) {
+ if (transition) {
+ ave_step = last_step;
+ ave_shift = last_shift;
+ } else {
+ ave_step = 2 << (aveStrength-1);
+ ave_shift = aveStrength;
+ }
+
+ if (!transition && ave_step != 0 && last_step != 0) {
+ if (ave_step > last_step) {
+ transition = true;
+ tras_counter = ave_step;
+ /*printk(KERN_DEBUG
+ "[E-PEN] Trans %d to %d\n",
+ last_step, ave_step);*/
+
+ memcpy(tmpBuffX, AveBuffX,
+ sizeof(unsigned int) * last_step);
+ memcpy(tmpBuffY, AveBuffY,
+ sizeof(unsigned int) * last_step);
+ for (i = 0 ; i < last_step; ++i) {
+ AveBuffX[i] = tmpBuffX[AvePtr];
+ AveBuffY[i] = tmpBuffY[AvePtr];
+ if (++AvePtr >= last_step)
+ AvePtr = 0;
+ }
+ for ( ; i < ave_step; ++i) {
+ AveBuffX[i] = *CoordX;
+ AveBuffY[i] = *CoordY;
+ Sum_X += *CoordX;
+ Sum_Y += *CoordY;
+ }
+ AvePtr = 0;
- ave_step = 4;
- ave_shift = 2;
+ *CoordX = Sum_X >> ave_shift;
+ *CoordY = Sum_Y >> ave_shift;
+
+ bResetted = 1;
+
+ last_step = ave_step;
+ last_shift = ave_shift;
+ return ;
+ } else if (ave_step < last_step) {
+ transition = true;
+ tras_counter = ave_step;
+ /*printk(KERN_DEBUG
+ "[E-PEN] Trans %d to %d\n",
+ last_step, ave_step);*/
+
+ memcpy(tmpBuffX, AveBuffX,
+ sizeof(unsigned int) * last_step);
+ memcpy(tmpBuffY, AveBuffY,
+ sizeof(unsigned int) * last_step);
+ Sum_X = 0;
+ Sum_Y = 0;
+ for (i = 1 ; i <= ave_step; ++i) {
+ if (AvePtr == 0)
+ AvePtr = last_step - 1;
+ else
+ --AvePtr;
+ AveBuffX[ave_step-i] = tmpBuffX[AvePtr];
+ Sum_X = Sum_X + tmpBuffX[AvePtr];
+
+ AveBuffY[ave_step-i] = tmpBuffY[AvePtr];
+ Sum_Y = Sum_Y + tmpBuffY[AvePtr];
- for (i = 0; i < ave_step; i++) {
- AveBuffX[i] = *CoordX;
- AveBuffY[i] = *CoordY;
- }
- Sum_X = (unsigned short)*CoordX << ave_shift;
- Sum_Y = (unsigned short)*CoordY << ave_shift;
- bResetted = 1;
- } else if (bFirstLscan) {
- Sum_X = Sum_X - AveBuffX[AvePtr] + (*CoordX);
- AveBuffX[AvePtr] = *CoordX;
- work = Sum_X >> ave_shift;
- *CoordX = (unsigned int)work;
-
- Sum_Y = Sum_Y - AveBuffY[AvePtr] + (*CoordY);
- AveBuffY[AvePtr] = (*CoordY);
- work = Sum_Y >> ave_shift;
- *CoordY = (unsigned int)work;
-
- if (++AvePtr >= ave_step)
+ }
AvePtr = 0;
+ bResetted = 1;
+ *CoordX = Sum_X >> ave_shift;
+ *CoordY = Sum_Y >> ave_shift;
+
+ bResetted = 1;
+
+ last_step = ave_step;
+ last_shift = ave_shift;
+ return ;
+ }
}
- }
+ if (!transition && (last_step != ave_step)) {
+ last_step = ave_step;
+ last_shift = ave_shift;
+ }
+ }
+#endif
+ if (bFirstLscan && (bResetted == 0)) {
+ AvePtr = 0;
+ ave_step = 4;
+ ave_shift = 2;
+#if defined(WACOM_USE_AVE_TRANSITION)
+ tras_counter = ave_step;
+#endif
+ for (i = 0; i < ave_step; i++) {
+ AveBuffX[i] = *CoordX;
+ AveBuffY[i] = *CoordY;
+ }
+ Sum_X = (unsigned int)*CoordX << ave_shift;
+ Sum_Y = (unsigned int)*CoordY << ave_shift;
+ bResetted = 1;
+ } else if (bFirstLscan) {
+ Sum_X = Sum_X - AveBuffX[AvePtr] + (*CoordX);
+ AveBuffX[AvePtr] = *CoordX;
+ work = Sum_X >> ave_shift;
+ *CoordX = (unsigned int)work;
+
+ Sum_Y = Sum_Y - AveBuffY[AvePtr] + (*CoordY);
+ AveBuffY[AvePtr] = (*CoordY);
+ work = Sum_Y >> ave_shift;
+ *CoordY = (unsigned int)work;
+
+ if (++AvePtr >= ave_step)
+ AvePtr = 0;
+ }
+#ifdef WACOM_USE_AVE_TRANSITION
+ if (transition) {
+ --tras_counter;
+ if (tras_counter < 0)
+ transition = false;
+ }
+#endif
}
#endif
-#if defined(WACOM_USE_BOXFILTER)
-/*Center*/
-int g_boxThreshold_C[] = {0, 0, 0, };
-int g_boxThreshold_X[] = {30, 20, 20, };
-int g_boxThreshold_Y[] = {50, 20, 20, };
-/*Transition*/
-int g_boxThreshold_Trs[] = {130, 20, 20, };
+#if defined(WACOM_USE_HEIGHT)
+u8 wacom_i2c_coord_level(u16 gain)
+{
+ if (gain >= 0 && gain <= 14)
+ return 0;
+ else if (gain > 14 && gain <= 24)
+ return 1;
+ else
+ return 2;
+}
+#endif
-void boxfilt(unsigned short *CoordX, unsigned short *CoordY,
+#ifdef WACOM_USE_BOX_FILTER
+void boxfilt(short *CoordX, short *CoordY,
int height, int bFirstLscan)
{
bool isMoved = false;
static bool bFirst = true;
- static unsigned short lastX_loc, lastY_loc;
+ static short lastX_loc, lastY_loc;
static unsigned char bResetted;
int threshold = 0;
int distance = 0;
- bool transition = false;
- bool isXMoved = false;
+ static short bounce;
/*Reset filter*/
if (bFirstLscan == 0) {
@@ -583,48 +694,14 @@ void boxfilt(unsigned short *CoordX, unsigned short *CoordY,
}
/*Start Filtering*/
- threshold = g_boxThreshold_C[height];
-
- if (*CoordX > X_INC_E1)
- threshold = g_boxThreshold_X[height];
- else if (*CoordX < X_INC_S1)
- threshold = g_boxThreshold_X[height];
-
- /*Right*/
- if (*CoordY > Y_INC_E1) {
- /*Transition*/
- if (*CoordY < Y_INC_E2 && *CoordY > Y_INC_E3) {
- transition = true;
- threshold += g_boxThreshold_Trs[height];
- } else
- threshold += g_boxThreshold_Y[height];
- }
- /*Left*/
- else if (*CoordY < Y_INC_S1) {
- /*Transition*/
- if (*CoordY > Y_INC_S2 && *CoordY < Y_INC_S3) {
- transition = true;
- threshold += g_boxThreshold_Trs[height];
- } else {
- threshold += g_boxThreshold_Y[height];
- }
- }
-
- /*Check Stop condition*/
- if (threshold == 0)
- return ;
+ threshold = 30;
/*X*/
distance = abs(*CoordX - lastX_loc);
- if (transition) {
- if (distance >= 70) {
- isMoved = true;
- isXMoved = true;
- }
- } else if (distance >= threshold)
+
+ if (distance >= threshold)
isMoved = true;
- /*Y*/
if (isMoved == false) {
distance = abs(*CoordY - lastY_loc);
if (distance >= threshold)
@@ -633,28 +710,96 @@ void boxfilt(unsigned short *CoordX, unsigned short *CoordY,
/*Update position*/
if (isMoved) {
- if (isXMoved)
- lastX_loc = *CoordX;
- else {
- lastX_loc = *CoordX;
- lastY_loc = *CoordY;
- }
+ lastX_loc = *CoordX;
+ lastY_loc = *CoordY;
} else {
- *CoordX = lastX_loc;
+ *CoordX = lastX_loc + bounce;
*CoordY = lastY_loc;
+ if (bounce)
+ bounce = 0;
+ else
+ bounce += 5;
}
}
#endif
+#if defined(WACOM_USE_AVE_TRANSITION)
+int g_aveLevel_C[] = {2, 2, 4, };
+int g_aveLevel_X[] = {3, 3, 4, };
+int g_aveLevel_Y[] = {3, 3, 4, };
+int g_aveLevel_Trs[] = {3, 4, 4, };
+int g_aveLevel_Cor[] = {4, 4, 4, };
+int g_aveShift;
+
+void ave_level(short CoordX, short CoordY,
+ int height, int *aveStrength)
+{
+ bool transition = false;
+ bool edgeY = false, edgeX = false;
+ bool cY = false, cX = false;
+
+ if (CoordY > (WACOM_MAX_COORD_Y - 800))
+ cY = true;
+ else if (CoordY < 800)
+ cY = true;
+
+ if (CoordX > (WACOM_MAX_COORD_X - 800))
+ cX = true;
+ else if (CoordX < 800)
+ cX = true;
+
+ if (cX && cY) {
+ *aveStrength = g_aveLevel_Cor[height];
+ return ;
+ }
+
+ /*Start Filtering*/
+ if (CoordX > X_INC_E1)
+ edgeX = true;
+ else if (CoordX < X_INC_S1)
+ edgeX = true;
+
+ /*Right*/
+ if (CoordY > Y_INC_E1) {
+ /*Transition*/
+ if (CoordY > Y_INC_E3)
+ transition = true;
+ else
+ edgeY = true;
+ }
+ /*Left*/
+ else if (CoordY < Y_INC_S1) {
+ /*Transition*/
+ if (CoordY > Y_INC_S3)
+ transition = true;
+ else
+ edgeY = true;
+ }
+
+ if (transition)
+ *aveStrength = g_aveLevel_Trs[height];
+ else if (edgeX)
+ *aveStrength = g_aveLevel_X[height];
+ else if (edgeY)
+ *aveStrength = g_aveLevel_Y[height];
+ else
+ *aveStrength = g_aveLevel_C[height];
+}
+#endif
#endif /*WACOM_IMPORT_FW_ALGO*/
-static bool wacom_i2c_coord_range(u16 *x, u16 *y)
+static bool wacom_i2c_coord_range(s16 *x, s16 *y)
{
#if defined(CONFIG_MACH_P4NOTE)
if ((*x <= WACOM_POSX_OFFSET) || (*y <= WACOM_POSY_OFFSET))
return false;
#endif
+#if defined(CONFIG_MACH_T0)
+ if ((*x >= 0) && (*y >= 0) &&
+ (*x <= WACOM_POSX_MAX) && (*y <= WACOM_POSY_MAX - 50))
+#else
if ((*x <= WACOM_POSX_MAX) && (*y <= WACOM_POSY_MAX))
+#endif
return true;
return false;
@@ -666,9 +811,12 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c)
int ret = 0;
u8 *data;
int rubber, stylus;
- static u16 x, y, pressure;
- static u16 tmp;
+ static s16 x, y, pressure;
+ static s16 tmp;
int rdy = 0;
+ u8 gain = 0;
+ u8 height = 0;
+ int aveStrength = 2;
#ifdef WACOM_IRQ_WORK_AROUND
cancel_delayed_work(&wac_i2c->pendct_dwork);
@@ -715,30 +863,50 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c)
x = ((u16) data[1] << 8) + (u16) data[2];
y = ((u16) data[3] << 8) + (u16) data[4];
pressure = ((u16) data[5] << 8) + (u16) data[6];
-
+#if defined(WACOM_USE_HEIGHT)
+ gain = data[7];
+#endif
#ifdef WACOM_IMPORT_FW_ALGO
+#if defined(CONFIG_MACH_T0)
+ x = x - origin_offset[0];
+ y = y - origin_offset[1];
+#else /*Q1*/
/* Change Position to Active Area */
- if (x <= origin_offset[0])
+ if (x < origin_offset[0])
x = 0;
else
x = x - origin_offset[0];
- if (y <= origin_offset[1])
+ if (y < origin_offset[1])
y = 0;
else
y = y - origin_offset[1];
-
+#endif
#ifdef WACOM_USE_OFFSET_TABLE
- if (wac_i2c->use_offset_table)
- wacom_i2c_coord_offset(&x, &y);
+ if (wac_i2c->use_offset_table) {
+ if (x >= 0 && y >= 0)
+ wacom_i2c_coord_offset(&x, &y);
+ }
#endif
-#ifdef WACOM_USE_AVERAGING
- wacom_i2c_coord_average(&x, &y, rdy);
+
+#ifdef CONFIG_MACH_T0
+ if (wac_i2c->use_aveTransition && pressure == 0) {
+#ifdef WACOM_USE_HEIGHT
+ height = wacom_i2c_coord_level(gain);
+#endif
+#ifdef WACOM_USE_AVE_TRANSITION
+ ave_level(x, y, height, &aveStrength);
#endif
-#ifdef WACOM_USE_BOXFILTER
- if (wac_i2c->use_box_filter && pressure == 0)
- boxfilt(&x, &y, 0, rdy);
+ }
+#endif
+
+#ifdef WACOM_USE_AVERAGING
+ wacom_i2c_coord_average(&x, &y, rdy, aveStrength);
#endif
+#ifdef WACOM_USE_BOX_FILTER
+ if (pressure == 0)
+ boxfilt(&x, &y, height, rdy);
#endif
+#endif /*WACOM_IMPORT_FW_ALGO*/
if (wac_i2c->wac_pdata->x_invert)
x = wac_i2c->wac_feature->x_max - x;
if (wac_i2c->wac_pdata->y_invert)
@@ -749,6 +917,7 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c)
x = y;
y = tmp;
}
+
#ifdef WACOM_USE_TILT_OFFSET
/* Add offset */
x = x + tilt_offsetX[user_hand][screen_rotate];
@@ -808,7 +977,7 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c)
}
#if defined(CONFIG_SAMSUNG_KERNEL_DEBUG_USER)
else
- printk(KERN_DEBUG "[E-PEN] raw data x=0x%x, y=0x%x\n",
+ printk(KERN_DEBUG "[E-PEN] raw data x=%d, y=%d\n",
x, y);
#endif
} else {
@@ -835,14 +1004,13 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c)
schedule_delayed_work(&wac_i2c->pendct_dwork, HZ / 10);
return 0;
-#else /* WACOM_IRQ_WORK_AROUND */
+#else /* WACOM_IRQ_WORK_AROUND */
#ifdef WACOM_USE_AVERAGING
/* enable emr device */
- wacom_i2c_coord_average(0, 0, 0);
+ wacom_i2c_coord_average(0, 0, 0, 0);
#endif
-#ifdef WACOM_USE_BOXFILTER
- if (wac_i2c->use_box_filter)
- boxfilt(0, 0, 0, 0);
+#ifdef WACOM_USE_BOX_FILTER
+ boxfilt(0, 0, 0, 0);
#endif
#ifdef WACOM_PDCT_WORK_AROUND