From d3dd59c232abdd2ab9c5e04e5229dd18f85b551d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Jul 2012 10:35:37 -0300 Subject: [PATCH] [media] mem2mem_testdev: convert to the control framework and v4l2_fh Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mem2mem_testdev.c | 234 +++++++++----------------- 1 file changed, 83 insertions(+), 151 deletions(-) diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c index f08cf38a496d..a1d5c15eff40 100644 --- a/drivers/media/video/mem2mem_testdev.c +++ b/drivers/media/video/mem2mem_testdev.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #define MEM2MEM_TEST_MODULE_NAME "mem2mem-testdev" @@ -101,6 +102,8 @@ static struct m2mtest_fmt formats[] = { }, }; +#define NUM_FORMATS ARRAY_SIZE(formats) + /* Per-queue, driver-specific private data */ struct m2mtest_q_data { unsigned int width; @@ -114,50 +117,8 @@ enum { V4L2_M2M_DST = 1, }; -#define V4L2_CID_TRANS_TIME_MSEC V4L2_CID_PRIVATE_BASE -#define V4L2_CID_TRANS_NUM_BUFS (V4L2_CID_PRIVATE_BASE + 1) - -static struct v4l2_queryctrl m2mtest_ctrls[] = { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - .flags = 0, - }, { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Vertical Mirror", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - .flags = 0, - }, { - .id = V4L2_CID_TRANS_TIME_MSEC, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Transaction time (msec)", - .minimum = 1, - .maximum = 10000, - .step = 100, - .default_value = 1000, - .flags = 0, - }, { - .id = V4L2_CID_TRANS_NUM_BUFS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Buffers per transaction", - .minimum = 1, - .maximum = MEM2MEM_DEF_NUM_BUFS, - .step = 1, - .default_value = 1, - .flags = 0, - }, -}; - -#define NUM_FORMATS ARRAY_SIZE(formats) +#define V4L2_CID_TRANS_TIME_MSEC (V4L2_CID_USER_BASE + 0x1000) +#define V4L2_CID_TRANS_NUM_BUFS (V4L2_CID_USER_BASE + 0x1001) static struct m2mtest_fmt *find_format(struct v4l2_format *f) { @@ -190,8 +151,11 @@ struct m2mtest_dev { }; struct m2mtest_ctx { + struct v4l2_fh fh; struct m2mtest_dev *dev; + struct v4l2_ctrl_handler hdl; + /* Processed buffers in this transaction */ u8 num_processed; @@ -212,6 +176,11 @@ struct m2mtest_ctx { struct m2mtest_q_data q_data[2]; }; +static inline struct m2mtest_ctx *file2ctx(struct file *file) +{ + return container_of(file->private_data, struct m2mtest_ctx, fh); +} + static struct m2mtest_q_data *get_q_data(struct m2mtest_ctx *ctx, enum v4l2_buf_type type) { @@ -227,18 +196,6 @@ static struct m2mtest_q_data *get_q_data(struct m2mtest_ctx *ctx, } -static struct v4l2_queryctrl *get_ctrl(int id) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(m2mtest_ctrls); ++i) { - if (id == m2mtest_ctrls[i].id) - return &m2mtest_ctrls[i]; - } - - return NULL; -} - static int device_process(struct m2mtest_ctx *ctx, struct vb2_buffer *in_vb, struct vb2_buffer *out_vb) @@ -543,13 +500,13 @@ static int vidioc_g_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) static int vidioc_g_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f) { - return vidioc_g_fmt(priv, f); + return vidioc_g_fmt(file2ctx(file), f); } static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - return vidioc_g_fmt(priv, f); + return vidioc_g_fmt(file2ctx(file), f); } static int vidioc_try_fmt(struct v4l2_format *f, struct m2mtest_fmt *fmt) @@ -588,7 +545,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct m2mtest_fmt *fmt; - struct m2mtest_ctx *ctx = priv; + struct m2mtest_ctx *ctx = file2ctx(file); fmt = find_format(f); if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) { @@ -605,7 +562,7 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f) { struct m2mtest_fmt *fmt; - struct m2mtest_ctx *ctx = priv; + struct m2mtest_ctx *ctx = file2ctx(file); fmt = find_format(f); if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) { @@ -658,7 +615,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, if (ret) return ret; - return vidioc_s_fmt(priv, f); + return vidioc_s_fmt(file2ctx(file), f); } static int vidioc_s_fmt_vid_out(struct file *file, void *priv, @@ -670,13 +627,13 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *priv, if (ret) return ret; - return vidioc_s_fmt(priv, f); + return vidioc_s_fmt(file2ctx(file), f); } static int vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *reqbufs) { - struct m2mtest_ctx *ctx = priv; + struct m2mtest_ctx *ctx = file2ctx(file); return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); } @@ -684,21 +641,21 @@ static int vidioc_reqbufs(struct file *file, void *priv, static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *buf) { - struct m2mtest_ctx *ctx = priv; + struct m2mtest_ctx *ctx = file2ctx(file); return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); } static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { - struct m2mtest_ctx *ctx = priv; + struct m2mtest_ctx *ctx = file2ctx(file); return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); } static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { - struct m2mtest_ctx *ctx = priv; + struct m2mtest_ctx *ctx = file2ctx(file); return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); } @@ -706,7 +663,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type type) { - struct m2mtest_ctx *ctx = priv; + struct m2mtest_ctx *ctx = file2ctx(file); return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); } @@ -714,101 +671,37 @@ static int vidioc_streamon(struct file *file, void *priv, static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type type) { - struct m2mtest_ctx *ctx = priv; + struct m2mtest_ctx *ctx = file2ctx(file); return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); } -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qc) -{ - struct v4l2_queryctrl *c; - - c = get_ctrl(qc->id); - if (!c) - return -EINVAL; - - *qc = *c; - return 0; -} - -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct m2mtest_ctx *ctx = priv; - - switch (ctrl->id) { - case V4L2_CID_HFLIP: - ctrl->value = (ctx->mode & MEM2MEM_HFLIP) ? 1 : 0; - break; - - case V4L2_CID_VFLIP: - ctrl->value = (ctx->mode & MEM2MEM_VFLIP) ? 1 : 0; - break; - - case V4L2_CID_TRANS_TIME_MSEC: - ctrl->value = ctx->transtime; - break; - - case V4L2_CID_TRANS_NUM_BUFS: - ctrl->value = ctx->translen; - break; - - default: - v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n"); - return -EINVAL; - } - - return 0; -} - -static int check_ctrl_val(struct m2mtest_ctx *ctx, struct v4l2_control *ctrl) +static int m2mtest_s_ctrl(struct v4l2_ctrl *ctrl) { - struct v4l2_queryctrl *c; - - c = get_ctrl(ctrl->id); - if (!c) - return -EINVAL; - - if (ctrl->value < c->minimum || ctrl->value > c->maximum) { - v4l2_err(&ctx->dev->v4l2_dev, "Value out of range\n"); - return -ERANGE; - } - - return 0; -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct m2mtest_ctx *ctx = priv; - int ret = 0; - - ret = check_ctrl_val(ctx, ctrl); - if (ret != 0) - return ret; + struct m2mtest_ctx *ctx = + container_of(ctrl->handler, struct m2mtest_ctx, hdl); switch (ctrl->id) { case V4L2_CID_HFLIP: - if (ctrl->value) + if (ctrl->val) ctx->mode |= MEM2MEM_HFLIP; else ctx->mode &= ~MEM2MEM_HFLIP; break; case V4L2_CID_VFLIP: - if (ctrl->value) + if (ctrl->val) ctx->mode |= MEM2MEM_VFLIP; else ctx->mode &= ~MEM2MEM_VFLIP; break; case V4L2_CID_TRANS_TIME_MSEC: - ctx->transtime = ctrl->value; + ctx->transtime = ctrl->val; break; case V4L2_CID_TRANS_NUM_BUFS: - ctx->translen = ctrl->value; + ctx->translen = ctrl->val; break; default: @@ -819,6 +712,10 @@ static int vidioc_s_ctrl(struct file *file, void *priv, return 0; } +static const struct v4l2_ctrl_ops m2mtest_ctrl_ops = { + .s_ctrl = m2mtest_s_ctrl, +}; + static const struct v4l2_ioctl_ops m2mtest_ioctl_ops = { .vidioc_querycap = vidioc_querycap, @@ -841,10 +738,6 @@ static const struct v4l2_ioctl_ops m2mtest_ioctl_ops = { .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, - - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, }; @@ -956,6 +849,28 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *ds return vb2_queue_init(dst_vq); } +static const struct v4l2_ctrl_config m2mtest_ctrl_trans_time_msec = { + .ops = &m2mtest_ctrl_ops, + .id = V4L2_CID_TRANS_TIME_MSEC, + .name = "Transaction Time (msec)", + .type = V4L2_CTRL_TYPE_INTEGER, + .def = 1001, + .min = 1, + .max = 10001, + .step = 100, +}; + +static const struct v4l2_ctrl_config m2mtest_ctrl_trans_num_bufs = { + .ops = &m2mtest_ctrl_ops, + .id = V4L2_CID_TRANS_NUM_BUFS, + .name = "Buffers Per Transaction", + .type = V4L2_CTRL_TYPE_INTEGER, + .def = 1, + .min = 1, + .max = MEM2MEM_DEF_NUM_BUFS, + .step = 1, +}; + /* * File operations */ @@ -963,17 +878,29 @@ static int m2mtest_open(struct file *file) { struct m2mtest_dev *dev = video_drvdata(file); struct m2mtest_ctx *ctx = NULL; + struct v4l2_ctrl_handler *hdl; ctx = kzalloc(sizeof *ctx, GFP_KERNEL); if (!ctx) return -ENOMEM; - file->private_data = ctx; + v4l2_fh_init(&ctx->fh, video_devdata(file)); + file->private_data = &ctx->fh; ctx->dev = dev; - ctx->translen = MEM2MEM_DEF_TRANSLEN; - ctx->transtime = MEM2MEM_DEF_TRANSTIME; - ctx->num_processed = 0; - ctx->mode = 0; + hdl = &ctx->hdl; + v4l2_ctrl_handler_init(hdl, 4); + v4l2_ctrl_new_std(hdl, &m2mtest_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(hdl, &m2mtest_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_custom(hdl, &m2mtest_ctrl_trans_time_msec, NULL); + v4l2_ctrl_new_custom(hdl, &m2mtest_ctrl_trans_num_bufs, NULL); + if (hdl->error) { + int err = hdl->error; + + v4l2_ctrl_handler_free(hdl); + return err; + } + ctx->fh.ctrl_handler = hdl; + v4l2_ctrl_handler_setup(hdl); ctx->q_data[V4L2_M2M_SRC].fmt = &formats[0]; ctx->q_data[V4L2_M2M_DST].fmt = &formats[0]; @@ -983,10 +910,12 @@ static int m2mtest_open(struct file *file) if (IS_ERR(ctx->m2m_ctx)) { int ret = PTR_ERR(ctx->m2m_ctx); + v4l2_ctrl_handler_free(hdl); kfree(ctx); return ret; } + v4l2_fh_add(&ctx->fh); atomic_inc(&dev->num_inst); dprintk(dev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx); @@ -997,10 +926,13 @@ static int m2mtest_open(struct file *file) static int m2mtest_release(struct file *file) { struct m2mtest_dev *dev = video_drvdata(file); - struct m2mtest_ctx *ctx = file->private_data; + struct m2mtest_ctx *ctx = file2ctx(file); dprintk(dev, "Releasing instance %p\n", ctx); + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); + v4l2_ctrl_handler_free(&ctx->hdl); v4l2_m2m_ctx_release(ctx->m2m_ctx); kfree(ctx); @@ -1012,14 +944,14 @@ static int m2mtest_release(struct file *file) static unsigned int m2mtest_poll(struct file *file, struct poll_table_struct *wait) { - struct m2mtest_ctx *ctx = file->private_data; + struct m2mtest_ctx *ctx = file2ctx(file); return v4l2_m2m_poll(file, ctx->m2m_ctx, wait); } static int m2mtest_mmap(struct file *file, struct vm_area_struct *vma) { - struct m2mtest_ctx *ctx = file->private_data; + struct m2mtest_ctx *ctx = file2ctx(file); return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); } -- 2.20.1