media: allegro: implement S_FMT for CAPTURE
authorMichael Tretter <m.tretter@pengutronix.de>
Fri, 15 Jan 2021 09:34:59 +0000 (10:34 +0100)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Wed, 27 Jan 2021 15:04:30 +0000 (16:04 +0100)
In order to support different codecs, the driver must support changing
the format on CAPTURE. Therefore, the driver needs to handle S_FMT on
CAPTURE.

As the driver will have a different number of formats for OUTPUT and
CAPTURE, split the check for the format index in ENUM_FMT into CAPTURE
and OUTPUT.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
drivers/media/platform/allegro-dvt/allegro-core.c

index dd02ca5..4d8e274 100644 (file)
@@ -2502,13 +2502,15 @@ static int allegro_querycap(struct file *file, void *fh,
 static int allegro_enum_fmt_vid(struct file *file, void *fh,
                                struct v4l2_fmtdesc *f)
 {
-       if (f->index)
-               return -EINVAL;
        switch (f->type) {
        case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+               if (f->index >= 1)
+                       return -EINVAL;
                f->pixelformat = V4L2_PIX_FMT_NV12;
                break;
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+               if (f->index >= 1)
+                       return -EINVAL;
                f->pixelformat = V4L2_PIX_FMT_H264;
                break;
        default:
@@ -2556,6 +2558,28 @@ static int allegro_try_fmt_vid_cap(struct file *file, void *fh,
        return 0;
 }
 
+static int allegro_s_fmt_vid_cap(struct file *file, void *fh,
+                                struct v4l2_format *f)
+{
+       struct allegro_channel *channel = fh_to_channel(fh);
+       struct vb2_queue *vq;
+       int err;
+
+       err = allegro_try_fmt_vid_cap(file, fh, f);
+       if (err)
+               return err;
+
+       vq = v4l2_m2m_get_vq(channel->fh.m2m_ctx, f->type);
+       if (!vq)
+               return -EINVAL;
+       if (vb2_is_busy(vq))
+               return -EBUSY;
+
+       channel->codec = f->fmt.pix.pixelformat;
+
+       return 0;
+}
+
 static int allegro_g_fmt_vid_out(struct file *file, void *fh,
                                 struct v4l2_format *f)
 {
@@ -2768,7 +2792,7 @@ static const struct v4l2_ioctl_ops allegro_ioctl_ops = {
        .vidioc_enum_fmt_vid_out = allegro_enum_fmt_vid,
        .vidioc_g_fmt_vid_cap = allegro_g_fmt_vid_cap,
        .vidioc_try_fmt_vid_cap = allegro_try_fmt_vid_cap,
-       .vidioc_s_fmt_vid_cap = allegro_try_fmt_vid_cap,
+       .vidioc_s_fmt_vid_cap = allegro_s_fmt_vid_cap,
        .vidioc_g_fmt_vid_out = allegro_g_fmt_vid_out,
        .vidioc_try_fmt_vid_out = allegro_try_fmt_vid_out,
        .vidioc_s_fmt_vid_out = allegro_s_fmt_vid_out,