/*
  *
  **************************************************************************
  **                        STMicroelectronics				**
  **************************************************************************
  **                        marco.cali@st.com			          **
  **************************************************************************
  *                                                                        *
  *		FTS Core functions					 *
  *                                                                        *
  **************************************************************************
  **************************************************************************
  *
  */

/*!
  * \file ftsCore.c
  * \brief Contains the implementation of the Core functions
  */

#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include "ftsCompensation.h"
#include "ftsCore.h"
#include "ftsError.h"
#include "ftsIO.h"
#include "ftsTest.h"
#include "ftsTime.h"
#include "ftsTool.h"
#include "ftsFrame.h"

/** @addtogroup system_info
  * @{
  */
SysInfo systemInfo;	/* Global System Info variable, accessible in all the
			 * driver */
/** @}*/

static int reset_gpio = GPIO_NOT_DEFINED;/* /< gpio number of the rest pin,
					  * the value is  GPIO_NOT_DEFINED
					  * if the reset pin is not connected */
static int system_reseted_up;	/* /< flag checked during resume to understand
				 * if there was a system reset
				 * and restore the proper state */
static int system_reseted_down; /* /< flag checked during suspend to understand
				 * if there was a system reset
				 *  and restore the proper state */

/**
  * Initialize core variables of the library.
  * Must be called during the probe before any other lib function
  * @param info pointer to fts_ts_info which contains info about the device and
  * its hw setup
  * @return OK if success or an error code which specify the type of error
  */
int initCore(struct fts_ts_info *info)
{
	int ret = OK;

	pr_info("%s: Initialization of the Core...\n", __func__);
	ret |= openChannel(info->client);
	ret |= resetErrorList();
	ret |= initTestToDo();
	setResetGpio(info->board->reset_gpio);
	if (ret < OK)
		pr_err("%s: Initialization Core ERROR %08X!\n",
			 __func__, ret);
	else
		pr_info("%s: Initialization Finished!\n",
			 __func__);
	return ret;
}

/**
  * Set the reset_gpio variable with the actual gpio number of the board link to
  * the reset pin
  * @param gpio gpio number link to the reset pin of the IC
  */
void setResetGpio(int gpio)
{
	reset_gpio = gpio;
	pr_info("setResetGpio: reset_gpio = %d\n", reset_gpio);
}

/**
  * Perform a system reset of the IC.
  * If the reset pin is associated to a gpio, the function execute an hw reset
  * (toggling of reset pin) otherwise send an hw command to the IC
  * @return OK if success or an error code which specify the type of error
  */
int fts_system_reset(void)
{
	u8 readData[FIFO_EVENT_SIZE];
	int event_to_search;
	int res = -1;
	int i;
	u8 data[1] = { SYSTEM_RESET_VALUE };
#ifdef SUPPORT_PROX_PALM
	struct fts_ts_info *info = NULL;
	info = dev_get_drvdata(&getClient()->dev);
#endif

	event_to_search = (int)EVT_ID_CONTROLLER_READY;

	pr_info("System resetting...\n");
	for (i = 0; i < RETRY_SYSTEM_RESET && res < 0; i++) {
		resetErrorList();
		fts_enableInterrupt(false);
		/* disable interrupt before resetting to be able to get boot
		 * events */

		if (reset_gpio == GPIO_NOT_DEFINED)
			res = fts_writeU8UX(FTS_CMD_HW_REG_W, ADDR_SIZE_HW_REG,
					    ADDR_SYSTEM_RESET, data, ARRAY_SIZE(
						    data));
		else {
			gpio_set_value(reset_gpio, 0);
			msleep(10);
			gpio_set_value(reset_gpio, 1);
			res = OK;
		}
		if (res < OK)
			pr_err("fts_system_reset: ERROR %08X\n", ERROR_BUS_W);
		else {
			res = pollForEvent(&event_to_search, 1, readData,
					   GENERAL_TIMEOUT);
			if (res < OK)
				pr_err("fts_system_reset: ERROR %08X\n", res);
		}
	}
#ifdef SUPPORT_PROX_PALM
	info->prox_palm_status = 0;
#endif
	if (res < OK) {
		pr_err("fts_system_reset...failed after 3 attempts: ERROR %08X\n",
			(res | ERROR_SYSTEM_RESET_FAIL));
		return res | ERROR_SYSTEM_RESET_FAIL;
	} else {
		pr_debug("System reset DONE!\n");
		system_reseted_down = 1;
		system_reseted_up = 1;
		return OK;
	}
}

/**
  * Return the value of system_resetted_down.
  * @return the flag value: 0 if not set, 1 if set
  */
int isSystemResettedDown(void)
{
	return system_reseted_down;
}

/**
  * Return the value of system_resetted_up.
  * @return the flag value: 0 if not set, 1 if set
  */
int isSystemResettedUp(void)
{
	return system_reseted_up;
}


/**
  * Set the value of system_reseted_down flag
  * @param val value to write in the flag
  */
void setSystemResetedDown(int val)
{
	system_reseted_down = val;
}

/**
  * Set the value of system_reseted_up flag
  * @param val value to write in the flag
  */
void setSystemResetedUp(int val)
{
	system_reseted_up = val;
}


/** @addtogroup events_group
  * @{
  */

/**
  * Poll the FIFO looking for a specified event within a timeout. Support a
  * retry mechanism.
  * @param event_to_search pointer to an array of int where each element
  * correspond to a byte of the event to find.
  * If the element of the array has value -1, the byte of the event,
  * in the same position of the element is ignored.
  * @param event_bytes size of event_to_search
  * @param readData pointer to an array of byte which will contain the event
  * found
  * @param time_to_wait time to wait before going in timeout
  * @return OK if success or an error code which specify the type of error
  */
int pollForEvent(int *event_to_search, int event_bytes, u8 *readData, int
		 time_to_wait)
{
	const u8 NO_RESPONSE = 0xFF;
	const int POLL_SLEEP_TIME_MS = 5;
	int i, find, retry, count_err;
	int time_to_count;
	int err_handling = OK;
	StopWatch clock;

	u8 cmd[1] = { FIFO_CMD_READONE };
	char temp[128] = { 0 };

	find = 0;
	retry = 0;
	count_err = 0;
	time_to_count = time_to_wait / POLL_SLEEP_TIME_MS;

	startStopWatch(&clock);
	while (find != 1 && retry < time_to_count &&
		fts_writeReadU8UX(cmd[0], 0, 0, readData, FIFO_EVENT_SIZE,
			DUMMY_FIFO)
	       >= OK) {
		if (readData[0] == NO_RESPONSE ||
		    readData[0] == EVT_ID_NOEVENT) {
			/* No events available, so sleep briefly */
			msleep(POLL_SLEEP_TIME_MS);
			retry++;
			continue;
		} else if (readData[0] == EVT_ID_ERROR) {
			/* Log of errors */
			pr_err("%s\n",
				 printHex("ERROR EVENT = ",
					  readData,
					  FIFO_EVENT_SIZE,
					  temp,
					  sizeof(temp)));
			memset(temp, 0, 128);
			count_err++;
			err_handling = errorHandler(readData, FIFO_EVENT_SIZE);
			if ((err_handling & 0xF0FF0000) ==
			    ERROR_HANDLER_STOP_PROC) {
				pr_err("pollForEvent: forced to be stopped! ERROR %08X\n",
					err_handling);
				return err_handling;
			}
		} else {
			pr_info("%s\n",
				 printHex("READ EVENT = ", readData,
					  FIFO_EVENT_SIZE,
					  temp,
					  sizeof(temp)));
			memset(temp, 0, 128);

			if (readData[0] == EVT_ID_CONTROLLER_READY &&
			    event_to_search[0] != EVT_ID_CONTROLLER_READY) {
				pr_err("pollForEvent: Unmanned Controller Ready Event! Setting reset flags...\n");
				setSystemResetedUp(1);
				setSystemResetedDown(1);
			}
		}

		find = 1;

		for (i = 0; i < event_bytes; i++) {
			if (event_to_search[i] != -1 && (int)readData[i] !=
			    event_to_search[i]) {
				find = 0;
				break;
			}
		}
	}
	stopStopWatch(&clock);
	if ((retry >= time_to_count) && find != 1) {
		pr_err("pollForEvent: ERROR %08X\n", ERROR_TIMEOUT);
		return ERROR_TIMEOUT;
	} else if (find == 1) {
		pr_info("%s\n",
			 printHex("FOUND EVENT = ",
				  readData,
				  FIFO_EVENT_SIZE,
				  temp,
				  sizeof(temp)));
		memset(temp, 0, 128);
		pr_debug("Event found in %d ms (%d iterations)! Number of errors found = %d\n",
			elapsedMillisecond(&clock), retry, count_err);
		return count_err;
	} else {
		pr_err("pollForEvent: ERROR %08X\n", ERROR_BUS_R);
		return ERROR_BUS_R;
	}
}

/** @}*/

/**
  * Check that the FW sent the echo even after a command was sent
  * @param cmd pointer to an array of byte which contain the command previously
  * sent
  * @param size size of cmd
  * @return OK if success or an error code which specify the type of error
  */
int checkEcho(u8 *cmd, int size)
{
	int ret, i;
	int event_to_search[FIFO_EVENT_SIZE];
	u8 readData[FIFO_EVENT_SIZE];


	if (size < 1) {
		pr_err("checkEcho: Error Size = %d not valid!\n", size);
		return ERROR_OP_NOT_ALLOW;
	} else {
		if ((size + 4) > FIFO_EVENT_SIZE)
			size = FIFO_EVENT_SIZE - 4;
		/* Echo event 0x43 0x01 xx xx xx xx xx fifo_status
		 * therefore command with more than 4 bytes will be trunked */

		event_to_search[0] = EVT_ID_STATUS_UPDATE;
		event_to_search[1] = EVT_TYPE_STATUS_ECHO;
		for (i = 2; i < size + 2; i++)
			event_to_search[i] = cmd[i - 2];
		if ((cmd[0] == FTS_CMD_SYSTEM) &&
			(cmd[1] == SYS_CMD_SPECIAL) &&
			((cmd[2] == SPECIAL_FULL_PANEL_INIT) ||
			(cmd[2] == SPECIAL_PANEL_INIT)))
			ret = pollForEvent(event_to_search, size + 2, readData,
				   TIMEOUT_ECHO_FPI);
		else if ((cmd[0] == FTS_CMD_SYSTEM) &&
			(cmd[1] == SYS_CMD_CX_TUNING))
			ret = pollForEvent(event_to_search, size + 2, readData,
				   TIMEOUT_ECHO_SINGLE_ENDED_SPECIAL_AUTOTUNE);
		else if (cmd[0] == FTS_CMD_SYSTEM &&
			 cmd[1] == SYS_CMD_SPECIAL &&
			 cmd[2] == SPECIAL_FIFO_FLUSH)
			ret = pollForEvent(event_to_search, size + 2, readData,
				   TIMEOUT_ECHO_FLUSH);
		else
			ret = pollForEvent(event_to_search, size + 2, readData,
				   TIEMOUT_ECHO);
		if (ret < OK) {
			pr_err("checkEcho: Echo Event not found! ERROR %08X\n",
				ret);
			return ret | ERROR_CHECK_ECHO_FAIL;
		} else if (ret > OK) {
			pr_err("checkEcho: Echo Event found but with some error events before! num_error = %d\n",
				ret);
			return ERROR_CHECK_ECHO_FAIL;
		}

		pr_info("ECHO OK!\n");
		return ret;
	}
}


/** @addtogroup scan_mode
  * @{
  */
/**
  * Set a scan mode in the IC
  * @param mode scan mode to set; possible values @link scan_opt Scan Mode
  * Option @endlink
  * @param settings option for the selected scan mode
  * (for example @link active_bitmask Active Mode Bitmask @endlink)
  * @return OK if success or an error code which specify the type of error
  */
int setScanMode(u8 mode, u8 settings)
{
	u8 cmd[3] = { FTS_CMD_SCAN_MODE, mode, settings };
	u8 cmd1[7] = {0xFA, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00};
	int ret, size = 3;

	pr_debug("%s: Setting scan mode: mode = %02X settings = %02X !\n",
		__func__, mode, settings);
	if (mode == SCAN_MODE_LOW_POWER)
		size = 2;
	ret = fts_write(cmd1, 7);
	if(ret >= OK)
		ret = fts_write(cmd, size);
	/* use write instead of writeFw because can be called while the
	 * interrupt are enabled */
	if (ret < OK) {
		pr_err("%s: write failed...ERROR %08X !\n",
			 __func__, ret);
		return ret | ERROR_SET_SCAN_MODE_FAIL;
	}
	pr_debug("%s: Setting scan mode OK!\n", __func__);
	return OK;
}
/** @}*/


/** @addtogroup feat_sel
  * @{
  */
/**
  * Set a feature and its option in the IC
  * @param feat feature to set; possible values @link feat_opt Feature Selection
  * Option @endlink
  * @param settings pointer to an array of byte which store the options for
  * the selected feature (for example the gesture mask to activate
  * @link gesture_opt Gesture IDs @endlink)
  * @param size in bytes of settings
  * @return OK if success or an error code which specify the type of error
  */
int setFeatures(u8 feat, u8 *settings, int size)
{
	u8 *cmd;
	int i = 0;
	int ret;
	char *buff;
	int buff_len = ((2 + 1) * size + 1) * sizeof(char);
	int index = 0;
	u8 cmd1[7] = {0xFA, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00};

	cmd = kzalloc((2 + size) * sizeof(u8), GFP_KERNEL);
	buff = kzalloc(buff_len, GFP_KERNEL);
	if ((buff == NULL) || (cmd == NULL)) {
		kfree(buff);
		kfree(cmd);
		return ERROR_ALLOC;
        }

	pr_info("%s: Setting feature: feat = %02X !\n", __func__, feat);
	cmd[0] = FTS_CMD_FEATURE;
	cmd[1] = feat;
	for (i = 0; i < size; i++) {
		cmd[2 + i] = settings[i];
		index += scnprintf(buff + index, buff_len - index,
					"%02X ", settings[i]);
	}
	pr_info("%s: Settings = %s\n", __func__, buff);
	ret = fts_write(cmd1, 7);
	if(ret >= OK)
		ret = fts_write(cmd, 2 + size);
	/* use write instead of writeFw because can be called while the
	 * interrupts are enabled */
	if (ret < OK) {
		pr_err("%s: write failed...ERROR %08X !\n", __func__, ret);
		kfree(buff);
		kfree(cmd);
		return ret | ERROR_SET_FEATURE_FAIL;
	}
	pr_info("%s: Setting feature OK!\n", __func__);
	kfree(cmd);
	kfree(buff);
	return OK;
}
/** @}*/

/** @addtogroup sys_cmd
  * @{
  */
/**
  * Write a system command to the IC
  * @param sys_cmd System Command to execute; possible values
  * @link sys_opt System Command Option @endlink
  * @param sett settings option for the selected system command
  * (@link sys_special_opt Special Command Option @endlink, @link ito_opt
  * ITO Test Option @endlink, @link load_opt Load Host Data Option @endlink)
  * @param size in bytes of settings
  * @return OK if success or an error code which specify the type of error
  */
int writeSysCmd(u8 sys_cmd, u8 *sett, int size)
{
	u8 *cmd;
	int ret;
	char *buff;
	int buff_len = ((2 + 1) * size + 1) * sizeof(char);
	int index = 0;
	u8 cmd1[7] = {0xFA, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00};

	cmd = kzalloc((2 + size) * sizeof(u8), GFP_KERNEL);
	buff = kzalloc(buff_len, GFP_KERNEL);
	if ((buff == NULL) || (cmd == NULL)) {
	        kfree(buff);
		kfree(cmd);
		return ERROR_ALLOC;
        }

	cmd[0] = FTS_CMD_SYSTEM;
	cmd[1] = sys_cmd;

	for (ret = 0; ret < size; ret++) {
		cmd[2 + ret] = sett[ret];
		index += scnprintf(buff + index, buff_len - index,
					"%02X ", sett[ret]);
	}
	pr_info("%s: Command = %02X %02X %s\n", __func__, cmd[0],
		 cmd[1], buff);
	pr_info("%s: Writing Sys command...\n", __func__);
	if (sys_cmd != SYS_CMD_LOAD_DATA) {
		ret = fts_write(cmd1, 7);
		if(ret >= OK)
			ret = fts_writeFwCmd(cmd, 2 + size);
	}
	else {
		if (size >= 1)
			ret = requestSyncFrame(sett[0]);
		else {
			pr_err("%s: No setting argument! ERROR %08X\n",
				__func__, ERROR_OP_NOT_ALLOW);
			kfree(cmd);
			kfree(buff);
			return ERROR_OP_NOT_ALLOW;
		}
	}
	if (ret < OK)
		pr_err("%s: ERROR %08X\n", __func__, ret);
	else
		pr_info("%s: FINISHED!\n", __func__);

	kfree(cmd);
	kfree(buff);
	return ret;
}
/** @}*/

/** @addtogroup system_info
  * @{
  */
/**
  * Initialize the System Info Struct with default values according to the error
  * found during the reading
  * @param i2cError 1 if there was an I2C error while reading the System Info
  * data from memory, other value if another error occurred
  * @return OK if success or an error code which specify the type of error
  */
int defaultSysInfo(int i2cError)
{
	int i;

	pr_info("Setting default System Info...\n");

	if (i2cError == 1) {
		systemInfo.u16_fwVer = 0xFFFF;
		systemInfo.u16_cfgProjectId = 0xFFFF;
		for (i = 0; i < RELEASE_INFO_SIZE; i++)
			systemInfo.u8_releaseInfo[i] = 0xFF;
		systemInfo.u16_cxVer = 0xFFFF;
	} else {
		systemInfo.u16_fwVer = 0x0000;
		systemInfo.u16_cfgProjectId = 0x0000;
		for (i = 0; i < RELEASE_INFO_SIZE; i++)
			systemInfo.u8_releaseInfo[i] = 0x00;
		systemInfo.u16_cxVer = 0x0000;
	}

	systemInfo.u8_scrRxLen = 0;
	systemInfo.u8_scrTxLen = 0;

	pr_info("default System Info DONE!\n");
	return OK;
}

/**
  * Read the System Info data from memory. System Info is loaded automatically
  * after every system reset.
  * @param request if 1, will be asked to the FW to reload the data, otherwise
  * attempt to read it directly from memory
  * @return OK if success or an error code which specify the type of error
  */
int readSysInfo(int request)
{
	int ret, i, index = 0;
	u8 sett = LOAD_SYS_INFO;
	u8 data[SYS_INFO_SIZE] = { 0 };
	char temp[256] = { 0 };

	if (request == 1) {
		pr_info("%s: Requesting System Info...\n", __func__);

		ret = writeSysCmd(SYS_CMD_LOAD_DATA, &sett, 1);
		if (ret < OK) {
			pr_err("%s: error while writing the sys cmd ERROR %08X\n",
				__func__, ret);
			goto FAIL;
		}
	}

	pr_info("%s: Reading System Info...\n", __func__);
	ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16,
				ADDR_FRAMEBUFFER, data, SYS_INFO_SIZE,
				DUMMY_FRAMEBUFFER);
	if (ret < OK) {
		pr_err("%s: error while reading the system data ERROR %08X\n",
			__func__, ret);
		goto FAIL;
	}

	pr_info("%s: Parsing System Info...\n", __func__);

	if (data[0] != HEADER_SIGNATURE) {
		pr_err("%s: The Header Signature is wrong!  sign: %02X != %02X ERROR %08X\n",
			__func__, data[0], HEADER_SIGNATURE,
			ERROR_WRONG_DATA_SIGN);
		ret = ERROR_WRONG_DATA_SIGN;
		goto FAIL;
	}


	if (data[1] != LOAD_SYS_INFO) {
		pr_err("%s: The Data ID is wrong!  ids: %02X != %02X ERROR %08X\n",
			__func__, data[3], LOAD_SYS_INFO,
			ERROR_DIFF_DATA_TYPE);
		ret = ERROR_DIFF_DATA_TYPE;
		goto FAIL;
	}

	index += 4;
	u8ToU16(&data[index], &systemInfo.u16_apiVer_rev);
	index += 2;
	systemInfo.u8_apiVer_minor = data[index++];
	systemInfo.u8_apiVer_major = data[index++];
	u8ToU16(&data[index], &systemInfo.u16_chip0Ver);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_chip0Id);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_chip1Ver);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_chip1Id);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_fwVer);
	index += 2;
	pr_info("FW VER = %04X\n", systemInfo.u16_fwVer);
	u8ToU16(&data[index], &systemInfo.u16_svnRev);
	index += 2;
	pr_info("SVN REV = %04X\n", systemInfo.u16_svnRev);
	u8ToU16(&data[index], &systemInfo.u16_cfgVer);
	index += 2;
	pr_info("CONFIG VER = %04X\n", systemInfo.u16_cfgVer);
	u8ToU16(&data[index], &systemInfo.u16_cfgProjectId);
	index += 2;
	pr_info("CONFIG PROJECT ID = %04X\n", systemInfo.u16_cfgProjectId);
	u8ToU16(&data[index], &systemInfo.u16_cxVer);
	index += 2;
	pr_info("CX VER = %04X\n", systemInfo.u16_cxVer);
	u8ToU16(&data[index], &systemInfo.u16_cxProjectId);
	index += 2;
	pr_info("CX PROJECT ID = %04X\n", systemInfo.u16_cxProjectId);
	systemInfo.u8_cfgAfeVer = data[index++];
	systemInfo.u8_cxAfeVer =  data[index++];
	systemInfo.u8_panelCfgAfeVer = data[index++];
	pr_info("AFE VER: CFG = %02X - CX = %02X - PANEL = %02X\n",
		 systemInfo.u8_cfgAfeVer, systemInfo.u8_cxAfeVer,
		 systemInfo.u8_panelCfgAfeVer);
	systemInfo.u8_protocol = data[index++];
	pr_info("Protocol = %02X\n", systemInfo.u8_protocol);
	/* index+= 1; */
	/* skip reserved area */

	/* pr_err("Die Info =  "); */
	for (i = 0; i < DIE_INFO_SIZE; i++)
		systemInfo.u8_dieInfo[i] = data[index++];

	/* pr_err("\n"); */
	pr_info("%s\n",
		 printHex("Die Info =  ",
			  systemInfo.u8_dieInfo,
			  DIE_INFO_SIZE, temp, sizeof(temp)));
	memset(temp, 0, 256);


	/* pr_err("Release Info =  "); */
	for (i = 0; i < RELEASE_INFO_SIZE; i++)
		systemInfo.u8_releaseInfo[i] = data[index++];

	/* pr_err("\n"); */

	pr_info("%s\n",
		 printHex("Release Info =  ",
			  systemInfo.u8_releaseInfo,
			  RELEASE_INFO_SIZE,
			  temp,
			  sizeof(temp)));
	memset(temp, 0, 256);

	u8ToU32(&data[index], &systemInfo.u32_fwCrc);
	index += 4;
	u8ToU32(&data[index], &systemInfo.u32_cfgCrc);
	index += 4;

	index += 4;	/* skip reserved area */

	systemInfo.u8_mpFlag = data[index++];
	pr_info("MP FLAG = %02X\n", systemInfo.u8_mpFlag);

	index += 3 + 4; /* +3 remaining from mp flag address */

	systemInfo.u8_ssDetScanSet = data[index];
	pr_info("SS Detect Scan Select = %d\n",
		 systemInfo.u8_ssDetScanSet);
	index += 4;

	u8ToU16(&data[index], &systemInfo.u16_scrResX);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_scrResY);
	index += 2;
	pr_info("Screen Resolution = %d x %d\n",
		 systemInfo.u16_scrResX, systemInfo.u16_scrResY);
	systemInfo.u8_scrTxLen = data[index++];
	pr_info("TX Len = %d\n", systemInfo.u8_scrTxLen);
	systemInfo.u8_scrRxLen = data[index++];
	pr_info("RX Len = %d\n", systemInfo.u8_scrRxLen);
	systemInfo.u8_keyLen = data[index++];
	pr_info("Key Len = %d\n", systemInfo.u8_keyLen);
	systemInfo.u8_forceLen = data[index++];
	pr_info("Force Len = %d\n", systemInfo.u8_forceLen);
	index += 8;

	u8ToU32(&data[index], &systemInfo.u32_productionTimestamp);
	pr_info("Production Timestamp = %08X\n",
	systemInfo.u32_productionTimestamp);

	index += 32;	/* skip reserved area */

	u8ToU16(&data[index], &systemInfo.u16_dbgInfoAddr);
	index += 2;

	index += 6;	/* skip reserved area */

	u8ToU16(&data[index], &systemInfo.u16_msTchRawAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_msTchFilterAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_msTchStrenAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_msTchBaselineAddr);
	index += 2;

	u8ToU16(&data[index], &systemInfo.u16_ssTchTxRawAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssTchTxFilterAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssTchTxStrenAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssTchTxBaselineAddr);
	index += 2;

	u8ToU16(&data[index], &systemInfo.u16_ssTchRxRawAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssTchRxFilterAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssTchRxStrenAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssTchRxBaselineAddr);
	index += 2;

	u8ToU16(&data[index], &systemInfo.u16_keyRawAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_keyFilterAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_keyStrenAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_keyBaselineAddr);
	index += 2;

	u8ToU16(&data[index], &systemInfo.u16_frcRawAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_frcFilterAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_frcStrenAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_frcBaselineAddr);
	index += 2;

	u8ToU16(&data[index], &systemInfo.u16_ssHvrTxRawAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssHvrTxFilterAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssHvrTxStrenAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssHvrTxBaselineAddr);
	index += 2;

	u8ToU16(&data[index], &systemInfo.u16_ssHvrRxRawAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssHvrRxFilterAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssHvrRxStrenAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssHvrRxBaselineAddr);
	index += 2;

	u8ToU16(&data[index], &systemInfo.u16_ssPrxTxRawAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssPrxTxFilterAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssPrxTxStrenAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssPrxTxBaselineAddr);
	index += 2;

	u8ToU16(&data[index], &systemInfo.u16_ssPrxRxRawAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssPrxRxFilterAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssPrxRxStrenAddr);
	index += 2;
	u8ToU16(&data[index], &systemInfo.u16_ssPrxRxBaselineAddr);
	index += 2;

	u8ToU16(&data[index], &systemInfo.u16_ssDetRawAddr);
	index += 2;

	u8ToU16(&data[index], &systemInfo.u16_ssDetFilterAddr);
	index += 2;

	u8ToU16(&data[index], &systemInfo.u16_ssDetStrenAddr);
	index += 2;

	u8ToU16(&data[index], &systemInfo.u16_ssDetBaselineAddr);
	index += 2;

	pr_info("Parsed %d bytes!\n", index);


	if (index != SYS_INFO_SIZE) {
		pr_err("%s: index = %d different from %d ERROR %08X\n",
			__func__, index, SYS_INFO_SIZE,
			ERROR_OP_NOT_ALLOW);
		return ERROR_OP_NOT_ALLOW;
	}

	pr_info("System Info Read DONE!\n");
	return OK;

FAIL:
	defaultSysInfo(isI2cError(ret));
	return ret;
}
/** @}*/


/**
  * Read data from the Config Memory
  * @param offset Starting address in the Config Memory of data to read
  * @param outBuf pointer of a byte array which contain the bytes to read
  * @param len number of bytes to read
  * @return OK if success or an error code which specify the type of error
  */
int readConfig(u16 offset, u8 *outBuf, int len)
{
	int ret;
	u64 final_address = offset + ADDR_CONFIG_OFFSET;

	pr_info("%s: Starting to read config memory at %llx ...\n",
		__func__, final_address);
	ret = fts_writeReadU8UX(FTS_CMD_CONFIG_R, BITS_16, final_address,
				outBuf, len, DUMMY_CONFIG);
	if (ret < OK) {
		pr_err("%s: Impossible to read Config Memory... ERROR %08X!\n",
			__func__, ret);
		return ret;
	}

	pr_info("%s: Read config memory FINISHED!\n", __func__);
	return OK;
}

/**
  * Write data into the Config Memory
  * @param offset Starting address in the Config Memory where write the data
  * @param data pointer of a byte array which contain the data to write
  * @param len number of bytes to write
  * @return OK if success or an error code which specify the type of error
  */
int writeConfig(u16 offset, u8 *data, int len)
{
	int ret;
	u64 final_address = offset + ADDR_CONFIG_OFFSET;

	pr_info("%s: Starting to write config memory at %llx ...\n",
		__func__, final_address);
	ret = fts_writeU8UX(FTS_CMD_CONFIG_W, BITS_16, final_address, data,
			    len);
	if (ret < OK) {
		pr_err("%s: Impossible to write Config Memory... ERROR %08X!\n",
			__func__, ret);
		return ret;
	}

	pr_info("%s: Write config memory FINISHED!\n", __func__);
	return OK;
}

/* Set the interrupt state
 * @param enable Indicates whether interrupts should enabled.
 * @return OK if success
 */
int fts_enableInterrupt(bool enable)
{
	struct fts_ts_info *info = NULL;
	unsigned long flag;

	if (getClient() == NULL) {
		pr_err("Cannot get client irq. Error = %08X\n",
			ERROR_OP_NOT_ALLOW);
		return ERROR_OP_NOT_ALLOW;
	}
	info = dev_get_drvdata(&getClient()->dev);

	spin_lock_irqsave(&info->fts_int, flag);

	if (enable == info->irq_enabled)
		pr_debug("Interrupt is already set (enable = %d).\n", enable);
	else {
		info->irq_enabled = enable;
		if (enable) {
			enable_irq(getClient()->irq);
			pr_debug("Interrupt enabled.\n");
		} else {
			disable_irq_nosync(getClient()->irq);
			pr_debug("Interrupt disabled.\n");
		}
	}

	spin_unlock_irqrestore(&info->fts_int, flag);
	return OK;
}

/**
  * Check if there is a crc error in the IC which prevent the fw to run.
  * @return  OK if no CRC error, or a number >OK according the CRC error found
  */
int fts_crc_check(void)
{
	u8 val;
	u8 crc_status;
	int res;
	u8 error_to_search[6] = { EVT_TYPE_ERROR_CRC_CFG_HEAD,
				  EVT_TYPE_ERROR_CRC_CFG,
				  EVT_TYPE_ERROR_CRC_CX,
				  EVT_TYPE_ERROR_CRC_CX_HEAD,
				  EVT_TYPE_ERROR_CRC_CX_SUB,
				  EVT_TYPE_ERROR_CRC_CX_SUB_HEAD };


	res = fts_writeReadU8UX(FTS_CMD_HW_REG_R, ADDR_SIZE_HW_REG, ADDR_CRC,
				&val, 1, DUMMY_HW_REG);
	/* read 2 bytes because the first one is a dummy byte! */
	if (res < OK) {
		pr_err("%s Cannot read crc status ERROR %08X\n", __func__, res);
		return res;
	}

	crc_status = val & CRC_MASK;
	if (crc_status != OK) {	/* CRC error if crc_status!=0 */
		pr_err("%s CRC ERROR = %02X\n", __func__, crc_status);
		return CRC_CODE;
	}

	pr_info("%s: Verifying if Config CRC Error...\n", __func__);
	res = fts_system_reset();
	if (res >= OK) {
		res = pollForErrorType(error_to_search, 2);
		if (res < OK) {
			pr_info("%s: No Config CRC Error Found!\n", __func__);
			pr_info("%s: Verifying if Cx CRC Error...\n", __func__);
			res = pollForErrorType(&error_to_search[2], 4);
			if (res < OK) {
				pr_info("%s: No Cx CRC Error Found!\n",
					__func__);
				return OK;
			} else {
				pr_err("%s: Cx CRC Error found! CRC ERROR = %02X\n",
					__func__, res);
				return CRC_CX;
			}
		} else {
			pr_err("%s: Config CRC Error found! CRC ERROR = %02X\n",
				__func__, res);
			return CRC_CONFIG;
		}
	} else {
		pr_err("%s: Error while executing system reset! ERROR %08X\n",
			__func__, res);
		return res;
	}

	return OK;
}

/**
  * Request a host data and use the sync method to understand when the FW load
  * it
  * @param type the type ID of host data to load (@link load_opt Load Host Data
  * Option  @endlink)
  * @return OK if success or an error code which specify the type of error
  */
int requestSyncFrame(u8 type)
{
	u8 request[3] = { FTS_CMD_SYSTEM, SYS_CMD_LOAD_DATA, type };
	u8 readData[DATA_HEADER] = { 0 };
	int ret, retry = 0, retry2 = 0, time_to_count;
	int count, new_count;
	u8 cmd[7] = {0xFA, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00};

	pr_info("%s: Starting to get a sync frame...\n", __func__);

	while (retry2 < RETRY_MAX_REQU_DATA) {
		pr_info("%s: Reading count...\n", __func__);

		ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16,
					ADDR_FRAMEBUFFER, readData, DATA_HEADER,
					DUMMY_FRAMEBUFFER);
		if (ret < OK) {
			pr_err("%s: Error while reading count! ERROR %08X\n",
				__func__, ret | ERROR_REQU_DATA);
			ret |= ERROR_REQU_DATA;
			retry2++;
			continue;
		}

		if (readData[0] != HEADER_SIGNATURE)
			pr_err("%s: Invalid Signature while reading count! ERROR %08X\n",
				__func__, ret | ERROR_REQU_DATA);

		count = (readData[3] << 8) | readData[2];
		new_count = count;
		pr_info("%s: Base count = %d\n", __func__, count);

		pr_info("%s: Requesting frame %02X  attempt = %d\n",
			__func__,  type, retry2 + 1);
		ret = fts_write(cmd, 7);
		if(ret >= OK)
			ret = fts_write(request, ARRAY_SIZE(request));
		if (ret >= OK) {
			pr_info("%s: Polling for new count...\n", __func__);
			time_to_count = TIMEOUT_REQU_DATA / TIMEOUT_RESOLUTION;
			while (count == new_count && retry < time_to_count) {
				ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R,
							BITS_16,
							ADDR_FRAMEBUFFER,
							readData,
							DATA_HEADER,
							DUMMY_FRAMEBUFFER);
				if ((ret >= OK) && (readData[0] ==
						    HEADER_SIGNATURE) &&
				    (readData[1] == type))
					new_count = ((readData[3] << 8) |
						     readData[2]);
				else
					pr_err("%s: invalid Signature or can not read count... ERROR %08X\n",
						__func__, ret);
				retry++;
				mdelay(TIMEOUT_RESOLUTION);
			}

			if (count == new_count) {
				pr_err("%s: New count not received! ERROR %08X\n",
					__func__,
					ERROR_TIMEOUT | ERROR_REQU_DATA);
				ret = ERROR_TIMEOUT | ERROR_REQU_DATA;
			} else {
				pr_info("%s: New count found! count = %d! Frame ready!\n",
					__func__, new_count);
				return OK;
			}
		}
		retry2++;
	}
	pr_err("%s: Request Data failed! ERROR %08X\n", __func__, ret);
	return ret;
}

/**
  * Set the Active Scanning Frequency to a defined value
  * @param freq scanning frequency to set in Hz
  * @return OK if success or an error code which specify the type of error
  * @warning The scan frequency can be set only for the MS scan!
  */
int setActiveScanFrequency(u32 freq)
{
	int res;
	u8 temp[2] = { 0 };
	u16 t_cycle;

	pr_info("%s: Setting the scanning frequency to %uHz...\n",
		__func__, freq);

	/* read MRN register */
	res = readConfig(ADDR_CONFIG_MRN, temp, 1);
	if (res < OK) {
		pr_err("%s: error while reading mrn count! ERROR %08X\n",
			__func__, res);
		return res;
	}

	/* setting r count to 0 (= 1 R cycle used) and write it back */
	temp[0] &= (~0x03);
	res = writeConfig(ADDR_CONFIG_MRN, temp, 1);
	if (res < OK) {
		pr_err("%s: error while writing mrn count! ERROR %08X\n",
			__func__, res);
		return res;
	}

	/* set first R cycle slot according the specified frequency */
	/* read T cycle */
	res = readConfig(ADDR_CONFIG_T_CYCLE, temp, 2);
	if (res < OK) {
		pr_err("%s: error while reading T cycle! ERROR %08X\n",
			__func__, res);
		return res;
	}
	t_cycle = ((u16)(temp[1] << 8)) | temp[0];


	/* compute the value of R cycle according the formula
	  * scan_freq = 30Mhz/(2*(T_cycle+R_cycle)) */
	temp[0] = (30000000) / (freq * 2) - t_cycle;
	/* write R cycle in Config Area */
	pr_info("%s: T cycle  = %d (0x%04X) => R0 cycle = %d (0x%02X)\n",
		__func__, t_cycle, t_cycle, temp[0], temp[0]);
	res = writeConfig(ADDR_CONFIG_R0_CYCLE, temp, 1);
	if (res < OK) {
		pr_err("%s: error while writing R0 cycle! ERROR %08X\n",
			__func__, res);
		return res;
	}

	pr_info("%s: Saving Config into the flash ...\n", __func__);
	/* save config */
	temp[0] = SAVE_FW_CONF;
	res = writeSysCmd(SYS_CMD_SAVE_FLASH, temp, 1);
	if (res < OK) {
		pr_err("%s: error while saving config into the flash! ERROR %08X\n",
			__func__, res);
		return res;
	}

	/* system reset */
	res = fts_system_reset();
	if (res < OK) {
		pr_err("%s: error at system reset! ERROR %08X\n",
			__func__, res);
		return res;
	}

	pr_info("%s: Setting the scanning frequency FINISHED!\n", __func__);
	return OK;
}

/**
  * Write Host Data Memory
  * @param type type of data to write
  * @param data pointer to the data which are written
  * @param msForceLen number of force (Tx) channels used with Mutual
  * @param msSenseLen number of sense (Rx) channels used with Mutual
  * @param ssForceLen number of force (Tx) channel used with Self
  * @param ssSenseLen number of sense (Rx) channel used with Self
  * @param save if =1 will save the host data written into the flash
  * @return OK if success or an error code which specify the type of error
  */
int writeHostDataMemory(u8 type, u8 *data, u8 msForceLen, u8 msSenseLen,
			u8 ssForceLen, u8 ssSenseLen, int save)
{
	int res;
	int size = (msForceLen * msSenseLen) + (ssForceLen + ssSenseLen);
	u8 sett = SPECIAL_WRITE_HOST_MEM_TO_FLASH;
	u8 *temp;

	temp = kzalloc((size + SYNCFRAME_DATA_HEADER) * sizeof(u8), GFP_KERNEL);
	if (temp == NULL)
                return ERROR_ALLOC;

	pr_info("%s: Starting to write Host Data Memory\n", __func__);

	temp[0] = 0x5A;
	temp[1] = type;
	temp[5] = msForceLen;
	temp[6] = msSenseLen;
	temp[7] = ssForceLen;
	temp[8] = ssSenseLen;

	memcpy(&temp[16], data, size);

	pr_info("%s: Write Host Data Memory in buffer...\n", __func__);
	res = fts_writeU8UX(FTS_CMD_FRAMEBUFFER_W, BITS_16,
			    ADDR_FRAMEBUFFER, temp, size +
			    SYNCFRAME_DATA_HEADER);

	if (res < OK) {
		pr_err("%s: error while writing the buffer! ERROR %08X\n",
			__func__, res);
		kfree(temp);
		return res;
	}

	/* save host data memory into the flash */
	if (save == 1) {
		pr_info("%s: Trigger writing into the flash...\n", __func__);
		res = writeSysCmd(SYS_CMD_SPECIAL, &sett, 1);
		if (res < OK) {
			pr_err("%s: error while writing into the flash! ERROR %08X\n",
				__func__, res);
			kfree(temp);
			return res;
		}
	}


	pr_info("%s: write Host Data Memory FINISHED!\n", __func__);
	kfree(temp);
	return OK;
}

/*
 * Save MP flag value into the flash
 * @param mpflag Value to write in the MP Flag field
 * @return OK if success or an error code which specify the type of error
 */
int saveMpFlag(u8 mpflag)
{
	int ret = OK;
	u8 panelCfg = SAVE_PANEL_CONF;

	pr_info("%s: Saving MP Flag = %02X\n", __func__, mpflag);
	ret |= writeSysCmd(SYS_CMD_MP_FLAG, &mpflag, 1);
	if (ret < OK)
		pr_err("%s: Error while writing MP flag on ram... ERROR %08X\n",
			__func__, ret);

	ret |= writeSysCmd(SYS_CMD_SAVE_FLASH, &panelCfg, 1);
	if (ret < OK)
		pr_err("%s: Error while saving MP flag on flash... ERROR %08X\n",
			__func__, ret);

	ret |= readSysInfo(1);
	if (ret < OK) {
		pr_err("%s: Error while refreshing SysInfo... ERROR %08X\n",
			__func__, ret);
		return ret;
	}

	pr_info("%s: Saving MP Flag OK!\n", __func__);
	return OK;
}
