/* SynaFlashFirmwareWrite writes the firmware section of the image block by block */ void SynaFlashFirmwareWrite(struct i2c_client *client) { unsigned char *puFirmwareData = SynafirmwareImgData; unsigned char uData[2]; unsigned short blockNum; enum FlashCommand cmd; TPD_LOG("%s\n", __func__); for (blockNum = 0; blockNum < SynaFirmwareBlockCount; ++blockNum) { if (blockNum == 0) { /* Block by blcok, write the block number and data to the corresponding F34 data registers */ uData[0] = blockNum & 0xff; uData[1] = (blockNum & 0xff00) >> 8; writeRMI(client, SynaF34Reflash_BlockNum, &uData[0], 2); } writeRMI(client, SynaF34Reflash_BlockData, puFirmwareData, SynaFirmwareBlockSize); puFirmwareData += SynaFirmwareBlockSize; /* Issue the "Write Firmware Block" command */ cmd = m_uF34ReflashCmd_FirmwareWrite; writeRMI(client, SynaF34_FlashControl, (unsigned char *)&cmd, 1); SynaWaitForATTN(1000, client); CheckFlashStatus(cmd, client); /* #ifdef SHOW_PROGRESS */ #if 1 /* APK_TEST */ if (blockNum % 100 == 0) TPD_LOG("blk %d / %d\n", blockNum, SynaFirmwareBlockCount); #endif }
/* SynaEnableFlashing kicks off the reflash process */ void SynaEnableFlashing(struct i2c_client *client) { unsigned char uStatus = 0; enum FlashCommand cmd; TPD_LOG("%s\n", __func__); TPD_LOG("Enable Reflash...\n"); readRMI(client, SynaF01DataBase, &uStatus, 1); /* APK_TEST */ TPD_LOG("APK_TEST uStatus= 0x%02x\n", uStatus); if ((uStatus & 0x40) == 0 /*|| force */) { /* Reflash is enabled by first reading the bootloader ID from the firmware and write it back */ SynaReadBootloadID(client); SynaWriteBootloadID(client); /* Write the "Enable Flash Programming command to F34 Control register */ /* Wait for ATTN and then clear the ATTN. */ cmd = m_uF34ReflashCmd_Enable; writeRMI(client, SynaF34_FlashControl, (unsigned char *)&cmd, 1); SynaWaitForATTN(1000, client); /* I2C addrss may change */ /* ConfigCommunication();//APK_TEST */ /* Scan the PDT again to ensure all register offsets are correct */ SynaScanPDT(client); /* Read the "Program Enabled" bit of the F34 Control register, and proceed only if the */ /* bit is set. */ CheckFlashStatus(cmd, client); } }
/* 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; }
/* EraseConfigBlock erases the config block */ void eraseAllBlock(struct i2c_client *client) { enum FlashCommand cmd; TPD_LOG("%s\n", __func__); /* Erase of config block is done by first entering into bootloader mode */ SynaReadBootloadID(client); SynaWriteBootloadID(client); /* Command 7 to erase config block */ cmd = m_uF34ReflashCmd_EraseAll; writeRMI(client, SynaF34_FlashControl, (unsigned char *)&cmd, 1); SynaWaitForATTN(6000, client); CheckFlashStatus(cmd, client); }
/* 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"); }
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); }