aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/au0828/au0828-video.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/au0828/au0828-video.c')
-rw-r--r--drivers/media/video/au0828/au0828-video.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 20ba5915542f..8d11e544c879 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -312,6 +312,9 @@ static inline void buffer_filled(struct au0828_dev *dev,
312 312
313 list_del(&buf->vb.queue); 313 list_del(&buf->vb.queue);
314 wake_up(&buf->vb.done); 314 wake_up(&buf->vb.done);
315
316 /* Reset the timer for "no video condition" */
317 mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
315} 318}
316 319
317static inline void vbi_buffer_filled(struct au0828_dev *dev, 320static inline void vbi_buffer_filled(struct au0828_dev *dev,
@@ -329,6 +332,9 @@ static inline void vbi_buffer_filled(struct au0828_dev *dev,
329 332
330 list_del(&buf->vb.queue); 333 list_del(&buf->vb.queue);
331 wake_up(&buf->vb.done); 334 wake_up(&buf->vb.done);
335
336 /* Reset the timer for "no video condition" */
337 mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
332} 338}
333 339
334/* 340/*
@@ -907,6 +913,50 @@ static int get_ressource(struct au0828_fh *fh)
907 } 913 }
908} 914}
909 915
916/* This function ensures that video frames continue to be delivered even if
917 the ITU-656 input isn't receiving any data (thereby preventing applications
918 such as tvtime from hanging) */
919void au0828_vid_buffer_timeout(unsigned long data)
920{
921 struct au0828_dev *dev = (struct au0828_dev *) data;
922 struct au0828_dmaqueue *dma_q = &dev->vidq;
923 struct au0828_buffer *buf;
924 unsigned char *vid_data;
925
926 spin_lock(&dev->slock);
927
928 buf = dev->isoc_ctl.buf;
929 if (buf != NULL) {
930 vid_data = videobuf_to_vmalloc(&buf->vb);
931 memset(vid_data, 0x00, buf->vb.size); /* Blank green frame */
932 buffer_filled(dev, dma_q, buf);
933 get_next_buf(dma_q, &buf);
934 }
935
936 spin_unlock(&dev->slock);
937}
938
939void au0828_vbi_buffer_timeout(unsigned long data)
940{
941 struct au0828_dev *dev = (struct au0828_dev *) data;
942 struct au0828_dmaqueue *dma_q = &dev->vbiq;
943 struct au0828_buffer *buf;
944 unsigned char *vbi_data;
945
946 spin_lock(&dev->slock);
947
948 buf = dev->isoc_ctl.vbi_buf;
949 if (buf != NULL) {
950 vbi_data = videobuf_to_vmalloc(&buf->vb);
951 memset(vbi_data, 0x00, buf->vb.size);
952 vbi_buffer_filled(dev, dma_q, buf);
953 vbi_get_next_buf(dma_q, &buf);
954 }
955
956 spin_unlock(&dev->slock);
957}
958
959
910static int au0828_v4l2_open(struct file *filp) 960static int au0828_v4l2_open(struct file *filp)
911{ 961{
912 int ret = 0; 962 int ret = 0;
@@ -976,6 +1026,15 @@ static int au0828_v4l2_open(struct file *filp)
976 V4L2_FIELD_SEQ_TB, 1026 V4L2_FIELD_SEQ_TB,
977 sizeof(struct au0828_buffer), fh, NULL); 1027 sizeof(struct au0828_buffer), fh, NULL);
978 1028
1029 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1030 dev->vid_timeout.function = au0828_vid_buffer_timeout;
1031 dev->vid_timeout.data = (unsigned long) dev;
1032 init_timer(&dev->vid_timeout);
1033 } else {
1034 dev->vbi_timeout.function = au0828_vbi_buffer_timeout;
1035 dev->vbi_timeout.data = (unsigned long) dev;
1036 init_timer(&dev->vbi_timeout);
1037 }
979 1038
980 return ret; 1039 return ret;
981} 1040}
@@ -987,11 +1046,13 @@ static int au0828_v4l2_close(struct file *filp)
987 struct au0828_dev *dev = fh->dev; 1046 struct au0828_dev *dev = fh->dev;
988 1047
989 if (res_check(fh, AU0828_RESOURCE_VIDEO)) { 1048 if (res_check(fh, AU0828_RESOURCE_VIDEO)) {
1049 del_timer(&dev->vid_timeout);
990 videobuf_stop(&fh->vb_vidq); 1050 videobuf_stop(&fh->vb_vidq);
991 res_free(fh, AU0828_RESOURCE_VIDEO); 1051 res_free(fh, AU0828_RESOURCE_VIDEO);
992 } 1052 }
993 1053
994 if (res_check(fh, AU0828_RESOURCE_VBI)) { 1054 if (res_check(fh, AU0828_RESOURCE_VBI)) {
1055 del_timer(&dev->vbi_timeout);
995 videobuf_stop(&fh->vb_vbiq); 1056 videobuf_stop(&fh->vb_vbiq);
996 res_free(fh, AU0828_RESOURCE_VBI); 1057 res_free(fh, AU0828_RESOURCE_VBI);
997 } 1058 }