[media] v4l2 framework: add support for the new dv_timings ioctls
authorHans Verkuil <hans.verkuil@cisco.com>
Tue, 15 May 2012 11:06:44 +0000 (08:06 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sun, 20 May 2012 11:22:30 +0000 (08:22 -0300)
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Reviewed-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/v4l2-compat-ioctl32.c
drivers/media/video/v4l2-ioctl.c
include/media/v4l2-ioctl.h
include/media/v4l2-subdev.h

index 89ae433877e67247ded70b6d35676122a296d1c5..5327ad3a63907a87f3da587812269b60edef5880 100644 (file)
@@ -1023,6 +1023,9 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
        case VIDIOC_UNSUBSCRIBE_EVENT:
        case VIDIOC_CREATE_BUFS32:
        case VIDIOC_PREPARE_BUF32:
+       case VIDIOC_ENUM_DV_TIMINGS:
+       case VIDIOC_QUERY_DV_TIMINGS:
+       case VIDIOC_DV_TIMINGS_CAP:
                ret = do_video_ioctl(file, cmd, arg);
                break;
 
index 623d280ce095941b6572e9a2e2f2ba5635c6bfd2..91be4e871f43644c2052c942092a3f808688c9a8 100644 (file)
@@ -281,6 +281,9 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
        IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT, 0),
        IOCTL_INFO(VIDIOC_CREATE_BUFS, INFO_FL_PRIO),
        IOCTL_INFO(VIDIOC_PREPARE_BUF, 0),
+       IOCTL_INFO(VIDIOC_ENUM_DV_TIMINGS, 0),
+       IOCTL_INFO(VIDIOC_QUERY_DV_TIMINGS, 0),
+       IOCTL_INFO(VIDIOC_DV_TIMINGS_CAP, 0),
 };
 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
 
@@ -368,6 +371,34 @@ static inline void dbgrect(struct video_device *vfd, char *s,
                                                r->width, r->height);
 };
 
+static void dbgtimings(struct video_device *vfd,
+                       const struct v4l2_dv_timings *p)
+{
+       switch (p->type) {
+       case V4L2_DV_BT_656_1120:
+               dbgarg2("bt-656/1120:interlaced=%d,"
+                               " pixelclock=%lld,"
+                               " width=%d, height=%d, polarities=%x,"
+                               " hfrontporch=%d, hsync=%d,"
+                               " hbackporch=%d, vfrontporch=%d,"
+                               " vsync=%d, vbackporch=%d,"
+                               " il_vfrontporch=%d, il_vsync=%d,"
+                               " il_vbackporch=%d, standards=%x, flags=%x\n",
+                               p->bt.interlaced, p->bt.pixelclock,
+                               p->bt.width, p->bt.height,
+                               p->bt.polarities, p->bt.hfrontporch,
+                               p->bt.hsync, p->bt.hbackporch,
+                               p->bt.vfrontporch, p->bt.vsync,
+                               p->bt.vbackporch, p->bt.il_vfrontporch,
+                               p->bt.il_vsync, p->bt.il_vbackporch,
+                               p->bt.standards, p->bt.flags);
+               break;
+       default:
+               dbgarg2("Unknown type %d!\n", p->type);
+               break;
+       }
+}
+
 static inline void v4l_print_pix_fmt(struct video_device *vfd,
                                                struct v4l2_pix_format *fmt)
 {
@@ -1916,25 +1947,13 @@ static long __video_do_ioctl(struct file *file,
        {
                struct v4l2_dv_timings *p = arg;
 
+               dbgtimings(vfd, p);
                switch (p->type) {
                case V4L2_DV_BT_656_1120:
-                       dbgarg2("bt-656/1120:interlaced=%d, pixelclock=%lld,"
-                               " width=%d, height=%d, polarities=%x,"
-                               " hfrontporch=%d, hsync=%d, hbackporch=%d,"
-                               " vfrontporch=%d, vsync=%d, vbackporch=%d,"
-                               " il_vfrontporch=%d, il_vsync=%d,"
-                               " il_vbackporch=%d\n",
-                               p->bt.interlaced, p->bt.pixelclock,
-                               p->bt.width, p->bt.height, p->bt.polarities,
-                               p->bt.hfrontporch, p->bt.hsync,
-                               p->bt.hbackporch, p->bt.vfrontporch,
-                               p->bt.vsync, p->bt.vbackporch,
-                               p->bt.il_vfrontporch, p->bt.il_vsync,
-                               p->bt.il_vbackporch);
                        ret = ops->vidioc_s_dv_timings(file, fh, p);
                        break;
                default:
-                       dbgarg2("Unknown type %d!\n", p->type);
+                       ret = -EINVAL;
                        break;
                }
                break;
@@ -1944,29 +1963,60 @@ static long __video_do_ioctl(struct file *file,
                struct v4l2_dv_timings *p = arg;
 
                ret = ops->vidioc_g_dv_timings(file, fh, p);
+               if (!ret)
+                       dbgtimings(vfd, p);
+               break;
+       }
+       case VIDIOC_ENUM_DV_TIMINGS:
+       {
+               struct v4l2_enum_dv_timings *p = arg;
+
+               if (!ops->vidioc_enum_dv_timings)
+                       break;
+
+               ret = ops->vidioc_enum_dv_timings(file, fh, p);
                if (!ret) {
-                       switch (p->type) {
-                       case V4L2_DV_BT_656_1120:
-                               dbgarg2("bt-656/1120:interlaced=%d,"
-                                       " pixelclock=%lld,"
-                                       " width=%d, height=%d, polarities=%x,"
-                                       " hfrontporch=%d, hsync=%d,"
-                                       " hbackporch=%d, vfrontporch=%d,"
-                                       " vsync=%d, vbackporch=%d,"
-                                       " il_vfrontporch=%d, il_vsync=%d,"
-                                       " il_vbackporch=%d\n",
-                                       p->bt.interlaced, p->bt.pixelclock,
-                                       p->bt.width, p->bt.height,
-                                       p->bt.polarities, p->bt.hfrontporch,
-                                       p->bt.hsync, p->bt.hbackporch,
-                                       p->bt.vfrontporch, p->bt.vsync,
-                                       p->bt.vbackporch, p->bt.il_vfrontporch,
-                                       p->bt.il_vsync, p->bt.il_vbackporch);
-                               break;
-                       default:
-                               dbgarg2("Unknown type %d!\n", p->type);
-                               break;
-                       }
+                       dbgarg(cmd, "index=%d: ", p->index);
+                       dbgtimings(vfd, &p->timings);
+               }
+               break;
+       }
+       case VIDIOC_QUERY_DV_TIMINGS:
+       {
+               struct v4l2_dv_timings *p = arg;
+
+               if (!ops->vidioc_query_dv_timings)
+                       break;
+
+               ret = ops->vidioc_query_dv_timings(file, fh, p);
+               if (!ret)
+                       dbgtimings(vfd, p);
+               break;
+       }
+       case VIDIOC_DV_TIMINGS_CAP:
+       {
+               struct v4l2_dv_timings_cap *p = arg;
+
+               if (!ops->vidioc_dv_timings_cap)
+                       break;
+
+               ret = ops->vidioc_dv_timings_cap(file, fh, p);
+               if (ret)
+                       break;
+               switch (p->type) {
+               case V4L2_DV_BT_656_1120:
+                       dbgarg(cmd,
+                              "type=%d, width=%u-%u, height=%u-%u, "
+                              "pixelclock=%llu-%llu, standards=%x, capabilities=%x ",
+                              p->type,
+                              p->bt.min_width, p->bt.max_width,
+                              p->bt.min_height, p->bt.max_height,
+                              p->bt.min_pixelclock, p->bt.max_pixelclock,
+                              p->bt.standards, p->bt.capabilities);
+                       break;
+               default:
+                       dbgarg(cmd, "unknown type ");
+                       break;
                }
                break;
        }
@@ -2215,7 +2265,9 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
                        err = -EFAULT;
                goto out_array_args;
        }
-       if (err < 0)
+       /* VIDIOC_QUERY_DV_TIMINGS can return an error, but still have valid
+          results that must be returned. */
+       if (err < 0 && cmd != VIDIOC_QUERY_DV_TIMINGS)
                goto out;
 
 out_array_args:
index 3cb939cd03f9218843b278624b7c138bfccd2809..d8b76f7392f8d793c6abdf0a2a1a46b53fa115bc 100644 (file)
@@ -271,6 +271,12 @@ struct v4l2_ioctl_ops {
                                    struct v4l2_dv_timings *timings);
        int (*vidioc_g_dv_timings) (struct file *file, void *fh,
                                    struct v4l2_dv_timings *timings);
+       int (*vidioc_query_dv_timings) (struct file *file, void *fh,
+                                   struct v4l2_dv_timings *timings);
+       int (*vidioc_enum_dv_timings) (struct file *file, void *fh,
+                                   struct v4l2_enum_dv_timings *timings);
+       int (*vidioc_dv_timings_cap) (struct file *file, void *fh,
+                                   struct v4l2_dv_timings_cap *cap);
 
        int (*vidioc_subscribe_event)  (struct v4l2_fh *fh,
                                        struct v4l2_event_subscription *sub);
index 1c2318b15bd2ecc1d4150dfc0a1ef1dc67295d30..c35a3545e273258bf9afcb7a04fa512f55ef9685 100644 (file)
@@ -307,6 +307,12 @@ struct v4l2_subdev_video_ops {
                        struct v4l2_dv_timings *timings);
        int (*g_dv_timings)(struct v4l2_subdev *sd,
                        struct v4l2_dv_timings *timings);
+       int (*enum_dv_timings)(struct v4l2_subdev *sd,
+                       struct v4l2_enum_dv_timings *timings);
+       int (*query_dv_timings)(struct v4l2_subdev *sd,
+                       struct v4l2_dv_timings *timings);
+       int (*dv_timings_cap)(struct v4l2_subdev *sd,
+                       struct v4l2_dv_timings_cap *cap);
        int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index,
                             enum v4l2_mbus_pixelcode *code);
        int (*enum_mbus_fsizes)(struct v4l2_subdev *sd,