struct v4l2_subdev_format *sdformat)
{
struct prp_priv *priv = sd_to_priv(sd);
- struct imx_media_video_dev *vdev = priv->vdev;
const struct imx_media_pixfmt *cc;
- struct v4l2_pix_format vdev_fmt;
struct v4l2_mbus_framefmt *fmt;
int ret = 0;
priv->cc[PRPENCVF_SRC_PAD] = outcc;
}
- if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY)
- goto out;
-
- priv->cc[sdformat->pad] = cc;
+ if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ priv->cc[sdformat->pad] = cc;
- /* propagate output pad format to capture device */
- imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt,
- &priv->format_mbus[PRPENCVF_SRC_PAD],
- priv->cc[PRPENCVF_SRC_PAD]);
- mutex_unlock(&priv->lock);
- imx_media_capture_device_set_format(vdev, &vdev_fmt);
-
- return 0;
out:
mutex_unlock(&priv->lock);
return ret;
static int __capture_try_fmt_vid_cap(struct capture_priv *priv,
struct v4l2_subdev_format *fmt_src,
- struct v4l2_format *f)
+ struct v4l2_format *f,
+ const struct imx_media_pixfmt **retcc,
+ struct v4l2_rect *compose)
{
const struct imx_media_pixfmt *cc, *cc_src;
imx_media_mbus_fmt_to_pix_fmt(&f->fmt.pix, &fmt_src->format, cc);
+ if (retcc)
+ *retcc = cc;
+
+ if (compose) {
+ compose->left = 0;
+ compose->top = 0;
+ compose->width = fmt_src->format.width;
+ compose->height = fmt_src->format.height;
+ }
+
return 0;
}
if (ret)
return ret;
- return __capture_try_fmt_vid_cap(priv, &fmt_src, f);
+ return __capture_try_fmt_vid_cap(priv, &fmt_src, f, NULL, NULL);
}
static int capture_s_fmt_vid_cap(struct file *file, void *fh,
if (ret)
return ret;
- ret = __capture_try_fmt_vid_cap(priv, &fmt_src, f);
+ ret = __capture_try_fmt_vid_cap(priv, &fmt_src, f, &priv->vdev.cc,
+ &priv->vdev.compose);
if (ret)
return ret;
priv->vdev.fmt.fmt.pix = f->fmt.pix;
- priv->vdev.cc = imx_media_find_format(f->fmt.pix.pixelformat,
- CS_SEL_ANY, true);
- priv->vdev.compose.left = 0;
- priv->vdev.compose.top = 0;
- priv->vdev.compose.width = fmt_src.format.width;
- priv->vdev.compose.height = fmt_src.format.height;
return 0;
}
spin_unlock_irqrestore(&priv->q_lock, flags);
}
+static int capture_validate_fmt(struct capture_priv *priv)
+{
+ struct v4l2_subdev_format fmt_src;
+ const struct imx_media_pixfmt *cc;
+ struct v4l2_rect compose;
+ struct v4l2_format f;
+ int ret;
+
+ fmt_src.pad = priv->src_sd_pad;
+ fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src);
+ if (ret)
+ return ret;
+
+ v4l2_fill_pix_format(&f.fmt.pix, &fmt_src.format);
+
+ ret = __capture_try_fmt_vid_cap(priv, &fmt_src, &f, &cc, &compose);
+ if (ret)
+ return ret;
+
+ return (priv->vdev.fmt.fmt.pix.width != f.fmt.pix.width ||
+ priv->vdev.fmt.fmt.pix.height != f.fmt.pix.height ||
+ priv->vdev.cc->cs != cc->cs ||
+ priv->vdev.compose.width != compose.width ||
+ priv->vdev.compose.height != compose.height) ? -EINVAL : 0;
+}
+
static int capture_start_streaming(struct vb2_queue *vq, unsigned int count)
{
struct capture_priv *priv = vb2_get_drv_priv(vq);
unsigned long flags;
int ret;
+ ret = capture_validate_fmt(priv);
+ if (ret) {
+ v4l2_err(priv->src_sd, "capture format not valid\n");
+ goto return_bufs;
+ }
+
ret = imx_media_pipeline_set_stream(priv->md, &priv->src_sd->entity,
true);
if (ret) {
.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING,
};
-void imx_media_capture_device_set_format(struct imx_media_video_dev *vdev,
- struct v4l2_pix_format *pix)
-{
- struct capture_priv *priv = to_capture_priv(vdev);
-
- mutex_lock(&priv->mutex);
- priv->vdev.fmt.fmt.pix = *pix;
- priv->vdev.cc = imx_media_find_format(pix->pixelformat, CS_SEL_ANY,
- true);
- mutex_unlock(&priv->mutex);
-}
-EXPORT_SYMBOL_GPL(imx_media_capture_device_set_format);
-
struct imx_media_buffer *
imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev)
{
struct v4l2_subdev_format *sdformat)
{
struct csi_priv *priv = v4l2_get_subdevdata(sd);
- struct imx_media_video_dev *vdev = priv->vdev;
struct v4l2_fwnode_endpoint upstream_ep = { .bus_type = 0 };
const struct imx_media_pixfmt *cc;
- struct v4l2_pix_format vdev_fmt;
struct v4l2_mbus_framefmt *fmt;
struct v4l2_rect *crop, *compose;
int ret;
}
}
- if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY)
- goto out;
-
- priv->cc[sdformat->pad] = cc;
+ if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ priv->cc[sdformat->pad] = cc;
- /* propagate IDMAC output pad format to capture device */
- imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt,
- &priv->format_mbus[CSI_SRC_PAD_IDMAC],
- priv->cc[CSI_SRC_PAD_IDMAC]);
- mutex_unlock(&priv->lock);
- imx_media_capture_device_set_format(vdev, &vdev_fmt);
-
- return 0;
out:
mutex_unlock(&priv->lock);
return ret;
struct v4l2_subdev_format *sdformat)
{
struct imx7_csi *csi = v4l2_get_subdevdata(sd);
- struct imx_media_video_dev *vdev = csi->vdev;
const struct imx_media_pixfmt *outcc;
struct v4l2_mbus_framefmt *outfmt;
- struct v4l2_pix_format vdev_fmt;
const struct imx_media_pixfmt *cc;
struct v4l2_mbus_framefmt *fmt;
struct v4l2_subdev_format format;
csi->cc[IMX7_CSI_PAD_SRC] = outcc;
}
- if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY)
- goto out_unlock;
-
- csi->cc[sdformat->pad] = cc;
-
- /* propagate output pad format to capture device */
- imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt,
- &csi->format_mbus[IMX7_CSI_PAD_SRC],
- csi->cc[IMX7_CSI_PAD_SRC]);
- mutex_unlock(&csi->lock);
- imx_media_capture_device_set_format(vdev, &vdev_fmt);
-
- return 0;
+ if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ csi->cc[sdformat->pad] = cc;
out_unlock:
mutex_unlock(&csi->lock);