Commit 76ae8538 authored by Hans de Goede's avatar Hans de Goede Committed by Mauro Carvalho Chehab

[media] pwc: Use v4l2-device and v4l2-fh

This is a preperation patch for adding support for control events. Actually
enabling support for control events will be done in a separate patch, as that
depends on the necessary poll changes going upstream
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent ee186fd9
...@@ -144,17 +144,15 @@ static struct { ...@@ -144,17 +144,15 @@ static struct {
/***/ /***/
static int pwc_video_open(struct file *file);
static int pwc_video_close(struct file *file); static int pwc_video_close(struct file *file);
static ssize_t pwc_video_read(struct file *file, char __user *buf, static ssize_t pwc_video_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos); size_t count, loff_t *ppos);
static unsigned int pwc_video_poll(struct file *file, poll_table *wait); static unsigned int pwc_video_poll(struct file *file, poll_table *wait);
static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma);
static void pwc_video_release(struct video_device *vfd);
static const struct v4l2_file_operations pwc_fops = { static const struct v4l2_file_operations pwc_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = pwc_video_open, .open = v4l2_fh_open,
.release = pwc_video_close, .release = pwc_video_close,
.read = pwc_video_read, .read = pwc_video_read,
.poll = pwc_video_poll, .poll = pwc_video_poll,
...@@ -163,7 +161,7 @@ static const struct v4l2_file_operations pwc_fops = { ...@@ -163,7 +161,7 @@ static const struct v4l2_file_operations pwc_fops = {
}; };
static struct video_device pwc_template = { static struct video_device pwc_template = {
.name = "Philips Webcam", /* Filled in later */ .name = "Philips Webcam", /* Filled in later */
.release = pwc_video_release, .release = video_device_release_empty,
.fops = &pwc_fops, .fops = &pwc_fops,
.ioctl_ops = &pwc_ioctl_ops, .ioctl_ops = &pwc_ioctl_ops,
}; };
...@@ -644,25 +642,9 @@ static const char *pwc_sensor_type_to_string(unsigned int sensor_type) ...@@ -644,25 +642,9 @@ static const char *pwc_sensor_type_to_string(unsigned int sensor_type)
/***************************************************************************/ /***************************************************************************/
/* Video4Linux functions */ /* Video4Linux functions */
static int pwc_video_open(struct file *file) static void pwc_video_release(struct v4l2_device *v)
{ {
struct video_device *vdev = video_devdata(file); struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
struct pwc_device *pdev;
PWC_DEBUG_OPEN(">> video_open called(vdev = 0x%p).\n", vdev);
pdev = video_get_drvdata(vdev);
if (!pdev->udev)
return -ENODEV;
file->private_data = vdev;
PWC_DEBUG_OPEN("<< video_open() returns 0.\n");
return 0;
}
static void pwc_video_release(struct video_device *vfd)
{
struct pwc_device *pdev = container_of(vfd, struct pwc_device, vdev);
int hint; int hint;
/* search device_hint[] table if we occupy a slot, by any chance */ /* search device_hint[] table if we occupy a slot, by any chance */
...@@ -685,26 +667,19 @@ static void pwc_video_release(struct video_device *vfd) ...@@ -685,26 +667,19 @@ static void pwc_video_release(struct video_device *vfd)
static int pwc_video_close(struct file *file) static int pwc_video_close(struct file *file)
{ {
struct video_device *vdev = file->private_data; struct pwc_device *pdev = video_drvdata(file);
struct pwc_device *pdev;
PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
pdev = video_get_drvdata(vdev);
if (pdev->capt_file == file) { if (pdev->capt_file == file) {
vb2_queue_release(&pdev->vb_queue); vb2_queue_release(&pdev->vb_queue);
pdev->capt_file = NULL; pdev->capt_file = NULL;
} }
return v4l2_fh_release(file);
PWC_DEBUG_OPEN("<< video_close()\n");
return 0;
} }
static ssize_t pwc_video_read(struct file *file, char __user *buf, static ssize_t pwc_video_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct video_device *vdev = file->private_data; struct pwc_device *pdev = video_drvdata(file);
struct pwc_device *pdev = video_get_drvdata(vdev);
if (!pdev->udev) if (!pdev->udev)
return -ENODEV; return -ENODEV;
...@@ -721,8 +696,7 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf, ...@@ -721,8 +696,7 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
static unsigned int pwc_video_poll(struct file *file, poll_table *wait) static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
{ {
struct video_device *vdev = file->private_data; struct pwc_device *pdev = video_drvdata(file);
struct pwc_device *pdev = video_get_drvdata(vdev);
if (!pdev->udev) if (!pdev->udev)
return POLL_ERR; return POLL_ERR;
...@@ -732,8 +706,7 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait) ...@@ -732,8 +706,7 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
{ {
struct video_device *vdev = file->private_data; struct pwc_device *pdev = video_drvdata(file);
struct pwc_device *pdev = video_get_drvdata(vdev);
if (pdev->capt_file != file) if (pdev->capt_file != file)
return -EBUSY; return -EBUSY;
...@@ -1185,9 +1158,9 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id ...@@ -1185,9 +1158,9 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
/* Init video_device structure */ /* Init video_device structure */
memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template)); memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template));
pdev->vdev.parent = &intf->dev;
pdev->vdev.lock = &pdev->modlock; pdev->vdev.lock = &pdev->modlock;
strcpy(pdev->vdev.name, name); strcpy(pdev->vdev.name, name);
set_bit(V4L2_FL_USE_FH_PRIO, &pdev->vdev.flags);
video_set_drvdata(&pdev->vdev, pdev); video_set_drvdata(&pdev->vdev, pdev);
pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
...@@ -1211,9 +1184,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id ...@@ -1211,9 +1184,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
if (hint < MAX_DEV_HINTS) if (hint < MAX_DEV_HINTS)
device_hint[hint].pdev = pdev; device_hint[hint].pdev = pdev;
PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev);
usb_set_intfdata(intf, pdev);
#ifdef CONFIG_USB_PWC_DEBUG #ifdef CONFIG_USB_PWC_DEBUG
/* Query sensor type */ /* Query sensor type */
if (pwc_get_cmos_sensor(pdev, &rc) >= 0) { if (pwc_get_cmos_sensor(pdev, &rc) >= 0) {
...@@ -1239,15 +1209,24 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id ...@@ -1239,15 +1209,24 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
goto err_free_mem; goto err_free_mem;
} }
pdev->vdev.ctrl_handler = &pdev->ctrl_handler;
/* And powerdown the camera until streaming starts */ /* And powerdown the camera until streaming starts */
pwc_camera_power(pdev, 0); pwc_camera_power(pdev, 0);
/* Register the v4l2_device structure */
pdev->v4l2_dev.release = pwc_video_release;
rc = v4l2_device_register(&intf->dev, &pdev->v4l2_dev);
if (rc) {
PWC_ERROR("Failed to register v4l2-device (%d).\n", rc);
goto err_free_controls;
}
pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler;
pdev->vdev.v4l2_dev = &pdev->v4l2_dev;
rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr); rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr);
if (rc < 0) { if (rc < 0) {
PWC_ERROR("Failed to register as video device (%d).\n", rc); PWC_ERROR("Failed to register as video device (%d).\n", rc);
goto err_free_controls; goto err_unregister_v4l2_dev;
} }
rc = pwc_create_sysfs_files(pdev); rc = pwc_create_sysfs_files(pdev);
if (rc) if (rc)
...@@ -1290,10 +1269,11 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id ...@@ -1290,10 +1269,11 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
if (hint < MAX_DEV_HINTS) if (hint < MAX_DEV_HINTS)
device_hint[hint].pdev = NULL; device_hint[hint].pdev = NULL;
video_unregister_device(&pdev->vdev); video_unregister_device(&pdev->vdev);
err_unregister_v4l2_dev:
v4l2_device_unregister(&pdev->v4l2_dev);
err_free_controls: err_free_controls:
v4l2_ctrl_handler_free(&pdev->ctrl_handler); v4l2_ctrl_handler_free(&pdev->ctrl_handler);
err_free_mem: err_free_mem:
usb_set_intfdata(intf, NULL);
kfree(pdev); kfree(pdev);
return rc; return rc;
} }
...@@ -1301,12 +1281,12 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id ...@@ -1301,12 +1281,12 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
/* The user yanked out the cable... */ /* The user yanked out the cable... */
static void usb_pwc_disconnect(struct usb_interface *intf) static void usb_pwc_disconnect(struct usb_interface *intf)
{ {
struct pwc_device *pdev = usb_get_intfdata(intf); struct v4l2_device *v = usb_get_intfdata(intf);
struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
mutex_lock(&pdev->udevlock); mutex_lock(&pdev->udevlock);
mutex_lock(&pdev->modlock); mutex_lock(&pdev->modlock);
usb_set_intfdata(intf, NULL);
/* No need to keep the urbs around after disconnection */ /* No need to keep the urbs around after disconnection */
pwc_isoc_cleanup(pdev); pwc_isoc_cleanup(pdev);
pwc_cleanup_queued_bufs(pdev); pwc_cleanup_queued_bufs(pdev);
...@@ -1317,11 +1297,14 @@ static void usb_pwc_disconnect(struct usb_interface *intf) ...@@ -1317,11 +1297,14 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
pwc_remove_sysfs_files(pdev); pwc_remove_sysfs_files(pdev);
video_unregister_device(&pdev->vdev); video_unregister_device(&pdev->vdev);
v4l2_device_unregister(&pdev->v4l2_dev);
#ifdef CONFIG_USB_PWC_INPUT_EVDEV #ifdef CONFIG_USB_PWC_INPUT_EVDEV
if (pdev->button_dev) if (pdev->button_dev)
input_unregister_device(pdev->button_dev); input_unregister_device(pdev->button_dev);
#endif #endif
v4l2_device_put(&pdev->v4l2_dev);
} }
......
...@@ -35,8 +35,11 @@ ...@@ -35,8 +35,11 @@
#include <asm/errno.h> #include <asm/errno.h>
#include <linux/videodev2.h> #include <linux/videodev2.h>
#include <media/v4l2-common.h> #include <media/v4l2-common.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h> #include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h> #include <media/v4l2-ctrls.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-event.h>
#include <media/videobuf2-vmalloc.h> #include <media/videobuf2-vmalloc.h>
#ifdef CONFIG_USB_PWC_INPUT_EVDEV #ifdef CONFIG_USB_PWC_INPUT_EVDEV
#include <linux/input.h> #include <linux/input.h>
...@@ -198,6 +201,7 @@ struct pwc_frame_buf ...@@ -198,6 +201,7 @@ struct pwc_frame_buf
struct pwc_device struct pwc_device
{ {
struct video_device vdev; struct video_device vdev;
struct v4l2_device v4l2_dev;
struct mutex modlock; struct mutex modlock;
/* Pointer to our usb_device, may be NULL after unplug */ /* Pointer to our usb_device, may be NULL after unplug */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment