Skip to content

Commit 719ec29

Browse files
0xB0DHans Verkuil
authored andcommitted
media: ov5675: Fix power on/off delay timings
The ov5675 specification says that the gap between XSHUTDN deassert and the first I2C transaction should be a minimum of 8192 XVCLK cycles. Right now we use a usleep_rage() that gives a sleep time of between about 430 and 860 microseconds. On the Lenovo X13s we have observed that in about 1/20 cases the current timing is too tight and we start transacting before the ov5675's reset cycle completes, leading to I2C bus transaction failures. The reset racing is sometimes triggered at initial chip probe but, more usually on a subsequent power-off/power-on cycle e.g. [ 71.451662] ov5675 24-0010: failed to write reg 0x0103. error = -5 [ 71.451686] ov5675 24-0010: failed to set plls The current quiescence period we have is too tight. Instead of expressing the post reset delay in terms of the current XVCLK this patch converts the power-on and power-off delays to the maximum theoretical delay @ 6 MHz with an additional buffer. 1.365 milliseconds on the power-on path is 1.5 milliseconds with grace. 85.3 microseconds on the power-off path is 90 microseconds with grace. Fixes: 49d9ad7 ("media: ov5675: add device-tree support and support runtime PM") Cc: stable@vger.kernel.org Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> Tested-by: Johan Hovold <johan+linaro@kernel.org> Reviewed-by: Quentin Schulz <quentin.schulz@cherry.de> Tested-by: Quentin Schulz <quentin.schulz@cherry.de> # RK3399 Puma with Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
1 parent a1be997 commit 719ec29

1 file changed

Lines changed: 6 additions & 6 deletions

File tree

drivers/media/i2c/ov5675.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -972,12 +972,10 @@ static int ov5675_set_stream(struct v4l2_subdev *sd, int enable)
972972

973973
static int ov5675_power_off(struct device *dev)
974974
{
975-
/* 512 xvclk cycles after the last SCCB transation or MIPI frame end */
976-
u32 delay_us = DIV_ROUND_UP(512, OV5675_XVCLK_19_2 / 1000 / 1000);
977975
struct v4l2_subdev *sd = dev_get_drvdata(dev);
978976
struct ov5675 *ov5675 = to_ov5675(sd);
979977

980-
usleep_range(delay_us, delay_us * 2);
978+
usleep_range(90, 100);
981979

982980
clk_disable_unprepare(ov5675->xvclk);
983981
gpiod_set_value_cansleep(ov5675->reset_gpio, 1);
@@ -988,7 +986,6 @@ static int ov5675_power_off(struct device *dev)
988986

989987
static int ov5675_power_on(struct device *dev)
990988
{
991-
u32 delay_us = DIV_ROUND_UP(8192, OV5675_XVCLK_19_2 / 1000 / 1000);
992989
struct v4l2_subdev *sd = dev_get_drvdata(dev);
993990
struct ov5675 *ov5675 = to_ov5675(sd);
994991
int ret;
@@ -1014,8 +1011,11 @@ static int ov5675_power_on(struct device *dev)
10141011

10151012
gpiod_set_value_cansleep(ov5675->reset_gpio, 0);
10161013

1017-
/* 8192 xvclk cycles prior to the first SCCB transation */
1018-
usleep_range(delay_us, delay_us * 2);
1014+
/* Worst case quiesence gap is 1.365 milliseconds @ 6MHz XVCLK
1015+
* Add an additional threshold grace period to ensure reset
1016+
* completion before initiating our first I2C transaction.
1017+
*/
1018+
usleep_range(1500, 1600);
10191019

10201020
return 0;
10211021
}

0 commit comments

Comments
 (0)