From: Cho KyongHo Date: Thu, 2 Apr 2015 01:39:17 +0000 (+0900) Subject: [COMMON] media: smfc: add V4L2 control values X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=a26dac9505a3bae80214c7144ed8db11d5724243;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git [COMMON] media: smfc: add V4L2 control values SMFC Driver support JPEG class controls which includes quality factor, chroma subsampling and restart interval. Change-Id: I34fcd547a38696cd0f3576d6033a19a5f4fd754b Signed-off-by: Cho KyongHo --- diff --git a/drivers/media/platform/exynos/smfc/smfc-regs.c b/drivers/media/platform/exynos/smfc/smfc-regs.c index dd37a8bc88ea..0c54ae662f1e 100644 --- a/drivers/media/platform/exynos/smfc/smfc-regs.c +++ b/drivers/media/platform/exynos/smfc/smfc-regs.c @@ -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); } diff --git a/drivers/media/platform/exynos/smfc/smfc.c b/drivers/media/platform/exynos/smfc/smfc.c index b2ec853e32f9..73b41d300053 100644 --- a/drivers/media/platform/exynos/smfc/smfc.c +++ b/drivers/media/platform/exynos/smfc/smfc.c @@ -21,9 +21,6 @@ #include #include -#include -#include -#include #include #include @@ -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; diff --git a/drivers/media/platform/exynos/smfc/smfc.h b/drivers/media/platform/exynos/smfc/smfc.h index ba0f17382e9e..98e3a08c6546 100644 --- a/drivers/media/platform/exynos/smfc/smfc.h +++ b/drivers/media/platform/exynos/smfc/smfc.h @@ -12,6 +12,11 @@ #ifndef _MEDIA_EXYNOS_SMFC_H_ #define _MEDIA_EXYNOS_SMFC_H_ +#include +#include +#include +#include + #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)