diff options
Diffstat (limited to 'drivers/input/touchscreen/wacom/wacom_i2c_func.c')
-rw-r--r-- | drivers/input/touchscreen/wacom/wacom_i2c_func.c | 522 |
1 files changed, 395 insertions, 127 deletions
diff --git a/drivers/input/touchscreen/wacom/wacom_i2c_func.c b/drivers/input/touchscreen/wacom/wacom_i2c_func.c index dd1c988..a24a41b 100644 --- a/drivers/input/touchscreen/wacom/wacom_i2c_func.c +++ b/drivers/input/touchscreen/wacom/wacom_i2c_func.c @@ -19,23 +19,14 @@ #include <linux/wacom_i2c.h> #include "wacom_i2c_flash.h" -#ifdef COOR_WORK_AROUND -#include "wacom_i2c_coord_table.h" -#define WACOM_OFFSET_X (-60) -#define WACOM_OFFSET_Y (-100) +#ifdef WACOM_IMPORT_FW_ALGO +#include "wacom_i2c_coord_table.h" /* For firmware algorithm */ #define CAL_PITCH 100 -#define MAX_COORD_X 11392 -#define MAX_COORD_Y 7120 -#define LATTICE_SIZE_X ((MAX_COORD_X / CAL_PITCH)+2) -#define LATTICE_SIZE_Y ((MAX_COORD_Y / CAL_PITCH)+2) -#endif - -#if defined(CONFIG_MACH_P4NOTE) -#define MAX_COORD_X WACOM_POSX_MAX -#define MAX_COORD_Y WACOM_POSY_MAX +#define LATTICE_SIZE_X ((WACOM_MAX_COORD_X / CAL_PITCH)+2) +#define LATTICE_SIZE_Y ((WACOM_MAX_COORD_Y / CAL_PITCH)+2) #endif #if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP) @@ -43,20 +34,49 @@ #endif /* block wacom coordinate print */ -/* extern int sec_debug_level(void); */ #ifdef CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK +#if defined(CONFIG_MACH_P4NOTE) +void free_dvfs_lock(struct work_struct *work) +{ + struct wacom_i2c *wac_i2c = + container_of(work, struct wacom_i2c, dvfs_work.work); + + if (wac_i2c->dvfs_lock_status) + dev_lock(wac_i2c->bus_dev, + wac_i2c->dev, SEC_BUS_LOCK_FREQ); + else { + dev_unlock(wac_i2c->bus_dev, wac_i2c->dev); + exynos_cpufreq_lock_free(DVFS_LOCK_ID_PEN); + } +} + +static void set_dvfs_lock(struct wacom_i2c *wac_i2c, bool on) +{ + if (on) { + if (!wac_i2c->dvfs_lock_status) { + cancel_delayed_work(&wac_i2c->dvfs_work); + dev_lock(wac_i2c->bus_dev, + wac_i2c->dev, SEC_BUS_LOCK_FREQ2); + exynos_cpufreq_lock(DVFS_LOCK_ID_PEN, + wac_i2c->cpufreq_level); + wac_i2c->dvfs_lock_status = true; + schedule_delayed_work(&wac_i2c->dvfs_work, + msecs_to_jiffies(SEC_DVFS_LOCK_TIMEOUT_MS)); + } + } else { + if (wac_i2c->dvfs_lock_status) { + schedule_delayed_work(&wac_i2c->dvfs_work, + msecs_to_jiffies(SEC_DVFS_LOCK_TIMEOUT_MS)); + wac_i2c->dvfs_lock_status = false; + } + } +} +#else /* CONFIG_MACH_P4NOTE */ void free_dvfs_lock(struct work_struct *work) { struct wacom_i2c *wac_i2c = container_of(work, struct wacom_i2c, dvfs_work.work); -#ifdef SEC_BUS_LOCK -#if defined(CONFIG_MACH_P4NOTE) - dev_unlock(wac_i2c->bus_dev, wac_i2c->dev); -#else - exynos4_busfreq_lock_free(DVFS_LOCK_ID_PEN); -#endif -#endif /* SEC_BUS_LOCK */ exynos_cpufreq_lock_free(DVFS_LOCK_ID_PEN); wac_i2c->dvfs_lock_status = false; } @@ -66,14 +86,6 @@ static void set_dvfs_lock(struct wacom_i2c *wac_i2c, bool on) if (on) { cancel_delayed_work(&wac_i2c->dvfs_work); if (!wac_i2c->dvfs_lock_status) { -#ifdef SEC_BUS_LOCK -#if defined(CONFIG_MACH_P4NOTE) - dev_lock(wac_i2c->bus_dev, - wac_i2c->dev, BUS_LOCK_FREQ); -#else - exynos4_busfreq_lock(DVFS_LOCK_ID_PEN, BUS_L1); -#endif -#endif /* SEC_BUS_LOCK */ exynos_cpufreq_lock(DVFS_LOCK_ID_PEN, wac_i2c->cpufreq_level); wac_i2c->dvfs_lock_status = true; @@ -85,23 +97,29 @@ static void set_dvfs_lock(struct wacom_i2c *wac_i2c, bool on) } } #endif +#endif /* CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK */ void forced_release(struct wacom_i2c *wac_i2c) { #if defined(CONFIG_SAMSUNG_KERNEL_DEBUG_USER) printk(KERN_DEBUG "[E-PEN] %s\n", __func__); #endif + input_report_abs(wac_i2c->input_dev, ABS_X, wac_i2c->last_x); + input_report_abs(wac_i2c->input_dev, ABS_Y, wac_i2c->last_y); input_report_abs(wac_i2c->input_dev, ABS_PRESSURE, 0); input_report_key(wac_i2c->input_dev, BTN_STYLUS, 0); input_report_key(wac_i2c->input_dev, BTN_TOUCH, 0); #if defined(WACOM_IRQ_WORK_AROUND) || defined(WACOM_PDCT_WORK_AROUND) input_report_key(wac_i2c->input_dev, BTN_TOOL_RUBBER, 0); input_report_key(wac_i2c->input_dev, BTN_TOOL_PEN, 0); + input_report_key(wac_i2c->input_dev, KEY_PEN_PDCT, 0); #else input_report_key(wac_i2c->input_dev, wac_i2c->tool, 0); #endif input_sync(wac_i2c->input_dev); + wac_i2c->last_x = 0; + wac_i2c->last_y = 0; wac_i2c->pen_prox = 0; wac_i2c->pen_pressed = 0; wac_i2c->side_pressed = 0; @@ -116,15 +134,16 @@ void forced_release(struct wacom_i2c *wac_i2c) #ifdef WACOM_PDCT_WORK_AROUND void forced_hover(struct wacom_i2c *wac_i2c) { + /* To distinguish hover and pdct area, release */ + if (wac_i2c->last_x != 0 || wac_i2c->last_y != 0) { + printk(KERN_DEBUG "[E-PEN] release hover\n"); + forced_release(wac_i2c); + } + wac_i2c->rdy_pdct = true; #if defined(CONFIG_SAMSUNG_KERNEL_DEBUG_USER) printk(KERN_DEBUG "[E-PEN] %s\n", __func__); #endif - input_report_abs(wac_i2c->input_dev, ABS_X, 0); - input_report_abs(wac_i2c->input_dev, ABS_Y, 0); - input_report_abs(wac_i2c->input_dev, ABS_PRESSURE, 0); - input_report_key(wac_i2c->input_dev, BTN_STYLUS, 0); - input_report_key(wac_i2c->input_dev, BTN_TOUCH, 1); - input_report_key(wac_i2c->input_dev, BTN_TOOL_PEN, 1); + input_report_key(wac_i2c->input_dev, KEY_PEN_PDCT, 1); input_sync(wac_i2c->input_dev); #ifdef CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK @@ -147,121 +166,224 @@ void wacom_i2c_pendct_work(struct work_struct *work) } #endif +int wacom_i2c_send(struct wacom_i2c *wac_i2c, + const char *buf, int count, bool mode) +{ + struct i2c_client *client = mode ? + wac_i2c->client_boot : wac_i2c->client; + + if (wac_i2c->boot_mode && !mode) { + printk(KERN_DEBUG + "[E-PEN] failed to send\n"); + return 0; + } + + return i2c_master_send(client, buf, count); +} + +int wacom_i2c_recv(struct wacom_i2c *wac_i2c, + char *buf, int count, bool mode) +{ + struct i2c_client *client = mode ? + wac_i2c->client_boot : wac_i2c->client; + + if (wac_i2c->boot_mode && !mode) { + printk(KERN_DEBUG + "[E-PEN] failed to send\n"); + return 0; + } + + return i2c_master_recv(client, buf, count); +} + int wacom_i2c_test(struct wacom_i2c *wac_i2c) { int ret, i; char buf, test[10]; buf = COM_QUERY; - ret = i2c_master_send(wac_i2c->client, &buf, sizeof(buf)); + ret = wacom_i2c_send(wac_i2c, &buf, sizeof(buf), false); if (ret > 0) - printk(KERN_INFO "[E-PEN]: buf:%d, sent:%d\n", buf, ret); + printk(KERN_INFO "[E-PEN] buf:%d, sent:%d\n", buf, ret); else { - printk(KERN_ERR "[E-PEN]: Digitizer is not active\n"); + printk(KERN_ERR "[E-PEN] Digitizer is not active\n"); return -1; } - ret = i2c_master_recv(wac_i2c->client, test, sizeof(test)); + ret = wacom_i2c_recv(wac_i2c, test, sizeof(test), false); if (ret >= 0) { for (i = 0; i < 8; i++) - printk(KERN_INFO "[E-PEN]: %d\n", test[i]); + printk(KERN_INFO "[E-PEN] %d\n", test[i]); } else { - printk(KERN_ERR "[E-PEN]: Digitizer does not reply\n"); + printk(KERN_ERR "[E-PEN] Digitizer does not reply\n"); return -1; } return 0; } -int wacom_i2c_master_send(struct i2c_client *client, - const char *buf, int count, unsigned short addr) +#ifdef WACOM_CONNECTION_CHECK +static void wacom_open_test(struct wacom_i2c *wac_i2c) { - int ret; - struct i2c_adapter *adap = client->adapter; - struct i2c_msg msg; + u8 cmd = 0; + u8 buf[2] = {0,}; + int ret = 0, cnt = 30; + + cmd = WACOM_I2C_STOP; + ret = wacom_i2c_send(wac_i2c, &cmd, 1, false); + if (ret <= 0) { + printk(KERN_ERR "[E-PEN] failed to send stop command\n"); + return ; + } - msg.addr = addr; - msg.flags = client->flags & I2C_M_TEN; - msg.len = count; - msg.buf = (char *)buf; + cmd = WACOM_I2C_GRID_CHECK; + ret = wacom_i2c_send(wac_i2c, &cmd, 1, false); + if (ret <= 0) { + printk(KERN_ERR "[E-PEN] failed to send stop command\n"); + goto grid_check_error; + } + + cmd = WACOM_STATUS; + do { + msleep(50); + if (1 == wacom_i2c_send(wac_i2c, &cmd, 1, false)) { + if (2 == wacom_i2c_recv(wac_i2c, + buf, 2, false)) { + switch (buf[0]) { + /* + * status value + * 0 : data is not ready + * 1 : PASS + * 2 : Fail (coil function error) + * 3 : Fail (All coil function error) + */ + case 1: + case 2: + case 3: + cnt = 0; + break; + + default: + break; + } + } + } + } while (cnt--); - ret = i2c_transfer(adap, &msg, 1); + wac_i2c->connection_check = (1 == buf[0]); + printk(KERN_DEBUG + "[E-PEN] epen_connection : %s %d\n", + (1 == buf[0]) ? "Pass" : "Fail", buf[1]); + +grid_check_error: + cmd = WACOM_I2C_STOP; + wacom_i2c_send(wac_i2c, &cmd, 1, false); + + cmd = WACOM_I2C_START; + wacom_i2c_send(wac_i2c, &cmd, 1, false); - /* If everything went ok (i.e. 1 msg transmitted), return #bytes - transmitted, else error code. */ - return (ret == 1) ? count : ret; } +#endif -int wacom_i2c_master_recv(struct i2c_client *client, char *buf, - int count, unsigned short addr) +int wacom_checksum(struct wacom_i2c *wac_i2c) { - struct i2c_adapter *adap = client->adapter; - struct i2c_msg msg; - int ret; + int ret = 0, retry = 10; + int i = 0; + u8 buf[5] = {0, }; + + buf[0] = COM_CHECKSUM; + + while (retry--) { + ret = wacom_i2c_send(wac_i2c, &buf[0], 1, false); + if (ret < 0) { + printk(KERN_DEBUG + "[E-PEN] i2c fail, retry, %d\n", + __LINE__); + continue; + } + + msleep(200); + ret = wacom_i2c_recv(wac_i2c, buf, 5, false); + if (ret < 0) { + printk(KERN_DEBUG + "[E-PEN] i2c fail, retry, %d\n", + __LINE__); + continue; + } else if (buf[0] == 0x1f) + break; + printk(KERN_DEBUG "[E-PEN] checksum retry\n"); + } + + if (ret >= 0) { + printk(KERN_DEBUG + "[E-PEN] received checksum %x, %x, %x, %x, %x\n", + buf[0], buf[1], buf[2], buf[3], buf[4]); + } + + for (i = 0; i < 5; ++i) { + if (buf[i] != Firmware_checksum[i]) { + printk(KERN_DEBUG + "[E-PEN] checksum fail %dth %x %x\n", i, + buf[i], Firmware_checksum[i]); + break; + } + } - msg.addr = addr; - msg.flags = client->flags & I2C_M_TEN; - msg.flags |= I2C_M_RD; - msg.len = count; - msg.buf = buf; + wac_i2c->checksum_result = (5 == i); - ret = i2c_transfer(adap, &msg, 1); +#ifdef WACOM_CONNECTION_CHECK + if (!wac_i2c->connection_check) + wacom_open_test(wac_i2c); +#endif - /* If everything went ok (i.e. 1 msg transmitted), return #bytes - transmitted, else error code. */ - return (ret == 1) ? count : ret; + return ret; } int wacom_i2c_query(struct wacom_i2c *wac_i2c) { struct wacom_features *wac_feature = wac_i2c->wac_feature; - struct i2c_msg msg[2]; int ret; - char buf; - u8 data[9]; + u8 buf; + u8 data[9] = {0, }; int i = 0; int query_limit = 10; buf = COM_QUERY; - msg[0].addr = wac_i2c->client->addr; - msg[0].flags = 0x00; - msg[0].len = 1; - msg[0].buf = (u8 *)&buf; - - msg[1].addr = wac_i2c->client->addr; - msg[1].flags = I2C_M_RD; - msg[1].len = COM_QUERY_NUM; - msg[1].buf = (u8 *) data; - - do { - ret = i2c_transfer(wac_i2c->client->adapter, msg, 2); - printk(KERN_INFO "[E-PEN]: %s: %dth ret of wacom query=%d\n", - __func__, i, ret); - - i++; - if (ret < 0) + for (i = 0; i < query_limit; i++) { + ret = wacom_i2c_send(wac_i2c, &buf, 1, false); + if (ret < 0) { + printk(KERN_ERR"[E-PEN] I2C send failed(%d)\n", ret); continue; - - wac_feature->fw_version = ((u16) data[7] << 8) + (u16) data[8]; - if (wac_feature->fw_version != 0xFF - && wac_feature->fw_version != 0xFFFF - && wac_feature->fw_version != 0x0) { - break; - } else { - printk(KERN_NOTICE - "[E-PEN]: %X, %X, %X, %X, %X, %X, %X, %X, %X fw=0x%x\n", - data[0], data[1], data[2], data[3], data[4], - data[5], data[6], data[7], data[8], - wac_feature->fw_version); } + msleep(100); + ret = wacom_i2c_recv(wac_i2c, data, COM_QUERY_NUM, false); + if (ret < 0) { + printk(KERN_ERR"[E-PEN] I2C recv failed(%d)\n", ret); + continue; + } + printk(KERN_INFO "[E-PEN] %s: %dth ret of wacom query=%d\n", + __func__, i, ret); + if (COM_QUERY_NUM == ret) { + if (0x0f == data[0]) { + wac_feature->fw_version = + ((u16) data[7] << 8) + (u16) data[8]; + break; + } else { + printk(KERN_NOTICE + "[E-PEN] %X, %X, %X, %X, %X, %X, %X, fw=0x%x\n", + data[0], data[1], data[2], data[3], + data[4], data[5], data[6], + wac_feature->fw_version); + } + } + } - i++; - } while (i < query_limit); - -#if defined(CONFIG_MACH_Q1_BD) || defined(CONFIG_MACH_P4NOTE) - wac_feature->x_max = (u16) MAX_COORD_X; - wac_feature->y_max = (u16) MAX_COORD_Y; +#if defined(CONFIG_MACH_Q1_BD)\ + || defined(CONFIG_MACH_P4NOTE)\ + || defined(CONFIG_MACH_T0) + wac_feature->x_max = (u16) WACOM_MAX_COORD_X; + wac_feature->y_max = (u16) WACOM_MAX_COORD_Y; #else wac_feature->x_max = ((u16) data[1] << 8) + (u16) data[2]; wac_feature->y_max = ((u16) data[3] << 8) + (u16) data[4]; @@ -270,35 +392,48 @@ int wacom_i2c_query(struct wacom_i2c *wac_i2c) #if defined(COOR_WORK_AROUND) if (i == 10 || ret < 0) { - printk(KERN_NOTICE "[E-PEN]: COOR_WORK_AROUND is applied\n"); + printk(KERN_NOTICE "[E-PEN] COOR_WORK_AROUND is applied\n"); printk(KERN_NOTICE - "[E-PEN]: %X, %X, %X, %X, %X, %X, %X, %X, %X\n", data[0], + "[E-PEN] %X, %X, %X, %X, %X, %X, %X, %X, %X\n", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]); - wac_feature->x_max = (u16) COOR_WORK_AROUND_X_MAX; - wac_feature->y_max = (u16) COOR_WORK_AROUND_Y_MAX; - wac_feature->pressure_max = (u16) COOR_WORK_AROUND_PRESSURE_MAX; + wac_feature->x_max = (u16) WACOM_MAX_COORD_X; + wac_feature->y_max = (u16) WACOM_MAX_COORD_Y; + wac_feature->pressure_max = (u16) WACOM_MAX_PRESSURE; +#ifdef CONFIG_MACH_T0 + wac_feature->fw_version = 0; +#else wac_feature->fw_version = 0xFF; +#endif } #endif - printk(KERN_NOTICE "[E-PEN]: x_max=0x%X\n", wac_feature->x_max); - printk(KERN_NOTICE "[E-PEN]: y_max=0x%X\n", wac_feature->y_max); - printk(KERN_NOTICE "[E-PEN]: pressure_max=0x%X\n", + printk(KERN_NOTICE "[E-PEN] x_max=0x%X\n", wac_feature->x_max); + printk(KERN_NOTICE "[E-PEN] y_max=0x%X\n", wac_feature->y_max); + printk(KERN_NOTICE "[E-PEN] pressure_max=0x%X\n", wac_feature->pressure_max); - printk(KERN_NOTICE "[E-PEN]: fw_version=0x%X (d7:0x%X,d8:0x%X)\n", + printk(KERN_NOTICE "[E-PEN] fw_version=0x%X (d7:0x%X,d8:0x%X)\n", wac_feature->fw_version, data[7], data[8]); - printk(KERN_NOTICE "[E-PEN]: %X, %X, %X, %X, %X, %X, %X, %X, %X\n", + printk(KERN_NOTICE "[E-PEN] %X, %X, %X, %X, %X, %X, %X, %X, %X\n", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]); - if ((i == 10) && (ret < 0)) + if ((i == 10) && (ret < 0)) { + printk(KERN_DEBUG"[E-PEN] %s, failed\n", __func__); + wac_i2c->query_status = false; return ret; + } + wac_i2c->query_status = true; + +#if defined(CONFIG_MACH_P4NOTE) + wacom_checksum(wac_i2c); +#endif return 0; } -#ifdef COOR_WORK_AROUND +#ifdef WACOM_IMPORT_FW_ALGO +#ifdef WACOM_USE_OFFSET_TABLE void wacom_i2c_coord_offset(u16 *coordX, u16 *coordY) { u16 ix, iy; @@ -314,7 +449,7 @@ void wacom_i2c_coord_offset(u16 *coordX, u16 *coordY) dXy_0 = *coordY - (iy * CAL_PITCH); dXy_1 = CAL_PITCH - dXy_0; - if (*coordX <= MAX_COORD_X) { + if (*coordX <= WACOM_MAX_COORD_X) { D0 = tableX[user_hand][screen_rotate][ix + (iy * LATTICE_SIZE_X)] * (dXx_1 + dXy_1); @@ -337,7 +472,7 @@ void wacom_i2c_coord_offset(u16 *coordX, u16 *coordY) *coordX = 0; } - if (*coordY <= MAX_COORD_Y) { + if (*coordY <= WACOM_MAX_COORD_Y) { D0 = tableY[user_hand][screen_rotate][ix + (iy * LATTICE_SIZE_X)] * (dXy_1 + dXx_1); @@ -360,7 +495,9 @@ void wacom_i2c_coord_offset(u16 *coordX, u16 *coordY) *coordY = 0; } } +#endif +#ifdef WACOM_USE_AVERAGING void wacom_i2c_coord_average(unsigned short *CoordX, unsigned short *CoordY, int bFirstLscan) { @@ -407,6 +544,110 @@ void wacom_i2c_coord_average(unsigned short *CoordX, unsigned short *CoordY, } #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, }; + +void boxfilt(unsigned short *CoordX, unsigned short *CoordY, + int height, int bFirstLscan) +{ + bool isMoved = false; + static bool bFirst = true; + static unsigned short lastX_loc, lastY_loc; + static unsigned char bResetted; + int threshold = 0; + int distance = 0; + bool transition = false; + bool isXMoved = false; + + /*Reset filter*/ + if (bFirstLscan == 0) { + bResetted = 0; + return ; + } + + if (bFirstLscan && (bResetted == 0)) { + lastX_loc = *CoordX; + lastY_loc = *CoordY; + bResetted = 1; + } + + if (bFirst) { + lastX_loc = *CoordX; + lastY_loc = *CoordY; + bFirst = false; + } + + /*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 ; + + /*X*/ + distance = abs(*CoordX - lastX_loc); + if (transition) { + if (distance >= 70) { + isMoved = true; + isXMoved = true; + } + } else if (distance >= threshold) + isMoved = true; + + /*Y*/ + if (isMoved == false) { + distance = abs(*CoordY - lastY_loc); + if (distance >= threshold) + isMoved = true; + } + + /*Update position*/ + if (isMoved) { + if (isXMoved) + lastX_loc = *CoordX; + else { + lastX_loc = *CoordX; + lastY_loc = *CoordY; + } + } else { + *CoordX = lastX_loc; + *CoordY = lastY_loc; + } +} +#endif + +#endif /*WACOM_IMPORT_FW_ALGO*/ + static bool wacom_i2c_coord_range(u16 *x, u16 *y) { #if defined(CONFIG_MACH_P4NOTE) @@ -434,7 +675,7 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c) #endif data = wac_i2c->wac_feature->data; - ret = i2c_master_recv(wac_i2c->client, data, COM_COORD_NUM); + ret = wacom_i2c_recv(wac_i2c, data, COM_COORD_NUM, false); if (ret < 0) { printk(KERN_ERR "[E-PEN] %s failed to read i2c.L%d\n", __func__, @@ -442,8 +683,14 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c) return -1; } #if defined(CONFIG_SAMSUNG_KERNEL_DEBUG_USER) +#if defined(CONFIG_MACH_T0) + /*printk(KERN_DEBUG"[E-PEN] %x, %x, %x, %x, %x, %x, %x %x\n", + data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7]);*/ +#else pr_debug("[E-PEN] %x, %x, %x, %x, %x, %x, %x\n", - data[0], data[1], data[2], data[3], data[4], data[5], data[6]); + data[0], data[1], data[2], data[3], data[4], data[5], data[6]); +#endif #endif if (data[0] & 0x80) { /* enable emr device */ @@ -479,12 +726,19 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c) y = 0; else y = y - origin_offset[1]; -#ifdef COOR_WORK_AROUND - wacom_i2c_coord_offset(&x, &y); + +#ifdef WACOM_USE_OFFSET_TABLE + if (wac_i2c->use_offset_table) + wacom_i2c_coord_offset(&x, &y); +#endif +#ifdef WACOM_USE_AVERAGING wacom_i2c_coord_average(&x, &y, rdy); #endif +#ifdef WACOM_USE_BOXFILTER + if (wac_i2c->use_box_filter && pressure == 0) + boxfilt(&x, &y, 0, rdy); +#endif #endif - if (wac_i2c->wac_pdata->x_invert) x = wac_i2c->wac_feature->x_max - x; if (wac_i2c->wac_pdata->y_invert) @@ -495,7 +749,7 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c) x = y; y = tmp; } -#ifdef COOR_WORK_AROUND +#ifdef WACOM_USE_TILT_OFFSET /* Add offset */ x = x + tilt_offsetX[user_hand][screen_rotate]; y = y + tilt_offsetY[user_hand][screen_rotate]; @@ -509,7 +763,14 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c) BTN_STYLUS, stylus); input_report_key(wac_i2c->input_dev, BTN_TOUCH, prox); input_report_key(wac_i2c->input_dev, wac_i2c->tool, 1); + if (wac_i2c->rdy_pdct) { + wac_i2c->rdy_pdct = false; + input_report_key(wac_i2c->input_dev, + KEY_PEN_PDCT, 0); + } input_sync(wac_i2c->input_dev); + wac_i2c->last_x = x; + wac_i2c->last_y = y; if (prox && !wac_i2c->pen_pressed) { #ifdef CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK @@ -575,10 +836,14 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c) return 0; #else /* WACOM_IRQ_WORK_AROUND */ -#ifdef COOR_WORK_AROUND +#ifdef WACOM_USE_AVERAGING /* enable emr device */ wacom_i2c_coord_average(0, 0, 0); #endif +#ifdef WACOM_USE_BOXFILTER + if (wac_i2c->use_box_filter) + boxfilt(0, 0, 0, 0); +#endif #ifdef WACOM_PDCT_WORK_AROUND if (wac_i2c->pen_pdct == PDCT_DETECT_PEN) @@ -598,6 +863,7 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c) input_report_key(wac_i2c->input_dev, BTN_TOOL_RUBBER, 0); input_report_key(wac_i2c->input_dev, BTN_TOOL_PEN, 0); + input_report_key(wac_i2c->input_dev, KEY_PEN_PDCT, 0); #else input_report_key(wac_i2c->input_dev, wac_i2c->tool, 0); #endif @@ -608,6 +874,8 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c) wac_i2c->pen_prox = 0; wac_i2c->pen_pressed = 0; wac_i2c->side_pressed = 0; + wac_i2c->last_x = 0; + wac_i2c->last_y = 0; #ifdef CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK set_dvfs_lock(wac_i2c, false); |