aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen/mms_ts_gc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen/mms_ts_gc.c')
-rw-r--r--drivers/input/touchscreen/mms_ts_gc.c925
1 files changed, 545 insertions, 380 deletions
diff --git a/drivers/input/touchscreen/mms_ts_gc.c b/drivers/input/touchscreen/mms_ts_gc.c
index 6fe7dbb..7efe079 100644
--- a/drivers/input/touchscreen/mms_ts_gc.c
+++ b/drivers/input/touchscreen/mms_ts_gc.c
@@ -16,9 +16,10 @@
*/
#define SHOW_COORD 1
+#define FW_UPDATABLE 1
#define ISC_DL_MODE 1
-#define TOUCH_BOOSTER 0
-#define SEC_TSP_FACTORY_TEST
+#define TOUCH_BOOSTER 1
+#define SEC_TSP_FACTORY_TEST 1
/* #define ESD_DEBUG */
#include <linux/delay.h>
@@ -44,25 +45,33 @@
#include <mach/dev.h>
#endif
-/* Model dependency values */
+#define EVENT_SZ_8_BYTES 8
+#define EVENT_SZ_6_BYTES 6
#define MAX_FINGERS 10
#define MAX_WIDTH 30
#define MAX_PRESSURE 255
-#define FINGER_EVENT_SZ 6
-#define TSP_VENDOR "MELFAS"
-#define TSP_IC "MMS136"
-#define FW_VERSION 0x02 /* GC Bring-up */
+#define MAX_ANGLE 90
+#define MIN_ANGLE -90
/* Registers */
#define MMS_INPUT_EVENT_PKT_SZ 0x0F
#define MMS_INPUT_EVENT0 0x10
-#define MMS_FW_VER_CORE 0xF3 /* GC Bring-up */
-#define MMS_FW_VER_PRIV 0xF4 /* GC Bring-up */
-#define MMS_FW_VER_PUBL 0xF5 /* GC Bring-up */
-#define MMS_FW_VERSION 0xF5 /* GC Bring-up */
-#define MMS_TA_NOISE_REG 0x30
-#define MMS_TA_NOISE_ON 0x01
-#define MMS_TA_NOISE_OFF 0x02
+
+#define MMS_TSP_REVISION 0xF0
+#define MMS_HW_REVISION 0xF1
+#define MMS_COMPAT_GROUP 0xF2
+#define MMS_FW_VERSION 0xF3
+
+#define MMS_TA_REG 0x60
+#define MMS_TA_OFF 0x00
+#define MMS_TA_ON 0x01
+#define MMS_NOISE_REG 0x61
+#define MMS_NOISE_OFF 0x00
+#define MMS_NOISE_ON 0x01
+
+#if FW_UPDATABLE
+#include "GC_BOOT.h"
+#endif
enum {
TSP_STATE_RELEASE = 0,
@@ -71,12 +80,30 @@ enum {
};
#if TOUCH_BOOSTER
+#define TOUCH_BOOSTER_CPU_CLK 800000
+#define TOUCH_BOOSTER_BUS_CLK_266 267160
+#define TOUCH_BOOSTER_BUS_CLK_400 400200
#define TOUCH_BOOSTER_OFF_TIME 100
#define TOUCH_BOOSTER_CHG_TIME 200
+enum {
+ TOUCH_BOOSTER_DELAY_OFF = 0,
+ TOUCH_BOOSTER_ON,
+ TOUCH_BOOSTER_QUICK_OFF,
+};
#endif
#if ISC_DL_MODE /* ISC_DL_MODE start */
-#define MAX_FW_PATH 255
+char *isc_dl_msg;
+char *isc_dl_msg_temp;
+#define ISC_DL_MSG(args ...) \
+do { \
+ sprintf(isc_dl_msg_temp, args); \
+ strcat(isc_dl_msg, isc_dl_msg_temp); \
+} while (0)
+
+#define MAX_FW_PATH 255
+#define FW_DIRECTORY "tsp_melfas/gc/"
+
enum {
BUILT_IN = 0,
UMS,
@@ -84,6 +111,17 @@ enum {
};
enum {
+ COMPARE_UPDATE = 0,
+ FORCED_UPDATE,
+};
+
+enum {
+ PANEL_MOREENS = 'A',
+ PANEL_SMAC = 'B',
+ PANEL_SMAC_NEW = 'C',
+};
+
+enum {
ISC_NONE = -1,
ISC_SUCCESS = 0,
ISC_FILE_OPEN_ERROR,
@@ -195,10 +233,6 @@ static bool section_update_flag[SECTION_NUM];
const struct firmware *fw_mbin[SECTION_NUM];
static unsigned char g_wr_buf[1024 + 3 + 2];
-enum {
- COMPARE_UPDATE = 0,
- FORCED_UPDATE,
-};
#endif /* ISC_DL_MODE end */
enum {
@@ -211,11 +245,7 @@ enum {
#define ISP_MAX_FW_SIZE (0x1F00 * 4)
#define ISP_IC_INFO_ADDR 0x1F00
-#ifdef SEC_TSP_FACTORY_TEST
-/* Model dependency values */
-#define TX_NUM 19 /* GC Bring-up */
-#define RX_NUM 11 /* GC Bring-up */
-#define NODE_NUM (TX_NUM * RX_NUM)
+#if SEC_TSP_FACTORY_TEST
#define TSP_BUF_SIZE 1024
/* VSC(Vender Specific Command) */
@@ -265,6 +295,8 @@ struct mms_ts_info {
void (*input_event)(void *data);
bool enabled;
u8 fw_ic_ver;
+ u8 panel_type;
+ int finger_byte;
const u8 *config_fw_version;
unsigned char finger_state[MAX_FINGERS];
@@ -287,7 +319,7 @@ struct mms_ts_info {
struct device *sec_touchscreen;
#endif /* TOUCH_BOOSTER */
-#if defined(SEC_TSP_FACTORY_TEST)
+#if SEC_TSP_FACTORY_TEST
struct list_head cmd_list_head;
u8 cmd_state;
char cmd[TSP_CMD_STR_LEN];
@@ -296,11 +328,10 @@ struct mms_ts_info {
struct mutex cmd_lock;
bool cmd_is_running;
bool ft_flag;
-
- unsigned int reference[NODE_NUM];
- unsigned int raw[NODE_NUM]; /* CM_ABS */
- unsigned int inspection[NODE_NUM];/* CM_DELTA */
- unsigned int intensity[NODE_NUM];
+ unsigned int *reference;
+ unsigned int *cm_abs;
+ unsigned int *cm_delta;
+ unsigned int *intensity;
#endif /* SEC_TSP_FACTORY_TEST */
};
@@ -309,7 +340,7 @@ static void mms_ts_early_suspend(struct early_suspend *h);
static void mms_ts_late_resume(struct early_suspend *h);
#endif
-#if defined(SEC_TSP_FACTORY_TEST)
+#if SEC_TSP_FACTORY_TEST
#define TSP_CMD(name, func) .cmd_name = name, .cmd_func = func
struct tsp_cmd {
@@ -395,7 +426,7 @@ static int mms100_i2c_read(struct i2c_client *client,
}
if (ret < 0)
- pr_err("[TSP] : read error : [%d]", ret);
+ ISC_DL_MSG("[TSP ISC] i2c read error : [%d]\n", ret);
return ret;
}
@@ -443,7 +474,7 @@ static int mms100_get_version_info(struct i2c_client *_client)
ret = mms100_i2c_read(_client, ISC_ADDR_VERSION, 4, rd_buf);
if (ret < 0) {
- pr_info("[TSP ISC] %s,%d: i2c read fail[%d]\n",
+ ISC_DL_MSG("[TSP ISC] %s,%d: i2c read fail[%d]\n",
__func__, __LINE__, ret);
return ISC_I2C_ERROR;
}
@@ -460,7 +491,7 @@ static int mms100_get_version_info(struct i2c_client *_client)
ret = mms100_i2c_read(_client, ISC_ADDR_SECTION_PAGE_INFO, 8, rd_buf);
if (ret < 0) {
- pr_info("[TSP ISC] %s,%d: i2c read fail[%d]\n",
+ ISC_DL_MSG("[TSP ISC] %s,%d: i2c read fail[%d]\n",
__func__, __LINE__, ret);
return ISC_I2C_ERROR;
}
@@ -470,16 +501,10 @@ static int mms100_get_version_info(struct i2c_client *_client)
ts_info[i].end_addr = rd_buf[i + SECTION_NUM];
}
- for (i = 0; i < SECTION_NUM; i++) {
- pr_info("[TSP ISC] TS : Section(%d) version: 0x%02X",
- i, ts_info[i].version);
- pr_info("[TSP ISC] TS : Section(%d) Start Address: 0x%02X",
- i, ts_info[i].start_addr);
- pr_info("[TSP ISC] TS : Section(%d) End Address: 0x%02X",
- i, ts_info[i].end_addr);
- pr_info("[TSP ISC] TS : Section(%d) Compatibility: 0x%02X",
- i, ts_info[i].compatible_version);
- }
+ for (i = 0; i < SECTION_NUM; i++)
+ ISC_DL_MSG("[TSP ISC] IC (%d): Ver[0x%02X] Addr[0x%02X]~[0x%02X] Compatibility[0x%02X]\n",
+ i, ts_info[i].version, ts_info[i].start_addr,
+ ts_info[i].end_addr, ts_info[i].compatible_version);
return ISC_SUCCESS;
}
@@ -498,7 +523,7 @@ static int mms100_seek_section_info(void)
for (i = 0; i < SECTION_NUM; i++) {
if (tsp_firmware_file[i] == NULL) {
buf = NULL;
- pr_info("[TSP ISC] tsp_firmware_file[%d] is NULL", i);
+ ISC_DL_MSG("[TSP ISC] F/W file[%d] is NULL\n", i);
} else
buf = tsp_firmware_file[i];
@@ -565,16 +590,10 @@ static int mms100_seek_section_info(void)
}
}
- for (i = 0; i < SECTION_NUM; i++) {
- pr_info("[TSP ISC] MBin : Section(%d) Version: 0x%02X",
- i, mbin_info[i].version);
- pr_info("[TSP ISC] MBin : Section(%d) Start Address: 0x%02X",
- i, mbin_info[i].start_addr);
- pr_info("[TSP ISC] MBin : Section(%d) End Address: 0x%02X",
- i, mbin_info[i].end_addr);
- pr_info("[TSP ISC] MBin : Section(%d) Compatibility: 0x%02X",
- i, mbin_info[i].compatible_version);
- }
+ for (i = 0; i < SECTION_NUM; i++)
+ ISC_DL_MSG("[TSP ISC] mBin (%d): Ver[0x%02X] Addr[0x%02X]~[0x%02X] Compatibility[0x%02X]\n",
+ i, mbin_info[i].version, mbin_info[i].start_addr,
+ mbin_info[i].end_addr, mbin_info[i].compatible_version);
return ISC_SUCCESS;
}
@@ -596,18 +615,16 @@ static int mms100_compare_version_info(struct i2c_client *_client,
/* Check update areas , 0 : bootloader 1: core 2: private 3: public */
for (i = SEC_CORE; i < SECTION_NUM; i++) {
if ((mbin_info[i].version == 0) ||
- (mbin_info[i].version != ts_info[i].version)) {
+ (mbin_info[i].version > ts_info[i].version))
section_update_flag[i] = true;
- pr_info("[TSP ISC] [%d] section will be updated!", i);
- }
}
if (forced_update) {
section_update_flag[SEC_CORE] = true;
section_update_flag[SEC_PRIVATE_CONFIG] = true;
section_update_flag[SEC_PUBLIC_CONFIG] = true;
- pr_info("[TSP ISC] forced_update enable!");
+ ISC_DL_MSG("[TSP ISC] forced_update enable!\n");
}
- pr_info("[TSP ISC] section_update_flag : [%d][%d][%d]",
+ ISC_DL_MSG("[TSP ISC] Update_flag : Core[%d] PRIV[%d] PUBL[%d]\n",
section_update_flag[1], section_update_flag[2],
section_update_flag[3]);
@@ -629,25 +646,13 @@ static int mms100_compare_version_info(struct i2c_client *_client,
ts_info[SEC_CORE].version;
}
- for (i = SEC_CORE; i < SEC_PUBLIC_CONFIG; i++) {
- if (section_update_flag[i]) {
- pr_info("[TSP ISC] section_update_flag(%d), 0x%02x, 0x%02x\n",
- i, expected_compatibility[i],
- mbin_info[i].compatible_version);
- if (!forced_update) {
- if (expected_compatibility[i] !=
- mbin_info[i].compatible_version)
- return ISC_COMPATIVILITY_ERROR;
- }
- } else {
- pr_info("[TSP ISC] !section_update_flag(%d), 0x%02x, 0x%02x\n",
- i, expected_compatibility[i],
- ts_info[i].compatible_version);
- if (!forced_update) {
- if (expected_compatibility[i] !=
- ts_info[i].compatible_version)
- return ISC_COMPATIVILITY_ERROR;
- }
+ for (i = SEC_CORE; i <= SEC_PUBLIC_CONFIG; i++) {
+ if (expected_compatibility[i] != ts_info[i].compatible_version
+ && !forced_update) {
+ ISC_DL_MSG("[TSP ISC] compatible error(%d)- expected:[0x%02x] mbin:[0x%02x]\n",
+ i, expected_compatibility[i],
+ mbin_info[i].compatible_version);
+ return ISC_COMPATIVILITY_ERROR;
}
}
return ISC_SUCCESS;
@@ -658,15 +663,13 @@ static int mms100_enter_ISC_mode(struct i2c_client *_client)
int ret;
unsigned char wr_buf[2];
- pr_info("[TSP ISC] %s\n", __func__);
-
wr_buf[0] = ISC_CMD_ENTER_ISC;
wr_buf[1] = ISC_CMD_ENTER_ISC_PARA1;
ret = i2c_master_send(_client, wr_buf, 2);
if (ret < 0) {
- pr_info("[TSP ISC] %s,%d: i2c write fail[%d]\n",
+ ISC_DL_MSG("[TSP ISC] %s,%d: i2c write fail[%d]\n",
__func__, __LINE__, ret);
return ISC_I2C_ERROR;
}
@@ -688,14 +691,14 @@ static int mms100_enter_config_update(struct i2c_client *_client)
ret = i2c_master_send(_client, wr_buf, 10);
if (ret < 0) {
- pr_info("[TSP ISC] %s,%d: i2c write fail[%d]\n",
+ ISC_DL_MSG("[TSP ISC] %s,%d: i2c write fail[%d]\n",
__func__, __LINE__, ret);
return ISC_I2C_ERROR;
}
ret = mms100_i2c_read(_client, ISC_CMD_CONFIRM_STATUS, 1, &rd_buf);
if (ret < 0) {
- pr_info("[TSP ISC] %s,%d: i2c read fail[%d]\n",
+ ISC_DL_MSG("[TSP ISC] %s,%d: i2c read fail[%d]\n",
__func__, __LINE__, ret);
return ISC_I2C_ERROR;
}
@@ -724,7 +727,7 @@ static int mms100_ISC_clear_page(struct i2c_client *_client,
ret = i2c_master_send(_client, g_wr_buf, PACKET_SIZE);
if (ret < 0) {
- pr_info("[TSP ISC] %s,%d: i2c write fail[%d]\n",
+ ISC_DL_MSG("[TSP ISC] %s,%d: i2c write fail[%d]\n",
__func__, __LINE__, ret);
return ISC_I2C_ERROR;
}
@@ -732,7 +735,7 @@ static int mms100_ISC_clear_page(struct i2c_client *_client,
ret = mms100_i2c_read(_client, ISC_CMD_CONFIRM_STATUS, 1, &rd_buf);
if (ret < 0) {
- pr_info("[TSP ISC] %s,%d: i2c read fail[%d]\n",
+ ISC_DL_MSG("[TSP ISC] %s,%d: i2c read fail[%d]\n",
__func__, __LINE__, ret);
return ISC_I2C_ERROR;
}
@@ -799,7 +802,7 @@ static int mms100_update_section_data(struct i2c_client *_client)
for (i = 0; i < SECTION_NUM; i++) {
if (section_update_flag[i]) {
- pr_info("[TSP ISC] section data i2c flash : [%d]", i);
+ ISC_DL_MSG("[TSP ISC] %d section data i2c flash\n", i);
next_ptr = 0;
ptr_fw = tsp_firmware_file[i];
@@ -824,7 +827,7 @@ static int mms100_update_section_data(struct i2c_client *_client)
ret = i2c_master_send(_client,
ptr_fw, PACKET_SIZE);
if (ret < 0) {
- pr_info("[TSP ISC] %s,%d: i2c write fail[%d]",
+ ISC_DL_MSG("[TSP ISC] %s,%d: i2c write fail[%d]\n",
__func__, __LINE__, ret);
return ISC_I2C_ERROR;
}
@@ -832,7 +835,7 @@ static int mms100_update_section_data(struct i2c_client *_client)
ret = mms100_i2c_read(_client,
ISC_CMD_CONFIRM_STATUS, 1, &rd_buf);
if (ret < 0) {
- pr_info("[TSP ISC] %s,%d: i2c read fail[%d]",
+ ISC_DL_MSG("[TSP ISC] %s,%d: i2c read fail[%d]\n",
__func__, __LINE__, ret);
return ISC_I2C_ERROR;
}
@@ -847,25 +850,25 @@ static int mms100_update_section_data(struct i2c_client *_client)
return ISC_SUCCESS;
}
-static int mms100_open_mbinary(struct i2c_client *_client, int mode)
+static int mms100_open_mbinary(struct i2c_client *_client,
+ int panel_type, int mode)
{
int i;
int ret = 0;
mm_segment_t old_fs = {0};
struct file *fp = NULL;
long fsize = 0, nread = 0;
-/* u8 *fw_name[] = {"BOOT", "CORE", "PRIV", "PUBL"}; */
char fw_path[MAX_FW_PATH+1];
if (mode == REQ_FW) {
for (i = SEC_CORE; i <= SEC_PUBLIC_CONFIG ; i++) {
- snprintf(fw_path, MAX_FW_PATH, "tsp_melfas/GC_%s.fw",
- section_name[i]);
-
+ snprintf(fw_path, MAX_FW_PATH, "%s%c_%s.fw",
+ FW_DIRECTORY, panel_type, section_name[i]);
ret = request_firmware(&(fw_mbin[i]), fw_path,
- &_client->dev);
+ &_client->dev);
if (ret) {
- pr_err("[TSP ISC] fail requestfirmware[%d]", i);
+ ISC_DL_MSG("[TSP ISC] fail REQ_FW[%s]\n",
+ fw_path);
break;
}
@@ -873,7 +876,7 @@ static int mms100_open_mbinary(struct i2c_client *_client, int mode)
GFP_KERNEL);
if (!tsp_firmware_file[i])
- pr_err("[TSP ISC] fail to alloc buffer for fw");
+ ISC_DL_MSG("[TSP ISC] fail to alloc buffer for fw\n");
else
memcpy((void *)tsp_firmware_file[i],
fw_mbin[i]->data, fw_mbin[i]->size);
@@ -881,7 +884,8 @@ static int mms100_open_mbinary(struct i2c_client *_client, int mode)
if (fw_mbin[i] != NULL)
release_firmware(fw_mbin[i]);
}
- pr_info("[TSP ISC] request_firmware[%d] is loaded!!", i);
+ if (!ret)
+ ISC_DL_MSG("[TSP ISC] All REQ_FW is loaded!\n");
} else if (mode == UMS) {
old_fs = get_fs();
@@ -892,9 +896,10 @@ static int mms100_open_mbinary(struct i2c_client *_client, int mode)
section_name[i]);
fp = filp_open(fw_path, O_RDONLY, 0);
if (IS_ERR(fp)) {
- pr_err("[TSP ISC] file %s open error:%d",
+ ISC_DL_MSG("[TSP ISC] file %s open error:%d\n",
fw_path, (s32)fp);
- ret = 1;
+ set_fs(old_fs);
+ return ISC_FILE_OPEN_ERROR;
}
fsize = fp->f_path.dentry->d_inode->i_size;
@@ -902,49 +907,58 @@ static int mms100_open_mbinary(struct i2c_client *_client, int mode)
tsp_firmware_file[i] = kzalloc((size_t)fsize,
GFP_KERNEL);
if (!tsp_firmware_file[i]) {
- pr_err("[TSP ISC] fail to alloc buffer for fw");
- ret = 1;
+ ISC_DL_MSG("[TSP ISC] fail to alloc buffer for fw\n");
+ ret = ISC_FILE_OPEN_ERROR;
}
nread = vfs_read(fp,
(char __user *)tsp_firmware_file[i],
fsize, &fp->f_pos);
if (nread != fsize) {
- pr_err("[TSP ISC] nread != fsize error");
- ret = 1;
+ ISC_DL_MSG("[TSP ISC] nread != fsize error\n");
+ ret = ISC_FILE_OPEN_ERROR;
}
filp_close(fp, current->files);
}
set_fs(old_fs);
- pr_info("[TSP ISC] ums fw is loaded!");
+ if (!ret)
+ ISC_DL_MSG("[TSP ISC] ums fw is loaded!\n");
} else {
- pr_err("[TSP ISC] Not support mode[%d]", mode);
- ret = 1;
+ ISC_DL_MSG("[TSP ISC] Not support mode[%d]\n", mode);
+ ret = ISC_FILE_OPEN_ERROR;
}
if (!ret)
return ISC_SUCCESS;
else {
- pr_err("[TSP ISC] mms100_open_mbinary fail");
+ ISC_DL_MSG("[TSP ISC] mms100_open_mbinary fail\n");
return ret;
}
}
int mms100_ISC_download_mbinary(struct i2c_client *_client, int mode,
- bool forced_update)
+ int panel_type, bool forced_update)
{
int ret_msg = ISC_NONE;
+ isc_dl_msg = kzalloc(sizeof(char) * 8096 , GFP_KERNEL);
+ isc_dl_msg_temp = kzalloc(sizeof(char) * 256 , GFP_KERNEL);
+
+ if (isc_dl_msg == NULL || isc_dl_msg_temp == NULL) {
+ pr_err("isc_dl_msg = kzalloc error!");
+ return ISC_NONE;
+ }
+
+ pr_info("[TSP ISC] FIRMWARE_UPDATE_START!");
- pr_info("[TSP ISC] %s\n", __func__);
/*
mms100_reset(_client);
ret_msg = mms100_check_operating_mode(_client, EC_BOOT_ON_SUCCEEDED);
if (ret_msg != ISC_SUCCESS)
goto ISC_ERROR_HANDLE;
*/
- ret_msg = mms100_open_mbinary(_client, mode);
+ ret_msg = mms100_open_mbinary(_client, panel_type, mode);
if (ret_msg != ISC_SUCCESS)
goto ISC_ERROR_HANDLE;
@@ -952,6 +966,11 @@ int mms100_ISC_download_mbinary(struct i2c_client *_client, int mode,
ret_msg = mms100_compare_version_info(_client, forced_update);
if (ret_msg != ISC_SUCCESS)
goto ISC_ERROR_HANDLE;
+ else if (!section_update_flag[1] && !section_update_flag[2]
+ && !section_update_flag[3]) {
+ pr_info("[TSP ISC] FIRMWARE_UPDATE SKIP!");
+ goto ISC_NEED_NOT_UPDATE;
+ }
ret_msg = mms100_enter_ISC_mode(_client);
if (ret_msg != ISC_SUCCESS)
@@ -972,20 +991,29 @@ int mms100_ISC_download_mbinary(struct i2c_client *_client, int mode,
ret_msg = ISC_SUCCESS;
ISC_ERROR_HANDLE:
- if (ret_msg != ISC_SUCCESS)
- pr_err("[TSP ISC] ISC_ERROR_CODE: %d\n", ret_msg);
-
mms100_reset(_client);
+ if (ret_msg != ISC_SUCCESS) {
+ pr_err("[TSP ISC] FW update fail message start!");
+ pr_err("%s", isc_dl_msg);
+ pr_err("[TSP ISC] FW update fail message END!");
+ pr_err("[TSP ISC] FIRMWARE_UPDATE ERROR : %d\n", ret_msg);
+ } else
+ pr_info("[TSP ISC] FIRMWARE_UPDATE SUCCESS!");
- kfree(tsp_firmware_file[1]);
- kfree(tsp_firmware_file[2]);
- kfree(tsp_firmware_file[3]);
+ISC_NEED_NOT_UPDATE:
- pr_info("[TSP ISC]FIRMWARE_UPDATE_FINISHED!");
+ kfree(isc_dl_msg);
+ kfree(isc_dl_msg_temp);
+
+ if (ret_msg != ISC_FILE_OPEN_ERROR) {
+ kfree(tsp_firmware_file[1]);
+ kfree(tsp_firmware_file[2]);
+ kfree(tsp_firmware_file[3]);
+ }
return ret_msg;
}
-#endif /* ISC_DL_MODE start */
+#endif /* ISC_DL_MODE */
#if TOUCH_BOOSTER
@@ -996,14 +1024,15 @@ static void change_dvfs_lock(struct work_struct *work)
int ret;
mutex_lock(&info->dvfs_lock);
-
- ret = dev_lock(info->bus_dev, info->sec_touchscreen, 267160);
+ ret = dev_lock(info->bus_dev, info->sec_touchscreen,
+ TOUCH_BOOSTER_BUS_CLK_266);
if (ret < 0)
- pr_err("melfas-ts : %s dev change bud lock failed(%d)\n",\
- __func__, __LINE__);
+ dev_err(&info->client->dev,
+ "%s dev change bud lock failed(%d)\n",\
+ __func__, __LINE__);
else
- pr_info("melfas-ts : change_dvfs_lock");
+ dev_notice(&info->client->dev, "Change dvfs lock");
mutex_unlock(&info->dvfs_lock);
}
static void set_dvfs_off(struct work_struct *work)
@@ -1017,56 +1046,62 @@ static void set_dvfs_off(struct work_struct *work)
ret = dev_unlock(info->bus_dev, info->sec_touchscreen);
if (ret < 0)
- pr_err("melfas-ts : %s: dev unlock failed(%d)\n",
- __func__, __LINE__);
+ dev_err(&info->client->dev, " %s: dev unlock failed(%d)\n",
+ __func__, __LINE__);
exynos_cpufreq_lock_free(DVFS_LOCK_ID_TSP);
info->dvfs_lock_status = false;
- pr_info("melfas-ts : DVFS Off!");
+ dev_notice(&info->client->dev, "dvfs off!");
mutex_unlock(&info->dvfs_lock);
- }
+}
-static void set_dvfs_lock(struct mms_ts_info *info, uint32_t on)
+static void set_dvfs_lock(struct mms_ts_info *info, uint32_t mode)
{
int ret;
mutex_lock(&info->dvfs_lock);
if (info->cpufreq_level <= 0) {
- ret = exynos_cpufreq_get_level(800000, &info->cpufreq_level);
+ ret = exynos_cpufreq_get_level(TOUCH_BOOSTER_CPU_CLK,
+ &info->cpufreq_level);
if (ret < 0)
- pr_err("melfas-ts : exynos_cpufreq_get_level error");
+ dev_err(&info->client->dev,
+ "exynos_cpufreq_get_level error");
goto out;
}
- if (on == 0) {
+
+ if (mode == TOUCH_BOOSTER_DELAY_OFF) {
if (info->dvfs_lock_status) {
cancel_delayed_work(&info->work_dvfs_chg);
schedule_delayed_work(&info->work_dvfs_off,
msecs_to_jiffies(TOUCH_BOOSTER_OFF_TIME));
}
- } else if (on == 1) {
+ } else if (mode == TOUCH_BOOSTER_ON) {
cancel_delayed_work(&info->work_dvfs_off);
if (!info->dvfs_lock_status) {
- ret = dev_lock(info->bus_dev,
- info->sec_touchscreen, 400200);
+ ret = dev_lock(info->bus_dev, info->sec_touchscreen,
+ TOUCH_BOOSTER_BUS_CLK_400);
if (ret < 0) {
- pr_err("melfas-ts : %s: dev lock failed(%d)",\
+ dev_err(&info->client->dev,
+ "%s: dev lock failed(%d)",
__func__, __LINE__);
-}
+ }
ret = exynos_cpufreq_lock(DVFS_LOCK_ID_TSP,
info->cpufreq_level);
if (ret < 0)
- pr_err("melfas-ts : %s: cpu lock failed(%d)",\
- __func__, __LINE__);
+ dev_err(&info->client->dev,
+ "%s: cpu lock failed(%d)",
+ __func__, __LINE__);
schedule_delayed_work(&info->work_dvfs_chg,
msecs_to_jiffies(TOUCH_BOOSTER_CHG_TIME));
info->dvfs_lock_status = true;
- pr_info("melfas-ts :DVFS On[%d]", info->cpufreq_level);
+ dev_notice(&info->client->dev, "dvfs on[%d]",
+ info->cpufreq_level);
}
- } else if (on == 2) {
+ } else if (mode == TOUCH_BOOSTER_QUICK_OFF) {
cancel_delayed_work(&info->work_dvfs_off);
cancel_delayed_work(&info->work_dvfs_chg);
schedule_work(&info->work_dvfs_off.work);
@@ -1080,19 +1115,24 @@ static void release_all_fingers(struct mms_ts_info *info)
{
int i;
- printk(KERN_DEBUG "[TSP] %s\n", __func__);
+ dev_notice(&info->client->dev, "%s\n", __func__);
for (i = 0; i < MAX_FINGERS; i++) {
input_mt_slot(info->input_dev, i);
input_mt_report_slot_state(info->input_dev, MT_TOOL_FINGER,
false);
+
+ if (info->finger_state[i] != TSP_STATE_RELEASE) {
+ dev_notice(&info->client->dev,
+ "finger %d up(force)\n", i);
+ }
info->finger_state[i] = TSP_STATE_RELEASE;
}
input_sync(info->input_dev);
#if TOUCH_BOOSTER
- set_dvfs_lock(info, 2);
- dev_notice(&client->dev, "[TSP] dvfs_lock free.\n");
+ set_dvfs_lock(info, TOUCH_BOOSTER_QUICK_OFF);
+ dev_notice(&info->client->dev, "dvfs lock free.\n");
#endif
}
@@ -1116,28 +1156,20 @@ static void reset_mms_ts(struct mms_ts_info *info)
info->pdata->power(1);
msleep(120);
- enable_irq(info->irq);
- info->enabled = true;
-}
-
-static void mms_set_noise_mode(struct mms_ts_info *info)
-{
- struct i2c_client *client = info->client;
+ if (info->ta_status) {
+ dev_notice(&client->dev, "TA or USB connect!!!\n");
+ i2c_smbus_write_byte_data(info->client, MMS_TA_REG, MMS_TA_ON);
- if (!(info->noise_mode && info->enabled))
- return;
- dev_notice(&client->dev, "%s\n", __func__);
+ if (info->noise_mode) {
+ i2c_smbus_write_byte_data(info->client, MMS_NOISE_REG,
+ MMS_NOISE_ON);
+ dev_notice(&client->dev, "reset & noise mode on!\n");
+ }
+ } else
+ info->noise_mode = false;
- if (info->ta_status) {
- dev_notice(&client->dev, "TA connect!!!\n");
- i2c_smbus_write_byte_data(info->client, MMS_TA_NOISE_REG,
- MMS_TA_NOISE_ON);
- } else {
- dev_notice(&client->dev, "TA disconnect!!!\n");
- i2c_smbus_write_byte_data(info->client, MMS_TA_NOISE_REG,
- MMS_TA_NOISE_OFF);
- info->noise_mode = 0;
- }
+ enable_irq(info->irq);
+ info->enabled = true;
}
static void melfas_ta_cb(struct tsp_callbacks *cb, bool ta_status)
@@ -1146,27 +1178,44 @@ static void melfas_ta_cb(struct tsp_callbacks *cb, bool ta_status)
container_of(cb, struct mms_ts_info, callbacks);
struct i2c_client *client = info->client;
- dev_notice(&client->dev, "%s [%s]\n", __func__,
- ta_status ? "ON" : "OFF");
+ dev_notice(&client->dev, "%s TA or USB %sconnect\n", __func__,
+ ta_status ? "" : "dis");
info->ta_status = ta_status;
- /* GC Not support yet!
- if (!ta_status)
- mms_set_noise_mode(info);
- */
+
+ if (info->enabled) {
+ if (info->ta_status)
+ i2c_smbus_write_byte_data(info->client,
+ MMS_TA_REG, MMS_TA_ON);
+ else {
+ i2c_smbus_write_byte_data(info->client,
+ MMS_TA_REG, MMS_TA_OFF);
+
+ if (info->noise_mode) {
+ info->noise_mode = false;
+ i2c_smbus_write_byte_data(info->client,
+ MMS_NOISE_REG,
+ MMS_NOISE_OFF);
+ dev_notice(&client->dev,
+ "ta_cb & noise mode off!\n");
+ }
+ }
+ }
}
static irqreturn_t mms_ts_interrupt(int irq, void *dev_id)
{
struct mms_ts_info *info = dev_id;
struct i2c_client *client = info->client;
- u8 buf[MAX_FINGERS * FINGER_EVENT_SZ] = { 0, };
- int ret;
- int i;
- int sz;
+ u8 buf[MAX_FINGERS * EVENT_SZ_8_BYTES] = { 0, };
+ int ret, i, sz;
+ int id, state, posX, posY, strenth, width;
+ int angle, palm, major_axis, minor_axis;
+ int finger_event_sz;
+ u8 *read_data;
u8 reg = MMS_INPUT_EVENT0;
#if TOUCH_BOOSTER
- int touch_is_pressed = 0;
+ bool press_flag = false;
#endif
struct i2c_msg msg[] = {
{
@@ -1180,6 +1229,7 @@ static irqreturn_t mms_ts_interrupt(int irq, void *dev_id)
.buf = buf,
},
};
+ finger_event_sz = info->finger_byte;
sz = i2c_smbus_read_byte_data(client, MMS_INPUT_EVENT_PKT_SZ);
@@ -1195,73 +1245,110 @@ static irqreturn_t mms_ts_interrupt(int irq, void *dev_id)
if (i == 50) {
dev_dbg(&client->dev, "i2c failed... reset!!\n");
reset_mms_ts(info);
- goto out;
+ return IRQ_HANDLED;
}
+ dev_err(&client->dev, "success read touch info data\n");
}
if (sz == 0)
- goto out;
+ return IRQ_HANDLED;
- if (sz > MAX_FINGERS*FINGER_EVENT_SZ) {
- dev_err(&client->dev, "[TSP] abnormal data inputed.\n");
- goto out;
+ if (sz > MAX_FINGERS*finger_event_sz || sz%finger_event_sz) {
+ dev_err(&client->dev, "abnormal data inputed & reset IC[%d]\n",
+ sz);
+ reset_mms_ts(info);
+ return IRQ_HANDLED;
}
msg[1].len = sz;
ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
+
if (ret != ARRAY_SIZE(msg)) {
dev_err(&client->dev,
"failed to read %d bytes of touch data (%d)\n",
sz, ret);
- goto out;
+
+ for (i = 0; i < 5; i++) {
+ ret = i2c_transfer(client->adapter, msg,
+ ARRAY_SIZE(msg));
+ if (ret == ARRAY_SIZE(msg))
+ break;
+ }
+
+ if (i == 5) {
+ dev_err(&client->dev,
+ "failed to read touch data & reset IC[%d]\n",
+ ret);
+ reset_mms_ts(info);
+ return IRQ_HANDLED;
+ }
+ dev_err(&client->dev, "success read touch data\n");
}
if (buf[0] == 0x0F) { /* ESD */
dev_dbg(&client->dev, "ESD DETECT.... reset!!\n");
reset_mms_ts(info);
- goto out;
+ return IRQ_HANDLED;
}
if (buf[0] == 0x0E) { /* NOISE MODE */
- dev_dbg(&client->dev, "[TSP] noise mode enter!!\n");
- info->noise_mode = 1 ;
- /* GC Not support yet!
- mms_set_noise_mode(info);
- */
- goto out;
- }
+ dev_dbg(&client->dev, "Noise mode enter!!\n");
+
+ info->noise_mode = true;
+ i2c_smbus_write_byte_data(info->client, MMS_NOISE_REG,
+ MMS_NOISE_ON);
+ dev_notice(&client->dev, "interrupt & noise mode on!\n");
+ return IRQ_HANDLED;
+ }
+
+ for (i = 0; i < sz; i += finger_event_sz) {
+ read_data = &buf[i];
+ id = (read_data[0] & 0xf) - 1;
+ state = read_data[0] & 0x80;
+ posX = read_data[2] | ((read_data[1] & 0xf) << 8);
+ posY = read_data[3] | (((read_data[1] >> 4) & 0xf) << 8);
+ strenth = read_data[4];
+
+ if (finger_event_sz == EVENT_SZ_8_BYTES) {
+ angle = (read_data[5] >= 127) ? \
+ (-(256 - read_data[5])) : read_data[5];
+ palm = (read_data[0] & 0x10) >> 4;
+ major_axis = read_data[6];
+ minor_axis = read_data[7];
+
+ } else
+ width = read_data[5];
- for (i = 0; i < sz; i += FINGER_EVENT_SZ) {
- u8 *tmp = &buf[i];
- int id = (tmp[0] & 0xf) - 1;
- int x = tmp[2] | ((tmp[1] & 0xf) << 8);
- int y = tmp[3] | (((tmp[1] >> 4) & 0xf) << 8);
if (info->invert_x) {
- x = info->max_x - x;
- if (x < 0)
- x = 0;
+ posX = info->max_x - posX;
+ if (posX < 0)
+ posX = 0;
}
if (info->invert_y) {
- y = info->max_y - y;
- if (y < 0)
- y = 0;
+ posY = info->max_y - posY;
+ if (posY < 0)
+ posY = 0;
}
if (id >= MAX_FINGERS) {
dev_notice(&client->dev, \
"finger id error [%d]\n", id);
reset_mms_ts(info);
- goto out;
+ return IRQ_HANDLED;
}
- if ((tmp[0] & 0x80) == TSP_STATE_RELEASE) {
+ if (state == TSP_STATE_RELEASE) {
input_mt_slot(info->input_dev, id);
input_mt_report_slot_state(info->input_dev,
MT_TOOL_FINGER, false);
- input_sync(info->input_dev);
#if SHOW_COORD
- dev_notice(&client->dev,
- "R [%2d],([%4d],[%3d]),S:%d W:%d [%d]",
- id, x, y, tmp[4], tmp[5],
- info->finger_state[id]);
+ if (finger_event_sz == EVENT_SZ_8_BYTES)
+ dev_notice(&client->dev,
+ "R [%2d],([%4d],[%3d])[%d][%d]",
+ id, posX, posY, palm, info->finger_state[id]);
+ else
+ dev_notice(&client->dev,
+ "R [%2d],([%4d],[%3d])[%d]",
+ id, posX, posY, info->finger_state[id]);
+
#else
dev_notice(&client->dev, "R [%2d][%d]", id,
info->finger_state[id]);
@@ -1272,21 +1359,40 @@ static irqreturn_t mms_ts_interrupt(int irq, void *dev_id)
input_mt_report_slot_state(info->input_dev,
MT_TOOL_FINGER, true);
input_report_abs(info->input_dev,
- ABS_MT_POSITION_X, x);
- input_report_abs(info->input_dev,
- ABS_MT_POSITION_Y, y);
- input_report_abs(info->input_dev,
- ABS_MT_TOUCH_MAJOR, tmp[4]);
+ ABS_MT_POSITION_X, posX);
input_report_abs(info->input_dev,
- ABS_MT_WIDTH_MAJOR, tmp[5]);
- input_sync(info->input_dev);
+ ABS_MT_POSITION_Y, posY);
+
+ if (finger_event_sz == EVENT_SZ_8_BYTES) {
+ input_report_abs(info->input_dev,
+ ABS_MT_WIDTH_MAJOR, strenth);
+ input_report_abs(info->input_dev,
+ ABS_MT_TOUCH_MAJOR, major_axis);
+ input_report_abs(info->input_dev,
+ ABS_MT_TOUCH_MINOR, minor_axis);
+ input_report_abs(info->input_dev,
+ ABS_MT_ANGLE, angle);
+ input_report_abs(info->input_dev,
+ ABS_MT_PALM, palm);
+ } else {
+ input_report_abs(info->input_dev,
+ ABS_MT_TOUCH_MAJOR, strenth);
+ input_report_abs(info->input_dev,
+ ABS_MT_WIDTH_MAJOR, width);
+ }
if (info->finger_state[id] == TSP_STATE_RELEASE) {
info->finger_state[id] = TSP_STATE_PRESS;
#if SHOW_COORD
- dev_notice(&client->dev,
- "P [%2d],([%4d],[%3d]),S:%d W:%d",
- id, x, y, tmp[4], tmp[5]);
+ if (finger_event_sz == EVENT_SZ_8_BYTES)
+ dev_notice(&client->dev,
+ "P [%2d],([%4d],[%3d]),S:%d A:%3d P:%d Mj_a:%d Mi_a:%d",\
+ id, posX, posY, strenth, angle,
+ palm, major_axis, minor_axis);
+ else
+ dev_notice(&client->dev,
+ "P [%2d],([%4d],[%3d]),S:%d W:%d",
+ id, posX, posY, strenth, width);
#else
dev_notice(&client->dev, "P [%2d]", id);
#endif
@@ -1294,17 +1400,20 @@ static irqreturn_t mms_ts_interrupt(int irq, void *dev_id)
info->finger_state[id] = TSP_STATE_MOVE;
}
}
+ input_sync(info->input_dev);
#if TOUCH_BOOSTER
- for (i = 0 ; MAX_FINGERS ; i++)
+ for (i = 0 ; i < MAX_FINGERS ; i++) {
if (info->finger_state[i] == TSP_STATE_PRESS
- || info->finger_state[i] == TSP_STATE_MOVE)
- touch_is_pressed++;
+ || info->finger_state[i] == TSP_STATE_MOVE) {
+ press_flag = TOUCH_BOOSTER_ON;
+ break;
+ }
+ }
- set_dvfs_lock(info, !!touch_is_pressed);
+ set_dvfs_lock(info, press_flag);
#endif
-out:
return IRQ_HANDLED;
}
@@ -1619,73 +1728,26 @@ static int get_fw_version(struct mms_ts_info *info)
ret = i2c_smbus_read_byte_data(info->client, MMS_FW_VERSION);
} while (ret < 0 && retries-- > 0);
- dev_info(&client->dev, "MMS_FW_VER_CORE [0x%02x]",
- i2c_smbus_read_byte_data(info->client, MMS_FW_VER_CORE));
- dev_info(&client->dev, "MMS_FW_VER_PRIV [0x%02x]",
- i2c_smbus_read_byte_data(info->client, MMS_FW_VER_PRIV));
- dev_info(&client->dev, "MMS_FW_VER_PUBL [0x%02x]",
- i2c_smbus_read_byte_data(info->client, MMS_FW_VER_PUBL));
+ dev_info(&client->dev, "TSP_REVISION = [%c Type], HW_REVISION = [0x%02x], COMPAT_GROUP = [0x%02x]",
+ i2c_smbus_read_byte_data(info->client, MMS_TSP_REVISION),
+ i2c_smbus_read_byte_data(info->client, MMS_HW_REVISION),
+ i2c_smbus_read_byte_data(info->client, MMS_COMPAT_GROUP));
+
return ret;
}
-static int mms_ts_finish_config(struct mms_ts_info *info)
+static int get_panel_type(struct mms_ts_info *info)
{
struct i2c_client *client = info->client;
int ret;
+ int retries = 3;
- ret = request_threaded_irq(client->irq, NULL, mms_ts_interrupt,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- MELFAS_TS_NAME, info);
- if (ret < 0) {
- ret = 1;
- dev_err(&client->dev, "Failed to register interrupt\n");
- goto err_req_irq;
- }
-
- info->irq = client->irq;
- barrier();
-
- dev_info(&client->dev,
- "Melfas MMS-series touch controller initialized\n");
-
- return 0;
-
-err_req_irq:
- return ret;
-}
-static int mms_ts_fw_info(struct mms_ts_info *info)
-{
- struct i2c_client *client = info->client;
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- int ret = 0;
- int ver;
-
- /* firmware check */
- ver = get_fw_version(info);
- info->fw_ic_ver = ver;
- dev_info(&client->dev, "FW ver [0x%02x]", ver);
-
- if (!info->pdata || !info->pdata->mux_fw_flash) {
- ret = 1;
- dev_err(&client->dev,
- "fw cannot be updated, missing platform data\n");
- return ret;
- }
-
- ret = request_threaded_irq(client->irq, NULL, mms_ts_interrupt,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
- MELFAS_TS_NAME, info);
- if (ret < 0) {
- ret = 1;
- dev_err(&client->dev, "Failed to register interrupt\n");
- return ret;
- }
-
- info->irq = client->irq;
- barrier();
+ /* this seems to fail sometimes after a reset.. retry a few times */
+ do {
+ ret = i2c_smbus_read_byte_data(info->client, MMS_TSP_REVISION);
+ } while (ret < 0 && retries-- > 0);
- dev_info(&client->dev,
- "Melfas MMS-series touch controller initialized\n");
+ dev_info(&client->dev, "MMS_TSP_REVISION = [0x%02x],[%c]", ret, ret);
return ret;
}
@@ -1696,42 +1758,68 @@ static int mms_ts_fw_load(struct mms_ts_info *info)
struct i2c_client *client = info->client;
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
int ret = 0, ret_isp = 0;
- int ver = 0x00;
int retries_isc = 3;
int retries_isp = 3;
/* firmware check */
- ver = get_fw_version(info);
- info->fw_ic_ver = ver;
- dev_info(&client->dev, "FW ver. [0x%02x]", ver);
- goto done;
+ info->fw_ic_ver = get_fw_version(info);
+ dev_info(&client->dev, "Before FW update : [0x%02x]", info->fw_ic_ver);
+
+ if (system_rev < 2) {
+ dev_err(&client->dev, "FW update skip[%d]\n", system_rev);
+ return ret;
+ }
+
+ /* Add panel type check logic */
+ if (system_rev >= 2 && system_rev <= 5) {
+ info->panel_type = get_panel_type(info);
+
+ if (info->panel_type != PANEL_MOREENS && \
+ info->panel_type != PANEL_SMAC) {
+ dev_err(&client->dev, "abnormal panel type[%c]!\n",
+ info->panel_type);
+ if (system_rev == 2)
+ info->panel_type = PANEL_MOREENS;
+ else
+ info->panel_type = PANEL_SMAC;
+ }
+ } else if (system_rev >= 6)
+ info->panel_type = PANEL_SMAC_NEW;
+
+ dev_info(&client->dev, "Rev = 0x%02x, %c type Panel\n",
+ system_rev, info->panel_type);
if (!info->pdata || !info->pdata->mux_fw_flash) {
- ret = 1;
dev_err(&client->dev,
"fw cannot be updated, missing platform data\n");
- return ret;
+ return 1;
}
-#if 0
-/* firmware update 3 try */
-/* ISC firmware update */
+#if FW_UPDATABLE
- /* ISP firmware update */
while (retries_isc--) {
- ret = mms100_ISC_download_mbinary(client, REQ_FW,
+ /* ISC firmware update */
+ if (info->fw_ic_ver == 0x00) {
+ dev_err(&client->dev, "TSP panel info dismatched\n");
+ ret = mms100_ISC_download_mbinary(client, REQ_FW,
+ info->panel_type,
+ FORCED_UPDATE);
+ } else
+ ret = mms100_ISC_download_mbinary(client, REQ_FW,
+ info->panel_type,
COMPARE_UPDATE);
if (ret > 0) {
- dev_err(&client->dev, "ISP D/L mode fail\n");
+ dev_err(&client->dev, "ISC D/L mode fail\n");
i2c_lock_adapter(adapter);
info->pdata->mux_fw_flash(true);
while (retries_isp--) {
+ /* ISP firmware update */
ret_isp = mms100_ISP_download(info,
- BOOT_binary,
- BOOT_binary_nLength);
+ boot_binary,
+ boot_binary_nLength);
if (ret_isp < 0)
dev_err(&client->dev,
"ISP D/L mode fail\n");
@@ -1745,16 +1833,23 @@ static int mms_ts_fw_load(struct mms_ts_info *info)
info->pdata->mux_fw_flash(false);
i2c_unlock_adapter(adapter);
+ if (retries_isp == 0) {
+ dev_err(&client->dev,
+ "ISP D/L mode all fail!\n");
+ return ret_isp;
+ }
+
ret = mms100_ISC_download_mbinary(client, REQ_FW,
- FORCED_UPDATE);
+ info->panel_type,
+ FORCED_UPDATE);
}
if (ret == ISC_SUCCESS) {
- ver = get_fw_version(info);
- info->fw_ic_ver = ver;
- dev_info(&client->dev, "fw update done: ver = 0x%02x\n",
- ver);
- goto done;
+ info->fw_ic_ver = get_fw_version(info);
+ info->pdata->fw_version = mbin_info[SEC_PUBLIC_CONFIG].version;
+ dev_info(&client->dev, "After FW update : [0x%02x]\n",
+ info->fw_ic_ver);
+ return ret;
}
dev_err(&client->dev, "retrying flashing\n");
continue;
@@ -1766,34 +1861,11 @@ static int mms_ts_fw_load(struct mms_ts_info *info)
}
#endif
-done:
- ret = request_threaded_irq(client->irq, NULL, mms_ts_interrupt,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
- MELFAS_TS_NAME, info);
- if (ret < 0) {
- ret = 1;
- dev_err(&client->dev, "Failed to register interrupt\n");
- return ret;
- }
-
- info->irq = client->irq;
- barrier();
-
- dev_info(&client->dev,
- "Melfas MMS-series touch controller initialized\n");
return ret;
}
-#ifdef SEC_TSP_FACTORY_TEST
-#if 0
-static inline int msm_irq_to_gpio(unsigned irq)
-{
- /* TODO : Need to verify chip->base=0 */
- return irq - MSM_GPIO_TO_INT(0);
-}
-#endif
-
+#if SEC_TSP_FACTORY_TEST
static void set_cmd_result(struct mms_ts_info *info, char *buff, int len)
{
strncat(info->cmd_result, buff, len);
@@ -1803,15 +1875,15 @@ static void get_raw_data_all(struct mms_ts_info *info, u8 cmd)
{
u8 w_buf[6];
u8 read_buffer[2]; /* 52 */
- int gpio;
+ int gpio = info->pdata->gpio_int;
int ret;
int i, j;
u32 max_value = 0, min_value = 0;
u32 raw_data;
char buff[TSP_CMD_STR_LEN] = {0};
- gpio = info->pdata->gpio_int;
+ int tx_num = info->pdata->tsp_tx;
+ int rx_num = info->pdata->tsp_rx;
-/* gpio = msm_irq_to_gpio(info->irq); */
disable_irq(info->irq);
w_buf[0] = MMS_VSC_CMD; /* vendor specific command id */
@@ -1853,8 +1925,8 @@ static void get_raw_data_all(struct mms_ts_info *info, u8 cmd)
udelay(100);
}
- for (i = 0; i < RX_NUM; i++) {
- for (j = 0; j < TX_NUM; j++) {
+ for (i = 0; i < rx_num; i++) {
+ for (j = 0; j < tx_num; j++) {
w_buf[2] = j; /* tx */
w_buf[3] = i; /* rx */
@@ -1881,22 +1953,22 @@ static void get_raw_data_all(struct mms_ts_info *info, u8 cmd)
}
if (cmd == MMS_VSC_CMD_INTENSITY) {
- info->intensity[j * RX_NUM + i] = raw_data;
+ info->intensity[j * rx_num + i] = raw_data;
dev_dbg(&info->client->dev, "[TSP] intensity[%d][%d] = %d\n",
- i, j, info->intensity[j * RX_NUM + i]);
+ i, j, info->intensity[j * rx_num + i]);
} else if (cmd == MMS_VSC_CMD_CM_DELTA) {
- info->inspection[j * RX_NUM + i] = raw_data;
+ info->cm_delta[j * rx_num + i] = raw_data;
dev_dbg(&info->client->dev, "[TSP] delta[%d][%d] = %d\n",
- i, j, info->inspection[j * RX_NUM + i]);
+ i, j, info->cm_delta[j * rx_num + i]);
} else if (cmd == MMS_VSC_CMD_CM_ABS) {
- info->raw[j * RX_NUM + i] = raw_data;
+ info->cm_abs[j * rx_num + i] = raw_data;
dev_dbg(&info->client->dev, "[TSP] raw[%d][%d] = %d\n",
- i, j, info->raw[j * RX_NUM + i]);
+ i, j, info->cm_abs[j * rx_num + i]);
} else if (cmd == MMS_VSC_CMD_REFER) {
- info->reference[j * RX_NUM + i] =
+ info->reference[j * rx_num + i] =
raw_data >> 3;
dev_dbg(&info->client->dev, "[TSP] reference[%d][%d] = %d\n",
- i, j, info->reference[j * RX_NUM + i]);
+ i, j, info->reference[j * rx_num + i]);
}
}
@@ -1987,9 +2059,9 @@ static int check_rx_tx_num(void *device_data)
int node;
if (info->cmd_param[0] < 0 ||
- info->cmd_param[0] >= TX_NUM ||
+ info->cmd_param[0] >= info->pdata->tsp_tx ||
info->cmd_param[1] < 0 ||
- info->cmd_param[1] >= RX_NUM) {
+ info->cmd_param[1] >= info->pdata->tsp_rx) {
snprintf(buff, sizeof(buff) , "%s", "NG");
set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
info->cmd_state = 3;
@@ -1999,8 +2071,9 @@ static int check_rx_tx_num(void *device_data)
info->cmd_param[1]);
node = -1;
return node;
-}
- node = info->cmd_param[1] * RX_NUM + info->cmd_param[0];
+ }
+ /* Model dependency */
+ node = info->cmd_param[0] * info->pdata->tsp_rx + info->cmd_param[1];
dev_info(&info->client->dev, "%s: node = %d\n", __func__,
node);
return node;
@@ -2034,9 +2107,7 @@ static void fw_update(void *device_data)
dev_info(&client->dev,
"fw_ic_ver = 0x%02x, fw_bin_ver = 0x%02x\n",
- info->fw_ic_ver, FW_VERSION);
-
- goto not_support; /* GC Bring up- Not support yet */
+ info->fw_ic_ver, info->pdata->fw_version);
switch (info->cmd_param[0]) {
case BUILT_IN:
@@ -2063,6 +2134,7 @@ static void fw_update(void *device_data)
#if ISC_DL_MODE
ret = mms100_ISC_download_mbinary(client, info->cmd_param[0],
+ info->panel_type,
FORCED_UPDATE);
#endif
if (ret) {
@@ -2074,11 +2146,13 @@ static void fw_update(void *device_data)
info->fw_ic_ver = ver;
dev_info(&client->dev,
- "fw update done. ver = 0x%02x\n", ver);
+ "After FW update : [0x%02x]\n", ver);
info->cmd_state = OK;
enable_irq(info->irq);
return;
}
+ info->cmd_state = FAIL;
+ enable_irq(info->irq);
not_support:
return;
@@ -2091,7 +2165,7 @@ static void get_fw_ver_bin(void *device_data)
char buff[16] = {0};
set_default_result(info);
- snprintf(buff, sizeof(buff), "%#02x", FW_VERSION);
+ snprintf(buff, sizeof(buff), "%#02x", info->pdata->fw_version);
set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
info->cmd_state = OK;
@@ -2238,7 +2312,7 @@ static void get_chip_vendor(void *device_data)
set_default_result(info);
- snprintf(buff, sizeof(buff), "%s", TSP_VENDOR);
+ snprintf(buff, sizeof(buff), "%s", info->pdata->tsp_vendor);
set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
info->cmd_state = OK;
dev_info(&info->client->dev, "%s: %s(%d)\n", __func__,
@@ -2253,7 +2327,7 @@ static void get_chip_name(void *device_data)
set_default_result(info);
- snprintf(buff, sizeof(buff), "%s", TSP_IC);
+ snprintf(buff, sizeof(buff), "%s", info->pdata->tsp_ic);
set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
info->cmd_state = OK;
dev_info(&info->client->dev, "%s: %s(%d)\n", __func__,
@@ -2299,7 +2373,7 @@ static void get_cm_abs(void *device_data)
if (node < 0)
return;
- val = info->raw[node];
+ val = info->cm_abs[node];
snprintf(buff, sizeof(buff), "%u", val);
set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
info->cmd_state = OK;
@@ -2322,7 +2396,7 @@ static void get_cm_delta(void *device_data)
if (node < 0)
return;
- val = info->inspection[node];
+ val = info->cm_delta[node];
snprintf(buff, sizeof(buff), "%u", val);
set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
info->cmd_state = OK;
@@ -2339,12 +2413,22 @@ static void get_intensity(void *device_data)
unsigned int val;
int node;
+ int i, j;
+
set_default_result(info);
node = check_rx_tx_num(info);
if (node < 0)
return;
-
+#if 0
+ for (i = 0 ; i < info->pdata->tsp_tx ; i++) {
+ for (j = 0 ; j < info->pdata->tsp_rx ; j++) {
+ printk(KERN_INFO "[%2d]",
+ info->intensity[i*info->pdata->tsp_rx + j]);
+ }
+ printk("\n");
+ }
+#endif
val = info->intensity[node];
snprintf(buff, sizeof(buff), "%u", val);
@@ -2361,10 +2445,14 @@ static void get_x_num(void *device_data)
char buff[16] = {0};
int val;
-
+#if 1
+ if (info->enabled)
+ dev_info(&info->client->dev, "%s = [%d] from ic\n", __func__,
+ i2c_smbus_read_byte_data(info->client, 0xEF));
+#endif
set_default_result(info);
- snprintf(buff, sizeof(buff), "%d", TX_NUM); /* TX_NUM(0xEF) */
+ snprintf(buff, sizeof(buff), "%d", info->pdata->tsp_tx);
set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
info->cmd_state = OK;
@@ -2377,10 +2465,15 @@ static void get_y_num(void *device_data)
struct mms_ts_info *info = (struct mms_ts_info *)device_data;
char buff[16] = {0};
int val;
+#if 1
+ if (info->enabled)
+ dev_info(&info->client->dev, "%s = [%d] from ic\n", __func__,
+ i2c_smbus_read_byte_data(info->client, 0xEE));
+#endif
set_default_result(info);
- snprintf(buff, sizeof(buff), "%d", RX_NUM); /* RX_NUM(0xEE) */
+ snprintf(buff, sizeof(buff), "%d", info->pdata->tsp_rx);
set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
info->cmd_state = OK;
@@ -2608,7 +2701,7 @@ static ssize_t show_intensity_logging_on(struct device *dev,
snprintf(buff, 16, "%1u: ", y);
strncat(log_data, buff, strnlen(buff, 16));
- for (i = 0; i < RX_NUM; i++) {
+ for (i = 0; i < info->pdata->tsp_rx ; i++) {
val = get_raw_data_one(info, i, y,
MMS_VSC_CMD_INTENSITY);
snprintf(buff, 16, "%5u, ", val);
@@ -2679,8 +2772,10 @@ static int __devinit mms_ts_probe(struct i2c_client *client,
char buf[4] = { 0, };
int i;
-#ifdef SEC_TSP_FACTORY_TEST
+#if SEC_TSP_FACTORY_TEST
struct device *fac_dev_ts;
+ int rx_num;
+ int tx_num;
#endif
if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
@@ -2725,10 +2820,6 @@ static int __devinit mms_ts_probe(struct i2c_client *client,
for (i = 0 ; i < MAX_FINGERS; i++)
info->finger_state[i] = TSP_STATE_RELEASE;
- info->callbacks.inform_charger = melfas_ta_cb;
- if (info->register_cb)
- info->register_cb(&info->callbacks);
-
info->pdata->power(true);
msleep(100);
@@ -2740,8 +2831,17 @@ static int __devinit mms_ts_probe(struct i2c_client *client,
goto err_config;
}
- ret = mms_ts_fw_info(info);
-/* ret = mms_ts_fw_load(info); */
+ if (system_rev < 2) {
+ info->pdata->tsp_ic = "MMS136";
+ info->pdata->tsp_tx = 19;
+ info->pdata->tsp_rx = 11;
+ info->finger_byte = 6;
+ } else
+ info->finger_byte = 8;
+
+ dev_info(&client->dev, "TSP Packet size %d", info->finger_byte);
+
+ ret = mms_ts_fw_load(info);
if (ret) {
dev_err(&client->dev, "failed to initialize (%d)\n", ret);
@@ -2761,15 +2861,23 @@ static int __devinit mms_ts_probe(struct i2c_client *client,
__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
input_mt_init_slots(input_dev, MAX_FINGERS);
- input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, MAX_WIDTH, 0, 0);
input_set_abs_params(input_dev, ABS_MT_POSITION_X,
0, (info->max_x)-1, 0, 0);
input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
0, (info->max_y)-1, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR,
+ 0, MAX_WIDTH, 0, 0);
input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
0, MAX_PRESSURE, 0, 0);
- input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR,
- 0, MAX_PRESSURE, 0, 0);
+
+ if (info->finger_byte == 8) {
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR,
+ 0, MAX_PRESSURE, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_ANGLE,
+ MIN_ANGLE, MAX_ANGLE, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_PALM,
+ 0, 1, 0, 0);
+ }
input_set_drvdata(input_dev, info);
ret = input_register_device(input_dev);
@@ -2796,13 +2904,47 @@ static int __devinit mms_ts_probe(struct i2c_client *client,
register_early_suspend(&info->early_suspend);
#endif
-#ifdef SEC_TSP_FACTORY_TEST
- INIT_LIST_HEAD(&info->cmd_list_head);
- for (i = 0; i < ARRAY_SIZE(tsp_cmds); i++)
- list_add_tail(&tsp_cmds[i].list, &info->cmd_list_head);
+ info->callbacks.inform_charger = melfas_ta_cb;
+ if (info->register_cb)
+ info->register_cb(&info->callbacks);
+
+ ret = request_threaded_irq(client->irq, NULL, mms_ts_interrupt,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ MELFAS_TS_NAME, info);
+ if (ret < 0) {
+ dev_err(&client->dev, "Failed to register interrupt\n");
+ goto err_reg_input_dev;
+ }
+
+ info->irq = client->irq;
+ barrier();
- mutex_init(&info->cmd_lock);
- info->cmd_is_running = false;
+ dev_info(&client->dev,
+ "Melfas MMS-series touch controller initialized\n");
+
+#if SEC_TSP_FACTORY_TEST
+ rx_num = info->pdata->tsp_rx;
+ tx_num = info->pdata->tsp_tx;
+
+ info->reference = kzalloc(sizeof(int) * rx_num * tx_num, GFP_KERNEL);
+ info->cm_abs = kzalloc(sizeof(int) * rx_num * tx_num, GFP_KERNEL);
+ info->cm_delta = kzalloc(sizeof(int) * rx_num * tx_num, GFP_KERNEL);
+ info->intensity = kzalloc(sizeof(int) * rx_num * tx_num, GFP_KERNEL);
+ if (unlikely(info->reference == NULL ||
+ info->cm_abs == NULL ||
+ info->cm_delta == NULL ||
+ info->intensity == NULL)) {
+ ret = -ENOMEM;
+ goto err_alloc_node_data_failed;
+ }
+
+
+ INIT_LIST_HEAD(&info->cmd_list_head);
+ for (i = 0; i < ARRAY_SIZE(tsp_cmds); i++)
+ list_add_tail(&tsp_cmds[i].list, &info->cmd_list_head);
+
+ mutex_init(&info->cmd_lock);
+ info->cmd_is_running = false;
fac_dev_ts = device_create(sec_class,
NULL, 0, info, "tsp");
@@ -2813,16 +2955,22 @@ static int __devinit mms_ts_probe(struct i2c_client *client,
&sec_touch_factory_attr_group);
if (ret)
dev_err(&client->dev, "Failed to create sysfs group\n");
-#endif
+#endif /* SEC_TSP_FACTORY_TEST */
return 0;
+#if SEC_TSP_FACTORY_TEST
+err_alloc_node_data_failed:
+ dev_err(&client->dev, "Err_alloc_node_data failed\n");
+ kfree(info->reference);
+ kfree(info->cm_abs);
+ kfree(info->cm_delta);
+ kfree(info->intensity);
+#endif
+
err_reg_input_dev:
input_unregister_device(input_dev);
input_free_device(input_dev);
err_config:
-/* input_unregister_device(input_dev);
- input_dev = NULL;
-*/
err_input_alloc:
kfree(info);
err_alloc:
@@ -2834,6 +2982,14 @@ static int __devexit mms_ts_remove(struct i2c_client *client)
{
struct mms_ts_info *info = i2c_get_clientdata(client);
+#if SEC_TSP_FACTORY_TEST
+ dev_err(&client->dev, "Err_alloc_node_data failed\n");
+ kfree(info->reference);
+ kfree(info->cm_abs);
+ kfree(info->cm_delta);
+ kfree(info->intensity);
+#endif
+
unregister_early_suspend(&info->early_suspend);
if (info->irq >= 0)
free_irq(info->irq, info);
@@ -2872,9 +3028,18 @@ static int mms_ts_resume(struct device *dev)
dev_notice(&info->client->dev, "%s\n", __func__);
info->pdata->power(1);
msleep(120);
- /* GC Not support yet!
- mms_set_noise_mode(info);
- */
+
+ if (info->ta_status) {
+ dev_notice(&client->dev, "TA or USB connect!!!\n");
+ i2c_smbus_write_byte_data(info->client, MMS_TA_REG, MMS_TA_ON);
+
+ if (info->noise_mode) {
+ i2c_smbus_write_byte_data(info->client, MMS_NOISE_REG,
+ MMS_NOISE_ON);
+ dev_notice(&client->dev, "resume & noise mode on!\n");
+ }
+ } else
+ info->noise_mode = false;
/* Because irq_type by EXT_INTxCON register is changed to low_level
* after wakeup, irq_type set to falling edge interrupt again.