/* SynaInitialize sets up the reflahs process
 */
static void SynaInitialize(void)
{
    unsigned char uData[1]; // uData[2]
    unsigned char uStatus;

    printk("\nInitializing Reflash Process...");
#define PAGE_SELECT_REG 0xff
    uData[0] = 0x00;
    writeRMI(PAGE_SELECT_REG, uData, 1); //select page 0

    SynafirmwareImgData = 0;

    SynaconfigImgData = 0 ;

    do {
        readRMI(0, &uStatus, 1);

        if (uStatus & 0x80) {
            break;
        }
    } while (uStatus & 0x40);

    SynaSetup();

    //readRMI(SynaF34ReflashQuery_FirmwareBlockSize, &uData[0], 2);

    //SynaFirmwareBlockSize = uData[0] | (uData[1] << 8);
}
/* SynaFinalizeReflash finalizes the reflash process
 */
static void SynaFinalizeReflash(void)
{
    unsigned char uData;
    unsigned char uStatus;

    printk("\nFinalizing Reflash...\n");

    // Issue the "Reset" command to F01 command register to reset the chip
    // This command will also test the new firmware image and check if its is valid
    uData = 1;
    writeRMI(SynaF01CommandBase, &uData, 1);

    SynaWaitForATTN();
    readRMI(SynaF01DataBase, &uData, 1);
    printk("-----SynaFinalizeReflash-1-\n");
    // Sanity check that the reflash process is still enabled
    do {
        readRMI(SynaF34_FlashControl, &uStatus, 1);
        printk("-----SynaFinalizeReflash-2-\n");
    } while ((uStatus & 0x0f) != 0x00);
    printk("-----SynaFinalizeReflash-3-\n");
    readRMI((SynaF01DataBase + 1), &uStatus, 1);
    printk("-----SynaFinalizeReflash-4-\n");
    SynaSetup();
    printk("-----SynaFinalizeReflash-5-\n");
    uData = 0;

    // Check if the "Program Enabled" bit in F01 data register is cleared
    // Reflash is completed, and the image passes testing when the bit is cleared
    do {
        readRMI(SynaF01DataBase, &uData, 1);
        printk("-----SynaFinalizeReflash-6- data=%02x\n", uData);
    } while ((uData & 0x40) != 0);
    printk("-----SynaFinalizeReflash-7-\n");
    // Rescan PDT the update any changed register offsets
    SynaSetup();

    printk("\nReflash Completed. Please reboot.\n");
}
/* SynaEnableFlashing kicks off the reflash process
 */
static int SynaEnableFlashing(void)
{
    unsigned char uData;
    unsigned char uStatus;
    int retry = 3;

    printk("\nEnable Reflash...\n");

    // Reflash is enabled by first reading the bootloader ID from the firmware and write it back
    SynaReadBootloadID();
    SynaWriteBootloadID();

    // Make sure Reflash is not already enabled
    do {
        readRMI(SynaF34_FlashControl, &uData, 1);
        printk("----Read reflash enable ---uData=0x%x--\n",uData);
    } while (uData  ==  0x0f);//while (((uData & 0x0f) != 0x00));

    // Clear ATTN
    readRMI (SynaF01DataBase, &uStatus, 1);
    printk("----Read status ---uStatus=0x%x--\n",uStatus);
    if ((uStatus &0x40) == 0) {
        // Write the "Enable Flash Programming command to F34 Control register
        // Wait for ATTN and then clear the ATTN.
        //uData = 0x0f;    //lemon
        readRMI(SynaF34_FlashControl, &uData, 1);
        uData = uData | 0x0f;  
        writeRMI(SynaF34_FlashControl, &uData, 1);
        SynaWaitForATTN();
        readRMI((SynaF01DataBase + 1), &uStatus, 1);

        // Scan the PDT again to ensure all register offsets are correct
        SynaSetup();

        // Read the "Program Enabled" bit of the F34 Control register, and proceed only if the
        // bit is set.
        readRMI(SynaF34_FlashControl, &uData, 1);
        printk("----read--enable ---uData=0x%x--\n",uData);
        while (uData != 0x80) {
            // In practice, if uData!=0x80 happens for multiple counts, it indicates reflash
            // is failed to be enabled, and program should quit
            printk("%s Can NOT enable reflash !!!\n",__func__);

            if (!retry--)
                return -1;
            readRMI(SynaF34_FlashControl, &uData, 1);
            printk("----read--enable ---uData=0x%x--\n",uData);
        }
    }
    return 0;
}
/* SynaFinalizeReflash finalizes the reflash process
*/
static void SynaFinalizeReflash(void)
{
	u8 uData;
	u8 uStatus;

	pr_info("tsp fw. : Finalizing Reflash..\n");

	/* Issue the "Reset" command to F01 command register to reset the chip
	 This command will also test the new firmware image and check if its is
	 valid */
	uData = 1;
	writeRMI(SynaF01CommandBase, &uData, 1);

	mdelay(300);
	readRMI(SynaF01DataBase, &uData, 1);

	/* Sanity check that the reflash process is still enabled */
	do {
		readRMI(SynaF34_FlashControl, &uStatus, 1);
	} while ((uStatus & 0x0f) != 0x00);
	readRMI((SynaF01DataBase + 1), &uStatus, 1);

	SynaSetup();

	uData = 0;

	/* Check if the "Program Enabled" bit in F01 data register is cleared
	 Reflash is completed, and the image passes testing when the bit is
	 cleared */
	do {
		readRMI(SynaF01DataBase, &uData, 1);
	} while ((uData & 0x40) != 0);

	/* Rescan PDT the update any changed register offsets */
	SynaSetup();

	pr_info("tsp fw. : Reflash Completed. Please reboot.\n");
}
/* SynaEnableFlashing kicks off the reflash process
 */
static void SynaEnableFlashing(void)
{
	u8 uData;
	u8 uStatus;

	pr_info("\nEnable Reflash...");

	/* Reflash is enabled by first reading the bootloader ID from
	   the firmware and write it back */
	SynaReadBootloadID();
	SynaWriteBootloadID();

	/* Make sure Reflash is not already enabled */
	do {
		readRMI(SynaF34_FlashControl, &uData, 1);
	} while (((uData & 0x0f) != 0x00));

	readRMI(SynaF01DataBase, &uStatus, 1);

	if ((uStatus & 0x40) == 0) {
		/* Write the "Enable Flash Programming command to
		F34 Control register Wait for ATTN and then clear the ATTN. */
		uData = 0x0f;
		writeRMI(SynaF34_FlashControl, &uData, 1);
		mdelay(300);
		readRMI((SynaF01DataBase + 1), &uStatus, 1);

		/* Scan the PDT again to ensure all register offsets are
		correct */
		SynaSetup();

		/* Read the "Program Enabled" bit of the F34 Control register,
		and proceed only if the bit is set.*/
		readRMI(SynaF34_FlashControl, &uData, 1);

		while (uData != 0x80) {
			/* In practice, if uData!=0x80 happens for multiple
			counts, it indicates reflash is failed to be enabled,
			and program should quit */
			;
		}
	}
}
/* SynaInitialize sets up the reflahs process
 */
static void SynaInitialize(void)
{
	u8 uData[2];

	pr_info("tsp fw. : Initializing Reflash Process...\n");

	uData[0] = 0x00;
	writeRMI(0xff, uData, 1);

	SynaSetup();

	SynafirmwareImgData = &FirmwareImage[0];
	SynaconfigImgData = &ConfigImage[0];

	readRMI(SynaF34ReflashQuery_FirmwareBlockSize, uData, 2);

	SynaFirmwareBlockSize = uData[0] | (uData[1] << 8);

}