diff options
| author | Jai Luthra <jai.luthra@ideasonboard.com> | 2026-02-14 16:05:22 +0300 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | 2026-03-11 03:05:35 +0300 |
| commit | 9206359b2c396ff594adf39bc7daaadab0fcb367 (patch) | |
| tree | d574789801e20b9535381dfd12d04968565d10b0 | |
| parent | bce1349dbf6348ddee47308e2ed08878356de317 (diff) | |
| download | linux-9206359b2c396ff594adf39bc7daaadab0fcb367.tar.xz | |
media: i2c: imx283: Fix hang when going from large to small resolution
When switching between modes (e.g. full resolution to binned),
standby_cancel() previously cleared XMSTA (starting master mode data
output) before the new mode's MDSEL, crop, and timing registers were
programmed in start_streaming(). This caused the sensor to briefly
output MIPI data using the previous mode's configuration.
On receivers like imx-mipi-csis, this leads to FIFO overflow errors
when switching from a higher to a lower resolution, as the receiver is
configured for the new smaller frame size but receives stale
full-resolution data.
Fix this by moving the XMSTA and SYNCDRV register writes from
standby_cancel() to the end of start_streaming(), after all mode,
crop, and timing registers have been configured. Also explicitly stop
master mode (XMSTA=1) when stopping the stream, matching the pattern
used by other Sony sensor drivers (imx290, imx415).
Use named macros IMX283_XMSTA_START/STOP instead of raw 0/BIT(0) for
readability.
Cc: stable@vger.kernel.org
Fixes: ccb4eb4496fa ("media: i2c: Add imx283 camera sensor driver")
Signed-off-by: Jai Luthra <jai.luthra@ideasonboard.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
| -rw-r--r-- | drivers/media/i2c/imx283.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/media/i2c/imx283.c b/drivers/media/i2c/imx283.c index 9b3094a57873..1be6164c2d15 100644 --- a/drivers/media/i2c/imx283.c +++ b/drivers/media/i2c/imx283.c @@ -129,7 +129,8 @@ /* Master Mode Operation Control */ #define IMX283_REG_XMSTA CCI_REG8(0x3105) -#define IMX283_XMSTA BIT(0) +#define IMX283_XMSTA_START 0 +#define IMX283_XMSTA_STOP BIT(0) #define IMX283_REG_SYNCDRV CCI_REG8(0x3107) #define IMX283_SYNCDRV_XHS_XVS (0xa0 | 0x02) @@ -1023,8 +1024,6 @@ static int imx283_standby_cancel(struct imx283 *imx283) usleep_range(19000, 20000); cci_write(imx283->cci, IMX283_REG_CLAMP, IMX283_CLPSQRST, &ret); - cci_write(imx283->cci, IMX283_REG_XMSTA, 0, &ret); - cci_write(imx283->cci, IMX283_REG_SYNCDRV, IMX283_SYNCDRV_XHS_XVS, &ret); return ret; } @@ -1117,6 +1116,10 @@ static int imx283_start_streaming(struct imx283 *imx283, /* Apply customized values from controls (HMAX/VMAX/SHR) */ ret = __v4l2_ctrl_handler_setup(imx283->sd.ctrl_handler); + /* Start master mode */ + cci_write(imx283->cci, IMX283_REG_XMSTA, IMX283_XMSTA_START, &ret); + cci_write(imx283->cci, IMX283_REG_SYNCDRV, IMX283_SYNCDRV_XHS_XVS, &ret); + return ret; } @@ -1153,12 +1156,14 @@ static int imx283_disable_streams(struct v4l2_subdev *sd, u64 streams_mask) { struct imx283 *imx283 = to_imx283(sd); - int ret; + int ret = 0; if (pad != IMAGE_PAD) return -EINVAL; - ret = cci_write(imx283->cci, IMX283_REG_STANDBY, IMX283_STANDBY, NULL); + cci_write(imx283->cci, IMX283_REG_XMSTA, IMX283_XMSTA_STOP, &ret); + cci_write(imx283->cci, IMX283_REG_STANDBY, IMX283_STANDBY, &ret); + if (ret) dev_err(imx283->dev, "Failed to stop stream\n"); |
