bool fw_update_internal(struct i2c_client *ts_client)
{
	not_reset = 1;
	client = ts_client;
	SynaFirmwareData = SynaFirmware;

	FirmwareImage = kzalloc(16000, GFP_KERNEL);
	if (FirmwareImage == NULL) {
		pr_err("tsp fw. : alloc fw. memory failed.\n");
		return false;
	}
	ConfigImage = kzalloc(16000, GFP_KERNEL);
	if (ConfigImage == NULL) {
		pr_err("tsp fw. : alloc fw. memory failed.\n");
		return false;
	}

	SynaInitialize();
	SynaReadConfigInfo();
	SynaReadFirmwareInfo();
	SynaF34_FlashControl = SynaF34DataBase + SynaFirmwareBlockSize + 2;
	SynaEnableFlashing();
	SynaProgramFirmware();
	SynaProgramConfiguration();
	SynaFinalizeReflash();

	kfree(FirmwareImage);
	kfree(ConfigImage);

	not_reset = 0;
	return true;
}
Esempio n. 2
0
bool synaptics_fw_update(struct i2c_client *ts_client, const u8 *fw_data,
							const int gpio)
{
	client = ts_client;
	SynaFirmwareData = fw_data;
	gpio_irq = gpio;

	FirmwareImage = kzalloc(16000, GFP_KERNEL);
	if (FirmwareImage == NULL) {
		pr_err("tsp fw. : alloc fw. memory failed.\n");
		return false;
	}
	ConfigImage = kzalloc(16000, GFP_KERNEL);
	if (ConfigImage == NULL) {
		pr_err("tsp fw. : alloc fw. memory failed.\n");
		return false;
	}

	SynaInitialize();
	SynaReadConfigInfo();
	SynaReadFirmwareInfo();
	SynaF34_FlashControl = SynaF34DataBase + SynaFirmwareBlockSize + 2;
	SynaEnableFlashing();
	SynaProgramFirmware();
	SynaProgramConfiguration();
	SynaFinalizeReflash();

	kfree(FirmwareImage);
	kfree(ConfigImage);

	pr_info("tsp fw. : fw. update completed.");

	return true;
}
/* SynaBootloaderLock locks down the bootloader
*/
static void SynaBootloaderLock(void)
{
    unsigned short lockBlockCount;
    unsigned char *puFirmwareData = SynalockImgData;
    unsigned char uData[2];
    unsigned short uBlockNum;

    // Check if device is in unlocked state
    readRMI((SynaF34QueryBase+ 2), &uData[0], 1);

    //Device is unlocked
    if (uData[0] & 0x02) {
        printk("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:
            lockBlockCount = 4;
            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 */
            readRMI(SynaF34Reflash_BlockNum, &uData[0], 2);

            /* Write Data Block */
            writeRMI(SynaF34Reflash_BlockData, puFirmwareData, SynaFirmwareBlockSize);

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

            /* Issue Write Lockdown Block command */
            uData[0] = 4;
            writeRMI(SynaF34_FlashControl, &uData[0], 1);

            /* Wait ATTN until device is done writing the block and is ready for the next. */
            SynaWaitATTN();
        }
        printk("Device locking done.\n");

        // 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();
    } else printk("Device already locked.\n");
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_ERR_MSG( "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_ERR_MSG("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);
	}
bool fw_update_file(struct i2c_client *ts_client)
{
	int ret = 0;
	long fw_size = 0;
	unsigned char *fw_data;
	struct file *filp;
	loff_t pos;
	mm_segment_t oldfs;

	client = ts_client;

	oldfs = get_fs();
	set_fs(KERNEL_DS);

	filp = filp_open("/sdcard/synaptics_fw.img", O_RDONLY, 0);
	if (IS_ERR(filp)) {
		pr_err("tsp fw. : file open error:%d\n", (s32)filp);
		return false;
	}

	fw_size = filp->f_path.dentry->d_inode->i_size;
	pr_info("tsp fw. : size of the file : %ld(bytes)\n", fw_size);

	fw_data = kzalloc(fw_size, GFP_KERNEL);

	pos = 0;
	ret = vfs_read(filp, (char __user *)fw_data, fw_size, &pos);
	if (ret != fw_size) {
		pr_err("tsp fw. : failed to read file (ret = %d)\n", ret);
		kfree(fw_data);
		filp_close(filp, current->files);
		return false;
	}

	filp_close(filp, current->files);

	set_fs(oldfs);

	FirmwareImage = kzalloc(16000, GFP_KERNEL);
	if (FirmwareImage == NULL) {
		pr_err("tsp fw. : alloc fw. memory failed.\n");
		return false;
	}
	ConfigImage = kzalloc(16000, GFP_KERNEL);
	if (ConfigImage == NULL) {
		pr_err("tsp fw. : alloc fw. memory failed.\n");
		return false;
	}

	SynaFirmwareData = fw_data;
	SynaInitialize();
	SynaReadConfigInfo();
	SynaReadFirmwareInfo();
	SynaF34_FlashControl = SynaF34DataBase + SynaFirmwareBlockSize + 2;
	SynaEnableFlashing();
	SynaProgramFirmware();
	SynaProgramConfiguration();
	SynaFinalizeReflash();

	kfree(FirmwareImage);
	kfree(ConfigImage);
	kfree(fw_data);

	return true;
}