Skip to content

Commit 3fe3d04

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 08743f9 commit 3fe3d04

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
@@ -78,7 +78,9 @@
7878
#define MT9P031_PIXEL_CLOCK_INVERT (1 << 15)
7979
#define MT9P031_PIXEL_CLOCK_SHIFT(n) ((n) << 8)
8080
#define MT9P031_PIXEL_CLOCK_DIVIDE(n) ((n) << 0)
81-
#define MT9P031_FRAME_RESTART 0x0b
81+
#define MT9P031_RESTART 0x0b
82+
#define MT9P031_FRAME_PAUSE_RESTART (1 << 1)
83+
#define MT9P031_FRAME_RESTART (1 << 0)
8284
#define MT9P031_SHUTTER_DELAY 0x0c
8385
#define MT9P031_RST 0x0d
8486
#define MT9P031_RST_ENABLE 1
@@ -445,9 +447,23 @@ static int mt9p031_set_params(struct mt9p031 *mt9p031)
445447
static int mt9p031_s_stream(struct v4l2_subdev *subdev, int enable)
446448
{
447449
struct mt9p031 *mt9p031 = to_mt9p031(subdev);
450+
struct i2c_client *client = v4l2_get_subdevdata(subdev);
451+
int val;
448452
int ret;
449453

450454
if (!enable) {
455+
/* enable pause restart */
456+
val = MT9P031_FRAME_PAUSE_RESTART;
457+
ret = mt9p031_write(client, MT9P031_RESTART, val);
458+
if (ret < 0)
459+
return ret;
460+
461+
/* enable restart + keep pause restart set */
462+
val |= MT9P031_FRAME_RESTART;
463+
ret = mt9p031_write(client, MT9P031_RESTART, val);
464+
if (ret < 0)
465+
return ret;
466+
451467
/* Stop sensor readout */
452468
ret = mt9p031_set_output_control(mt9p031,
453469
MT9P031_OUTPUT_CONTROL_CEN, 0);
@@ -467,6 +483,16 @@ static int mt9p031_s_stream(struct v4l2_subdev *subdev, int enable)
467483
if (ret < 0)
468484
return ret;
469485

486+
/*
487+
* - clear pause restart
488+
* - don't clear restart as clearing restart manually can cause
489+
* undefined behavior
490+
*/
491+
val = MT9P031_FRAME_RESTART;
492+
ret = mt9p031_write(client, MT9P031_RESTART, val);
493+
if (ret < 0)
494+
return ret;
495+
470496
return mt9p031_pll_enable(mt9p031);
471497
}
472498

0 commit comments

Comments
 (0)