media: imx-jpeg: Encoder support to set jpeg quality
authorMing Qian <ming.qian@nxp.com>
Thu, 19 May 2022 01:43:48 +0000 (02:43 +0100)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Mon, 20 Jun 2022 09:30:31 +0000 (10:30 +0100)
Implement V4L2_CID_JPEG_COMPRESSION_QUALITY
to set jpeg quality

Signed-off-by: Ming Qian <ming.qian@nxp.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c
drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h
drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h

index 29c604b1b1790515eea3a1e8dbc781b12ec9e2a4..c482228262a33d289ddacc523556745919e21b09 100644 (file)
@@ -100,9 +100,6 @@ void mxc_jpeg_enc_mode_conf(struct device *dev, void __iomem *reg)
 
        /* all markers and segments */
        writel(0x3ff, reg + CAST_CFG_MODE);
-
-       /* quality factor */
-       writel(0x4b, reg + CAST_QUALITY);
 }
 
 void mxc_jpeg_enc_mode_go(struct device *dev, void __iomem *reg)
@@ -114,6 +111,14 @@ void mxc_jpeg_enc_mode_go(struct device *dev, void __iomem *reg)
        writel(0x140, reg + CAST_MODE);
 }
 
+void mxc_jpeg_enc_set_quality(struct device *dev, void __iomem *reg, u8 quality)
+{
+       dev_dbg(dev, "CAST Encoder Quality %d...\n", quality);
+
+       /* quality factor */
+       writel(quality, reg + CAST_QUALITY);
+}
+
 void mxc_jpeg_dec_mode_go(struct device *dev, void __iomem *reg)
 {
        dev_dbg(dev, "CAST Decoder GO...\n");
index d838e875616c35a5c7176cd75f90cdd81f40daa2..e7e8954754b192e21a93e6678d66b67e21f218d1 100644 (file)
@@ -119,6 +119,7 @@ int mxc_jpeg_enable(void __iomem *reg);
 void wait_frmdone(struct device *dev, void __iomem *reg);
 void mxc_jpeg_enc_mode_conf(struct device *dev, void __iomem *reg);
 void mxc_jpeg_enc_mode_go(struct device *dev, void __iomem *reg);
+void mxc_jpeg_enc_set_quality(struct device *dev, void __iomem *reg, u8 quality);
 void mxc_jpeg_dec_mode_go(struct device *dev, void __iomem *reg);
 int mxc_jpeg_get_slot(void __iomem *reg);
 u32 mxc_jpeg_get_offset(void __iomem *reg, int slot);
index de57101b5df37d36e3104586d48f50b4213073cb..734e1b65fbc7ff4a4286f45aefe4b26035358738 100644 (file)
@@ -623,6 +623,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
            ctx->enc_state == MXC_JPEG_ENC_CONF) {
                ctx->enc_state = MXC_JPEG_ENCODING;
                dev_dbg(dev, "Encoder config finished. Start encoding...\n");
+               mxc_jpeg_enc_set_quality(dev, reg, ctx->jpeg_quality);
                mxc_jpeg_enc_mode_go(dev, reg);
                goto job_unlock;
        }
@@ -1562,6 +1563,56 @@ static void mxc_jpeg_set_default_params(struct mxc_jpeg_ctx *ctx)
        }
 }
 
+static int mxc_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct mxc_jpeg_ctx *ctx =
+               container_of(ctrl->handler, struct mxc_jpeg_ctx, ctrl_handler);
+
+       switch (ctrl->id) {
+       case V4L2_CID_JPEG_COMPRESSION_QUALITY:
+               ctx->jpeg_quality = ctrl->val;
+               break;
+       default:
+               dev_err(ctx->mxc_jpeg->dev, "Invalid control, id = %d, val = %d\n",
+                       ctrl->id, ctrl->val);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static const struct v4l2_ctrl_ops mxc_jpeg_ctrl_ops = {
+       .s_ctrl = mxc_jpeg_s_ctrl,
+};
+
+static void mxc_jpeg_encode_ctrls(struct mxc_jpeg_ctx *ctx)
+{
+       v4l2_ctrl_new_std(&ctx->ctrl_handler, &mxc_jpeg_ctrl_ops,
+                         V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, 100, 1, 75);
+}
+
+static int mxc_jpeg_ctrls_setup(struct mxc_jpeg_ctx *ctx)
+{
+       int err;
+
+       v4l2_ctrl_handler_init(&ctx->ctrl_handler, 2);
+
+       if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE)
+               mxc_jpeg_encode_ctrls(ctx);
+
+       if (ctx->ctrl_handler.error) {
+               err = ctx->ctrl_handler.error;
+
+               v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+               return err;
+       }
+
+       err = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
+       if (err)
+               v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+       return err;
+}
+
 static int mxc_jpeg_open(struct file *file)
 {
        struct mxc_jpeg_dev *mxc_jpeg = video_drvdata(file);
@@ -1593,6 +1644,12 @@ static int mxc_jpeg_open(struct file *file)
                goto error;
        }
 
+       ret = mxc_jpeg_ctrls_setup(ctx);
+       if (ret) {
+               dev_err(ctx->mxc_jpeg->dev, "failed to setup mxc jpeg controls\n");
+               goto err_ctrls_setup;
+       }
+       ctx->fh.ctrl_handler = &ctx->ctrl_handler;
        mxc_jpeg_set_default_params(ctx);
        ctx->slot = MXC_MAX_SLOTS; /* slot not allocated yet */
 
@@ -1604,6 +1661,8 @@ static int mxc_jpeg_open(struct file *file)
 
        return 0;
 
+err_ctrls_setup:
+       v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
 error:
        v4l2_fh_del(&ctx->fh);
        v4l2_fh_exit(&ctx->fh);
@@ -1956,6 +2015,8 @@ static int mxc_jpeg_subscribe_event(struct v4l2_fh *fh,
                return v4l2_event_subscribe(fh, sub, 0, NULL);
        case V4L2_EVENT_SOURCE_CHANGE:
                return v4l2_src_change_event_subscribe(fh, sub);
+       case V4L2_EVENT_CTRL:
+               return v4l2_ctrl_subscribe_event(fh, sub);
        default:
                return -EINVAL;
        }
@@ -2029,6 +2090,7 @@ static int mxc_jpeg_release(struct file *file)
        else
                dev_dbg(dev, "Release JPEG encoder instance on slot %d.",
                        ctx->slot);
+       v4l2_ctrl_handler_free(&ctx->ctrl_handler);
        v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
        v4l2_fh_del(&ctx->fh);
        v4l2_fh_exit(&ctx->fh);
index 760eaf5387a1c2a57d8f53f8974b1dde351b370a..d439be6e4acf446db5811fd3d27870023850599a 100644 (file)
@@ -97,6 +97,8 @@ struct mxc_jpeg_ctx {
        unsigned int                    slot;
        unsigned int                    source_change;
        bool                            header_parsed;
+       struct v4l2_ctrl_handler        ctrl_handler;
+       u8                              jpeg_quality;
 };
 
 struct mxc_jpeg_slot_data {