[COMMON] media: smfc: add V4L2 control values
authorCho KyongHo <pullip.cho@samsung.com>
Thu, 2 Apr 2015 01:39:17 +0000 (10:39 +0900)
committerCosmin Tanislav <demonsingur@gmail.com>
Mon, 22 Apr 2024 17:22:18 +0000 (20:22 +0300)
SMFC Driver support JPEG class controls which includes quality factor,
chroma subsampling and restart interval.

Change-Id: I34fcd547a38696cd0f3576d6033a19a5f4fd754b
Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
drivers/media/platform/exynos/smfc/smfc-regs.c
drivers/media/platform/exynos/smfc/smfc.c
drivers/media/platform/exynos/smfc/smfc.h

index dd37a8bc88eadeaa632dc6edb2642ed720e3d2df..0c54ae662f1ec69568bbb983bbfa3ddcb71a583d 100644 (file)
@@ -208,8 +208,16 @@ static u32 smfc_hwconfigure_jpeg_base(struct smfc_ctx *ctx,
 /* [hfactor - 1][vfactor - 1]: 444, 422V, 422, 420 */
 static u32 smfc_get_jpeg_format(unsigned int hfactor, unsigned int vfactor)
 {
-       static unsigned char jpeg_regfmt[2][2] = { {1, 4}, {2, 3} };
-       return jpeg_regfmt[hfactor - 1][vfactor - 1] << 24;
+       switch ((hfactor << 4) | vfactor) {
+       case 0x00: return 0 << 24;
+       case 0x11: return 1 << 24;
+       case 0x21: return 2 << 24;
+       case 0x22: return 3 << 24;
+       case 0x12: return 4 << 24;
+       case 0x41: return 5 << 24;
+       }
+
+       return 2 << 24; /* default: YUV422 */
 }
 
 void smfc_hwconfigure_image(struct smfc_ctx *ctx)
@@ -259,6 +267,8 @@ void smfc_hwconfigure_start(struct smfc_ctx *ctx)
        cfg |= 1 << 19; /* update huffman table from SFR */
        cfg |= 1 << 28; /* enables interrupt */
        cfg |= 1 << 29; /* Release reset */
+       if (ctx->restart_interval != 0)
+               cfg |= (ctx->restart_interval << 3) | (1 << 2);
 
        writel(cfg, base + REG_JPEG_CNTL);
 }
index b2ec853e32f96e60698a6c210a036f5671bde5ed..73b41d300053ee786657b8e171a2e473e85cb5c8 100644 (file)
@@ -21,9 +21,6 @@
 #include <linux/mutex.h>
 #include <linux/exynos_iovmm.h>
 
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-core.h>
 #include <media/videobuf2-dma-sg.h>
 
@@ -427,6 +424,93 @@ 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_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;
+
+       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;
+       }
+
+       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);
@@ -446,8 +530,14 @@ static int exynos_smfc_open(struct file *filp)
                goto err_m2m_ctx_init;
        }
 
-
        v4l2_fh_init(&ctx->v4l2_fh, smfc->videodev);
+
+       ret = smfc_init_controls(smfc, &ctx->v4l2_ctrlhdlr);
+       if (ret)
+               goto err_control;
+
+       ctx->v4l2_fh.ctrl_handler = &ctx->v4l2_ctrlhdlr;
+
        v4l2_fh_add(&ctx->v4l2_fh);
 
        filp->private_data = &ctx->v4l2_fh;
@@ -478,6 +568,7 @@ static int exynos_smfc_open(struct file *filp)
        ctx->chroma_vfactor = ctx->img_fmt->chroma_vfactor;
        ctx->flags |= SMFC_CTX_COMPRESS;
        ctx->quality_factor = 96;
+       ctx->restart_interval = 0;
 
        ctx->smfc = smfc;
 
@@ -486,6 +577,7 @@ err_clk:
        v4l2_fh_del(&ctx->v4l2_fh);
        v4l2_fh_exit(&ctx->v4l2_fh);
        v4l2_m2m_ctx_release(ctx->m2mctx);
+err_control:
 err_m2m_ctx_init:
        kfree(ctx);
        return ret;
index ba0f17382e9eb8145b5c3d164009d3c7e61255de..98e3a08c6546c78774e2cda61e6309a471eae31f 100644 (file)
 #ifndef _MEDIA_EXYNOS_SMFC_H_
 #define _MEDIA_EXYNOS_SMFC_H_
 
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ctrls.h>
+
 #include "smfc-regs.h"
 
 #define MODULE_NAME    "exynos-jpeg"
@@ -54,6 +59,7 @@ struct smfc_dev {
 
 struct smfc_ctx {
        struct v4l2_fh v4l2_fh;
+       struct v4l2_ctrl_handler v4l2_ctrlhdlr;
        struct smfc_dev *smfc;
        struct v4l2_m2m_ctx *m2mctx;
        u32 flags;
@@ -64,7 +70,8 @@ struct smfc_ctx {
        /* JPEG chroma subsampling factors */
        unsigned char chroma_hfactor;
        unsigned char chroma_vfactor;
-       unsigned int quality_factor;
+       unsigned char restart_interval;
+       unsigned char quality_factor;
 };
 
 static inline struct smfc_ctx *v4l2_fh_to_smfc_ctx(struct v4l2_fh *fh)