mirror of
https://github.com/torvalds/linux.git
synced 2026-09-25 17:42:03 +02:00
media: i2c: ov8865: Program the sensor on stream start
The sensor registers are only written in the runtime PM resume handler; ov8865_set_fmt() merely stores the requested mode, relying on the sensor being runtime suspended between uses so that the next resume applies it. That assumption breaks when something keeps the sensor powered. On IPU3 platforms, ipu_bridge instantiates the VCM device with a DL_FLAG_PM_RUNTIME device link to the sensor, so a userspace process holding the VCM subdev open (e.g. wireplumber's camera monitor) pins the sensor runtime-active. A subsequent set_fmt() then never reaches the hardware: the sensor keeps streaming the mode programmed on the last resume while the CSI-2 receiver expects the newly negotiated format. On a Surface Book 2 (IPU3, ov8865 + dw9719 VCM), requesting the 3264x2448 mode while the hardware was left programmed for the 1632x1224 binned mode makes ipu3-cio2 report "frame sync error" and "payload length is 10340352, received 2585088" (exactly one binned frame) for every frame, and the inverse case stalls the stream after a single frame. Camera applications end up displaying one bogus frame forever. Program the sensor configuration and apply the control values on stream start instead, where the negotiated mode is always current, and only write the configuration in the runtime PM resume handler when resuming with the stream already started. Signed-off-by: Jurison Murati <eng.juri@gmail.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
This commit is contained in:
parent
3fe797a12b
commit
4e1446ac16
|
|
@ -2609,7 +2609,7 @@ static int ov8865_s_stream(struct v4l2_subdev *subdev, int enable)
|
|||
{
|
||||
struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);
|
||||
struct ov8865_state *state = &sensor->state;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (enable) {
|
||||
ret = pm_runtime_resume_and_get(sensor->dev);
|
||||
|
|
@ -2618,7 +2618,23 @@ static int ov8865_s_stream(struct v4l2_subdev *subdev, int enable)
|
|||
}
|
||||
|
||||
mutex_lock(&sensor->mutex);
|
||||
ret = ov8865_sw_standby(sensor, !enable);
|
||||
|
||||
/*
|
||||
* The sensor may have been kept powered by something else (e.g. the
|
||||
* VCM's runtime PM device link on IPU3 platforms), in which case
|
||||
* runtime resume did not run and the hardware may still be
|
||||
* configured for a previous mode. Always program the negotiated
|
||||
* configuration on stream start.
|
||||
*/
|
||||
if (enable) {
|
||||
ret = ov8865_sensor_init(sensor);
|
||||
if (!ret)
|
||||
ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
ret = ov8865_sw_standby(sensor, !enable);
|
||||
|
||||
mutex_unlock(&sensor->mutex);
|
||||
|
||||
if (ret || !enable)
|
||||
|
|
@ -2914,15 +2930,15 @@ static int ov8865_resume(struct device *dev)
|
|||
if (ret)
|
||||
goto complete;
|
||||
|
||||
ret = ov8865_sensor_init(sensor);
|
||||
if (ret)
|
||||
goto error_power;
|
||||
|
||||
ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
|
||||
if (ret)
|
||||
goto error_power;
|
||||
|
||||
if (state->streaming) {
|
||||
ret = ov8865_sensor_init(sensor);
|
||||
if (ret)
|
||||
goto error_power;
|
||||
|
||||
ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
|
||||
if (ret)
|
||||
goto error_power;
|
||||
|
||||
ret = ov8865_sw_standby(sensor, false);
|
||||
if (ret)
|
||||
goto error_power;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user