bool fimc_is_ois_check_fw(struct fimc_is_core *core) { u8 *buf = NULL; int ret = 0; ret = fimc_is_ois_fw_version(core); if (!ret) { err("Failed to read ois fw version."); return false; } fimc_is_ois_read_userdata(core); if (ois_minfo.header_ver[0] == '6') { if (ois_minfo.header_ver[2] == 'C' || ois_minfo.header_ver[2] == 'E' || ois_minfo.header_ver[2] == 'G' || ois_minfo.header_ver[2] == 'I') { ret = fimc_is_ois_open_fw(core, FIMC_OIS_FW_NAME_DOM, &buf); } else if (ois_minfo.header_ver[2] == 'D' || ois_minfo.header_ver[2] == 'F' || ois_minfo.header_ver[2] == 'H' || ois_minfo.header_ver[2] == 'J') { ret = fimc_is_ois_open_fw(core, FIMC_OIS_FW_NAME_SEC, &buf); } } else if (ois_minfo.header_ver[0] == '8') { if (ois_minfo.header_ver[2] == 'H' || ois_minfo.header_ver[2] == 'J') { ret = fimc_is_ois_open_fw(core, FIMC_OIS_FW_NAME_SEC_2, &buf); } } else { info("Module FW version does not matched with phone FW version.\n"); strcpy(ois_pinfo.header_ver, "NULL"); return true; } if (ret) { err("fimc_is_ois_open_fw failed(%d)\n", ret); } if (buf) { vfree(buf); } return true; }
void fimc_is_ois_check_fw(struct fimc_is_core *core) { u8 *buf = NULL; int ret = 0; fimc_is_ois_fw_version(core); fimc_is_ois_read_userdata(core); if (ois_minfo.header_ver[2] == 'A') { ret = fimc_is_ois_open_fw(core, FIMC_OIS_FW_NAME_DOM, &buf); } else if (ois_minfo.header_ver[2] == 'B') { ret = fimc_is_ois_open_fw(core, FIMC_OIS_FW_NAME_SEC, &buf); } if (ret) { err("fimc_is_ois_open_fw failed(%d)\n", ret); } if (buf) { vfree(buf); } return; }
void fimc_is_ois_check_fw(struct fimc_is_core *core) { u8 *buf = NULL; int ret = 0; ret = fimc_is_ois_open_fw(core, FIMC_OIS_FW_NAME, &buf); if (ret) { err("fimc_is_ois_open_fw failed(%d)\n", ret); } if (buf) { vfree(buf); } return; }
void fimc_is_ois_fw_update(struct fimc_is_core *core) { u8 SendData[256], RcvData; u16 RcvDataShort = 0; u8 data[2] = {0, }; int block, i, position = 0; u16 checkSum; u8 *buf = NULL; int ret = 0, sum_size = 0, retry_count = 3; int module_ver = 0, binary_ver = 0; u8 error_status = 0; bool forced_update = false, crc_result = false; bool need_reset = false; struct i2c_client *client = core->client1; struct exynos_platform_fimc_is *core_pdata = NULL; core_pdata = dev_get_platdata(fimc_is_dev); if (!core_pdata) { err("core->pdata is null"); return; } /* OIS Status Check */ error_status = fimc_is_ois_read_status(core); if (error_status == 0x01) { forced_update = true; } ret = fimc_is_ois_fw_version(core); if (!ret) { err("Failed to read ois fw version."); return; } fimc_is_ois_read_userdata(core); if (ois_minfo.header_ver[0] == '6') { if (ois_minfo.header_ver[2] == 'C' || ois_minfo.header_ver[2] == 'E' || ois_minfo.header_ver[2] == 'G' || ois_minfo.header_ver[2] == 'I') { ret = fimc_is_ois_open_fw(core, FIMC_OIS_FW_NAME_DOM, &buf); } else if (ois_minfo.header_ver[2] == 'D' || ois_minfo.header_ver[2] == 'F' || ois_minfo.header_ver[2] == 'H' || ois_minfo.header_ver[2] == 'J') { ret = fimc_is_ois_open_fw(core, FIMC_OIS_FW_NAME_SEC, &buf); } } else if (ois_minfo.header_ver[0] == '8') { if (ois_minfo.header_ver[2] == 'H' || ois_minfo.header_ver[2] == 'J') { ret = fimc_is_ois_open_fw(core, FIMC_OIS_FW_NAME_SEC_2, &buf); } } else { info("Module FW version does not matched with phone FW version.\n"); strcpy(ois_pinfo.header_ver, "NULL"); return; } if (ret) { err("fimc_is_ois_open_fw failed(%d)", ret); goto p_err; } if (ois_minfo.header_ver[2] != CAMERA_OIS_DOM_UPDATE_VERSION && ois_minfo.header_ver[2] != CAMERA_OIS_SEC_UPDATE_VERSION) { info("Do not update ois Firmware. FW version is low.\n"); goto p_err; } if (buf == NULL) { err("buf is NULL. OIS FW Update failed."); return; } if (!forced_update) { if (ois_uinfo.header_ver[0] == 0xFF && ois_uinfo.header_ver[1] == 0xFF && ois_uinfo.header_ver[2] == 0xFF) { err("OIS userdata is not valid."); goto p_err; } } /*Update OIS FW when Gyro sensor/Driver IC/ Core version is same*/ if (!forced_update) { if (!fimc_is_ois_version_compare(ois_minfo.header_ver, ois_pinfo.header_ver, ois_uinfo.header_ver)) { err("Does not update ois fw. OIS module ver = %s, binary ver = %s, userdata ver = %s", ois_minfo.header_ver, ois_pinfo.header_ver, ois_uinfo.header_ver); goto p_err; } } else { if (!fimc_is_ois_version_compare_default(ois_minfo.header_ver, ois_pinfo.header_ver)) { err("Does not update ois fw. OIS module ver = %s, binary ver = %s", ois_minfo.header_ver, ois_pinfo.header_ver); goto p_err; } } crc_result = fimc_is_ois_crc_check(core, buf); if (crc_result == false) { err("OIS CRC32 error.\n"); goto p_err; } if (!fw_sdcard && !forced_update) { module_ver = fimc_is_ois_fw_revision(ois_minfo.header_ver); binary_ver = fimc_is_ois_fw_revision(ois_pinfo.header_ver); if (binary_ver <= module_ver) { err("OIS module ver = %d, binary ver = %d", module_ver, binary_ver); goto p_err; } } info("OIS fw update started. module ver = %s, binary ver = %s, userdata ver = %s\n", ois_minfo.header_ver, ois_pinfo.header_ver, ois_uinfo.header_ver); if (core_pdata->use_ois_hsi2c) { fimc_is_ois_i2c_config(core->client1, true); } retry: if (need_reset) { fimc_is_ois_gpio_off(core); msleep(30); fimc_is_ois_gpio_on(core); msleep(150); } fimc_is_ois_i2c_read(client, 0x01, &RcvData); /* OISSTS Read */ if (RcvData != 0x01) {/* OISSTS != IDLE */ err("RCV data return!!"); goto p_err; } /* Update a Boot Program */ /* SET FWUP_CTRL REG */ fimc_is_ois_i2c_write(client ,0x000C, 0x0B); msleep(20); position = 0; /* Write Boot Data */ for (block = 4; block < 8; block++) { /* 0x1000 - 0x1FFF */ for (i = 0; i < 4; i++) { memcpy(SendData, bootCode + position, FW_TRANS_SIZE); fimc_is_ois_i2c_write_multi(client, 0x0100, SendData, FW_TRANS_SIZE + 2); position += FW_TRANS_SIZE; if (i == 0 ) { msleep(20); } else if ((i == 1) || (i == 2)) { /* Wait Erase and Write process */ msleep(10); /* Wait Write process */ } else { msleep(15); /* Wait Write and Verify process */ } } } /* CHECKSUM (Boot) */ sum_size = OIS_BOOT_FW_SIZE; checkSum = fimc_is_ois_calc_checksum(&bootCode[0], sum_size); SendData[0] = (checkSum & 0x00FF); SendData[1] = (checkSum & 0xFF00) >> 8; SendData[2] = 0x00; SendData[3] = 0x00; fimc_is_ois_i2c_write_multi(client, 0x08, SendData, 6); msleep(10); /* (RUMBA Self Reset) */ fimc_is_ois_i2c_read_multi(client, 0x06, data, 2); /* Error Status read */ info("%s: OISSTS Read = 0x%02x%02x\n", __func__, data[1], data[0]); if (data[1] == 0x00 && data[0] == 0x01) { /* Boot F/W Update Error check */ /* Update a User Program */ /* SET FWUP_CTRL REG */ position = 0; SendData[0] = 0x09; /* FWUP_DSIZE=256Byte, FWUP_MODE=PROG, FWUPEN=Start */ fimc_is_ois_i2c_write(client, 0x0C, SendData[0]); /* FWUPCTRL REG(0x000C) 1Byte Send */ /* Write UserProgram Data */ for (block = 4; block <= 27; block++) { /* 0x1000 -0x 6FFF (RUMBA-SA)*/ for (i = 0; i < 4; i++) { memcpy(SendData, &progCode[position], (size_t)FW_TRANS_SIZE); fimc_is_ois_i2c_write_multi(client, 0x100, SendData, FW_TRANS_SIZE + 2); /* FLS_DATA REG(0x0100) 256Byte Send */ position += FW_TRANS_SIZE; if (i ==0 ) { msleep(20); /* Wait Erase and Write process */ } else if ((i==1) || (i==2)) { msleep(10); /* Wait Write process */ } else { msleep(15); /* Wait Write and Verify process */ } } } /* CHECKSUM (Program) */ sum_size = OIS_PROG_FW_SIZE; checkSum = fimc_is_ois_calc_checksum(&progCode[0], sum_size); SendData[0] = (checkSum & 0x00FF); SendData[1] = (checkSum & 0xFF00) >> 8; SendData[2] = 0; /* Don't Care */ SendData[3] = 0x80; /* Self Reset Request */ fimc_is_ois_i2c_write_multi(client, 0x08, SendData, 6); /* FWUP_CHKSUM REG(0x0008) 4Byte Send */ msleep(60); /* (Wait RUMBA Self Reset) */ fimc_is_ois_i2c_read(client, 0x6, (u8*)&RcvDataShort); /* Error Status read */ if (RcvDataShort == 0x0000) { /* F/W Update Success Process */ info("%s: OISLOG OIS program update success\n", __func__); } else { /* Retry Process */ if (retry_count > 0) { err("OISLOG OIS program update fail, retry update. count = %d", retry_count); retry_count--; need_reset = true; goto retry; } /* F/W Update Error Process */ err("OISLOG OIS program update fail"); goto p_err; } } else {
void fimc_is_ois_fw_update(struct fimc_is_core *core) { u8 SendData[256], RcvData; u16 RcvDataShort = 0; int block, i, position = 0; u16 checkSum; u8 *buf = NULL; int ret = 0, sum_size = 0; int module_ver = 0, binary_ver = 0; struct i2c_client *client = core->client1; /* OIS Status Check */ ret = fimc_is_ois_open_fw(core, FIMC_OIS_FW_NAME, &buf); if (ret) { err("fimc_is_ois_open_fw failed(%d)\n", ret); goto p_err; } fimc_is_ois_fw_version(core); /*Update OIS FW when Gyro sensor/Driver IC/ Core version is same*/ if (!fimc_is_ois_version_compare(ois_minfo.header_ver, ois_pinfo.header_ver)) { err("Does not update ois fw. OIS module ver = %s, binary ver = %s\n", ois_minfo.header_ver, ois_pinfo.header_ver ); goto p_err; } module_ver = fimc_is_ois_fw_revision(ois_minfo.header_ver); binary_ver = fimc_is_ois_fw_revision(ois_pinfo.header_ver); if (binary_ver <= module_ver) { err("OIS module ver = %d, binary ver = %d\n", module_ver, binary_ver); goto p_err; } fimc_is_ois_i2c_read(client, 0x01, &RcvData); /* OISSTS Read */ if (RcvData != 0x01) {/* OISSTS != IDLE */ err("RCV data return!!\n"); goto p_err; } /* Update a Boot Program */ /* SET FWUP_CTRL REG */ fimc_is_ois_i2c_write(client ,0x000C, 0x0B); position = 0; /* Write Boot Data */ for (block = 4; block < 8; block++) { /* 0x1000 - 0x1FFF */ for (i = 0; i < 4; i++) { memcpy(SendData, bootCode + position, FW_TRANS_SIZE); fimc_is_ois_i2c_write_multi(client, 0x0100, SendData, FW_TRANS_SIZE + 2); position += FW_TRANS_SIZE; if (i == 0 ) { msleep(20); } else if ((i == 1) || (i == 2)) { /* Wait Erase and Write process */ msleep(10); /* Wait Write process */ } else { msleep(15); /* Wait Write and Verify process */ } } } /* CHECKSUM (Boot) */ sum_size = OIS_BOOT_FW_SIZE; checkSum = fimc_is_ois_calc_checksum(&bootCode[0], sum_size); SendData[0] = (checkSum & 0x00FF); SendData[1] = (checkSum & 0xFF00) >> 8; SendData[2] = 0x00; SendData[3] = 0x00; fimc_is_ois_i2c_write_multi(client, 0x08, SendData, 6); msleep(10); /* (RUMBA Self Reset) */ fimc_is_ois_i2c_read_multi(client, 0x06, &RcvDataShort); /* Error Status read */ pr_info("OISSTS Read = 0x%04x\n", RcvDataShort); if (RcvDataShort == 0x0001) { /* Boot F/W Update Error check */ /* Update a User Program */ /* SET FWUP_CTRL REG */ position = 0; SendData[0] = 0x09; /* FWUP_DSIZE=256Byte, FWUP_MODE=PROG, FWUPEN=Start */ fimc_is_ois_i2c_write(client, 0x0C, SendData[0]); /* FWUPCTRL REG(0x000C) 1Byte Send */ /* Write UserProgram Data */ for (block = 4; block <= 27; block++) { /* 0x1000 -0x 6FFF (RUMBA-SA)*/ for (i = 0; i < 4; i++) { memcpy(SendData, &progCode[position], (size_t)FW_TRANS_SIZE); fimc_is_ois_i2c_write_multi(client, 0x100, SendData, FW_TRANS_SIZE + 2); /* FLS_DATA REG(0x0100) 256Byte Send */ position += FW_TRANS_SIZE; if (i ==0 ) { msleep(20); /* Wait Erase and Write process */ } else if ((i==1) || (i==2)) { msleep(10); /* Wait Write process */ } else { msleep(15); /* Wait Write and Verify process */ } } } /* CHECKSUM (Program) */ sum_size = OIS_PROG_FW_SIZE; checkSum = fimc_is_ois_calc_checksum(&progCode[0], sum_size); SendData[0] = (checkSum & 0x00FF); SendData[1] = (checkSum & 0xFF00) >> 8; SendData[2] = 0; /* Don't Care */ SendData[3] = 0x80; /* Self Reset Request */ fimc_is_ois_i2c_write_multi(client, 0x08, SendData, 6); /* FWUP_CHKSUM REG(0x0008) 4Byte Send */ msleep(10); /* (Wait RUMBA Self Reset) */ fimc_is_ois_i2c_read(client, 0x6, (u8*)&RcvDataShort); /* Error Status read */ if (RcvDataShort == 0x0000) { /* F/W Update Success Process */ err("OISLOG OIS program update success\n"); } else { /* F/W Update Error Process */ err("OISLOG OIS program update fail\n"); } } else {