aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2010-03-27 13:10:13 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-19 11:58:08 -0400
commit092501936fc128992456a086193746cf34642815 (patch)
tree6a6910b3fd4f9a1304adfb5af1a4e7a96085960d /drivers/media/video/ivtv
parent1bcaf4bd53872e70c4fceec6bbb76044325f337f (diff)
V4L/DVB: ivtv: support the new events API
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/ivtv')
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h7
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c53
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c24
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c15
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c5
5 files changed, 87 insertions, 17 deletions
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 851f07de5296..5b45fd2b2645 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -63,6 +63,7 @@
63#include <media/v4l2-common.h> 63#include <media/v4l2-common.h>
64#include <media/v4l2-ioctl.h> 64#include <media/v4l2-ioctl.h>
65#include <media/v4l2-device.h> 65#include <media/v4l2-device.h>
66#include <media/v4l2-fh.h>
66#include <media/tuner.h> 67#include <media/tuner.h>
67#include <media/cx2341x.h> 68#include <media/cx2341x.h>
68#include <media/ir-kbd-i2c.h> 69#include <media/ir-kbd-i2c.h>
@@ -375,6 +376,7 @@ struct ivtv_stream {
375}; 376};
376 377
377struct ivtv_open_id { 378struct ivtv_open_id {
379 struct v4l2_fh fh;
378 u32 open_id; /* unique ID for this file descriptor */ 380 u32 open_id; /* unique ID for this file descriptor */
379 int type; /* stream type */ 381 int type; /* stream type */
380 int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */ 382 int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */
@@ -382,6 +384,11 @@ struct ivtv_open_id {
382 struct ivtv *itv; 384 struct ivtv *itv;
383}; 385};
384 386
387static inline struct ivtv_open_id *fh2id(struct v4l2_fh *fh)
388{
389 return container_of(fh, struct ivtv_open_id, fh);
390}
391
385struct yuv_frame_info 392struct yuv_frame_info
386{ 393{
387 u32 update; 394 u32 update;
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index babcabd73c08..bee9605bd273 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -32,6 +32,7 @@
32#include "ivtv-yuv.h" 32#include "ivtv-yuv.h"
33#include "ivtv-ioctl.h" 33#include "ivtv-ioctl.h"
34#include "ivtv-cards.h" 34#include "ivtv-cards.h"
35#include <media/v4l2-event.h>
35#include <media/saa7115.h> 36#include <media/saa7115.h>
36 37
37/* This function tries to claim the stream for a specific file descriptor. 38/* This function tries to claim the stream for a specific file descriptor.
@@ -506,7 +507,7 @@ int ivtv_start_capture(struct ivtv_open_id *id)
506 507
507ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_t * pos) 508ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_t * pos)
508{ 509{
509 struct ivtv_open_id *id = filp->private_data; 510 struct ivtv_open_id *id = fh2id(filp->private_data);
510 struct ivtv *itv = id->itv; 511 struct ivtv *itv = id->itv;
511 struct ivtv_stream *s = &itv->streams[id->type]; 512 struct ivtv_stream *s = &itv->streams[id->type];
512 int rc; 513 int rc;
@@ -541,7 +542,7 @@ int ivtv_start_decoding(struct ivtv_open_id *id, int speed)
541 542
542ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos) 543ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos)
543{ 544{
544 struct ivtv_open_id *id = filp->private_data; 545 struct ivtv_open_id *id = fh2id(filp->private_data);
545 struct ivtv *itv = id->itv; 546 struct ivtv *itv = id->itv;
546 struct ivtv_stream *s = &itv->streams[id->type]; 547 struct ivtv_stream *s = &itv->streams[id->type];
547 struct yuv_playback_info *yi = &itv->yuv_info; 548 struct yuv_playback_info *yi = &itv->yuv_info;
@@ -711,19 +712,31 @@ retry:
711 712
712unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait) 713unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait)
713{ 714{
714 struct ivtv_open_id *id = filp->private_data; 715 struct ivtv_open_id *id = fh2id(filp->private_data);
715 struct ivtv *itv = id->itv; 716 struct ivtv *itv = id->itv;
716 struct ivtv_stream *s = &itv->streams[id->type]; 717 struct ivtv_stream *s = &itv->streams[id->type];
717 int res = 0; 718 int res = 0;
718 719
719 /* add stream's waitq to the poll list */ 720 /* add stream's waitq to the poll list */
720 IVTV_DEBUG_HI_FILE("Decoder poll\n"); 721 IVTV_DEBUG_HI_FILE("Decoder poll\n");
721 poll_wait(filp, &s->waitq, wait);
722 722
723 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags); 723 /* If there are subscribed events, then only use the new event
724 if (test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags) || 724 API instead of the old video.h based API. */
725 test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags)) 725 if (!list_empty(&id->fh.events->subscribed)) {
726 res = POLLPRI; 726 poll_wait(filp, &id->fh.events->wait, wait);
727 /* Turn off the old-style vsync events */
728 clear_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
729 if (v4l2_event_pending(&id->fh))
730 res = POLLPRI;
731 } else {
732 /* This is the old-style API which is here only for backwards
733 compatibility. */
734 poll_wait(filp, &s->waitq, wait);
735 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
736 if (test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags) ||
737 test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
738 res = POLLPRI;
739 }
727 740
728 /* Allow write if buffers are available for writing */ 741 /* Allow write if buffers are available for writing */
729 if (s->q_free.buffers) 742 if (s->q_free.buffers)
@@ -733,7 +746,7 @@ unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait)
733 746
734unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait) 747unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait)
735{ 748{
736 struct ivtv_open_id *id = filp->private_data; 749 struct ivtv_open_id *id = fh2id(filp->private_data);
737 struct ivtv *itv = id->itv; 750 struct ivtv *itv = id->itv;
738 struct ivtv_stream *s = &itv->streams[id->type]; 751 struct ivtv_stream *s = &itv->streams[id->type];
739 int eof = test_bit(IVTV_F_S_STREAMOFF, &s->s_flags); 752 int eof = test_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
@@ -833,13 +846,16 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
833 846
834int ivtv_v4l2_close(struct file *filp) 847int ivtv_v4l2_close(struct file *filp)
835{ 848{
836 struct ivtv_open_id *id = filp->private_data; 849 struct v4l2_fh *fh = filp->private_data;
850 struct ivtv_open_id *id = fh2id(fh);
837 struct ivtv *itv = id->itv; 851 struct ivtv *itv = id->itv;
838 struct ivtv_stream *s = &itv->streams[id->type]; 852 struct ivtv_stream *s = &itv->streams[id->type];
839 853
840 IVTV_DEBUG_FILE("close %s\n", s->name); 854 IVTV_DEBUG_FILE("close %s\n", s->name);
841 855
842 v4l2_prio_close(&itv->prio, &id->prio); 856 v4l2_prio_close(&itv->prio, &id->prio);
857 v4l2_fh_del(fh);
858 v4l2_fh_exit(fh);
843 859
844 /* Easy case first: this stream was never claimed by us */ 860 /* Easy case first: this stream was never claimed by us */
845 if (s->id != id->open_id) { 861 if (s->id != id->open_id) {
@@ -895,6 +911,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
895{ 911{
896 struct ivtv *itv = s->itv; 912 struct ivtv *itv = s->itv;
897 struct ivtv_open_id *item; 913 struct ivtv_open_id *item;
914 int res = 0;
898 915
899 IVTV_DEBUG_FILE("open %s\n", s->name); 916 IVTV_DEBUG_FILE("open %s\n", s->name);
900 917
@@ -915,17 +932,27 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
915 } 932 }
916 933
917 /* Allocate memory */ 934 /* Allocate memory */
918 item = kmalloc(sizeof(struct ivtv_open_id), GFP_KERNEL); 935 item = kzalloc(sizeof(struct ivtv_open_id), GFP_KERNEL);
919 if (NULL == item) { 936 if (NULL == item) {
920 IVTV_DEBUG_WARN("nomem on v4l2 open\n"); 937 IVTV_DEBUG_WARN("nomem on v4l2 open\n");
921 return -ENOMEM; 938 return -ENOMEM;
922 } 939 }
940 v4l2_fh_init(&item->fh, s->vdev);
941 if (s->type == IVTV_DEC_STREAM_TYPE_YUV ||
942 s->type == IVTV_DEC_STREAM_TYPE_MPG) {
943 res = v4l2_event_alloc(&item->fh, 60);
944 }
945 if (res < 0) {
946 v4l2_fh_exit(&item->fh);
947 kfree(item);
948 return res;
949 }
923 item->itv = itv; 950 item->itv = itv;
924 item->type = s->type; 951 item->type = s->type;
925 v4l2_prio_open(&itv->prio, &item->prio); 952 v4l2_prio_open(&itv->prio, &item->prio);
926 953
927 item->open_id = itv->open_id++; 954 item->open_id = itv->open_id++;
928 filp->private_data = item; 955 filp->private_data = &item->fh;
929 956
930 if (item->type == IVTV_ENC_STREAM_TYPE_RAD) { 957 if (item->type == IVTV_ENC_STREAM_TYPE_RAD) {
931 /* Try to claim this stream */ 958 /* Try to claim this stream */
@@ -940,6 +967,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
940 /* switching to radio while capture is 967 /* switching to radio while capture is
941 in progress is not polite */ 968 in progress is not polite */
942 ivtv_release_stream(s); 969 ivtv_release_stream(s);
970 v4l2_fh_exit(&item->fh);
943 kfree(item); 971 kfree(item);
944 return -EBUSY; 972 return -EBUSY;
945 } 973 }
@@ -970,6 +998,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
970 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31); 998 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
971 itv->yuv_info.stream_size = 0; 999 itv->yuv_info.stream_size = 0;
972 } 1000 }
1001 v4l2_fh_add(&item->fh);
973 return 0; 1002 return 0;
974} 1003}
975 1004
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 6422cf8f189d..e95ebdeaa72f 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -35,6 +35,7 @@
35#include <media/saa7127.h> 35#include <media/saa7127.h>
36#include <media/tveeprom.h> 36#include <media/tveeprom.h>
37#include <media/v4l2-chip-ident.h> 37#include <media/v4l2-chip-ident.h>
38#include <media/v4l2-event.h>
38#include <linux/dvb/audio.h> 39#include <linux/dvb/audio.h>
39#include <linux/i2c-id.h> 40#include <linux/i2c-id.h>
40 41
@@ -1452,6 +1453,18 @@ static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1452 return 0; 1453 return 0;
1453} 1454}
1454 1455
1456static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscription *sub)
1457{
1458 switch (sub->type) {
1459 case V4L2_EVENT_VSYNC:
1460 case V4L2_EVENT_EOS:
1461 break;
1462 default:
1463 return -EINVAL;
1464 }
1465 return v4l2_event_subscribe(fh, sub);
1466}
1467
1455static int ivtv_log_status(struct file *file, void *fh) 1468static int ivtv_log_status(struct file *file, void *fh)
1456{ 1469{
1457 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1470 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
@@ -1560,7 +1573,7 @@ static int ivtv_log_status(struct file *file, void *fh)
1560 1573
1561static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) 1574static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
1562{ 1575{
1563 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; 1576 struct ivtv_open_id *id = fh2id(filp->private_data);
1564 struct ivtv *itv = id->itv; 1577 struct ivtv *itv = id->itv;
1565 int nonblocking = filp->f_flags & O_NONBLOCK; 1578 int nonblocking = filp->f_flags & O_NONBLOCK;
1566 struct ivtv_stream *s = &itv->streams[id->type]; 1579 struct ivtv_stream *s = &itv->streams[id->type];
@@ -1820,7 +1833,7 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
1820 unsigned int cmd, unsigned long arg) 1833 unsigned int cmd, unsigned long arg)
1821{ 1834{
1822 struct video_device *vfd = video_devdata(filp); 1835 struct video_device *vfd = video_devdata(filp);
1823 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; 1836 struct ivtv_open_id *id = fh2id(filp->private_data);
1824 long ret; 1837 long ret;
1825 1838
1826 /* check priority */ 1839 /* check priority */
@@ -1852,10 +1865,13 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
1852 1865
1853long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 1866long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1854{ 1867{
1855 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; 1868 struct ivtv_open_id *id = fh2id(filp->private_data);
1856 struct ivtv *itv = id->itv; 1869 struct ivtv *itv = id->itv;
1857 long res; 1870 long res;
1858 1871
1872 /* DQEVENT can block, so this should not run with the serialize lock */
1873 if (cmd == VIDIOC_DQEVENT)
1874 return ivtv_serialized_ioctl(itv, filp, cmd, arg);
1859 mutex_lock(&itv->serialize_lock); 1875 mutex_lock(&itv->serialize_lock);
1860 res = ivtv_serialized_ioctl(itv, filp, cmd, arg); 1876 res = ivtv_serialized_ioctl(itv, filp, cmd, arg);
1861 mutex_unlock(&itv->serialize_lock); 1877 mutex_unlock(&itv->serialize_lock);
@@ -1926,6 +1942,8 @@ static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1926 .vidioc_g_ext_ctrls = ivtv_g_ext_ctrls, 1942 .vidioc_g_ext_ctrls = ivtv_g_ext_ctrls,
1927 .vidioc_s_ext_ctrls = ivtv_s_ext_ctrls, 1943 .vidioc_s_ext_ctrls = ivtv_s_ext_ctrls,
1928 .vidioc_try_ext_ctrls = ivtv_try_ext_ctrls, 1944 .vidioc_try_ext_ctrls = ivtv_try_ext_ctrls,
1945 .vidioc_subscribe_event = ivtv_subscribe_event,
1946 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1929}; 1947};
1930 1948
1931void ivtv_set_funcs(struct video_device *vdev) 1949void ivtv_set_funcs(struct video_device *vdev)
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index dbd46c5d6975..fea1ec33b0df 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -25,6 +25,7 @@
25#include "ivtv-mailbox.h" 25#include "ivtv-mailbox.h"
26#include "ivtv-vbi.h" 26#include "ivtv-vbi.h"
27#include "ivtv-yuv.h" 27#include "ivtv-yuv.h"
28#include <media/v4l2-event.h>
28 29
29#define DMA_MAGIC_COOKIE 0x000001fe 30#define DMA_MAGIC_COOKIE 0x000001fe
30 31
@@ -778,6 +779,14 @@ static void ivtv_irq_vsync(struct ivtv *itv)
778 } 779 }
779 } 780 }
780 if (frame != (itv->last_vsync_field & 1)) { 781 if (frame != (itv->last_vsync_field & 1)) {
782 static const struct v4l2_event evtop = {
783 .type = V4L2_EVENT_VSYNC,
784 .u.vsync.field = V4L2_FIELD_TOP,
785 };
786 static const struct v4l2_event evbottom = {
787 .type = V4L2_EVENT_VSYNC,
788 .u.vsync.field = V4L2_FIELD_BOTTOM,
789 };
781 struct ivtv_stream *s = ivtv_get_output_stream(itv); 790 struct ivtv_stream *s = ivtv_get_output_stream(itv);
782 791
783 itv->last_vsync_field += 1; 792 itv->last_vsync_field += 1;
@@ -791,10 +800,12 @@ static void ivtv_irq_vsync(struct ivtv *itv)
791 if (test_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags)) { 800 if (test_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags)) {
792 set_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags); 801 set_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags);
793 wake_up(&itv->event_waitq); 802 wake_up(&itv->event_waitq);
803 if (s)
804 wake_up(&s->waitq);
794 } 805 }
806 if (s && s->vdev)
807 v4l2_event_queue(s->vdev, frame ? &evtop : &evbottom);
795 wake_up(&itv->vsync_waitq); 808 wake_up(&itv->vsync_waitq);
796 if (s)
797 wake_up(&s->waitq);
798 809
799 /* Send VBI to saa7127 */ 810 /* Send VBI to saa7127 */
800 if (frame && (itv->output_mode == OUT_PASSTHROUGH || 811 if (frame && (itv->output_mode == OUT_PASSTHROUGH ||
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 6917c497fb7e..def507ee106a 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -42,6 +42,7 @@
42#include "ivtv-yuv.h" 42#include "ivtv-yuv.h"
43#include "ivtv-cards.h" 43#include "ivtv-cards.h"
44#include "ivtv-streams.h" 44#include "ivtv-streams.h"
45#include <media/v4l2-event.h>
45 46
46static const struct v4l2_file_operations ivtv_v4l2_enc_fops = { 47static const struct v4l2_file_operations ivtv_v4l2_enc_fops = {
47 .owner = THIS_MODULE, 48 .owner = THIS_MODULE,
@@ -840,6 +841,9 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
840 841
841int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) 842int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
842{ 843{
844 static const struct v4l2_event ev = {
845 .type = V4L2_EVENT_EOS,
846 };
843 struct ivtv *itv = s->itv; 847 struct ivtv *itv = s->itv;
844 848
845 if (s->vdev == NULL) 849 if (s->vdev == NULL)
@@ -891,6 +895,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
891 895
892 set_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags); 896 set_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags);
893 wake_up(&itv->event_waitq); 897 wake_up(&itv->event_waitq);
898 v4l2_event_queue(s->vdev, &ev);
894 899
895 /* wake up wait queues */ 900 /* wake up wait queues */
896 wake_up(&s->waitq); 901 wake_up(&s->waitq);