/* SynaReadConfigInfo reads the F34 query registers and retrieves the block size * and count of the configuration section of the image to be reflashed */ static void SynaReadConfigInfo(void) { u8 uData[2]; pr_info("tsp fw. : Read Config Info\n"); readRMI(SynaF34ReflashQuery_ConfigBlockSize, uData, 2); SynaConfigBlockSize = uData[0] | (uData[1] << 8); readRMI(SynaF34ReflashQuery_ConfigBlockCount, uData, 2); SynaConfigBlockCount = uData[0] | (uData[1] << 8); SynaConfigImageSize = SynaConfigBlockCount * SynaConfigBlockSize; }
static void RegSetup(void) { unsigned char MaxNumberTx; unsigned char MaxNumberRx; unsigned char command; int i; numberOfRx = 0; numberOfTx = 0; SetPage(0x01); F54_PDTscan(); /* scan for page 0x01 */ SetPage(0x00); F54_PDTscan(); /* scan for page 0x00 */ /* Check Used Rx channels */ readRMI(F11_MaxNumberOfRx_Addr, &MaxNumberRx, 1); SetPage(0x01); F54_PhysicalTx_Addr = F54_PhysicalRx_Addr + MaxNumberRx; readRMI(F54_PhysicalRx_Addr, &RxChannelUsed[0], MaxNumberRx); /* Checking Used Tx channels */ SetPage(0x00); readRMI(F11_MaxNumberOfTx_Addr, &MaxNumberTx, 1); SetPage(0x01); readRMI(F54_PhysicalTx_Addr, &TxChannelUsed[0], MaxNumberTx); /* Check used number of Rx */ for (i = 0; i < MaxNumberRx; i++) { if (RxChannelUsed[i] == 0xff) break; numberOfRx++; } /* Check used number of Tx */ for (i = 0; i < MaxNumberTx; i++) { if (TxChannelUsed[i] == 0xff) break; numberOfTx++; } /* Enabling only the analog image reporting interrupt, and * turn off the rest */ SetPage(0x00); command = 0x08; writeRMI(F01_Control_Base+1, &command, 1); SetPage(0x01); }
static void SynaWaitATTN1(void) { unsigned char uData; unsigned char uStatus; //waitATTN(ASSERT, 300); msleep(5); do { readRMI(SynaF34_FlashControl, &uData, 1); //printk("----SynaWaitATTN1-1-1\n"); readRMI((SynaF01DataBase + 1), &uStatus, 1); //printk("----SynaWaitATTN1-1-2\n"); } while (uData!= 0x80); }
/* SynaWaitATTN waits for ATTN to be asserted within a certain time threshold. * The function also checks for the F34 "Program Enabled" bit and clear ATTN * accordingly. */ static void SynaWaitATTN(void) { u8 uData; u8 uStatus; int cnt = 1; while (gpio_get_value(91) && cnt < 30) { //msleep(20); cnt++; } do { readRMI(SynaF34_FlashControl, &uData, 1); readRMI((SynaF01DataBase + 1), &uStatus, 1); } while (uData != 0x80); }
/* 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); }
/* SynaWaitATTN waits for ATTN to be asserted within a certain time threshold. * The function also checks for the F34 "Program Enabled" bit and clear ATTN * accordingly. */ static void SynaWaitATTN(void) { u8 uData; u8 uStatus; int cnt = 0; while (gpio_get_value(gpio_irq) && cnt++ < 300) usleep_range(500, 1000); do { readRMI(SynaF34_FlashControl, &uData, 1); usleep_range(500, 1000); } while ((uData != 0x80) && (cnt++ < 300)); readRMI((SynaF01DataBase + 1), &uStatus, 1); }
/* SynaReadBootloadID reads the F34 query registers and retrieves the bootloader ID of the firmware */ static void SynaReadBootloadID(void) { unsigned char uData[2]; readRMI(SynaF34ReflashQuery_BootID, &uData[0], 2); SynaBootloadID = uData[0] + uData[1] * 0x100; }
/* 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); } }
/* SynaReadConfigInfo reads the F34 query registers and retrieves the block size and count * of the configuration section of the image to be reflashed */ static void SynaReadConfigInfo(void) { unsigned char uData[2]; printk("\nRead Config Info"); readRMI(SynaF34ReflashQuery_ConfigBlockSize, &uData[0], 2); SynaConfigBlockSize = uData[0] | (uData[1] << 8); readRMI(SynaF34ReflashQuery_ConfigBlockCount, &uData[0], 2); SynaConfigBlockCount = uData[0] | (uData[1] << 8); SynaConfigImageSize = SynaConfigBlockCount * SynaConfigBlockSize; printk("\nConfig block:%d count:%d total_size:%lu", SynaConfigBlockSize, SynaConfigBlockCount, SynaConfigImageSize); }
bool readTouchKeyThreshold(struct i2c_client *ts_client, u8 *command) { #if 0 u8 resetCmd; client = ts_client; SetPage(0x02); F54_PDTscan(); /* scan for page 0x02 */ readRMI(F1A_Button_Threshold, command, 2);; // printk("hunny2 : %d 0x%x\n", *command, *command); /* reset TSP IC */ SetPage(0x00); resetCmd = 0x01; writeRMI(F01_Command_Base, &resetCmd, 1); #else *command = 50; // guide by synaptics. #endif return true; }
/* SynaReadFirmwareInfo reads the F34 query registers and retrieves the block size and count * of the firmware section of the image to be reflashed */ static void SynaReadFirmwareInfo(void) { unsigned char uData[2]; printk("\nRead Firmware Info"); readRMI(SynaF34ReflashQuery_FirmwareBlockSize, &uData[0], 2); SynaFirmwareBlockSize = uData[0] | (uData[1] << 8); readRMI(SynaF34ReflashQuery_FirmwareBlockCount, &uData[0], 2); SynaFirmwareBlockCount = uData[0] | (uData[1] << 8); SynaImageSize = SynaFirmwareBlockCount * SynaFirmwareBlockSize; //printk("\nFirmware block:%d count:%d total_size:%lu", // SynaFirmwareBlockSize, SynaFirmwareBlockCount, SynaImageSize); }
void SYNA_PDTScan_BootloaderMode() { unsigned char j, tmp = 255; unsigned char in[10]; unsigned short i; i = 0; j = 0; // reset func addr info index readRMI((i << 8) | PDT_ADDR, &tmp, 1); if(tmp & 0x40) { printk("\nNon-Standard Page Description Table not supported\n"); cleanExit(1); } while(1) { j++; readRMI((i << 8) | (PDT_ADDR - PDT_SIZE*j), in, 6); if(in[5] == 0x00) { // No more functions on this page return; } else if(in[5] == 0x34) { // Function34 F34_Query_Base = (i << 8) | in[0]; F34_Cmd_Base = (i << 8) | in[1]; F34_Ctrl_Base = (i << 8) | in[2]; F34_Data_Base = (i << 8) | in[3]; printk("\n-- RMI Function $%02X, Address = 0x%02x --\n", in[5], (PDT_ADDR - PDT_SIZE*j)); } else if(in[5] == 0x01) { // Function01 F01_Query_Base = (i << 8) | in[0]; F01_Cmd_Base = (i << 8) | in[1]; F01_Ctrl_Base = (i << 8) | in[2]; F01_Data_Base = (i << 8) | in[3]; printk("\n-- RMI Function $%02X, Address = 0x%02x --\n", in[5], (PDT_ADDR - PDT_SIZE*j)); } else { printk("\n-- RMI Function $%02X not supported --\n", in[5]); } } }
/* SynaReadBootloadID reads the F34 query registers and retrieves the bootloader * ID of the firmware */ static void SynaReadBootloadID(void) { u8 uData[2]; pr_info("tsp fw. : SynaReadBootloadID\n"); readRMI(SynaF34ReflashQuery_BootID, uData, 2); SynaBootloadID = uData[0] + uData[1] * 0x100; }
/* SynaReadBootloadID reads the F34 query registers and retrieves the bootloader ID of the firmware */ void SynaReadBootloadID(struct i2c_client *client) { unsigned char uData[2] = { 0, }; TPD_LOG("%s\n", __func__); readRMI(client, SynaF34ReflashQuery_BootID, &uData[0], 2); SynaBootloadID = uData[0] | (uData[1] << 8); }
/* SynaReadFirmwareInfo reads the F34 query registers and retrieves the block size and count * of the firmware section of the image to be reflashed */ void SynaReadFirmwareInfo(struct i2c_client *client) { unsigned char uData[3] = { 0, }; unsigned char product_id[11] = { 0, }; int firmware_version = 0; TPD_LOG("%s\n", __func__); readRMI(client, SynaF01QueryBase + 11, product_id, 10); product_id[10] = '\0'; TPD_LOG("Read Product ID %s\n", product_id); readRMI(client, SynaF01QueryBase + 18, uData, 3); firmware_version = uData[2] << 16 | uData[1] << 8 | uData[0]; TPD_LOG("Read Firmware Info %d\n", firmware_version); CheckTouchControllerType(client); /* CheckFimrwareRevision();//APK_TEST */ }
/* 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 */ ; } } }
/* SynaScanPDT scans the Page Description Table (PDT) and sets up the necessary variables * for the reflash process. This function is a "slim" version of the PDT scan function in * in PDT.c, since only F34 and F01 are needed for reflash. */ void SynaScanPDT(struct i2c_client *client) { unsigned char address = 0; unsigned char uData[2] = { 0, }; unsigned char buffer[6] = { 0, }; TPD_LOG("%s\n", __func__); for (address = 0xe9; address > 0xc0; address = address - 6) { readRMI(client, address, buffer, 6); switch (buffer[5]) { case 0x34: SynaF34DataBase = buffer[3]; SynaF34QueryBase = buffer[0]; break; case 0x01: SynaF01DataBase = buffer[3]; SynaF01CommandBase = buffer[1]; SynaF01QueryBase = buffer[0]; break; } } SynaF34Reflash_BlockNum = SynaF34DataBase; SynaF34Reflash_BlockData = SynaF34DataBase + 1; SynaF34ReflashQuery_BootID = SynaF34QueryBase; SynaF34ReflashQuery_FlashPropertyQuery = SynaF34QueryBase + 1; SynaF34ReflashQuery_BlockSize = SynaF34QueryBase + 2; SynaF34ReflashQuery_FirmwareBlockCount = SynaF34QueryBase + 3; SynaF34_FlashControl = SynaF34DataBase + 2; SynaF34_FlashStatus = SynaF34DataBase + 3; readRMI(client, SynaF34ReflashQuery_FirmwareBlockCount, buffer, 4); SynaFirmwareBlockCount = buffer[0] | (buffer[1] << 8); SynaConfigBlockCount = buffer[2] | (buffer[3] << 8); readRMI(client, SynaF34ReflashQuery_BlockSize, &uData[0], 2); SynaConfigBlockSize = SynaFirmwareBlockSize = uData[0] | (uData[1] << 8); /* cleat ATTN */ readRMI(client, (SynaF01DataBase + 1), buffer, 1); }
bool CheckFlashStatus(enum FlashCommand command, struct i2c_client *client) { unsigned char uData = 0; /* Read the "Program Enabled" bit of the F34 Control register, and proceed only if the */ /* bit is set. */ readRMI(client, SynaF34_FlashStatus, &uData, 1); /* if ((uData & 0x3F) != 0) */ /* printf("Command %s failed.\n\tFlash status : 0x%X\n", SynaFlashCommandStr[command], uData & 0x3F); */ return !(uData & 0x3F); }
bool CheckFlashStatus(struct synaptics_ts_data *ts, enum FlashCommand command)//no ds4 { unsigned char uData = 0; // Read the "Program Enabled" bit of the F34 Control register, and proceed only if the // bit is set. readRMI(ts->client, SynaF34_FlashStatus, &uData, 1); // TOUCH_INFO_MSG("SynaF34_FlashStatus=[%x], uData=[%x]\n", SynaF34_FlashStatus, uData); //if ((uData & 0x3F) != 0) // TOUCH_ERR_MSG( "Command %s failed.\n\tFlash status : 0x%X\n", SynaFlashCommandStr[command], uData & 0x3F); return !(uData & 0x3F); }
/* SynaWaitForATTN waits for ATTN to be asserted within a certain time threshold. */ unsigned int SynaWaitForATTN(int timeout, struct i2c_client *client) { unsigned char uStatus; /* int duration = 50; */ /* int retry = timeout/duration; */ /* int times = 0; */ #ifdef POLLING do { uStatus = 0x00; readRMI((SynaF01DataBase + 1), &uStatus, 1); if (uStatus != 0) break; Sleep(duration); times++; } while (times < retry); if (times == retry) return -1; #else /* if (Line_WaitForAttention(timeout) == EErrorTimeout) */ /* { */ /* return -1; */ /* } */ int trial_us = 0; while ((mt_get_gpio_in(GPIO_CTP_EINT_PIN) != 0) && (trial_us < (timeout * 1000))) { udelay(1); trial_us++; } if (mt_get_gpio_in(GPIO_CTP_EINT_PIN) != 0) { TPD_LOG("interrupt pin is busy..."); return -EBUSY; } readRMI(client, (SynaF01DataBase + 1), &uStatus, 1); #endif return 0; }
/* 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"); }
/* SynaSetup scans the Page Description Table (PDT) and sets up the necessary * variables for the reflash process. This function is a "slim" version of the * PDT scan function in PDT.c, since only F34 and F01 are needed for reflash. */ static void SynaSetup(void) { u8 address; u8 buffer[6]; pr_info("tsp fw. : SynaSetup ++\n"); for (address = 0xe9; address > 0xc0; address = address - 6) { readRMI(address, buffer, 6); switch (buffer[5]) { case 0x34: SynaF34DataBase = buffer[3]; SynaF34QueryBase = buffer[0]; break; case 0x01: SynaF01DataBase = buffer[3]; SynaF01CommandBase = buffer[1]; break; } } SynaF34Reflash_BlockNum = SynaF34DataBase; SynaF34Reflash_BlockData = SynaF34DataBase + 2; SynaF34ReflashQuery_BootID = SynaF34QueryBase; SynaF34ReflashQuery_FlashPropertyQuery = SynaF34QueryBase + 2; SynaF34ReflashQuery_FirmwareBlockSize = SynaF34QueryBase + 3; SynaF34ReflashQuery_FirmwareBlockCount = SynaF34QueryBase + 5; SynaF34ReflashQuery_ConfigBlockSize = SynaF34QueryBase + 3; SynaF34ReflashQuery_ConfigBlockCount = SynaF34QueryBase + 7; SynafirmwareImgData = (u8 *)((&SynaFirmwareData[0]) + 0x100); SynaconfigImgData = (u8 *)(SynafirmwareImgData + SynaImageSize); SynafirmwareImgVersion = (u32)(SynaFirmwareData[7]); switch (SynafirmwareImgVersion) { case 2: SynalockImgData = (u8 *)((&SynaFirmwareData[0]) + 0xD0); break; case 3: case 4: SynalockImgData = (u8 *)((&SynaFirmwareData[0]) + 0xC0); break; case 5: SynalockImgData = (u8 *)((&SynaFirmwareData[0]) + 0xB0); break; default: break; } }
/* 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"); }
void SYNA_ConstructRMI_F54(void) { #ifdef F54_Porting #else unsigned char command; #endif int i; numberOfRx = 0; numberOfTx = 0; MaxButton = 0; for (i = 0 ; i < CFG_F54_TXCOUNT; i++) { ButtonRXUsed[i] = 0; ButtonTXUsed[i] = 0; } F11_MaxNumberOfTx_Addr = F11_Query_Base + 2; F11_MaxNumberOfRx_Addr = F11_Query_Base + 3; //Check Used Rx channels readRMI(F11_MaxNumberOfRx_Addr, &MaxNumberRx, 1); //#ifdef _DS4_3_0_ F54_PhysicalTx_Addr= F54_PhysicalRx_Addr + MaxNumberRx; readRMI(F54_PhysicalRx_Addr, &RxChannelUsed[0], MaxNumberRx); readRMI(F11_MaxNumberOfTx_Addr, &MaxNumberTx, 1); readRMI(F54_PhysicalTx_Addr, &TxChannelUsed[0], MaxNumberTx); //#else #ifdef _DS4_3_2_ readRMI(F55_PhysicalRx_Addr, &RxChannelUsed[0], MaxNumberRx); readRMI(F11_MaxNumberOfTx_Addr, &MaxNumberTx, 1); readRMI(F55_PhysicalRx_Addr + 1, &TxChannelUsed[0], MaxNumberTx); #endif //#endif //Check used number of Rx for(i=0; i<MaxNumberRx; i++) { if(RxChannelUsed[i] == 0xff) break; numberOfRx++; } //Check used number of Tx for(i=0; i<MaxNumberTx; i++) { if(TxChannelUsed[i] == 0xff) break; numberOfTx++; } }
static void F54_PDTscan(void) { unsigned char address; unsigned char buffer[6]; for (address = 0xe9; address > 0xd0; address = address - 6) { readRMI(address, &buffer[0], 6); if (!buffer[5]) break; switch (buffer[5]) { case 0x01: F01_Command_Base = buffer[1]; F01_Control_Base = buffer[2]; F01_Data_Base = buffer[3]; break; case 0x11: F11_Query_Base = buffer[0]; F11_MaxNumberOfTx_Addr = F11_Query_Base + 2; F11_MaxNumberOfRx_Addr = F11_Query_Base + 3; break; case 0x54: F54_Query_Base = buffer[0]; F54_Command_Base = buffer[1]; F54_Control_Base = buffer[2]; F54_Data_Base = buffer[3]; F54_Data_LowIndex = F54_Data_Base + 1; F54_Data_HighIndex = F54_Data_Base + 2; F54_Data_Buffer = F54_Data_Base + 3; F54_CBCSettings = F54_Control_Base + 8; #ifdef _DS4_3_0_ F54_PhysicalRx_Addr = F54_Control_Base + 18; #endif break; case 0x1A: F1A_Query_Base = buffer[0]; F1A_Command_Base = buffer[1]; F1A_Control_Base = buffer[2]; F1A_Data_Base = buffer[3]; F1A_Button_Mapping = F1A_Control_Base + 3; F1A_Button_Threshold = F1A_Control_Base + 19; break; } } }
/* SynaSetup scans the Page Description Table (PDT) and sets up the necessary variables * for the reflash process. This function is a "slim" version of the PDT scan function in * in PDT.c, since only F34 and F01 are needed for reflash. */ static void SynaSetup(void) { unsigned char address; unsigned char buffer[6]; printk("\nSynaSetup... "); for (address = 0xe9; address > 0xdc/*0xc0*/; address = address - 6) { readRMI(address, buffer, 6); //printk("----Finding fn base--buffer[5]=0x%02x---\n",buffer[5]); switch (buffer[5]) { case 0x34: SynaF34DataBase = buffer[3]; SynaF34QueryBase = buffer[0]; break; case 0x01: SynaF01DataBase = buffer[3]; SynaF01CommandBase = buffer[1]; break; } } printk("--[F34] data=0x%02x query=0x%02x [F01] data=0x%02x cmd=0x%02x--\n", SynaF34DataBase, SynaF34QueryBase, SynaF01DataBase, SynaF01CommandBase); SynaF34Reflash_BlockNum = SynaF34DataBase; SynaF34Reflash_BlockData = SynaF34DataBase + 2; SynaF34ReflashQuery_BootID = SynaF34QueryBase; SynaF34ReflashQuery_FlashPropertyQuery = SynaF34QueryBase + 2; SynaF34ReflashQuery_FirmwareBlockSize = SynaF34QueryBase + 3; SynaF34ReflashQuery_FirmwareBlockCount = SynaF34QueryBase +5; SynaF34ReflashQuery_ConfigBlockSize = SynaF34QueryBase + 3; SynaF34ReflashQuery_ConfigBlockCount = SynaF34QueryBase + 7; SynaF34_FlashControl = SynaF34DataBase + SynaFirmwareBlockSize + 2; #if 0 SynafirmwareImgVersion = (unsigned int)(SynaFirmware[7]); switch (SynafirmwareImgVersion) { case 2: SynalockImgData = (unsigned char *)((&SynaFirmware[0]) + 0xD0); break; case 3: SynalockImgData = (unsigned char *)((&SynaFirmware[0]) + 0xC0); break; default: break; } #endif }
/* 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; }
/* 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); }
/* SynaSetup scans the Page Description Table (PDT) and sets up the necessary * variables for the reflash process. */ static void PDTscan(void) { unsigned char address; unsigned char buffer[6]; for (address = 0xe9; address > 0xd0; address = address - 6) { readRMI(address, &buffer[0], 6); if (!buffer[5]) break; switch (buffer[5]) { case 0x01: F01_Command_Base = buffer[1]; F01_Control_Base = buffer[2]; F01_Data_Base = buffer[3]; break; case 0x11: F11_Query_Base = buffer[0]; F11_MaxNumberOfTx_Addr = F11_Query_Base + 2; F11_MaxNumberOfRx_Addr = F11_Query_Base + 3; break; case 0x51: F51_Query_Base = buffer[0]; F51_Command_Base = buffer[1]; F51_Control_Base = buffer[2]; F51_Data_Base = buffer[3]; F51_Feature_Ctrl = F51_Control_Base + 8; break; case 0x54: F54_Query_Base = buffer[0]; F54_Command_Base = buffer[1]; F54_Control_Base = buffer[2]; F54_Data_Base = buffer[3]; F54_Data_LowIndex = F54_Data_Base + 1; F54_Data_HighIndex = F54_Data_Base + 2; F54_Data_Buffer = F54_Data_Base + 3; F54_PhysicalRx_Addr = F54_Control_Base + 18; break; } } }
int synaptics_set_low_temp_bit(const bool set) { u8 command; if (!client) { pr_err("tsp: %s: Can't find i2c client info.\n", __func__); return -1; } SetPage(0x04); PDTscan(); readRMI(F51_Feature_Ctrl, &command, 1); command |= set ? 0x80 : 0x00; writeRMI(F51_Feature_Ctrl, &command, 1); SetPage(0x00); return 0; }