aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/tm6000
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-09-11 10:50:37 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-02-05 15:31:33 -0500
commit770056c47fbb5c4d892d1cd55ae5ec68cf44c2b4 (patch)
tree674919c0d81c9ff58900fbc1313ea1e8ccc623cd /drivers/media/usb/tm6000
parent9f7473592bd2c8d73657dcc1644de4ab610b0d90 (diff)
[media] tm6000: add support for control events and prio handling
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb/tm6000')
-rw-r--r--drivers/media/usb/tm6000/tm6000-video.c31
-rw-r--r--drivers/media/usb/tm6000/tm6000.h2
2 files changed, 25 insertions, 8 deletions
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c
index 4329fbcf2de2..25202a71d65e 100644
--- a/drivers/media/usb/tm6000/tm6000-video.c
+++ b/drivers/media/usb/tm6000/tm6000-video.c
@@ -34,6 +34,7 @@
34#include <linux/usb.h> 34#include <linux/usb.h>
35#include <linux/videodev2.h> 35#include <linux/videodev2.h>
36#include <media/v4l2-ioctl.h> 36#include <media/v4l2-ioctl.h>
37#include <media/v4l2-event.h>
37#include <media/tuner.h> 38#include <media/tuner.h>
38#include <linux/interrupt.h> 39#include <linux/interrupt.h>
39#include <linux/kthread.h> 40#include <linux/kthread.h>
@@ -1350,6 +1351,7 @@ static int __tm6000_open(struct file *file)
1350 return -ENOMEM; 1351 return -ENOMEM;
1351 } 1352 }
1352 1353
1354 v4l2_fh_init(&fh->fh, vdev);
1353 file->private_data = fh; 1355 file->private_data = fh;
1354 fh->dev = dev; 1356 fh->dev = dev;
1355 fh->radio = radio; 1357 fh->radio = radio;
@@ -1393,6 +1395,7 @@ static int __tm6000_open(struct file *file)
1393 tm6000_prepare_isoc(dev); 1395 tm6000_prepare_isoc(dev);
1394 tm6000_start_thread(dev); 1396 tm6000_start_thread(dev);
1395 } 1397 }
1398 v4l2_fh_add(&fh->fh);
1396 1399
1397 return 0; 1400 return 0;
1398} 1401}
@@ -1433,29 +1436,35 @@ tm6000_read(struct file *file, char __user *data, size_t count, loff_t *pos)
1433static unsigned int 1436static unsigned int
1434__tm6000_poll(struct file *file, struct poll_table_struct *wait) 1437__tm6000_poll(struct file *file, struct poll_table_struct *wait)
1435{ 1438{
1439 unsigned long req_events = poll_requested_events(wait);
1436 struct tm6000_fh *fh = file->private_data; 1440 struct tm6000_fh *fh = file->private_data;
1437 struct tm6000_buffer *buf; 1441 struct tm6000_buffer *buf;
1442 int res = 0;
1438 1443
1444 if (v4l2_event_pending(&fh->fh))
1445 res = POLLPRI;
1446 else if (req_events & POLLPRI)
1447 poll_wait(file, &fh->fh.wait, wait);
1439 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) 1448 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1440 return POLLERR; 1449 return res | POLLERR;
1441 1450
1442 if (!!is_res_streaming(fh->dev, fh)) 1451 if (!!is_res_streaming(fh->dev, fh))
1443 return POLLERR; 1452 return res | POLLERR;
1444 1453
1445 if (!is_res_read(fh->dev, fh)) { 1454 if (!is_res_read(fh->dev, fh)) {
1446 /* streaming capture */ 1455 /* streaming capture */
1447 if (list_empty(&fh->vb_vidq.stream)) 1456 if (list_empty(&fh->vb_vidq.stream))
1448 return POLLERR; 1457 return res | POLLERR;
1449 buf = list_entry(fh->vb_vidq.stream.next, struct tm6000_buffer, vb.stream); 1458 buf = list_entry(fh->vb_vidq.stream.next, struct tm6000_buffer, vb.stream);
1450 } else { 1459 } else if (req_events & (POLLIN | POLLRDNORM)) {
1451 /* read() capture */ 1460 /* read() capture */
1452 return videobuf_poll_stream(file, &fh->vb_vidq, wait); 1461 return res | videobuf_poll_stream(file, &fh->vb_vidq, wait);
1453 } 1462 }
1454 poll_wait(file, &buf->vb.done, wait); 1463 poll_wait(file, &buf->vb.done, wait);
1455 if (buf->vb.state == VIDEOBUF_DONE || 1464 if (buf->vb.state == VIDEOBUF_DONE ||
1456 buf->vb.state == VIDEOBUF_ERROR) 1465 buf->vb.state == VIDEOBUF_ERROR)
1457 return POLLIN | POLLRDNORM; 1466 return res | POLLIN | POLLRDNORM;
1458 return 0; 1467 return res;
1459} 1468}
1460 1469
1461static unsigned int tm6000_poll(struct file *file, struct poll_table_struct *wait) 1470static unsigned int tm6000_poll(struct file *file, struct poll_table_struct *wait)
@@ -1505,7 +1514,8 @@ static int tm6000_release(struct file *file)
1505 if (!fh->radio) 1514 if (!fh->radio)
1506 videobuf_mmap_free(&fh->vb_vidq); 1515 videobuf_mmap_free(&fh->vb_vidq);
1507 } 1516 }
1508 1517 v4l2_fh_del(&fh->fh);
1518 v4l2_fh_exit(&fh->fh);
1509 kfree(fh); 1519 kfree(fh);
1510 mutex_unlock(&dev->lock); 1520 mutex_unlock(&dev->lock);
1511 1521
@@ -1555,6 +1565,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
1555 .vidioc_querybuf = vidioc_querybuf, 1565 .vidioc_querybuf = vidioc_querybuf,
1556 .vidioc_qbuf = vidioc_qbuf, 1566 .vidioc_qbuf = vidioc_qbuf,
1557 .vidioc_dqbuf = vidioc_dqbuf, 1567 .vidioc_dqbuf = vidioc_dqbuf,
1568 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1569 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1558}; 1570};
1559 1571
1560static struct video_device tm6000_template = { 1572static struct video_device tm6000_template = {
@@ -1579,6 +1591,8 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = {
1579 .vidioc_s_tuner = radio_s_tuner, 1591 .vidioc_s_tuner = radio_s_tuner,
1580 .vidioc_g_frequency = vidioc_g_frequency, 1592 .vidioc_g_frequency = vidioc_g_frequency,
1581 .vidioc_s_frequency = vidioc_s_frequency, 1593 .vidioc_s_frequency = vidioc_s_frequency,
1594 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1595 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1582}; 1596};
1583 1597
1584static struct video_device tm6000_radio_template = { 1598static struct video_device tm6000_radio_template = {
@@ -1607,6 +1621,7 @@ static struct video_device *vdev_init(struct tm6000_core *dev,
1607 vfd->release = video_device_release; 1621 vfd->release = video_device_release;
1608 vfd->debug = tm6000_debug; 1622 vfd->debug = tm6000_debug;
1609 vfd->lock = &dev->lock; 1623 vfd->lock = &dev->lock;
1624 set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
1610 1625
1611 snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); 1626 snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);
1612 1627
diff --git a/drivers/media/usb/tm6000/tm6000.h b/drivers/media/usb/tm6000/tm6000.h
index a9ac262fcc93..08bd0740dd23 100644
--- a/drivers/media/usb/tm6000/tm6000.h
+++ b/drivers/media/usb/tm6000/tm6000.h
@@ -28,6 +28,7 @@
28#include <linux/mutex.h> 28#include <linux/mutex.h>
29#include <media/v4l2-device.h> 29#include <media/v4l2-device.h>
30#include <media/v4l2-ctrls.h> 30#include <media/v4l2-ctrls.h>
31#include <media/v4l2-fh.h>
31 32
32#include <linux/dvb/frontend.h> 33#include <linux/dvb/frontend.h>
33#include "dvb_demux.h" 34#include "dvb_demux.h"
@@ -290,6 +291,7 @@ struct tm6000_ops {
290}; 291};
291 292
292struct tm6000_fh { 293struct tm6000_fh {
294 struct v4l2_fh fh;
293 struct tm6000_core *dev; 295 struct tm6000_core *dev;
294 unsigned int radio; 296 unsigned int radio;
295 297