[COMMON] media: smfc: move v4l2 ioctl handlers in separate file
authorCho KyongHo <pullip.cho@samsung.com>
Thu, 23 Jul 2015 08:07:25 +0000 (17:07 +0900)
committerCosmin Tanislav <demonsingur@gmail.com>
Mon, 22 Apr 2024 17:22:19 +0000 (20:22 +0300)
The implementation of v4l2 ioctl handlers occupies the half of smfc.c
The handlers are moved to another file for easier maintenance.

Change-Id: Ic65243aef0e173177f819be9b723bdea36c81ba9
Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
drivers/media/platform/exynos/smfc/Makefile
drivers/media/platform/exynos/smfc/smfc-v4l2-ioctls.c [new file with mode: 0644]
drivers/media/platform/exynos/smfc/smfc.c
drivers/media/platform/exynos/smfc/smfc.h

index 3b802490fe8eada587cc9635c6b34364eaceca61..6977f942f4a33c7597a35568fb421b76ba5bb004 100644 (file)
@@ -3,4 +3,4 @@
 #              http://www.samsung.com
 #
 
-obj-$(CONFIG_VIDEO_EXYNOS_SMFC) += smfc.o smfc-regs.o
+obj-$(CONFIG_VIDEO_EXYNOS_SMFC) += smfc.o smfc-v4l2-ioctls.o smfc-regs.o
diff --git a/drivers/media/platform/exynos/smfc/smfc-v4l2-ioctls.c b/drivers/media/platform/exynos/smfc/smfc-v4l2-ioctls.c
new file mode 100644 (file)
index 0000000..dfef008
--- /dev/null
@@ -0,0 +1,797 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * The main source file of Samsung Exynos SMFC Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+
+#include "smfc.h"
+
+/* SMFC SPECIFIC DEVICE CAPABILITIES */
+/* set if H/W supports for decompression */
+#define V4L2_CAP_EXYNOS_JPEG_DECOMPRESSION             0x0100
+/* set if H/W can compress dual images */
+#define V4L2_CAP_EXYNOS_JPEG_B2B_COMPRESSION           0x0200
+/* set if H/W supports for Hardware Flow Control */
+#define V4L2_CAP_EXYNOS_JPEG_HWFC                      0x0400
+/* set if H/W supports for HWFC on internal buffers */
+#define V4L2_CAP_EXYNOS_JPEG_HWFC_EMBEDDED             0x0800
+/* set if H/W has a register to configure stream buffer size */
+#define V4L2_CAP_EXYNOS_JPEG_MAX_STREAMSIZE            0x1000
+/* set if H/W does not have 128-bit alignment constraint for stream base */
+#define V4L2_CAP_EXYNOS_JPEG_NO_STREAMBASE_ALIGN       0x2000
+/* set if H/W does not have 128-bit alignment constraint for image base */
+#define V4L2_CAP_EXYNOS_JPEG_NO_IMAGEBASE_ALIGN                0x4000
+
+/* SMFC SPECIFIC CONTROLS */
+#define V4L2_CID_JPEG_SEC_COMP_QUALITY (V4L2_CID_JPEG_CLASS_BASE + 20)
+#define V4L2_CID_JPEG_HWFC_ENABLE      (V4L2_CID_JPEG_CLASS_BASE + 25)
+
+#define SMFC_FMT_MAIN_SIZE(val) ((val) & 0xFFFF)
+#define SMFC_FMT_SEC_SIZE(val) (((val) >> 16) & 0xFFFF)
+
+const struct smfc_image_format smfc_image_formats[] = {
+       {
+               /* JPEG should be the first format */
+               .description    = "Baseline JPEG(Sequential DCT)",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_JPEG,
+               .regcfg         = 0, /* Chagneable accroding to chroma factor */
+               .bpp_buf        = {0}, /* undeterministic */
+               .bpp_pix        = {0}, /* undeterministic */
+               .num_planes     = 1,
+               .num_buffers    = 1,
+               .chroma_hfactor = 1, /* dummy chroma subsampling factor */
+               .chroma_vfactor = 1, /* These will not affect to H/W config. */
+       }, {
+               /* YUYV is the default format */
+               .description    = "YUV4:2:2 1-Plane 16BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_YUYV,
+               .regcfg         = SMFC_IMGFMT_YUYV,
+               .bpp_buf        = {16},
+               .bpp_pix        = {16},
+               .num_planes     = 1,
+               .num_buffers    = 1,
+               .chroma_hfactor = 2,
+               .chroma_vfactor = 1,
+       }, {
+               .description    = "YUV4:2:2 1-Plane 16BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_YVYU,
+               .regcfg         = SMFC_IMGFMT_YVYU,
+               .bpp_buf        = {16},
+               .bpp_pix        = {16},
+               .num_planes     = 1,
+               .num_buffers    = 1,
+               .chroma_hfactor = 2,
+               .chroma_vfactor = 1,
+       }, {
+               .description    = "YUV4:2:2 2-Plane 16BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_NV16,
+               .regcfg         = SMFC_IMGFMT_NV16,
+               .bpp_buf        = {16},
+               .bpp_pix        = {8, 8, 0},
+               .num_planes     = 2,
+               .num_buffers    = 1,
+               .chroma_hfactor = 2,
+               .chroma_vfactor = 1,
+       }, {
+               .description    = "YUV4:2:2 2-Plane 16BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_NV61,
+               .regcfg         = SMFC_IMGFMT_NV61,
+               .bpp_buf        = {16},
+               .bpp_pix        = {8, 8, 0},
+               .num_planes     = 2,
+               .num_buffers    = 1,
+               .chroma_hfactor = 2,
+               .chroma_vfactor = 1,
+       }, {
+               .description    = "YUV4:2:2 3-Plane 16BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_YUV422P,
+               .regcfg         = SMFC_IMGFMT_YUV422,
+               .bpp_buf        = {16},
+               .bpp_pix        = {8, 2, 2},
+               .num_planes     = 3,
+               .num_buffers    = 1,
+               .chroma_hfactor = 2,
+               .chroma_vfactor = 1,
+       }, {
+               .description    = "YUV4:2:0 2-Plane(Cb/Cr) 12BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_NV12,
+               .regcfg         = SMFC_IMGFMT_NV12,
+               .bpp_buf        = {12},
+               .bpp_pix        = {8, 4, 0},
+               .num_planes     = 2,
+               .num_buffers    = 1,
+               .chroma_hfactor = 2,
+               .chroma_vfactor = 2,
+       }, {
+               .description    = "YUV4:2:0 2-Plane(Cr/Cb) 12BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_NV21,
+               .regcfg         = SMFC_IMGFMT_NV21,
+               .bpp_buf        = {12},
+               .bpp_pix        = {8, 4, 0},
+               .num_planes     = 2,
+               .num_buffers    = 1,
+               .chroma_hfactor = 2,
+               .chroma_vfactor = 2,
+       }, {
+               .description    = "YUV4:2:0 3-Plane 12BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_YUV420,
+               .regcfg         = SMFC_IMGFMT_YUV420P,
+               .bpp_buf        = {12},
+               .bpp_pix        = {8, 2, 2},
+               .num_planes     = 3,
+               .num_buffers    = 1,
+               .chroma_hfactor = 2,
+               .chroma_vfactor = 2,
+       }, {
+               .description    = "YVU4:2:0 3-Plane 12BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_YVU420,
+               .regcfg         = SMFC_IMGFMT_YVU420P,
+               .bpp_buf        = {12},
+               .bpp_pix        = {8, 2, 2},
+               .num_planes     = 3,
+               .num_buffers    = 1,
+               .chroma_hfactor = 2,
+               .chroma_vfactor = 2,
+       }, {
+               .description    = "YUV4:4:4 3-Plane 16BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_YUV444,
+               .regcfg         = SMFC_IMGFMT_YUV444,
+               .bpp_buf        = {24},
+               .bpp_pix        = {8, 8, 8},
+               .num_planes     = 3,
+               .num_buffers    = 1,
+               .chroma_hfactor = 1,
+               .chroma_vfactor = 1,
+       }, {
+               .description    = "RGB565 LE 16BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_RGB565,
+               .regcfg         = SMFC_IMGFMT_RGB565,
+               .bpp_buf        = {16},
+               .bpp_pix        = {16},
+               .num_planes     = 1,
+               .num_buffers    = 1,
+               .chroma_hfactor = 1,
+               .chroma_vfactor = 1,
+       }, {
+               .description    = "RGB565 BE 16BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_RGB565X,
+               .regcfg         = SMFC_IMGFMT_BGR565,
+               .bpp_buf        = {16},
+               .bpp_pix        = {16},
+               .num_planes     = 1,
+               .num_buffers    = 1,
+               .chroma_hfactor = 1,
+               .chroma_vfactor = 1,
+       }, {
+               .description    = "RGB888 LE 24BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_RGB24,
+               .regcfg         = SMFC_IMGFMT_RGB24,
+               .bpp_buf        = {24},
+               .bpp_pix        = {24},
+               .num_planes     = 1,
+               .num_buffers    = 1,
+               .chroma_hfactor = 1,
+               .chroma_vfactor = 1,
+       }, {
+               .description    = "RGB888 BE 24BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_BGR24,
+               .regcfg         = SMFC_IMGFMT_BGR24,
+               .bpp_buf        = {24},
+               .bpp_pix        = {24},
+               .num_planes     = 1,
+               .num_buffers    = 1,
+               .chroma_hfactor = 1,
+               .chroma_vfactor = 1,
+       }, {
+               .description    = "ABGR8888 LE 32BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_RGB32,
+               .regcfg         = SMFC_IMGFMT_RGBA32,
+               .bpp_buf        = {32},
+               .bpp_pix        = {32},
+               .num_planes     = 1,
+               .num_buffers    = 1,
+               .chroma_hfactor = 1,
+               .chroma_vfactor = 1,
+       }, {
+               .description    = "ARGB8888 BE 32BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_BGR32,
+               .regcfg         = SMFC_IMGFMT_BGRA32,
+               .bpp_buf        = {32},
+               .bpp_pix        = {32},
+               .num_planes     = 1,
+               .num_buffers    = 1,
+               .chroma_hfactor = 1,
+               .chroma_vfactor = 1,
+       },
+       /* multi-planar formats must be at the last becuse of VIDOC_ENUM_FMT */
+       {
+               .description    = "YUV4:2:0 2-MPlane(Cb/Cr) 8+4BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_NV12M,
+               .regcfg         = SMFC_IMGFMT_NV12,
+               .bpp_buf        = {8, 4},
+               .bpp_pix        = {8, 4},
+               .num_planes     = 2,
+               .num_buffers    = 2,
+               .chroma_hfactor = 2,
+               .chroma_vfactor = 2,
+       }, {
+               .description    = "YUV4:2:0 2-MPlane(Cr/Cb) 8+4BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_NV21M,
+               .regcfg         = SMFC_IMGFMT_NV21,
+               .bpp_buf        = {8, 4},
+               .bpp_pix        = {8, 4},
+               .num_planes     = 2,
+               .num_buffers    = 2,
+               .chroma_hfactor = 2,
+               .chroma_vfactor = 2,
+       }, {
+               .description    = "YUV4:2:0 3-MPlane 8+2+2BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_YUV420M,
+               .regcfg         = SMFC_IMGFMT_YUV420P,
+               .bpp_buf        = {8, 2, 2},
+               .bpp_pix        = {8, 2, 2},
+               .num_planes     = 3,
+               .num_buffers    = 3,
+               .chroma_hfactor = 2,
+               .chroma_vfactor = 2,
+       }, {
+               .description    = "YVU4:2:0 3-MPlane 8+2+2BPP",
+               .v4l2_pixfmt    = V4L2_PIX_FMT_YVU420M,
+               .regcfg         = SMFC_IMGFMT_YVU420P,
+               .bpp_buf        = {8, 2, 2},
+               .bpp_pix        = {8, 2, 2},
+               .num_planes     = 3,
+               .num_buffers    = 3,
+               .chroma_hfactor = 2,
+               .chroma_vfactor = 2,
+       }
+};
+
+static const struct smfc_image_format *smfc_find_format(
+                               struct smfc_dev *smfc, __u32 v4l2_pixfmt)
+{
+       size_t i;
+
+       for (i = 0; i < ARRAY_SIZE(smfc_image_formats); i++)
+               if (smfc_image_formats[i].v4l2_pixfmt == v4l2_pixfmt)
+                       return &smfc_image_formats[i];
+
+       dev_warn(smfc->dev, "Pixel format '%08X' not found, YUYV is forced.\n",
+               v4l2_pixfmt);
+
+       return V4L2_TYPE_IS_OUTPUT(v4l2_pixfmt) ? SMFC_DEFAULT_OUTPUT_FORMAT
+                                               : SMFC_DEFAULT_CAPTURE_FORMAT;
+}
+
+static const char *buf_type_name(__u32 type)
+{
+       return V4L2_TYPE_IS_OUTPUT(type) ? "capture" : "output";
+}
+
+static int smfc_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct smfc_ctx *ctx = container_of(ctrl->handler,
+                                           struct smfc_ctx, v4l2_ctrlhdlr);
+       switch (ctrl->id) {
+       case V4L2_CID_JPEG_COMPRESSION_QUALITY:
+               ctx->quality_factor = (unsigned char)ctrl->val;
+               break;
+       case V4L2_CID_JPEG_SEC_COMP_QUALITY:
+               ctx->thumb_quality_factor = (unsigned char)ctrl->val;
+               break;
+       case V4L2_CID_JPEG_HWFC_ENABLE:
+               ctx->enable_hwfc = (unsigned char)ctrl->val;
+               break;
+       case V4L2_CID_JPEG_RESTART_INTERVAL:
+               ctx->restart_interval = (unsigned char)ctrl->val;
+               break;
+       case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
+               switch (ctrl->val) {
+               case V4L2_JPEG_CHROMA_SUBSAMPLING_444:
+                       ctx->chroma_hfactor = 1;
+                       ctx->chroma_vfactor = 1;
+                       break;
+               case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
+                       ctx->chroma_hfactor = 2;
+                       ctx->chroma_vfactor = 2;
+                       break;
+               case V4L2_JPEG_CHROMA_SUBSAMPLING_411:
+                       ctx->chroma_hfactor = 4;
+                       ctx->chroma_vfactor = 1;
+                       break;
+               case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
+                       ctx->chroma_hfactor = 0;
+                       ctx->chroma_vfactor = 0;
+                       break;
+               case V4L2_JPEG_CHROMA_SUBSAMPLING_410:
+                       dev_info(ctx->smfc->dev,
+                               "Compression to YUV410 is not supported\n");
+                       /* pass through to 422 */
+               case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
+               default:
+                       ctx->chroma_hfactor = 2;
+                       ctx->chroma_vfactor = 1;
+                       break;
+               }
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+static const struct v4l2_ctrl_ops smfc_ctrl_ops = {
+       .s_ctrl = smfc_s_ctrl,
+};
+
+int smfc_init_controls(struct smfc_dev *smfc,
+                       struct v4l2_ctrl_handler *hdlr)
+{
+       const char *msg;
+       struct v4l2_ctrl_config ctrlcfg;
+
+       v4l2_ctrl_handler_init(hdlr, 1);
+
+       if (!v4l2_ctrl_new_std(hdlr, &smfc_ctrl_ops,
+                               V4L2_CID_JPEG_COMPRESSION_QUALITY,
+                               1, 100, 1, 96)) {
+               msg = "quality factor";
+               goto err;
+       }
+
+       memset(&ctrlcfg, 0, sizeof(ctrlcfg));
+       ctrlcfg.ops = &smfc_ctrl_ops;
+       ctrlcfg.id = V4L2_CID_JPEG_SEC_COMP_QUALITY;
+       ctrlcfg.name = "Quality factor of secondray image";
+       ctrlcfg.type = V4L2_CTRL_TYPE_INTEGER;
+       ctrlcfg.min = 1;
+       ctrlcfg.max = 100;
+       ctrlcfg.step = 1;
+       ctrlcfg.def = 50;
+       if (!v4l2_ctrl_new_custom(hdlr, &ctrlcfg, NULL)) {
+               msg = "secondary quality factor";
+               goto err;
+       }
+
+       memset(&ctrlcfg, 0, sizeof(ctrlcfg));
+       ctrlcfg.ops = &smfc_ctrl_ops;
+       ctrlcfg.id = V4L2_CID_JPEG_HWFC_ENABLE;
+       ctrlcfg.name = "HWFC configuration";
+       ctrlcfg.type = V4L2_CTRL_TYPE_BOOLEAN;
+       ctrlcfg.min = 0;
+       ctrlcfg.max = 1;
+       ctrlcfg.step = 1;
+       ctrlcfg.def = 0;
+       if (!v4l2_ctrl_new_custom(hdlr, &ctrlcfg, NULL)) {
+               msg = "secondary quality factor";
+               goto err;
+       }
+
+       if (!v4l2_ctrl_new_std(hdlr, &smfc_ctrl_ops,
+                               V4L2_CID_JPEG_RESTART_INTERVAL,
+                               0, 64, 1, 0)) {
+               msg = "restart interval";
+               goto err;
+       }
+
+       if (!v4l2_ctrl_new_std_menu(hdlr, &smfc_ctrl_ops,
+                               V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
+                               V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, 0,
+                               V4L2_JPEG_CHROMA_SUBSAMPLING_422)) {
+               msg = "chroma subsampling";
+               goto err;
+       }
+
+       return 0;
+err:
+       dev_err(smfc->dev, "Failed to install %s control (%d)\n",
+               msg, hdlr->error);
+       return hdlr->error;
+}
+
+static int smfc_v4l2_querycap(struct file *filp, void *fh,
+                            struct v4l2_capability *cap)
+{
+       struct smfc_dev *smfc = v4l2_fh_to_smfc_ctx(fh)->smfc;
+
+       strncpy(cap->driver, MODULE_NAME, sizeof(cap->driver));
+       strncpy(cap->bus_info, dev_name(smfc->dev), sizeof(cap->bus_info));
+       scnprintf(cap->card, sizeof(cap->card), "Still MFC %02x.%02x.%04x",
+                       (smfc->hwver >> 24) & 0xFF, (smfc->hwver >> 16) & 0xFF,
+                       smfc->hwver & 0xFFFF);
+
+       cap->driver[sizeof(cap->driver) - 1] = '\0';
+       cap->card[sizeof(cap->card) - 1] = '\0';
+       cap->bus_info[sizeof(cap->bus_info) - 1] = '\0';
+
+       cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE
+                               | V4L2_CAP_VIDEO_M2M;
+       cap->capabilities |= V4L2_CAP_DEVICE_CAPS;
+
+       cap->device_caps = V4L2_CAP_EXYNOS_JPEG_B2B_COMPRESSION;
+       cap->device_caps |= V4L2_CAP_EXYNOS_JPEG_HWFC;
+       cap->device_caps |= V4L2_CAP_EXYNOS_JPEG_MAX_STREAMSIZE;
+       cap->device_caps |= V4L2_CAP_EXYNOS_JPEG_NO_STREAMBASE_ALIGN;
+       cap->device_caps |= V4L2_CAP_EXYNOS_JPEG_NO_IMAGEBASE_ALIGN;
+
+       return 0;
+}
+
+static int smfc_v4l2_enum_fmt_mplane(struct file *filp, void *fh,
+                                    struct v4l2_fmtdesc *f)
+{
+       const struct smfc_image_format *fmt;
+
+       if (f->index >= ARRAY_SIZE(smfc_image_formats))
+               return -EINVAL;
+
+       fmt = &smfc_image_formats[f->index];
+       strncpy(f->description, fmt->description, sizeof(f->description));
+       f->description[sizeof(f->description) - 1] = '\0';
+       f->pixelformat = fmt->v4l2_pixfmt;
+       if (fmt->bpp_buf[0] == 0)
+               f->flags = V4L2_FMT_FLAG_COMPRESSED;
+
+       return 0;
+}
+
+static int smfc_v4l2_enum_fmt(struct file *filp, void *fh,
+                             struct v4l2_fmtdesc *f)
+{
+       int ret = smfc_v4l2_enum_fmt_mplane(filp, fh, f);
+
+       if (ret < 0)
+               return ret;
+
+       return smfc_image_formats[f->index].num_buffers > 1 ? -EINVAL : 0;
+}
+
+static int smfc_v4l2_g_fmt_mplane(struct file *filp, void *fh,
+                                 struct v4l2_format *f)
+{
+       struct smfc_ctx *ctx = v4l2_fh_to_smfc_ctx(fh);
+
+       f->fmt.pix_mp.width = ctx->width;
+       f->fmt.pix_mp.height = ctx->height;
+
+       if (!smfc_is_compressed_type(ctx, f->type)) {
+               int i;
+               /* uncompressed image */
+               f->fmt.pix_mp.pixelformat = ctx->img_fmt->v4l2_pixfmt;
+               f->fmt.pix_mp.num_planes = ctx->img_fmt->num_buffers;
+               for (i = 0; i < ctx->img_fmt->num_buffers; i++) {
+                       f->fmt.pix_mp.plane_fmt[i].bytesperline =
+                               (f->fmt.pix_mp.width *
+                                        ctx->img_fmt->bpp_buf[i]) / 8;
+                       f->fmt.pix_mp.plane_fmt[i].sizeimage =
+                                       f->fmt.pix_mp.plane_fmt[i].bytesperline;
+                       f->fmt.pix_mp.plane_fmt[i].sizeimage *=
+                                                       f->fmt.pix_mp.height;
+               }
+       } else {
+               f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_JPEG;
+               f->fmt.pix_mp.num_planes = 1;
+               f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
+               f->fmt.pix_mp.plane_fmt[0].sizeimage = 0;
+       }
+
+       f->fmt.pix_mp.field = 0;
+       f->fmt.pix_mp.colorspace = 0;
+
+       return 0;
+}
+
+static int smfc_v4l2_g_fmt(struct file *filp, void *fh, struct v4l2_format *f)
+{
+       struct smfc_ctx *ctx = v4l2_fh_to_smfc_ctx(fh);
+
+       f->fmt.pix.width = ctx->width;
+       f->fmt.pix.height = ctx->height;
+
+       if (!smfc_is_compressed_type(ctx, f->type)) {
+               if (ctx->img_fmt->num_buffers > 1) {
+                       dev_err(ctx->smfc->dev,
+                               "Current format is a multi-planar format\n");
+                       return -EINVAL;
+               }
+
+               /* uncompressed image */
+               f->fmt.pix.pixelformat = ctx->img_fmt->v4l2_pixfmt;
+               f->fmt.pix.bytesperline =
+                       (f->fmt.pix.width * ctx->img_fmt->bpp_buf[0]) / 8;
+               f->fmt.pix.sizeimage = f->fmt.pix.bytesperline;
+               f->fmt.pix.sizeimage *= f->fmt.pix.height;
+       } else {
+               f->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG;
+               f->fmt.pix.bytesperline = 0;
+               f->fmt.pix.sizeimage = 0;
+       }
+
+       f->fmt.pix.field = 0;
+       f->fmt.pix.colorspace = 0;
+
+       return 0;
+}
+
+static bool __smfc_check_image_size(struct device *dev, __u32 type,
+                                 const struct smfc_image_format *smfc_fmt,
+                                 __u32 width, __u32 height)
+{
+       __u32 min_width = SMFC_MIN_WIDTH << smfc_fmt->chroma_hfactor;
+       __u32 min_height = SMFC_MIN_WIDTH << smfc_fmt->chroma_vfactor;
+
+       if ((width < min_width) || (height < min_height)) {
+               dev_warn(dev, "Too small image size(%ux%u) for '%s'\n",
+                               width, height, buf_type_name(type));
+               return false;
+       }
+
+       if ((width > SMFC_MAX_WIDTH) || (height > SMFC_MAX_HEIGHT)) {
+               dev_warn(dev, "Too large image size(%ux%u) for '%s'\n",
+                               width, height, buf_type_name(type));
+               return false;
+       }
+
+       if (((width % smfc_fmt->chroma_hfactor) != 0) ||
+               ((height % smfc_fmt->chroma_vfactor) != 0)) {
+               dev_err(dev, "Invalid size %ux%u for format '%s'\n",
+                       width, height, smfc_fmt->description);
+               return false;
+       }
+
+       return true;
+}
+static bool smfc_check_image_size(struct device *dev, __u32 type,
+                                 const struct smfc_image_format *smfc_fmt,
+                                 __u32 width, __u32 height)
+{
+       __u32 twidth = SMFC_FMT_SEC_SIZE(width);
+       __u32 theight = SMFC_FMT_SEC_SIZE(height);
+
+       width = SMFC_FMT_MAIN_SIZE(width);
+       height = SMFC_FMT_MAIN_SIZE(height);
+
+       if (!__smfc_check_image_size(dev, type, smfc_fmt, width, height))
+               return false;
+
+       if (!twidth || !theight) /* thumbnail image size is not specified */
+               return true;
+
+       if (!__smfc_check_image_size(dev, type, smfc_fmt, twidth, theight))
+               return false;
+
+       return true;
+}
+
+static bool smfc_v4l2_init_fmt_mplane(const struct smfc_ctx *ctx,
+                       const struct smfc_image_format *smfc_fmt,
+                       __u32 type, struct v4l2_pix_format_mplane *pix_mp)
+{
+       unsigned int i;
+
+       if (!smfc_check_image_size(ctx->smfc->dev, type,
+                               smfc_fmt, pix_mp->width, pix_mp->height))
+               return false;
+       /* informs the user that the format might be changed to the default */
+       pix_mp->pixelformat = smfc_fmt->v4l2_pixfmt;
+       /* JPEG format has zero in smfc_fmt->bpp_buf[0] */
+       for (i = 0; i < smfc_fmt->num_buffers; i++) {
+               pix_mp->plane_fmt[i].bytesperline =
+                               (SMFC_FMT_MAIN_SIZE(pix_mp->width) *
+                                smfc_fmt->bpp_buf[i]) / 8;
+               pix_mp->plane_fmt[i].sizeimage =
+                               pix_mp->plane_fmt[i].bytesperline *
+                                       SMFC_FMT_MAIN_SIZE(pix_mp->height);
+       }
+
+       pix_mp->field = 0;
+       pix_mp->num_planes = smfc_fmt->num_buffers;
+
+       if (SMFC_FMT_SEC_SIZE(pix_mp->width) &&
+                               SMFC_FMT_SEC_SIZE(pix_mp->height)) {
+               /*
+                * Format information for the secondary image is stored after
+                * the last plane of the main image. It is okay to use more
+                * planes because the maximum valid planes are eight
+                */
+               unsigned int j;
+
+               for (j = 0; j < smfc_fmt->num_buffers; j++) {
+                       pix_mp->plane_fmt[i + j].bytesperline =
+                               (SMFC_FMT_SEC_SIZE(pix_mp->width) *
+                                       smfc_fmt->bpp_buf[j]) / 8;
+                       pix_mp->plane_fmt[i + j].sizeimage =
+                               pix_mp->plane_fmt[i + j].bytesperline *
+                                       SMFC_FMT_SEC_SIZE(pix_mp->height);
+               }
+       }
+
+       return true;
+}
+
+static int smfc_v4l2_try_fmt_mplane(struct file *filp, void *fh,
+                                 struct v4l2_format *f)
+{
+       struct smfc_ctx *ctx = v4l2_fh_to_smfc_ctx(fh);
+       const struct smfc_image_format *smfc_fmt =
+                       smfc_find_format(ctx->smfc, f->fmt.pix_mp.pixelformat);
+
+       return smfc_v4l2_init_fmt_mplane(
+                       ctx, smfc_fmt, f->type, &f->fmt.pix_mp) ? 0 : -EINVAL;
+}
+
+static int smfc_v4l2_check_s_fmt(struct smfc_ctx *ctx,
+                                const struct smfc_image_format *smfc_fmt,
+                                __u32 type)
+{
+       struct vb2_queue *thisvq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, type);
+       struct vb2_queue *othervq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+                       V4L2_TYPE_IS_OUTPUT(type) ?
+                               V4L2_BUF_TYPE_VIDEO_CAPTURE :
+                               V4L2_BUF_TYPE_VIDEO_OUTPUT);
+       u32 flags;
+
+       if (thisvq->num_buffers > 0) {
+               dev_err(ctx->smfc->dev,
+                       "S_FMT after REQBUFS is not allowed\n");
+               return -EBUSY;
+       }
+
+       flags = smfc_config_ctxflag(ctx, SMFC_CTX_COMPRESS,
+                       is_jpeg(smfc_fmt) != V4L2_TYPE_IS_OUTPUT(type));
+
+       if (othervq->num_buffers > 0) { /* REQBUFSed on other vq */
+               if ((flags & SMFC_CTX_COMPRESS) !=
+                                       (ctx->flags & SMFC_CTX_COMPRESS)) {
+                       dev_err(ctx->smfc->dev,
+                               "Changing mode is prohibited after reqbufs\n");
+                       ctx->flags = flags;
+                       return -EBUSY;
+               }
+       }
+
+       /* reset the buf type of vq with the given buf type */
+       thisvq->type = type;
+
+       return 0;
+}
+
+static __u32 v4l2_to_multiplane_type(__u32 type)
+{
+       /* V4L2_BUF_TYPE_VIDEO_CAPTURE+8 = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */
+       return V4L2_TYPE_IS_MULTIPLANAR(type) ? type : type + 8;
+}
+
+static int smfc_v4l2_s_fmt_mplane(struct file *filp, void *fh,
+                                   struct v4l2_format *f)
+{
+       struct smfc_ctx *ctx = v4l2_fh_to_smfc_ctx(fh);
+       const struct smfc_image_format *smfc_fmt =
+                       smfc_find_format(ctx->smfc, f->fmt.pix_mp.pixelformat);
+       int ret = smfc_v4l2_check_s_fmt(ctx, smfc_fmt, f->type);
+
+       if (ret)
+               return ret;
+
+       if (!smfc_v4l2_init_fmt_mplane(ctx, smfc_fmt, f->type, &f->fmt.pix_mp))
+               return -EINVAL;
+
+       ctx->width = SMFC_FMT_MAIN_SIZE(f->fmt.pix_mp.width);
+       ctx->height = SMFC_FMT_MAIN_SIZE(f->fmt.pix_mp.height);
+       ctx->thumb_width = SMFC_FMT_SEC_SIZE(f->fmt.pix_mp.width);
+       ctx->thumb_height = SMFC_FMT_SEC_SIZE(f->fmt.pix_mp.height);
+
+       if (ctx->thumb_width && ctx->thumb_height)
+               ctx->flags |= SMFC_CTX_B2B_COMPRESS;
+       else
+               ctx->flags &= ~SMFC_CTX_B2B_COMPRESS;
+
+       if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_JPEG)
+               ctx->img_fmt = smfc_fmt;
+
+       if (ctx->flags & SMFC_CTX_B2B_COMPRESS) {
+               struct vb2_queue *othervq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+                       V4L2_TYPE_IS_OUTPUT(f->type) ?
+                               V4L2_BUF_TYPE_VIDEO_CAPTURE :
+                               V4L2_BUF_TYPE_VIDEO_OUTPUT);
+               /*
+                * type change of the current queue is completed in
+                * smfc_v4l2_check_s_fmt()
+                */
+               othervq->type = v4l2_to_multiplane_type(othervq->type);
+       }
+
+       return 0;
+}
+
+static bool smfc_v4l2_init_fmt(const struct smfc_ctx *ctx,
+                               const struct smfc_image_format *smfc_fmt,
+                               __u32 type, struct v4l2_pix_format *pix)
+{
+       BUG_ON(V4L2_TYPE_IS_MULTIPLANAR(pix->pixelformat));
+
+       if (!smfc_check_image_size(ctx->smfc->dev, type,
+                               smfc_fmt, pix->width, pix->height))
+               return false;
+       /* informs the user that the format might be changed to the default */
+       pix->pixelformat = smfc_fmt->v4l2_pixfmt;
+       /* JPEG format has zero in smfc_fmt->bpp_buf[0] */
+       pix->bytesperline = (pix->width *  smfc_fmt->bpp_buf[0]) / 8;
+       pix->sizeimage = pix->bytesperline * pix->height;
+       pix->field = 0;
+
+       return true;
+}
+
+static int smfc_v4l2_try_fmt(struct file *filp, void *fh, struct v4l2_format *f)
+{
+       struct smfc_ctx *ctx = v4l2_fh_to_smfc_ctx(fh);
+       const struct smfc_image_format *smfc_fmt =
+                       smfc_find_format(ctx->smfc, f->fmt.pix.pixelformat);
+
+       return smfc_v4l2_init_fmt(ctx, smfc_fmt, f->type, &f->fmt.pix)
+                                                               ? 0 : -EINVAL;
+}
+
+static int smfc_v4l2_s_fmt(struct file *filp, void *fh, struct v4l2_format *f)
+{
+       struct smfc_ctx *ctx = v4l2_fh_to_smfc_ctx(fh);
+       const struct smfc_image_format *smfc_fmt =
+                       smfc_find_format(ctx->smfc, f->fmt.pix.pixelformat);
+       int ret = smfc_v4l2_check_s_fmt(ctx, smfc_fmt, f->type);
+
+       if (ret)
+               return ret;
+
+       if (!smfc_v4l2_init_fmt(ctx, smfc_fmt, f->type, &f->fmt.pix))
+               return -EINVAL;
+
+       ctx->width = SMFC_FMT_MAIN_SIZE(f->fmt.pix.width);
+       ctx->height = SMFC_FMT_MAIN_SIZE(f->fmt.pix.height);
+       /* back-to-back compression is not supported with single plane */
+       ctx->thumb_width = 0;
+       ctx->thumb_height = 0;
+
+       if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
+               ctx->img_fmt = smfc_fmt;
+
+       return 0;
+}
+
+const struct v4l2_ioctl_ops smfc_v4l2_ioctl_ops = {
+       .vidioc_querycap                = smfc_v4l2_querycap,
+       .vidioc_enum_fmt_vid_cap        = smfc_v4l2_enum_fmt,
+       .vidioc_enum_fmt_vid_out        = smfc_v4l2_enum_fmt,
+       .vidioc_enum_fmt_vid_cap_mplane = smfc_v4l2_enum_fmt_mplane,
+       .vidioc_enum_fmt_vid_out_mplane = smfc_v4l2_enum_fmt_mplane,
+       .vidioc_g_fmt_vid_cap           = smfc_v4l2_g_fmt,
+       .vidioc_g_fmt_vid_out           = smfc_v4l2_g_fmt,
+       .vidioc_g_fmt_vid_cap_mplane    = smfc_v4l2_g_fmt_mplane,
+       .vidioc_g_fmt_vid_out_mplane    = smfc_v4l2_g_fmt_mplane,
+       .vidioc_try_fmt_vid_cap         = smfc_v4l2_try_fmt,
+       .vidioc_try_fmt_vid_out         = smfc_v4l2_try_fmt,
+       .vidioc_try_fmt_vid_cap_mplane  = smfc_v4l2_try_fmt_mplane,
+       .vidioc_try_fmt_vid_out_mplane  = smfc_v4l2_try_fmt_mplane,
+       .vidioc_s_fmt_vid_cap           = smfc_v4l2_s_fmt,
+       .vidioc_s_fmt_vid_out           = smfc_v4l2_s_fmt,
+       .vidioc_s_fmt_vid_cap_mplane    = smfc_v4l2_s_fmt_mplane,
+       .vidioc_s_fmt_vid_out_mplane    = smfc_v4l2_s_fmt_mplane,
+
+       .vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
+       .vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
+       .vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
+       .vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
+
+       .vidioc_streamon                = v4l2_m2m_ioctl_streamon,
+       .vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
+
+       .vidioc_log_status              = v4l2_ctrl_log_status,
+};
index 9c2c9992cbad5c02fbac12f6a18867dc8ca7e37b..e279aa5ac7320bc5c0900516757209925c141189 100644 (file)
 
 #include "smfc.h"
 
-/* SMFC SPECIFIC DEVICE CAPABILITIES */
-/* set if H/W supports for decompression */
-#define V4L2_CAP_EXYNOS_JPEG_DECOMPRESSION             0x0100
-/* set if H/W can compress dual images */
-#define V4L2_CAP_EXYNOS_JPEG_B2B_COMPRESSION           0x0200
-/* set if H/W supports for Hardware Flow Control */
-#define V4L2_CAP_EXYNOS_JPEG_HWFC                      0x0400
-/* set if H/W supports for HWFC on internal buffers */
-#define V4L2_CAP_EXYNOS_JPEG_HWFC_EMBEDDED             0x0800
-/* set if H/W has a register to configure stream buffer size */
-#define V4L2_CAP_EXYNOS_JPEG_MAX_STREAMSIZE            0x1000
-/* set if H/W does not have 128-bit alignment constraint for stream base */
-#define V4L2_CAP_EXYNOS_JPEG_NO_STREAMBASE_ALIGN       0x2000
-/* set if H/W does not have 128-bit alignment constraint for image base */
-#define V4L2_CAP_EXYNOS_JPEG_NO_IMAGEBASE_ALIGN                0x4000
-
-/* SMFC SPECIFIC CONTROLS */
-#define V4L2_CID_JPEG_SEC_COMP_QUALITY (V4L2_CID_JPEG_CLASS_BASE + 20)
-#define V4L2_CID_JPEG_HWFC_ENABLE      (V4L2_CID_JPEG_CLASS_BASE + 25)
-
-#define SMFC_DEFAULT_OUTPUT_FORMAT     (&smfc_image_formats[1])
-#define SMFC_DEFAULT_CAPTURE_FORMAT    (&smfc_image_formats[0])
-
-#define SMFC_FMT_MAIN_SIZE(val) ((val) & 0xFFFF)
-#define SMFC_FMT_SEC_SIZE(val) (((val) >> 16) & 0xFFFF)
-
-const struct smfc_image_format smfc_image_formats[] = {
-       {
-               /* JPEG should be the first format */
-               .description    = "Baseline JPEG(Sequential DCT)",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_JPEG,
-               .regcfg         = 0, /* Chagneable accroding to chroma factor */
-               .bpp_buf        = {0}, /* undeterministic */
-               .bpp_pix        = {0}, /* undeterministic */
-               .num_planes     = 1,
-               .num_buffers    = 1,
-               .chroma_hfactor = 1, /* dummy chroma subsampling factor */
-               .chroma_vfactor = 1, /* These will not affect to H/W config. */
-       }, {
-               /* YUYV is the default format */
-               .description    = "YUV4:2:2 1-Plane 16BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_YUYV,
-               .regcfg         = SMFC_IMGFMT_YUYV,
-               .bpp_buf        = {16},
-               .bpp_pix        = {16},
-               .num_planes     = 1,
-               .num_buffers    = 1,
-               .chroma_hfactor = 2,
-               .chroma_vfactor = 1,
-       }, {
-               .description    = "YUV4:2:2 1-Plane 16BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_YVYU,
-               .regcfg         = SMFC_IMGFMT_YVYU,
-               .bpp_buf        = {16},
-               .bpp_pix        = {16},
-               .num_planes     = 1,
-               .num_buffers    = 1,
-               .chroma_hfactor = 2,
-               .chroma_vfactor = 1,
-       }, {
-               .description    = "YUV4:2:2 2-Plane 16BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_NV16,
-               .regcfg         = SMFC_IMGFMT_NV16,
-               .bpp_buf        = {16},
-               .bpp_pix        = {8, 8, 0},
-               .num_planes     = 2,
-               .num_buffers    = 1,
-               .chroma_hfactor = 2,
-               .chroma_vfactor = 1,
-       }, {
-               .description    = "YUV4:2:2 2-Plane 16BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_NV61,
-               .regcfg         = SMFC_IMGFMT_NV61,
-               .bpp_buf        = {16},
-               .bpp_pix        = {8, 8, 0},
-               .num_planes     = 2,
-               .num_buffers    = 1,
-               .chroma_hfactor = 2,
-               .chroma_vfactor = 1,
-       }, {
-               .description    = "YUV4:2:2 3-Plane 16BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_YUV422P,
-               .regcfg         = SMFC_IMGFMT_YUV422,
-               .bpp_buf        = {16},
-               .bpp_pix        = {8, 2, 2},
-               .num_planes     = 3,
-               .num_buffers    = 1,
-               .chroma_hfactor = 2,
-               .chroma_vfactor = 1,
-       }, {
-               .description    = "YUV4:2:0 2-Plane(Cb/Cr) 12BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_NV12,
-               .regcfg         = SMFC_IMGFMT_NV12,
-               .bpp_buf        = {12},
-               .bpp_pix        = {8, 4, 0},
-               .num_planes     = 2,
-               .num_buffers    = 1,
-               .chroma_hfactor = 2,
-               .chroma_vfactor = 2,
-       }, {
-               .description    = "YUV4:2:0 2-Plane(Cr/Cb) 12BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_NV21,
-               .regcfg         = SMFC_IMGFMT_NV21,
-               .bpp_buf        = {12},
-               .bpp_pix        = {8, 4, 0},
-               .num_planes     = 2,
-               .num_buffers    = 1,
-               .chroma_hfactor = 2,
-               .chroma_vfactor = 2,
-       }, {
-               .description    = "YUV4:2:0 3-Plane 12BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_YUV420,
-               .regcfg         = SMFC_IMGFMT_YUV420P,
-               .bpp_buf        = {12},
-               .bpp_pix        = {8, 2, 2},
-               .num_planes     = 3,
-               .num_buffers    = 1,
-               .chroma_hfactor = 2,
-               .chroma_vfactor = 2,
-       }, {
-               .description    = "YVU4:2:0 3-Plane 12BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_YVU420,
-               .regcfg         = SMFC_IMGFMT_YVU420P,
-               .bpp_buf        = {12},
-               .bpp_pix        = {8, 2, 2},
-               .num_planes     = 3,
-               .num_buffers    = 1,
-               .chroma_hfactor = 2,
-               .chroma_vfactor = 2,
-       }, {
-               .description    = "YUV4:4:4 3-Plane 16BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_YUV444,
-               .regcfg         = SMFC_IMGFMT_YUV444,
-               .bpp_buf        = {24},
-               .bpp_pix        = {8, 8, 8},
-               .num_planes     = 3,
-               .num_buffers    = 1,
-               .chroma_hfactor = 1,
-               .chroma_vfactor = 1,
-       }, {
-               .description    = "RGB565 LE 16BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_RGB565,
-               .regcfg         = SMFC_IMGFMT_RGB565,
-               .bpp_buf        = {16},
-               .bpp_pix        = {16},
-               .num_planes     = 1,
-               .num_buffers    = 1,
-               .chroma_hfactor = 1,
-               .chroma_vfactor = 1,
-       }, {
-               .description    = "RGB565 BE 16BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_RGB565X,
-               .regcfg         = SMFC_IMGFMT_BGR565,
-               .bpp_buf        = {16},
-               .bpp_pix        = {16},
-               .num_planes     = 1,
-               .num_buffers    = 1,
-               .chroma_hfactor = 1,
-               .chroma_vfactor = 1,
-       }, {
-               .description    = "RGB888 LE 24BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_RGB24,
-               .regcfg         = SMFC_IMGFMT_RGB24,
-               .bpp_buf        = {24},
-               .bpp_pix        = {24},
-               .num_planes     = 1,
-               .num_buffers    = 1,
-               .chroma_hfactor = 1,
-               .chroma_vfactor = 1,
-       }, {
-               .description    = "RGB888 BE 24BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_BGR24,
-               .regcfg         = SMFC_IMGFMT_BGR24,
-               .bpp_buf        = {24},
-               .bpp_pix        = {24},
-               .num_planes     = 1,
-               .num_buffers    = 1,
-               .chroma_hfactor = 1,
-               .chroma_vfactor = 1,
-       }, {
-               .description    = "ABGR8888 LE 32BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_RGB32,
-               .regcfg         = SMFC_IMGFMT_RGBA32,
-               .bpp_buf        = {32},
-               .bpp_pix        = {32},
-               .num_planes     = 1,
-               .num_buffers    = 1,
-               .chroma_hfactor = 1,
-               .chroma_vfactor = 1,
-       }, {
-               .description    = "ARGB8888 BE 32BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_BGR32,
-               .regcfg         = SMFC_IMGFMT_BGRA32,
-               .bpp_buf        = {32},
-               .bpp_pix        = {32},
-               .num_planes     = 1,
-               .num_buffers    = 1,
-               .chroma_hfactor = 1,
-               .chroma_vfactor = 1,
-       },
-       /* multi-planar formats must be at the last becuse of VIDOC_ENUM_FMT */
-       {
-               .description    = "YUV4:2:0 2-MPlane(Cb/Cr) 8+4BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_NV12M,
-               .regcfg         = SMFC_IMGFMT_NV12,
-               .bpp_buf        = {8, 4},
-               .bpp_pix        = {8, 4},
-               .num_planes     = 2,
-               .num_buffers    = 2,
-               .chroma_hfactor = 2,
-               .chroma_vfactor = 2,
-       }, {
-               .description    = "YUV4:2:0 2-MPlane(Cr/Cb) 8+4BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_NV21M,
-               .regcfg         = SMFC_IMGFMT_NV21,
-               .bpp_buf        = {8, 4},
-               .bpp_pix        = {8, 4},
-               .num_planes     = 2,
-               .num_buffers    = 2,
-               .chroma_hfactor = 2,
-               .chroma_vfactor = 2,
-       }, {
-               .description    = "YUV4:2:0 3-MPlane 8+2+2BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_YUV420M,
-               .regcfg         = SMFC_IMGFMT_YUV420P,
-               .bpp_buf        = {8, 2, 2},
-               .bpp_pix        = {8, 2, 2},
-               .num_planes     = 3,
-               .num_buffers    = 3,
-               .chroma_hfactor = 2,
-               .chroma_vfactor = 2,
-       }, {
-               .description    = "YVU4:2:0 3-MPlane 8+2+2BPP",
-               .v4l2_pixfmt    = V4L2_PIX_FMT_YVU420M,
-               .regcfg         = SMFC_IMGFMT_YVU420P,
-               .bpp_buf        = {8, 2, 2},
-               .bpp_pix        = {8, 2, 2},
-               .num_planes     = 3,
-               .num_buffers    = 3,
-               .chroma_hfactor = 2,
-               .chroma_vfactor = 2,
-       }
-};
-
-static const struct smfc_image_format *smfc_find_format(
-                               struct smfc_dev *smfc, __u32 v4l2_pixfmt)
-{
-       size_t i;
-       for (i = 0; i < ARRAY_SIZE(smfc_image_formats); i++)
-               if (smfc_image_formats[i].v4l2_pixfmt == v4l2_pixfmt)
-                       return &smfc_image_formats[i];
-
-       dev_warn(smfc->dev, "Pixel format '%08X' not found, YUYV is forced.\n",
-               v4l2_pixfmt);
-
-       return V4L2_TYPE_IS_OUTPUT(v4l2_pixfmt) ? SMFC_DEFAULT_OUTPUT_FORMAT
-                                               : SMFC_DEFAULT_CAPTURE_FORMAT;
-}
-
-static const char *buf_type_name(__u32 type)
-{
-       return V4L2_TYPE_IS_OUTPUT(type) ? "capture" : "output";
-}
-
 static irqreturn_t exynos_smfc_irq_handler(int irq, void *priv)
 {
        struct smfc_dev *smfc = priv;
@@ -588,128 +324,6 @@ static int smfc_queue_init(void *priv, struct vb2_queue *src_vq,
        return vb2_queue_init(dst_vq);
 }
 
-static int smfc_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-       struct smfc_ctx *ctx = container_of(ctrl->handler,
-                                           struct smfc_ctx, v4l2_ctrlhdlr);
-       switch (ctrl->id) {
-       case V4L2_CID_JPEG_COMPRESSION_QUALITY:
-               ctx->quality_factor = (unsigned char)ctrl->val;
-               break;
-       case V4L2_CID_JPEG_SEC_COMP_QUALITY:
-               ctx->thumb_quality_factor = (unsigned char)ctrl->val;
-               break;
-       case V4L2_CID_JPEG_HWFC_ENABLE:
-               ctx->enable_hwfc = (unsigned char)ctrl->val;
-               break;
-       case V4L2_CID_JPEG_RESTART_INTERVAL:
-               ctx->restart_interval = (unsigned char)ctrl->val;
-               break;
-       case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
-               switch (ctrl->val) {
-               case V4L2_JPEG_CHROMA_SUBSAMPLING_444:
-                       ctx->chroma_hfactor = 1;
-                       ctx->chroma_vfactor = 1;
-                       break;
-               case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
-                       ctx->chroma_hfactor = 2;
-                       ctx->chroma_vfactor = 2;
-                       break;
-               case V4L2_JPEG_CHROMA_SUBSAMPLING_411:
-                       ctx->chroma_hfactor = 4;
-                       ctx->chroma_vfactor = 1;
-                       break;
-               case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
-                       ctx->chroma_hfactor = 0;
-                       ctx->chroma_vfactor = 0;
-                       break;
-               case V4L2_JPEG_CHROMA_SUBSAMPLING_410:
-                       dev_info(ctx->smfc->dev,
-                               "Compression to YUV410 is not supported\n");
-                       /* pass through to 422 */
-               case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
-               default:
-                       ctx->chroma_hfactor = 2;
-                       ctx->chroma_vfactor = 1;
-                       break;
-               }
-               break;
-       default:
-               break;
-       }
-
-       return 0;
-}
-
-static const struct v4l2_ctrl_ops smfc_ctrl_ops = {
-       .s_ctrl = smfc_s_ctrl,
-};
-
-static int smfc_init_controls(struct smfc_dev *smfc,
-                             struct v4l2_ctrl_handler *hdlr)
-{
-       const char *msg;
-       struct v4l2_ctrl_config ctrlcfg;
-
-       v4l2_ctrl_handler_init(hdlr, 1);
-
-       if (!v4l2_ctrl_new_std(hdlr, &smfc_ctrl_ops,
-                               V4L2_CID_JPEG_COMPRESSION_QUALITY,
-                               1, 100, 1, 96)) {
-               msg = "quality factor";
-               goto err;
-       }
-
-       memset(&ctrlcfg, 0, sizeof(ctrlcfg));
-       ctrlcfg.ops = &smfc_ctrl_ops;
-       ctrlcfg.id = V4L2_CID_JPEG_SEC_COMP_QUALITY;
-       ctrlcfg.name = "Quality factor of secondray image";
-       ctrlcfg.type = V4L2_CTRL_TYPE_INTEGER;
-       ctrlcfg.min = 1;
-       ctrlcfg.max = 100;
-       ctrlcfg.step = 1;
-       ctrlcfg.def = 50;
-       if (!v4l2_ctrl_new_custom(hdlr, &ctrlcfg, NULL)) {
-               msg = "secondary quality factor";
-               goto err;
-       }
-
-       memset(&ctrlcfg, 0, sizeof(ctrlcfg));
-       ctrlcfg.ops = &smfc_ctrl_ops;
-       ctrlcfg.id = V4L2_CID_JPEG_HWFC_ENABLE;
-       ctrlcfg.name = "HWFC configuration";
-       ctrlcfg.type = V4L2_CTRL_TYPE_BOOLEAN;
-       ctrlcfg.min = 0;
-       ctrlcfg.max = 1;
-       ctrlcfg.step = 1;
-       ctrlcfg.def = 0;
-       if (!v4l2_ctrl_new_custom(hdlr, &ctrlcfg, NULL)) {
-               msg = "secondary quality factor";
-               goto err;
-       }
-
-       if (!v4l2_ctrl_new_std(hdlr, &smfc_ctrl_ops,
-                               V4L2_CID_JPEG_RESTART_INTERVAL,
-                               0, 64, 1, 0)) {
-               msg = "restart interval";
-               goto err;
-       }
-
-       if (!v4l2_ctrl_new_std_menu(hdlr, &smfc_ctrl_ops,
-                               V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
-                               V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, 0,
-                               V4L2_JPEG_CHROMA_SUBSAMPLING_422)) {
-               msg = "chroma subsampling";
-               goto err;
-       }
-
-       return 0;
-err:
-       dev_err(smfc->dev, "Failed to install %s control (%d)\n",
-               msg, hdlr->error);
-       return hdlr->error;
-}
-
 static int exynos_smfc_open(struct file *filp)
 {
        struct smfc_dev *smfc = video_drvdata(filp);
@@ -813,400 +427,6 @@ static const struct v4l2_file_operations smfc_v4l2_fops = {
        .mmap           = v4l2_m2m_fop_mmap,
 };
 
-static int smfc_v4l2_querycap(struct file *filp, void *fh,
-                            struct v4l2_capability *cap)
-{
-       struct smfc_dev *smfc = v4l2_fh_to_smfc_ctx(fh)->smfc;
-
-       strncpy(cap->driver, MODULE_NAME, sizeof(cap->driver));
-       strncpy(cap->bus_info, dev_name(smfc->dev), sizeof(cap->bus_info));
-       scnprintf(cap->card, sizeof(cap->card), "Still MFC %02x.%02x.%04x",
-                       (smfc->hwver >> 24) & 0xFF, (smfc->hwver >> 16) & 0xFF,
-                       smfc->hwver & 0xFFFF);
-
-       cap->driver[sizeof(cap->driver) - 1] = '\0';
-       cap->card[sizeof(cap->card) - 1] = '\0';
-       cap->bus_info[sizeof(cap->bus_info) - 1] = '\0';
-
-       cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE
-                               | V4L2_CAP_VIDEO_M2M;
-       cap->capabilities |= V4L2_CAP_DEVICE_CAPS;
-
-       cap->device_caps = V4L2_CAP_EXYNOS_JPEG_B2B_COMPRESSION;
-       cap->device_caps |= V4L2_CAP_EXYNOS_JPEG_HWFC;
-       cap->device_caps |= V4L2_CAP_EXYNOS_JPEG_MAX_STREAMSIZE;
-       cap->device_caps |= V4L2_CAP_EXYNOS_JPEG_NO_STREAMBASE_ALIGN;
-       cap->device_caps |= V4L2_CAP_EXYNOS_JPEG_NO_IMAGEBASE_ALIGN;
-
-       return 0;
-}
-
-static int smfc_v4l2_enum_fmt_mplane(struct file *filp, void *fh,
-                                    struct v4l2_fmtdesc *f)
-{
-       const struct smfc_image_format *fmt;
-
-       if (f->index >= ARRAY_SIZE(smfc_image_formats))
-               return -EINVAL;
-
-       fmt = &smfc_image_formats[f->index];
-       strncpy(f->description, fmt->description, sizeof(f->description));
-       f->description[sizeof(f->description) - 1] = '\0';
-       f->pixelformat = fmt->v4l2_pixfmt;
-       if (fmt->bpp_buf[0] == 0)
-               f->flags = V4L2_FMT_FLAG_COMPRESSED;
-
-       return 0;
-}
-
-static int smfc_v4l2_enum_fmt(struct file *filp, void *fh,
-                             struct v4l2_fmtdesc *f)
-{
-       int ret = smfc_v4l2_enum_fmt_mplane(filp, fh, f);
-       if (ret < 0)
-               return ret;
-
-       return smfc_image_formats[f->index].num_buffers > 1 ? -EINVAL : 0;
-}
-
-static int smfc_v4l2_g_fmt_mplane(struct file *filp, void *fh,
-                                 struct v4l2_format *f)
-{
-       struct smfc_ctx *ctx = v4l2_fh_to_smfc_ctx(fh);
-       f->fmt.pix_mp.width = ctx->width;
-       f->fmt.pix_mp.height = ctx->height;
-
-       if (!smfc_is_compressed_type(ctx, f->type)) {
-               int i;
-               /* uncompressed image */
-               f->fmt.pix_mp.pixelformat = ctx->img_fmt->v4l2_pixfmt;
-               f->fmt.pix_mp.num_planes = ctx->img_fmt->num_buffers;
-               for (i = 0; i < ctx->img_fmt->num_buffers; i++) {
-                       f->fmt.pix_mp.plane_fmt[i].bytesperline =
-                               (f->fmt.pix_mp.width *
-                                        ctx->img_fmt->bpp_buf[i]) / 8;
-                       f->fmt.pix_mp.plane_fmt[i].sizeimage =
-                                       f->fmt.pix_mp.plane_fmt[i].bytesperline;
-                       f->fmt.pix_mp.plane_fmt[i].sizeimage *=
-                                                       f->fmt.pix_mp.height;
-               }
-       } else {
-               f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_JPEG;
-               f->fmt.pix_mp.num_planes = 1;
-               f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
-               f->fmt.pix_mp.plane_fmt[0].sizeimage = 0;
-       }
-
-       f->fmt.pix_mp.field = 0;
-       f->fmt.pix_mp.colorspace = 0;
-
-       return 0;
-}
-
-static int smfc_v4l2_g_fmt(struct file *filp, void *fh, struct v4l2_format *f)
-{
-       struct smfc_ctx *ctx = v4l2_fh_to_smfc_ctx(fh);
-
-       f->fmt.pix.width = ctx->width;
-       f->fmt.pix.height = ctx->height;
-
-       if (!smfc_is_compressed_type(ctx, f->type)) {
-               if (ctx->img_fmt->num_buffers > 1) {
-                       dev_err(ctx->smfc->dev,
-                               "Current format is a multi-planar format\n");
-                       return -EINVAL;
-               }
-
-               /* uncompressed image */
-               f->fmt.pix.pixelformat = ctx->img_fmt->v4l2_pixfmt;
-               f->fmt.pix.bytesperline =
-                       (f->fmt.pix.width * ctx->img_fmt->bpp_buf[0]) / 8;
-               f->fmt.pix.sizeimage = f->fmt.pix.bytesperline;
-               f->fmt.pix.sizeimage *= f->fmt.pix.height;
-       } else {
-               f->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG;
-               f->fmt.pix.bytesperline = 0;
-               f->fmt.pix.sizeimage = 0;
-       }
-
-       f->fmt.pix.field = 0;
-       f->fmt.pix.colorspace = 0;
-
-       return 0;
-}
-
-static bool __smfc_check_image_size(struct device *dev, __u32 type,
-                                 const struct smfc_image_format *smfc_fmt,
-                                 __u32 width, __u32 height)
-{
-       __u32 min_width = SMFC_MIN_WIDTH << smfc_fmt->chroma_hfactor;
-       __u32 min_height = SMFC_MIN_WIDTH << smfc_fmt->chroma_vfactor;
-
-       if ((width < min_width) || (height < min_height)) {
-               dev_warn(dev, "Too small image size(%ux%u) for '%s'\n",
-                               width, height, buf_type_name(type));
-               return false;
-       }
-
-       if ((width > SMFC_MAX_WIDTH) || (height > SMFC_MAX_HEIGHT)) {
-               dev_warn(dev, "Too large image size(%ux%u) for '%s'\n",
-                               width, height, buf_type_name(type));
-               return false;
-       }
-
-       if (((width % smfc_fmt->chroma_hfactor) != 0) ||
-               ((height % smfc_fmt->chroma_vfactor) != 0)) {
-               dev_err(dev, "Invalid size %ux%u for format '%s'\n",
-                       width, height, smfc_fmt->description);
-               return false;
-       }
-
-       return true;
-}
-static bool smfc_check_image_size(struct device *dev, __u32 type,
-                                 const struct smfc_image_format *smfc_fmt,
-                                 __u32 width, __u32 height)
-{
-       __u32 twidth = SMFC_FMT_SEC_SIZE(width);
-       __u32 theight = SMFC_FMT_SEC_SIZE(height);
-       width = SMFC_FMT_MAIN_SIZE(width);
-       height = SMFC_FMT_MAIN_SIZE(height);
-
-       if (!__smfc_check_image_size(dev, type, smfc_fmt, width, height))
-               return false;
-
-       if (!twidth || !theight) /* thumbnail image size is not specified */
-               return true;
-
-       if (!__smfc_check_image_size(dev, type, smfc_fmt, twidth, theight))
-               return false;
-
-       return true;
-}
-
-static bool smfc_v4l2_init_fmt_mplane(const struct smfc_ctx *ctx,
-                       const struct smfc_image_format *smfc_fmt,
-                       __u32 type, struct v4l2_pix_format_mplane *pix_mp)
-{
-       unsigned int i;
-
-       if (!smfc_check_image_size(ctx->smfc->dev, type,
-                               smfc_fmt, pix_mp->width, pix_mp->height))
-               return false;
-       /* informs the user that the format might be changed to the default */
-       pix_mp->pixelformat = smfc_fmt->v4l2_pixfmt;
-       /* JPEG format has zero in smfc_fmt->bpp_buf[0] */
-       for (i = 0; i < smfc_fmt->num_buffers; i++) {
-               pix_mp->plane_fmt[i].bytesperline =
-                               (SMFC_FMT_MAIN_SIZE(pix_mp->width) *
-                                smfc_fmt->bpp_buf[i]) / 8;
-               pix_mp->plane_fmt[i].sizeimage =
-                               pix_mp->plane_fmt[i].bytesperline *
-                                       SMFC_FMT_MAIN_SIZE(pix_mp->height);
-       }
-
-       pix_mp->field = 0;
-       pix_mp->num_planes = smfc_fmt->num_buffers;
-
-       if (SMFC_FMT_SEC_SIZE(pix_mp->width) &&
-                               SMFC_FMT_SEC_SIZE(pix_mp->height)) {
-               /*
-                * Format information for the secondary image is stored after
-                * the last plane of the main image. It is okay to use more
-                * planes because the maximum valid planes are eight
-                */
-               unsigned int j;
-               for (j = 0; j < smfc_fmt->num_buffers; j++) {
-                       pix_mp->plane_fmt[i + j].bytesperline =
-                               (SMFC_FMT_SEC_SIZE(pix_mp->width) *
-                                       smfc_fmt->bpp_buf[j]) / 8;
-                       pix_mp->plane_fmt[i + j].sizeimage =
-                               pix_mp->plane_fmt[i + j].bytesperline *
-                                       SMFC_FMT_SEC_SIZE(pix_mp->height);
-               }
-       }
-
-       return true;
-}
-
-static int smfc_v4l2_try_fmt_mplane(struct file *filp, void *fh,
-                                 struct v4l2_format *f)
-{
-       struct smfc_ctx *ctx = v4l2_fh_to_smfc_ctx(fh);
-       const struct smfc_image_format *smfc_fmt =
-                       smfc_find_format(ctx->smfc, f->fmt.pix_mp.pixelformat);
-
-       return smfc_v4l2_init_fmt_mplane(
-                       ctx, smfc_fmt, f->type, &f->fmt.pix_mp) ? 0 : -EINVAL;
-}
-
-static int smfc_v4l2_check_s_fmt(struct smfc_ctx *ctx,
-                                const struct smfc_image_format *smfc_fmt,
-                                __u32 type)
-{
-       struct vb2_queue *thisvq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, type);
-       struct vb2_queue *othervq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
-                       V4L2_TYPE_IS_OUTPUT(type) ?
-                               V4L2_BUF_TYPE_VIDEO_CAPTURE :
-                               V4L2_BUF_TYPE_VIDEO_OUTPUT);
-       u32 flags;
-
-       if (thisvq->num_buffers > 0) {
-               dev_err(ctx->smfc->dev,
-                       "S_FMT after REQBUFS is not allowed\n");
-               return -EBUSY;
-       }
-
-       flags = smfc_config_ctxflag(ctx, SMFC_CTX_COMPRESS,
-                       is_jpeg(smfc_fmt) != V4L2_TYPE_IS_OUTPUT(type));
-
-       if (othervq->num_buffers > 0) { /* REQBUFSed on other vq */
-               if ((flags & SMFC_CTX_COMPRESS) !=
-                                       (ctx->flags & SMFC_CTX_COMPRESS)) {
-                       dev_err(ctx->smfc->dev,
-                               "Changing mode is prohibited after reqbufs\n");
-                       ctx->flags = flags;
-                       return -EBUSY;
-               }
-       }
-
-       /* reset the buf type of vq with the given buf type */
-       thisvq->type = type;
-
-       return 0;
-}
-
-static __u32 v4l2_to_multiplane_type(__u32 type)
-{
-       /* V4L2_BUF_TYPE_VIDEO_CAPTURE+8 = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */
-       return V4L2_TYPE_IS_MULTIPLANAR(type) ? type : type + 8;
-}
-
-static int smfc_v4l2_s_fmt_mplane(struct file *filp, void *fh,
-                                   struct v4l2_format *f)
-{
-       struct smfc_ctx *ctx = v4l2_fh_to_smfc_ctx(fh);
-       const struct smfc_image_format *smfc_fmt =
-                       smfc_find_format(ctx->smfc, f->fmt.pix_mp.pixelformat);
-       int ret = smfc_v4l2_check_s_fmt(ctx, smfc_fmt, f->type);
-       if (ret)
-               return ret;
-
-       if (!smfc_v4l2_init_fmt_mplane(ctx, smfc_fmt, f->type, &f->fmt.pix_mp))
-               return -EINVAL;
-
-       ctx->width = SMFC_FMT_MAIN_SIZE(f->fmt.pix_mp.width);
-       ctx->height = SMFC_FMT_MAIN_SIZE(f->fmt.pix_mp.height);
-       ctx->thumb_width = SMFC_FMT_SEC_SIZE(f->fmt.pix_mp.width);
-       ctx->thumb_height = SMFC_FMT_SEC_SIZE(f->fmt.pix_mp.height);
-
-       if (ctx->thumb_width && ctx->thumb_height)
-               ctx->flags |= SMFC_CTX_B2B_COMPRESS;
-       else
-               ctx->flags &= ~SMFC_CTX_B2B_COMPRESS;
-
-       if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_JPEG)
-               ctx->img_fmt = smfc_fmt;
-
-       if (ctx->flags & SMFC_CTX_B2B_COMPRESS) {
-               struct vb2_queue *othervq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
-                       V4L2_TYPE_IS_OUTPUT(f->type) ?
-                               V4L2_BUF_TYPE_VIDEO_CAPTURE :
-                               V4L2_BUF_TYPE_VIDEO_OUTPUT);
-               /*
-                * type change of the current queue is completed in
-                * smfc_v4l2_check_s_fmt()
-                */
-               othervq->type = v4l2_to_multiplane_type(othervq->type);
-       }
-
-       return 0;
-}
-
-static bool smfc_v4l2_init_fmt(const struct smfc_ctx *ctx,
-                               const struct smfc_image_format *smfc_fmt,
-                               __u32 type, struct v4l2_pix_format *pix)
-{
-       BUG_ON(V4L2_TYPE_IS_MULTIPLANAR(pix->pixelformat));
-
-       if (!smfc_check_image_size(ctx->smfc->dev, type,
-                               smfc_fmt, pix->width, pix->height))
-               return false;
-       /* informs the user that the format might be changed to the default */
-       pix->pixelformat = smfc_fmt->v4l2_pixfmt;
-       /* JPEG format has zero in smfc_fmt->bpp_buf[0] */
-       pix->bytesperline = (pix->width *  smfc_fmt->bpp_buf[0]) / 8;
-       pix->sizeimage = pix->bytesperline * pix->height;
-       pix->field = 0;
-
-       return true;
-}
-
-static int smfc_v4l2_try_fmt(struct file *filp, void *fh, struct v4l2_format *f)
-{
-       struct smfc_ctx *ctx = v4l2_fh_to_smfc_ctx(fh);
-       const struct smfc_image_format *smfc_fmt =
-                       smfc_find_format(ctx->smfc, f->fmt.pix.pixelformat);
-
-       return smfc_v4l2_init_fmt(ctx, smfc_fmt, f->type, &f->fmt.pix)
-                                                               ? 0 : -EINVAL;
-}
-
-static int smfc_v4l2_s_fmt(struct file *filp, void *fh, struct v4l2_format *f)
-{
-       struct smfc_ctx *ctx = v4l2_fh_to_smfc_ctx(fh);
-       const struct smfc_image_format *smfc_fmt =
-                       smfc_find_format(ctx->smfc, f->fmt.pix.pixelformat);
-       int ret = smfc_v4l2_check_s_fmt(ctx, smfc_fmt, f->type);
-       if (ret)
-               return ret;
-
-       if (!smfc_v4l2_init_fmt(ctx, smfc_fmt, f->type, &f->fmt.pix))
-               return -EINVAL;
-
-       ctx->width = SMFC_FMT_MAIN_SIZE(f->fmt.pix.width);
-       ctx->height = SMFC_FMT_MAIN_SIZE(f->fmt.pix.height);
-       /* back-to-back compression is not supported with single plane */
-       ctx->thumb_width = 0;
-       ctx->thumb_height = 0;
-
-       if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
-               ctx->img_fmt = smfc_fmt;
-
-       return 0;
-}
-
-
-static const struct v4l2_ioctl_ops smfc_v4l2_ioctl_ops = {
-       .vidioc_querycap                = smfc_v4l2_querycap,
-       .vidioc_enum_fmt_vid_cap        = smfc_v4l2_enum_fmt,
-       .vidioc_enum_fmt_vid_out        = smfc_v4l2_enum_fmt,
-       .vidioc_enum_fmt_vid_cap_mplane = smfc_v4l2_enum_fmt_mplane,
-       .vidioc_enum_fmt_vid_out_mplane = smfc_v4l2_enum_fmt_mplane,
-       .vidioc_g_fmt_vid_cap           = smfc_v4l2_g_fmt,
-       .vidioc_g_fmt_vid_out           = smfc_v4l2_g_fmt,
-       .vidioc_g_fmt_vid_cap_mplane    = smfc_v4l2_g_fmt_mplane,
-       .vidioc_g_fmt_vid_out_mplane    = smfc_v4l2_g_fmt_mplane,
-       .vidioc_try_fmt_vid_cap         = smfc_v4l2_try_fmt,
-       .vidioc_try_fmt_vid_out         = smfc_v4l2_try_fmt,
-       .vidioc_try_fmt_vid_cap_mplane  = smfc_v4l2_try_fmt_mplane,
-       .vidioc_try_fmt_vid_out_mplane  = smfc_v4l2_try_fmt_mplane,
-       .vidioc_s_fmt_vid_cap           = smfc_v4l2_s_fmt,
-       .vidioc_s_fmt_vid_out           = smfc_v4l2_s_fmt,
-       .vidioc_s_fmt_vid_cap_mplane    = smfc_v4l2_s_fmt_mplane,
-       .vidioc_s_fmt_vid_out_mplane    = smfc_v4l2_s_fmt_mplane,
-
-       .vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
-       .vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
-       .vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
-       .vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
-
-       .vidioc_streamon                = v4l2_m2m_ioctl_streamon,
-       .vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
-
-       .vidioc_log_status              = v4l2_ctrl_log_status,
-};
-
 static bool smfc_check_hwfc_configuration(struct smfc_ctx *ctx, bool hwfc_en)
 {
        const struct smfc_image_format *fmt = ctx->img_fmt;
index d6778d73151ea44e310d793d14217d53383f44f7..e59a8948beb25cd19070e7f6bb2cab727685cb37 100644 (file)
@@ -38,6 +38,11 @@ struct smfc_image_format {
        unsigned char   chroma_vfactor;
 };
 
+extern const struct smfc_image_format smfc_image_formats[];
+
+#define SMFC_DEFAULT_OUTPUT_FORMAT     (&smfc_image_formats[1])
+#define SMFC_DEFAULT_CAPTURE_FORMAT    (&smfc_image_formats[0])
+
 static inline bool is_jpeg(const struct smfc_image_format *fmt)
 {
        return fmt->bpp_buf[0] == 0;
@@ -98,6 +103,8 @@ struct smfc_ctx {
        unsigned char enable_hwfc;
 };
 
+extern const struct v4l2_ioctl_ops smfc_v4l2_ioctl_ops;
+
 static inline struct smfc_ctx *v4l2_fh_to_smfc_ctx(struct v4l2_fh *fh)
 {
        return container_of(fh, struct smfc_ctx, fh);
@@ -116,6 +123,8 @@ static inline bool smfc_is_compressed_type(struct smfc_ctx *ctx, __u32 type)
        return !(ctx->flags & SMFC_CTX_COMPRESS) == V4L2_TYPE_IS_OUTPUT(type);
 }
 
+int smfc_init_controls(struct smfc_dev *smfc, struct v4l2_ctrl_handler *hdlr);
+
 /* H/W Configuration */
 void smfc_hwconfigure_tables(struct smfc_ctx *ctx, unsigned int qfactor);
 void smfc_hwconfigure_image(struct smfc_ctx *ctx,