V4L/DVB: V4L: Events: Support event handling in do_ioctl
[safe/jmp/linux-2.6] / drivers / media / video / v4l2-ioctl.c
index 3da8d8f..0eeceae 100644 (file)
@@ -26,6 +26,8 @@
 #endif
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-event.h>
 #include <media/v4l2-chip-ident.h>
 
 #define dbgarg(cmd, fmt, arg...) \
@@ -291,6 +293,9 @@ static const char *v4l2_ioctls[] = {
        [_IOC_NR(VIDIOC_QUERY_DV_PRESET)]  = "VIDIOC_QUERY_DV_PRESET",
        [_IOC_NR(VIDIOC_S_DV_TIMINGS)]     = "VIDIOC_S_DV_TIMINGS",
        [_IOC_NR(VIDIOC_G_DV_TIMINGS)]     = "VIDIOC_G_DV_TIMINGS",
+       [_IOC_NR(VIDIOC_DQEVENT)]          = "VIDIOC_DQEVENT",
+       [_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)]  = "VIDIOC_SUBSCRIBE_EVENT",
+       [_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
 };
 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
 
@@ -1948,7 +1953,55 @@ static long __video_do_ioctl(struct file *file,
                }
                break;
        }
+       case VIDIOC_DQEVENT:
+       {
+               struct v4l2_event *ev = arg;
+
+               if (!ops->vidioc_subscribe_event)
+                       break;
+
+               ret = v4l2_event_dequeue(fh, ev, file->f_flags & O_NONBLOCK);
+               if (ret < 0) {
+                       dbgarg(cmd, "no pending events?");
+                       break;
+               }
+               dbgarg(cmd,
+                      "pending=%d, type=0x%8.8x, sequence=%d, "
+                      "timestamp=%lu.%9.9lu ",
+                      ev->pending, ev->type, ev->sequence,
+                      ev->timestamp.tv_sec, ev->timestamp.tv_nsec);
+               break;
+       }
+       case VIDIOC_SUBSCRIBE_EVENT:
+       {
+               struct v4l2_event_subscription *sub = arg;
 
+               if (!ops->vidioc_subscribe_event)
+                       break;
+
+               ret = ops->vidioc_subscribe_event(fh, sub);
+               if (ret < 0) {
+                       dbgarg(cmd, "failed, ret=%ld", ret);
+                       break;
+               }
+               dbgarg(cmd, "type=0x%8.8x", sub->type);
+               break;
+       }
+       case VIDIOC_UNSUBSCRIBE_EVENT:
+       {
+               struct v4l2_event_subscription *sub = arg;
+
+               if (!ops->vidioc_unsubscribe_event)
+                       break;
+
+               ret = ops->vidioc_unsubscribe_event(fh, sub);
+               if (ret < 0) {
+                       dbgarg(cmd, "failed, ret=%ld", ret);
+                       break;
+               }
+               dbgarg(cmd, "type=0x%8.8x", sub->type);
+               break;
+       }
        default:
        {
                if (!ops->vidioc_default)