diff options
Diffstat (limited to 'drivers/input/touchscreen/mms152.c')
-rw-r--r-- | drivers/input/touchscreen/mms152.c | 2279 |
1 files changed, 0 insertions, 2279 deletions
diff --git a/drivers/input/touchscreen/mms152.c b/drivers/input/touchscreen/mms152.c deleted file mode 100644 index f3c75b0..0000000 --- a/drivers/input/touchscreen/mms152.c +++ /dev/null @@ -1,2279 +0,0 @@ -/* drivers/input/touchscreen/mms152.c - * - * Copyright (C) 2010 Melfas, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/earlysuspend.h> -#include <linux/hrtimer.h> -#include <linux/i2c.h> -#include <linux/input.h> -#include <linux/input/mt.h> -#include <linux/interrupt.h> -#include <linux/io.h> -#include <linux/slab.h> -#include <linux/platform_device.h> -#include <linux/mms152.h> -#include <linux/gpio.h> -#include <mach/cpufreq.h> - -/* firmware version start */ -#define HW_VERSION_EMPTY 0x00 - -#define GFS_HW_BASE_VER 0x03 -#define GFS_SW_BASE_VER 0x08 - -#define G2M_HW_BASE_VER 0x12 -#define G2M_SW_BASE_VER 0x09 - -#define GFD_HW_BASE_VER 0x26 -#define GFD_SW_BASE_VER 0x04 - -#define G2W_HW_BASE_VER 0x32 -#define G2W_SW_BASE_VER 0x01 - -/* ISP mode Ver */ -#define GFS_HW_VER 0x03 -#define GFS_SW_VER 0x14 - -#define G2M_HW_VER 0x12 -#define G2M_SW_VER 0x09 - -#define GFD_HW_VER 0x26 -#define GFD_SW_VER 0x07 - -#define G2W_HW_VER 0x32 -#define G2W_SW_VER 0x01 - -/* ISC mode Ver */ -#define CORE_VER 0x20 - -#define GFS_PRIVATE_VER 0x07 -#define GFS_PUBLIC_VER 0x08 - -#define G2M_PRIVATE_VER 0x00 -#define G2M_PUBLIC_VER 0x01 - -#define GFD_PRIVATE_VER 0x04 -#define GFD_PUBLIC_VER 0x05 - -#define G2W_PRIVATE_VER 0x00 -#define G2W_PUBLIC_VER 0x01 -/* firmware version end */ - -#define MELFAS_MAX_TOUCH 10 - -#define TS_MAX_X_COORD 1023 -#define TS_MAX_Y_COORD 599 -#define TS_MAX_Z_TOUCH 255 -#define TS_MAX_W_TOUCH 30 - -#define TS_READ_TSPCONNECT_ADDR 0x62 -#define TS_READ_VERSION_ADDR 0x63 -#define TS_READ_CORE_VERSION_ADDR 0x66 -#define TS_READ_PRIVATE_VERSION_ADDR 0x67 -#define TS_READ_PUBLIC_VERSION_ADDR 0x68 -#define TS_READ_REGS_LEN 66 - -#define TS_READ_START_ADDR 0x0F -#define TS_READ_START_ADDR2 0x10 - -#define TS_WRITE_REGS_LEN 16 -#define TS_THRESHOLD 0x70 -/* #define TSP_FACTORY_TEST */ -#define ENABLE_NOISE_TEST_MODE -#define TS_TA_STAT_ADDR 0x60 -/* #define DEBUG_LOW_DATA */ - -#define I2C_RETRY_CNT 50 -#define P2_MAX_I2C_FAIL 50 -#define P2_MAX_INFO_READ_FAIL 3 - -#define SET_DOWNLOAD_BY_GPIO 1 - -#define PRESS_KEY 1 -#define RELEASE_KEY 0 - -#define SHOW_COORD 0 -#define DEBUG_PRINT 0 -#define DEBUG_MODE - -#define TOUCH_BOOSTER 1 -#define SEC_DVFS_LOCK_TIMEOUT 3 - -#define X_LINE 20 -#define Y_LINE 31 -#define TSP_CHIP_VENDER_NAME "MELFAS,MMS152" - -enum { - TSP_STATE_RELEASE = 0, - TSP_STATE_PRESS, - TSP_STATE_MOVE, -}; - -#if SET_DOWNLOAD_BY_GPIO -#include "mms152_download.h" -#endif - -struct melfas_ts_data { - uint16_t addr; - struct i2c_client *client; - struct input_dev *input_dev; - struct ts_platform_data *pdata; - struct work_struct work; - struct tsp_callbacks cb; - struct mutex m_lock; -#if TOUCH_BOOSTER - struct delayed_work dvfs_work; - bool dvfs_lock_status; - int cpufreq_level; -#endif - u8 finger_state[MELFAS_MAX_TOUCH]; - uint32_t flags; - bool charging_status; - bool tsp_status; - int (*power)(int on); - struct early_suspend early_suspend; - void (*power_on)(void); - void (*power_off)(void); - void (*register_cb)(void *); - void (*read_ta_status)(bool *); - void (*set_touch_i2c)(void); - void (*set_touch_i2c_to_gpio)(void); - int touch_id; -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void melfas_ts_early_suspend(struct early_suspend *h); -static void melfas_ts_late_resume(struct early_suspend *h); -#endif - -static struct multi_touch_info g_Mtouch_info[MELFAS_MAX_TOUCH]; - -static bool debug_print; -static int firm_status_data; - -#ifdef DEBUG_MODE -static bool debug_on; - -static tCommandInfo_t tCommandInfo[] = { - { '?', "Help" }, - { 'T', "Go to LOGGING mode" }, - { 'M', "Go to MTSI_1_2_0 mode" }, - { 'R', "Toggle LOG ([R]awdata)" }, - { 'F', "Toggle LOG (Re[f]erence)" }, - { 'I', "Toggle LOG ([I]ntensity)" }, - { 'G', "Toggle LOG ([G]roup Image)" }, - { 'D', "Toggle LOG ([D]elay Image)" }, - { 'P', "Toggle LOG ([P]osition)" }, - { 'B', "Toggle LOG (De[b]ug)" }, - { 'V', "Toggle LOG (Debug2)" }, - { 'L', "Toggle LOG (Profi[l]ing)" }, - { 'O', "[O]ptimize Delay" }, - { 'N', "[N]ormalize Intensity" } -}; - -static bool vbLogType[LT_LIMIT] = {0, }; -static const char mcLogTypeName[LT_LIMIT][20] = { - "LT_DIAGNOSIS_IMG", - "LT_RAW_IMG", - "LT_REF_IMG", - "LT_INTENSITY_IMG", - "LT_GROUP_IMG", - "LT_DELAY_IMG", - "LT_POS", - "LT_DEBUG", - "LT_DEBUG2", - "LT_PROFILING", -}; - -static void toggle_log(struct melfas_ts_data *ts, eLogType_t _eLogType); -static void print_command_list(void); -static int melfas_i2c_read(struct i2c_client *client, u16 addr, - u16 length, u8 *value); -static void debug_i2c_read(struct i2c_client *client, u16 addr, - u8 *value, u16 length) -{ - melfas_i2c_read(client, addr, length, value); -} - -static int debug_i2c_write(struct i2c_client *client, u8 *value, u16 length) -{ - return i2c_master_send(client, value, length); -} - -static void key_handler(struct melfas_ts_data *ts, char key_val) -{ - u8 write_buf[2]; - int ret = 0; - pr_info("[TSP] %s - %c\n", __func__, key_val); - switch (key_val) { - case '?': - case '/': - print_command_list(); - break; - case 'T': - case 't': - write_buf[0] = ADDR_ENTER_LOGGING; - write_buf[1] = 1; - ret = debug_i2c_write(ts->client, write_buf, 2); - debug_on = true; - pr_info("result = %d", ret); - break; - case 'M': - case 'm': - write_buf[0] = ADDR_CHANGE_PROTOCOL; - write_buf[1] = 11; - debug_i2c_write(ts->client, write_buf, 2); - debug_on = false; - break; - case 'R': - case 'r': - toggle_log(ts, LT_RAW_IMG); - break; - case 'F': - case 'f': - toggle_log(ts, LT_REF_IMG); - break; - case 'I': - case 'i': - toggle_log(ts, LT_INTENSITY_IMG); - break; - case 'G': - case 'g': - toggle_log(ts, LT_GROUP_IMG); - break; - case 'D': - case 'd': - toggle_log(ts, LT_DELAY_IMG); - break; - case 'P': - case 'p': - toggle_log(ts, LT_POS); - break; - case 'B': - case 'b': - toggle_log(ts, LT_DEBUG); - break; - case 'V': - case 'v': - toggle_log(ts, LT_DEBUG2); - break; - case 'L': - case 'l': - toggle_log(ts, LT_PROFILING); - break; - case 'O': - case 'o': - pr_info("Enter 'Optimize Delay' mode!!!\n"); - write_buf[0] = ADDR_CHANGE_OPMODE; - write_buf[1] = OM_OPTIMIZE_DELAY; - if (!debug_i2c_write(ts->client, write_buf, 2)) - goto ERROR_HANDLE; - break; - case 'N': - case 'n': - pr_info("Enter 'Normalize Intensity' mode!!!\n"); - write_buf[0] = ADDR_CHANGE_OPMODE; - write_buf[1] = OM_NORMALIZE_INTENSITY; - if (!debug_i2c_write(ts->client, write_buf, 2)) - goto ERROR_HANDLE; - break; - default: - ; - } - return; -ERROR_HANDLE: - pr_info("ERROR!!!\n"); -} - -static void print_command_list(void) -{ - int i; - pr_info("######################################################\n"); - for (i = 0; i < sizeof(tCommandInfo) / sizeof(tCommandInfo_t); i++) - pr_info("[%c]: %s\n", tCommandInfo[i].cCommand, - tCommandInfo[i].sDescription); - pr_info("######################################################\n"); -} - -static void toggle_log(struct melfas_ts_data *ts, eLogType_t _eLogType) -{ - u8 write_buf[2]; - vbLogType[_eLogType] ^= 1; - if (vbLogType[_eLogType]) { - write_buf[0] = ADDR_LOGTYPE_ON; - pr_info("%s ON\n", mcLogTypeName[_eLogType]); - } else { - write_buf[0] = ADDR_LOGTYPE_OFF; - pr_info("%s OFF\n", mcLogTypeName[_eLogType]); - } - write_buf[1] = _eLogType; - debug_i2c_write(ts->client, write_buf, 2); -} - -static void logging_function(struct melfas_ts_data *ts) -{ - u8 read_buf[100]; - u8 read_mode, read_num; - int FingerX, FingerY, FingerID; - int i; - static int past_read_mode = HEADER_NONE; - static char *ps; - static char s[500]; - - debug_i2c_read(ts->client, LOG_READ_ADDR, read_buf, 2); - - read_mode = read_buf[0]; - read_num = read_buf[1]; - - switch (read_mode) { - case HEADER_U08: - { - unsigned char* p = (unsigned char *) &read_buf[2]; - i2c_master_recv(ts->client, read_buf, read_num + 2); - ps = s; - s[0] = '\0'; - - for (i = 0; i < read_num - 1; i++) { - sprintf(ps, "%4d,", p[i]); - ps = s + strlen(s); - } - sprintf(ps, "%4d\n", p[i]); - ps = s + strlen(s); - printk(KERN_DEBUG "%s", s); - break; - } - case HEADER_S08: - { - signed char* p = (signed char *) &read_buf[2]; - i2c_master_recv(ts->client, read_buf, read_num + 2); - ps = s; - s[0] = '\0'; - - for (i = 0; i < read_num - 1; i++) { - sprintf(ps, "%4d,", p[i]); - ps = s + strlen(s); - } - sprintf(ps, "%4d\n", p[i]); - ps = s + strlen(s); - printk(KERN_DEBUG "%s", s); - break; - } - case HEADER_U16: - { - unsigned short* p = (unsigned short *) &read_buf[2]; - i2c_master_recv(ts->client, read_buf, read_num * 2 + 2); - if (past_read_mode != HEADER_U16_NOCR) { - ps = s; - s[0] = '\0'; - } - - for (i = 0; i < read_num - 1; i++) { - sprintf(ps, "%5d,", p[i]); - ps = s + strlen(s); - } - sprintf(ps, "%5d\n", p[i]); - ps = s + strlen(s); - printk(KERN_DEBUG "%s", s); - break; - } - case HEADER_U16_NOCR: - { - unsigned short* p = (unsigned short *) &read_buf[2]; - i2c_master_recv(ts->client, read_buf, read_num * 2 + 2); - - if (past_read_mode != HEADER_U16_NOCR) { - ps = s; - s[0] = '\0'; - } - for (i = 0; i < read_num; i++) { - sprintf(ps, "%5d,", p[i]); - ps = s + strlen(s); - } - break; - } - case HEADER_S16: - { - signed short* p = (signed short *) &read_buf[2]; - i2c_master_recv(ts->client, read_buf, read_num * 2 + 2); - - if (past_read_mode != HEADER_S16_NOCR) { - ps = s; - s[0] = '\0'; - } - - for (i = 0; i < read_num - 1; i++) { - sprintf(ps, "%5d,", p[i]); - ps = s + strlen(s); - } - sprintf(ps, "%5d\n", p[i]); - ps = s + strlen(s); - printk(KERN_DEBUG "%s", s); - break; - } - case HEADER_S16_NOCR: - { - signed short* p = (signed short *) &read_buf[2]; - i2c_master_recv(ts->client, read_buf, read_num * 2 + 2); - - if (past_read_mode != HEADER_S16_NOCR) { - ps = s; - s[0] = '\0'; - } - for (i = 0; i < read_num; i++) { - sprintf(ps, "%5d,", p[i]); - ps = s + strlen(s); - } - break; - } - case HEADER_U32: - { - unsigned long* p = (unsigned long *) &read_buf[2]; - i2c_master_recv(ts->client, read_buf, read_num * 4 + 4); - - if (past_read_mode != HEADER_U32_NOCR) { - ps = s; - s[0] = '\0'; - } - - for (i = 0; i < read_num - 1; i++) { - sprintf(ps, "%10ld,", p[i]); - ps = s + strlen(s); - } - sprintf(ps, "%10ld\n", p[i]); - ps = s + strlen(s); - printk(KERN_DEBUG "%s", s); - break; - } - case HEADER_U32_NOCR: - { - unsigned long* p = (unsigned long *) &read_buf[2]; - i2c_master_recv(ts->client, read_buf, read_num * 4 + 4); - - if (past_read_mode != HEADER_U32_NOCR) { - ps = s; - s[0] = '\0'; - } - for (i = 0; i < read_num; i++) { - sprintf(ps, "%10ld,", p[i]); - ps = s + strlen(s); - } - break; - } - case HEADER_S32: - { - signed long* p = (signed long *) &read_buf[2]; - i2c_master_recv(ts->client, read_buf, read_num * 4 + 4); - - if (past_read_mode != HEADER_S32_NOCR) { - ps = s; - s[0] = '\0'; - } - - for (i = 0; i < read_num - 1; i++) { - sprintf(ps, "%10ld,", p[i]); - ps = s + strlen(s); - } - sprintf(ps, "%10ld\n", p[i]); - ps = s + strlen(s); - printk(KERN_DEBUG "%s", s); - break; - } - case HEADER_S32_NOCR: - { - signed long* p = (signed long *) &read_buf[2]; - i2c_master_recv(ts->client, read_buf, read_num * 4 + 4); - - if (past_read_mode != HEADER_S32_NOCR) { - ps = s; - s[0] = '\0'; - } - for (i = 0; i < read_num; i++) { - sprintf(ps, "%10ld,", p[i]); - ps = s + strlen(s); - } - break; - } - case HEADER_TEXT: - { - i2c_master_recv(ts->client, read_buf, read_num + 2); - - ps = s; - s[0] = '\0'; - - for (i = 2; i < read_num + 2; i++) { - sprintf(ps, "%c", read_buf[i]); - ps = s + strlen(s); - } - printk(KERN_DEBUG "%s\n", s); - break; - } - case HEADER_FINGER: - { - i2c_master_recv(ts->client, read_buf, read_num * 4 + 2); - - ps = s; - s[0] = '\0'; - for (i = 2; i < read_num * 4 + 2; i = i + 4) { - FingerX = (read_buf[i + 1] & 0x07) << 8 | read_buf[i]; - FingerY = (read_buf[i + 3] & 0x07) << 8 - | read_buf[i + 2]; - - FingerID = (read_buf[i + 1] & 0xF8) >> 3; - sprintf(ps, "%2d (%4d,%4d) | ", - FingerID, FingerX, FingerY); - ps = s + strlen(s); - } - printk(KERN_DEBUG "%s\n", s); - break; - } - case HEADER_S12: - { - signed short* p = (signed short *) &read_buf[2]; - i2c_master_recv(ts->client, read_buf, read_num * 2 + 2); - - if (past_read_mode != HEADER_S12_NOCR) { - ps = s; - s[0] = '\0'; - } - for (i = 0; i < read_num; i++) { - if (p[i] > 4096 / 2) - p[i] -= 4096; - } - - for (i = 0; i < read_num - 1; i++) { - sprintf(ps, "%5d,", p[i]); - ps = s + strlen(s); - } - sprintf(ps, "%5d\n", p[i]); - ps = s + strlen(s); - printk(KERN_DEBUG "%s", s); - break; - } - case HEADER_S12_NOCR: - { - signed short* p = (signed short *) &read_buf[2]; - i2c_master_recv(ts->client, read_buf, read_num * 2 + 2); - - if (past_read_mode != HEADER_S12_NOCR) { - ps = s; - s[0] = '\0'; - } - for (i = 0; i < read_num; i++) { - if (p[i] > 4096 / 2) - p[i] -= 4096; - } - for (i = 0; i < read_num; i++) { - sprintf(ps, "%5d,", p[i]); - ps = s + strlen(s); - } - break; - } - case HEADER_PRIVATE: - { - unsigned char* p = (unsigned char *) &read_buf[2]; - i2c_master_recv(ts->client, read_buf, - read_num + 2 + read_num % 2); - - ps = s; - s[0] = '\0'; - sprintf(ps, "################## CUSTOM_PRIVATE LOG: "); - ps = s + strlen(s); - for (i = 0; i < read_num - 1; i++) { - sprintf(ps, "%5d,", p[i]); - ps = s + strlen(s); - } - sprintf(ps, "%5d\n", p[i]); - ps = s + strlen(s); - printk(KERN_DEBUG "%s", s); - break; - } - default: - break; - } - - past_read_mode = read_mode; -} -#endif /* DEBUG_MODE */ - -static int melfas_i2c_read(struct i2c_client *client, - u16 addr, u16 length, u8 *value) -{ - struct i2c_adapter *adapter = client->adapter; - struct i2c_msg msg[2]; - int i; - - msg[0].addr = client->addr; - msg[0].flags = 0x00; - msg[0].len = 2; - msg[0].buf = (u8 *) &addr; - - msg[1].addr = client->addr; - msg[1].flags = I2C_M_RD; - msg[1].len = length; - msg[1].buf = (u8 *) value; - - i = i2c_transfer(adapter, msg, 2); - if (i == 2) - return 0; - else{ - pr_err("[TSP] melfas_i2c_read error : [%d]", i); - return -EIO; - } - -} - -static int melfas_i2c_write(struct i2c_client *client, char *buf, int length) -{ - int i; - char data[TS_WRITE_REGS_LEN]; - - if (length > TS_WRITE_REGS_LEN) { - pr_err("[TSP] size error - %s\n", __func__); - return -EINVAL; - } - - for (i = 0; i < length; i++) - data[i] = *buf++; - - i = i2c_master_send(client, (char *)data, length); - - if (i == length) - return length; - else{ - pr_err("[TSP] melfas_i2c_write error : [%d]", i); - return -EIO; - } -} - -static int read_input_info(struct melfas_ts_data *ts, - u8 *val, u8 start_addr, int read_length) -{ - return melfas_i2c_read(ts->client, start_addr, read_length, val); -} - -static int check_detail_firmware(struct melfas_ts_data *ts, u8 *val) -{ - return melfas_i2c_read(ts->client, TS_READ_VERSION_ADDR, 6, val); -} - -static int check_tsp_connect(struct melfas_ts_data *ts, u8 *val) -{ - return melfas_i2c_read(ts->client, TS_READ_TSPCONNECT_ADDR, 1, val); -} - -static int firmware_update(struct melfas_ts_data *ts) -{ - - int ret = 0, i = 0; - int touch_id = ts->touch_id; - uint8_t fw_ver[6] = {0,}; - uint8_t tsp_connect_stat = 0; - uint8_t fw_isc_update = 0x00; - bool fw_isp_update = false; - -#if SET_DOWNLOAD_BY_GPIO - - msleep(200); - - for (i = 0 ; i < P2_MAX_INFO_READ_FAIL ; i++) { - ret = check_tsp_connect(ts, &tsp_connect_stat); - if (!ret) - break; - msleep(100); - } - if (i == P2_MAX_INFO_READ_FAIL) { - pr_err("[TSP] check_tsp_connect check fail! [%d]", ret); - fw_isp_update |= true; - } - pr_info("[TSP] TSP panel is %sconnected [%d]", - tsp_connect_stat ? "" : "dis", i); - - if (touch_id == 3) - return 0; - - for (i = 0 ; i < P2_MAX_INFO_READ_FAIL ; i++) { - ret = check_detail_firmware(ts, fw_ver); - if (!ret) - break; - } - - if (i == P2_MAX_INFO_READ_FAIL) { - pr_err("[TSP] check_firmware fail! [%d]", ret); - fw_isp_update |= true; - } else { - pr_info("[TSP] Chk HW:[%x],SW:[%x],Core:[%x],Pri:[%x],Pub:[%x]", - fw_ver[0], fw_ver[1], fw_ver[3], fw_ver[4], fw_ver[5]); - - /* basic status for ISP D/L */ - if (ret > 0 || fw_ver[0] == HW_VERSION_EMPTY) { - fw_isp_update |= true; - } else if (fw_ver[0]>>4 != touch_id) { - if (fw_ver[3] == CORE_VER) { - fw_isc_update |= 0x06; - pr_info("[TSP] bin & panel dismatch ISC partial update!"); - } else { - fw_isp_update |= true; - pr_info("[TSP] bin & panel dismatch ISP Full update!"); - } - } else { - if (touch_id == 0) { /* GFF S-mac */ - if (fw_ver[0] < GFS_HW_BASE_VER || - (fw_ver[0] == GFS_HW_BASE_VER && - fw_ver[1] < GFS_SW_BASE_VER)) - fw_isp_update |= true; - } else if (touch_id == 1) { /* G2 -Morins */ - if (fw_ver[0] < G2M_HW_BASE_VER || - (fw_ver[0] == G2M_HW_BASE_VER && - fw_ver[1] < G2M_SW_BASE_VER)) - fw_isp_update |= true; - } else if (touch_id == 2) { /* GFF Digitec */ - if (fw_ver[0] < GFD_HW_BASE_VER || - (fw_ver[0] == GFD_HW_BASE_VER && - fw_ver[1] < GFD_SW_BASE_VER)) - fw_isp_update |= true; - } else if (touch_id == 3) { - pr_info("[TSP] touch_id=3 pannel is detached"); - return 0; - } - } - - if (!fw_isp_update && system_rev >= 2 && !fw_isc_update) { - if (fw_ver[3] < CORE_VER) - fw_isc_update |= 0x01; - - if ((touch_id == 0 && fw_ver[4] < GFS_PRIVATE_VER) || - (touch_id == 1 - && fw_ver[4] < G2M_PRIVATE_VER) || - (touch_id == 2 - && fw_ver[4] < GFD_PRIVATE_VER) || - (touch_id == 3 && fw_ver[4] < G2W_PRIVATE_VER)) - fw_isc_update |= 0x02; - - if ((touch_id == 0 && fw_ver[5] < GFS_PUBLIC_VER) || - (touch_id == 1 && fw_ver[5] < G2M_PUBLIC_VER) || - (touch_id == 2 && fw_ver[5] < GFD_PUBLIC_VER) || - (touch_id == 3 && fw_ver[5] < G2W_PUBLIC_VER)) - fw_isc_update |= 0x04; - } - } - - if (!fw_isp_update && !fw_isc_update) { - pr_info("[TSP] ISC & ISP Download ALL skip "); - return 0; - } else - pr_info("[TSP] ISP D/L mode %s & ISC D/L mode %s [%x]", - fw_isp_update ? "ON" : "OFF", - fw_isc_update ? "ON" : "OFF", fw_isc_update); - - ts->set_touch_i2c_to_gpio(); - - if (fw_isp_update) - ret = mcsdl_download_binary_data(touch_id); - else if (fw_isc_update) { - pr_info("[TSP] fw_isc_update bits = [%x]", fw_isc_update); - ret = mms100_ISC_download_binary_data(touch_id, fw_isc_update); - if (ret) { - pr_info("[TSP] ISC Fail & Try ISP mode D/L[%d]", ret); - ret = mcsdl_download_binary_data(touch_id); - if (ret) - pr_info("[TSP] ISC & ISP D/L Fail [%d]", ret); - } - } - - ts->set_touch_i2c(); - msleep(100); - - /* reset chip */ - ts->power_off(); - msleep(200); - ts->power_on(); - msleep(100); - - ret = check_detail_firmware(ts, fw_ver); - if (ret) - pr_err("[TSP] check_firmware fail! [%d]", ret); - else - pr_info("[TSP] FW HW:[%x],SW:[%x],Core:[%x],Pri:[%x],Pub:[%x]", - fw_ver[0], fw_ver[1], fw_ver[3], fw_ver[4], fw_ver[5]); - -#endif - - return ret; -} - -#if TOUCH_BOOSTER -static void free_dvfs_lock(struct work_struct *work) -{ - - struct melfas_ts_data *ts = container_of(work, - struct melfas_ts_data, dvfs_work.work); - - mutex_lock(&ts->m_lock); - exynos4_busfreq_lock_free(DVFS_LOCK_ID_TSP); - exynos_cpufreq_lock_free(DVFS_LOCK_ID_TSP); - ts->dvfs_lock_status = false; - pr_info("[TSP] DVFS Off!"); - mutex_unlock(&ts->m_lock); -} - -static void set_dvfs_lock(struct melfas_ts_data *ts, uint32_t on) -{ - mutex_lock(&ts->m_lock); - if (ts->cpufreq_level <= 0) { -#ifdef CONFIG_TARGET_LOCALE_P2TMO_TEMP - /*dvfs freq is temp modified to resolve dvfs kernel panic*/ - exynos_cpufreq_get_level(800000, &ts->cpufreq_level); -#else - exynos_cpufreq_get_level(500000, &ts->cpufreq_level); -#endif - } - if (on == 0) { - if (ts->dvfs_lock_status) - schedule_delayed_work(&ts->dvfs_work, - SEC_DVFS_LOCK_TIMEOUT * HZ); - } else if (on == 1) { - cancel_delayed_work(&ts->dvfs_work); - if (!ts->dvfs_lock_status) { - exynos4_busfreq_lock(DVFS_LOCK_ID_TSP, BUS_L1); - exynos_cpufreq_lock(DVFS_LOCK_ID_TSP, - ts->cpufreq_level); - ts->dvfs_lock_status = true; - pr_info("[TSP] DVFS On![%d]", ts->cpufreq_level); - } - } else if (on == 2) { - cancel_delayed_work(&ts->dvfs_work); - schedule_work(&ts->dvfs_work.work); - } - mutex_unlock(&ts->m_lock); -} -#endif - -static void release_all_fingers(struct melfas_ts_data *ts) -{ - int i; - - for (i = 0; i < MELFAS_MAX_TOUCH; i++) { - ts->finger_state[i] = TSP_STATE_RELEASE; - input_mt_slot(ts->input_dev, i); - input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, - false); - } - input_sync(ts->input_dev); - -#if TOUCH_BOOSTER - set_dvfs_lock(ts, 2); - pr_info("[TSP] release_all_fingers "); -#endif -} - -static void inform_charger_connection(struct tsp_callbacks *_cb, int mode) -{ - struct melfas_ts_data *ts = container_of(_cb, - struct melfas_ts_data, cb); - char buf[2]; - buf[0] = TS_TA_STAT_ADDR; - buf[1] = !!mode; - - if (ts->charging_status == !!mode) { - pr_info("[TSP] %s call but not change status", __func__); - } else { - ts->charging_status = !!mode; - - pr_info("[TSP] %s : TSP %s & TA %sconnect ", __func__, - ts->tsp_status ? "ON" : "OFF", - ts->charging_status ? "" : "dis"); - - if (ts->tsp_status) { - melfas_i2c_write(ts->client, (char *)buf, 2); - msleep(150); - } - } -} - - -static void reset_tsp(struct melfas_ts_data *ts) -{ - int ta_status = ts->charging_status; - char buf[2]; - - buf[0] = TS_TA_STAT_ADDR; - buf[1] = ta_status; - - release_all_fingers(ts); - - ts->power_off(); - msleep(200); - ts->power_on(); - msleep(200); - - pr_info("[TSP] reset_tsp & TA/USB %sconnect", ta_status ? "" : "dis"); - melfas_i2c_write(ts->client, (char *)buf, 2); - msleep(150); - -} - -static void melfas_ts_read_input(struct melfas_ts_data *ts) -{ - int ret = 0, i; - uint8_t buf[TS_READ_REGS_LEN]; - int touchStatus = 0; - int read_num, id, posX, posY, str, width; - int press_flag = 0; - -#if DEBUG_PRINT - pr_err("[TSP] melfas_ts_read_input\n"); - - if (ts == NULL) - pr_err("[TSP] melfas_ts_read_input : TS NULL\n"); -#endif - -#ifdef DEBUG_MODE - if (debug_on) { - logging_function(ts); - return; - } -#endif - - ret = read_input_info(ts, buf, TS_READ_START_ADDR, 1); - if (ret < 0) { - pr_err("[TSP] Failed to read the touch info\n"); - - for (i = 0; i < P2_MAX_I2C_FAIL; i++) { - ret = read_input_info(ts, buf, TS_READ_START_ADDR, 1); - if (ret >= 0) - break; - } - - if (i == P2_MAX_I2C_FAIL) { /* ESD Detection - I2c Fail */ - pr_err("[TSP] Melfas_ESD I2C FAIL\n"); - reset_tsp(ts); - return; - } - } - - read_num = buf[0]; -#if DEBUG_PRINT - pr_info("[TSP]touch count :[%d]", read_num/6); -#endif - - if (read_num <= 0) { - pr_err("[TSP] read_num error [%d]\n", read_num); - return; - } - - ret = read_input_info(ts, buf, TS_READ_START_ADDR2, read_num); - if (ret < 0) { - pr_err("[TSP] Failed to read the touch info"); - for (i = 0; i < P2_MAX_I2C_FAIL; i++) { - ret = read_input_info(ts, buf, - TS_READ_START_ADDR2, read_num); - if (ret >= 0) - break; - } - if (i == P2_MAX_I2C_FAIL) { - pr_err("[TSP] Melfas_ESD I2C FAIL\n"); - reset_tsp(ts); - return ; - } - } - - touchStatus = buf[0] & 0xFF; - - if (touchStatus == 0x0F) { - pr_info("[TSP] TSP ESD Detection [%x]", buf[0]); - reset_tsp(ts); - return ; - } else if (touchStatus == 0x1F) { - pr_info("[TSP] TSP RF Noise Detection [%x]", buf[0]); - return ; - } - - for (i = 0; i < read_num; i = i+6) { - id = (buf[i] & 0x0F)-1; - posX = (u16)(buf[i+1] & 0x0F) << 8 | buf[i+2]; - posY = (u16)(buf[i+1] & 0xF0) << 4 | buf[i+3]; - str = buf[i + 4]; - width = buf[i+5]; - - if ((buf[i] & 0x80) == TSP_STATE_RELEASE) { - if (ts->finger_state[id] == TSP_STATE_RELEASE) { - pr_err("[TSP] abnormal release"); - continue; - } - input_mt_slot(ts->input_dev, id); - input_mt_report_slot_state(ts->input_dev, - MT_TOOL_FINGER, false); -#if SHOW_COORD - pr_info("[TSP] R [%d],([%4d],[%3d]),S:%d W:%d (%d)", - id, posX, posY, str, width, - ts->finger_state[id]); -#else - pr_info("[TSP] R [%d] (%d)", id, ts->finger_state[id]); -#endif - ts->finger_state[id] = TSP_STATE_RELEASE; - } else { - input_mt_slot(ts->input_dev, id); - input_mt_report_slot_state(ts->input_dev, - MT_TOOL_FINGER, true); - input_report_abs(ts->input_dev, - ABS_MT_POSITION_X, posX); - input_report_abs(ts->input_dev, - ABS_MT_POSITION_Y, posY); - input_report_abs(ts->input_dev, - ABS_MT_TOUCH_MAJOR, str); - input_report_abs(ts->input_dev, - ABS_MT_WIDTH_MAJOR, width); - - if (ts->finger_state[id] == TSP_STATE_RELEASE) { -#if SHOW_COORD - pr_info("[TSP] P [%d],([%4d],[%3d]),S:%d W:%d", - id, posX, posY, str, width); -#else - pr_info("[TSP] P [%d]", id); -#endif - ts->finger_state[id] = TSP_STATE_PRESS; - } else if (ts->finger_state[id] == TSP_STATE_PRESS) - ts->finger_state[id] = TSP_STATE_MOVE; - } - } - input_sync(ts->input_dev); - - for (i = 0 ; i < MELFAS_MAX_TOUCH ; i++) { - if (ts->finger_state[i] == TSP_STATE_PRESS - || ts->finger_state[i] == TSP_STATE_MOVE) { - press_flag = 1; - break; - } - } - -#if TOUCH_BOOSTER - set_dvfs_lock(ts, press_flag); -#endif -} - -static irqreturn_t melfas_ts_irq_handler(int irq, void *handle) -{ - struct melfas_ts_data *ts = (struct melfas_ts_data *)handle; -#if DEBUG_PRINT - pr_err("[TSP] melfas_ts_irq_handler"); -#endif - - melfas_ts_read_input(ts); - return IRQ_HANDLED; -} - -static ssize_t show_firm_version_panel(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct melfas_ts_data *ts = dev_get_drvdata(dev); - u8 fw_ver[6] = {0,}; - int ret; - - ret = check_detail_firmware(ts, fw_ver); - if (ret) - pr_err("[TSP] show_firm_version_panel fail! [%d]", ret); - else - pr_info("[TSP] show_firm_version_panel [%x][%x],[%x][%x][%x]", - fw_ver[0], fw_ver[1], fw_ver[3], fw_ver[4], fw_ver[5]); - - if (ts->touch_id == 0) - return snprintf(buf, PAGE_SIZE, - "GFS_%2.2Xx%2.2X\n", fw_ver[0], fw_ver[1]); - else if (ts->touch_id == 1) - return snprintf(buf, PAGE_SIZE, - "G2M_%2.2Xx%2.2X\n", fw_ver[0], fw_ver[1]); - else if (ts->touch_id == 2) - return snprintf(buf, PAGE_SIZE, - "GFD_%2.2Xx%2.2X\n", fw_ver[0], fw_ver[1]); - else if (ts->touch_id == 3) - return snprintf(buf, PAGE_SIZE, - "G2W_%2.2Xx%2.2X\n", fw_ver[0], fw_ver[1]); - else - return snprintf(buf, PAGE_SIZE, - "MEL_%2.2Xx%2.2X\n", fw_ver[0], fw_ver[1]); - return 0; -} - -static ssize_t show_firm_version_phone(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct melfas_ts_data *ts = dev_get_drvdata(dev); - - if (ts->touch_id == 0) - return snprintf(buf, PAGE_SIZE, - "GFS_%2.2Xx%2.2X\n", GFS_HW_VER, GFS_SW_VER); - else if (ts->touch_id == 1) - return snprintf(buf, PAGE_SIZE, - "G2M_%2.2Xx%2.2X\n", G2M_HW_VER, G2M_SW_VER); - else if (ts->touch_id == 2) - return snprintf(buf, PAGE_SIZE, - "GFD_%2.2Xx%2.2X\n", GFD_HW_VER, GFD_SW_VER); - else if (ts->touch_id == 3) - return snprintf(buf, PAGE_SIZE, - "G2W_%2.2Xx%2.2X\n", G2W_HW_VER, G2W_SW_VER); - return 0; -} - -static ssize_t show_firm_update_status(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - - int count; - pr_info("[TSP] Enter firmware_status_show by Factory command\n"); - - if (firm_status_data == 1) - count = sprintf(buf, "DOWNLOADING\n"); - else if (firm_status_data == 2) - count = sprintf(buf, "PASS\n"); - else if (firm_status_data == 3) - count = sprintf(buf, "FAIL\n"); - else - count = sprintf(buf, "PASS\n"); - - return count; -} - -static ssize_t tsp_firm_update(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - struct melfas_ts_data *ts = dev_get_drvdata(dev); - u8 fw_ver[6] = {0,}; - int ret = 0; - -#if SET_DOWNLOAD_BY_GPIO - - disable_irq(ts->client->irq); - - firm_status_data = 1; - - ts->set_touch_i2c_to_gpio(); - - pr_info("[TSP] ADB F/W UPDATE MODE ENTER! :%s", buf); - if (*buf == 'F') - ret = mcsdl_download_binary_data(ts->touch_id); - else if (*buf == '0') { - pr_info("[TSP] GFS F/W UPDATE !"); - ret = mcsdl_download_binary_data(0); - } else if (*buf == '1') { - pr_info("[TSP] G2M F/W UPDATE !"); - ret = mcsdl_download_binary_data(1); - } else if (*buf == '2') { - pr_info("[TSP] GFD F/W UPDATE !"); - ret = mcsdl_download_binary_data(2); - } else if (*buf == '3') { - pr_info("[TSP] G2W F/W UPDATE !"); - ret = mcsdl_download_binary_data(3); - } else - ret = mcsdl_download_binary_file(); - - pr_info("[TSP] ADB F/W UPDATE MODE FROM %s END! %s", - (*buf == 'F' ? "BINARY" : "FILE"), (ret ? "fail" : "success")); - - firm_status_data = (ret ? 3 : 2); - - ts->set_touch_i2c(); - - reset_tsp(ts); - - enable_irq(ts->client->irq); -#endif - - ret = check_detail_firmware(ts, fw_ver); - if (ret) - pr_err("[TSP] check_firmware fail! [%d]", ret); - else - pr_info("[TSP] FW HW:[%x],SW:[%x],Core:[%x],Pri:[%x],Pub:[%x]", - fw_ver[0], fw_ver[1], fw_ver[3], fw_ver[4], fw_ver[5]); - - return count; -} - -static ssize_t tsp_firm_verify(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - struct melfas_ts_data *ts = dev_get_drvdata(dev); - int ret = 0; - -#if SET_DOWNLOAD_BY_GPIO - - disable_irq(ts->client->irq); - - ts->set_touch_i2c_to_gpio(); - - pr_info("[TSP] ADB F/W Verify MODE ENTER! :%s", buf); - if (*buf == 'F') - ret = mcsdl_download_binary_data_verify(ts->touch_id); - else if (*buf == '0') { - pr_info("[TSP] GFS F/W Verify !"); - ret = mcsdl_download_binary_data_verify(0); - } else if (*buf == '1') { - pr_info("[TSP] G2M F/W Verify !"); - ret = mcsdl_download_binary_data_verify(1); - } else if (*buf == '2') { - pr_info("[TSP] GFD F/W Verify !"); - ret = mcsdl_download_binary_data_verify(2); - } else if (*buf == '3') { - pr_info("[TSP] G2W F/W Verify !"); - ret = mcsdl_download_binary_data_verify(3); - } else - pr_info("[TSP] ADB F/W Verify MODE file error"); - - pr_info("[TSP] ADB F/W Verify %s", (ret ? "Fail" : "Success")); - - ts->set_touch_i2c(); - - reset_tsp(ts); - - enable_irq(ts->client->irq); -#endif - return count; -} - - -static ssize_t store_debug_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - struct melfas_ts_data *ts = dev_get_drvdata(dev); - char ch; - - if (sscanf(buf, "%c", &ch) != 1) - return -EINVAL; - - key_handler(ts, ch); - - return count; -} - -static ssize_t show_debug_mode(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, debug_on ? "ON\n" : "OFF\n"); -} - -static ssize_t store_debug_log(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - int i; - - if (sscanf(buf, "%d", &i) != 1) - return -EINVAL; - - if (i) - debug_print = 1; - else - debug_print = 0; - - pr_info("[TSP] debug log %s", i ? "ON" : "OFF"); - - return count; -} - -static ssize_t show_threshold(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct melfas_ts_data *ts = dev_get_drvdata(dev); - u8 threshold; - melfas_i2c_read(ts->client, TS_THRESHOLD, 1, &threshold); - - return sprintf(buf, "%d\n", threshold); -} - - -static DEVICE_ATTR(tsp_threshold, S_IRUGO, show_threshold, NULL); -static DEVICE_ATTR(tsp_firm_update, S_IWUSR | S_IWGRP, - NULL, tsp_firm_update); -static DEVICE_ATTR(tsp_firm_verify, S_IWUSR | S_IWGRP, - NULL, tsp_firm_verify); -static DEVICE_ATTR(tsp_firm_update_status, S_IRUGO, - show_firm_update_status, NULL); -static DEVICE_ATTR(tsp_firm_version_phone, S_IRUGO, - show_firm_version_phone, NULL); -static DEVICE_ATTR(tsp_firm_version_panel, S_IRUGO, - show_firm_version_panel, NULL); -static DEVICE_ATTR(debug_mode, S_IWUSR|S_IRUGO, - show_debug_mode, store_debug_mode); -static DEVICE_ATTR(debug_log, S_IWUSR|S_IRUGO, NULL, store_debug_log); - - -#ifdef ENABLE_NOISE_TEST_MODE -static DEVICE_ATTR(set_threshould, S_IRUGO, show_threshold, NULL); -#else -static DEVICE_ATTR(threshold, S_IRUGO, show_threshold, NULL); -#endif - -static u16 index_reference; -static u16 reference_data[X_LINE*Y_LINE] = { 0, }; -static u16 intensity_data[X_LINE*Y_LINE] = { 0, }; -static u16 inspection_data[X_LINE*Y_LINE] = { 0, }; - -static int check_debug_data(struct melfas_ts_data *ts) -{ - u8 write_buffer[6]; - u8 read_buffer[2]; - int sensing_line, exciting_line; - int gpio = ts->pdata->gpio_int; - int count = 0; - - disable_irq(ts->client->irq); - - /* enter the debug mode */ - write_buffer[0] = 0xA0; - write_buffer[1] = 0x1A; - write_buffer[2] = 0x0; - write_buffer[3] = 0x0; - write_buffer[4] = 0x0; - write_buffer[5] = 0x01; - melfas_i2c_write(ts->client, (char *)write_buffer, 6); - - /* wating for the interrupt*/ - while (gpio_get_value(gpio)) { - printk("."); - udelay(100); - count++; - if (count == 1000) { - enable_irq(ts->client->irq); - return -1; - } - } - - if (debug_print) - pr_info("[TSP] read dummy\n"); - - /* read the dummy data */ - melfas_i2c_read(ts->client, 0xA8, 2, read_buffer); - - if (debug_print) - pr_info("[TSP] read inspenction data\n"); - write_buffer[5] = 0x02; - for (sensing_line = 0; sensing_line < X_LINE; sensing_line++) { - for (exciting_line = 0; exciting_line < Y_LINE; - exciting_line++) { - write_buffer[2] = exciting_line; - write_buffer[3] = sensing_line; - melfas_i2c_write(ts->client, (char *)write_buffer, 6); - melfas_i2c_read(ts->client, 0xA8, 2, read_buffer); - reference_data[exciting_line + sensing_line * Y_LINE] = - (read_buffer[1] & 0xf) << 8 | read_buffer[0]; - } - } - - reset_tsp(ts); - msleep(200); - enable_irq(ts->client->irq); - return 0; -} - -static ssize_t all_refer_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int status = 0; - int i; - struct melfas_ts_data *ts = dev_get_drvdata(dev); - - for (i = 0; i < 3; i++) { - if (!check_debug_data(ts)) { - status = 0; - break; - } else { - pr_info("[TSP] check_debug_data Error try=%d", i); - reset_tsp(ts); - msleep(300); - status = 1; - } - } - - if (!status) { - for (i = 0; i < X_LINE*Y_LINE; i++) { - /* out of range */ - if (reference_data[i] < 30) { - status |= 1; - break; - } - - if (debug_print) { - if (0 == i % Y_LINE) - printk("\n"); - printk(KERN_INFO "%5u ", reference_data[i]); - } - } - } else { - pr_info("[TSP] all_refer_show& check_debug_data error[%d]", - status); - return sprintf(buf, "%u\n", status); - } - - pr_info("[TSP] all_refer_show func [%d]", status); - return sprintf(buf, "%u\n", status); -} - -static void check_intesity_data(struct melfas_ts_data *ts) -{ - u8 write_buffer[6]; - u8 read_buffer[2]; - int sensing_line, exciting_line; - int gpio = ts->pdata->gpio_int; - - if (0 == reference_data[0]) { - disable_irq(ts->client->irq); - - /* enter the debug mode */ - write_buffer[0] = 0xA0; - write_buffer[1] = 0x1A; - write_buffer[2] = 0x0; - write_buffer[3] = 0x0; - write_buffer[4] = 0x0; - write_buffer[5] = 0x01; - melfas_i2c_write(ts->client, (char *)write_buffer, 6); - - /* wating for the interrupt*/ - while (gpio_get_value(gpio)) { - printk("."); - udelay(100); - } - - /* read the dummy data */ - melfas_i2c_read(ts->client, 0xA8, 2, read_buffer); - - if (debug_print) - pr_info("[TSP] read the dummy data\n"); - - write_buffer[5] = 0x02; - for (sensing_line = 0; sensing_line < X_LINE; sensing_line++) { - for (exciting_line = 0; exciting_line < Y_LINE; - exciting_line++) { - write_buffer[2] = exciting_line; - write_buffer[3] = sensing_line; - melfas_i2c_write(ts->client, - (char *)write_buffer, 6); - melfas_i2c_read(ts->client, 0xA8, 2, - read_buffer); - reference_data[exciting_line + - sensing_line * Y_LINE] = - (read_buffer[1] & 0xf) << 8 - | read_buffer[0]; - } - } - reset_tsp(ts); - msleep(100); - enable_irq(ts->client->irq); - msleep(100); - } - - disable_irq(ts->client->irq); - release_all_fingers(ts); - - write_buffer[0] = 0xA0; - write_buffer[1] = 0x1A; - write_buffer[4] = 0x0; - write_buffer[5] = 0x04; - for (sensing_line = 0; sensing_line < X_LINE; sensing_line++) { - for (exciting_line = 0; exciting_line < Y_LINE; - exciting_line++) { - write_buffer[2] = exciting_line; - write_buffer[3] = sensing_line; - melfas_i2c_write(ts->client, (char *)write_buffer, 6); - melfas_i2c_read(ts->client, 0xA8, 2, read_buffer); - intensity_data[exciting_line + sensing_line * Y_LINE] = - (read_buffer[1] & 0xf) << 8 | read_buffer[0]; - } - } - enable_irq(ts->client->irq); -} - -static ssize_t set_refer0_mode_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - u16 refrence = 0; - struct melfas_ts_data *ts = dev_get_drvdata(dev); - - check_intesity_data(ts); - - refrence = reference_data[95]; - return sprintf(buf, "%u\n", refrence); -} - -static ssize_t set_refer1_mode_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - u16 refrence = 0; - refrence = reference_data[529]; - return sprintf(buf, "%u\n", refrence); -} - -static ssize_t set_refer2_mode_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - u16 refrence = 0; - refrence = reference_data[294]; - return sprintf(buf, "%u\n", refrence); -} - -static ssize_t set_refer3_mode_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - u16 refrence = 0; - refrence = reference_data[89]; - return sprintf(buf, "%u\n", refrence); -} - -static ssize_t set_refer4_mode_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - u16 refrence = 0; - refrence = reference_data[554]; - return sprintf(buf, "%u\n", refrence); -} - -static ssize_t set_intensity0_mode_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - u16 intensity = 0; - intensity = intensity_data[95]; - return sprintf(buf, "%u\n", intensity); -} - -static ssize_t set_intensity1_mode_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - u16 intensity = 0; - intensity = intensity_data[529]; - return sprintf(buf, "%u\n", intensity); -} - -static ssize_t set_intensity2_mode_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - u16 intensity = 0; - intensity = intensity_data[294]; - return sprintf(buf, "%u\n", intensity); -} - -static ssize_t set_intensity3_mode_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - u16 intensity = 0; - intensity = intensity_data[89]; - return sprintf(buf, "%u\n", intensity); -} - -static ssize_t set_intensity4_mode_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - u16 intensity = 0; - intensity = intensity_data[554]; - return sprintf(buf, "%u\n", intensity); -} - -static ssize_t tsp_power_control(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - struct melfas_ts_data *ts = dev_get_drvdata(dev); - - int ta_status = ts->charging_status; - char writebuf[2]; - - writebuf[0] = TS_TA_STAT_ADDR; - writebuf[1] = ta_status; - - if (*buf == '0' && ts->tsp_status == true) { - ts->tsp_status = false; - release_all_fingers(ts); - ts->power_off(); - msleep(200); - } else if (*buf == '1' && ts->tsp_status == false) { - ts->power_on(); - msleep(200); - melfas_i2c_write(ts->client, (char *)writebuf, 2); - msleep(150); - ts->tsp_status = true; - } else - pr_info("[TSP]tsp_power_control bad command!"); - return count; -} - -static ssize_t show_tsp_info(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "%s\n", TSP_CHIP_VENDER_NAME); -} - -static ssize_t show_tsp_x_line_info(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "%d\n", X_LINE); -} - -static ssize_t show_tsp_y_line_info(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "%d\n", Y_LINE); -} - -static int atoi(const char *str) -{ - int result = 0; - int count = 0; - char count_val = str[count]; - - if (str == NULL) - return -1; - while (str != NULL && count_val >= '0' && count_val <= '9') { - result = result * 10 + count_val - '0'; - ++count; - } - return result; -} - -static ssize_t set_debug_data1(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - - struct melfas_ts_data *ts = dev_get_drvdata(dev); - - u8 write_buffer[6]; - u8 read_buffer[2]; - int sensing_line, exciting_line; - int gpio = ts->pdata->gpio_int; - - if (!ts->tsp_status) { - pr_info("[TSP] call set_debug_data1 but TSP status OFF!"); - return count; - } - - disable_irq(ts->client->irq); - - /* enter the debug mode */ - write_buffer[0] = 0xA0; - write_buffer[1] = 0x1A; - write_buffer[2] = 0x0; - write_buffer[3] = 0x0; - write_buffer[4] = 0x0; - write_buffer[5] = 0x01; - melfas_i2c_write(ts->client, (char *)write_buffer, 6); - - /* wating for the interrupt*/ - while (gpio_get_value(gpio)) { - printk("."); - udelay(100); - } - - /* read the dummy data */ - melfas_i2c_read(ts->client, 0xA8, 2, read_buffer); - - pr_info("[TSP] read Reference data\n"); - write_buffer[5] = 0x02; - for (sensing_line = 0; sensing_line < X_LINE; sensing_line++) { - for (exciting_line = 0; exciting_line < Y_LINE; - exciting_line++) { - write_buffer[2] = exciting_line; - write_buffer[3] = sensing_line; - melfas_i2c_write(ts->client, (char *)write_buffer, 6); - melfas_i2c_read(ts->client, 0xA8, 2, read_buffer); - reference_data[exciting_line + sensing_line * Y_LINE] = - (read_buffer[1] & 0xf) << 8 | read_buffer[0]; - } - } - - reset_tsp(ts); - msleep(200); - enable_irq(ts->client->irq); - return count; -} - -static ssize_t set_debug_data2(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - - struct melfas_ts_data *ts = dev_get_drvdata(dev); - - u8 write_buffer[6]; - u8 read_buffer[2]; - int sensing_line, exciting_line; - int gpio = ts->pdata->gpio_int; - - if (!ts->tsp_status) { - pr_info("[TSP] call set_debug_data2 but TSP status OFF!"); - return count; - } - - disable_irq(ts->client->irq); - - /* enter the debug mode */ - write_buffer[0] = 0xA0; - write_buffer[1] = 0x1A; - write_buffer[2] = 0x0; - write_buffer[3] = 0x0; - write_buffer[4] = 0x0; - write_buffer[5] = 0x01; - melfas_i2c_write(ts->client, (char *)write_buffer, 6); - - /* wating for the interrupt*/ - while (gpio_get_value(gpio)) { - printk("."); - udelay(100); - } - - /* read the dummy data */ - melfas_i2c_read(ts->client, 0xA8, 2, read_buffer); - - pr_info("[TSP] read Inspection data\n"); - write_buffer[5] = 0x03; - for (sensing_line = 0; sensing_line < X_LINE; sensing_line++) { - for (exciting_line = 0; exciting_line < Y_LINE; - exciting_line++) { - write_buffer[2] = exciting_line; - write_buffer[3] = sensing_line; - melfas_i2c_write(ts->client, (char *)write_buffer, 6); - melfas_i2c_read(ts->client, 0xA8, 2, read_buffer); - inspection_data[exciting_line + - sensing_line * Y_LINE] = - (read_buffer[1] & 0xf) << 8 | read_buffer[0]; - } - } - reset_tsp(ts); - msleep(200); - enable_irq(ts->client->irq); - return count; -} - -static ssize_t set_debug_data3(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - - struct melfas_ts_data *ts = dev_get_drvdata(dev); - - u8 write_buffer[6]; - u8 read_buffer[2]; - int sensing_line, exciting_line; - - if (!ts->tsp_status) { - pr_info("[TSP] call set_debug_data3 but TSP status OFF!"); - return count; - } - - pr_info("[TSP] read lntensity data\n"); - - disable_irq(ts->client->irq); - - /* enter the debug mode */ - write_buffer[0] = 0xA0; - write_buffer[1] = 0x1A; - write_buffer[2] = 0x0; - write_buffer[3] = 0x0; - write_buffer[4] = 0x0; - write_buffer[5] = 0x04; - for (sensing_line = 0; sensing_line < X_LINE; sensing_line++) { - for (exciting_line = 0; exciting_line < Y_LINE; - exciting_line++) { - write_buffer[2] = exciting_line; - write_buffer[3] = sensing_line; - melfas_i2c_write(ts->client, (char *)write_buffer, 6); - melfas_i2c_read(ts->client, 0xA8, 2, read_buffer); - intensity_data[exciting_line + sensing_line * Y_LINE] = - (read_buffer[1] & 0xf) << 8 | read_buffer[0]; - } - } - - reset_tsp(ts); - msleep(200); - enable_irq(ts->client->irq); - return count; -} - - - -static ssize_t set_index_reference(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - index_reference = atoi(buf); - if (index_reference < 0 || index_reference >= X_LINE*Y_LINE) { - pr_info("[TSP] input bad index_reference value"); - return -1; - } else { - pr_info("[TSP]index_reference =%d ", index_reference); - return count; - } -} -static ssize_t show_reference_info(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int i = 0; - if (debug_print) { - for (i = 0; i < X_LINE*Y_LINE; i++) { - if (0 == i % Y_LINE) - printk(KERN_INFO "\n"); - printk(KERN_INFO "%4u", reference_data[i]); - } - } - return sprintf(buf, "%d\n", reference_data[index_reference]); -} -static ssize_t show_inspection_info(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int i = 0; - if (debug_print) { - for (i = 0; i < X_LINE*Y_LINE; i++) { - if (0 == i % Y_LINE) - printk(KERN_INFO "\n"); - printk(KERN_INFO "%5u", inspection_data[i]); - } - } - return sprintf(buf, "%d\n", inspection_data[index_reference]); -} -static ssize_t show_intensity_info(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int i = 0, max_idx = 0, max_val = 0; - if (debug_print) { - for (i = 0; i < X_LINE*Y_LINE; i++) { - if (max_val < intensity_data[i]) { - max_val = intensity_data[i]; - max_idx = i; - } - if (0 == i % Y_LINE) - printk(KERN_INFO "\n"); - printk(KERN_INFO "%4u", intensity_data[i]); - } - pr_info("[TSP] max val=[%d] , index=[%d] ", max_val, max_idx); - } - return sprintf(buf, "%d\n", intensity_data[index_reference]); -} - -static DEVICE_ATTR(set_all_refer, S_IRUGO, all_refer_show, NULL); -static DEVICE_ATTR(set_refer0, S_IRUGO, set_refer0_mode_show, NULL); -static DEVICE_ATTR(set_delta0, S_IRUGO, set_intensity0_mode_show, NULL); -static DEVICE_ATTR(set_refer1, S_IRUGO, set_refer1_mode_show, NULL); -static DEVICE_ATTR(set_delta1, S_IRUGO, set_intensity1_mode_show, NULL); -static DEVICE_ATTR(set_refer2, S_IRUGO, set_refer2_mode_show, NULL); -static DEVICE_ATTR(set_delta2, S_IRUGO, set_intensity2_mode_show, NULL); -static DEVICE_ATTR(set_refer3, S_IRUGO, set_refer3_mode_show, NULL); -static DEVICE_ATTR(set_delta3, S_IRUGO, set_intensity3_mode_show, NULL); -static DEVICE_ATTR(set_refer4, S_IRUGO, set_refer4_mode_show, NULL); -static DEVICE_ATTR(set_delta4, S_IRUGO, set_intensity4_mode_show, NULL); -static DEVICE_ATTR(tsp_info, S_IRUGO, show_tsp_info, NULL); -static DEVICE_ATTR(tsp_x_line, S_IRUGO, show_tsp_x_line_info, NULL); -static DEVICE_ATTR(tsp_y_line, S_IRUGO, show_tsp_y_line_info, NULL); -static DEVICE_ATTR(tsp_power, S_IWUSR | S_IWGRP, NULL, tsp_power_control); -static DEVICE_ATTR(set_debug_data1, S_IWUSR | S_IWGRP, NULL, set_debug_data1); -static DEVICE_ATTR(set_debug_data2, S_IWUSR | S_IWGRP, NULL, set_debug_data2); -static DEVICE_ATTR(set_debug_data3, S_IWUSR | S_IWGRP, NULL, set_debug_data3); -static DEVICE_ATTR(set_index_ref, S_IWUSR | S_IWGRP, - NULL, set_index_reference); -static DEVICE_ATTR(show_reference_info, S_IRUGO, show_reference_info, NULL); -static DEVICE_ATTR(show_inspection_info, S_IRUGO, show_inspection_info, NULL); -static DEVICE_ATTR(show_intensity_info, S_IRUGO, show_intensity_info, NULL); - - -static struct attribute *sec_touch_attributes[] = { - &dev_attr_tsp_threshold.attr, - &dev_attr_tsp_firm_update.attr, - &dev_attr_tsp_firm_verify.attr, - &dev_attr_tsp_firm_update_status.attr, - &dev_attr_tsp_firm_version_phone.attr, - &dev_attr_tsp_firm_version_panel.attr, - &dev_attr_debug_mode.attr, - &dev_attr_debug_log.attr, -#ifndef ENABLE_NOISE_TEST_MODE - &dev_attr_threshold.attr, - &dev_attr_set_all_refer.attr, - &dev_attr_set_refer0.attr, - &dev_attr_set_delta0.attr, - &dev_attr_set_refer1.attr, - &dev_attr_set_delta1.attr, - &dev_attr_set_refer2.attr, - &dev_attr_set_delta2.attr, - &dev_attr_set_refer3.attr, - &dev_attr_set_delta3.attr, - &dev_attr_set_refer4.attr, - &dev_attr_set_delta4.attr, -#endif - NULL, -}; - -static struct attribute_group sec_touch_attr_group = { - .attrs = sec_touch_attributes, -}; - -#ifdef ENABLE_NOISE_TEST_MODE -static struct attribute *sec_touch_facotry_attributes[] = { - &dev_attr_set_all_refer.attr, - &dev_attr_set_refer0.attr, - &dev_attr_set_delta0.attr, - &dev_attr_set_refer1.attr, - &dev_attr_set_delta1.attr, - &dev_attr_set_refer2.attr, - &dev_attr_set_delta2.attr, - &dev_attr_set_refer3.attr, - &dev_attr_set_delta3.attr, - &dev_attr_set_refer4.attr, - &dev_attr_set_delta4.attr, - &dev_attr_set_threshould.attr, - &dev_attr_tsp_power.attr, - &dev_attr_tsp_info.attr, - &dev_attr_tsp_x_line.attr, - &dev_attr_tsp_y_line.attr, - &dev_attr_set_debug_data1.attr, - &dev_attr_set_debug_data2.attr, - &dev_attr_set_debug_data3.attr, - &dev_attr_set_index_ref.attr, - &dev_attr_show_reference_info.attr, - &dev_attr_show_inspection_info.attr, - &dev_attr_show_intensity_info.attr, - NULL, -}; - -static struct attribute_group sec_touch_factory_attr_group = { - .attrs = sec_touch_facotry_attributes, -}; -#endif - - -static int melfas_ts_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - - struct ts_platform_data *pdata = client->dev.platform_data; - struct melfas_ts_data *ts; - struct device *tsp_dev; - -#ifdef ENABLE_NOISE_TEST_MODE - struct device *test_dev; -#endif - - int ret = 0, i, irq; - const char buf; - -#if DEBUG_PRINT - pr_err("[TSP] kim ms : melfas_ts_probe\n"); -#endif - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - pr_err("[TSP] melfas_ts_probe: need I2C_FUNC_I2C\n"); - ret = -ENODEV; - goto err_check_functionality_failed; - } - - ts = kmalloc(sizeof(struct melfas_ts_data), GFP_KERNEL); - if (ts == NULL) { - pr_err("[TSP] failed to create a state of melfas-ts"); - ret = -ENOMEM; - goto err_alloc_data_failed; - } - - ts->pdata = client->dev.platform_data; - - ts->power_on = pdata->power_on; - ts->power_off = pdata->power_off; - ts->read_ta_status = pdata->read_ta_status; - ts->set_touch_i2c = pdata->set_touch_i2c; - ts->set_touch_i2c_to_gpio = pdata->set_touch_i2c_to_gpio; - ts->touch_id = pdata->gpio_touch_id; - ts->tsp_status = true; - - mutex_init(&ts->m_lock); - - ts->cb.inform_charger = inform_charger_connection; - if (pdata->register_cb) - pdata->register_cb(&ts->cb); - - /* reset chip */ - gpio_set_value(GPIO_TSP_RST, 0); - msleep(200); - gpio_set_value(GPIO_TSP_RST, 1); - msleep(100); - - - ts->client = client; - i2c_set_clientdata(client, ts); - ret = i2c_master_send(ts->client, &buf, 1); - - -#if DEBUG_PRINT - pr_err("[TSP] melfas_ts_probe: i2c_master_send() [%d], Add[%d]\n", - ret, ts->client->addr); -#endif - - ret = firmware_update(ts); - - ts->input_dev = input_allocate_device(); - if (!ts->input_dev) { - pr_err("[TSP] melfas_ts_probe: Not enough memory\n"); - ret = -ENOMEM; - goto err_input_dev_alloc_failed; - } - - ts->input_dev->name = "sec_touchscreen" ; - - __set_bit(EV_ABS, ts->input_dev->evbit); - __set_bit(EV_KEY, ts->input_dev->evbit); - - input_mt_init_slots(ts->input_dev, MELFAS_MAX_TOUCH); - input_set_abs_params(ts->input_dev, - ABS_MT_POSITION_X, 0, TS_MAX_X_COORD, 0, 0); - input_set_abs_params(ts->input_dev, - ABS_MT_POSITION_Y, 0, TS_MAX_Y_COORD, 0, 0); - input_set_abs_params(ts->input_dev, - ABS_MT_TOUCH_MAJOR, 0, TS_MAX_Z_TOUCH, 0, 0); - input_set_abs_params(ts->input_dev, - ABS_MT_WIDTH_MAJOR, 0, TS_MAX_W_TOUCH, 0, 0); - - __set_bit(MT_TOOL_FINGER, ts->input_dev->keybit); - __set_bit(EV_SYN, ts->input_dev->evbit); - __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); - - - - ret = input_register_device(ts->input_dev); - if (ret) { - pr_err("[TSP] melfas_ts_probe: Failed to register device\n"); - ret = -ENOMEM; - goto err_input_register_device_failed; - } - - if (ts->client->irq) { - irq = ts->client->irq; - - ret = request_threaded_irq(irq, NULL, melfas_ts_irq_handler, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - ts->client->name, ts); - if (ret) { - pr_err("[TSP] %s: Can't allocate irq %d, ret %d\n", - __func__, irq, ret); - ret = -EBUSY; - goto err_request_irq; - } - } - -#if TOUCH_BOOSTER - INIT_DELAYED_WORK(&ts->dvfs_work, free_dvfs_lock); - ts->cpufreq_level = -1; - ts->dvfs_lock_status = false; -#endif - - for (i = 0; i < MELFAS_MAX_TOUCH; i++) - ts->finger_state[i] = TSP_STATE_RELEASE; - -#if DEBUG_PRINT - pr_err("[TSP] melfas_ts_probe: succeed to register input device\n"); -#endif - -/* ---------------------- */ - tsp_dev = device_create(sec_class, NULL, 0, ts, "sec_touchscreen"); - if (IS_ERR(tsp_dev)) - pr_err("[TSP] Failed to create device for the sysfs\n"); - - ret = sysfs_create_group(&tsp_dev->kobj, &sec_touch_attr_group); - if (ret) - pr_err("[TSP] Failed to create sysfs group\n"); -/* ----------------------- */ - -#ifdef ENABLE_NOISE_TEST_MODE - test_dev = device_create(sec_class, NULL, 0, ts, "tsp_noise_test"); - if (IS_ERR(test_dev)) { - pr_err("Failed to create device for the factory test\n"); - ret = -ENODEV; - } - - ret = sysfs_create_group(&test_dev->kobj, - &sec_touch_factory_attr_group); - if (ret) - pr_err("Failed to create sysfs group for the factory test\n"); -#endif - - -#if CONFIG_HAS_EARLYSUSPEND - ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; - ts->early_suspend.suspend = melfas_ts_early_suspend; - ts->early_suspend.resume = melfas_ts_late_resume; - register_early_suspend(&ts->early_suspend); -#endif - -#if DEBUG_PRINT - pr_info("melfas_ts_probe: Start touchscreen. name: %s, irq: %d\n", - ts->client->name, ts->client->irq); -#endif - return 0; - -err_request_irq: - pr_err("[TSP] melfas-ts: err_request_irq failed\n"); - free_irq(client->irq, ts); -err_input_register_device_failed: - pr_err("[TSP] melfas-ts: err_input_register_device failed\n"); - input_free_device(ts->input_dev); -err_input_dev_alloc_failed: - pr_err("[TSP] melfas-ts: err_input_dev_alloc failed\n"); -err_alloc_data_failed: - pr_err("[TSP] melfas-ts: err_alloc_data failed_\n"); - kfree(ts); -err_check_functionality_failed: - pr_err("[TSP] melfas-ts: err_check_functionality failed_\n"); - - return ret; -} - -static int melfas_ts_remove(struct i2c_client *client) -{ - struct melfas_ts_data *ts = i2c_get_clientdata(client); - - unregister_early_suspend(&ts->early_suspend); - free_irq(client->irq, ts); - input_unregister_device(ts->input_dev); - kfree(ts); - return 0; -} - -static int melfas_ts_suspend(struct i2c_client *client, pm_message_t mesg) -{ - char buf[2]; - struct melfas_ts_data *ts = i2c_get_clientdata(client); - ts->tsp_status = false; - -#ifdef DEBUG_MODE - if (debug_on) { - pr_info("[TSP] Out of debug-mode before suspend "); - buf[0] = ADDR_CHANGE_PROTOCOL; - buf[1] = 11; - debug_i2c_write(ts->client, buf, 2); - debug_on = false; - msleep(150); - } -#endif - - disable_irq(ts->client->irq); - release_all_fingers(ts); - - ts->power_off(); - - return 0; -} - -static int melfas_ts_resume(struct i2c_client *client) -{ - struct melfas_ts_data *ts = i2c_get_clientdata(client); - int ta_status = ts->charging_status; - char buf[2]; - - ts->power_on(); - msleep(100); - - if (ta_status) { - buf[0] = TS_TA_STAT_ADDR; - buf[1] = ta_status; - melfas_i2c_write(ts->client, (char *)buf, 2); - msleep(150); - } - - enable_irq(ts->client->irq); - pr_info("[TSP] melfas_ts_resume TA %sconnection", - ta_status ? "" : "dis"); - - ts->tsp_status = true; - - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void melfas_ts_early_suspend(struct early_suspend *h) -{ - struct melfas_ts_data *ts; - ts = container_of(h, struct melfas_ts_data, early_suspend); - melfas_ts_suspend(ts->client, PMSG_SUSPEND); -} - -static void melfas_ts_late_resume(struct early_suspend *h) -{ - struct melfas_ts_data *ts; - ts = container_of(h, struct melfas_ts_data, early_suspend); - melfas_ts_resume(ts->client); -} -#endif - -static const struct i2c_device_id melfas_ts_id[] = { - { TS_DEV_NAME, 0 }, - { } -}; - -static struct i2c_driver melfas_ts_driver = { - .driver = { - .name = TS_DEV_NAME, - }, - .id_table = melfas_ts_id, - .probe = melfas_ts_probe, - .remove = __devexit_p(melfas_ts_remove), -#ifndef CONFIG_HAS_EARLYSUSPEND - .suspend = melfas_ts_suspend, - .resume = melfas_ts_resume, -#endif -}; - -static int __devinit melfas_ts_init(void) -{ - return i2c_add_driver(&melfas_ts_driver); -} - -static void __exit melfas_ts_exit(void) -{ - i2c_del_driver(&melfas_ts_driver); -} - -MODULE_DESCRIPTION("Driver for Melfas MTSI Touchscreen Controller"); -MODULE_AUTHOR("MinSang, Kim <kimms@melfas.com>"); -MODULE_VERSION("0.1"); -MODULE_LICENSE("GPL"); - -module_init(melfas_ts_init); -module_exit(melfas_ts_exit); |