#include <asm/unaligned.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include "uvcvideo.h"
kref_put(&dev->ref, uvc_delete);
}
-static int uvc_register_video(struct uvc_device *dev,
- struct uvc_streaming *stream)
+int uvc_register_video_device(struct uvc_device *dev,
+ struct uvc_streaming *stream,
+ struct video_device *vdev,
+ struct uvc_video_queue *queue,
+ enum v4l2_buf_type type,
+ const struct v4l2_file_operations *fops,
+ const struct v4l2_ioctl_ops *ioctl_ops)
{
- struct video_device *vdev = &stream->vdev;
int ret;
/* Initialize the video buffers queue. */
- ret = uvc_queue_init(&stream->queue, stream->type, !uvc_no_drop_param);
+ ret = uvc_queue_init(queue, type, !uvc_no_drop_param);
if (ret)
return ret;
- /* Initialize the streaming interface with default streaming
- * parameters.
- */
- ret = uvc_video_init(stream);
- if (ret < 0) {
- uvc_printk(KERN_ERR, "Failed to initialize the device "
- "(%d).\n", ret);
- return ret;
- }
-
- uvc_debugfs_init_stream(stream);
-
/* Register the device with V4L. */
- /* We already hold a reference to dev->udev. The video device will be
+ /*
+ * We already hold a reference to dev->udev. The video device will be
* unregistered before the reference is released, so we don't need to
* get another one.
*/
vdev->v4l2_dev = &dev->vdev;
- vdev->fops = &uvc_fops;
- vdev->ioctl_ops = &uvc_ioctl_ops;
+ vdev->fops = fops;
+ vdev->ioctl_ops = ioctl_ops;
vdev->release = uvc_release;
vdev->prio = &stream->chain->prio;
- if (stream->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
vdev->vfl_dir = VFL_DIR_TX;
+ else
+ vdev->vfl_dir = VFL_DIR_RX;
strlcpy(vdev->name, dev->name, sizeof vdev->name);
- /* Set the driver data before calling video_register_device, otherwise
- * uvc_v4l2_open might race us.
+ /*
+ * Set the driver data before calling video_register_device, otherwise
+ * the file open() handler might race us.
*/
video_set_drvdata(vdev, stream);
ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
if (ret < 0) {
- uvc_printk(KERN_ERR, "Failed to register video device (%d).\n",
+ uvc_printk(KERN_ERR, "Failed to register %s device (%d).\n",
+ v4l2_type_names[type], ret);
+ return ret;
+ }
+
+ kref_get(&dev->ref);
+ return 0;
+}
+
+static int uvc_register_video(struct uvc_device *dev,
+ struct uvc_streaming *stream)
+{
+ int ret;
+
+ /* Initialize the streaming interface with default parameters. */
+ ret = uvc_video_init(stream);
+ if (ret < 0) {
+ uvc_printk(KERN_ERR, "Failed to initialize the device (%d).\n",
ret);
return ret;
}
else
stream->chain->caps |= V4L2_CAP_VIDEO_OUTPUT;
- kref_get(&dev->ref);
- return 0;
+ uvc_debugfs_init_stream(stream);
+
+ /* Register the device with V4L. */
+ return uvc_register_video_device(dev, stream, &stream->vdev,
+ &stream->queue, stream->type,
+ &uvc_fops, &uvc_ioctl_ops);
}
/*