return ret;
}
-int sensor_5e9_cis_otp_read(struct v4l2_subdev *subdev, struct fimc_is_device_sensor *device)
+int sensor_5e9_cis_otp_read(struct v4l2_subdev *subdev, struct fimc_is_device_sensor *device,
+ u32 page_start, u32 page_end,
+ u32 page_base, u32 page_index_start, u32 page_index_end)
{
int ret = 0;
struct fimc_is_cis *cis;
CALL_CISOPS(cis, cis_wait_streamon, subdev);
dbg_sensor(1, "%s, 3. page select & read cal", __func__);
- for (page = OTP_PAGE_START; page <= OTP_PAGE_END; page++) {
+ for (page = page_start; page <= page_end; page++) {
/* page select & read start */
fimc_is_sensor_write8(client, OTP_PAGE_SELECT, page);
fimc_is_sensor_write8(client, OTP_PAGE_CTRL, 0x01);
err("%s: OTP page[%d] read fail with err(%d)\n",
__func__, page, val);
- for (i = 0; i < OTP_PAGE_SIZE; i++) {
- fimc_is_sensor_read8(client, OTP_PAGE_BASE + i, &device->otp_cal_buf[page][i]);
+ for (i = page_index_start; i <= page_index_end; i++) {
+ fimc_is_sensor_read8(client, page_base + i, &device->otp_cal_buf[page][i]);
dbg_sensor(2, "cal: [%d][0x%x]: %x\n", page, OTP_PAGE_BASE + i, device->otp_cal_buf[page][i]);
}
char *otp_buf = (char *)&device->otp_cal_buf[0][0];
char file_str[60];
+ u8 serial_id[OTP_SERIAL_PAGE_MAX][OTP_SERIAL_NUMBER_SIZE];
+ int i,j;
+
+ for (i = 0; i < OTP_SERIAL_PAGE_MAX; i++) {
+ ret = sensor_5e9_cis_otp_read(subdev, device,
+ i * OTP_GRP2_OFFSET + OTP_SERIAL_PAGE_START, i * OTP_GRP2_OFFSET + OTP_SERIAL_PAGE_END,
+ OTP_PAGE_BASE, OTP_SERIAL_INDEX_START, OTP_SERIAL_INDEX_END);
+ if (ret) {
+ err("Don't read to serial number at OTP");
+ goto p_err;
+ }
+ for (j = OTP_SERIAL_INDEX_START; j <= OTP_SERIAL_INDEX_END; j++) {
+ serial_id[i][j - OTP_SERIAL_INDEX_START] =
+ device->otp_cal_buf[OTP_SERIAL_PAGE_START + i * OTP_GRP2_OFFSET][j];
+ }
+ }
+
snprintf(file_str, sizeof(file_str), "%s%s", OTP_DATA_PATH, device->otp_filename);
ret = sensor_cis_otp_read_file(file_str, (void *)device->otp_cal_buf, OTP_PAGE_SIZE * 64);
if (ret) {
- /* OTP data read */
- ret = sensor_5e9_cis_otp_read(subdev, device);
+ /* All OTP data read */
+ ret = sensor_5e9_cis_otp_read(subdev, device,
+ OTP_PAGE_START, OTP_PAGE_END,
+ OTP_PAGE_BASE, OTP_PAGE_START, OTP_PAGE_SIZE);
if (ret < 0) {
err("Don't read to 5E9 OTP data");
goto p_err;
/* Write to OTP data at file */
ret = sensor_cis_otp_write_file(file_str, (void *)device->otp_cal_buf, OTP_PAGE_SIZE * 64);
- if (ret < 0) {
+ if (ret < 0)
err("5E9 OTP data don't file write");
- goto p_err;
- }
+
+ goto p_err;
+ } else {
+ if (memcmp(serial_id[0], &device->otp_cal_buf[OTP_SERIAL_PAGE_START][OTP_SERIAL_INDEX_START], OTP_SERIAL_NUMBER_SIZE)
+ || memcmp(serial_id[1], &device->otp_cal_buf[OTP_SERIAL_PAGE_START + OTP_GRP2_OFFSET][OTP_SERIAL_INDEX_START], OTP_SERIAL_NUMBER_SIZE)) {
+ info("%s() : Different new module, so read OTP\n", __func__);
+
+ /* All OTP data read */
+ ret = sensor_5e9_cis_otp_read(subdev, device,
+ OTP_PAGE_START, OTP_PAGE_END,
+ OTP_PAGE_BASE, OTP_PAGE_START, OTP_PAGE_END);
+ if (ret < 0) {
+ err("Don't read to 2x5 OTP data");
+ goto p_err;
+ }
+
+ /* Write to OTP data at file */
+ ret = sensor_cis_otp_write_file(file_str, (void *)device->otp_cal_buf, OTP_PAGE_SIZE * 64);
+ if (ret < 0) {
+ err("5E9 OTP data don't file write");
+ goto p_err;
+ }
+ } else
+ info("%s(): Same module and file dump, use file dump data\n", __func__);
}
/* Need to first check GROUP2 */
#define CURRENT_BG_RATIO_OFFSET 0x34
#define CURRENT_GR_GB_RATIO_OFFSET 0x36
+#define OTP_SERIAL_PAGE_START 19
+#define OTP_SERIAL_PAGE_END 19
+#define OTP_SERIAL_NUMBER_SIZE 16
+
+#define OTP_SERIAL_PAGE_MAX 2
+#define OTP_SERIAL_INDEX_START 9
+#define OTP_SERIAL_INDEX_END 24
+
enum otp_group {
OTP_GROUP_ONE = 0x1,
OTP_GROUP_TWO = 0x2,
int ret = 0;
struct fimc_is_eeprom *eeprom;
struct i2c_client *client;
+ char serial_id[EEPROM_INFO_SERIAL_NUM_SIZE + 1];
+ char serial_id_dump[EEPROM_INFO_SERIAL_NUM_SIZE + 1];
FIMC_BUG(!subdev);
return ret;
}
+ I2C_MUTEX_LOCK(eeprom->i2c_lock);
+ ret = fimc_is_eeprom_module_read(client, EEPROM_INFO_SERIAL_NUM_START, serial_id, EEPROM_INFO_SERIAL_NUM_SIZE);
+ if (ret < 0) {
+ err("%s(): eeprom i2c read failed(%d)\n", __func__, ret);
+ I2C_MUTEX_UNLOCK(eeprom->i2c_lock);
+ return ret;
+ }
+ I2C_MUTEX_UNLOCK(eeprom->i2c_lock);
+ serial_id[EEPROM_INFO_SERIAL_NUM_SIZE] = '\0';
+
/*
* If already read at EEPROM data in module
* don't again read at EEPROM but there isn't file or
return ret;
}
} else {
- /* CRC check to each section cal data */
- ret = CALL_EEPROMOPS(eeprom, eeprom_check_all_crc, subdev);
- if (ret < 0)
- err("%s(): eeprom data invalid(%d)\n", __func__, ret);
+ memcpy(serial_id_dump, &eeprom->data[EEPROM_INFO_SERIAL_NUM_START],
+ EEPROM_INFO_SERIAL_NUM_SIZE);
+ serial_id_dump[EEPROM_INFO_SERIAL_NUM_SIZE] = '\0';
+
+ if(memcmp(serial_id, serial_id_dump, EEPROM_INFO_SERIAL_NUM_SIZE))
+ {
+ /* Read Sensor EEPROM cause change a module */
+ info("%s() : Different new module, so read eeprom\n", __func__);
+
+ I2C_MUTEX_LOCK(eeprom->i2c_lock);
+ /* I2C read to Sensor EEPROM cal data */
+ ret = fimc_is_eeprom_module_read(client, EEPROM_ADD_CRC_FST, eeprom->data, EEPROM_DATA_SIZE);
+ if (ret < 0) {
+ err("%s(): eeprom i2c read failed(%d)\n", __func__, ret);
+ I2C_MUTEX_UNLOCK(eeprom->i2c_lock);
+ return ret;
+ }
+ I2C_MUTEX_UNLOCK(eeprom->i2c_lock);
+
+ /* CRC check to each section cal data */
+ ret = CALL_EEPROMOPS(eeprom, eeprom_check_all_crc, subdev);
+ if (ret < 0)
+ err("%s(): eeprom data invalid(%d)\n", __func__, ret);
+
+ /* Write file to Cal data */
+ ret = fimc_is_eeprom_file_write(EEPROM_DATA_PATH, (void *)eeprom->data, EEPROM_DATA_SIZE);
+ if (ret < 0) {
+ err("%s(), eeprom file write fail(%d)\n", __func__, ret);
+ return ret;
+ }
+ } else {
+ info("%s(): Same module and file dump so use file dump data\n", __func__);
+
+ /* CRC check to each section cal data */
+ ret = CALL_EEPROMOPS(eeprom, eeprom_check_all_crc, subdev);
+ if (ret < 0)
+ err("%s(): eeprom data invalid(%d)\n", __func__, ret);
+ }
}
return ret;
int ret = 0;
struct fimc_is_eeprom *eeprom;
struct i2c_client *client;
+ char serial_id[EEPROM_INFO_SERIAL_NUM_SIZE + 1];
+ char serial_id_dump[EEPROM_INFO_SERIAL_NUM_SIZE + 1];
FIMC_BUG(!subdev);
return ret;
}
+ I2C_MUTEX_LOCK(eeprom->i2c_lock);
+ ret = fimc_is_eeprom_module_read(client, EEPROM_INFO_SERIAL_NUM_START, serial_id, EEPROM_INFO_SERIAL_NUM_SIZE);
+ if (ret < 0) {
+ err("%s(): eeprom i2c read failed(%d)\n", __func__, ret);
+ I2C_MUTEX_UNLOCK(eeprom->i2c_lock);
+ return ret;
+ }
+ I2C_MUTEX_UNLOCK(eeprom->i2c_lock);
+ serial_id[EEPROM_INFO_SERIAL_NUM_SIZE] = '\0';
+
/*
* If already read at EEPROM data in module
* don't again read at EEPROM but there isn't file or
return ret;
}
} else {
- /* CRC check to each section cal data */
- ret = CALL_EEPROMOPS(eeprom, eeprom_check_all_crc, subdev);
- if (ret < 0)
- err("%s(): eeprom data invalid(%d)\n", __func__, ret);
+ memcpy(serial_id_dump, &eeprom->data[EEPROM_INFO_SERIAL_NUM_START],
+ EEPROM_INFO_SERIAL_NUM_SIZE);
+ serial_id_dump[EEPROM_INFO_SERIAL_NUM_SIZE] = '\0';
+
+ if(memcmp(serial_id, serial_id_dump, EEPROM_INFO_SERIAL_NUM_SIZE))
+ {
+ /* Read Sensor EEPROM cause change a module */
+ info("%s() : Different new module, so read eeprom\n", __func__);
+
+ I2C_MUTEX_LOCK(eeprom->i2c_lock);
+ /* I2C read to Sensor EEPROM cal data */
+ ret = fimc_is_eeprom_module_read(client, EEPROM_ADD_CRC_FST, eeprom->data, EEPROM_DATA_SIZE);
+ if (ret < 0) {
+ err("%s(): eeprom i2c read failed(%d)\n", __func__, ret);
+ I2C_MUTEX_UNLOCK(eeprom->i2c_lock);
+ return ret;
+ }
+ I2C_MUTEX_UNLOCK(eeprom->i2c_lock);
+
+ /* CRC check to each section cal data */
+ ret = CALL_EEPROMOPS(eeprom, eeprom_check_all_crc, subdev);
+ if (ret < 0)
+ err("%s(): eeprom data invalid(%d)\n", __func__, ret);
+
+ /* Write file to Cal data */
+ ret = fimc_is_eeprom_file_write(EEPROM_DATA_PATH, (void *)eeprom->data, EEPROM_DATA_SIZE);
+ if (ret < 0) {
+ err("%s(), eeprom file write fail(%d)\n", __func__, ret);
+ return ret;
+ }
+ } else {
+ info("%s(): Same module and file dump so use file dump data\n", __func__);
+
+ /* CRC check to each section cal data */
+ ret = CALL_EEPROMOPS(eeprom, eeprom_check_all_crc, subdev);
+ if (ret < 0)
+ err("%s(): eeprom data invalid(%d)\n", __func__, ret);
+ }
}
return ret;