Commit 3a854824 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab

media: imx: capture: Rename ioctl operations with legacy prefix

The i.MX media drivers implement a legacy video node API, where the
format of the video node is influenced by the active format of the
connected subdev (both for enumeration and for the get, set and try
format ioctls), and where controls exposed by the subdevs in the
pipeline are inherited by the video node.

At the same time, the drivers implement the media controller API and
expose subdev video nodes to userspace. Those two modes of operation are
incompatible and should not be exposed together. Furthermore, the legacy
API gets in the way of proper enumeration of pixel formats on the video
node, as it prevents compliance with the V4L2 specification.

As a first step towards fixing this, rename all V4L2 video node ioctl
handlers with a legacy prefix. This will allow implementing a new set of
ioctls in parallel and gradually switching drivers. Add a task to the
TODO file for the removal of the legacy API.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: default avatarRui Miguel Silva <rmfrfs@gmail.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 300852e3
...@@ -17,9 +17,12 @@ ...@@ -17,9 +17,12 @@
- This media driver supports inheriting V4L2 controls to the - This media driver supports inheriting V4L2 controls to the
video capture devices, from the subdevices in the capture device's video capture devices, from the subdevices in the capture device's
pipeline. The controls for each capture device are updated in the pipeline. The controls for each capture device are updated in the
link_notify callback when the pipeline is modified. It should be link_notify callback when the pipeline is modified. This feature should be
decided whether this feature is useful enough to make it generally removed, userspace should use the subdev-based userspace API instead.
available by exporting to v4l2-core.
- Similarly to the legacy control handling, legacy format handling where
formats on the video nodes are influenced by the active format of the
connected subdev should be removed.
- i.MX7: all of the above, since it uses the imx media core - i.MX7: all of the above, since it uses the imx media core
......
...@@ -52,8 +52,8 @@ struct capture_priv { ...@@ -52,8 +52,8 @@ struct capture_priv {
/* In bytes, per queue */ /* In bytes, per queue */
#define VID_MEM_LIMIT SZ_64M #define VID_MEM_LIMIT SZ_64M
/* /* -----------------------------------------------------------------------------
* Video ioctls follow * Common Video IOCTLs
*/ */
static int capture_querycap(struct file *file, void *fh, static int capture_querycap(struct file *file, void *fh,
...@@ -69,7 +69,51 @@ static int capture_querycap(struct file *file, void *fh, ...@@ -69,7 +69,51 @@ static int capture_querycap(struct file *file, void *fh,
return 0; return 0;
} }
static int capture_enum_framesizes(struct file *file, void *fh, static int capture_g_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f)
{
struct capture_priv *priv = video_drvdata(file);
f->fmt.pix = priv->vdev.fmt;
return 0;
}
static int capture_g_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
struct capture_priv *priv = video_drvdata(file);
switch (s->target) {
case V4L2_SEL_TGT_COMPOSE:
case V4L2_SEL_TGT_COMPOSE_DEFAULT:
case V4L2_SEL_TGT_COMPOSE_BOUNDS:
/* The compose rectangle is fixed to the source format. */
s->r = priv->vdev.compose;
break;
case V4L2_SEL_TGT_COMPOSE_PADDED:
/*
* The hardware writes with a configurable but fixed DMA burst
* size. If the source format width is not burst size aligned,
* the written frame contains padding to the right.
*/
s->r.left = 0;
s->r.top = 0;
s->r.width = priv->vdev.fmt.width;
s->r.height = priv->vdev.fmt.height;
break;
default:
return -EINVAL;
}
return 0;
}
/* -----------------------------------------------------------------------------
* Legacy Video IOCTLs
*/
static int capture_legacy_enum_framesizes(struct file *file, void *fh,
struct v4l2_frmsizeenum *fsize) struct v4l2_frmsizeenum *fsize)
{ {
struct capture_priv *priv = video_drvdata(file); struct capture_priv *priv = video_drvdata(file);
...@@ -109,7 +153,7 @@ static int capture_enum_framesizes(struct file *file, void *fh, ...@@ -109,7 +153,7 @@ static int capture_enum_framesizes(struct file *file, void *fh,
return 0; return 0;
} }
static int capture_enum_frameintervals(struct file *file, void *fh, static int capture_legacy_enum_frameintervals(struct file *file, void *fh,
struct v4l2_frmivalenum *fival) struct v4l2_frmivalenum *fival)
{ {
struct capture_priv *priv = video_drvdata(file); struct capture_priv *priv = video_drvdata(file);
...@@ -140,7 +184,7 @@ static int capture_enum_frameintervals(struct file *file, void *fh, ...@@ -140,7 +184,7 @@ static int capture_enum_frameintervals(struct file *file, void *fh,
return 0; return 0;
} }
static int capture_enum_fmt_vid_cap(struct file *file, void *fh, static int capture_legacy_enum_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_fmtdesc *f) struct v4l2_fmtdesc *f)
{ {
struct capture_priv *priv = video_drvdata(file); struct capture_priv *priv = video_drvdata(file);
...@@ -184,17 +228,7 @@ static int capture_enum_fmt_vid_cap(struct file *file, void *fh, ...@@ -184,17 +228,7 @@ static int capture_enum_fmt_vid_cap(struct file *file, void *fh,
return 0; return 0;
} }
static int capture_g_fmt_vid_cap(struct file *file, void *fh, static int __capture_legacy_try_fmt(struct capture_priv *priv,
struct v4l2_format *f)
{
struct capture_priv *priv = video_drvdata(file);
f->fmt.pix = priv->vdev.fmt;
return 0;
}
static int __capture_try_fmt_vid_cap(struct capture_priv *priv,
struct v4l2_subdev_format *fmt_src, struct v4l2_subdev_format *fmt_src,
struct v4l2_format *f, struct v4l2_format *f,
const struct imx_media_pixfmt **retcc, const struct imx_media_pixfmt **retcc,
...@@ -255,7 +289,7 @@ static int __capture_try_fmt_vid_cap(struct capture_priv *priv, ...@@ -255,7 +289,7 @@ static int __capture_try_fmt_vid_cap(struct capture_priv *priv,
return 0; return 0;
} }
static int capture_try_fmt_vid_cap(struct file *file, void *fh, static int capture_legacy_try_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct capture_priv *priv = video_drvdata(file); struct capture_priv *priv = video_drvdata(file);
...@@ -268,10 +302,10 @@ static int capture_try_fmt_vid_cap(struct file *file, void *fh, ...@@ -268,10 +302,10 @@ static int capture_try_fmt_vid_cap(struct file *file, void *fh,
if (ret) if (ret)
return ret; return ret;
return __capture_try_fmt_vid_cap(priv, &fmt_src, f, NULL, NULL); return __capture_legacy_try_fmt(priv, &fmt_src, f, NULL, NULL);
} }
static int capture_s_fmt_vid_cap(struct file *file, void *fh, static int capture_legacy_s_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct capture_priv *priv = video_drvdata(file); struct capture_priv *priv = video_drvdata(file);
...@@ -289,7 +323,7 @@ static int capture_s_fmt_vid_cap(struct file *file, void *fh, ...@@ -289,7 +323,7 @@ static int capture_s_fmt_vid_cap(struct file *file, void *fh,
if (ret) if (ret)
return ret; return ret;
ret = __capture_try_fmt_vid_cap(priv, &fmt_src, f, &priv->vdev.cc, ret = __capture_legacy_try_fmt(priv, &fmt_src, f, &priv->vdev.cc,
&priv->vdev.compose); &priv->vdev.compose);
if (ret) if (ret)
return ret; return ret;
...@@ -299,21 +333,22 @@ static int capture_s_fmt_vid_cap(struct file *file, void *fh, ...@@ -299,21 +333,22 @@ static int capture_s_fmt_vid_cap(struct file *file, void *fh,
return 0; return 0;
} }
static int capture_querystd(struct file *file, void *fh, v4l2_std_id *std) static int capture_legacy_querystd(struct file *file, void *fh,
v4l2_std_id *std)
{ {
struct capture_priv *priv = video_drvdata(file); struct capture_priv *priv = video_drvdata(file);
return v4l2_subdev_call(priv->src_sd, video, querystd, std); return v4l2_subdev_call(priv->src_sd, video, querystd, std);
} }
static int capture_g_std(struct file *file, void *fh, v4l2_std_id *std) static int capture_legacy_g_std(struct file *file, void *fh, v4l2_std_id *std)
{ {
struct capture_priv *priv = video_drvdata(file); struct capture_priv *priv = video_drvdata(file);
return v4l2_subdev_call(priv->src_sd, video, g_std, std); return v4l2_subdev_call(priv->src_sd, video, g_std, std);
} }
static int capture_s_std(struct file *file, void *fh, v4l2_std_id std) static int capture_legacy_s_std(struct file *file, void *fh, v4l2_std_id std)
{ {
struct capture_priv *priv = video_drvdata(file); struct capture_priv *priv = video_drvdata(file);
...@@ -323,37 +358,7 @@ static int capture_s_std(struct file *file, void *fh, v4l2_std_id std) ...@@ -323,37 +358,7 @@ static int capture_s_std(struct file *file, void *fh, v4l2_std_id std)
return v4l2_subdev_call(priv->src_sd, video, s_std, std); return v4l2_subdev_call(priv->src_sd, video, s_std, std);
} }
static int capture_g_selection(struct file *file, void *fh, static int capture_legacy_g_parm(struct file *file, void *fh,
struct v4l2_selection *s)
{
struct capture_priv *priv = video_drvdata(file);
switch (s->target) {
case V4L2_SEL_TGT_COMPOSE:
case V4L2_SEL_TGT_COMPOSE_DEFAULT:
case V4L2_SEL_TGT_COMPOSE_BOUNDS:
/* The compose rectangle is fixed to the source format. */
s->r = priv->vdev.compose;
break;
case V4L2_SEL_TGT_COMPOSE_PADDED:
/*
* The hardware writes with a configurable but fixed DMA burst
* size. If the source format width is not burst size aligned,
* the written frame contains padding to the right.
*/
s->r.left = 0;
s->r.top = 0;
s->r.width = priv->vdev.fmt.width;
s->r.height = priv->vdev.fmt.height;
break;
default:
return -EINVAL;
}
return 0;
}
static int capture_g_parm(struct file *file, void *fh,
struct v4l2_streamparm *a) struct v4l2_streamparm *a)
{ {
struct capture_priv *priv = video_drvdata(file); struct capture_priv *priv = video_drvdata(file);
...@@ -375,7 +380,7 @@ static int capture_g_parm(struct file *file, void *fh, ...@@ -375,7 +380,7 @@ static int capture_g_parm(struct file *file, void *fh,
return 0; return 0;
} }
static int capture_s_parm(struct file *file, void *fh, static int capture_legacy_s_parm(struct file *file, void *fh,
struct v4l2_streamparm *a) struct v4l2_streamparm *a)
{ {
struct capture_priv *priv = video_drvdata(file); struct capture_priv *priv = video_drvdata(file);
...@@ -398,7 +403,7 @@ static int capture_s_parm(struct file *file, void *fh, ...@@ -398,7 +403,7 @@ static int capture_s_parm(struct file *file, void *fh,
return 0; return 0;
} }
static int capture_subscribe_event(struct v4l2_fh *fh, static int capture_legacy_subscribe_event(struct v4l2_fh *fh,
const struct v4l2_event_subscription *sub) const struct v4l2_event_subscription *sub)
{ {
switch (sub->type) { switch (sub->type) {
...@@ -413,25 +418,25 @@ static int capture_subscribe_event(struct v4l2_fh *fh, ...@@ -413,25 +418,25 @@ static int capture_subscribe_event(struct v4l2_fh *fh,
} }
} }
static const struct v4l2_ioctl_ops capture_ioctl_ops = { static const struct v4l2_ioctl_ops capture_legacy_ioctl_ops = {
.vidioc_querycap = capture_querycap, .vidioc_querycap = capture_querycap,
.vidioc_enum_framesizes = capture_enum_framesizes, .vidioc_enum_framesizes = capture_legacy_enum_framesizes,
.vidioc_enum_frameintervals = capture_enum_frameintervals, .vidioc_enum_frameintervals = capture_legacy_enum_frameintervals,
.vidioc_enum_fmt_vid_cap = capture_enum_fmt_vid_cap, .vidioc_enum_fmt_vid_cap = capture_legacy_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = capture_g_fmt_vid_cap, .vidioc_g_fmt_vid_cap = capture_g_fmt_vid_cap,
.vidioc_try_fmt_vid_cap = capture_try_fmt_vid_cap, .vidioc_try_fmt_vid_cap = capture_legacy_try_fmt_vid_cap,
.vidioc_s_fmt_vid_cap = capture_s_fmt_vid_cap, .vidioc_s_fmt_vid_cap = capture_legacy_s_fmt_vid_cap,
.vidioc_querystd = capture_querystd, .vidioc_querystd = capture_legacy_querystd,
.vidioc_g_std = capture_g_std, .vidioc_g_std = capture_legacy_g_std,
.vidioc_s_std = capture_s_std, .vidioc_s_std = capture_legacy_s_std,
.vidioc_g_selection = capture_g_selection, .vidioc_g_selection = capture_g_selection,
.vidioc_g_parm = capture_g_parm, .vidioc_g_parm = capture_legacy_g_parm,
.vidioc_s_parm = capture_s_parm, .vidioc_s_parm = capture_legacy_s_parm,
.vidioc_reqbufs = vb2_ioctl_reqbufs, .vidioc_reqbufs = vb2_ioctl_reqbufs,
.vidioc_create_bufs = vb2_ioctl_create_bufs, .vidioc_create_bufs = vb2_ioctl_create_bufs,
...@@ -443,12 +448,12 @@ static const struct v4l2_ioctl_ops capture_ioctl_ops = { ...@@ -443,12 +448,12 @@ static const struct v4l2_ioctl_ops capture_ioctl_ops = {
.vidioc_streamon = vb2_ioctl_streamon, .vidioc_streamon = vb2_ioctl_streamon,
.vidioc_streamoff = vb2_ioctl_streamoff, .vidioc_streamoff = vb2_ioctl_streamoff,
.vidioc_subscribe_event = capture_subscribe_event, .vidioc_subscribe_event = capture_legacy_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe, .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
}; };
/* /* -----------------------------------------------------------------------------
* Queue operations * Queue Operations
*/ */
static int capture_queue_setup(struct vb2_queue *vq, static int capture_queue_setup(struct vb2_queue *vq,
...@@ -540,7 +545,7 @@ static int capture_validate_fmt(struct capture_priv *priv) ...@@ -540,7 +545,7 @@ static int capture_validate_fmt(struct capture_priv *priv)
v4l2_fill_pix_format(&f.fmt.pix, &fmt_src.format); v4l2_fill_pix_format(&f.fmt.pix, &fmt_src.format);
ret = __capture_try_fmt_vid_cap(priv, &fmt_src, &f, &cc, &compose); ret = __capture_legacy_try_fmt(priv, &fmt_src, &f, &cc, &compose);
if (ret) if (ret)
return ret; return ret;
...@@ -616,9 +621,10 @@ static const struct vb2_ops capture_qops = { ...@@ -616,9 +621,10 @@ static const struct vb2_ops capture_qops = {
.stop_streaming = capture_stop_streaming, .stop_streaming = capture_stop_streaming,
}; };
/* /* -----------------------------------------------------------------------------
* File operations * File Operations
*/ */
static int capture_open(struct file *file) static int capture_open(struct file *file)
{ {
struct capture_priv *priv = video_drvdata(file); struct capture_priv *priv = video_drvdata(file);
...@@ -672,6 +678,10 @@ static const struct v4l2_file_operations capture_fops = { ...@@ -672,6 +678,10 @@ static const struct v4l2_file_operations capture_fops = {
.mmap = vb2_fop_mmap, .mmap = vb2_fop_mmap,
}; };
/* -----------------------------------------------------------------------------
* Public API
*/
struct imx_media_buffer * struct imx_media_buffer *
imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev) imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev)
{ {
...@@ -815,7 +825,7 @@ imx_media_capture_device_init(struct device *dev, struct v4l2_subdev *src_sd, ...@@ -815,7 +825,7 @@ imx_media_capture_device_init(struct device *dev, struct v4l2_subdev *src_sd,
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
vfd->fops = &capture_fops; vfd->fops = &capture_fops;
vfd->ioctl_ops = &capture_ioctl_ops; vfd->ioctl_ops = &capture_legacy_ioctl_ops;
vfd->minor = -1; vfd->minor = -1;
vfd->release = video_device_release; vfd->release = video_device_release;
vfd->vfl_dir = VFL_DIR_RX; vfd->vfl_dir = VFL_DIR_RX;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment