From b19685e5893c9eabe72e91484e9b3abc52e85b78 Mon Sep 17 00:00:00 2001 From: wangdw10 Date: Fri, 10 May 2019 15:39:49 +0800 Subject: [PATCH] [COMMON] fimc-is2: troika: improve eeprom dump flow read module serial numbe and check to dump eeprom Change-Id: Ib61d4041e720aed780b25c5ac462799f8100aafa Signed-off-by: wangdw10 --- .../module_framework/cis/fimc-is-cis-5e9.c | 61 ++++++++++++++++--- .../module_framework/cis/fimc-is-cis-5e9.h | 8 +++ .../eeprom/fimc-is-sensor-eeprom-12a10.c | 54 ++++++++++++++-- .../eeprom/fimc-is-sensor-eeprom-16885c.c | 54 ++++++++++++++-- 4 files changed, 160 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/cis/fimc-is-cis-5e9.c b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/cis/fimc-is-cis-5e9.c index e54585412176..966347b78a12 100755 --- a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/cis/fimc-is-cis-5e9.c +++ b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/cis/fimc-is-cis-5e9.c @@ -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 */ diff --git a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/cis/fimc-is-cis-5e9.h b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/cis/fimc-is-cis-5e9.h index 295c2e69a95e..5f2238992d5c 100644 --- a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/cis/fimc-is-cis-5e9.h +++ b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/cis/fimc-is-cis-5e9.h @@ -75,6 +75,14 @@ #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, diff --git a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/eeprom/fimc-is-sensor-eeprom-12a10.c b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/eeprom/fimc-is-sensor-eeprom-12a10.c index 7aefd77cbe53..45e23271b657 100644 --- a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/eeprom/fimc-is-sensor-eeprom-12a10.c +++ b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/eeprom/fimc-is-sensor-eeprom-12a10.c @@ -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; diff --git a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/eeprom/fimc-is-sensor-eeprom-16885c.c b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/eeprom/fimc-is-sensor-eeprom-16885c.c index 7d70cfddd0f6..383a32975483 100644 --- a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/eeprom/fimc-is-sensor-eeprom-16885c.c +++ b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/eeprom/fimc-is-sensor-eeprom-16885c.c @@ -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; -- 2.20.1