]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Fix vbi handling in saa7146 core driver
authorMichael Hunold <hunold@linuxtv.org>
Thu, 9 Oct 2003 00:50:23 +0000 (17:50 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Thu, 9 Oct 2003 00:50:23 +0000 (17:50 -0700)
 - add some debug and safety checks for video/vbi capture buffer
   handling
 - add new flag SAA7146_USE_PORT_B_FOR_VBI, so we can distinguish on
   which video port to apply the vbi workaround
 - add del_timer(...) for vbi capture queue and vbi_read timers,
   prevents oopses on vbi usage

drivers/media/common/saa7146_fops.c
drivers/media/common/saa7146_vbi.c
drivers/media/common/saa7146_video.c
include/media/saa7146_vv.h

index f2a3234318288336e0a6d8a3c8d232597a064298..9c4fcc49da7ad143737e5c3d4a323c6b4e1bc249 100644 (file)
@@ -61,8 +61,14 @@ void saa7146_buffer_finish(struct saa7146_dev *dev,
        }
 
        DEB_EE(("dev:%p, dmaq:%p, state:%d\n", dev, q, state));
+       DEB_EE(("q->curr:%p\n",q->curr));
 
        /* finish current buffer */
+       if (NULL == q->curr) {
+               DEB_D(("aiii. no current buffer\n"));
+               return; 
+       }
+                       
        q->curr->vb.state = state;
        do_gettimeofday(&q->curr->vb.ts);
        wake_up(&q->curr->vb.done);
@@ -221,9 +227,12 @@ static int fops_open(struct inode *inode, struct file *file)
        fh->dev = dev;
        fh->type = type;
 
-       saa7146_video_uops.open(dev,fh);
-       if( 0 != BOARD_CAN_DO_VBI(dev) ) {
+       if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+               DEB_S(("initializing vbi...\n"));
                saa7146_vbi_uops.open(dev,fh);
+       } else {
+               DEB_S(("initializing video...\n"));
+               saa7146_video_uops.open(dev,fh);
        }
 
        result = 0;
@@ -245,9 +254,10 @@ static int fops_release(struct inode *inode, struct file *file)
        if (down_interruptible(&saa7146_devices_lock))
                return -ERESTARTSYS;
 
-       saa7146_video_uops.release(dev,fh,file);
-       if( 0 != BOARD_CAN_DO_VBI(dev) ) {
+       if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
                saa7146_vbi_uops.release(dev,fh,file);
+       } else {
+               saa7146_video_uops.release(dev,fh,file);
        }
 
        module_put(dev->ext->module);
@@ -332,11 +342,11 @@ static ssize_t fops_read(struct file *file, char *data, size_t count, loff_t *pp
 
        switch (fh->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
-               DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun", file, data, (unsigned long)count));
+//             DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun", file, data, (unsigned long)count));
                return saa7146_video_uops.read(file,data,count,ppos);
                }
        case V4L2_BUF_TYPE_VBI_CAPTURE: {
-               DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count));
+//             DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count));
                return saa7146_vbi_uops.read(file,data,count,ppos);
                }
                break;
@@ -443,7 +453,7 @@ int saa7146_register_device(struct video_device *vid, struct saa7146_dev* dev, c
 {
        struct saa7146_vv *vv = dev->vv_data;
 
-       DEB_EE(("dev:%p, name:'%s'\n",dev,name));
+       DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type));
  
        *vid = device_template;
        strlcpy(vid->name, name, sizeof(vid->name));
@@ -451,7 +461,7 @@ int saa7146_register_device(struct video_device *vid, struct saa7146_dev* dev, c
 
        // fixme: -1 should be an insmod parameter *for the extension* (like "video_nr");
        if (video_register_device(vid,type,-1) < 0) {
-               ERR(("cannot register vbi v4l2 device. skipping.\n"));
+               ERR(("cannot register v4l2 device. skipping.\n"));
                return -1;
        }
 
index 19612d2fbe6edc555f67cbf51ef53ba580c5bb0a..9ed51e3a798952c8720b6d02fc219a5b20b377b5 100644 (file)
@@ -38,8 +38,14 @@ static int vbi_workaround(struct saa7146_dev *dev)
                WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
                /* BXO = 1h, BRS to outbound */
                WRITE_RPS1(0xc000008c);   
-               /* wait for vbi_a */
+       /* wait for vbi_a or vbi_b*/
+       if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
+               DEB_D(("...using port b\n"));
+               WRITE_RPS1(CMD_PAUSE | MASK_09);
+       } else {
+               DEB_D(("...using port a\n"));
                WRITE_RPS1(CMD_PAUSE | MASK_10);
+       }
                /* upload brs */
                WRITE_RPS1(CMD_UPLOAD | MASK_08);
                /* load brs-control register */
@@ -106,7 +112,7 @@ static int vbi_workaround(struct saa7146_dev *dev)
 
                if(signal_pending(current)) {
                
-                       DEB_VBI(("aborted.\n"));
+                       DEB_VBI(("aborted (rps:0x%08x).\n",saa7146_read(dev,RPS_ADDR1)));
 
                        /* stop rps1 for sure */
                        saa7146_write(dev, MC1, MASK_29);
@@ -316,6 +322,11 @@ static void vbi_stop(struct saa7146_fh *fh)
        saa7146_write(dev, MC1, MASK_20);
 
        vv->vbi_streaming = NULL;
+
+       del_timer(&vv->vbi_q.timeout);
+       del_timer(&fh->vbi_read_timeout);
+
+       DEB_VBI(("out\n"));
        spin_unlock_irqrestore(&dev->slock, flags);
 }
 
@@ -371,7 +382,10 @@ static void vbi_open(struct saa7146_dev *dev, struct saa7146_fh *fh)
        fh->vbi_read_timeout.function = vbi_read_timeout;
        fh->vbi_read_timeout.data = (unsigned long)fh;
 
+       /* fixme: enable this again, if the dvb-c w/ analog module work properly */
+/*
        vbi_workaround(dev);
+*/
 }
 
 static void vbi_close(struct saa7146_dev *dev, struct saa7146_fh *fh, struct file *file)
index 812e4a5f876d8491717f60cd496430a4ac4066fc..0a34ede32c1dda4d395eceeda9f26cea23966dd6 100644 (file)
@@ -1319,7 +1319,7 @@ static int buffer_prepare(struct file *file, struct videobuf_buffer *vb, enum v4
                        saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
                }
                
-               err = videobuf_iolock(dev->pci,&buf->vb,NULL);
+               err = videobuf_iolock(dev->pci,&buf->vb, &vv->ov_fb);
                if (err)
                        goto oops;
                err = saa7146_pgtable_build(dev,buf);
index b4a25aac2ae5f23f9f0a6ee40af245a424309fe1..f8362431c962c99a15b5851bdf6a8ac2272bb1b3 100644 (file)
@@ -150,6 +150,7 @@ struct saa7146_extension_ioctls
 
 /* flags */
 #define SAA7146_EXT_SWAP_ODD_EVEN       0x1     /* needs odd/even fields swapped */
+#define SAA7146_USE_PORT_B_FOR_VBI     0x2     /* use input port b for vbi hardware bug workaround */
 
 struct saa7146_ext_vv
 {