summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYouness Alaoui <youness.alaoui@collabora.co.uk>2012-06-29 17:47:32 (GMT)
committerYouness Alaoui <youness.alaoui@collabora.co.uk>2012-06-30 05:15:27 (GMT)
commitb4cb88f8d18d4c9c23f2ae81ed4a0674c5575187 (patch)
tree077674d9e60c3f5b9c2b3017a04ddcb3a3e84e01
parent95aede5104975bf9b4a50ac3bcdee63db67b20ee (diff)
downloadlinux-kernel-uvcvideo.tar.gz
linux-kernel-uvcvideo.tar.xz
uvcvideo: Add a UVCIOC_GET_LAST_SCR ioctl with its documentationuvcvideo
-rw-r--r--Documentation/video4linux/uvcvideo.txt32
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c3
-rw-r--r--drivers/media/video/uvc/uvc_video.c20
-rw-r--r--drivers/media/video/uvc/uvcvideo.h2
-rw-r--r--include/linux/uvcvideo.h11
5 files changed, 68 insertions, 0 deletions
diff --git a/Documentation/video4linux/uvcvideo.txt b/Documentation/video4linux/uvcvideo.txt
index 8492e94..26420ae 100644
--- a/Documentation/video4linux/uvcvideo.txt
+++ b/Documentation/video4linux/uvcvideo.txt
@@ -269,3 +269,35 @@ Data types:
__u8 guid[16] Extension unit GUID
__u8 unit Extension unit ID
+
+
+---- UVCIOC_GET_LAST_SCR - Get the last sampled Source Clock Reference ----
+
+Argument: struct uvc_last_scr_sample
+
+Description:
+ This ioctl returns the last sampled SCR from the device, allowing for user
+ space calculating of the linear regression in order to transform a frame's
+ PTS into the system clock's timestamp.
+
+ The SOF values are initiallize normaled if the driver detects that the
+ device is using its own frame numbers. They are also expanded into 32 bits
+ to increase its resolution.
+
+ If a SOF rollover is noticed, the value of UVC_SOF_ROLLOVER_FIX should be added
+ in order to fix the rollover.
+Return value:
+ On success 0 is returned. On error -1 is returned and errno is set
+ appropriately.
+
+ ENOBUGS
+ The driver does not have any SCR samples stored yet.
+
+Data types:
+ * struct uvc_last_scr_sample
+
+ __u32 dev_frequency The device frequency
+ __u32 dev_stc The STC of the device
+ __u16 dev_sof The SOF associated with the device STC
+ struct timespec host_ts The host timestamp
+ __u16 host_sof The SOF associated with the host timestamp
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index c20b7df..e8188bc 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -1041,6 +1041,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case UVCIOC_CTRL_FIND_UNIT:
return uvc_xu_find_unit(chain, arg);
+ case UVCIOC_GET_LAST_SCR:
+ return uvc_video_get_last_scr_sample(stream, arg);
+
default:
uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", cmd);
return -ENOTTY;
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index a7708df..6a46972 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -684,6 +684,26 @@ done:
spin_unlock_irqrestore(&stream->clock.lock, flags);
}
+int uvc_video_get_last_scr_sample(struct uvc_streaming *stream,
+ struct uvc_last_scr_sample *sample)
+{
+ struct uvc_clock *clock = &stream->clock;
+ struct uvc_clock_sample *last;
+
+ if (clock->count == 0)
+ return -ENOBUFS;
+
+ last = &clock->samples[(clock->head - 1) % clock->size];
+
+ sample->dev_frequency = stream->dev->clock_frequency;
+ sample->dev_stc = last->dev_stc;
+ sample->dev_sof = last->dev_sof;
+ sample->host_ts = last->host_ts;
+ sample->host_sof = last->host_sof;
+
+ return 0;
+}
+
/* ------------------------------------------------------------------------
* Stream statistics
*/
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index e840ac9..dc76c3b 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -639,6 +639,8 @@ extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
void uvc_video_clock_update(struct uvc_streaming *stream,
struct v4l2_buffer *v4l2_buf,
struct uvc_buffer *buf);
+extern int uvc_video_get_last_scr_sample(struct uvc_streaming *stream,
+ struct uvc_last_scr_sample *sample);
/* Status */
extern int uvc_status_init(struct uvc_device *dev);
diff --git a/include/linux/uvcvideo.h b/include/linux/uvcvideo.h
index 176c00e..ecbbc5a 100644
--- a/include/linux/uvcvideo.h
+++ b/include/linux/uvcvideo.h
@@ -33,6 +33,8 @@
UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES | \
UVC_CTRL_FLAG_GET_DEF)
+#define UVC_SOF_ROLLOVER_FIX 2048
+
struct uvc_menu_info {
__u32 value;
__u8 name[32];
@@ -68,8 +70,17 @@ struct uvc_xu_find_unit {
__u8 unit;
};
+struct uvc_last_scr_sample {
+ __u32 dev_frequency;
+ __u32 dev_stc;
+ __u16 dev_sof;
+ struct timespec host_ts;
+ __u16 host_sof;
+};
+
#define UVCIOC_CTRL_MAP _IOWR('u', 0x20, struct uvc_xu_control_mapping)
#define UVCIOC_CTRL_QUERY _IOWR('u', 0x21, struct uvc_xu_control_query)
#define UVCIOC_CTRL_FIND_UNIT _IOWR('u', 0x22, struct uvc_xu_find_unit)
+#define UVCIOC_GET_LAST_SCR _IOR('u', 0x23, struct uvc_last_scr_sample)
#endif