From 99aa4c8c189848fed7b33b7c2b27e3f01abb0354 Mon Sep 17 00:00:00 2001 From: "Guoniu.zhou" Date: Wed, 13 Nov 2019 16:28:59 +0800 Subject: [PATCH] media: i2c: fix the incomplete first frame issue VSYNC signal trigger before a frame end when ov5640 work at MIPI mode. It leads to the first frame content only hav some lines of image. I tried many configuration and finally have the patch to fix the issue. My thought is suspending sensor when update its registers and resume after update. Signed-off-by: Guoniu.zhou --- drivers/media/i2c/ov5640.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index b17bc6601f6c..057a718d0cf3 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -154,6 +154,7 @@ static const int ov5640_framerates[] = { [OV5640_15_FPS] = 15, [OV5640_30_FPS] = 30, [OV5640_60_FPS] = 60, + [OV5640_07_FPS] = 8, }; /* regulator supplies */ @@ -358,6 +359,7 @@ static const struct reg_value ov5640_init_setting_30fps_VGA[] = { }; static const struct reg_value ov5640_setting_VGA_640_480[] = { + {0x3008, 0x42, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, @@ -374,6 +376,7 @@ static const struct reg_value ov5640_setting_VGA_640_480[] = { {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, + {0x3008, 0x02, 0, 10}, }; static const struct reg_value ov5640_setting_XGA_1024_768[] = { @@ -398,6 +401,7 @@ static const struct reg_value ov5640_setting_XGA_1024_768[] = { }; static const struct reg_value ov5640_setting_QVGA_320_240[] = { + {0x3008, 0x42, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, @@ -414,9 +418,11 @@ static const struct reg_value ov5640_setting_QVGA_320_240[] = { {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, + {0x3008, 0x02, 0, 10}, }; static const struct reg_value ov5640_setting_QCIF_176_144[] = { + {0x3008, 0x42, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, @@ -433,9 +439,11 @@ static const struct reg_value ov5640_setting_QCIF_176_144[] = { {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, + {0x3008, 0x02, 0, 10}, }; static const struct reg_value ov5640_setting_NTSC_720_480[] = { + {0x3008, 0x42, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, @@ -452,9 +460,11 @@ static const struct reg_value ov5640_setting_NTSC_720_480[] = { {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, + {0x3008, 0x02, 0, 10}, }; static const struct reg_value ov5640_setting_PAL_720_576[] = { + {0x3008, 0x42, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, @@ -471,6 +481,7 @@ static const struct reg_value ov5640_setting_PAL_720_576[] = { {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, + {0x3008, 0x02, 0, 10}, }; static const struct reg_value ov5640_setting_720P_1280_720[] = { @@ -523,7 +534,7 @@ static const struct reg_value ov5640_setting_1080P_1920_1080[] = { {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x04, 0, 0}, {0x3a15, 0x60, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3824, 0x04, 0, 0}, - {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0}, + {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 10}, }; static const struct reg_value ov5640_setting_QSXGA_2592_1944[] = { @@ -1268,7 +1279,7 @@ static int ov5640_set_stream_dvp(struct ov5640_dev *sensor, bool on) * 2: MIPI enable */ ret = ov5640_write_reg(sensor, - OV5640_REG_IO_MIPI_CTRL00, on ? 0x18 : 0); + OV5640_REG_IO_MIPI_CTRL00, on ? 0x58 : 0); if (ret) return ret; @@ -1617,8 +1628,15 @@ ov5640_find_mode(struct ov5640_dev *sensor, enum ov5640_frame_rate fr, if (((mode->id == OV5640_MODE_1080P_1920_1080) && (fr != OV5640_15_FPS)) || ((mode->id == OV5640_MODE_QSXGA_2592_1944) && (fr != OV5640_07_FPS))) return NULL; + /* + * MIPI mode only support 2592x1944@15 + */ + } else if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY) { + if ((mode->id == OV5640_MODE_QSXGA_2592_1944) && (fr != OV5640_15_FPS)) + return NULL; } + if (!mode || (!nearest && (mode->hact != width || mode->vact != height))) return NULL; @@ -2027,7 +2045,7 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on) * [2] = 0 : MIPI interface disabled */ ret = ov5640_write_reg(sensor, - OV5640_REG_IO_MIPI_CTRL00, 0x40); + OV5640_REG_IO_MIPI_CTRL00, 0x45); if (ret) goto power_off;