static int write_log(char *filename, char *data)
{
	int fd;
	int cap_file_exist = 0;

	mm_segment_t old_fs = get_fs();
	set_fs(KERNEL_DS);

	if(filename == NULL){
		fd = sys_open(CAP_FILE_PATH, O_WRONLY|O_CREAT|O_APPEND, 0666);
		TOUCH_DBG("write log in /mnt/sdcard/touch_self_test.txt\n");
	} else{
		fd = sys_open(filename, O_WRONLY|O_CREAT, 0666);
		TOUCH_DBG("write log in /sns/touch/cap_diff_test.txt\n");
	}

	TOUCH_DBG("[%s]write file open %s, fd : %d\n", __FUNCTION__, (fd >= 0)? "success": "fail", fd);

	if(fd >= 0) {
		sys_write(fd, data, strlen(data));
		sys_close(fd);

		if(filename != NULL)
			cap_file_exist = 1;
	}
	set_fs(old_fs);

	return cap_file_exist;
}
static int ReadChCount(struct synaptics_ts_data *ts)
{
	int ret = 0;
	u8 data[64] = {0};
	u8 rx_max_cnt = 0;
	u8 tx_max_cnt = 0;
	int i;

	RxChNum = TxChNum = 0;

	/*Read channel count*/
	ret = Touch_I2C_Read(ts->client, RX_CH_CNT_REG, &rx_max_cnt, 1);
	if( ret < 0) {
		return TOUCH_FAIL;
	}
	
	ret = Touch_I2C_Read(ts->client, TX_CH_CNT_REG, &tx_max_cnt, 1);
	if( ret < 0) {
		return TOUCH_FAIL;
	}

	ret = Touch_I2C_Write_Byte(ts->client, PAGE_SELECT_REG, ts->sensor_fc.function_page);
	if( ret < 0) {
		return TOUCH_FAIL;
	}

	ret = Touch_I2C_Read(ts->client, ts->sensor_fc.dsc.data_base+1, data, rx_max_cnt);
	if( ret < 0) {
		return TOUCH_FAIL;
	}

	for (i = 0; i < (int)rx_max_cnt; i++) {
		if (data[i] != 0xFF)
			RxChNum++;
	}

	ret = Touch_I2C_Read(ts->client, ts->sensor_fc.dsc.data_base+2, data, tx_max_cnt);
	if( ret < 0) {
		return TOUCH_FAIL;
	}

	for (i = 0; i < (int)tx_max_cnt; i++) {
		if (data[i] != 0xFF)
			TxChNum++;
	}

	TOUCH_DBG("rx ch cnt = %d, tx ch cnt = %d\n", RxChNum, TxChNum);

	ret = Touch_I2C_Write_Byte(ts->client, PAGE_SELECT_REG, ts->analog_fc.function_page);
	if( ret < 0) {
		return TOUCH_FAIL;
	}

	return TOUCH_SUCCESS;

}
// The following funtion illustrates the steps in getting a full raw image report (report #20) by Function $54.
static int FullRawTest(struct synaptics_ts_data *ts, int mode)
{
	int ret = 0;
	u8 data;

	TestPreparation(ts);

	TOUCH_DBG("[Touch][%s] raw capacitance mode!\n", __FUNCTION__);

	data = 0x14;	//raw capacitance mode
	ret = Touch_I2C_Write(ts->client, REPORT_TYPE_REG, &data, 1);

	//Set the GetReport bit to run the AutoScan
	data = 0x01;
	ret = Touch_I2C_Write(ts->client, ANALOG_COMMAND_REG, &data, 1);
	msleep(WAIT_TIME);

	if (ReadRawData(ts))		//rawdata store mode
		return TOUCH_FAIL;

	return TOUCH_SUCCESS;
}
void SynaBootloaderLock(struct synaptics_ts_data *ts)//no ds4
{
	unsigned short lockBlockCount;
	unsigned char uData[2] = {0};
	unsigned short uBlockNum;
	enum FlashCommand cmd;

	if (my_image_bin[0x1E] == 0)
	{
		TOUCH_DBG( "Skip lockdown process with this .img\n");
		return;
	}
	// Check if device is in unlocked state
	readRMI(ts->client, (SynaF34QueryBase+ 1), &uData[0], 1);

	//Device is unlocked
	if (uData[0] & 0x02)
	{
		TOUCH_DBG("Device unlocked. Lock it first...\n");
		// Different bootloader version has different block count for the lockdown data
		// Need to check the bootloader version from the image file being reflashed
		switch (SynafirmwareImgVersion)
		{
			case 2:
				lockBlockCount = 3;
				break;
			case 3:
			case 4:
				lockBlockCount = 4;
				break;
			case 5:
			case 6:
				lockBlockCount = 5;
				break;
			default:
				lockBlockCount = 0;
				break;
		}

		// Write the lockdown info block by block
		// This reference code of lockdown process does not check for bootloader version
		// currently programmed on the ASIC against the bootloader version of the image to
		// be reflashed. Such case should not happen in practice. Reflashing cross different
		// bootloader versions is not supported.
		for (uBlockNum = 0; uBlockNum < lockBlockCount; ++uBlockNum)
		{
			uData[0] = uBlockNum & 0xff;
			uData[1] = (uBlockNum & 0xff00) >> 8;

			/* Write Block Number */
			writeRMI(ts->client, SynaF34Reflash_BlockNum, &uData[0], 2);

			/* Write Data Block */
			writeRMI(ts->client, SynaF34Reflash_BlockData, SynalockImgData, SynaFirmwareBlockSize);

			/* Move to next data block */
			SynalockImgData += SynaFirmwareBlockSize;

			/* Issue Write Lockdown Block command */
			cmd = m_uF34ReflashCmd_LockDown;
			writeRMI(ts->client, SynaF34_FlashControl, (unsigned char*)&cmd, 1);

			/* Wait ATTN until device is done writing the block and is ready for the next. */
			SynaWaitForATTN(1000,ts);
			CheckFlashStatus(ts,cmd);
		}

		// Enable reflash again to finish the lockdown process.
		// Since this lockdown process is part of the reflash process, we are enabling
		// reflash instead, rather than resetting the device to finish the unlock procedure.
		SynaEnableFlashing(ts);
	}