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.c3115
1 files changed, 0 insertions, 3115 deletions
diff --git a/drivers/input/touchscreen/mms_ts_gc.c b/drivers/input/touchscreen/mms_ts_gc.c
deleted file mode 100644
index 7efe079..0000000
--- a/drivers/input/touchscreen/mms_ts_gc.c
+++ /dev/null
@@ -1,3115 +0,0 @@
-/*
- * mms_ts.c - Touchscreen driver for Melfas MMS-series touch controllers
- *
- * Copyright (C) 2011 Google Inc.
- * Author: Dima Zavin <dima@android.com>
- * Simon Wilson <simonwilson@google.com>
- *
- * ISP reflashing code based on original code from Melfas.
- * ISC reflashing code based on original code from Melfas.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#define SHOW_COORD 1
-#define FW_UPDATABLE 1
-#define ISC_DL_MODE 1
-#define TOUCH_BOOSTER 1
-#define SEC_TSP_FACTORY_TEST 1
-/* #define ESD_DEBUG */
-
-#include <linux/delay.h>
-#include <linux/earlysuspend.h>
-#include <linux/firmware.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/input.h>
-#include <linux/input/mt.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <mach/gpio.h>
-#include <linux/uaccess.h>
-#include <linux/platform_data/mms_ts_gc.h>
-#include <asm/unaligned.h>
-#include <linux/fb.h>
-#if TOUCH_BOOSTER
-#include <mach/cpufreq.h>
-#include <mach/dev.h>
-#endif
-
-#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 MAX_ANGLE 90
-#define MIN_ANGLE -90
-
-/* Registers */
-#define MMS_INPUT_EVENT_PKT_SZ 0x0F
-#define MMS_INPUT_EVENT0 0x10
-
-#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,
- TSP_STATE_PRESS,
- TSP_STATE_MOVE,
-};
-
-#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 */
-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,
- REQ_FW,
-};
-
-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,
- ISC_FILE_CLOSE_ERROR,
- ISC_FILE_FORMAT_ERROR,
- ISC_WRITE_BUFFER_ERROR,
- ISC_I2C_ERROR,
- ISC_UPDATE_MODE_ENTER_ERROR,
- ISC_CRC_ERROR,
- ISC_VALIDATION_ERROR,
- ISC_COMPATIVILITY_ERROR,
- ISC_UPDATE_SECTION_ERROR,
- ISC_SLAVE_ERASE_ERROR,
- ISC_SLAVE_DOWNLOAD_ERROR,
- ISC_DOWNLOAD_WHEN_SLAVE_IS_UPDATED_ERROR,
- ISC_INITIAL_PACKET_ERROR,
- ISC_NO_NEED_UPDATE_ERROR,
- ISC_LIMIT
-};
-
-enum {
- EC_NONE = -1,
- EC_DEPRECATED = 0,
- EC_BOOTLOADER_RUNNING = 1,
- EC_BOOT_ON_SUCCEEDED = 2,
- EC_ERASE_END_MARKER_ON_SLAVE_FINISHED = 3,
- EC_SLAVE_DOWNLOAD_STARTS = 4,
- EC_SLAVE_DOWNLOAD_FINISHED = 5,
- EC_2CHIP_HANDSHAKE_FAILED = 0x0E,
- EC_ESD_PATTERN_CHECKED = 0x0F,
- EC_LIMIT
-};
-
-enum {
- SEC_NONE = -1,
- SEC_BOOTLOADER = 0,
- SEC_CORE,
- SEC_PRIVATE_CONFIG,
- SEC_PUBLIC_CONFIG,
- SEC_LIMIT
-};
-
-struct tISCFWInfo_t {
- unsigned char version;
- unsigned char compatible_version;
- unsigned char start_addr;
- unsigned char end_addr;
-};
-
-/*
- * Default configuration of ISC mode
- */
-#define DEFAULT_SLAVE_ADDR 0x48
-
-#define SECTION_NUM 4
-#define SECTION_NAME_LEN 5
-
-#define PAGE_HEADER 3
-#define PAGE_DATA 1024
-#define PAGE_TAIL 2
-#define PACKET_SIZE (PAGE_HEADER + PAGE_DATA + PAGE_TAIL)
-#define TS_WRITE_REGS_LEN 1030
-
-#define TIMEOUT_CNT 10
-#define STRING_BUF_LEN 100
-
-/* State Registers */
-#define MIP_ADDR_INPUT_INFORMATION 0x01
-#define ISC_ADDR_VERSION 0xE1
-#define ISC_ADDR_SECTION_PAGE_INFO 0xE5
-
-/* Config Update Commands */
-#define ISC_CMD_ENTER_ISC 0x5F
-#define ISC_CMD_ENTER_ISC_PARA1 0x01
-#define ISC_CMD_UPDATE_MODE 0xAE
-#define ISC_SUBCMD_ENTER_UPDATE 0x55
-#define ISC_SUBCMD_DATA_WRITE 0XF1
-#define ISC_SUBCMD_LEAVE_UPDATE_PARA1 0x0F
-#define ISC_SUBCMD_LEAVE_UPDATE_PARA2 0xF0
-#define ISC_CMD_CONFIRM_STATUS 0xAF
-
-#define ISC_STATUS_UPDATE_MODE 0x01
-#define ISC_STATUS_CRC_CHECK_SUCCESS 0x03
-
-#define ISC_CHAR_2_BCD(num) (((num/10)<<4) + (num%10))
-#define ISC_MAX(x, y) (((x) > (y)) ? (x) : (y))
-
-static const char section_name[SECTION_NUM][SECTION_NAME_LEN] = {
- "BOOT", "CORE", "PRIV", "PUBL"
-};
-
-static const unsigned char crc0_buf[31] = {
- 0x1D, 0x2C, 0x05, 0x34, 0x95, 0xA4, 0x8D, 0xBC,
- 0x59, 0x68, 0x41, 0x70, 0xD1, 0xE0, 0xC9, 0xF8,
- 0x3F, 0x0E, 0x27, 0x16, 0xB7, 0x86, 0xAF, 0x9E,
- 0x7B, 0x4A, 0x63, 0x52, 0xF3, 0xC2, 0xEB
-};
-
-static const unsigned char crc1_buf[31] = {
- 0x1E, 0x9C, 0xDF, 0x5D, 0x76, 0xF4, 0xB7, 0x35,
- 0x2A, 0xA8, 0xEB, 0x69, 0x42, 0xC0, 0x83, 0x01,
- 0x04, 0x86, 0xC5, 0x47, 0x6C, 0xEE, 0xAD, 0x2F,
- 0x30, 0xB2, 0xF1, 0x73, 0x58, 0xDA, 0x99
-};
-
-static struct tISCFWInfo_t mbin_info[SECTION_NUM]; /* F/W ver from File */
-static struct tISCFWInfo_t ts_info[SECTION_NUM]; /* F/W ver from IC */
-static bool section_update_flag[SECTION_NUM];
-const struct firmware *fw_mbin[SECTION_NUM];
-static unsigned char g_wr_buf[1024 + 3 + 2];
-
-#endif /* ISC_DL_MODE end */
-
-enum {
- ISP_MODE_FLASH_ERASE = 0x59F3,
- ISP_MODE_FLASH_WRITE = 0x62CD,
- ISP_MODE_FLASH_READ = 0x6AC9,
-};
-
-/* each address addresses 4-byte words */
-#define ISP_MAX_FW_SIZE (0x1F00 * 4)
-#define ISP_IC_INFO_ADDR 0x1F00
-
-#if SEC_TSP_FACTORY_TEST
-#define TSP_BUF_SIZE 1024
-
-/* VSC(Vender Specific Command) */
-#define MMS_VSC_CMD 0xB0 /* vendor specific command */
-#define MMS_VSC_MODE 0x1A /* mode of vendor */
-
-#define MMS_VSC_CMD_ENTER 0X01
-#define MMS_VSC_CMD_CM_DELTA 0X02
-#define MMS_VSC_CMD_CM_ABS 0X03
-#define MMS_VSC_CMD_EXIT 0X05
-#define MMS_VSC_CMD_INTENSITY 0X04
-#define MMS_VSC_CMD_RAW 0X06
-#define MMS_VSC_CMD_REFER 0X07
-
-#define TSP_CMD_STR_LEN 32
-#define TSP_CMD_RESULT_STR_LEN 512
-#define TSP_CMD_PARAM_NUM 8
-
-enum {
- FAIL_PWR_CONTROL = -1,
- SUCCESS_PWR_CONTROL = 0,
-};
-
-enum { /* this is using by cmd_state valiable. */
- WAITING = 0,
- RUNNING,
- OK,
- FAIL,
- NOT_APPLICABLE,
-};
-#endif /* SEC_TSP_FACTORY_TEST */
-
-struct tsp_callbacks {
- void (*inform_charger)(struct tsp_callbacks *tsp_cb, bool mode);
-};
-
-struct mms_ts_info {
- struct i2c_client *client;
- struct input_dev *input_dev;
- char phys[32];
- int max_x;
- int max_y;
- bool invert_x;
- bool invert_y;
- int irq;
- int (*power) (int on);
- 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];
-
- struct melfas_tsi_platform_data *pdata;
- struct early_suspend early_suspend;
- struct mutex lock;
-
- void (*register_cb)(void *);
- struct tsp_callbacks callbacks;
- bool ta_status;
- bool noise_mode;
-
-#if TOUCH_BOOSTER
- struct delayed_work work_dvfs_off;
- struct delayed_work work_dvfs_chg;
- bool dvfs_lock_status;
- int cpufreq_level;
- struct mutex dvfs_lock;
- struct device *bus_dev;
- struct device *sec_touchscreen;
-#endif /* TOUCH_BOOSTER */
-
-#if SEC_TSP_FACTORY_TEST
- struct list_head cmd_list_head;
- u8 cmd_state;
- char cmd[TSP_CMD_STR_LEN];
- int cmd_param[TSP_CMD_PARAM_NUM];
- char cmd_result[TSP_CMD_RESULT_STR_LEN];
- struct mutex cmd_lock;
- bool cmd_is_running;
- bool ft_flag;
- unsigned int *reference;
- unsigned int *cm_abs;
- unsigned int *cm_delta;
- unsigned int *intensity;
-#endif /* SEC_TSP_FACTORY_TEST */
-};
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static void mms_ts_early_suspend(struct early_suspend *h);
-static void mms_ts_late_resume(struct early_suspend *h);
-#endif
-
-#if SEC_TSP_FACTORY_TEST
-#define TSP_CMD(name, func) .cmd_name = name, .cmd_func = func
-
-struct tsp_cmd {
- struct list_head list;
- const char *cmd_name;
- void (*cmd_func)(void *device_data);
-};
-
-static void fw_update(void *device_data);
-static void get_fw_ver_bin(void *device_data);
-static void get_fw_ver_ic(void *device_data);
-static void get_config_ver(void *device_data);
-static void get_threshold(void *device_data);
-static void module_off_master(void *device_data);
-static void module_on_master(void *device_data);
-static void module_off_slave(void *device_data);
-static void module_on_slave(void *device_data);
-static void get_chip_vendor(void *device_data);
-static void get_chip_name(void *device_data);
-static void get_reference(void *device_data);
-static void get_cm_abs(void *device_data);
-static void get_cm_delta(void *device_data);
-static void get_intensity(void *device_data);
-static void get_x_num(void *device_data);
-static void get_y_num(void *device_data);
-static void run_reference_read(void *device_data);
-static void run_cm_abs_read(void *device_data);
-static void run_cm_delta_read(void *device_data);
-static void run_intensity_read(void *device_data);
-static void not_support_cmd(void *device_data);
-
-struct tsp_cmd tsp_cmds[] = {
- {TSP_CMD("fw_update", fw_update),},
- {TSP_CMD("get_fw_ver_bin", get_fw_ver_bin),},
- {TSP_CMD("get_fw_ver_ic", get_fw_ver_ic),},
- {TSP_CMD("get_config_ver", get_config_ver),},
- {TSP_CMD("get_threshold", get_threshold),},
- {TSP_CMD("module_off_master", module_off_master),},
- {TSP_CMD("module_on_master", module_on_master),},
- {TSP_CMD("module_off_slave", not_support_cmd),},
- {TSP_CMD("module_on_slave", not_support_cmd),},
- {TSP_CMD("get_chip_vendor", get_chip_vendor),},
- {TSP_CMD("get_chip_name", get_chip_name),},
- {TSP_CMD("get_x_num", get_x_num),},
- {TSP_CMD("get_y_num", get_y_num),},
- {TSP_CMD("get_reference", get_reference),},
- {TSP_CMD("get_cm_abs", get_cm_abs),},
- {TSP_CMD("get_cm_delta", get_cm_delta),},
- {TSP_CMD("get_intensity", get_intensity),},
- {TSP_CMD("run_reference_read", run_reference_read),},
- {TSP_CMD("run_cm_abs_read", run_cm_abs_read),},
- {TSP_CMD("run_cm_delta_read", run_cm_delta_read),},
- {TSP_CMD("run_intensity_read", run_intensity_read),},
- {TSP_CMD("not_support_cmd", not_support_cmd),},
-};
-#endif
-
-#if ISC_DL_MODE
-
-u8 *tsp_firmware_file[4] = {0, };
-
-static int mms100_i2c_read(struct i2c_client *client,
- u16 addr, u16 length, u8 *value)
-{
- struct i2c_adapter *adapter = client->adapter;
- struct i2c_msg msg;
- int ret = -1;
-
- msg.addr = client->addr;
- msg.flags = 0x00;
- msg.len = 1;
- msg.buf = (u8 *) &addr;
-
- ret = i2c_transfer(adapter, &msg, 1);
-
- if (ret >= 0) {
- msg.addr = client->addr;
- msg.flags = I2C_M_RD;
- msg.len = length;
- msg.buf = (u8 *) value;
-
- ret = i2c_transfer(adapter, &msg, 1);
- }
-
- if (ret < 0)
- ISC_DL_MSG("[TSP ISC] i2c read error : [%d]\n", ret);
-
- return ret;
-}
-
-
-static int mms100_reset(struct i2c_client *client)
-{
- struct mms_ts_info *info = i2c_get_clientdata(client);
-
- info->pdata->power(false);
- msleep(30);
- info->pdata->power(true);
- msleep(300);
-
- return ISC_SUCCESS;
-}
-/*
-static int mms100_check_operating_mode(struct i2c_client *_client,
- const int _error_code)
-{
- int ret;
- unsigned char rd_buf = 0x00;
- unsigned char count = 0;
-
- if(_client == NULL)
- pr_err("[TSP ISC] _client is null");
-
- ret = mms100_i2c_read(_client, ISC_ADDR_VERSION, 1, &rd_buf);
-
- if (ret<0) {
- pr_info("[TSP ISC] %s,%d: i2c read fail[%d]\n",
- __func__, __LINE__, ret);
- return _error_code;
- }
-
- return ISC_SUCCESS;
-}
-*/
-static int mms100_get_version_info(struct i2c_client *_client)
-{
- int i, ret;
- unsigned char rd_buf[8];
-
- /* config version brust read (core, private, public) */
- ret = mms100_i2c_read(_client, ISC_ADDR_VERSION, 4, rd_buf);
-
- if (ret < 0) {
- ISC_DL_MSG("[TSP ISC] %s,%d: i2c read fail[%d]\n",
- __func__, __LINE__, ret);
- return ISC_I2C_ERROR;
- }
-
- for (i = 0; i < SECTION_NUM; i++)
- ts_info[i].version = rd_buf[i];
-
- ts_info[SEC_CORE].compatible_version =
- ts_info[SEC_BOOTLOADER].version;
- ts_info[SEC_PRIVATE_CONFIG].compatible_version =
- ts_info[SEC_PUBLIC_CONFIG].compatible_version =
- ts_info[SEC_CORE].version;
-
- ret = mms100_i2c_read(_client, ISC_ADDR_SECTION_PAGE_INFO, 8, rd_buf);
-
- if (ret < 0) {
- ISC_DL_MSG("[TSP ISC] %s,%d: i2c read fail[%d]\n",
- __func__, __LINE__, ret);
- return ISC_I2C_ERROR;
- }
-
- for (i = 0; i < SECTION_NUM; i++) {
- ts_info[i].start_addr = rd_buf[i];
- ts_info[i].end_addr = rd_buf[i + SECTION_NUM];
- }
-
- 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;
-}
-
-static int mms100_seek_section_info(void)
-{
- int i;
- char str_buf[STRING_BUF_LEN];
- char name_buf[SECTION_NAME_LEN];
- int version;
- int page_num;
-
- const unsigned char *buf;
- int next_ptr;
-
- for (i = 0; i < SECTION_NUM; i++) {
- if (tsp_firmware_file[i] == NULL) {
- buf = NULL;
- ISC_DL_MSG("[TSP ISC] F/W file[%d] is NULL\n", i);
- } else
- buf = tsp_firmware_file[i];
-
- if (buf == NULL) {
- mbin_info[i].version = ts_info[i].version;
- mbin_info[i].compatible_version =
- ts_info[i].compatible_version;
- mbin_info[i].start_addr = ts_info[i].start_addr;
- mbin_info[i].end_addr = ts_info[i].end_addr;
- } else {
- next_ptr = 0;
-
- do {
- sscanf(buf + next_ptr, "%s", str_buf);
- next_ptr += strlen(str_buf) + 1;
- } while (!strstr(str_buf, "SECTION_NAME"));
-
- sscanf(buf + next_ptr, "%s%s", str_buf, name_buf);
-
- if (strncmp(section_name[i], name_buf,
- SECTION_NAME_LEN))
- return ISC_FILE_FORMAT_ERROR;
-
- do {
- sscanf(buf + next_ptr, "%s", str_buf);
- next_ptr += strlen(str_buf) + 1;
- } while (!strstr(str_buf, "SECTION_VERSION"));
-
- sscanf(buf + next_ptr, "%s%d", str_buf, &version);
- mbin_info[i].version = ISC_CHAR_2_BCD(version);
-
- do {
- sscanf(buf + next_ptr, "%s", str_buf);
- next_ptr += strlen(str_buf) + 1;
- } while (!strstr(str_buf, "START_PAGE_ADDR"));
-
- sscanf(buf + next_ptr, "%s%d", str_buf, &page_num);
- mbin_info[i].start_addr = page_num;
-
- do {
- sscanf(buf + next_ptr, "%s", str_buf);
- next_ptr += strlen(str_buf) + 1;
- } while (!strstr(str_buf, "END_PAGE_ADDR"));
-
- sscanf(buf + next_ptr, "%s%d", str_buf, &page_num);
- mbin_info[i].end_addr = page_num;
-
- do {
- sscanf(buf + next_ptr, "%s", str_buf);
- next_ptr += strlen(str_buf) + 1;
- } while (!strstr(str_buf, "COMPATIBLE_VERSION"));
-
- sscanf(buf + next_ptr, "%s%d", str_buf, &version);
- mbin_info[i].compatible_version =
- ISC_CHAR_2_BCD(version);
-
- do {
- sscanf(buf + next_ptr, "%s", str_buf);
- next_ptr += strlen(str_buf) + 1;
- } while (!strstr(str_buf, "[Binary]"));
-
- if (mbin_info[i].version == 0xFF)
- return ISC_FILE_FORMAT_ERROR;
- }
- }
-
- 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;
-}
-
-static int mms100_compare_version_info(struct i2c_client *_client,
- bool forced_update)
-{
- int i, ret;
- unsigned char expected_compatibility[SECTION_NUM];
-
- if (mms100_get_version_info(_client) != ISC_SUCCESS)
- return ISC_I2C_ERROR;
-
- ret = mms100_seek_section_info();
- if (ret)
- return ret;
-
- section_update_flag[0] = false;
- /* 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))
- section_update_flag[i] = true;
- }
- if (forced_update) {
- section_update_flag[SEC_CORE] = true;
- section_update_flag[SEC_PRIVATE_CONFIG] = true;
- section_update_flag[SEC_PUBLIC_CONFIG] = true;
- ISC_DL_MSG("[TSP ISC] forced_update enable!\n");
- }
- 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]);
-
- if (section_update_flag[SEC_BOOTLOADER]) {
- expected_compatibility[SEC_CORE] =
- mbin_info[SEC_BOOTLOADER].version;
- } else {
- expected_compatibility[SEC_CORE] =
- ts_info[SEC_BOOTLOADER].version;
- }
-
- if (section_update_flag[SEC_CORE]) {
- expected_compatibility[SEC_PUBLIC_CONFIG] =
- expected_compatibility[SEC_PRIVATE_CONFIG] =
- mbin_info[SEC_CORE].version;
- } else {
- expected_compatibility[SEC_PUBLIC_CONFIG] =
- expected_compatibility[SEC_PRIVATE_CONFIG] =
- ts_info[SEC_CORE].version;
- }
-
- 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;
-}
-
-static int mms100_enter_ISC_mode(struct i2c_client *_client)
-{
- int ret;
- unsigned char wr_buf[2];
-
- 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) {
- ISC_DL_MSG("[TSP ISC] %s,%d: i2c write fail[%d]\n",
- __func__, __LINE__, ret);
- return ISC_I2C_ERROR;
- }
-
- msleep(50);
-
- return ISC_SUCCESS;
-}
-
-static int mms100_enter_config_update(struct i2c_client *_client)
-{
- int ret;
- unsigned char wr_buf[10] = {0,};
- unsigned char rd_buf;
-
- wr_buf[0] = ISC_CMD_UPDATE_MODE;
- wr_buf[1] = ISC_SUBCMD_ENTER_UPDATE;
-
- ret = i2c_master_send(_client, wr_buf, 10);
-
- if (ret < 0) {
- 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) {
- ISC_DL_MSG("[TSP ISC] %s,%d: i2c read fail[%d]\n",
- __func__, __LINE__, ret);
- return ISC_I2C_ERROR;
- }
-
- if (rd_buf != ISC_STATUS_UPDATE_MODE)
- return ISC_UPDATE_MODE_ENTER_ERROR;
-
- return ISC_SUCCESS;
-}
-
-static int mms100_ISC_clear_page(struct i2c_client *_client,
- unsigned char _page_addr)
-{
- int ret;
- unsigned char rd_buf;
-
- memset(&g_wr_buf[3], 0xFF, PAGE_DATA);
-
- g_wr_buf[0] = ISC_CMD_UPDATE_MODE; /* command */
- g_wr_buf[1] = ISC_SUBCMD_DATA_WRITE; /* sub_command */
- g_wr_buf[2] = _page_addr;
-
- g_wr_buf[PAGE_HEADER + PAGE_DATA] = crc0_buf[_page_addr];
- g_wr_buf[PAGE_HEADER + PAGE_DATA + 1] = crc1_buf[_page_addr];
-
- ret = i2c_master_send(_client, g_wr_buf, PACKET_SIZE);
-
- if (ret < 0) {
- 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) {
- ISC_DL_MSG("[TSP ISC] %s,%d: i2c read fail[%d]\n",
- __func__, __LINE__, ret);
- return ISC_I2C_ERROR;
- }
-
- if (rd_buf != ISC_STATUS_CRC_CHECK_SUCCESS)
- return ISC_UPDATE_MODE_ENTER_ERROR;
-
- return ISC_SUCCESS;
-}
-
-static int mms100_ISC_clear_validate_markers(struct i2c_client *_client)
-{
- int ret_msg;
- int i, j;
- bool is_matched_address;
-
- for (i = SEC_CORE; i <= SEC_PUBLIC_CONFIG; i++) {
- if (section_update_flag[i]) {
- if (ts_info[i].end_addr <= 30 &&
- ts_info[i].end_addr > 0) {
- ret_msg = mms100_ISC_clear_page(_client,
- ts_info[i].end_addr);
-
- if (ret_msg != ISC_SUCCESS)
- return ret_msg;
- }
- }
- }
-
- for (i = SEC_CORE; i <= SEC_PUBLIC_CONFIG; i++) {
- if (section_update_flag[i]) {
- is_matched_address = false;
- for (j = SEC_CORE; j <= SEC_PUBLIC_CONFIG; j++) {
- if (mbin_info[i].end_addr ==
- ts_info[i].end_addr) {
- is_matched_address = true;
- break;
- }
- }
-
- if (!is_matched_address) {
- if (mbin_info[i].end_addr <= 30 &&
- mbin_info[i].end_addr > 0) {
- ret_msg = mms100_ISC_clear_page(_client,
- mbin_info[i].end_addr);
-
- if (ret_msg != ISC_SUCCESS)
- return ret_msg;
- }
- }
- }
- }
-
- return ISC_SUCCESS;
-}
-
-static int mms100_update_section_data(struct i2c_client *_client)
-{
- int i, ret, next_ptr;
- unsigned char rd_buf;
- const unsigned char *ptr_fw;
- char str_buf[STRING_BUF_LEN];
- int page_addr;
-
- for (i = 0; i < SECTION_NUM; i++) {
- if (section_update_flag[i]) {
- ISC_DL_MSG("[TSP ISC] %d section data i2c flash\n", i);
-
- next_ptr = 0;
- ptr_fw = tsp_firmware_file[i];
-
- do {
- sscanf(ptr_fw + next_ptr, "%s", str_buf);
- next_ptr += strlen(str_buf) + 1;
- } while (!strstr(str_buf, "[Binary]"));
- ptr_fw = ptr_fw + next_ptr + 2;
-
- for (page_addr = mbin_info[i].start_addr;
- page_addr <= mbin_info[i].end_addr;
- page_addr++) {
- if (page_addr - mbin_info[i].start_addr > 0)
- ptr_fw += PACKET_SIZE;
-
- if ((ptr_fw[0] != ISC_CMD_UPDATE_MODE) ||
- (ptr_fw[1] != ISC_SUBCMD_DATA_WRITE) ||
- (ptr_fw[2] != page_addr))
- return ISC_WRITE_BUFFER_ERROR;
-
- ret = i2c_master_send(_client,
- ptr_fw, PACKET_SIZE);
- if (ret < 0) {
- 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) {
- ISC_DL_MSG("[TSP ISC] %s,%d: i2c read fail[%d]\n",
- __func__, __LINE__, ret);
- return ISC_I2C_ERROR;
- }
-
- if (rd_buf != ISC_STATUS_CRC_CHECK_SUCCESS)
- return ISC_CRC_ERROR;
-
- section_update_flag[i] = false;
- }
- }
- }
- return ISC_SUCCESS;
-}
-
-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;
- 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, "%s%c_%s.fw",
- FW_DIRECTORY, panel_type, section_name[i]);
- ret = request_firmware(&(fw_mbin[i]), fw_path,
- &_client->dev);
- if (ret) {
- ISC_DL_MSG("[TSP ISC] fail REQ_FW[%s]\n",
- fw_path);
- break;
- }
-
- tsp_firmware_file[i] = kzalloc((size_t)fw_mbin[i]->size,
- GFP_KERNEL);
-
- if (!tsp_firmware_file[i])
- 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);
-
- if (fw_mbin[i] != NULL)
- release_firmware(fw_mbin[i]);
- }
- if (!ret)
- ISC_DL_MSG("[TSP ISC] All REQ_FW is loaded!\n");
- } else if (mode == UMS) {
-
- old_fs = get_fs();
- set_fs(get_ds());
-
- for (i = SEC_CORE ; i <= SEC_PUBLIC_CONFIG ; i++) {
- snprintf(fw_path, MAX_FW_PATH, "/sdcard/%s.mbin",
- section_name[i]);
- fp = filp_open(fw_path, O_RDONLY, 0);
- if (IS_ERR(fp)) {
- ISC_DL_MSG("[TSP ISC] file %s open error:%d\n",
- fw_path, (s32)fp);
- set_fs(old_fs);
- return ISC_FILE_OPEN_ERROR;
- }
-
- fsize = fp->f_path.dentry->d_inode->i_size;
-
- tsp_firmware_file[i] = kzalloc((size_t)fsize,
- GFP_KERNEL);
- if (!tsp_firmware_file[i]) {
- 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) {
- ISC_DL_MSG("[TSP ISC] nread != fsize error\n");
- ret = ISC_FILE_OPEN_ERROR;
- }
-
- filp_close(fp, current->files);
- }
-
- set_fs(old_fs);
- if (!ret)
- ISC_DL_MSG("[TSP ISC] ums fw is loaded!\n");
- } else {
- ISC_DL_MSG("[TSP ISC] Not support mode[%d]\n", mode);
- ret = ISC_FILE_OPEN_ERROR;
- }
-
- if (!ret)
- return ISC_SUCCESS;
- else {
- ISC_DL_MSG("[TSP ISC] mms100_open_mbinary fail\n");
- return ret;
- }
-}
-
-int mms100_ISC_download_mbinary(struct i2c_client *_client, int mode,
- 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!");
-
-/*
- 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, panel_type, mode);
- if (ret_msg != ISC_SUCCESS)
- goto ISC_ERROR_HANDLE;
-
- /*Config version Check*/
- 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)
- goto ISC_ERROR_HANDLE;
-
- ret_msg = mms100_enter_config_update(_client);
- if (ret_msg != ISC_SUCCESS)
- goto ISC_ERROR_HANDLE;
-
- ret_msg = mms100_ISC_clear_validate_markers(_client);
- if (ret_msg != ISC_SUCCESS)
- goto ISC_ERROR_HANDLE;
-
- ret_msg = mms100_update_section_data(_client);
- if (ret_msg != ISC_SUCCESS)
- goto ISC_ERROR_HANDLE;
-
- ret_msg = ISC_SUCCESS;
-
-ISC_ERROR_HANDLE:
- 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!");
-
-ISC_NEED_NOT_UPDATE:
-
- 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 */
-
-
-#if TOUCH_BOOSTER
-static void change_dvfs_lock(struct work_struct *work)
-{
- struct mms_ts_info *info = container_of(work,
- struct mms_ts_info, work_dvfs_chg.work);
- int ret;
-
- mutex_lock(&info->dvfs_lock);
- ret = dev_lock(info->bus_dev, info->sec_touchscreen,
- TOUCH_BOOSTER_BUS_CLK_266);
-
- if (ret < 0)
- dev_err(&info->client->dev,
- "%s dev change bud lock failed(%d)\n",\
- __func__, __LINE__);
- else
- dev_notice(&info->client->dev, "Change dvfs lock");
- mutex_unlock(&info->dvfs_lock);
-}
-static void set_dvfs_off(struct work_struct *work)
-{
-
- struct mms_ts_info *info = container_of(work,
- struct mms_ts_info, work_dvfs_off.work);
- int ret;
-
- mutex_lock(&info->dvfs_lock);
-
- ret = dev_unlock(info->bus_dev, info->sec_touchscreen);
- if (ret < 0)
- 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;
- dev_notice(&info->client->dev, "dvfs off!");
- mutex_unlock(&info->dvfs_lock);
-}
-
-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(TOUCH_BOOSTER_CPU_CLK,
- &info->cpufreq_level);
- if (ret < 0)
- dev_err(&info->client->dev,
- "exynos_cpufreq_get_level error");
- goto out;
- }
-
- 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 (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,
- TOUCH_BOOSTER_BUS_CLK_400);
- if (ret < 0) {
- 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)
- 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;
- dev_notice(&info->client->dev, "dvfs on[%d]",
- info->cpufreq_level);
- }
- } 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);
- }
-out:
- mutex_unlock(&info->dvfs_lock);
-}
-#endif
-
-static void release_all_fingers(struct mms_ts_info *info)
-{
- int i;
-
- 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, TOUCH_BOOSTER_QUICK_OFF);
- dev_notice(&info->client->dev, "dvfs lock free.\n");
-#endif
-}
-
-static void reset_mms_ts(struct mms_ts_info *info)
-{
- struct i2c_client *client = info->client;
-
- dev_notice(&client->dev, "%s called, tsp state [%s]!\n",
- __func__, info->enabled ? "enable" : "disable");
- if (info->enabled == false)
- return;
-
- disable_irq_nosync(info->irq);
- info->enabled = false;
-
- info->pdata->power(0);
- msleep(30);
-
- release_all_fingers(info);
-
- info->pdata->power(1);
- msleep(120);
-
- 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, "reset & noise mode on!\n");
- }
- } else
- info->noise_mode = false;
-
- enable_irq(info->irq);
- info->enabled = true;
-}
-
-static void melfas_ta_cb(struct tsp_callbacks *cb, bool ta_status)
-{
- struct mms_ts_info *info =
- container_of(cb, struct mms_ts_info, callbacks);
- struct i2c_client *client = info->client;
-
- dev_notice(&client->dev, "%s TA or USB %sconnect\n", __func__,
- ta_status ? "" : "dis");
-
- info->ta_status = ta_status;
-
- 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 * 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
- bool press_flag = false;
-#endif
- struct i2c_msg msg[] = {
- {
- .addr = client->addr,
- .flags = 0,
- .buf = &reg,
- .len = 1,
- }, {
- .addr = client->addr,
- .flags = I2C_M_RD,
- .buf = buf,
- },
- };
- finger_event_sz = info->finger_byte;
-
- sz = i2c_smbus_read_byte_data(client, MMS_INPUT_EVENT_PKT_SZ);
-
- if (sz < 0) {
- dev_err(&client->dev, "%s bytes=%d\n", __func__, sz);
- for (i = 0; i < 50; i++) {
- sz = i2c_smbus_read_byte_data(client,
- MMS_INPUT_EVENT_PKT_SZ);
- if (sz > 0)
- break;
- }
-
- if (i == 50) {
- dev_dbg(&client->dev, "i2c failed... reset!!\n");
- reset_mms_ts(info);
- return IRQ_HANDLED;
- }
- dev_err(&client->dev, "success read touch info data\n");
- }
- if (sz == 0)
- return IRQ_HANDLED;
-
- 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);
-
- 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);
- return IRQ_HANDLED;
- }
-
- if (buf[0] == 0x0E) { /* NOISE MODE */
- 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];
-
- if (info->invert_x) {
- posX = info->max_x - posX;
- if (posX < 0)
- posX = 0;
- }
- if (info->invert_y) {
- 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);
- return IRQ_HANDLED;
- }
-
- if (state == TSP_STATE_RELEASE) {
- input_mt_slot(info->input_dev, id);
- input_mt_report_slot_state(info->input_dev,
- MT_TOOL_FINGER, false);
-#if SHOW_COORD
- 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]);
-#endif
- info->finger_state[id] = TSP_STATE_RELEASE;
- } else {
- input_mt_slot(info->input_dev, id);
- input_mt_report_slot_state(info->input_dev,
- MT_TOOL_FINGER, true);
- input_report_abs(info->input_dev,
- ABS_MT_POSITION_X, posX);
- input_report_abs(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
- 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
- } else
- info->finger_state[id] = TSP_STATE_MOVE;
- }
- }
- input_sync(info->input_dev);
-
-#if TOUCH_BOOSTER
- for (i = 0 ; i < MAX_FINGERS ; i++) {
- if (info->finger_state[i] == TSP_STATE_PRESS
- || info->finger_state[i] == TSP_STATE_MOVE) {
- press_flag = TOUCH_BOOSTER_ON;
- break;
- }
- }
-
- set_dvfs_lock(info, press_flag);
-#endif
-
- return IRQ_HANDLED;
-}
-
-static void hw_reboot(struct mms_ts_info *info, bool bootloader)
-{
- info->pdata->power(0);
- gpio_direction_output(info->pdata->gpio_sda, bootloader ? 0 : 1);
- gpio_direction_output(info->pdata->gpio_scl, bootloader ? 0 : 1);
- gpio_direction_output(info->pdata->gpio_int, 0);
- msleep(30);
- info->pdata->power(1);
- msleep(30);
-
- if (bootloader) {
- gpio_set_value(info->pdata->gpio_scl, 0);
- gpio_set_value(info->pdata->gpio_sda, 1);
- } else {
- gpio_set_value(info->pdata->gpio_int, 1);
- gpio_direction_input(info->pdata->gpio_int);
- gpio_direction_input(info->pdata->gpio_scl);
- gpio_direction_input(info->pdata->gpio_sda);
- }
- msleep(40);
-}
-
-static inline void hw_reboot_bootloader(struct mms_ts_info *info)
-{
- hw_reboot(info, true);
-}
-
-static inline void hw_reboot_normal(struct mms_ts_info *info)
-{
- hw_reboot(info, false);
-}
-
-static void isp_toggle_clk(struct mms_ts_info *info, int start_lvl, int end_lvl,
- int hold_us)
-{
- gpio_set_value(info->pdata->gpio_scl, start_lvl);
- udelay(hold_us);
- gpio_set_value(info->pdata->gpio_scl, end_lvl);
- udelay(hold_us);
-}
-
-/* 1 <= cnt <= 32 bits to write */
-static void isp_send_bits(struct mms_ts_info *info, u32 data, int cnt)
-{
- gpio_direction_output(info->pdata->gpio_int, 0);
- gpio_direction_output(info->pdata->gpio_scl, 0);
- gpio_direction_output(info->pdata->gpio_sda, 0);
-
- /* clock out the bits, msb first */
- while (cnt--) {
- gpio_set_value(info->pdata->gpio_sda, (data >> cnt) & 1);
- udelay(3);
- isp_toggle_clk(info, 1, 0, 3);
- }
-}
-
-/* 1 <= cnt <= 32 bits to read */
-static u32 isp_recv_bits(struct mms_ts_info *info, int cnt)
-{
- u32 data = 0;
-
- gpio_direction_output(info->pdata->gpio_int, 0);
- gpio_direction_output(info->pdata->gpio_scl, 0);
- gpio_set_value(info->pdata->gpio_sda, 0);
- gpio_direction_input(info->pdata->gpio_sda);
-
- /* clock in the bits, msb first */
- while (cnt--) {
- isp_toggle_clk(info, 0, 1, 1);
- data = (data << 1) | (!!gpio_get_value(info->pdata->gpio_sda));
- }
-
- gpio_direction_output(info->pdata->gpio_sda, 0);
- return data;
-}
-
-static void isp_enter_mode(struct mms_ts_info *info, u32 mode)
-{
- int cnt;
- unsigned long flags;
-
- local_irq_save(flags);
- gpio_direction_output(info->pdata->gpio_int, 0);
- gpio_direction_output(info->pdata->gpio_scl, 0);
- gpio_direction_output(info->pdata->gpio_sda, 1);
-
- mode &= 0xffff;
- for (cnt = 15; cnt >= 0; cnt--) {
- gpio_set_value(info->pdata->gpio_int, (mode >> cnt) & 1);
- udelay(3);
- isp_toggle_clk(info, 1, 0, 3);
- }
-
- gpio_set_value(info->pdata->gpio_int, 0);
- local_irq_restore(flags);
-}
-
-static void isp_exit_mode(struct mms_ts_info *info)
-{
- int i;
- unsigned long flags;
-
- local_irq_save(flags);
- gpio_direction_output(info->pdata->gpio_int, 0);
- udelay(3);
-
- for (i = 0; i < 10; i++)
- isp_toggle_clk(info, 1, 0, 3);
- local_irq_restore(flags);
-}
-
-static void flash_set_address(struct mms_ts_info *info, u16 addr)
-{
- /* Only 13 bits of addr are valid.
- * The addr is in bits 13:1 of cmd */
- isp_send_bits(info, (u32) (addr & 0x1fff) << 1, 18);
-}
-
-static void flash_erase(struct mms_ts_info *info)
-{
- isp_enter_mode(info, ISP_MODE_FLASH_ERASE);
-
- gpio_direction_output(info->pdata->gpio_int, 0);
- gpio_direction_output(info->pdata->gpio_scl, 0);
- gpio_direction_output(info->pdata->gpio_sda, 1);
-
- /* 4 clock cycles with different timings for the erase to
- * get processed, clk is already 0 from above */
- udelay(7);
- isp_toggle_clk(info, 1, 0, 3);
- udelay(7);
- isp_toggle_clk(info, 1, 0, 3);
- usleep_range(25000, 35000);
- isp_toggle_clk(info, 1, 0, 3);
- usleep_range(150, 200);
- isp_toggle_clk(info, 1, 0, 3);
-
- gpio_set_value(info->pdata->gpio_sda, 0);
-
- isp_exit_mode(info);
-}
-
-static u32 flash_readl(struct mms_ts_info *info, u16 addr)
-{
- int i;
- u32 val;
- unsigned long flags;
-
- local_irq_save(flags);
- isp_enter_mode(info, ISP_MODE_FLASH_READ);
- flash_set_address(info, addr);
-
- gpio_direction_output(info->pdata->gpio_scl, 0);
- gpio_direction_output(info->pdata->gpio_sda, 0);
- udelay(40);
-
- /* data load cycle */
- for (i = 0; i < 6; i++)
- isp_toggle_clk(info, 1, 0, 10);
-
- val = isp_recv_bits(info, 32);
- isp_exit_mode(info);
- local_irq_restore(flags);
-
- return val;
-}
-
-static void flash_writel(struct mms_ts_info *info, u16 addr, u32 val)
-{
- unsigned long flags;
-
- local_irq_save(flags);
- isp_enter_mode(info, ISP_MODE_FLASH_WRITE);
- flash_set_address(info, addr);
- isp_send_bits(info, val, 32);
-
- gpio_direction_output(info->pdata->gpio_sda, 1);
- /* 6 clock cycles with different timings for the data to get written
- * into flash */
- isp_toggle_clk(info, 0, 1, 3);
- isp_toggle_clk(info, 0, 1, 3);
- isp_toggle_clk(info, 0, 1, 6);
- isp_toggle_clk(info, 0, 1, 12);
- isp_toggle_clk(info, 0, 1, 3);
- isp_toggle_clk(info, 0, 1, 3);
-
- isp_toggle_clk(info, 1, 0, 1);
-
- gpio_direction_output(info->pdata->gpio_sda, 0);
- isp_exit_mode(info);
- local_irq_restore(flags);
- usleep_range(300, 400);
-}
-
-static bool flash_is_erased(struct mms_ts_info *info)
-{
- struct i2c_client *client = info->client;
- u32 val;
- u16 addr;
-
- for (addr = 0; addr < (ISP_MAX_FW_SIZE / 4); addr++) {
- udelay(40);
- val = flash_readl(info, addr);
-
- if (val != 0xffffffff) {
- dev_dbg(&client->dev,
- "addr 0x%x not erased: 0x%08x != 0xffffffff\n",
- addr, val);
- return false;
- }
- }
- return true;
-}
-
-static int fw_write_image(struct mms_ts_info *info, const u8 * data, size_t len)
-{
- struct i2c_client *client = info->client;
- u16 addr = 0;
-
- for (addr = 0; addr < (len / 4); addr++, data += 4) {
- u32 val = get_unaligned_le32(data);
- u32 verify_val;
- int retries = 3;
-
- while (retries--) {
- flash_writel(info, addr, val);
- verify_val = flash_readl(info, addr);
- if (val == verify_val)
- break;
- dev_err(&client->dev,
- "mismatch @ addr 0x%x: 0x%x != 0x%x\n",
- addr, verify_val, val);
- continue;
- }
- if (retries < 0)
- return -ENXIO;
- }
-
- return 0;
-}
-
-static int mms100_ISP_download(struct mms_ts_info *info, const u8 * data,
- size_t len)
-{
- struct i2c_client *client = info->client;
- u32 val;
- int ret = 0;
-
- if (len % 4) {
- dev_err(&client->dev,
- "fw image size (%d) must be a multiple of 4 bytes\n",
- len);
- return -EINVAL;
- } else if (len > ISP_MAX_FW_SIZE) {
- dev_err(&client->dev,
- "fw image is too big, %d > %d\n", len, ISP_MAX_FW_SIZE);
- return -EINVAL;
- }
-
- dev_info(&client->dev, "fw download start\n");
-
- info->pdata->power(0);
- gpio_direction_output(info->pdata->gpio_sda, 0);
- gpio_direction_output(info->pdata->gpio_scl, 0);
- gpio_direction_output(info->pdata->gpio_int, 0);
-
- hw_reboot_bootloader(info);
-
- val = flash_readl(info, ISP_IC_INFO_ADDR);
- dev_info(&client->dev, "IC info before erase : [%x]\n", val);
-
- dev_info(&client->dev, "fw erase...\n");
- flash_erase(info);
- if (!flash_is_erased(info)) {
- ret = -ENXIO;
- goto err;
- }
-
- flash_writel(info, ISP_IC_INFO_ADDR, val);
- val = flash_readl(info, ISP_IC_INFO_ADDR);
- dev_info(&client->dev, "IC info after erase & write : [%x]\n", val);
-
- dev_info(&client->dev, "fw write...\n");
- usleep_range(1000, 1500);
- ret = fw_write_image(info, data, len);
- if (ret)
- goto err;
- usleep_range(1000, 1500);
-
- hw_reboot_normal(info);
- usleep_range(1000, 1500);
- dev_info(&client->dev, "fw download done...\n");
- return 0;
-
-err:
- dev_err(&client->dev, "fw download failed...\n");
- hw_reboot_normal(info);
- return ret;
-}
-
-static int get_fw_version(struct mms_ts_info *info)
-{
- struct i2c_client *client = info->client;
- int ret;
- int retries = 3;
-
- /* this seems to fail sometimes after a reset.. retry a few times */
- do {
- ret = i2c_smbus_read_byte_data(info->client, MMS_FW_VERSION);
- } while (ret < 0 && retries-- > 0);
-
- 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 get_panel_type(struct mms_ts_info *info)
-{
- struct i2c_client *client = info->client;
- int ret;
- int retries = 3;
-
- /* 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, "MMS_TSP_REVISION = [0x%02x],[%c]", ret, ret);
-
- return ret;
-}
-
-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 retries_isc = 3;
- int retries_isp = 3;
-
- /* firmware check */
- 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) {
- dev_err(&client->dev,
- "fw cannot be updated, missing platform data\n");
- return 1;
- }
-
-#if FW_UPDATABLE
-
- while (retries_isc--) {
- /* 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, "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);
- if (ret_isp < 0)
- dev_err(&client->dev,
- "ISP D/L mode fail\n");
- else {
- dev_err(&client->dev,
- "ISP D/L mode success\n");
- break;
- }
- }
-
- 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,
- info->panel_type,
- FORCED_UPDATE);
- }
-
- if (ret == ISC_SUCCESS) {
- 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;
- }
-
- if (retries_isc == 0) {
- dev_err(&client->dev, "tsp f/w update all fail!\n");
- return ret;
- }
-#endif
-
- return ret;
-}
-
-
-#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);
-}
-
-static void get_raw_data_all(struct mms_ts_info *info, u8 cmd)
-{
- u8 w_buf[6];
- u8 read_buffer[2]; /* 52 */
- 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};
- int tx_num = info->pdata->tsp_tx;
- int rx_num = info->pdata->tsp_rx;
-
- disable_irq(info->irq);
-
- w_buf[0] = MMS_VSC_CMD; /* vendor specific command id */
- w_buf[1] = MMS_VSC_MODE; /* mode of vendor */
- w_buf[2] = 0; /* tx line */
- w_buf[3] = 0; /* rx line */
- w_buf[4] = 0; /* reserved */
- w_buf[5] = 0; /* sub command */
-
- if (cmd == MMS_VSC_CMD_EXIT) {
- w_buf[5] = MMS_VSC_CMD_EXIT; /* exit test mode */
-
- ret = i2c_smbus_write_i2c_block_data(info->client,
- w_buf[0], 5, &w_buf[1]);
- if (ret < 0)
- goto err_i2c;
- enable_irq(info->irq);
- msleep(200);
- return;
- }
-
- /* MMS_VSC_CMD_CM_DELTA or MMS_VSC_CMD_CM_ABS
- * this two mode need to enter the test mode
- * exit command must be followed by testing.
- */
- if (cmd == MMS_VSC_CMD_CM_DELTA || cmd == MMS_VSC_CMD_CM_ABS) {
- /* enter the debug mode */
- w_buf[2] = 0x0; /* tx */
- w_buf[3] = 0x0; /* rx */
- w_buf[5] = MMS_VSC_CMD_ENTER;
-
- ret = i2c_smbus_write_i2c_block_data(info->client,
- w_buf[0], 5, &w_buf[1]);
- if (ret < 0)
- goto err_i2c;
-
- /* wating for the interrupt */
- while (gpio_get_value(gpio))
- udelay(100);
- }
-
- for (i = 0; i < rx_num; i++) {
- for (j = 0; j < tx_num; j++) {
-
- w_buf[2] = j; /* tx */
- w_buf[3] = i; /* rx */
- w_buf[5] = cmd;
-
- ret = i2c_smbus_write_i2c_block_data(info->client,
- w_buf[0], 5, &w_buf[1]);
- if (ret < 0)
- goto err_i2c;
-
- usleep_range(1, 5);
-
- ret = i2c_smbus_read_i2c_block_data(info->client, 0xBF,
- 2, read_buffer);
- if (ret < 0)
- goto err_i2c;
-
- raw_data = ((u16) read_buffer[1] << 8) | read_buffer[0];
- if (i == 0 && j == 0) {
- max_value = min_value = raw_data;
- } else {
- max_value = max(max_value, raw_data);
- min_value = min(min_value, raw_data);
- }
-
- if (cmd == MMS_VSC_CMD_INTENSITY) {
- 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]);
- } else if (cmd == MMS_VSC_CMD_CM_DELTA) {
- info->cm_delta[j * rx_num + i] = raw_data;
- dev_dbg(&info->client->dev, "[TSP] delta[%d][%d] = %d\n",
- i, j, info->cm_delta[j * rx_num + i]);
- } else if (cmd == MMS_VSC_CMD_CM_ABS) {
- info->cm_abs[j * rx_num + i] = raw_data;
- dev_dbg(&info->client->dev, "[TSP] raw[%d][%d] = %d\n",
- i, j, info->cm_abs[j * rx_num + i]);
- } else if (cmd == MMS_VSC_CMD_REFER) {
- 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]);
- }
- }
-
- }
-
- snprintf(buff, sizeof(buff), "%d,%d", min_value, max_value);
- set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
-
- enable_irq(info->irq);
-
-err_i2c:
- dev_err(&info->client->dev, "%s: fail to i2c (cmd=%d)\n",
- __func__, cmd);
-}
-
-static u32 get_raw_data_one(struct mms_ts_info *info, u16 rx_idx, u16 tx_idx,
- u8 cmd)
-{
- u8 w_buf[6];
- u8 read_buffer[2];
- int ret;
- u32 raw_data;
-
- w_buf[0] = MMS_VSC_CMD; /* vendor specific command id */
- w_buf[1] = MMS_VSC_MODE; /* mode of vendor */
- w_buf[2] = 0; /* tx line */
- w_buf[3] = 0; /* rx line */
- w_buf[4] = 0; /* reserved */
- w_buf[5] = 0; /* sub command */
-
- if (cmd != MMS_VSC_CMD_INTENSITY && cmd != MMS_VSC_CMD_RAW &&
- cmd != MMS_VSC_CMD_REFER) {
- dev_err(&info->client->dev, "%s: not profer command(cmd=%d)\n",
- __func__, cmd);
- return -1;
- }
-
- w_buf[2] = tx_idx; /* tx */
- w_buf[3] = rx_idx; /* rx */
- w_buf[5] = cmd; /* sub command */
-
- ret = i2c_smbus_write_i2c_block_data(info->client, w_buf[0], 5,
- &w_buf[1]);
- if (ret < 0)
- goto err_i2c;
-
- ret = i2c_smbus_read_i2c_block_data(info->client, 0xBF, 2, read_buffer);
- if (ret < 0)
- goto err_i2c;
-
- raw_data = ((u16) read_buffer[1] << 8) | read_buffer[0];
- if (cmd == MMS_VSC_CMD_REFER)
- raw_data = raw_data >> 4;
-
- return raw_data;
-
-err_i2c:
- dev_err(&info->client->dev, "%s: fail to i2c (cmd=%d)\n",
- __func__, cmd);
- return -1;
-}
-
-static ssize_t show_close_tsp_test(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct mms_ts_info *info = dev_get_drvdata(dev);
-
- get_raw_data_all(info, MMS_VSC_CMD_EXIT);
- info->ft_flag = 0;
-
- return snprintf(buf, TSP_BUF_SIZE, "%u\n", 0);
-}
-
-static void set_default_result(struct mms_ts_info *info)
-{
- char delim = ':';
-
- memset(info->cmd_result, 0x00, ARRAY_SIZE(info->cmd_result));
- memcpy(info->cmd_result, info->cmd, strlen(info->cmd));
- strncat(info->cmd_result, &delim, 1);
-}
-
-static int check_rx_tx_num(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- char buff[TSP_CMD_STR_LEN] = {0};
- int node;
-
- if (info->cmd_param[0] < 0 ||
- info->cmd_param[0] >= info->pdata->tsp_tx ||
- info->cmd_param[1] < 0 ||
- 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;
-
- dev_info(&info->client->dev, "%s: parameter error: %u,%u\n",
- __func__, info->cmd_param[0],
- info->cmd_param[1]);
- node = -1;
- return node;
- }
- /* 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;
-
-}
-
-static void not_support_cmd(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
- char buff[16] = {0};
-
- set_default_result(info);
- sprintf(buff, "%s", "NA");
- set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
- info->cmd_state = 4;
- dev_info(&info->client->dev, "%s: \"%s(%d)\"\n", __func__,
- buff, strnlen(buff, sizeof(buff)));
- return;
-}
-
-static void fw_update(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
- struct i2c_client *client = info->client;
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- int ret = 0;
- int ver = 0;
- int retries = 5;
-
- set_default_result(info);
-
- dev_info(&client->dev,
- "fw_ic_ver = 0x%02x, fw_bin_ver = 0x%02x\n",
- info->fw_ic_ver, info->pdata->fw_version);
-
- switch (info->cmd_param[0]) {
- case BUILT_IN:
- info->cmd_param[0] = REQ_FW;
- dev_info(&client->dev, "BUILT_IN=>REQ_FW update mode!\n");
- break;
-
- case UMS:
- dev_info(&client->dev, "UMS update mode!\n");
- break;
-
- case REQ_FW:
- dev_info(&client->dev, "REQ_FW update mode!\n");
- break;
-
- default:
- dev_err(&client->dev, "invalid cmd_param[%d]\n",
- info->cmd_param[0]);
- goto not_support;
- }
-
- disable_irq(info->irq);
- while (retries--) {
-
-#if ISC_DL_MODE
- ret = mms100_ISC_download_mbinary(client, info->cmd_param[0],
- info->panel_type,
- FORCED_UPDATE);
-#endif
- if (ret) {
- dev_err(&client->dev, "retrying flashing\n");
- continue;
- }
-
- ver = get_fw_version(info);
- info->fw_ic_ver = ver;
-
- dev_info(&client->dev,
- "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;
-}
-
-static void get_fw_ver_bin(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- char buff[16] = {0};
-
- set_default_result(info);
- snprintf(buff, sizeof(buff), "%#02x", info->pdata->fw_version);
-
- set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
- info->cmd_state = OK;
- dev_info(&info->client->dev, "%s: %s(%d)\n", __func__,
- buff, strnlen(buff, sizeof(buff)));
-}
-
-static void get_fw_ver_ic(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- char buff[16] = {0};
- int ver;
-
- set_default_result(info);
-
- ver = info->fw_ic_ver;
- snprintf(buff, sizeof(buff), "%#02x", ver);
-
- set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
- info->cmd_state = OK;
- dev_info(&info->client->dev, "%s: %s(%d)\n", __func__,
- buff, strnlen(buff, sizeof(buff)));
-}
-
-static void get_config_ver(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- char buff[20] = {0};
-
- set_default_result(info);
-
- snprintf(buff, sizeof(buff), "%s", info->config_fw_version);
- set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
- info->cmd_state = 2;
- dev_info(&info->client->dev, "%s: %s(%d)\n", __func__,
- buff, strnlen(buff, sizeof(buff)));
-}
-
-static void get_threshold(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- char buff[16] = {0};
- int threshold;
-
- set_default_result(info);
-
- threshold = i2c_smbus_read_byte_data(info->client, 0x05);
- if (threshold < 0) {
- snprintf(buff, sizeof(buff), "%s", "NG");
- set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
- info->cmd_state = FAIL;
- return;
-}
- snprintf(buff, sizeof(buff), "%d", threshold);
-
- set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
- info->cmd_state = OK;
- dev_info(&info->client->dev, "%s: %s(%d)\n", __func__,
- buff, strnlen(buff, sizeof(buff)));
-}
-
-static void module_off_master(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- char buff[3] = {0};
-
- mutex_lock(&info->lock);
- if (info->enabled) {
- disable_irq(info->irq);
- info->enabled = false;
- }
- mutex_unlock(&info->lock);
-
- if (info->pdata->power(0) == SUCCESS_PWR_CONTROL)
- snprintf(buff, sizeof(buff), "%s", "OK");
- else
- snprintf(buff, sizeof(buff), "%s", "NG");
-
- set_default_result(info);
- set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
-
- if (strncmp(buff, "OK", 2) == 0)
- info->cmd_state = OK;
- else
- info->cmd_state = FAIL;
-
- dev_info(&info->client->dev, "%s: %s\n", __func__, buff);
-}
-
-static void module_on_master(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- char buff[3] = {0};
-
-
- mutex_lock(&info->lock);
- if (!info->enabled) {
- enable_irq(info->irq);
- info->enabled = true;
- }
- mutex_unlock(&info->lock);
-
- if (info->pdata->power(1) == SUCCESS_PWR_CONTROL)
- snprintf(buff, sizeof(buff), "%s", "OK");
- else
- snprintf(buff, sizeof(buff), "%s", "NG");
-
- set_default_result(info);
- set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
-
- if (strncmp(buff, "OK", 2) == 0)
- info->cmd_state = OK;
- else
- info->cmd_state = FAIL;
-
- dev_info(&info->client->dev, "%s: %s\n", __func__, buff);
-
-}
-
-static void module_off_slave(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- not_support_cmd(info);
-}
-
-static void module_on_slave(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- not_support_cmd(info);
-}
-
-static void get_chip_vendor(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- char buff[16] = {0};
-
- set_default_result(info);
-
- 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__,
- buff, strnlen(buff, sizeof(buff)));
-}
-
-static void get_chip_name(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- char buff[16] = {0};
-
- set_default_result(info);
-
- 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__,
- buff, strnlen(buff, sizeof(buff)));
-}
-
-static void get_reference(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- char buff[16] = {0};
- unsigned int val;
- int node;
-
- set_default_result(info);
- node = check_rx_tx_num(info);
-
- if (node < 0)
- return;
-
- val = info->reference[node];
- snprintf(buff, sizeof(buff), "%u", val);
- set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
-
- info->cmd_state = OK;
-
- dev_info(&info->client->dev, "%s: %s(%d)\n", __func__,
- buff, strnlen(buff, sizeof(buff)));
-
-}
-
-static void get_cm_abs(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- char buff[16] = {0};
- unsigned int val;
- int node;
-
- set_default_result(info);
- node = check_rx_tx_num(info);
-
- if (node < 0)
- return;
-
- val = info->cm_abs[node];
- snprintf(buff, sizeof(buff), "%u", val);
- set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
- info->cmd_state = OK;
-
- dev_info(&info->client->dev, "%s: %s(%d)\n", __func__, buff,
- strnlen(buff, sizeof(buff)));
-}
-
-static void get_cm_delta(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- char buff[16] = {0};
- unsigned int val;
- int node;
-
- set_default_result(info);
- node = check_rx_tx_num(info);
-
- if (node < 0)
- return;
-
- val = info->cm_delta[node];
- snprintf(buff, sizeof(buff), "%u", val);
- set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
- info->cmd_state = OK;
-
- dev_info(&info->client->dev, "%s: %s(%d)\n", __func__, buff,
- strnlen(buff, sizeof(buff)));
-}
-
-static void get_intensity(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- char buff[16] = {0};
- 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);
- set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
- info->cmd_state = OK;
-
- dev_info(&info->client->dev, "%s: %s(%d)\n", __func__, buff,
- strnlen(buff, sizeof(buff)));
-}
-
-static void get_x_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, 0xEF));
-#endif
- set_default_result(info);
-
- snprintf(buff, sizeof(buff), "%d", info->pdata->tsp_tx);
- set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
- info->cmd_state = OK;
-
- dev_info(&info->client->dev, "%s: %s(%d)\n", __func__, buff,
- strnlen(buff, sizeof(buff)));
-}
-
-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", info->pdata->tsp_rx);
- set_cmd_result(info, buff, strnlen(buff, sizeof(buff)));
- info->cmd_state = OK;
-
- dev_info(&info->client->dev, "%s: %s(%d)\n", __func__, buff,
- strnlen(buff, sizeof(buff)));
-}
-
-static void run_reference_read(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- set_default_result(info);
- get_raw_data_all(info, MMS_VSC_CMD_REFER);
- info->cmd_state = OK;
-
-/* dev_info(&info->client->dev, "%s: %s(%d)\n", __func__); */
-}
-
-static void run_cm_abs_read(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- set_default_result(info);
- get_raw_data_all(info, MMS_VSC_CMD_CM_ABS);
- get_raw_data_all(info, MMS_VSC_CMD_EXIT);
- info->cmd_state = OK;
-
-/* dev_info(&info->client->dev, "%s: %s(%d)\n", __func__); */
-}
-
-static void run_cm_delta_read(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- set_default_result(info);
- get_raw_data_all(info, MMS_VSC_CMD_CM_DELTA);
- get_raw_data_all(info, MMS_VSC_CMD_EXIT);
- info->cmd_state = OK;
-
-/* dev_info(&info->client->dev, "%s: %s(%d)\n", __func__); */
-}
-
-static void run_intensity_read(void *device_data)
-{
- struct mms_ts_info *info = (struct mms_ts_info *)device_data;
-
- set_default_result(info);
- get_raw_data_all(info, MMS_VSC_CMD_INTENSITY);
- info->cmd_state = OK;
-
-/* dev_info(&info->client->dev, "%s: %s(%d)\n", __func__); */
-}
-
-static ssize_t store_cmd(struct device *dev, struct device_attribute
- *devattr, const char *buf, size_t count)
-{
- struct mms_ts_info *info = dev_get_drvdata(dev);
- struct i2c_client *client = info->client;
-
- char *cur, *start, *end;
- char buff[TSP_CMD_STR_LEN] = {0};
- int len, i;
- struct tsp_cmd *tsp_cmd_ptr = NULL;
- char delim = ',';
- bool cmd_found = false;
- int param_cnt = 0;
- int ret;
-
- if (info->cmd_is_running == true) {
- dev_err(&info->client->dev, "tsp_cmd: other cmd is running.\n");
- goto err_out;
- }
-
-
- /* check lock */
- mutex_lock(&info->cmd_lock);
- info->cmd_is_running = true;
- mutex_unlock(&info->cmd_lock);
-
- info->cmd_state = RUNNING;
-
- for (i = 0; i < ARRAY_SIZE(info->cmd_param); i++)
- info->cmd_param[i] = 0;
-
- len = (int)count;
- if (*(buf + len - 1) == '\n')
- len--;
- memset(info->cmd, 0x00, ARRAY_SIZE(info->cmd));
- memcpy(info->cmd, buf, len);
-
- cur = strchr(buf, (int)delim);
- if (cur)
- memcpy(buff, buf, cur - buf);
- else
- memcpy(buff, buf, len);
-
- /* find command */
- list_for_each_entry(tsp_cmd_ptr, &info->cmd_list_head, list) {
- if (!strcmp(buff, tsp_cmd_ptr->cmd_name)) {
- cmd_found = true;
- break;
- }
- }
-
- /* set not_support_cmd */
- if (!cmd_found) {
- list_for_each_entry(tsp_cmd_ptr, &info->cmd_list_head, list) {
- if (!strcmp("not_support_cmd", tsp_cmd_ptr->cmd_name))
- break;
- }
- }
-
- /* parsing parameters */
- if (cur && cmd_found) {
- cur++;
- start = cur;
- memset(buff, 0x00, ARRAY_SIZE(buff));
- do {
- if (*cur == delim || cur - buf == len) {
- end = cur;
- memcpy(buff, start, end - start);
- *(buff + strlen(buff)) = '\0';
- ret = kstrtoint(buff, 10,\
- info->cmd_param + param_cnt);
- start = cur + 1;
- memset(buff, 0x00, ARRAY_SIZE(buff));
- param_cnt++;
- }
- cur++;
- } while (cur - buf <= len);
- }
-
- dev_info(&client->dev, "cmd = %s\n", tsp_cmd_ptr->cmd_name);
- for (i = 0; i < param_cnt; i++)
- dev_info(&client->dev, "cmd param %d= %d\n", i,
- info->cmd_param[i]);
-
- tsp_cmd_ptr->cmd_func(info);
-
-
-err_out:
- return count;
-}
-
-static ssize_t show_cmd_status(struct device *dev,
- struct device_attribute *devattr, char *buf)
-{
- struct mms_ts_info *info = dev_get_drvdata(dev);
- char buff[16] = {0};
-
- dev_info(&info->client->dev, "tsp cmd: status:%d\n",
- info->cmd_state);
-
- if (info->cmd_state == WAITING)
- snprintf(buff, sizeof(buff), "WAITING");
-
- else if (info->cmd_state == RUNNING)
- snprintf(buff, sizeof(buff), "RUNNING");
-
- else if (info->cmd_state == OK)
- snprintf(buff, sizeof(buff), "OK");
-
- else if (info->cmd_state == FAIL)
- snprintf(buff, sizeof(buff), "FAIL");
-
- else if (info->cmd_state == NOT_APPLICABLE)
- snprintf(buff, sizeof(buff), "NOT_APPLICABLE");
-
- return snprintf(buf, TSP_BUF_SIZE, "%s\n", buff);
-}
-
-static ssize_t show_cmd_result(struct device *dev, struct device_attribute
- *devattr, char *buf)
-{
- struct mms_ts_info *info = dev_get_drvdata(dev);
-
- dev_info(&info->client->dev, "tsp cmd: result: %s\n", info->cmd_result);
-
- mutex_lock(&info->cmd_lock);
- info->cmd_is_running = false;
- mutex_unlock(&info->cmd_lock);
-
- info->cmd_state = WAITING;
-
- return snprintf(buf, TSP_BUF_SIZE, "%s\n", info->cmd_result);
-}
-
-#ifdef ESD_DEBUG
-
-static bool intensity_log_flag;
-
-static ssize_t show_intensity_logging_on(struct device *dev,
- struct device_attribute *devattr, char *buf)
-{
- struct mms_ts_info *info = dev_get_drvdata(dev);
- struct i2c_client *client = info->client;
- struct file *fp;
- char log_data[160] = { 0, };
- char buff[16] = { 0, };
- mm_segment_t old_fs;
- long nwrite;
- u32 val;
- int i, y, c;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
-#define MELFAS_DEBUG_LOG_PATH "/sdcard/melfas_log"
-
- dev_info(&client->dev, "%s: start.\n", __func__);
- fp = filp_open(MELFAS_DEBUG_LOG_PATH, O_RDWR | O_CREAT,
- S_IRWXU | S_IRWXG | S_IRWXO);
- if (IS_ERR(fp)) {
- dev_err(&client->dev, "%s: fail to open log file\n", __func__);
- set_fs(old_fs);
- return -1;
- }
-
- intensity_log_flag = 1;
- do {
- for (y = 0; y < 3; y++) {
- /* for tx chanel 0~2 */
- memset(log_data, 0x00, 160);
-
- snprintf(buff, 16, "%1u: ", y);
- strncat(log_data, buff, strnlen(buff, 16));
-
- 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);
- strncat(log_data, buff, strnlen(buff, 16));
- }
- memset(buff, '\n', 2);
- c = (y == 2) ? 2 : 1;
- strncat(log_data, buff, c);
- nwrite = vfs_write(fp, (const char __user *)log_data,
- strnlen(log_data, 160), &fp->f_pos);
- }
- usleep_range(5000);
- } while (intensity_log_flag);
-
- filp_close(fp, current->files);
- set_fs(old_fs);
-
- return 0;
-}
-
-static ssize_t show_intensity_logging_off(struct device *dev,
- struct device_attribute *devattr, char *buf)
-{
- struct mms_ts_info *info = dev_get_drvdata(dev);
- intensity_log_flag = 0;
- usleep_range(10000);
- get_raw_data_all(info, MMS_VSC_CMD_EXIT);
- return 0;
-}
-
-#endif
-
-static DEVICE_ATTR(close_tsp_test, S_IRUGO, show_close_tsp_test, NULL);
-static DEVICE_ATTR(cmd, S_IWUSR | S_IWGRP, NULL, store_cmd);
-static DEVICE_ATTR(cmd_status, S_IRUGO, show_cmd_status, NULL);
-static DEVICE_ATTR(cmd_result, S_IRUGO, show_cmd_result, NULL);
-#ifdef ESD_DEBUG
-static DEVICE_ATTR(intensity_logging_on, S_IRUGO, show_intensity_logging_on,
- NULL);
-static DEVICE_ATTR(intensity_logging_off, S_IRUGO, show_intensity_logging_off,
- NULL);
-#endif
-
-static struct attribute *sec_touch_facotry_attributes[] = {
- &dev_attr_close_tsp_test.attr,
- &dev_attr_cmd.attr,
- &dev_attr_cmd_status.attr,
- &dev_attr_cmd_result.attr,
-#ifdef ESD_DEBUG
- &dev_attr_intensity_logging_on.attr,
- &dev_attr_intensity_logging_off.attr,
-#endif
- NULL,
-};
-
-static struct attribute_group sec_touch_factory_attr_group = {
- .attrs = sec_touch_facotry_attributes,
-};
-#endif /* SEC_TSP_FACTORY_TEST */
-
-static int __devinit mms_ts_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- struct mms_ts_info *info;
- struct input_dev *input_dev;
- int ret = 0;
- char buf[4] = { 0, };
- int i;
-
-#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))
- return -EIO;
-
- info = kzalloc(sizeof(struct mms_ts_info), GFP_KERNEL);
- if (!info) {
- dev_err(&client->dev, "Failed to allocate memory\n");
- ret = -ENOMEM;
- goto err_alloc;
- }
-
- input_dev = input_allocate_device();
- if (!input_dev) {
- dev_err(&client->dev, "Failed to allocate memory for input device\n");
- ret = -ENOMEM;
- goto err_input_alloc;
- }
-
- info->client = client;
- info->input_dev = input_dev;
- info->pdata = client->dev.platform_data;
- if (NULL == info->pdata) {
- dev_err(&client->dev, "failed to get platform data\n");
- goto err_config;
- }
- info->irq = -1;
- mutex_init(&info->lock);
-
- if (info->pdata) {
- info->max_x = info->pdata->max_x;
- info->max_y = info->pdata->max_y;
- info->invert_x = info->pdata->invert_x;
- info->invert_y = info->pdata->invert_y;
- info->config_fw_version = info->pdata->config_fw_version;
- info->input_event = info->pdata->input_event;
- info->register_cb = info->pdata->register_cb;
- } else {
- info->max_x = 720;
- info->max_y = 1280;
- }
- for (i = 0 ; i < MAX_FINGERS; i++)
- info->finger_state[i] = TSP_STATE_RELEASE;
-
- info->pdata->power(true);
- msleep(100);
-
- i2c_set_clientdata(client, info);
- ret = i2c_master_recv(client, buf, 1);
- if (ret < 0) { /* tsp connect check */
- dev_err(&client->dev, "%s: tsp connect err [%d], Add[%d]\n",
- __func__, ret, info->client->addr);
- goto err_config;
- }
-
- 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);
- goto err_config;
- }
-
- info->enabled = true;
-
- snprintf(info->phys, sizeof(info->phys),
- "%s/input0", dev_name(&client->dev));
- input_dev->name = "sec_touchscreen"; /*= "Melfas MMSxxx Touchscreen";*/
- input_dev->phys = info->phys;
- input_dev->id.bustype = BUS_I2C;
- input_dev->dev.parent = &client->dev;
-
- __set_bit(EV_ABS, input_dev->evbit);
- __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
-
- input_mt_init_slots(input_dev, MAX_FINGERS);
- 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);
-
- 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);
- if (ret) {
- dev_err(&client->dev, "failed to register input dev (%d)\n",
- ret);
- goto err_reg_input_dev;
- }
-
-#if TOUCH_BOOSTER
- mutex_init(&info->dvfs_lock);
- INIT_DELAYED_WORK(&info->work_dvfs_off, set_dvfs_off);
- INIT_DELAYED_WORK(&info->work_dvfs_chg, change_dvfs_lock);
- info->bus_dev = dev_get("exynos-busfreq");
- info->sec_touchscreen = dev_get("sec_touchscreen");
- info->cpufreq_level = -1;
- info->dvfs_lock_status = false;
-#endif
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
- info->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
- info->early_suspend.suspend = mms_ts_early_suspend;
- info->early_suspend.resume = mms_ts_late_resume;
- register_early_suspend(&info->early_suspend);
-#endif
-
- 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();
-
- 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");
- if (IS_ERR(fac_dev_ts))
- dev_err(&client->dev, "Failed to create device for the sysfs\n");
-
- ret = sysfs_create_group(&fac_dev_ts->kobj,
- &sec_touch_factory_attr_group);
- if (ret)
- dev_err(&client->dev, "Failed to create sysfs group\n");
-#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:
-err_input_alloc:
- kfree(info);
-err_alloc:
- return ret;
-
-}
-
-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);
- input_unregister_device(info->input_dev);
- kfree(info);
-
- return 0;
-}
-
-#if defined(CONFIG_PM) || defined(CONFIG_HAS_EARLYSUSPEND)
-static int mms_ts_suspend(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct mms_ts_info *info = i2c_get_clientdata(client);
-
- if (!info->enabled)
- return 0;
-
- dev_notice(&info->client->dev, "%s\n", __func__);
-
- disable_irq(info->irq);
- info->enabled = false;
- release_all_fingers(info);
- info->pdata->power(0);
- return 0;
-}
-
-static int mms_ts_resume(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct mms_ts_info *info = i2c_get_clientdata(client);
-
- if (info->enabled)
- return 0;
-
- dev_notice(&info->client->dev, "%s\n", __func__);
- info->pdata->power(1);
- msleep(120);
-
- 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.
- */
- /* irq_set_irq_type(client->irq, IRQ_TYPE_EDGE_FALLING); */
-
- enable_irq(info->irq);
- info->enabled = true;
- return 0;
-}
-#endif
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static void mms_ts_early_suspend(struct early_suspend *h)
-{
- struct mms_ts_info *info;
- info = container_of(h, struct mms_ts_info, early_suspend);
- mms_ts_suspend(&info->client->dev);
-
-}
-
-static void mms_ts_late_resume(struct early_suspend *h)
-{
- struct mms_ts_info *info;
- info = container_of(h, struct mms_ts_info, early_suspend);
- mms_ts_resume(&info->client->dev);
-}
-#endif
-
-#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND)
-static const struct dev_pm_ops mms_ts_pm_ops = {
- .suspend = mms_ts_suspend,
- .resume = mms_ts_resume,
-};
-#endif
-
-static const struct i2c_device_id mms_ts_id[] = {
- {MELFAS_TS_NAME, 0},
- {}
-};
-
-MODULE_DEVICE_TABLE(i2c, mms_ts_id);
-
-static struct i2c_driver mms_ts_driver = {
- .probe = mms_ts_probe,
- .remove = __devexit_p(mms_ts_remove),
- .driver = {
- .name = MELFAS_TS_NAME,
-#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND)
- .pm = &mms_ts_pm_ops,
-#endif
- },
- .id_table = mms_ts_id,
-};
-
-static int __init mms_ts_init(void)
-{
-
- return i2c_add_driver(&mms_ts_driver);
-
-}
-
-static void __exit mms_ts_exit(void)
-{
- i2c_del_driver(&mms_ts_driver);
-}
-
-module_init(mms_ts_init);
-module_exit(mms_ts_exit);
-
-/* Module information */
-MODULE_DESCRIPTION("Touchscreen driver for Melfas MMS-series controllers");
-MODULE_LICENSE("GPL");