mirror of https://gitee.com/openkylin/linux.git
media: ov772x: make set_fmt() and s_frame_interval() return -EBUSY while streaming
The ov772x driver is going to offer a V4L2 sub-device interface, so changing the output data format and the frame interval on this sub-device can be made anytime. However, these requests are preferred to fail while the video stream on the device is active. Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Cc: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
parent
95f5a45aea
commit
7b9998c936
|
@ -424,9 +424,10 @@ struct ov772x_priv {
|
||||||
/* band_filter = COM8[5] ? 256 - BDBASE : 0 */
|
/* band_filter = COM8[5] ? 256 - BDBASE : 0 */
|
||||||
struct v4l2_ctrl *band_filter_ctrl;
|
struct v4l2_ctrl *band_filter_ctrl;
|
||||||
unsigned int fps;
|
unsigned int fps;
|
||||||
/* lock to protect power_count */
|
/* lock to protect power_count and streaming */
|
||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
int power_count;
|
int power_count;
|
||||||
|
int streaming;
|
||||||
#ifdef CONFIG_MEDIA_CONTROLLER
|
#ifdef CONFIG_MEDIA_CONTROLLER
|
||||||
struct media_pad pad;
|
struct media_pad pad;
|
||||||
#endif
|
#endif
|
||||||
|
@ -603,18 +604,28 @@ static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
|
||||||
{
|
{
|
||||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||||
struct ov772x_priv *priv = to_ov772x(sd);
|
struct ov772x_priv *priv = to_ov772x(sd);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (!enable) {
|
mutex_lock(&priv->lock);
|
||||||
ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
|
|
||||||
return 0;
|
if (priv->streaming == enable)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
ret = ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE,
|
||||||
|
enable ? 0 : SOFT_SLEEP_MODE);
|
||||||
|
if (ret)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
dev_dbg(&client->dev, "format %d, win %s\n",
|
||||||
|
priv->cfmt->code, priv->win->name);
|
||||||
}
|
}
|
||||||
|
priv->streaming = enable;
|
||||||
|
|
||||||
ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0);
|
done:
|
||||||
|
mutex_unlock(&priv->lock);
|
||||||
|
|
||||||
dev_dbg(&client->dev, "format %d, win %s\n",
|
return ret;
|
||||||
priv->cfmt->code, priv->win->name);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int ov772x_select_fps(struct ov772x_priv *priv,
|
static unsigned int ov772x_select_fps(struct ov772x_priv *priv,
|
||||||
|
@ -743,9 +754,15 @@ static int ov772x_s_frame_interval(struct v4l2_subdev *sd,
|
||||||
unsigned int fps;
|
unsigned int fps;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
mutex_lock(&priv->lock);
|
||||||
|
|
||||||
|
if (priv->streaming) {
|
||||||
|
ret = -EBUSY;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
fps = ov772x_select_fps(priv, tpf);
|
fps = ov772x_select_fps(priv, tpf);
|
||||||
|
|
||||||
mutex_lock(&priv->lock);
|
|
||||||
/*
|
/*
|
||||||
* If the device is not powered up by the host driver do
|
* If the device is not powered up by the host driver do
|
||||||
* not apply any changes to H/W at this time. Instead
|
* not apply any changes to H/W at this time. Instead
|
||||||
|
@ -1222,6 +1239,12 @@ static int ov772x_set_fmt(struct v4l2_subdev *sd,
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&priv->lock);
|
mutex_lock(&priv->lock);
|
||||||
|
|
||||||
|
if (priv->streaming) {
|
||||||
|
ret = -EBUSY;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the device is not powered up by the host driver do
|
* If the device is not powered up by the host driver do
|
||||||
* not apply any changes to H/W at this time. Instead
|
* not apply any changes to H/W at this time. Instead
|
||||||
|
|
Loading…
Reference in New Issue