Commit 83b09422 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

[media] au0828: add prio, control event and log_status support

Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Reviewed-by: default avatarDevin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent e8c26f45
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/suspend.h> #include <linux/suspend.h>
#include <media/v4l2-common.h> #include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h> #include <media/v4l2-ioctl.h>
#include <media/v4l2-event.h>
#include <media/v4l2-chip-ident.h> #include <media/v4l2-chip-ident.h>
#include <media/tuner.h> #include <media/tuner.h>
#include "au0828.h" #include "au0828.h"
...@@ -988,6 +989,7 @@ static int au0828_v4l2_open(struct file *filp) ...@@ -988,6 +989,7 @@ static int au0828_v4l2_open(struct file *filp)
fh->type = type; fh->type = type;
fh->dev = dev; fh->dev = dev;
v4l2_fh_init(&fh->fh, vdev);
filp->private_data = fh; filp->private_data = fh;
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
...@@ -1031,6 +1033,7 @@ static int au0828_v4l2_open(struct file *filp) ...@@ -1031,6 +1033,7 @@ static int au0828_v4l2_open(struct file *filp)
V4L2_FIELD_SEQ_TB, V4L2_FIELD_SEQ_TB,
sizeof(struct au0828_buffer), fh, sizeof(struct au0828_buffer), fh,
&dev->lock); &dev->lock);
v4l2_fh_add(&fh->fh);
return ret; return ret;
} }
...@@ -1040,6 +1043,8 @@ static int au0828_v4l2_close(struct file *filp) ...@@ -1040,6 +1043,8 @@ static int au0828_v4l2_close(struct file *filp)
struct au0828_fh *fh = filp->private_data; struct au0828_fh *fh = filp->private_data;
struct au0828_dev *dev = fh->dev; struct au0828_dev *dev = fh->dev;
v4l2_fh_del(&fh->fh);
v4l2_fh_exit(&fh->fh);
if (res_check(fh, AU0828_RESOURCE_VIDEO)) { if (res_check(fh, AU0828_RESOURCE_VIDEO)) {
/* Cancel timeout thread in case they didn't call streamoff */ /* Cancel timeout thread in case they didn't call streamoff */
dev->vid_timeout_running = 0; dev->vid_timeout_running = 0;
...@@ -1061,6 +1066,7 @@ static int au0828_v4l2_close(struct file *filp) ...@@ -1061,6 +1066,7 @@ static int au0828_v4l2_close(struct file *filp)
if (dev->users == 1) { if (dev->users == 1) {
if (dev->dev_state & DEV_DISCONNECTED) { if (dev->dev_state & DEV_DISCONNECTED) {
au0828_analog_unregister(dev); au0828_analog_unregister(dev);
kfree(fh);
kfree(dev); kfree(dev);
return 0; return 0;
} }
...@@ -1128,23 +1134,27 @@ static unsigned int au0828_v4l2_poll(struct file *filp, poll_table *wait) ...@@ -1128,23 +1134,27 @@ static unsigned int au0828_v4l2_poll(struct file *filp, poll_table *wait)
{ {
struct au0828_fh *fh = filp->private_data; struct au0828_fh *fh = filp->private_data;
struct au0828_dev *dev = fh->dev; struct au0828_dev *dev = fh->dev;
int rc; unsigned long req_events = poll_requested_events(wait);
unsigned int res;
rc = check_dev(dev); if (check_dev(dev) < 0)
if (rc < 0) return POLLERR;
return rc;
res = v4l2_ctrl_poll(filp, wait);
if (!(req_events & (POLLIN | POLLRDNORM)))
return res;
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
if (!res_get(fh, AU0828_RESOURCE_VIDEO)) if (!res_get(fh, AU0828_RESOURCE_VIDEO))
return POLLERR; return POLLERR;
return videobuf_poll_stream(filp, &fh->vb_vidq, wait); return res | videobuf_poll_stream(filp, &fh->vb_vidq, wait);
} else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { }
if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
if (!res_get(fh, AU0828_RESOURCE_VBI)) if (!res_get(fh, AU0828_RESOURCE_VBI))
return POLLERR; return POLLERR;
return videobuf_poll_stream(filp, &fh->vb_vbiq, wait); return res | videobuf_poll_stream(filp, &fh->vb_vbiq, wait);
} else {
return POLLERR;
} }
return POLLERR;
} }
static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
...@@ -1761,6 +1771,15 @@ static int vidioc_s_register(struct file *file, void *priv, ...@@ -1761,6 +1771,15 @@ static int vidioc_s_register(struct file *file, void *priv,
} }
#endif #endif
static int vidioc_log_status(struct file *file, void *fh)
{
struct video_device *vdev = video_devdata(file);
v4l2_ctrl_log_status(file, fh);
v4l2_device_call_all(vdev->v4l2_dev, 0, core, log_status);
return 0;
}
static int vidioc_reqbufs(struct file *file, void *priv, static int vidioc_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *rb) struct v4l2_requestbuffers *rb)
{ {
...@@ -1884,6 +1903,9 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { ...@@ -1884,6 +1903,9 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_s_register = vidioc_s_register, .vidioc_s_register = vidioc_s_register,
#endif #endif
.vidioc_g_chip_ident = vidioc_g_chip_ident, .vidioc_g_chip_ident = vidioc_g_chip_ident,
.vidioc_log_status = vidioc_log_status,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
}; };
static const struct video_device au0828_video_template = { static const struct video_device au0828_video_template = {
...@@ -1980,12 +2002,14 @@ int au0828_analog_register(struct au0828_dev *dev, ...@@ -1980,12 +2002,14 @@ int au0828_analog_register(struct au0828_dev *dev,
*dev->vdev = au0828_video_template; *dev->vdev = au0828_video_template;
dev->vdev->v4l2_dev = &dev->v4l2_dev; dev->vdev->v4l2_dev = &dev->v4l2_dev;
dev->vdev->lock = &dev->lock; dev->vdev->lock = &dev->lock;
set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev->flags);
strcpy(dev->vdev->name, "au0828a video"); strcpy(dev->vdev->name, "au0828a video");
/* Setup the VBI device */ /* Setup the VBI device */
*dev->vbi_dev = au0828_video_template; *dev->vbi_dev = au0828_video_template;
dev->vbi_dev->v4l2_dev = &dev->v4l2_dev; dev->vbi_dev->v4l2_dev = &dev->v4l2_dev;
dev->vbi_dev->lock = &dev->lock; dev->vbi_dev->lock = &dev->lock;
set_bit(V4L2_FL_USE_FH_PRIO, &dev->vbi_dev->flags);
strcpy(dev->vbi_dev->name, "au0828a vbi"); strcpy(dev->vbi_dev->name, "au0828a vbi");
/* Register the v4l2 device */ /* Register the v4l2 device */
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <media/videobuf-vmalloc.h> #include <media/videobuf-vmalloc.h>
#include <media/v4l2-device.h> #include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h> #include <media/v4l2-ctrls.h>
#include <media/v4l2-fh.h>
/* DVB */ /* DVB */
#include "demux.h" #include "demux.h"
...@@ -119,6 +120,9 @@ enum au0828_dev_state { ...@@ -119,6 +120,9 @@ enum au0828_dev_state {
}; };
struct au0828_fh { struct au0828_fh {
/* must be the first field of this struct! */
struct v4l2_fh fh;
struct au0828_dev *dev; struct au0828_dev *dev;
unsigned int resources; unsigned int resources;
......
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