Jiri Slaby ef7db2
From: Jai Luthra <j-luthra@ti.com>
Jiri Slaby ef7db2
Date: Tue, 3 Jan 2023 13:27:35 +0100
Jiri Slaby ef7db2
Subject: [PATCH] media: ov5640: Fix soft reset sequence and timings
Jiri Slaby ef7db2
References: bsc#1012628
Jiri Slaby ef7db2
Patch-mainline: 6.2.3
Jiri Slaby ef7db2
Git-commit: decea0a98b7ac04536c7d659f74783e8d67a06c0
Jiri Slaby ef7db2
Jiri Slaby ef7db2
[ Upstream commit decea0a98b7ac04536c7d659f74783e8d67a06c0 ]
Jiri Slaby ef7db2
Jiri Slaby ef7db2
Move the register-based reset out of the init_setting[] and into the
Jiri Slaby ef7db2
powerup_sequence function. The sensor is power cycled and reset using
Jiri Slaby ef7db2
the gpio pins so the soft reset is not always necessary.
Jiri Slaby ef7db2
Jiri Slaby ef7db2
This also ensures that soft reset honors the timing sequence
Jiri Slaby ef7db2
from the datasheet [1].
Jiri Slaby ef7db2
Jiri Slaby ef7db2
[1] https://cdn.sparkfun.com/datasheets/Sensors/LightImaging/OV5640_datasheet.pdf
Jiri Slaby ef7db2
Jiri Slaby ef7db2
Fixes: 19a81c1426c1 ("[media] add Omnivision OV5640 sensor driver")
Jiri Slaby ef7db2
Reported-by: Nishanth Menon <nm@ti.com>
Jiri Slaby ef7db2
Suggested-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Jiri Slaby ef7db2
Signed-off-by: Jai Luthra <j-luthra@ti.com>
Jiri Slaby ef7db2
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonaboard.com>
Jiri Slaby ef7db2
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Jiri Slaby ef7db2
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Jiri Slaby ef7db2
Signed-off-by: Sasha Levin <sashal@kernel.org>
Jiri Slaby ef7db2
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Jiri Slaby ef7db2
---
Jiri Slaby ef7db2
 drivers/media/i2c/ov5640.c | 34 ++++++++++++++++++++++++----------
Jiri Slaby ef7db2
 1 file changed, 24 insertions(+), 10 deletions(-)
Jiri Slaby ef7db2
Jiri Slaby ef7db2
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
Jiri Slaby ef7db2
index e0f908af..75dada60 100644
Jiri Slaby ef7db2
--- a/drivers/media/i2c/ov5640.c
Jiri Slaby ef7db2
+++ b/drivers/media/i2c/ov5640.c
Jiri Slaby ef7db2
@@ -50,6 +50,7 @@
Jiri Slaby ef7db2
 #define OV5640_REG_SYS_CTRL0		0x3008
Jiri Slaby ef7db2
 #define OV5640_REG_SYS_CTRL0_SW_PWDN	0x42
Jiri Slaby ef7db2
 #define OV5640_REG_SYS_CTRL0_SW_PWUP	0x02
Jiri Slaby ef7db2
+#define OV5640_REG_SYS_CTRL0_SW_RST	0x82
Jiri Slaby ef7db2
 #define OV5640_REG_CHIP_ID		0x300a
Jiri Slaby ef7db2
 #define OV5640_REG_IO_MIPI_CTRL00	0x300e
Jiri Slaby ef7db2
 #define OV5640_REG_PAD_OUTPUT_ENABLE01	0x3017
Jiri Slaby ef7db2
@@ -532,7 +533,7 @@ static const struct v4l2_mbus_framefmt ov5640_default_fmt = {
Jiri Slaby ef7db2
 };
Jiri Slaby ef7db2
 
Jiri Slaby ef7db2
 static const struct reg_value ov5640_init_setting[] = {
Jiri Slaby ef7db2
-	{0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
Jiri Slaby ef7db2
+	{0x3103, 0x11, 0, 0},
Jiri Slaby ef7db2
 	{0x3103, 0x03, 0, 0}, {0x3630, 0x36, 0, 0},
Jiri Slaby ef7db2
 	{0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
Jiri Slaby ef7db2
 	{0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
Jiri Slaby ef7db2
@@ -2429,19 +2430,32 @@ static void ov5640_reset(struct ov5640_dev *sensor)
Jiri Slaby ef7db2
 	if (!sensor->reset_gpio)
Jiri Slaby ef7db2
 		return;
Jiri Slaby ef7db2
 
Jiri Slaby ef7db2
-	gpiod_set_value_cansleep(sensor->reset_gpio, 0);
Jiri Slaby ef7db2
+	if (sensor->pwdn_gpio) {
Jiri Slaby ef7db2
+		gpiod_set_value_cansleep(sensor->reset_gpio, 0);
Jiri Slaby ef7db2
 
Jiri Slaby ef7db2
-	/* camera power cycle */
Jiri Slaby ef7db2
-	ov5640_power(sensor, false);
Jiri Slaby ef7db2
-	usleep_range(5000, 10000);
Jiri Slaby ef7db2
-	ov5640_power(sensor, true);
Jiri Slaby ef7db2
-	usleep_range(5000, 10000);
Jiri Slaby ef7db2
+		/* camera power cycle */
Jiri Slaby ef7db2
+		ov5640_power(sensor, false);
Jiri Slaby ef7db2
+		usleep_range(5000, 10000);
Jiri Slaby ef7db2
+		ov5640_power(sensor, true);
Jiri Slaby ef7db2
+		usleep_range(5000, 10000);
Jiri Slaby ef7db2
 
Jiri Slaby ef7db2
-	gpiod_set_value_cansleep(sensor->reset_gpio, 1);
Jiri Slaby ef7db2
-	usleep_range(1000, 2000);
Jiri Slaby ef7db2
+		gpiod_set_value_cansleep(sensor->reset_gpio, 1);
Jiri Slaby ef7db2
+		usleep_range(1000, 2000);
Jiri Slaby ef7db2
 
Jiri Slaby ef7db2
-	gpiod_set_value_cansleep(sensor->reset_gpio, 0);
Jiri Slaby ef7db2
+		gpiod_set_value_cansleep(sensor->reset_gpio, 0);
Jiri Slaby ef7db2
+	} else {
Jiri Slaby ef7db2
+		/* software reset */
Jiri Slaby ef7db2
+		ov5640_write_reg(sensor, OV5640_REG_SYS_CTRL0,
Jiri Slaby ef7db2
+				 OV5640_REG_SYS_CTRL0_SW_RST);
Jiri Slaby ef7db2
+	}
Jiri Slaby ef7db2
 	usleep_range(20000, 25000);
Jiri Slaby ef7db2
+
Jiri Slaby ef7db2
+	/*
Jiri Slaby ef7db2
+	 * software standby: allows registers programming;
Jiri Slaby ef7db2
+	 * exit at restore_mode() for CSI, s_stream(1) for DVP
Jiri Slaby ef7db2
+	 */
Jiri Slaby ef7db2
+	ov5640_write_reg(sensor, OV5640_REG_SYS_CTRL0,
Jiri Slaby ef7db2
+			 OV5640_REG_SYS_CTRL0_SW_PWDN);
Jiri Slaby ef7db2
 }
Jiri Slaby ef7db2
 
Jiri Slaby ef7db2
 static int ov5640_set_power_on(struct ov5640_dev *sensor)
Jiri Slaby ef7db2
-- 
Jiri Slaby ef7db2
2.35.3
Jiri Slaby ef7db2