static int spi_read_wait_chg(struct ssp_data *data, uint8_t *buffer, int len) { int ret; ret = ssp_wait_for_chg(data); if (ret < 0) { pr_err("[SSP] Error %d while waiting for chg\n", ret); } ret = spi_read(data->spi, buffer, len); if (ret < 0) { pr_err("[SSP] Error in %d spi_read()\n", ret); } return ret; }
static int load_kernel_fw_bootmode(struct i2c_client *client, 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; struct ssp_data *data = i2c_get_clientdata(client); pr_info("[SSP] ssp_load_fw start!!!\n"); iRet = request_firmware(&fw, pFn, &client->dev); if (iRet) { pr_err("[SSP]: %s - Unable to open firmware %s\n", __func__, pFn); return iRet; } /* Unlock bootloader */ iRet = unlock_bootloader(client); if (iRet < 0) { pr_err("[SSP] %s - unlock_bootloader failed! %d\n", __func__, iRet); goto out; } while (uPos < fw->size) { if (data->ssp_changes == SSP_MCU_L5) { iRet = ssp_wait_for_chg(data); if (iRet < 0) { pr_err("[SSP] %s - ssp_wait_for_chg failed! %d\n", __func__, iRet); goto out; } } iRet = check_bootloader(client, 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(client, fw->data + uPos, uFrameSize); if (data->ssp_changes == SSP_MCU_L5) { iRet = ssp_wait_for_chg(data); if (iRet < 0) { pr_err("[SSP] %s - ssp_wait_for_chg failed! %d\n", __func__, iRet); goto out; } } iRet = check_bootloader(client, 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; } mdelay(1); } pr_info("[SSP] Firmware download is success.(%d bytes)\n", uPos); out: release_firmware(fw); return iRet; }
static int check_bootloader(struct i2c_client *client, unsigned int uState) { u8 uVal; u8 uTemp; struct ssp_data *data = i2c_get_clientdata(client); recheck: if (i2c_master_recv(client, &uVal, 1) != 1) return -EIO; pr_debug("%s, uVal = 0x%x\n", __func__, uVal); if (uVal & 0x20) { if (i2c_master_recv(client, &uTemp, 1) != 1) { pr_err("[SSP]: %s - i2c recv fail\n", __func__); return -EIO; } if (i2c_master_recv(client, &uTemp, 1) != 1) { pr_err("[SSP]: %s - i2c recv fail\n", __func__); return -EIO; } uVal &= ~0x20; } if ((uVal & 0xF0) == BL_APP_CRC_FAIL) { pr_info("[SSP] SSP_APP_CRC_FAIL - There is no bootloader.\n"); if (i2c_master_recv(client, &uVal, 1) != 1) { pr_err("[SSP]: %s - i2c recv fail\n", __func__); return -EIO; } if (uVal & 0x20) { if (i2c_master_recv(client, &uTemp, 1) != 1) { pr_err("[SSP]: %s - i2c recv fail\n", __func__); return -EIO; } if (i2c_master_recv(client, &uTemp, 1) != 1) { pr_err("[SSP]: %s - i2c recv fail\n", __func__); return -EIO; } uVal &= ~0x20; } } switch (uState) { case BL_WAITING_BOOTLOAD_CMD: case BL_WAITING_FRAME_DATA: uVal &= ~BL_BOOT_STATUS_MASK; break; case BL_FRAME_CRC_PASS: if (uVal == BL_FRAME_CRC_CHECK) { if (data->ssp_changes == SSP_MCU_L5) ssp_wait_for_chg(data); goto recheck; } break; default: return -EINVAL; } if (uVal != uState) { pr_err("[SSP]: %s - Invalid bootloader mode state\n", __func__); return -EINVAL; } return 0; }
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; int count = 0; struct file *fp = NULL; mm_segment_t old_fs = get_fs(); struct ssp_data *data = i2c_get_clientdata(client); 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 */ iRet = unlock_bootloader(client); if (iRet < 0) { pr_err("[SSP] %s - unlock_bootloader failed! %d\n", __func__, iRet); goto out; } while (uPos < uFSize) { if (data->ssp_changes == SSP_MCU_L5) { iRet = ssp_wait_for_chg(data); if (iRet < 0) { pr_err("[SSP] %s - ssp_wait_for_chg failed! %d\n", __func__, iRet); goto out; } } 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 (data->ssp_changes == SSP_MCU_L5) { iRet = ssp_wait_for_chg(data); if (iRet < 0) { pr_err("[SSP] %s - ssp_wait_for_chg failed! %d\n", __func__, iRet); goto out; } } 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; if (count++ == 100) { pr_info("[SSP] Updated %u bytes / %u bytes\n", uPos, uFSize); count = 0; } mdelay(1); } out: err_fw_size: kfree(buff); err_alloc: filp_close(fp, NULL); err_open: set_fs(old_fs); return iRet; }