int mxt_load_firmware(struct device *dev, const char *fn) { struct mxt_data *mxt = dev_get_drvdata(dev); unsigned int frame_size; unsigned int pos = 0; unsigned int retry; int ret; #if READ_FW_FROM_HEADER struct firmware *fw = NULL; fw = kzalloc(sizeof(struct firmware), GFP_KERNEL); fw->data = firmware_latest; fw->size = sizeof(firmware_latest); #else const struct firmware *fw = NULL; ret = request_firmware(&fw, fn, dev); if (ret < 0) { dev_err(&client->dev, "[TSP] Unable to open firmware %s\n", fn); return -ENOMEM; } #endif /* set resets into bootloader mode */ reset_chip(mxt, RESET_TO_BOOTLOADER); msleep(250); /* mdelay(100); */ /* change to slave address of bootloader */ if (mxt->client->addr == MXT_I2C_APP_ADDR) { pr_info("[TSP] I2C address: 0x%02X --> 0x%02X", MXT_I2C_APP_ADDR, MXT_I2C_BOOTLOADER_ADDR); mxt->client->addr = MXT_I2C_BOOTLOADER_ADDR; } ret = check_bootloader(mxt->client, WAITING_BOOTLOAD_COMMAND); if (ret < 0) { pr_err("[TSP] ... Waiting bootloader command: Failed"); goto err_fw; } /* unlock bootloader */ unlock_bootloader(mxt->client); msleep(200); /* mdelay(100); */ /* reading the information of the firmware */ pr_info("[TSP] Firmware info: version [0x%02X], build [0x%02X]", fw->data[0], fw->data[1]); pr_info("Updating progress: "); pos += 2; while (pos < fw->size) { retry = 0; ret = check_bootloader(mxt->client, WAITING_FRAME_DATA); if (ret < 0) { pr_err("... Waiting frame data: Failed"); goto err_fw; } frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1)); /* We should add 2 at frame size as the the firmware data is not * included the CRC bytes. */ frame_size += 2; /* write one frame to device */ try_to_resend_the_last_frame: i2c_master_send(mxt->client, (u8 *)(fw->data + pos), frame_size); ret = check_bootloader(mxt->client, FRAME_CRC_PASS); if (ret < 0) { if (++retry < 10) { check_bootloader(mxt->client, WAITING_FRAME_DATA); /* recommendation from ATMEL */ pr_info("[TSP] We've got a FRAME_CRC_FAIL, so try again up to 10 times (count=%d)", retry); goto try_to_resend_the_last_frame; } pr_err("... CRC on the frame failed after 10 trials!"); goto err_fw; } pos += frame_size; pr_info("#"); pr_info("%zd / %zd (bytes) updated...", pos, fw->size); } pr_info("\n[TSP] Updating firmware completed!\n"); pr_info("[TSP] note: You may need to reset this target.\n"); err_fw: /* change to slave address of application */ if (mxt->client->addr == MXT_I2C_BOOTLOADER_ADDR) { pr_info("[TSP] I2C address: 0x%02X --> 0x%02X", MXT_I2C_BOOTLOADER_ADDR, MXT_I2C_APP_ADDR); mxt->client->addr = MXT_I2C_APP_ADDR; } #if READ_FW_FROM_HEADER kfree(fw); #endif return ret; }
void check_fwbl(struct ssp_data *data) { int iRet; data->client->addr = BOOTLOADER_SLAVE_ADDR; iRet = check_bootloader(data->client, BL_WAITING_BOOTLOAD_CMD); if (iRet >= 0) { pr_info("[SSP] ssp_load_fw_bootmode\n"); load_fw_bootmode(data->client, BL_FW_NAME); msleep(SSP_SW_RESET_TIME); } else { data->client->addr = APP_SLAVE_ADDR; data->uCurFirmRev = get_firmware_rev(data); if (data->uCurFirmRev != SSP_FIRMWARE_REVISION) { pr_info("[SSP] MPU Firm Rev. : Old = %8u, New = %8u\n", data->uCurFirmRev, SSP_FIRMWARE_REVISION); update_mcu_bin(data); } } data->client->addr = APP_SLAVE_ADDR; data->uCurFirmRev = get_firmware_rev(data); pr_info("[SSP] MPU Firm Rev. : Old = %8u, New = %8u\n", data->uCurFirmRev, SSP_FIRMWARE_REVISION); }
int check_fwbl(struct ssp_data *data) { int iRet; unsigned int fw_revision; fw_revision = get_module_rev(data); data->uCurFirmRev = get_firmware_rev(data); if ((data->uCurFirmRev == SSP_INVALID_REVISION) \ || (data->uCurFirmRev == SSP_INVALID_REVISION2)) { iRet = check_bootloader(data, BL_WAITING_BOOTLOAD_CMD); if (iRet >= 0) pr_info("[SSP] ssp_load_fw_bootmode\n"); else { pr_warn("[SSP] Firm Rev is invalid(%8u). Retry.\n", data->uCurFirmRev); data->uCurFirmRev = get_firmware_rev(data); } data->uCurFirmRev = SSP_INVALID_REVISION; pr_err("[SSP] SSP_INVALID_REVISION\n"); return FW_DL_STATE_NEED_TO_SCHEDULE; } else { if (data->uCurFirmRev != fw_revision) { pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n", data->uCurFirmRev, fw_revision); return FW_DL_STATE_NEED_TO_SCHEDULE; } pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n", data->uCurFirmRev, fw_revision); } return FW_DL_STATE_NONE; }
int check_fwbl(struct ssp_data *data) { int iRet; unsigned int fw_revision; pr_info("[SSP] change_rev = %d\n", data->ssp_changes); if (data->ssp_changes == SSP_MCU_L0) fw_revision = SSP_FIRMWARE_REVISION; else fw_revision = SSP_FIRMWARE_REVISION_03; data->client->addr = APP_SLAVE_ADDR; data->uCurFirmRev = check_firmware_rev(data); if (data->uCurFirmRev == SSP_INVALID_REVISION) { toggle_mcu_reset(data); msleep(SSP_SW_RESET_TIME); } if ((data->uCurFirmRev == SSP_INVALID_REVISION) \ || (data->uCurFirmRev == SSP_INVALID_REVISION2)) { data->client->addr = BOOTLOADER_SLAVE_ADDR; iRet = check_bootloader(data->client, BL_WAITING_BOOTLOAD_CMD); if (iRet >= 0) { pr_info("[SSP] ssp_load_fw_bootmode\n"); return FW_DL_STATE_NEED_TO_SCHEDULE; } else { pr_warn("[SSP] Firm Rev is invalid(%8u). Retry.\n", data->uCurFirmRev); data->client->addr = APP_SLAVE_ADDR; data->uCurFirmRev = get_firmware_rev(data); if (data->uCurFirmRev == SSP_INVALID_REVISION ||\ data->uCurFirmRev == ERROR) { pr_err("[SSP] MCU is not working, FW download failed\n"); return FW_DL_STATE_FAIL; } else if (data->uCurFirmRev != fw_revision) { pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n", data->uCurFirmRev, fw_revision); return FW_DL_STATE_NEED_TO_SCHEDULE; } pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n", data->uCurFirmRev, fw_revision); } } else { if (data->uCurFirmRev != fw_revision) { pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n", data->uCurFirmRev, fw_revision); return FW_DL_STATE_NEED_TO_SCHEDULE; } pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n", data->uCurFirmRev, fw_revision); } return FW_DL_STATE_NONE; }
int main(void) { _buttonusr_isr = (void *)&buttonisr_usr; _timerusr_isr = (void *)&timerisr_usr; _mmhusr_isr = (void *)&mmhisr; /* Drop privileges */ drop_privs(); /* Init board */ kk_board_init(); /* Program the model into OTP, if we're not in screen-test mode, and it's * not already there */ (void)flash_programModel(); /* Init for safeguard against stack overflow (-fstack-protector-all) */ __stack_chk_guard = (uintptr_t)random32(); /* Bootloader Verification */ check_bootloader(); led_func(SET_RED_LED); dbg_print("Application Version %d.%d.%d\n\r", MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION); /* Init storage */ storage_init(); /* Init protcol buffer message map and usb msg callback */ fsm_init(); led_func(SET_GREEN_LED); usbInit(); u2fInit(); led_func(CLR_RED_LED); reset_idle_time(); if (is_mfg_mode()) layout_screen_test(); else if (!storage_isInitialized()) layout_standard_notification("Welcome", "keepkey.com/get-started", NOTIFICATION_LOGO); else layoutHomeForced(); while (1) { delay_ms_with_callback(ONE_SEC, &exec, 1); increment_idle_time(ONE_SEC); toggle_screensaver(); } return 0; }
int check_fwbl(struct ssp_data *data) { unsigned int fw_revision; pr_info("[SSP] change_rev = %d\n", data->ssp_changes); #if defined(CONFIG_SEC_KSPORTS_PROJECT) fw_revision = SSP_FIRMWARE_REVISION_TASMAN; #elif defined(CONFIG_SENSORS_SSP_STM_HESTIA) fw_revision = SSP_FIRMWARE_REVISION_HESTIA; #else fw_revision = SSP_FIRMWARE_REVISION_STM; #endif data->uCurFirmRev = get_firmware_rev(data); if ((data->uCurFirmRev == SSP_INVALID_REVISION) || (data->uCurFirmRev == SSP_INVALID_REVISION2)) { #if STM_SHOULD_BE_IMPLEMENT data->client->addr = BOOTLOADER_SLAVE_ADDR; iRet = check_bootloader(data->client, BL_WAITING_BOOTLOAD_CMD); if (iRet >= 0) pr_info("[SSP] ssp_load_fw_bootmode\n"); else { pr_warn("[SSP] Firm Rev is invalid(%8u). Retry.\n", data->uCurFirmRev); data->client->addr = APP_SLAVE_ADDR; data->uCurFirmRev = get_firmware_rev(data); if (data->uCurFirmRev == SSP_INVALID_REVISION || data->uCurFirmRev == ERROR) { pr_err("[SSP] MCU is not working, FW download failed\n"); return FW_DL_STATE_FAIL; } } #endif data->uCurFirmRev = SSP_INVALID_REVISION; pr_err("[SSP] SSP_INVALID_REVISION\n"); return FW_DL_STATE_NEED_TO_SCHEDULE; } else { if (data->uCurFirmRev != fw_revision) { pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n", data->uCurFirmRev, fw_revision); return FW_DL_STATE_NEED_TO_SCHEDULE; } pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n", data->uCurFirmRev, fw_revision); } return FW_DL_STATE_NONE; }
int check_fwbl(struct ssp_data *data) { int iRet; data->client->addr = APP_SLAVE_ADDR; data->uCurFirmRev = get_firmware_rev(data); if (data->uCurFirmRev == SSP_INVALID_REVISION) { toggle_mcu_reset(data); msleep(SSP_SW_RESET_TIME); data->client->addr = BOOTLOADER_SLAVE_ADDR; iRet = check_bootloader(data->client, BL_WAITING_BOOTLOAD_CMD); if (iRet >= 0) { pr_info("[SSP] ssp_load_fw_bootmode\n"); return FW_DL_STATE_NEED_TO_SCHEDULE; } else { pr_warn("[SSP] Firm Rev is invalid. Retry.\n"); data->client->addr = APP_SLAVE_ADDR; data->uCurFirmRev = get_firmware_rev(data); if (data->uCurFirmRev == SSP_INVALID_REVISION ||\ data->uCurFirmRev == ERROR) { pr_err("[SSP] MCU is not working\n"); return FW_DL_STATE_FAIL; } else if (data->uCurFirmRev != SSP_FIRMWARE_REVISION) { pr_info("[SSP] MCU Firm Rev : Old = %8u, New = " "%8u\n", data->uCurFirmRev, SSP_FIRMWARE_REVISION); return FW_DL_STATE_NEED_TO_SCHEDULE; } pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n", data->uCurFirmRev, SSP_FIRMWARE_REVISION); } } else { if (data->uCurFirmRev != SSP_FIRMWARE_REVISION) { pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n", data->uCurFirmRev, SSP_FIRMWARE_REVISION); return FW_DL_STATE_NEED_TO_SCHEDULE; } pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n", data->uCurFirmRev, SSP_FIRMWARE_REVISION); } return FW_DL_STATE_NONE; }
int check_fwbl(struct ssp_data *data) { int iRet; unsigned int fw_revision; #if defined(CONFIG_SENSORS_MPU6500_BMI058_DUAL) if (data->ap_rev < MPU6500_REV) fw_revision = SSP_BMI_FIRMWARE_REVISION; else fw_revision = SSP_FIRMWARE_REVISION; #else fw_revision = SSP_FIRMWARE_REVISION; #endif data->uCurFirmRev = get_firmware_rev(data); if ((data->uCurFirmRev == SSP_INVALID_REVISION) \ || (data->uCurFirmRev == SSP_INVALID_REVISION2)) { iRet = check_bootloader(data, BL_WAITING_BOOTLOAD_CMD); if (iRet >= 0) pr_info("[SSP] ssp_load_fw_bootmode\n"); else { pr_warn("[SSP] Firm Rev is invalid(%8u). Retry.\n", data->uCurFirmRev); data->uCurFirmRev = get_firmware_rev(data); } data->uCurFirmRev = SSP_INVALID_REVISION; pr_err("[SSP] SSP_INVALID_REVISION\n"); return FW_DL_STATE_NEED_TO_SCHEDULE; } else { if (data->uCurFirmRev != fw_revision) { pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n", data->uCurFirmRev, fw_revision); return FW_DL_STATE_NEED_TO_SCHEDULE; } pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n", data->uCurFirmRev, fw_revision); } return FW_DL_STATE_NONE; }
int main(void) { int i, j, k, l; unsigned button[3]; unsigned steps[3]; unsigned hz; /*------------------------------------------------------------- * First things first: Start the watchdog */ fido_setup(0x1000); /*------------------------------------------------------------- * Setup GPIO */ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 6); // GPIO LPC_SYSCON->PRESETCTRL &= ~(1 << 10); // GPIO reset LPC_SYSCON->PRESETCTRL |= (1 << 10); LPC_IOCON->PIO0_0 = 0 | (1 << 3) // Pull down | (1 << 5) // Hysteresis ; LPC_IOCON->PIO0_1 = 0 | (2 << 3) // Pull up | (1 << 5) // Hysteresis ; LPC_IOCON->PIO0_2 = 0 | (2 << 3) // Pull up | (1 << 5) // Hysteresis ; LPC_IOCON->PIO0_3 = 0 | (2 << 3) // Pull up | (1 << 5) // Hysteresis ; LPC_IOCON->PIO0_5 = 0 | (2 << 3) // Pull up | (1 << 5) // Hysteresis ; /*------------------------------------------------------------- * Provide a chance to enter the boot-loader */ check_bootloader(); /*------------------------------------------------------------- * Enable UART for startup-debugging */ uart0Init(115200); uart_enable(); /*------------------------------------------------------------- * Start timer */ mrtInit(__SYSTEM_CLOCK/1000); /*------------------------------------------------------------- * Enable reset pin */ LPC_SWM->PINENABLE0 = ~(1 << 6); // PIO0_5 RESET_EN /*------------------------------------------------------------- * Hello World */ welcome(); /*------------------------------------------------------------- * Detect pin-configuration by counting edges on the two possible * possible clock inputs. * * If neither is active the watch-dog will trigger. */ do { /* Measure input frequency on PIO0_1 and PIO0_2 */ for (i = 1; i < 3; i++) { sct_setup(i); k = LPC_SCT->COUNT_U; mrtDelay(100); l = LPC_SCT->COUNT_U; hz = 10 * (l-k); printf("Rate PIO0_%d = %u\r\n", i, hz); if (hz > 1000) break; } } while (hz < 1000); /*------------------------------------------------------------- * Configure counter */ mrtDelay(100); printf("Using PIO0_%d\r\n", i); mrtDelay(100); uart_disable(); button[0] = 1<<(3-i); steps[0] = 1; button[1] = 1<<3; steps[1] = 60; button[2] = 1<<5; steps[2] = 3600; if (i == 1) { LPC_SWM->PINENABLE0 &= ~(1 << 7); // Enable CLKIN LPC_SYSCON->MAINCLKSEL = 0x1; // PLL input LPC_SYSCON->MAINCLKUEN = 0x0; LPC_SYSCON->MAINCLKUEN = 0x1; LPC_SYSCON->SYSPLLCLKSEL = 0x3; // CLKIN LPC_SYSCON->SYSPLLCLKUEN = 0x0; LPC_SYSCON->SYSPLLCLKUEN = 0x1; LPC_SYSCON->SYSAHBCLKDIV = 1; sct_setup(0xff); mrtInit(FREQ/1000); /* Calibrated to look like 0x00 at 115200 bps */ pulse_lo = 29; pulse_hi = 10; } else { sct_setup(2); } sct_output(4); /*------------------------------------------------------------- * Until the clock is set, have it run 11 times too fast */ while (1) { fido_pat(); if (!(LPC_GPIO_PORT->PIN0 & button[0])) break; if (!(LPC_GPIO_PORT->PIN0 & button[1])) break; if (!(LPC_GPIO_PORT->PIN0 & button[2])) break; mrtDelay(100); run_pulse(); } LPC_SWM->PINENABLE0 |= (1 << 6); // Disable RESET j = 0; while(1) { if (j == 0 && LPC_SCT->COUNT_U < 10000) { fido_pat(); j = 1; } if (j == 1 && LPC_SCT->COUNT_U > 10000) { j = 0; } for (i = 0; i < 3; i++) { if (LPC_GPIO_PORT->PIN0 & button[i]) continue; fido_pat(); for(k = 0; k < steps[i]; k++) run_pulse(); if (i > 0) { /* * Min/Hour button release * If you hold them for 10+ seconds * The watch-dog bites */ for(k = 0; k < 1000; k++) { if (LPC_GPIO_PORT->PIN0 & button[i]) continue; k = 0; } continue; } /* Check if the Sec button is held for >1s */ mrt_counter = 0; for(k = 0; k < 1000; k++) { if (LPC_GPIO_PORT->PIN0 & button[i]) break; if (mrt_counter > 1000) break; k = 0; } if (k == 1000) continue; /* Stop counter */ sct_stop(); /* * Restart counter on button release * or sync input */ for(k = 0; k < 1000; k++) { if (LPC_GPIO_PORT->PIN0 & button[i]) break; l = LPC_GPIO_PORT->PIN0 & (1<<0); if (l) k = 0; } l = (1 << 0) | button[i]; while (!(LPC_GPIO_PORT->PIN0 & l)) continue; /* * Calibrated for falling edge = PPI rising edge * PPSO comes 164ns after PPS1 */ LPC_SCT->COUNT_U = FREQ - 366; LPC_SCT->CTRL_L &= ~(1 << 2); // Start for(k = 0; k < 1000; k++) { if (LPC_GPIO_PORT->PIN0 & button[i]) continue; k = 0; } } } }
static int load_kernel_fw_bootmode(struct i2c_client *client, const char *pFn) { unsigned int uFrameSize; unsigned int uPos = 0; int iRet = SUCCESS; int iCheckFrameCrcError = 0; int iCheckWatingFrameDataError = 0; const struct firmware *fw = NULL; pr_info("[SSP] ssp_load_fw start!!!\n"); if (request_firmware(&fw, pFn, &client->dev)) { iRet = ERROR; pr_err("[SSP]: %s - Unable to open firmware %s\n", __func__, pFn); return iRet; } /* Unlock bootloader */ unlock_bootloader(client); while (uPos < fw->size) { if (check_bootloader(client, BL_WAITING_FRAME_DATA)) { iCheckWatingFrameDataError++; if (iCheckWatingFrameDataError > 10) { iRet = ERROR; pr_err("[SSP]: %s - F/W update fail\n", __func__); goto out; } else { pr_err("[SSP]: %s - F/W data_error %d, retry\n", __func__, iCheckWatingFrameDataError); continue; } } uFrameSize = ((*(fw->data + uPos) << 8) | *(fw->data + uPos + 1)); /* We should add 2 at frame size as the the firmware data is not * included the CRC bytes. */ uFrameSize += 2; /* Write one frame to device */ fw_write(client, fw->data + uPos, uFrameSize); if (check_bootloader(client, BL_FRAME_CRC_PASS)) { iCheckFrameCrcError++; if (iCheckFrameCrcError > 10) { iRet = ERROR; pr_err("[SSP]: %s - F/W Update Fail. crc err\n", __func__); goto out; } else { pr_err("[SSP]: %s - F/W crc_error %d, retry\n", __func__, iCheckFrameCrcError); continue; } } uPos += uFrameSize; pr_info("[SSP] Updated %d bytes / %zd bytes\n", uPos, fw->size); mdelay(1); } out: release_firmware(fw); return iRet; }
static int load_ums_fw_bootmode(struct i2c_client *client, const char *pFn) { const u8 *buff = NULL; char fw_path[BL_UMS_FW_PATH+1]; unsigned int uFrameSize; unsigned int uFSize = 0, uNRead = 0; unsigned int uPos = 0; int iRet = SUCCESS; int iCheckFrameCrcError = 0; int iCheckWatingFrameDataError = 0; struct file *fp = NULL; mm_segment_t old_fs = get_fs(); pr_info("[SSP] ssp_load_ums_fw start!!!\n"); old_fs = get_fs(); set_fs(get_ds()); snprintf(fw_path, BL_UMS_FW_PATH, "/sdcard/ssp/%s", pFn); fp = filp_open(fw_path, O_RDONLY, 0); if (IS_ERR(fp)) { iRet = ERROR; pr_err("file %s open error:%d\n", fw_path, (s32)fp); goto err_open; } uFSize = (unsigned int)fp->f_path.dentry->d_inode->i_size; pr_info("ssp_load_ums firmware size: %u\n", uFSize); buff = kzalloc((size_t)uFSize, GFP_KERNEL); if (!buff) { iRet = ERROR; pr_err("fail to alloc buffer for fw\n"); goto err_alloc; } uNRead = (unsigned int)vfs_read(fp, (char __user *)buff, (unsigned int)uFSize, &fp->f_pos); if (uNRead != uFSize) { iRet = ERROR; pr_err("fail to read file %s (nread = %u)\n", fw_path, uNRead); goto err_fw_size; } /* Unlock bootloader */ unlock_bootloader(client); while (uPos < uFSize) { if (check_bootloader(client, BL_WAITING_FRAME_DATA)) { iCheckWatingFrameDataError++; if (iCheckWatingFrameDataError > 10) { iRet = ERROR; pr_err("[SSP]: %s - F/W update fail\n", __func__); goto out; } else { pr_err("[SSP]: %s - F/W data_error %d, retry\n", __func__, iCheckWatingFrameDataError); continue; } } uFrameSize = (unsigned int)((*(buff + uPos) << 8) | *(buff + uPos + 1)); /* We should add 2 at frame size as the the firmware data is not * included the CRC bytes. */ uFrameSize += 2; /* Write one frame to device */ fw_write(client, buff + uPos, uFrameSize); if (check_bootloader(client, BL_FRAME_CRC_PASS)) { iCheckFrameCrcError++; if (iCheckFrameCrcError > 10) { iRet = ERROR; pr_err("[SSP]: %s - F/W Update Fail. crc err\n", __func__); goto out; } else { pr_err("[SSP]: %s - F/W crc_error %d, retry\n", __func__, iCheckFrameCrcError); continue; } } uPos += uFrameSize; pr_info("[SSP] Updated %u bytes / %u bytes\n", uPos, uFSize); mdelay(1); } out: err_fw_size: kfree(buff); err_alloc: filp_close(fp, NULL); err_open: set_fs(old_fs); return iRet; }
static int load_kernel_fw_bootmode(struct ssp_data *data, const char *pFn) { const struct firmware *fw = NULL; unsigned int uFrameSize; unsigned int uPos = 0; int iRet; int iCheckFrameCrcError = 0; int iCheckWatingFrameDataError = 0; int count = 0; pr_info("[SSP] ssp_load_fw start!!!\n"); iRet = request_firmware(&fw, pFn, &data->spi->dev); if (iRet) { pr_err("[SSP]: %s - Unable to open firmware %s\n", __func__, pFn); return iRet; } /* Unlock bootloader */ iRet = unlock_bootloader(data); if (iRet < 0) { pr_err("[SSP] %s - unlock_bootloader failed! %d\n", __func__, iRet); goto out; } while (uPos < fw->size) { iRet = check_bootloader(data, BL_WAITING_FRAME_DATA); if (iRet) { iCheckWatingFrameDataError++; if (iCheckWatingFrameDataError > 10) { pr_err("[SSP]: %s - F/W update fail\n", __func__); goto out; } else { pr_err("[SSP]: %s - F/W data_error %d, retry\n", __func__, iCheckWatingFrameDataError); continue; } } uFrameSize = ((*(fw->data + uPos) << 8) | *(fw->data + uPos + 1)); /* We should add 2 at frame size as the the firmware data is not * included the CRC bytes. */ uFrameSize += 2; /* Write one frame to device */ fw_write(data, fw->data + uPos, uFrameSize); iRet = check_bootloader(data, BL_FRAME_CRC_PASS); if (iRet) { iCheckFrameCrcError++; if (iCheckFrameCrcError > 10) { pr_err("[SSP]: %s - F/W Update Fail. crc err\n", __func__); goto out; } else { pr_err("[SSP]: %s - F/W crc_error %d, retry\n", __func__, iCheckFrameCrcError); continue; } } uPos += uFrameSize; if (count++ == 100) { pr_info("[SSP] Updated %d bytes / %zd bytes\n", uPos, fw->size); count = 0; } } pr_info("[SSP] Firmware download is success.(%d bytes)\n", uPos); out: release_firmware(fw); return iRet; }
int check_fwbl(struct ssp_data *data) { unsigned int fw_revision; pr_info("[SSP] change_rev = %d\n", data->ssp_changes); #if defined (CONFIG_MACH_VIKALCU) fw_revision = SSP_FIRMWARE_REVISION_STM; #elif defined (CONFIG_MACH_HLTEVZW) || defined (CONFIG_MACH_HLTESPR) \ || defined (CONFIG_MACH_HLTEUSC) if (data->ap_rev > 3) fw_revision = SSP_FIRMWARE_REVISION_STM; else if (data->ap_rev > 2) fw_revision = SSP_FIRMWARE_REVISION_STM_88921; else fw_revision = SSP_FIRMWARE_REVISION_STM_RVS; #else if (data->ap_rev > 3) fw_revision = SSP_FIRMWARE_REVISION_STM; else fw_revision = SSP_FIRMWARE_REVISION_STM_88921; #endif data->uCurFirmRev = get_firmware_rev(data); if ((data->uCurFirmRev == SSP_INVALID_REVISION) \ || (data->uCurFirmRev == SSP_INVALID_REVISION2)) { #if STM_SHOULD_BE_IMPLEMENT data->client->addr = BOOTLOADER_SLAVE_ADDR; iRet = check_bootloader(data->client, BL_WAITING_BOOTLOAD_CMD); if (iRet >= 0) { pr_info("[SSP] ssp_load_fw_bootmode\n"); return FW_DL_STATE_NEED_TO_SCHEDULE; } else { pr_warn("[SSP] Firm Rev is invalid(%8u). Retry.\n", data->uCurFirmRev); data->client->addr = APP_SLAVE_ADDR; data->uCurFirmRev = get_firmware_rev(data); if (data->uCurFirmRev == SSP_INVALID_REVISION ||\ data->uCurFirmRev == ERROR) { pr_err("[SSP] MCU is not working, FW download failed\n"); return FW_DL_STATE_FAIL; } else if (data->uCurFirmRev != fw_revision) { pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n", data->uCurFirmRev, fw_revision); return FW_DL_STATE_NEED_TO_SCHEDULE; } pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n", data->uCurFirmRev, fw_revision); } #endif pr_err("[SSP] SSP_INVALID_REVISION\n"); return FW_DL_STATE_NEED_TO_SCHEDULE; } else { if (data->uCurFirmRev != fw_revision) { pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n", data->uCurFirmRev, fw_revision); return FW_DL_STATE_NEED_TO_SCHEDULE; } pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n", data->uCurFirmRev, fw_revision); } return FW_DL_STATE_NONE; }