Skip to content

Commit 2d6f69a

Browse files
phyBendergregkh
authored andcommitted
media: mt9p031: Fix corrupted frame after restarting stream
[ Upstream commit 0961ba6 ] To prevent corrupted frames after starting and stopping the sensor its datasheet specifies a specific pause sequence to follow: Stopping: Set Pause_Restart Bit -> Set Restart Bit -> Set Chip_Enable Off Restarting: Set Chip_Enable On -> Clear Pause_Restart Bit The Restart Bit is cleared automatically and must not be cleared manually as this would cause undefined behavior. Signed-off-by: Dirk Bender <[email protected]> Signed-off-by: Stefan Riedmueller <[email protected]> Signed-off-by: Sakari Ailus <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 89d75fc commit 2d6f69a

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

drivers/media/i2c/mt9p031.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@
8181
#define MT9P031_PIXEL_CLOCK_INVERT (1 << 15)
8282
#define MT9P031_PIXEL_CLOCK_SHIFT(n) ((n) << 8)
8383
#define MT9P031_PIXEL_CLOCK_DIVIDE(n) ((n) << 0)
84-
#define MT9P031_FRAME_RESTART 0x0b
84+
#define MT9P031_RESTART 0x0b
85+
#define MT9P031_FRAME_PAUSE_RESTART (1 << 1)
86+
#define MT9P031_FRAME_RESTART (1 << 0)
8587
#define MT9P031_SHUTTER_DELAY 0x0c
8688
#define MT9P031_RST 0x0d
8789
#define MT9P031_RST_ENABLE 1
@@ -448,9 +450,23 @@ static int mt9p031_set_params(struct mt9p031 *mt9p031)
448450
static int mt9p031_s_stream(struct v4l2_subdev *subdev, int enable)
449451
{
450452
struct mt9p031 *mt9p031 = to_mt9p031(subdev);
453+
struct i2c_client *client = v4l2_get_subdevdata(subdev);
454+
int val;
451455
int ret;
452456

453457
if (!enable) {
458+
/* enable pause restart */
459+
val = MT9P031_FRAME_PAUSE_RESTART;
460+
ret = mt9p031_write(client, MT9P031_RESTART, val);
461+
if (ret < 0)
462+
return ret;
463+
464+
/* enable restart + keep pause restart set */
465+
val |= MT9P031_FRAME_RESTART;
466+
ret = mt9p031_write(client, MT9P031_RESTART, val);
467+
if (ret < 0)
468+
return ret;
469+
454470
/* Stop sensor readout */
455471
ret = mt9p031_set_output_control(mt9p031,
456472
MT9P031_OUTPUT_CONTROL_CEN, 0);
@@ -470,6 +486,16 @@ static int mt9p031_s_stream(struct v4l2_subdev *subdev, int enable)
470486
if (ret < 0)
471487
return ret;
472488

489+
/*
490+
* - clear pause restart
491+
* - don't clear restart as clearing restart manually can cause
492+
* undefined behavior
493+
*/
494+
val = MT9P031_FRAME_RESTART;
495+
ret = mt9p031_write(client, MT9P031_RESTART, val);
496+
if (ret < 0)
497+
return ret;
498+
473499
return mt9p031_pll_enable(mt9p031);
474500
}
475501

0 commit comments

Comments
 (0)