summaryrefslogtreecommitdiff
path: root/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c')
-rw-r--r--drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
index de57101b5df3..734e1b65fbc7 100644
--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
@@ -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);