Fixed MTP to work with TWRP

This commit is contained in:
awab228 2018-06-19 23:16:04 +02:00
commit f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions

View file

@ -0,0 +1,12 @@
#
# STMicroelectronics TOUCH driver configuration
#
config TOUCHSCREEN_FTS
tristate "STMicroelectronics i2c multitouch touchscreen with FingerTipS"
depends on I2C
help
Say Y here to enable STMicroelectronics touchscreen support.
If unsure, say N.
To compile this driver as a module, choose M here: the
module will be called STM_ts.

View file

@ -0,0 +1 @@
obj-$(CONFIG_TOUCHSCREEN_FTS) += fts_ts.o fts_fwu.o

View file

@ -0,0 +1,712 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/firmware.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/hrtimer.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include "fts_ts.h"
#define WRITE_CHUNK_SIZE 64
#define FTS_DEFAULT_UMS_FW "/sdcard/stm.fw"
#define FTS_DEFAULT_FFU_FW "ffu_tsp.bin"
#define FTS64FILE_SIGNATURE 0xaaaa5555
enum {
BUILT_IN = 0,
UMS,
NONE,
FFU,
};
struct fts64_header {
unsigned int signature;
unsigned short fw_ver;
unsigned char fw_id;
unsigned char reserved1;
unsigned char internal_ver[8];
unsigned char released_ver[8];
unsigned int reserved2;
unsigned int checksum;
};
static int fts_fw_wait_for_flash_ready(struct fts_ts_info *info)
{
unsigned char regAdd;
unsigned char buf[3];
int retry = 0;
regAdd = FTS_CMD_READ_FLASH_STAT;
while (info->fts_read_reg
(info, &regAdd, 1, (unsigned char *)buf, 1)) {
if ((buf[0] & 0x01) == 0)
break;
if (retry++ > FTS_RETRY_COUNT * 10) {
tsp_debug_err(true, info->dev,
"%s: Time Over\n",
__func__);
return -FTS_ERROR_TIMEOUT;
}
msleep(20);
}
return 0;
}
#define FW_IMAGE_SIZE_D1 64 * 1024
#define FW_IMAGE_SIZE_D2 128 * 1024
#define SIGNEDKEY_SIZE 256
static int fts_fw_burn(struct fts_ts_info *info, unsigned char *fw_data)
{
unsigned char regAdd[WRITE_CHUNK_SIZE + 3];
int section;
int fsize = FW_IMAGE_SIZE_D1;
/* Check busy Flash */
if (fts_fw_wait_for_flash_ready(info)<0)
return -1;
/* FTS_CMD_UNLOCK_FLASH */
tsp_debug_info(true, info->dev, "%s: Unlock Flash\n", __func__);
regAdd[0] = FTS_CMD_UNLOCK_FLASH;
regAdd[1] = 0x74;
regAdd[2] = 0x45;
info->fts_write_reg(info, &regAdd[0], 3);
msleep(500);
/* Copy to PRAM */
if (info->digital_rev == FTS_DIGITAL_REV_2)
fsize = FW_IMAGE_SIZE_D2 + sizeof(struct fts64_header);
tsp_debug_info(true, info->dev, "%s: Copy to PRAM [Size : %d]\n", __func__, fsize);
for (section = 0; section < (fsize / WRITE_CHUNK_SIZE); section++) {
regAdd[0] = FTS_CMD_WRITE_PRAM + (((section * WRITE_CHUNK_SIZE) >> 16) & 0x0f);
regAdd[1] = ((section * WRITE_CHUNK_SIZE) >> 8) & 0xff;
regAdd[2] = (section * WRITE_CHUNK_SIZE) & 0xff;
memcpy(&regAdd[3],
&fw_data[section * WRITE_CHUNK_SIZE +
sizeof(struct fts64_header)],
WRITE_CHUNK_SIZE);
info->fts_write_reg(info, &regAdd[0], WRITE_CHUNK_SIZE + 3);
}
msleep(100);
/* Erase Program Flash */
tsp_debug_info(true, info->dev, "%s: Erase Program Flash\n", __func__);
info->fts_command(info, FTS_CMD_ERASE_PROG_FLASH);
msleep(100);
/* Check busy Flash */
if (fts_fw_wait_for_flash_ready(info)<0)
return -1;
/* Burn Program Flash */
tsp_debug_info(true, info->dev, "%s: Burn Program Flash\n", __func__);
info->fts_command(info, FTS_CMD_BURN_PROG_FLASH);
msleep(100);
/* Check busy Flash */
if (fts_fw_wait_for_flash_ready(info)<0)
return -1;
/* Reset FTS */
info->fts_systemreset(info);
return 0;
}
static int fts_get_system_status(struct fts_ts_info *info, unsigned char *val1, unsigned char *val2)
{
bool rc = -1;
unsigned char regAdd1[4] = { 0xb2, 0x07, 0xfb, 0x04 };
unsigned char regAdd2[4] = { 0xb2, 0x17, 0xfb, 0x04 };
unsigned char data[FTS_EVENT_SIZE];
int retry = 0;
if (info->digital_rev == FTS_DIGITAL_REV_2)
regAdd2[1] = 0x1f;
info->fts_write_reg(info, &regAdd1[0], 4);
info->fts_write_reg(info, &regAdd2[0], 4);
memset(data, 0x0, FTS_EVENT_SIZE);
regAdd1[0] = READ_ONE_EVENT;
while (info->fts_read_reg(info, &regAdd1[0], 1, (unsigned char *)data,
FTS_EVENT_SIZE)) {
if ((data[0] == 0x12) && (data[1] == regAdd1[1])
&& (data[2] == regAdd1[2])) {
rc = 0;
*val1 = data[3];
tsp_debug_info(true, info->dev,
"%s: System Status 1 : 0x%02x\n",
__func__, data[3]);
}
else if ((data[0] == 0x12) && (data[1] == regAdd2[1])
&& (data[2] == regAdd2[2])) {
rc = 0;
*val2 = data[3];
tsp_debug_info(true, info->dev,
"%s: System Status 2 : 0x%02x\n",
__func__, data[3]);
break;
}
if (retry++ > FTS_RETRY_COUNT) {
rc = -1;
tsp_debug_err(true, info->dev,
"%s: Time Over\n", __func__);
break;
}
}
return rc;
}
int fts_fw_wait_for_event(struct fts_ts_info *info, unsigned char eid)
{
int rc;
unsigned char regAdd;
unsigned char data[FTS_EVENT_SIZE];
int retry = 0;
memset(data, 0x0, FTS_EVENT_SIZE);
regAdd = READ_ONE_EVENT;
rc = -1;
while (info->fts_read_reg
(info, &regAdd, 1, (unsigned char *)data, FTS_EVENT_SIZE)) {
if ((data[0] == EVENTID_STATUS_EVENT) &&
(data[1] == eid)) {
rc = 0;
break;
}
if (retry++ > FTS_RETRY_COUNT * 15) {
rc = -1;
tsp_debug_info(true, info->dev, "%s: Time Over\n", __func__);
break;
}
msleep(20);
}
return rc;
}
void fts_execute_autotune(struct fts_ts_info *info)
{
info->fts_command(info, CX_TUNNING);
msleep(300);
fts_fw_wait_for_event(info, STATUS_EVENT_MUTUAL_AUTOTUNE_DONE);
#ifdef FTS_SUPPORT_WATER_MODE
fts_fw_wait_for_event (info, STATUS_EVENT_WATER_SELF_AUTOTUNE_DONE);
fts_fw_wait_for_event(info, STATUS_EVENT_SELF_AUTOTUNE_DONE);
#endif
#ifdef FTS_SUPPORT_SELF_MODE
info->fts_command(info, SELF_AUTO_TUNE);
msleep(300);
fts_fw_wait_for_event(info, STATUS_EVENT_SELF_AUTOTUNE_DONE);
#endif
info->fts_command(info, FTS_CMD_SAVE_CX_TUNING);
msleep(230);
fts_fw_wait_for_event(info, STATUS_EVENT_FLASH_WRITE_CXTUNE_VALUE);
}
void fts_fw_init(struct fts_ts_info *info)
{
info->fts_command(info, SLEEPOUT);
msleep(50);
if (info->digital_rev == FTS_DIGITAL_REV_2) {
info->fts_command(info, FTS_CMD_TRIM_LOW_POWER_OSCILLATOR);
msleep(300);
}
fts_execute_autotune(info);
info->fts_command(info, SLEEPOUT);
msleep(50);
info->fts_command(info, SENSEON);
#ifdef FTS_SUPPORT_WATER_MODE
fts_fw_wait_for_event(info, STATUS_EVENT_WATER_SELF_DONE);
#else
fts_fw_wait_for_event (info, STATUS_EVENT_FORCE_CAL_DONE);
#endif
#ifdef FTS_SUPPORT_TOUCH_KEY
if (info->board->support_mskey)
info->fts_command(info, FTS_CMD_KEY_SENSE_ON);
#endif
}
const int fts_fw_updater(struct fts_ts_info *info, unsigned char *fw_data)
{
const struct fts64_header *header;
int retval;
int retry;
unsigned short fw_main_version;
if (!fw_data) {
tsp_debug_err(true, info->dev, "%s: Firmware data is NULL\n",
__func__);
return -ENODEV;
}
header = (struct fts64_header *)fw_data;
fw_main_version = (header->released_ver[0] << 8) +
(header->released_ver[1]);
tsp_debug_info(true, info->dev,
"Starting firmware update : 0x%04X\n",
fw_main_version);
retry = 0;
while (1) {
retval = fts_fw_burn(info, fw_data);
if (retval >= 0) {
info->fts_wait_for_ready(info);
info->fts_get_version_info(info);
#ifdef FTS_SUPPORT_NOISE_PARAM
info->fts_get_noise_param_address(info);
#endif
if (fw_main_version == info->fw_main_version_of_ic) {
tsp_debug_info(true, info->dev,
"%s: Success Firmware update\n",
__func__);
fts_fw_init(info);
retval = 0;
break;
}
}
if (retry++ > 3) {
tsp_debug_err(true, info->dev, "%s: Fail Firmware update\n",
__func__);
retval = -1;
break;
}
}
return retval;
}
EXPORT_SYMBOL(fts_fw_updater);
#define FW_IMAGE_NAME_D2_TB_INTEG "tsp_stm/stm_tb_integ.fw"
#define FW_IMAGE_NAME_D2_Z2A "tsp_stm/stm_z2a.fw"
#define FW_IMAGE_NAME_D2_Z2I "tsp_stm/stm_z2i.fw"
#define FW_IMAGE_NAME_D2_Z1 "tsp_stm/stm_z1.fw"
#define CONFIG_ID_D1_S 0x2C
#define CONFIG_ID_D2_TR 0x2E
#define CONFIG_ID_D2_TB 0x30
#define CONFIG_OFFSET_BIN_D1 0xf822
#define CONFIG_OFFSET_BIN_D2 0x1E822
#define RX_OFFSET_BIN_D2 0x1E834
#define TX_OFFSET_BIN_D2 0x1E835
static bool fts_skip_firmware_update(struct fts_ts_info *info, unsigned char *fw_data)
{
int config_id, num_rx, num_tx;
config_id = fw_data[CONFIG_OFFSET_BIN_D2];
num_rx = fw_data[RX_OFFSET_BIN_D2];
num_tx = fw_data[TX_OFFSET_BIN_D2];
if (strncmp(info->board->project_name, "TB", 2) == 0) {
if (config_id != CONFIG_ID_D2_TB) {
tsp_debug_info(true, info->dev, "%s: Skip update because config ID(%0x2X) is mismatched.\n",
__func__,config_id);
// return true; // tempory blocking to update f/w for TB, it will be remove later.. Xtopher
}
if ((num_rx != info->board->SenseChannelLength)
|| (num_tx != info->board->ForceChannelLength)) {
tsp_debug_info(true, info->dev,
"%s: Skip update because revision is mismatched. rx[%d] tx[%d]\n",
__func__, num_rx, num_tx);
//return true; // tempory blocking to update f/w for TB, it will be remove later.. Xtopher
}
} else if (strncmp(info->board->project_name, "TR", 2) == 0) {
if (config_id != CONFIG_ID_D2_TR) {
tsp_debug_info(true, info->dev,
"%s: Skip update because config ID is mismatched. config_id[%d]\n",
__func__, config_id);
return true;
}
} else
goto out;
out:
return false;
}
int fts_fw_update_on_probe(struct fts_ts_info *info)
{
int retval = 0;
const struct firmware *fw_entry = NULL;
unsigned char *fw_data = NULL;
char fw_path[FTS_MAX_FW_PATH];
const struct fts64_header *header;
unsigned char SYS_STAT[2] = {0, };
int tspid = 0;
if (info->board->firmware_name)
info->firmware_name = info->board->firmware_name;
else {
#if 0
if ((lcdtype == S6E3HF2_WQXGA_ID1) || (lcdtype == S6E3HF2_WQXGA_ID2)) {
info->firmware_name = FW_IMAGE_NAME_D2_TB_INTEG;
} else {
tspid = gpio_get_value(info->board->tspid);
if (tspid)
info->firmware_name = FW_IMAGE_NAME_D2_Z2I;
else
info->firmware_name = FW_IMAGE_NAME_D2_Z2A;
}
#endif
return -1;
}
snprintf(fw_path, FTS_MAX_FW_PATH, "%s", info->firmware_name);
tsp_debug_info(true, info->dev, "%s: Load firmware : %s, Digital_rev : %d, TSP_ID : %d\n", __func__,
fw_path, info->digital_rev, tspid);
retval = request_firmware(&fw_entry, fw_path, info->dev);
if (retval) {
tsp_debug_err(true, info->dev,
"%s: Firmware image %s not available\n", __func__,
fw_path);
goto done;
}
if (info->digital_rev == FTS_DIGITAL_REV_1 && fw_entry->size!=(FW_IMAGE_SIZE_D1 + sizeof(struct fts64_header))) {
tsp_debug_err(true, info->dev,
"%s: Firmware image %s not available for FTS D1\n", __func__,
fw_path);
goto done;
}
if (info->digital_rev == FTS_DIGITAL_REV_2 && fw_entry->size!=(FW_IMAGE_SIZE_D2 + sizeof(struct fts64_header))) {
tsp_debug_err(true, info->dev,
"%s: Firmware image %s not available for FTS D2\n", __func__,
fw_path);
goto done;
}
fw_data = (unsigned char *)fw_entry->data;
header = (struct fts64_header *)fw_data;
info->fw_version_of_bin = (fw_data[5] << 8)+fw_data[4];
info->fw_main_version_of_bin = (header->released_ver[0] << 8) +
(header->released_ver[1]);
if (info->digital_rev == FTS_DIGITAL_REV_1)
info->config_version_of_bin = (fw_data[CONFIG_OFFSET_BIN_D1] << 8) + fw_data[CONFIG_OFFSET_BIN_D1 - 1];
else
info->config_version_of_bin = (fw_data[CONFIG_OFFSET_BIN_D2] << 8) + fw_data[CONFIG_OFFSET_BIN_D2 - 1];
tsp_debug_info(true, info->dev,
"Bin Firmware Version : 0x%04X "
"Bin Config Version : 0x%04X "
"Bin Main Version : 0x%04X\n",
info->fw_version_of_bin,
info->config_version_of_bin,
info->fw_main_version_of_bin);
if (fts_skip_firmware_update(info, fw_data))
goto done;
if ((info->fw_main_version_of_ic < info->fw_main_version_of_bin)
|| ((info->config_version_of_ic < info->config_version_of_bin))
|| ((info->fw_version_of_ic < info->fw_version_of_bin)))
retval = fts_fw_updater(info, fw_data);
else
retval = FTS_NOT_ERROR;
if (fts_get_system_status(info, &SYS_STAT[0], &SYS_STAT[1]) >= 0) {
if (SYS_STAT[0] != SYS_STAT[1]) {
info->fts_systemreset(info);
msleep(20);
info->fts_wait_for_ready(info);
fts_fw_init(info);
}
}
done:
if (fw_entry)
release_firmware(fw_entry);
return retval;
}
EXPORT_SYMBOL(fts_fw_update_on_probe);
static int fts_load_fw_from_kernel(struct fts_ts_info *info,
const char *fw_path)
{
int retval;
const struct firmware *fw_entry = NULL;
unsigned char *fw_data = NULL;
if (!fw_path) {
tsp_debug_err(true, info->dev, "%s: Firmware name is not defined\n",
__func__);
return -EINVAL;
}
tsp_debug_info(true, info->dev, "%s: Load firmware : %s\n", __func__,
fw_path);
retval = request_firmware(&fw_entry, fw_path, info->dev);
if (retval) {
tsp_debug_err(true, info->dev,
"%s: Firmware image %s not available\n", __func__,
fw_path);
goto done;
}
fw_data = (unsigned char *)fw_entry->data;
if (fts_skip_firmware_update(info, fw_data))
goto done;
if (info->irq)
disable_irq(info->irq);
else
hrtimer_cancel(&info->timer);
info->fts_systemreset(info);
info->fts_wait_for_ready(info);
retval = fts_fw_updater(info, fw_data);
if (retval)
tsp_debug_err(true, info->dev, "%s: failed update firmware\n",
__func__);
if (info->irq)
enable_irq(info->irq);
else
hrtimer_start(&info->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
done:
if (fw_entry)
release_firmware(fw_entry);
return retval;
}
static int fts_load_fw_from_ums(struct fts_ts_info *info)
{
struct file *fp;
mm_segment_t old_fs;
long fw_size, nread;
int error = 0;
old_fs = get_fs();
set_fs(KERNEL_DS);
fp = filp_open(FTS_DEFAULT_UMS_FW, O_RDONLY, S_IRUSR);
if (IS_ERR(fp)) {
tsp_debug_err(true, info->dev, "%s: failed to open %s.\n", __func__,
FTS_DEFAULT_UMS_FW);
error = -ENOENT;
goto open_err;
}
fw_size = fp->f_path.dentry->d_inode->i_size;
if (0 < fw_size) {
unsigned char *fw_data;
const struct fts64_header *header;
fw_data = kzalloc(fw_size, GFP_KERNEL);
nread = vfs_read(fp, (char __user *)fw_data,
fw_size, &fp->f_pos);
tsp_debug_info(true, info->dev,
"%s: start, file path %s, size %ld Bytes\n",
__func__, FTS_DEFAULT_UMS_FW, fw_size);
if (nread != fw_size) {
tsp_debug_err(true, info->dev,
"%s: failed to read firmware file, nread %ld Bytes\n",
__func__, nread);
error = -EIO;
} else {
if (fts_skip_firmware_update(info, fw_data))
goto done;
header = (struct fts64_header *)fw_data;
if (header->signature == FTS64FILE_SIGNATURE) {
if (info->irq)
disable_irq(info->irq);
else
hrtimer_cancel(&info->timer);
info->fts_systemreset(info);
info->fts_wait_for_ready(info);
tsp_debug_info(true, info->dev,
"[UMS] Firmware Version : 0x%04X "
"[UMS] Main Version : 0x%04X\n",
(fw_data[5] << 8)+fw_data[4],
(header->released_ver[0] << 8) +
(header->released_ver[1]));
error = fts_fw_updater(info, fw_data);
if (info->irq)
enable_irq(info->irq);
else
hrtimer_start(&info->timer,
ktime_set(1, 0),
HRTIMER_MODE_REL);
} else {
error = -1;
tsp_debug_err(true, info->dev,
"%s: File type is not match with FTS64 file. [%8x]\n",
__func__, header->signature);
}
}
if (error < 0)
tsp_debug_err(true, info->dev, "%s: failed update firmware\n",
__func__);
done:
kfree(fw_data);
}
filp_close(fp, NULL);
open_err:
set_fs(old_fs);
return error;
}
static int fts_load_fw_from_ffu(struct fts_ts_info *info)
{
int retval;
const struct firmware *fw_entry = NULL;
unsigned char *fw_data = NULL;
const char *fw_path = FTS_DEFAULT_FFU_FW;
const struct fts64_header *header;
if (!fw_path) {
tsp_debug_err(true, info->dev, "%s: Firmware name is not defined\n",
__func__);
return -EINVAL;
}
tsp_debug_info(true, info->dev, "%s: Load firmware : %s\n", __func__,
fw_path);
retval = request_firmware(&fw_entry, fw_path, info->dev);
if (retval) {
tsp_debug_err(true, info->dev,
"%s: Firmware image %s not available\n", __func__,
fw_path);
goto done;
}
if ((info->digital_rev == FTS_DIGITAL_REV_2) &&
(fw_entry->size != (FW_IMAGE_SIZE_D2 + sizeof(struct fts64_header) + SIGNEDKEY_SIZE))) {
tsp_debug_err(true, info->dev,
"%s: Unsigned firmware %s is not available, %ld\n", __func__,
fw_path, fw_entry->size);
retval = -EPERM;
goto done;
}
fw_data = (unsigned char *)fw_entry->data;
header = (struct fts64_header *)fw_data;
info->fw_version_of_bin = (fw_data[5] << 8)+fw_data[4];
info->fw_main_version_of_bin = (header->released_ver[0] << 8) +
(header->released_ver[1]);
if (info->digital_rev == FTS_DIGITAL_REV_1)
info->config_version_of_bin = (fw_data[CONFIG_OFFSET_BIN_D1] << 8) + fw_data[CONFIG_OFFSET_BIN_D1 - 1];
else
info->config_version_of_bin = (fw_data[CONFIG_OFFSET_BIN_D2] << 8) + fw_data[CONFIG_OFFSET_BIN_D2 - 1];
tsp_debug_info(true, info->dev,
"FFU Firmware Version : 0x%04X "
"FFU Config Version : 0x%04X "
"FFU Main Version : 0x%04X\n",
info->fw_version_of_bin,
info->config_version_of_bin,
info->fw_main_version_of_bin);
/* TODO : if you need to check firmware version between IC and Binary,
* add it this position.
*/
if (info->irq)
disable_irq(info->irq);
else
hrtimer_cancel(&info->timer);
info->fts_systemreset(info);
info->fts_wait_for_ready(info);
retval = fts_fw_updater(info, fw_data);
if (retval)
tsp_debug_err(true, info->dev, "%s: failed update firmware\n",
__func__);
if (info->irq)
enable_irq(info->irq);
else
hrtimer_start(&info->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
done:
if (fw_entry)
release_firmware(fw_entry);
return retval;
}
int fts_fw_update_on_hidden_menu(struct fts_ts_info *info, int update_type)
{
int retval = 0;
/* Factory cmd for firmware update
* argument represent what is source of firmware like below.
*
* 0 : [BUILT_IN] Getting firmware which is for user.
* 1 : [UMS] Getting firmware from sd card.
* 2 : none
* 3 : [FFU] Getting firmware from air.
*/
switch (update_type) {
case BUILT_IN:
retval = fts_load_fw_from_kernel(info, info->firmware_name);
break;
case UMS:
retval = fts_load_fw_from_ums(info);
break;
case FFU:
retval = fts_load_fw_from_ffu(info);
break;
default:
tsp_debug_err(true, info->dev, "%s: Not support command[%d]\n",
__func__, update_type);
break;
}
return retval;
}
EXPORT_SYMBOL(fts_fw_update_on_hidden_menu);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,454 @@
#ifndef _LINUX_FTS_TS_H_
#define _LINUX_FTS_TS_H_
#include <linux/device.h>
#include <linux/hrtimer.h>
#include <linux/i2c/fts.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#ifdef CONFIG_SEC_DEBUG_TSP_LOG
#include <linux/sec_debug.h>
#endif
#ifdef CONFIG_INPUT_BOOSTER
#include <linux/input/input_booster.h>
#endif
#ifdef CONFIG_SEC_DEBUG_TSP_LOG
#define tsp_debug_dbg(mode, dev, fmt, ...) \
({ \
if (mode) { \
dev_dbg(dev, fmt, ## __VA_ARGS__); \
sec_debug_tsp_log(fmt, ## __VA_ARGS__); \
} \
else \
dev_dbg(dev, fmt, ## __VA_ARGS__); \
})
#define tsp_debug_info(mode, dev, fmt, ...) \
({ \
if (mode) { \
dev_info(dev, fmt, ## __VA_ARGS__); \
sec_debug_tsp_log(fmt, ## __VA_ARGS__); \
} \
else \
dev_info(dev, fmt, ## __VA_ARGS__); \
})
#define tsp_debug_err(mode, dev, fmt, ...) \
({ \
if (mode) { \
dev_err(dev, fmt, ## __VA_ARGS__); \
sec_debug_tsp_log(fmt, ## __VA_ARGS__); \
} \
else \
dev_err(dev, fmt, ## __VA_ARGS__); \
})
#else
#define tsp_debug_dbg(mode, dev, fmt, ...) dev_dbg(dev, fmt, ## __VA_ARGS__)
#define tsp_debug_info(mode, dev, fmt, ...) dev_info(dev, fmt, ## __VA_ARGS__)
#define tsp_debug_err(mode, dev, fmt, ...) dev_err(dev, fmt, ## __VA_ARGS__)
#endif
#define USE_OPEN_CLOSE
#ifdef USE_OPEN_DWORK
#define TOUCH_OPEN_DWORK_TIME 10
#endif
/*
#define FTS_SUPPORT_STRINGLIB
*/
#define FIRMWARE_IC "fts_ic"
#define FTS_MAX_FW_PATH 64
#define FTS_TS_DRV_NAME "fts_touch"
#define FTS_TS_DRV_VERSION "0132"
#define STM_DEVICE_NAME "STM"
#define FTS_ID0 0x39
#define FTS_ID1 0x80
#define FTS_ID2 0x6C
#define FTS_DIGITAL_REV_1 0x01
#define FTS_DIGITAL_REV_2 0x02
#define FTS_FIFO_MAX 32
#define FTS_EVENT_SIZE 8
#define PRESSURE_MIN 0
#define PRESSURE_MAX 127
#define P70_PATCH_ADDR_START 0x00420000
#define FINGER_MAX 10
#define AREA_MIN PRESSURE_MIN
#define AREA_MAX PRESSURE_MAX
#define EVENTID_NO_EVENT 0x00
#define EVENTID_ENTER_POINTER 0x03
#define EVENTID_LEAVE_POINTER 0x04
#define EVENTID_MOTION_POINTER 0x05
#define EVENTID_HOVER_ENTER_POINTER 0x07
#define EVENTID_HOVER_LEAVE_POINTER 0x08
#define EVENTID_HOVER_MOTION_POINTER 0x09
#define EVENTID_PROXIMITY_IN 0x0B
#define EVENTID_PROXIMITY_OUT 0x0C
#define EVENTID_MSKEY 0x0E
#define EVENTID_ERROR 0x0F
#define EVENTID_CONTROLLER_READY 0x10
#define EVENTID_SLEEPOUT_CONTROLLER_READY 0x11
#define EVENTID_RESULT_READ_REGISTER 0x12
#define EVENTID_STATUS_EVENT 0x16
#define EVENTID_INTERNAL_RELEASE_INFO 0x19
#define EVENTID_EXTERNAL_RELEASE_INFO 0x1A
#define EVENTID_FROM_STRING 0x80
#define EVENTID_GESTURE 0x20
#define EVENTID_SIDE_SCROLL 0x40
#define EVENTID_SIDE_TOUCH_DEBUG 0xDB /* side touch event-id for debug, remove after f/w fixed */
#define EVENTID_SIDE_TOUCH 0x0B
#define STATUS_EVENT_MUTUAL_AUTOTUNE_DONE 0x01
#define STATUS_EVENT_SELF_AUTOTUNE_DONE 0x42
#define STATUS_EVENT_WATER_SELF_AUTOTUNE_DONE 0x4E
#define STATUS_EVENT_FORCE_CAL_DONE 0x15
#ifdef FTS_SUPPORT_WATER_MODE
#define STATUS_EVENT_WATER_SELF_DONE 0x17
#endif
#define STATUS_EVENT_FLASH_WRITE_CONFIG 0x03
#define STATUS_EVENT_FLASH_WRITE_CXTUNE_VALUE 0x04
#define STATUS_EVENT_FORCE_CAL_MUTUAL_SELF 0x05
#define STATUS_EVENT_FORCE_CAL_MUTUAL 0x15
#define STATUS_EVENT_FORCE_CAL_SELF 0x06
#define STATUS_EVENT_WATERMODE_ON 0x07
#define STATUS_EVENT_WATERMODE_OFF 0x08
#define STATUS_EVENT_RTUNE_MUTUAL 0x09
#define STATUS_EVENT_RTUNE_SELF 0x0A
#define STATUS_EVENT_PANEL_TEST_RESULT 0x0B
#define STATUS_EVENT_GLOVE_MODE 0x0C
#define STATUS_EVENT_RAW_DATA_READY 0x0D
#define STATUS_EVENT_MUTUAL_CAL_FRAME_CHECK 0xC1
#define STATUS_EVENT_SELF_CAL_FRAME_CHECK 0xC2
#define STATUS_EVENT_CHARGER_CONNECTED 0xCC
#define STATUS_EVENT_CHARGER_DISCONNECTED 0xCD
#define INT_ENABLE 0x41
#define INT_DISABLE 0x00
#define READ_STATUS 0x84
#define READ_ONE_EVENT 0x85
#define READ_ALL_EVENT 0x86
#define SLEEPIN 0x90
#define SLEEPOUT 0x91
#define SENSEOFF 0x92
#define SENSEON 0x93
#define FTS_CMD_HOVER_OFF 0x94
#define FTS_CMD_HOVER_ON 0x95
#define FTS_CMD_MSKEY_AUTOTUNE 0x96
#define FTS_CMD_TRIM_LOW_POWER_OSCILLATOR 0x97
#define FTS_CMD_KEY_SENSE_OFF 0x9A
#define FTS_CMD_KEY_SENSE_ON 0x9B
#define FTS_CMD_SET_FAST_GLOVE_MODE 0x9D
#define FTS_CMD_MSHOVER_OFF 0x9E
#define FTS_CMD_MSHOVER_ON 0x9F
#define FTS_CMD_SET_NOR_GLOVE_MODE 0x9F
#define FLUSHBUFFER 0xA1
#define FORCECALIBRATION 0xA2
#define CX_TUNNING 0xA3
#define SELF_AUTO_TUNE 0xA4
#define FTS_CMD_CHARGER_PLUGGED 0xA8
#define FTS_CMD_CHARGER_UNPLUGGED 0xAB
#define FTS_CMD_RELEASEINFO 0xAA
#define FTS_CMD_STYLUS_OFF 0xAB
#define FTS_CMD_STYLUS_ON 0xAC
#define FTS_CMD_LOWPOWER_MODE 0xAD
#define FTS_CMS_ENABLE_FEATURE 0xC1
#define FTS_CMS_DISABLE_FEATURE 0xC2
#define FTS_CMD_WRITE_PRAM 0xF0
#define FTS_CMD_BURN_PROG_FLASH 0xF2
#define FTS_CMD_ERASE_PROG_FLASH 0xF3
#define FTS_CMD_READ_FLASH_STAT 0xF4
#define FTS_CMD_UNLOCK_FLASH 0xF7
#define FTS_CMD_SAVE_FWCONFIG 0xFB
#define FTS_CMD_SAVE_CX_TUNING 0xFC
#define FTS_CMD_FAST_SCAN 0x01
#define FTS_CMD_SLOW_SCAN 0x02
#define FTS_CMD_USLOW_SCAN 0x03
#define REPORT_RATE_90HZ 0
#define REPORT_RATE_60HZ 1
#define REPORT_RATE_30HZ 2
#define FTS_CMD_STRING_ACCESS 0xEC00
#define FTS_CMD_NOTIFY 0xC0
#define FTS_RETRY_COUNT 10
/* QUICK SHOT : Quick Camera Launching */
#define FTS_STRING_EVENT_REAR_CAM (1 << 0)
#define FTS_STRING_EVENT_FRONT_CAM (1 << 1)
/* SCRUB : Display Watch, Event Status / Fast Access Event */
#define FTS_STRING_EVENT_WATCH_STATUS (1 << 2)
#define FTS_STRING_EVENT_FAST_ACCESS (1 << 3)
#define FTS_STRING_EVENT_DIRECT_INDICATOR (1 << 3) | (1 << 2)
#define FTS_STRING_EVENT_SPAY (1 << 4)
#define FTS_STRING_EVENT_SPAY1 (1 << 5)
#define FTS_STRING_EVENT_SPAY2 (1 << 4) | (1 << 5)
#define FTS_SIDEGESTURE_EVENT_SINGLE_STROKE 0xE0
#define FTS_SIDEGESTURE_EVENT_DOUBLE_STROKE 0xE1
#define FTS_SIDEGESTURE_EVENT_INNER_STROKE 0xE3
#define FTS_SIDETOUCH_EVENT_LONG_PRESS 0xBB
#define FTS_SIDETOUCH_EVENT_REBOOT_BY_ESD 0xED
#define FTS_ENABLE 1
#define FTS_DISABLE 0
#define FTS_MODE_QUICK_SHOT (1 << 0)
#define FTS_MODE_SCRUB (1 << 1)
#define FTS_MODE_SPAY (1 << 1)
#define FTS_MODE_QUICK_APP_ACCESS (1 << 2)
#define FTS_MODE_DIRECT_INDICATOR (1 << 3)
#define TSP_BUF_SIZE 2048
#define CMD_STR_LEN 32
#define CMD_RESULT_STR_LEN 2048
#define CMD_PARAM_NUM 8
#define FTS_LOWP_FLAG_QUICK_CAM (1 << 0)
#define FTS_LOWP_FLAG_2ND_SCREEN (1 << 1)
#define FTS_LOWP_FLAG_BLACK_UI (1 << 2)
#define FTS_LOWP_FLAG_QUICK_APP_ACCESS (1 << 3)
#define FTS_LOWP_FLAG_DIRECT_INDICATOR (1 << 4)
#define FTS_LOWP_FLAG_SPAY (1 << 5)
#define FTS_LOWP_FLAG_TEMP_CMD (1 << 6)
/* refer to lcd driver to support TB UB */
#define S6E3HF2_WQXGA_ID1 0x404013
#define S6E3HF2_WQXGA_ID2 0x404014
#define SMARTCOVER_COVER // for Various Cover
#ifdef SMARTCOVER_COVER
#define MAX_W 16 // zero is 16 x 28
#define MAX_H 32 // byte size to IC
#define MAX_TX MAX_W
#define MAX_BYTE MAX_H
#endif
enum fts_error_return {
FTS_NOT_ERROR = 0,
FTS_ERROR_INVALID_CHIP_ID,
FTS_ERROR_INVALID_CHIP_VERSION_ID,
FTS_ERROR_INVALID_SW_VERSION,
FTS_ERROR_EVENT_ID,
FTS_ERROR_TIMEOUT,
FTS_ERROR_FW_UPDATE_FAIL,
};
#define RAW_MAX 3750
/**
* struct fts_finger - Represents fingers.
* @ state: finger status (Event ID).
* @ mcount: moving counter for debug.
*/
struct fts_finger {
unsigned char state;
unsigned short mcount;
int lx;
int ly;
};
enum tsp_power_mode {
FTS_POWER_STATE_ACTIVE = 0,
FTS_POWER_STATE_LOWPOWER,
FTS_POWER_STATE_POWERDOWN,
FTS_POWER_STATE_DEEPSLEEP,
};
enum fts_cover_id {
FTS_FLIP_WALLET = 0,
FTS_VIEW_COVER,
FTS_COVER_NOTHING1,
FTS_VIEW_WIRELESS,
FTS_COVER_NOTHING2,
FTS_CHARGER_COVER,
FTS_VIEW_WALLET,
FTS_LED_COVER,
FTS_CLEAR_FLIP_COVER,
FTS_MONTBLANC_COVER = 100,
};
enum fts_customer_feature {
FTS_FEATURE_ORIENTATION_GESTURE = 1,
FTS_FEATURE_STYLUS,
FTS_FEATURE_QUICK_SHORT_CAMERA_ACCESS,
FTS_FEATURE_SIDE_GUSTURE,
FTS_FEATURE_COVER_GLASS,
FTS_FEATURE_COVER_WALLET,
FTS_FEATURE_COVER_LED,
FTS_FEATURE_COVER_CLEAR_FLIP,
FTS_FEATURE_DUAL_SIDE_GUSTURE,
FTS_FEATURE_CUSTOM_COVER_GLASS_ON,
};
struct fts_ts_info {
struct device *dev;
struct i2c_client *client;
struct input_dev *input_dev;
struct hrtimer timer;
struct timer_list timer_charger;
struct timer_list timer_firmware;
struct work_struct work;
int irq;
int irq_type;
bool irq_enabled;
struct fts_i2c_platform_data *board;
void (*register_cb) (void *);
struct fts_callbacks callbacks;
struct mutex lock;
bool enabled;
#ifdef CONFIG_HAS_EARLYSUSPEND
struct early_suspend early_suspend;
#endif
#ifdef SEC_TSP_FACTORY_TEST
struct device *fac_dev_ts;
struct list_head cmd_list_head;
u8 cmd_state;
char cmd[CMD_STR_LEN];
int cmd_param[CMD_PARAM_NUM];
char cmd_result[CMD_RESULT_STR_LEN];
int cmd_buffer_size;
struct mutex cmd_lock;
bool cmd_is_running;
int SenseChannelLength;
int ForceChannelLength;
short *pFrame;
unsigned char *cx_data;
struct delayed_work cover_cmd_work;
int delayed_cmd_param[2];
#endif
bool hover_ready;
bool hover_enabled;
bool mshover_enabled;
bool fast_mshover_enabled;
bool flip_enable;
bool run_autotune;
bool mainscr_disable;
unsigned int cover_type;
unsigned char lowpower_flag;
bool lowpower_mode;
bool deepsleep_mode;
int fts_power_state;
#ifdef FTS_SUPPORT_STRINGLIB
unsigned char fts_mode;
#endif
#ifdef FTS_SUPPORT_TA_MODE
bool TA_Pluged;
#endif
#ifdef FTS_SUPPORT_2NDSCREEN
u8 SIDE_Flag;
u8 previous_SIDE_value;
#endif
#ifdef FTS_SUPPORT_TOUCH_KEY
unsigned char tsp_keystatus;
int touchkey_threshold;
struct device *fac_dev_tk;
#endif
int digital_rev;
int touch_count;
struct fts_finger finger[FINGER_MAX];
int touch_mode;
int retry_hover_enable_after_wakeup;
int ic_product_id; /* product id of ic */
int ic_revision_of_ic; /* revision of reading from IC */
int fw_version_of_ic; /* firmware version of IC */
int ic_revision_of_bin; /* revision of reading from binary */
int fw_version_of_bin; /* firmware version of binary */
int config_version_of_ic; /* Config release data from IC */
int config_version_of_bin; /* Config release data from IC */
unsigned short fw_main_version_of_ic; /* firmware main version of IC */
unsigned short fw_main_version_of_bin; /* firmware main version of binary */
int panel_revision; /* Octa panel revision */
int tspid_val;
int tspid2_val;
#ifdef USE_OPEN_DWORK
struct delayed_work open_work;
#endif
#ifdef FTS_SUPPORT_NOISE_PARAM
struct fts_noise_param noise_param;
int (*fts_get_noise_param_address) (struct fts_ts_info *info);
#endif
unsigned int delay_time;
unsigned int debug_string;
struct delayed_work reset_work;
#ifdef CONFIG_SEC_DEBUG_TSP_LOG
struct delayed_work debug_work;
bool rawdata_read_lock;
#endif
unsigned int scrub_id;
unsigned int scrub_x;
unsigned int scrub_y;
struct mutex i2c_mutex;
struct mutex device_mutex;
bool touch_stopped;
bool reinit_done;
unsigned char data[FTS_EVENT_SIZE * FTS_FIFO_MAX];
unsigned char ddi_type;
const char *firmware_name;
#ifdef SMARTCOVER_COVER
bool smart_cover[MAX_BYTE][MAX_TX];
bool changed_table[MAX_TX][MAX_BYTE];
u8 send_table[MAX_TX][4];
#endif
int (*stop_device) (struct fts_ts_info * info);
int (*start_device) (struct fts_ts_info * info);
int (*fts_write_reg)(struct fts_ts_info *info, unsigned char *reg, unsigned short num_com);
int (*fts_read_reg)(struct fts_ts_info *info, unsigned char *reg, int cnum, unsigned char *buf, int num);
void (*fts_systemreset)(struct fts_ts_info *info);
int (*fts_wait_for_ready)(struct fts_ts_info *info);
void (*fts_command)(struct fts_ts_info *info, unsigned char cmd);
void (*fts_enable_feature)(struct fts_ts_info *info, unsigned char cmd, int enable);
int (*fts_get_version_info)(struct fts_ts_info *info);
#ifdef FTS_SUPPORT_STRINGLIB
int (*fts_read_from_string)(struct fts_ts_info *info, unsigned short *reg, unsigned char *data, int length);
int (*fts_write_to_string)(struct fts_ts_info *info, unsigned short *reg, unsigned char *data, int length);
#endif
};
int fts_fw_update_on_probe(struct fts_ts_info *info);
int fts_fw_update_on_hidden_menu(struct fts_ts_info *info, int update_type);
void fts_fw_init(struct fts_ts_info *info);
void fts_execute_autotune(struct fts_ts_info *info);
int fts_fw_wait_for_event(struct fts_ts_info *info, unsigned char eid);
#endif //_LINUX_FTS_TS_H_