]> git.karo-electronics.de Git - linux-beck.git/commitdiff
[media] mem2mem_testdev: convert to the control framework and v4l2_fh
authorHans Verkuil <hans.verkuil@cisco.com>
Wed, 18 Jul 2012 13:35:37 +0000 (10:35 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 30 Jul 2012 22:19:31 +0000 (19:19 -0300)
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/mem2mem_testdev.c

index f08cf38a496da83cfc4a093493d6e331ed8761fa..a1d5c15eff40aa9d83d029c9bfd3f8209cbad5c4 100644 (file)
@@ -27,6 +27,7 @@
 #include <media/v4l2-mem2mem.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
 #include <media/videobuf2-vmalloc.h>
 
 #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);
 }