/* drivers/input/touchscreen/sec_ts_fw.c
 *
 * Copyright (C) 2016 Samsung Electronics Co., Ltd.
 * http://www.samsungsemi.com/
 *
 * Core file for Samsung TSC driver
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/time.h>

#include <linux/uaccess.h>

#include "sec_ts.h"

#define SEC_TS_FW_BLK_SIZE 256
/*for hardware info get tp fw version */
extern unsigned int ctp_fw_version_1;
extern unsigned int ctp_fw_version_2;
static u8 sec_ts_fw_data[] = {
	#include "s6d6ft0_v1.10_20170918.i"
};

u8 *sec_get_fwdata(void) { return sec_ts_fw_data; }

int sec_ts_sw_reset(struct sec_ts_data *ts) {
	int ret;

	ret = ts->sec_ts_i2c_write(ts, SEC_TS_CMD_SW_RESET, NULL, 0);
	if (ret < 0) {
		input_err(true, &ts->client->dev, "%s: write fail, sw_reset\n", __func__);
		return 0;
	}

	sec_ts_delay(500);
	input_info(true, &ts->client->dev, "%s: sw_reset\n", __func__);

	return 1;
}

int sec_ts_check_firmware_version(struct sec_ts_data *ts, const u8 *fw_info) {
	struct fw_header *fw_hd;
	u8 data[20] = {0};
	u8 device_id[3] = {0};
	u8 fw_ver[4];
	int ret;
	/*
	 * sec_ts_check_firmware_version
	 * return value = 2 : bootloader mode
	 * return value = 1 : firmware download needed,
	 * return value = 0 : skip firmware download
	 */

	fw_hd = (struct fw_header *)fw_info;

	ret = ts->sec_ts_i2c_read(ts, SEC_TS_READ_DEVICE_ID, device_id, 3);
	if (ret < 0) {
		input_err(true, &ts->client->dev, "%s: failed to read device id(%d)\n",
							__func__, ret);
		return -1;
	}

	input_info(true, &ts->client->dev, "%s: %X, %X, %X\n", __func__, device_id[0],
						 device_id[1], device_id[2]);

	if (device_id[0] == SEC_TS_ID_ON_BOOT)
		return 2;

	ret = ts->sec_ts_i2c_read(ts, SEC_TS_READ_SUB_ID, data, 20);
	if (ret < 0) {
		input_info(true, &ts->client->dev, "%s: firmware version read error\n ",
							 __func__);
		return -1;
	}
	input_info(true, &ts->client->dev,
						 "%s: [IC] Image version info : %x.%x.%x.%x // [BIN] %08X\n",
						 __func__, data[9], data[10], data[11], data[12], fw_hd->version);

	fw_ver[0] = data[9];
	fw_ver[1] = data[10];
	fw_ver[2] = data[11];
	fw_ver[3] = data[12];

	ts->plat_data->img_version_of_ic[0] = fw_ver[0];
	ts->plat_data->img_version_of_ic[1] = fw_ver[1];
	ts->plat_data->img_version_of_ic[2] = fw_ver[2];
	ts->plat_data->img_version_of_ic[3] = fw_ver[3];

	ts->plat_data->img_version_of_bin[0] = (fw_hd->version && 0xFF);
	ts->plat_data->img_version_of_bin[1] = (fw_hd->version >> 8 && 0xFF);
	ts->plat_data->img_version_of_bin[2] = (fw_hd->version >> 16 && 0xFF);
	ts->plat_data->img_version_of_bin[3] = (fw_hd->version >> 24 && 0xFF);

	input_info(true, &ts->client->dev,
						 "%s: [FW] IMG version : %x.%x. [IC] IMG version %x.%x.\n",
						 __func__, (fw_hd->version >> 16) & 0xff,
						 (fw_hd->version >> 24) & 0xff, fw_ver[2], fw_ver[3]);

	if (((fw_hd->version) & 0xff) != fw_ver[0]) {
		input_err(true, &ts->client->dev, "%s: f/w product 0 is not equal: %x\n ",
							__func__, fw_ver[0]);
		return -1;
	}
	if (((fw_hd->version >> 8) & 0xff) != fw_ver[1]) {
		input_err(true, &ts->client->dev, "%s: f/w project 1 is not equal : %x\n ",
							__func__, fw_ver[1]);
		return -1;
	}

	if (((fw_hd->version >> 16) & 0xff) > fw_ver[2]) {
		return 1;
	} else if ((((fw_hd->version >> 16) & 0xff) == fw_ver[2]) &&
						 (((fw_hd->version >> 24) & 0xff) > fw_ver[3])) {
		return 1;
	}

	return 0;
}

static u8 sec_ts_checksum(u8 *data, int offset, int size) {
	int i;
	u8 checksum = 0;

	for (i = 0; i < size; i++)
		checksum += data[i + offset];

	return checksum;
}

/***********************/
/** Ext-flash control **/
/***********************/
#define SEC_TS_CMD_CS_CONTROL				0x8B
#define SEC_TS_CMD_SET_DATA_NUM			0xD1
#define FLASH_CMD_RDSR							0x05
#define FLASH_CMD_WREN							0x06
#define FLASH_CMD_SE 								0x20
#define FLASH_CMD_PP								0x02
#define SEC_TS_CMD_FLASH_SEND_DATA	0xEB
#define SEC_TS_CMD_FLASH_READ_DATA	0xEC

#define CS_LOW	0
#define CS_HIGH	1

#define BYTE_PER_SECTOR				4096
#define BYTE_PER_PAGE					256
#define PAGE_DATA_HEADER_SIZE	4

#define SEC_TS_FLASH_WIP_MASK	0x01
#define SEC_TS_FLASH_SIZE_256	256

#define BYTE_PER_SECTOR				4096
#define BYTE_PER_PAGE					256
#define PAGE_PER_SECTOR				16

static int sec_ts_flash_set_datanum(struct sec_ts_data *ts, u16 num) {
	u8 tData[2];
	int ret;

	tData[0] = (num >> 8) & 0xFF;
	tData[1] = num & 0xFF;

	ret = ts->sec_ts_i2c_write(ts, SEC_TS_CMD_SET_DATA_NUM, tData, 2);
	if (ret < 0)
		input_err(true, &ts->client->dev, "%s: Set datanum Fail %d\n", __func__,
							num);

	return ret;
}

static int sec_ts_flash_cs_control(struct sec_ts_data *ts, bool cs_level) {
	u8 tData;
	int ret;

	tData = cs_level ? 1 : 0;

	ret = ts->sec_ts_i2c_write(ts, SEC_TS_CMD_CS_CONTROL, &tData, 1);
	if (ret < 0)
		input_info(true, &ts->client->dev, "%s: %s control Fail!\n", __func__,
							 cs_level ? "CS High" : "CS Low");
	return ret;
}

static int sec_ts_wren(struct sec_ts_data *ts) {
	u8 tData[2];
	int ret;

	sec_ts_flash_cs_control(ts, CS_LOW);

	sec_ts_flash_set_datanum(ts, 6);

	tData[0] = FLASH_CMD_WREN;
	ret = ts->sec_ts_i2c_write(ts, SEC_TS_CMD_FLASH_SEND_DATA, &tData[0], 1);
	if (ret < 0)
		input_err(true, &ts->client->dev, "%s: Send WREN fail!\n", __func__);

	sec_ts_flash_cs_control(ts, CS_HIGH);

	return ret;
}

static u8 sec_ts_rdsr(struct sec_ts_data *ts) {
	u8 tData[2];

	sec_ts_flash_cs_control(ts, CS_LOW);

	sec_ts_flash_set_datanum(ts, 2);

	tData[0] = FLASH_CMD_RDSR;
	ts->sec_ts_i2c_write(ts, SEC_TS_CMD_FLASH_SEND_DATA, tData, 1);

	sec_ts_flash_set_datanum(ts, 1);

	ts->sec_ts_i2c_read(ts, SEC_TS_CMD_FLASH_READ_DATA, tData, 1);

	sec_ts_flash_cs_control(ts, CS_HIGH);

	return tData[0];
}

static bool IsFlashBusy(struct sec_ts_data *ts) {
	u8 tBuf;

	sec_ts_wren(ts);
	tBuf = sec_ts_rdsr(ts);
	if ((tBuf & SEC_TS_FLASH_WIP_MASK) == SEC_TS_FLASH_WIP_MASK)
		return true;

	return false;
}

static int sec_ts_wait_for_flash_busy(struct sec_ts_data *ts) {
	int retry_cnt = 0;
	int ret = 0;

	while (IsFlashBusy(ts)) {
		sec_ts_delay(10);

		if (retry_cnt++ > SEC_TS_WAIT_RETRY_CNT) { /*RETRY_CNT = 100*/
			input_err(true, &ts->client->dev, "%s: Retry Cnt over!\n", __func__);
			ret = -1;
		}
	}

	return ret;
}

static int sec_ts_cmd_flash_se(struct sec_ts_data *ts, u32 flash_addr) {
	int ret;
	u8 tBuf[5];

	if (IsFlashBusy(ts))
		return false;

	sec_ts_wren(ts);

	sec_ts_flash_cs_control(ts, CS_LOW);

	sec_ts_flash_set_datanum(ts, 5);

	tBuf[0] = SEC_TS_CMD_FLASH_SEND_DATA;
	tBuf[1] = FLASH_CMD_SE;
	tBuf[2] = (flash_addr >> 16) & 0xFF;
	tBuf[3] = (flash_addr >> 8) & 0xFF;
	tBuf[4] = (flash_addr >> 0) & 0xFF;
	ret = ts->sec_ts_i2c_write_burst(ts, tBuf, 5);
	sec_ts_flash_cs_control(ts, CS_HIGH);
	if (ret < 0) {
		input_err(true, &ts->client->dev, "%s: Send sector erase cmd fail!\n",
							__func__);
		return ret;
	}

	ret = sec_ts_wait_for_flash_busy(ts);
	if (ret < 0)
		input_err(true, &ts->client->dev, "%s: Time out! - flash busy wait\n",
							__func__);

	return ret;
}

#ifdef CONFIG_CMD_PP
bool sec_ts_cmd_pp(struct sec_ts_data *ts, int flash_address, u8 *source_data,
									 int byte_length) {
	int data_byte_total_length;
	u8 *tCmd;
	int ret, i;

	if (IsFlashBusy(ts))
		return false;

	sec_ts_wren(ts);

	data_byte_total_length = 1 + 3 + byte_length + 1;
	tCmd = kzalloc(data_byte_total_length, GFP_KERNEL);

	sec_ts_flash_cs_control(ts, CS_LOW);
	sec_ts_flash_set_datanum(ts, 0x104);

	tCmd[0] = SEC_TS_CMD_FLASH_SEND_DATA;
	tCmd[1] = FLASH_CMD_PP;
	tCmd[2] = (flash_address >> 16) & 0xFF;
	tCmd[3] = (flash_address >> 8) & 0xFF;
	tCmd[4] = (flash_address >> 0) & 0xFF;

	for (i = 0; i < byte_length; i++)
		tCmd[5 + i] = source_data[i];

	ret = ts->sec_ts_i2c_write_burst(ts, tCmd, data_byte_total_length);
	sec_ts_flash_cs_control(ts, CS_HIGH);

	if (ret < 0) {
		input_err(true, &ts->client->dev, "%s: PP cmd fail!\n", __func__);
		return false;
	}
	input_dbg(true, &ts->client->dev, "%s : addr = %X%X%X\n", __func__, tCmd[2],
						tCmd[3], tCmd[4]);

	kfree(tCmd);

	while (IsFlashBusy(ts))
		sec_ts_delay(10);

	return true;
}
#endif

static int sec_ts_FlashSectorErase(struct sec_ts_data *ts, u32 sector_idx) {
	u32 addr;
	int ret = 0;

	addr = sector_idx * BYTE_PER_PAGE;

	ret = sec_ts_cmd_flash_se(ts, addr);
	if (ret < 0)
		input_err(true, &ts->client->dev, "%s: Fail!\n", __func__);

	return ret;
}

static bool sec_ts_flashpagewrite(struct sec_ts_data *ts, u32 page_idx,
																	u8 *page_data) {
#ifndef CONFIG_CMD_PP
	int ret;
	int i, j;
	u8 *tCmd;
	u8 copy_data[3 + SEC_TS_FLASH_SIZE_256];
	int copy_left = SEC_TS_FLASH_SIZE_256 + 3;
	int copy_size = 0;
	int copy_max = SEC_TS_FLASH_SIZE_256 + 3;

	copy_data[0] = (u8)((page_idx >> 8) & 0xFF);
	copy_data[1] = (u8)((page_idx >> 0) & 0xFF);
	for (i = 0; i < SEC_TS_FLASH_SIZE_256; i++)
		copy_data[2 + i] = page_data[i];
	copy_data[2 + SEC_TS_FLASH_SIZE_256] =
			sec_ts_checksum(copy_data, 0, 2 + SEC_TS_FLASH_SIZE_256);

	sec_ts_flash_cs_control(ts, CS_LOW);
	while (copy_left > 0) {
		int copy_cur = (copy_left > copy_max) ? copy_max : copy_left;
		tCmd = (u8 *)kzalloc(copy_cur + 1, GFP_KERNEL);
		if (copy_size == 0)
			tCmd[0] = 0xD9;
		else
			tCmd[0] = 0xDA;

		for (j = 0; j < copy_cur; j++)
			tCmd[j + 1] = copy_data[copy_size + j];
		ret = ts->sec_ts_i2c_write_burst(ts, tCmd, 1 + copy_cur);
		if (ret < 0)
			input_err(true, &ts->client->dev, "%s i2c error =  %d\n", __func__,
								copy_left);
		copy_size += copy_cur;
		copy_left -= copy_cur;
		kfree(tCmd);
	}
	sec_ts_delay(5); // add for test
	sec_ts_flash_cs_control(ts, CS_HIGH);

	return ret;
#else
	int size;
	int addr;

	size = BYTE_PER_PAGE;
	addr = page_idx * BYTE_PER_PAGE;

	sec_ts_cmd_pp(ts, addr, page_data, size);

	return true;
#endif
}

static bool sec_ts_flashlimitread(struct sec_ts_data *ts, u32 mem_addr,
																	u32 mem_size, u8 *mem_data) {
	int ret = 0;
	int copy_left = mem_size;
	int copy_size = 0;
	int copy_max = 32;
	u32 copy_addr = mem_addr;
	u8 tCmd[5];
	u8 *copy_data = mem_data;

	sec_ts_flash_cs_control(ts, CS_LOW);
	while (copy_left > 0) {
		int copy_cur = (copy_left > copy_max) ? copy_max : copy_left;

		tCmd[0] = 0xD0;
		tCmd[1] = (u8)((copy_addr >> 24) & 0xff);
		tCmd[2] = (u8)((copy_addr >> 16) & 0xff);
		tCmd[3] = (u8)((copy_addr >> 8) & 0xff);
		tCmd[4] = (u8)((copy_addr >> 0) & 0xff);
		ret = ts->sec_ts_i2c_write_burst(ts, tCmd, 5);
		if (ret < 0) {
			input_info(true, &ts->client->dev, "%s: D0 fail\n", __func__);
			goto burst_err;
		}

		tCmd[0] = 0xD1;
		tCmd[1] = (u8)((copy_cur >> 8) & 0xff);
		tCmd[2] = (u8)((copy_cur >> 0) & 0xff);
		ret = ts->sec_ts_i2c_write_burst(ts, tCmd, 3);
		if (ret < 0) {
			input_info(true, &ts->client->dev, "%s: D1 fail\n", __func__);
			goto burst_err;
		}

		tCmd[0] = 0xDC;
		ret = ts->sec_ts_i2c_read(ts, tCmd[0], &copy_data[copy_size], copy_cur);
		if (ret < 0) {
			input_info(true, &ts->client->dev, "%s: memroy read fail\n", __func__);
			goto burst_err;
		}

		copy_addr += copy_cur;
		copy_size += copy_cur;
		copy_left -= copy_cur;
	}

	sec_ts_flash_cs_control(ts, CS_HIGH);

burst_err:
	return ret;
}

static int sec_ts_flashwrite(struct sec_ts_data *ts, u32 mem_addr, u8 *mem_data,
														 u32 mem_size) {
	int ret;
	int page_idx;
	int size_left;
	int size_copy;
	u32 flash_page_size;
	u32 page_idx_start;
	u32 page_idx_end;
	u32 page_num;
	u8 page_buf[SEC_TS_FLASH_SIZE_256];

	if (mem_size == 0) {
		input_err(true, &ts->client->dev,
							"%s, mem_size 0\n", __func__);
		return 0;
	}

	flash_page_size = SEC_TS_FLASH_SIZE_256;
	page_idx_start = mem_addr / flash_page_size;
	page_idx_end = (mem_addr + mem_size - 1) / flash_page_size;
	page_num = page_idx_end - page_idx_start + 1;

	for (page_idx = (int)((page_num - 1) / 16); page_idx >= 0; page_idx--) {
		ret = sec_ts_FlashSectorErase(ts, (page_idx_start + page_idx * 16));
		if (ret < 0) {
			input_err(true, &ts->client->dev,
								"%s: Sector erase fail! sector_idx = %08X\n", __func__,
								page_idx_start + page_idx * 16);
			return -EIO;
		}
	}
	input_info(true, &ts->client->dev, "%s flash sector erase done\n", __func__);

	sec_ts_delay(page_num + 10);

	size_left = (int)mem_size;
	size_copy = (int)(mem_size % flash_page_size);
	if (size_copy == 0)
		size_copy = (int)flash_page_size;

	memset(page_buf, 0, SEC_TS_FLASH_SIZE_256);

	for (page_idx = (int)page_num - 1; page_idx >= 0; page_idx--) {
		memcpy(page_buf, mem_data + (page_idx * flash_page_size), size_copy);
		ret = sec_ts_flashpagewrite(ts, (u32)(page_idx + page_idx_start), page_buf);
		if (ret < 0) {
			input_err(true, &ts->client->dev, "%s fw write failed, page_idx = %d\n",
								__func__, page_idx);
			goto err;
		}

		size_copy = (int)flash_page_size;
		sec_ts_delay(5);
	}
	input_info(true, &ts->client->dev, "%s flash page write done\n", __func__);

	return mem_size;
err:
	return -EIO;
}

static int sec_ts_flashread(struct sec_ts_data *ts, u32 mem_addr, u8 *mem_data,
														u32 mem_size) {
	int ret;

	if ((mem_size == 0) || (mem_size > 128000))
		return 0;

	ret = sec_ts_flashlimitread(ts, mem_addr, mem_size, mem_data);
	if (ret < 0) {
		input_err(true, &ts->client->dev, "%s fw read failed\n", __func__);
		goto err;
	}
	return mem_size;
err:
	return -EIO;
}
static int sec_ts_chunk_update(struct sec_ts_data *ts, u32 addr, u32 size,
															 u8 *data) {
	int i;
	int ret;
	u32 fw_size;
	u32 write_size;
	u8 *mem_data;
	u8 *mem_rb;

	fw_size = size;

	mem_data = kzalloc(fw_size, GFP_KERNEL);
	if (!mem_data)
		return -ENOMEM;

	memcpy(mem_data, data, sizeof(u8) * fw_size);

	write_size = sec_ts_flashwrite(ts, addr, mem_data, fw_size);
	if (write_size != fw_size) {
		input_err(true, &ts->client->dev, "%s fw write failed\n", __func__);
		return -1;
	}

	input_info(true, &ts->client->dev, "%s flash write done\n", __func__);
	kfree(mem_data);
	sec_ts_delay(1000);

	return 0;
verify_err:
	input_info(true, &ts->client->dev, "%s flash verify failed\n", __func__);
	kfree(mem_data);
	return -ENOMEM;
}

static int sec_ts_firmware_update(struct sec_ts_data *ts, const u8 *data,
																	size_t size) {
	int i, ret;
	u8 device_id[3];
	u8 *fd = (u8 *)data;
	u8 num_chunk;
	struct fw_header *fw_hd;

	fw_hd = (struct fw_header *)fd;

	if (fw_hd->signature != SEC_TS_FW_HEADER_SIGN) {
		input_err(true, &ts->client->dev, "%s: firmware header error = %08X\n",
							__func__, fw_hd->signature);
		return -1;
	}

	num_chunk = fw_hd->NumberOfChunk[0] && 0xFF;
	input_info(true, &ts->client->dev, "%s: num_chunk : %d\n", __func__,
						 num_chunk);
	input_info(true, &ts->client->dev, "%s: 0x%08X, 0x%08X, 0x%zu, 0x%08X\n",
						 __func__, fw_hd->signature, fw_hd->flag, size, fw_hd->setting);

	for (i = 0; i < num_chunk; i++) {
		ret = sec_ts_chunk_update(ts, 0, (u32)size, fd);
		if (ret < 0) {
			input_err(true, &ts->client->dev, "%s: firmware chunk write failed\n",
								__func__);
			return -1;
		}
	}

	ts->sec_ts_i2c_write(ts, SEC_TS_CMD_SW_RESET, NULL, 0);
	sec_ts_delay(500);
	sec_ts_wait_for_ready(ts, SEC_TS_ACK_BOOT_COMPLETE);

	if (ts->sec_ts_i2c_read(ts, SEC_TS_READ_DEVICE_ID, device_id, 3) < 0) {
		input_err(true, &ts->client->dev,
							"%s: read fail, read_boot_status = 0x%x\n", __func__,
							device_id[0]);
		return -1;
	}

	if (device_id[0] != SEC_TS_ID_ON_FW) {
		input_err(
				true, &ts->client->dev,
				"%s: fw update sequence done, BUT fw is not loaded (id[0] = 0x%x)\n",
				__func__, device_id[0]);
		return -1;
	}

	input_err(true, &ts->client->dev, "%s: fw update Success! id[0] = 0x%x\n",
						__func__, device_id[0]);

	return 0;
}

int sec_ts_firmware_update_on_probe(struct sec_ts_data *ts) {
	const struct firmware *fw_entry;
	char fw_path[SEC_TS_MAX_FW_PATH];
	int result = -1;

	disable_irq(ts->client->irq);

	if (!ts->plat_data->firmware_name)
		snprintf(fw_path, SEC_TS_MAX_FW_PATH, "%s", SEC_TS_DEFAULT_FW_NAME);
	else
		snprintf(fw_path, SEC_TS_MAX_FW_PATH, "%s", ts->plat_data->firmware_name);

	input_info(true, &ts->client->dev, "%s: initial firmware update  %s\n",
						 __func__, fw_path);

	/* Loading Firmware */
	if (request_firmware(&fw_entry, fw_path, &ts->client->dev) != 0) {
		input_err(true, &ts->client->dev, "%s: firmware is not available\n",
							__func__);
		goto err_request_fw;
	}
	input_info(true, &ts->client->dev, "%s: request firmware done! size = %d\n",
						 __func__, (int)fw_entry->size);

	result = sec_ts_check_firmware_version(ts, fw_entry->data);
	if (result <= 0)
		goto err_request_fw;

	if (sec_ts_firmware_update(ts, fw_entry->data, fw_entry->size) < 0)
		result = -1;
	else
		result = 0;

err_request_fw:
	release_firmware(fw_entry);
	enable_irq(ts->client->irq);
	return result;
}

int sec_ts_firmwarei_update_on_probe(struct sec_ts_data *ts) {
	int ret;
	int result = -1;
	int fw_size;
	int ctp_fw_version_1;
	int ctp_fw_version_2;

	input_info(true, &ts->client->dev,
						 "%s: initial firmware update with i file\n", __func__);

	fw_size = sizeof(sec_ts_fw_data);
	/* Loading Firmware */
	input_info(true, &ts->client->dev, "%s: request firmware done! size = %d\n",
						 __func__, (int)fw_size);

	result = sec_ts_check_firmware_version(ts, sec_ts_fw_data);
	/*for hardware info get tp fw version */
	ctp_fw_version_1 = ts->plat_data->img_version_of_ic[2];
	ctp_fw_version_2 = ts->plat_data->img_version_of_ic[3];
	if (!ts->force_fwup) {
		if (result < 0)
			goto err_request_fw;
		else if (result == 0)
			goto skip_request_fw;
	}
	if (sec_ts_firmware_update(ts, sec_ts_fw_data, fw_size) < 0) {
		result = -1;
		return result;
	}
	ret = ts->sec_ts_i2c_write(ts, SEC_TS_CMD_CALIBRATION_OFFSET_SDC, NULL, 0);
	if (ret < 0) {
		input_err(true, &ts->client->dev, "%s: calibration fail\n", __func__);
		goto err_request_fw;
	}
	sec_ts_delay(1000);

	ts->sec_ts_i2c_write(ts, SEC_TS_CMD_SW_RESET, NULL, 0);
	sec_ts_delay(500);
	sec_ts_wait_for_ready(ts, SEC_TS_ACK_BOOT_COMPLETE);
	if (result >= 1)
		sec_ts_check_firmware_version(ts, sec_ts_fw_data);
	ctp_fw_version_1 = ts->plat_data->img_version_of_bin[2];
	ctp_fw_version_2 = ts->plat_data->img_version_of_bin[3];
	// after update
	return 0;

err_request_fw:
	return -1;
skip_request_fw:
	return result;
}

static int sec_ts_load_fw_from_ums(struct sec_ts_data *ts) {
	struct fw_header *fw_hd;
	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(SEC_TS_DEFAULT_UMS_FW, O_RDONLY, S_IRUSR);
	if (IS_ERR(fp)) {
		input_err(true, ts->dev, "%s: failed to open %s.\n", __func__,
							SEC_TS_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;

		fw_data = kzalloc(fw_size, GFP_KERNEL);
		nread = vfs_read(fp, (char __user *)fw_data, fw_size, &fp->f_pos);

		input_info(true, ts->dev, "%s: start, file path %s, size %ld Bytes\n",
							 __func__, SEC_TS_DEFAULT_UMS_FW, fw_size);

		if (nread != fw_size) {
			input_err(true, ts->dev,
								"%s: failed to read firmware file, nread %ld Bytes\n", __func__,
								nread);
			error = -EIO;
		} else {
			fw_hd = (struct fw_header *)fw_data;

			input_info(true, &ts->client->dev, "%s: IMG version %08X\n ", __func__,
								 fw_hd->version);

			if (ts->irq)
				disable_irq(ts->irq);
			if (sec_ts_firmware_update(ts, fw_data, fw_size) < 0)
				goto done;
			if (ts->irq)
				enable_irq(ts->irq);
		}

		if (error < 0)
			input_err(true, ts->dev, "%s: failed update firmware\n", __func__);

	done:
		kfree(fw_data);
	}

	filp_close(fp, NULL);

open_err:
	set_fs(old_fs);
	return error;
}

int sec_ts_firmware_update_on_hidden_menu(struct sec_ts_data *ts,
																					int update_type) {
	int ret = 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:
		ret = sec_ts_firmware_update_on_probe(ts);
		break;
	case UMS:
		ret = sec_ts_load_fw_from_ums(ts);
		break;
	case FFU:
		input_err(true, ts->dev, "%s: Not support yet\n", __func__);
		break;
	default:
		input_err(true, ts->dev, "%s: Not support command[%d]\n", __func__,
							update_type);
		break;
	}
	return ret;
}
EXPORT_SYMBOL(sec_ts_firmware_update_on_hidden_menu);
