Merge gregkh@master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
[pandora-kernel.git] / drivers / media / video / saa7134 / saa7134-video.c
index 35e5e85..2c171af 100644 (file)
 
 #include "saa7134-reg.h"
 #include "saa7134.h"
+#include <media/v4l2-common.h>
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+/* Include V4L1 specific functions. Should be removed soon */
+#include <linux/videodev.h>
+#endif
 
 /* ------------------------------------------------------------------ */
 
 static unsigned int video_debug   = 0;
 static unsigned int gbuffers      = 8;
-static unsigned int noninterlaced = 0;
+static unsigned int noninterlaced = 1;
 static unsigned int gbufsize      = 720*576*4;
 static unsigned int gbufsize_max  = 720*576*4;
 module_param(video_debug, int, 0644);
@@ -42,11 +48,48 @@ MODULE_PARM_DESC(video_debug,"enable debug messages [video]");
 module_param(gbuffers, int, 0444);
 MODULE_PARM_DESC(gbuffers,"number of capture buffers, range 2-32");
 module_param(noninterlaced, int, 0644);
-MODULE_PARM_DESC(noninterlaced,"video input is noninterlaced");
+MODULE_PARM_DESC(noninterlaced,"capture non interlaced video");
 
 #define dprintk(fmt, arg...)   if (video_debug) \
        printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg)
 
+/* ------------------------------------------------------------------ */
+/* Defines for Video Output Port Register at address 0x191            */
+
+/* Bit 0: VIP code T bit polarity */
+
+#define VP_T_CODE_P_NON_INVERTED       0x00
+#define VP_T_CODE_P_INVERTED           0x01
+
+/* ------------------------------------------------------------------ */
+/* Defines for Video Output Port Register at address 0x195            */
+
+/* Bit 2: Video output clock delay control */
+
+#define VP_CLK_CTRL2_NOT_DELAYED       0x00
+#define VP_CLK_CTRL2_DELAYED           0x04
+
+/* Bit 1: Video output clock invert control */
+
+#define VP_CLK_CTRL1_NON_INVERTED      0x00
+#define VP_CLK_CTRL1_INVERTED          0x02
+
+/* ------------------------------------------------------------------ */
+/* Defines for Video Output Port Register at address 0x196            */
+
+/* Bits 2 to 0: VSYNC pin video vertical sync type */
+
+#define VP_VS_TYPE_MASK                        0x07
+
+#define VP_VS_TYPE_OFF                 0x00
+#define VP_VS_TYPE_V123                        0x01
+#define VP_VS_TYPE_V_ITU               0x02
+#define VP_VS_TYPE_VGATE_L             0x03
+#define VP_VS_TYPE_RESERVED1           0x04
+#define VP_VS_TYPE_RESERVED2           0x05
+#define VP_VS_TYPE_F_ITU               0x06
+#define VP_VS_TYPE_SC_FID              0x07
+
 /* ------------------------------------------------------------------ */
 /* data structs for video                                             */
 
@@ -273,12 +316,12 @@ static struct saa7134_tvnorm tvnorms[] = {
 
                .h_start       = 0,
                .h_stop        = 719,
-               .video_v_start = 23,
-               .video_v_stop  = 262,
-               .vbi_v_start_0 = 10,
-               .vbi_v_stop_0  = 21,
-               .vbi_v_start_1 = 273,
-               .src_timing    = 7,
+               .video_v_start = 23,
+               .video_v_stop  = 262,
+               .vbi_v_start_0 = 10,
+               .vbi_v_stop_0  = 21,
+               .vbi_v_start_1 = 273,
+               .src_timing    = 7,
 
                .sync_control  = 0x18,
                .luma_control  = 0x40,
@@ -419,17 +462,17 @@ static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int
                return 1;
 
        /* is it free? */
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
        if (dev->resources & bit) {
                /* no, someone else uses it */
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                return 0;
        }
        /* it's free, grab it */
        fh->resources  |= bit;
        dev->resources |= bit;
        dprintk("res: get %d\n",bit);
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
        return 1;
 }
 
@@ -448,14 +491,13 @@ int res_locked(struct saa7134_dev *dev, unsigned int bit)
 static
 void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits)
 {
-       if ((fh->resources & bits) != bits)
-               BUG();
+       BUG_ON((fh->resources & bits) != bits);
 
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
        fh->resources  &= ~bits;
        dev->resources &= ~bits;
        dprintk("res: put %d\n",bits);
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
 }
 
 /* ------------------------------------------------------------------ */
@@ -622,7 +664,7 @@ static void set_size(struct saa7134_dev *dev, int task,
                prescale = 1;
        xscale = 1024 * dev->crop_current.width / prescale / width;
        yscale = 512 * div * dev->crop_current.height / height;
-               dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale);
+       dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale);
        set_h_prescale(dev,task,prescale);
        saa_writeb(SAA7134_H_SCALE_INC1(task),      xscale &  0xff);
        saa_writeb(SAA7134_H_SCALE_INC2(task),      xscale >> 8);
@@ -752,20 +794,20 @@ static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win)
        maxh  = dev->crop_current.height;
 
        if (V4L2_FIELD_ANY == field) {
-                field = (win->w.height > maxh/2)
-                        ? V4L2_FIELD_INTERLACED
-                        : V4L2_FIELD_TOP;
-        }
-        switch (field) {
-        case V4L2_FIELD_TOP:
-        case V4L2_FIELD_BOTTOM:
-                maxh = maxh / 2;
-                break;
-        case V4L2_FIELD_INTERLACED:
-                break;
-        default:
-                return -EINVAL;
-        }
+               field = (win->w.height > maxh/2)
+                       ? V4L2_FIELD_INTERLACED
+                       : V4L2_FIELD_TOP;
+       }
+       switch (field) {
+       case V4L2_FIELD_TOP:
+       case V4L2_FIELD_BOTTOM:
+               maxh = maxh / 2;
+               break;
+       case V4L2_FIELD_INTERLACED:
+               break;
+       default:
+               return -EINVAL;
+       }
 
        win->field = field;
        if (win->w.width > maxw)
@@ -953,7 +995,7 @@ static int buffer_prepare(struct videobuf_queue *q,
            buf->vb.size   != size       ||
            buf->vb.field  != field      ||
            buf->fmt       != fh->fmt) {
-               saa7134_dma_free(dev,buf);
+               saa7134_dma_free(q,buf);
        }
 
        if (STATE_NEEDS_INIT == buf->vb.state) {
@@ -964,7 +1006,7 @@ static int buffer_prepare(struct videobuf_queue *q,
                buf->fmt       = fh->fmt;
                buf->pt        = &fh->pt_cap;
 
-               err = videobuf_iolock(dev->pci,&buf->vb,&dev->ovbuf);
+               err = videobuf_iolock(q,&buf->vb,&dev->ovbuf);
                if (err)
                        goto oops;
                err = saa7134_pgtable_build(dev->pci,buf->pt,
@@ -979,7 +1021,7 @@ static int buffer_prepare(struct videobuf_queue *q,
        return 0;
 
  oops:
-       saa7134_dma_free(dev,buf);
+       saa7134_dma_free(q,buf);
        return err;
 }
 
@@ -1005,10 +1047,9 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
 
 static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
 {
-       struct saa7134_fh *fh = q->priv_data;
        struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
 
-       saa7134_dma_free(fh->dev,buf);
+       saa7134_dma_free(q,buf);
 }
 
 static struct videobuf_queue_ops video_qops = {
@@ -1223,10 +1264,9 @@ static int video_open(struct inode *inode, struct file *file)
                v4l2_type_names[type]);
 
        /* allocate + initialize per filehandle data */
-       fh = kmalloc(sizeof(*fh),GFP_KERNEL);
+       fh = kzalloc(sizeof(*fh),GFP_KERNEL);
        if (NULL == fh)
                return -ENOMEM;
-       memset(fh,0,sizeof(*fh));
        file->private_data = fh;
        fh->dev      = dev;
        fh->radio    = radio;
@@ -1300,21 +1340,21 @@ video_poll(struct file *file, struct poll_table_struct *wait)
                if (!list_empty(&fh->cap.stream))
                        buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
        } else {
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                if (UNSET == fh->cap.read_off) {
                        /* need to capture a new frame */
                        if (res_locked(fh->dev,RESOURCE_VIDEO)) {
-                               up(&fh->cap.lock);
+                               mutex_unlock(&fh->cap.lock);
+                               return POLLERR;
+                       }
+                       if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
+                               mutex_unlock(&fh->cap.lock);
                                return POLLERR;
-                        }
-                        if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
-                                up(&fh->cap.lock);
-                                return POLLERR;
-                        }
-                        fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
-                        fh->cap.read_off = 0;
+                       }
+                       fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
+                       fh->cap.read_off = 0;
                }
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                buf = fh->cap.read_buf;
        }
 
@@ -1423,6 +1463,10 @@ static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
                        f->fmt.pix.height * f->fmt.pix.bytesperline;
                return 0;
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+               if (saa7134_no_overlay > 0) {
+                       printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
+                       return -EINVAL;
+               }
                f->fmt.win = fh->win;
                return 0;
        case V4L2_BUF_TYPE_VBI_CAPTURE:
@@ -1487,6 +1531,10 @@ static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
                return 0;
        }
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+               if (saa7134_no_overlay > 0) {
+                       printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
+                       return -EINVAL;
+               }
                err = verify_preview(dev,&f->fmt.win);
                if (0 != err)
                        return err;
@@ -1517,18 +1565,22 @@ static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
                fh->cap.field = f->fmt.pix.field;
                return 0;
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+               if (saa7134_no_overlay > 0) {
+                       printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
+                       return -EINVAL;
+               }
                err = verify_preview(dev,&f->fmt.win);
                if (0 != err)
                        return err;
 
-               down(&dev->lock);
+               mutex_lock(&dev->lock);
                fh->win    = f->fmt.win;
                fh->nclips = f->fmt.win.clipcount;
                if (fh->nclips > 8)
                        fh->nclips = 8;
                if (copy_from_user(fh->clips,f->fmt.win.clips,
                                   sizeof(struct v4l2_clip)*fh->nclips)) {
-                       up(&dev->lock);
+                       mutex_unlock(&dev->lock);
                        return -EFAULT;
                }
 
@@ -1538,7 +1590,7 @@ static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
                        start_preview(dev,fh);
                        spin_unlock_irqrestore(&dev->slock,flags);
                }
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                return 0;
        case V4L2_BUF_TYPE_VBI_CAPTURE:
                saa7134_vbi_fmt(dev,f);
@@ -1572,9 +1624,9 @@ int saa7134_common_ioctl(struct saa7134_dev *dev,
                return get_control(dev,arg);
        case VIDIOC_S_CTRL:
        {
-               down(&dev->lock);
+               mutex_lock(&dev->lock);
                err = set_control(dev,NULL,arg);
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                return err;
        }
        /* --- input switching --------------------------------------- */
@@ -1624,9 +1676,9 @@ int saa7134_common_ioctl(struct saa7134_dev *dev,
                        return -EINVAL;
                if (NULL == card_in(dev,*i).name)
                        return -EINVAL;
-               down(&dev->lock);
+               mutex_lock(&dev->lock);
                video_mux(dev,*i);
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                return 0;
        }
 
@@ -1649,7 +1701,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
        int err;
 
        if (video_debug > 1)
-               saa7134_print_ioctl(dev->name,cmd);
+               v4l_print_ioctl(dev->name,cmd);
 
        switch (cmd) {
        case VIDIOC_S_CTRL:
@@ -1666,20 +1718,27 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
        case VIDIOC_QUERYCAP:
        {
                struct v4l2_capability *cap = arg;
+               unsigned int tuner_type = dev->tuner_type;
 
                memset(cap,0,sizeof(*cap));
-                strcpy(cap->driver, "saa7134");
+               strcpy(cap->driver, "saa7134");
                strlcpy(cap->card, saa7134_boards[dev->board].name,
                        sizeof(cap->card));
                sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
                cap->version = SAA7134_VERSION_CODE;
                cap->capabilities =
                        V4L2_CAP_VIDEO_CAPTURE |
-                       V4L2_CAP_VIDEO_OVERLAY |
                        V4L2_CAP_VBI_CAPTURE |
-                       V4L2_CAP_TUNER |
                        V4L2_CAP_READWRITE |
-                       V4L2_CAP_STREAMING;
+                       V4L2_CAP_STREAMING |
+                       V4L2_CAP_TUNER;
+               if (saa7134_no_overlay <= 0) {
+                       cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
+               }
+
+               if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET))
+                       cap->capabilities &= ~V4L2_CAP_TUNER;
+
                return 0;
        }
 
@@ -1721,7 +1780,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
                if (i == TVNORMS)
                        return -EINVAL;
 
-               down(&dev->lock);
+               mutex_lock(&dev->lock);
                if (res_check(fh, RESOURCE_OVERLAY)) {
                        spin_lock_irqsave(&dev->slock,flags);
                        stop_preview(dev,fh);
@@ -1731,7 +1790,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
                } else
                        set_tvnorm(dev,&tvnorms[i]);
                saa7134_tvaudio_do_scan(dev);
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                return 0;
        }
 
@@ -1793,9 +1852,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
                        crop->c.height = b->top - crop->c.top + b->height;
 
                if (crop->c.left < b->left)
-                       crop->c.top = b->left;
+                       crop->c.left = b->left;
                if (crop->c.left > b->left + b->width)
-                       crop->c.top = b->left + b->width;
+                       crop->c.left = b->left + b->width;
                if (crop->c.width > b->left - crop->c.left + b->width)
                        crop->c.width = b->left - crop->c.left + b->width;
 
@@ -1817,6 +1876,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
                                break;
                if (NULL != card_in(dev,n).name) {
                        strcpy(t->name, "Television");
+                       t->type = V4L2_TUNER_ANALOG_TV;
                        t->capability = V4L2_TUNER_CAP_NORM |
                                V4L2_TUNER_CAP_STEREO |
                                V4L2_TUNER_CAP_LANG1 |
@@ -1863,13 +1923,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
                        return -EINVAL;
                if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
                        return -EINVAL;
-               down(&dev->lock);
+               mutex_lock(&dev->lock);
                dev->ctl_freq = f->frequency;
 
                saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f);
 
                saa7134_tvaudio_do_scan(dev);
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                return 0;
        }
 
@@ -1892,26 +1952,26 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
        }
        case VIDIOC_S_AUDIO:
                return 0;
-        case VIDIOC_G_PARM:
-        {
-                struct v4l2_captureparm *parm = arg;
-                memset(parm,0,sizeof(*parm));
-                return 0;
-        }
-
-        case VIDIOC_G_PRIORITY:
-        {
-                enum v4l2_priority *p = arg;
-
-                *p = v4l2_prio_max(&dev->prio);
-                return 0;
-        }
-        case VIDIOC_S_PRIORITY:
-        {
-                enum v4l2_priority *prio = arg;
-
-                return v4l2_prio_change(&dev->prio, &fh->prio, *prio);
-        }
+       case VIDIOC_G_PARM:
+       {
+               struct v4l2_captureparm *parm = arg;
+               memset(parm,0,sizeof(*parm));
+               return 0;
+       }
+
+       case VIDIOC_G_PRIORITY:
+       {
+               enum v4l2_priority *p = arg;
+
+               *p = v4l2_prio_max(&dev->prio);
+               return 0;
+       }
+       case VIDIOC_S_PRIORITY:
+       {
+               enum v4l2_priority *prio = arg;
+
+               return v4l2_prio_change(&dev->prio, &fh->prio, *prio);
+       }
 
        /* --- preview ioctls ---------------------------------------- */
        case VIDIOC_ENUM_FMT:
@@ -1925,6 +1985,10 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
                switch (type) {
                case V4L2_BUF_TYPE_VIDEO_CAPTURE:
                case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+                       if (saa7134_no_overlay > 0) {
+                               printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
+                               return -EINVAL;
+                       }
                        if (index >= FORMATS)
                                return -EINVAL;
                        if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY &&
@@ -1985,6 +2049,11 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
                int *on = arg;
 
                if (*on) {
+                       if (saa7134_no_overlay > 0) {
+                               printk ("no_overlay\n");
+                               return -EINVAL;
+                       }
+
                        if (!res_get(dev,fh,RESOURCE_OVERLAY))
                                return -EBUSY;
                        spin_lock_irqsave(&dev->slock,flags);
@@ -2018,7 +2087,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
                struct v4l2_format *f = arg;
                return saa7134_try_fmt(dev,fh,f);
        }
-
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
        case VIDIOCGMBUF:
        {
                struct video_mbuf *mbuf = arg;
@@ -2043,6 +2112,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
                }
                return 0;
        }
+#endif
        case VIDIOC_REQBUFS:
                return videobuf_reqbufs(saa7134_queue(fh),arg);
 
@@ -2060,7 +2130,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
        {
                int res = saa7134_resource(fh);
 
-                if (!res_get(dev,fh,res))
+               if (!res_get(dev,fh,res))
                        return -EBUSY;
                return videobuf_streamon(saa7134_queue(fh));
        }
@@ -2095,14 +2165,14 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
        struct saa7134_dev *dev = fh->dev;
 
        if (video_debug > 1)
-               saa7134_print_ioctl(dev->name,cmd);
+               v4l_print_ioctl(dev->name,cmd);
        switch (cmd) {
        case VIDIOC_QUERYCAP:
        {
                struct v4l2_capability *cap = arg;
 
                memset(cap,0,sizeof(*cap));
-                strcpy(cap->driver, "saa7134");
+               strcpy(cap->driver, "saa7134");
                strlcpy(cap->card, saa7134_boards[dev->board].name,
                        sizeof(cap->card));
                sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
@@ -2119,6 +2189,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
 
                memset(t,0,sizeof(*t));
                strcpy(t->name, "Radio");
+               t->type = V4L2_TUNER_RADIO;
 
                saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
 
@@ -2214,6 +2285,7 @@ static struct file_operations video_fops =
        .poll     = video_poll,
        .mmap     = video_mmap,
        .ioctl    = video_ioctl,
+       .compat_ioctl   = v4l_compat_ioctl32,
        .llseek   = no_llseek,
 };
 
@@ -2223,6 +2295,7 @@ static struct file_operations radio_fops =
        .open     = video_open,
        .release  = video_release,
        .ioctl    = radio_ioctl,
+       .compat_ioctl   = v4l_compat_ioctl32,
        .llseek   = no_llseek,
 };
 
@@ -2232,8 +2305,8 @@ static struct file_operations radio_fops =
 struct video_device saa7134_video_template =
 {
        .name          = "saa7134-video",
-       .type          = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
-                        VID_TYPE_CLIPPING|VID_TYPE_SCALES,
+       .type          = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
+                        VID_TYPE_CLIPPING|VID_TYPE_SCALES,
        .hardware      = 0,
        .fops          = &video_fops,
        .minor         = -1,
@@ -2280,7 +2353,7 @@ int saa7134_video_init1(struct saa7134_dev *dev)
                dev->tda9887_conf |= TDA9887_AUTOMUTE;
        dev->automute       = 0;
 
-        INIT_LIST_HEAD(&dev->video_q.queue);
+       INIT_LIST_HEAD(&dev->video_q.queue);
        init_timer(&dev->video_q.timeout);
        dev->video_q.timeout.function = saa7134_buffer_timeout;
        dev->video_q.timeout.data     = (unsigned long)(&dev->video_q);
@@ -2289,13 +2362,28 @@ int saa7134_video_init1(struct saa7134_dev *dev)
        if (saa7134_boards[dev->board].video_out) {
                /* enable video output */
                int vo = saa7134_boards[dev->board].video_out;
+               int video_reg;
+               unsigned int vid_port_opts = saa7134_boards[dev->board].vid_port_opts;
                saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]);
-               saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_out[vo][1]);
+               video_reg = video_out[vo][1];
+               if (vid_port_opts & SET_T_CODE_POLARITY_NON_INVERTED)
+                       video_reg &= ~VP_T_CODE_P_INVERTED;
+               saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_reg);
                saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]);
                saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);
                saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]);
-               saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_out[vo][5]);
-               saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_out[vo][6]);
+               video_reg = video_out[vo][5];
+               if (vid_port_opts & SET_CLOCK_NOT_DELAYED)
+                       video_reg &= ~VP_CLK_CTRL2_DELAYED;
+               if (vid_port_opts & SET_CLOCK_INVERTED)
+                       video_reg |= VP_CLK_CTRL1_INVERTED;
+               saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_reg);
+               video_reg = video_out[vo][6];
+               if (vid_port_opts & SET_VSYNC_OFF) {
+                       video_reg &= ~VP_VS_TYPE_MASK;
+                       video_reg |= VP_VS_TYPE_OFF;
+               }
+               saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_reg);
                saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]);
                saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]);
        }