[COMMON] fimc-is2: troika: improve eeprom dump flow
authorwangdw10 <wangdw10@lenovo.com>
Fri, 10 May 2019 07:39:49 +0000 (15:39 +0800)
committerKim Gunho <gunho.kim@samsung.com>
Wed, 7 Aug 2019 13:00:11 +0000 (22:00 +0900)
read module serial numbe and check to dump eeprom

Change-Id: Ib61d4041e720aed780b25c5ac462799f8100aafa
Signed-off-by: wangdw10 <wangdw10@lenovo.com>
drivers/media/platform/exynos/fimc-is2/sensor/module_framework/cis/fimc-is-cis-5e9.c
drivers/media/platform/exynos/fimc-is2/sensor/module_framework/cis/fimc-is-cis-5e9.h
drivers/media/platform/exynos/fimc-is2/sensor/module_framework/eeprom/fimc-is-sensor-eeprom-12a10.c
drivers/media/platform/exynos/fimc-is2/sensor/module_framework/eeprom/fimc-is-sensor-eeprom-16885c.c

index e545854121764859903011bed6652b248e9d1ad3..966347b78a12cbd0f4a466642f127f5aae285ac5 100755 (executable)
@@ -291,7 +291,9 @@ int sensor_5e9_cis_otp_check_crc(struct v4l2_subdev *subdev,
        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;
@@ -326,7 +328,7 @@ int sensor_5e9_cis_otp_read(struct v4l2_subdev *subdev, struct fimc_is_device_se
        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);
@@ -347,8 +349,8 @@ int sensor_5e9_cis_otp_read(struct v4l2_subdev *subdev, struct fimc_is_device_se
                        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]);
                }
 
@@ -374,11 +376,30 @@ int sensor_5e9_cis_otp(struct v4l2_subdev *subdev, struct fimc_is_device_sensor
        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;
@@ -386,10 +407,32 @@ int sensor_5e9_cis_otp(struct v4l2_subdev *subdev, struct fimc_is_device_sensor
 
                /* 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 */
index 295c2e69a95e6e72b74cd2cfbec3bc22ec704d41..5f2238992d5c65db975f5e23674a8a1fade7496e 100644 (file)
 #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,
index 7aefd77cbe536a622e17521697d97ea32ac1ba27..45e23271b6570a7870f730801a5a5c5d7a986706 100644 (file)
@@ -450,6 +450,8 @@ int fimc_is_eeprom_12a10_get_cal_data(struct v4l2_subdev *subdev)
        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);
 
@@ -464,6 +466,16 @@ int fimc_is_eeprom_12a10_get_cal_data(struct v4l2_subdev *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
@@ -493,10 +505,44 @@ int fimc_is_eeprom_12a10_get_cal_data(struct v4l2_subdev *subdev)
                        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;
index 7d70cfddd0f662465818e6a93666a631f9773a1a..383a329754839d59d34fa6fd06528a1e8e209103 100644 (file)
@@ -269,6 +269,8 @@ int fimc_is_eeprom_16885c_get_cal_data(struct v4l2_subdev *subdev)
        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);
 
@@ -283,6 +285,16 @@ int fimc_is_eeprom_16885c_get_cal_data(struct v4l2_subdev *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
@@ -312,10 +324,44 @@ int fimc_is_eeprom_16885c_get_cal_data(struct v4l2_subdev *subdev)
                        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;