@@ -112,7 +112,7 @@ const struct rockchip_vpu_variant rk3288_vpu_variant = {
.enc_fmts = rk3288_vpu_enc_fmts,
.num_enc_fmts = ARRAY_SIZE(rk3288_vpu_enc_fmts),
.codec_ops = rk3288_vpu_codec_ops,
- .codec = RK_VPU_CODEC_JPEG,
+ .codec = RK_VPU_JPEG_ENCODER,
.vepu_irq = rk3288_vepu_irq,
.init = rk3288_vpu_hw_init,
.clk_names = {"aclk", "hclk"},
@@ -129,7 +129,7 @@ const struct rockchip_vpu_variant rk3399_vpu_variant = {
.enc_offset = 0x0,
.enc_fmts = rk3399_vpu_enc_fmts,
.num_enc_fmts = ARRAY_SIZE(rk3399_vpu_enc_fmts),
- .codec = RK_VPU_CODEC_JPEG,
+ .codec = RK_VPU_JPEG_ENCODER,
.codec_ops = rk3399_vpu_codec_ops,
.vepu_irq = rk3399_vepu_irq,
.vdpu_irq = rk3399_vdpu_irq,
@@ -34,7 +34,10 @@
struct rockchip_vpu_ctx;
struct rockchip_vpu_codec_ops;
-#define RK_VPU_CODEC_JPEG BIT(0)
+#define RK_VPU_JPEG_ENCODER BIT(0)
+#define RK_VPU_ENCODERS 0x0000ffff
+
+#define RK_VPU_DECODERS 0xffff0000
/**
* struct rockchip_vpu_variant - information about VPU hardware variant
@@ -89,6 +92,18 @@ enum rockchip_vpu_type {
RK_VPU_DECODER,
};
+/*
+ * struct rockchip_vpu_ctrl - helper type to declare supported controls
+ * @id: V4L2 control ID (V4L2_CID_xxx)
+ * @codec: codec id this control belong to (RK_VPU_JPEG_ENCODER, etc.)
+ * @cfg: control configuration
+ */
+struct rockchip_vpu_ctrl {
+ unsigned int id;
+ unsigned int codec;
+ struct v4l2_ctrl_config cfg;
+};
+
/*
* struct rockchip_vpu_mc - media controller data
*
@@ -248,22 +248,51 @@ static const struct v4l2_ctrl_ops rockchip_vpu_ctrl_ops = {
.s_ctrl = rockchip_vpu_s_ctrl,
};
+static struct rockchip_vpu_ctrl controls[] = {
+ {
+ .id = V4L2_CID_JPEG_COMPRESSION_QUALITY,
+ .codec = RK_VPU_JPEG_ENCODER,
+ .cfg = {
+ .min = 5,
+ .max = 100,
+ .step = 1,
+ .def = 50,
+ },
+ },
+};
+
static int rockchip_vpu_ctrls_setup(struct rockchip_vpu_dev *vpu,
- struct rockchip_vpu_ctx *ctx)
+ struct rockchip_vpu_ctx *ctx,
+ int allowed_codecs)
{
- v4l2_ctrl_handler_init(&ctx->ctrl_handler, 1);
- if (vpu->variant->codec & RK_VPU_CODEC_JPEG) {
- v4l2_ctrl_new_std(&ctx->ctrl_handler, &rockchip_vpu_ctrl_ops,
- V4L2_CID_JPEG_COMPRESSION_QUALITY,
- 5, 100, 1, 50);
+ int j, i, num_ctrls = ARRAY_SIZE(controls);
+
+ v4l2_ctrl_handler_init(&ctx->ctrl_handler, num_ctrls);
+
+ for (i = 0, j = 0; i < num_ctrls; i++) {
+ if (!(allowed_codecs & controls[i].codec))
+ continue;
+ if (!controls[i].cfg.elem_size) {
+ v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &rockchip_vpu_ctrl_ops,
+ controls[i].id, controls[i].cfg.min,
+ controls[i].cfg.max,
+ controls[i].cfg.step,
+ controls[i].cfg.def);
+ } else {
+ controls[i].cfg.id = controls[i].id;
+ v4l2_ctrl_new_custom(&ctx->ctrl_handler,
+ &controls[i].cfg, NULL);
+ }
+
if (ctx->ctrl_handler.error) {
- vpu_err("Adding JPEG control failed %d\n",
+ vpu_err("Adding control (%d) failed %d\n",
+ controls[i].id,
ctx->ctrl_handler.error);
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
return ctx->ctrl_handler.error;
}
}
-
return v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
}
@@ -276,7 +305,7 @@ static int rockchip_vpu_open(struct file *filp)
struct rockchip_vpu_dev *vpu = video_drvdata(filp);
struct video_device *vdev = video_devdata(filp);
struct rockchip_vpu_ctx *ctx;
- int ret;
+ int allowed_codecs, ret;
/*
* We do not need any extra locking here, because we operate only
@@ -293,10 +322,12 @@ static int rockchip_vpu_open(struct file *filp)
ctx->dev = vpu;
if (vdev == vpu->vfd_enc) {
+ allowed_codecs = vpu->variant->codec & RK_VPU_ENCODERS;
ctx->buf_finish = rockchip_vpu_enc_buf_finish;
ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(vpu->m2m_dev, ctx,
queue_init);
} else if (vdev == vpu->vfd_dec) {
+ allowed_codecs = vpu->variant->codec & RK_VPU_DECODERS;
ctx->buf_finish = rockchip_vpu_dec_buf_finish;
ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(vpu->m2m_dev, ctx,
queue_init);
@@ -315,7 +346,7 @@ static int rockchip_vpu_open(struct file *filp)
rockchip_vpu_reset_fmts(ctx);
- ret = rockchip_vpu_ctrls_setup(vpu, ctx);
+ ret = rockchip_vpu_ctrls_setup(vpu, ctx, allowed_codecs);
if (ret) {
vpu_err("Failed to set up controls\n");
goto err_fh_free;