V4L/DVB (10632): Added support for AVerMedia Cardbus Hybrid remote control
[safe/jmp/linux-2.6] / drivers / media / video / saa7134 / saa7134-video.c
index 6f9f9db..aa7fa1f 100644 (file)
@@ -40,7 +40,7 @@
 
 unsigned int video_debug;
 static unsigned int gbuffers      = 8;
-static unsigned int noninterlaced = 0;
+static unsigned int noninterlaced; /* 0 */
 static unsigned int gbufsize      = 720*576*4;
 static unsigned int gbufsize_max  = 720*576*4;
 static char secam[] = "--";
@@ -217,12 +217,6 @@ static struct saa7134_format formats[] = {
                .vbi_v_start_1 = 273,   \
                .src_timing    = 7
 
-#define SAA7134_NORMS  \
-               V4L2_STD_PAL    | V4L2_STD_PAL_N | \
-               V4L2_STD_PAL_Nc | V4L2_STD_SECAM | \
-               V4L2_STD_NTSC   | V4L2_STD_PAL_M | \
-               V4L2_STD_PAL_60
-
 static struct saa7134_tvnorm tvnorms[] = {
        {
                .name          = "PAL", /* autodetect */
@@ -458,6 +452,7 @@ static const struct v4l2_queryctrl video_ctrls[] = {
                .name          = "y offset odd field",
                .minimum       = 0,
                .maximum       = 128,
+               .step          = 1,
                .default_value = 0,
                .type          = V4L2_CTRL_TYPE_INTEGER,
        },{
@@ -465,6 +460,7 @@ static const struct v4l2_queryctrl video_ctrls[] = {
                .name          = "y offset even field",
                .minimum       = 0,
                .maximum       = 128,
+               .step          = 1,
                .default_value = 0,
                .type          = V4L2_CTRL_TYPE_INTEGER,
        },{
@@ -632,13 +628,11 @@ void saa7134_set_tvnorm_hw(struct saa7134_dev *dev)
 {
        saa7134_set_decoder(dev);
 
-       if (card_in(dev, dev->ctl_input).tv) {
-               if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290)
-                               && ((card(dev).tuner_config == 1)
-                               ||  (card(dev).tuner_config == 2)))
-                       saa7134_set_gpio(dev, 22, 5);
-               saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id);
-       }
+       if (card_in(dev, dev->ctl_input).tv)
+               saa_call_all(dev, tuner, s_std, dev->tvnorm->id);
+       /* Set the correct norm for the saa6752hs. This function
+          does nothing if there is no saa6752hs. */
+       saa_call_empress(dev, tuner, s_std, dev->tvnorm->id);
 }
 
 static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
@@ -1123,11 +1117,8 @@ static struct videobuf_queue_ops video_qops = {
 
 /* ------------------------------------------------------------------ */
 
-static int saa7134_g_ctrl(struct file *file, void *priv,
-                                       struct v4l2_control *c)
+int saa7134_g_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c)
 {
-       struct saa7134_fh *fh = priv;
-       struct saa7134_dev *dev = fh->dev;
        const struct v4l2_queryctrl* ctrl;
 
        ctrl = ctrl_by_id(c->id);
@@ -1172,20 +1163,31 @@ static int saa7134_g_ctrl(struct file *file, void *priv,
        }
        return 0;
 }
+EXPORT_SYMBOL_GPL(saa7134_g_ctrl_internal);
+
+static int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c)
+{
+       struct saa7134_fh *fh = priv;
+
+       return saa7134_g_ctrl_internal(fh->dev, fh, c);
+}
 
-static int saa7134_s_ctrl(struct file *file, void *f,
-                                       struct v4l2_control *c)
+int saa7134_s_ctrl_internal(struct saa7134_dev *dev,  struct saa7134_fh *fh, struct v4l2_control *c)
 {
        const struct v4l2_queryctrl* ctrl;
-       struct saa7134_fh *fh = f;
-       struct saa7134_dev *dev = fh->dev;
        unsigned long flags;
        int restart_overlay = 0;
-       int err = -EINVAL;
+       int err;
 
-       err = v4l2_prio_check(&dev->prio, &fh->prio);
-       if (0 != err)
-               return err;
+       /* When called from the empress code fh == NULL.
+          That needs to be fixed somehow, but for now this is
+          good enough. */
+       if (fh) {
+               err = v4l2_prio_check(&dev->prio, &fh->prio);
+               if (0 != err)
+                       return err;
+       }
+       err = -EINVAL;
 
        mutex_lock(&dev->lock);
 
@@ -1266,8 +1268,7 @@ static int saa7134_s_ctrl(struct file *file, void *f,
                        else
                                dev->tda9887_conf &= ~TDA9887_AUTOMUTE;
 
-                       saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG,
-                                                &tda9887_cfg);
+                       saa_call_all(dev, tuner, s_config, &tda9887_cfg);
                }
                break;
        }
@@ -1286,6 +1287,14 @@ error:
        mutex_unlock(&dev->lock);
        return err;
 }
+EXPORT_SYMBOL_GPL(saa7134_s_ctrl_internal);
+
+static int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c)
+{
+       struct saa7134_fh *fh = f;
+
+       return saa7134_s_ctrl_internal(fh->dev, fh, c);
+}
 
 /* ------------------------------------------------------------------ */
 
@@ -1318,13 +1327,15 @@ static int saa7134_resource(struct saa7134_fh *fh)
        return 0;
 }
 
-static int video_open(struct inode *inode, struct file *file)
+static int video_open(struct file *file)
 {
-       int minor = iminor(inode);
+       int minor = video_devdata(file)->minor;
        struct saa7134_dev *dev;
        struct saa7134_fh *fh;
        enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        int radio = 0;
+
+       mutex_lock(&saa7134_devlist_lock);
        list_for_each_entry(dev, &saa7134_devlist, devlist) {
                if (dev->video_dev && (dev->video_dev->minor == minor))
                        goto found;
@@ -1337,8 +1348,11 @@ static int video_open(struct inode *inode, struct file *file)
                        goto found;
                }
        }
+       mutex_unlock(&saa7134_devlist_lock);
        return -ENODEV;
- found:
+
+found:
+       mutex_unlock(&saa7134_devlist_lock);
 
        dprintk("open minor=%d radio=%d type=%s\n",minor,radio,
                v4l2_type_names[type]);
@@ -1347,6 +1361,7 @@ static int video_open(struct inode *inode, struct file *file)
        fh = kzalloc(sizeof(*fh),GFP_KERNEL);
        if (NULL == fh)
                return -ENOMEM;
+
        file->private_data = fh;
        fh->dev      = dev;
        fh->radio    = radio;
@@ -1356,14 +1371,14 @@ static int video_open(struct inode *inode, struct file *file)
        fh->height   = 576;
        v4l2_prio_open(&dev->prio,&fh->prio);
 
-       videobuf_queue_pci_init(&fh->cap, &video_qops,
-                           dev->pci, &dev->slock,
+       videobuf_queue_sg_init(&fh->cap, &video_qops,
+                           &dev->pci->dev, &dev->slock,
                            V4L2_BUF_TYPE_VIDEO_CAPTURE,
                            V4L2_FIELD_INTERLACED,
                            sizeof(struct saa7134_buf),
                            fh);
-       videobuf_queue_pci_init(&fh->vbi, &saa7134_vbi_qops,
-                           dev->pci, &dev->slock,
+       videobuf_queue_sg_init(&fh->vbi, &saa7134_vbi_qops,
+                           &dev->pci->dev, &dev->slock,
                            V4L2_BUF_TYPE_VBI_CAPTURE,
                            V4L2_FIELD_SEQ_TB,
                            sizeof(struct saa7134_buf),
@@ -1374,7 +1389,7 @@ static int video_open(struct inode *inode, struct file *file)
        if (fh->radio) {
                /* switch to radio mode */
                saa7134_tvaudio_setinput(dev,&card(dev).radio);
-               saa7134_i2c_call_clients(dev,AUDC_SET_RADIO, NULL);
+               saa_call_all(dev, tuner, s_radio);
        } else {
                /* switch to video/vbi mode */
                video_mux(dev,dev->ctl_input);
@@ -1420,21 +1435,17 @@ 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 {
-               mutex_lock(&fh->cap.lock);
+               mutex_lock(&fh->cap.vb_lock);
                if (UNSET == fh->cap.read_off) {
                        /* need to capture a new frame */
-                       if (res_locked(fh->dev,RESOURCE_VIDEO)) {
-                               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 (res_locked(fh->dev,RESOURCE_VIDEO))
+                               goto err;
+                       if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field))
+                               goto err;
                        fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
                        fh->cap.read_off = 0;
                }
-               mutex_unlock(&fh->cap.lock);
+               mutex_unlock(&fh->cap.vb_lock);
                buf = fh->cap.read_buf;
        }
 
@@ -1446,9 +1457,13 @@ video_poll(struct file *file, struct poll_table_struct *wait)
            buf->state == VIDEOBUF_ERROR)
                return POLLIN|POLLRDNORM;
        return 0;
+
+err:
+       mutex_unlock(&fh->cap.vb_lock);
+       return POLLERR;
 }
 
-static int video_release(struct inode *inode, struct file *file)
+static int video_release(struct file *file)
 {
        struct saa7134_fh  *fh  = file->private_data;
        struct saa7134_dev *dev = fh->dev;
@@ -1484,7 +1499,7 @@ static int video_release(struct inode *inode, struct file *file)
        saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
        saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
 
-       saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
+       saa_call_all(dev, core, s_standby, 0);
 
        /* free stuff */
        videobuf_mmap_free(&fh->cap);
@@ -1507,7 +1522,7 @@ static int video_mmap(struct file *file, struct vm_area_struct * vma)
 
 /* ------------------------------------------------------------------ */
 
-static int saa7134_try_get_set_fmt_vbi(struct file *file, void *priv,
+static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv,
                                                struct v4l2_format *f)
 {
        struct saa7134_fh *fh = priv;
@@ -1527,7 +1542,7 @@ static int saa7134_try_get_set_fmt_vbi(struct file *file, void *priv,
        return 0;
 }
 
-static int saa7134_g_fmt_cap(struct file *file, void *priv,
+static int saa7134_g_fmt_vid_cap(struct file *file, void *priv,
                                struct v4l2_format *f)
 {
        struct saa7134_fh *fh = priv;
@@ -1543,7 +1558,7 @@ static int saa7134_g_fmt_cap(struct file *file, void *priv,
        return 0;
 }
 
-static int saa7134_g_fmt_overlay(struct file *file, void *priv,
+static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv,
                                struct v4l2_format *f)
 {
        struct saa7134_fh *fh = priv;
@@ -1557,7 +1572,7 @@ static int saa7134_g_fmt_overlay(struct file *file, void *priv,
        return 0;
 }
 
-static int saa7134_try_fmt_cap(struct file *file, void *priv,
+static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,
                                                struct v4l2_format *f)
 {
        struct saa7134_fh *fh = priv;
@@ -1608,7 +1623,7 @@ static int saa7134_try_fmt_cap(struct file *file, void *priv,
        return 0;
 }
 
-static int saa7134_try_fmt_overlay(struct file *file, void *priv,
+static int saa7134_try_fmt_vid_overlay(struct file *file, void *priv,
                                                struct v4l2_format *f)
 {
        struct saa7134_fh *fh = priv;
@@ -1622,13 +1637,13 @@ static int saa7134_try_fmt_overlay(struct file *file, void *priv,
        return verify_preview(dev, &f->fmt.win);
 }
 
-static int saa7134_s_fmt_cap(struct file *file, void *priv,
+static int saa7134_s_fmt_vid_cap(struct file *file, void *priv,
                                        struct v4l2_format *f)
 {
        struct saa7134_fh *fh = priv;
        int err;
 
-       err = saa7134_try_fmt_cap(file, priv, f);
+       err = saa7134_try_fmt_vid_cap(file, priv, f);
        if (0 != err)
                return err;
 
@@ -1639,13 +1654,13 @@ static int saa7134_s_fmt_cap(struct file *file, void *priv,
        return 0;
 }
 
-static int saa7134_s_fmt_overlay(struct file *file, void *priv,
+static int saa7134_s_fmt_vid_overlay(struct file *file, void *priv,
                                        struct v4l2_format *f)
 {
        struct saa7134_fh *fh = priv;
        struct saa7134_dev *dev = fh->dev;
        int err;
-       unsigned int flags;
+       unsigned long flags;
 
        if (saa7134_no_overlay > 0) {
                printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
@@ -1680,8 +1695,7 @@ static int saa7134_s_fmt_overlay(struct file *file, void *priv,
        return 0;
 }
 
-static int saa7134_queryctrl(struct file *file, void *priv,
-                                       struct v4l2_queryctrl *c)
+int saa7134_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c)
 {
        const struct v4l2_queryctrl *ctrl;
 
@@ -1694,6 +1708,7 @@ static int saa7134_queryctrl(struct file *file, void *priv,
        *c = (NULL != ctrl) ? *ctrl : no_ctrl;
        return 0;
 }
+EXPORT_SYMBOL_GPL(saa7134_queryctrl);
 
 static int saa7134_enum_input(struct file *file, void *priv,
                                        struct v4l2_input *i)
@@ -1785,18 +1800,25 @@ static int saa7134_querycap(struct file *file, void  *priv,
                return 0;
 }
 
-static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id *id)
+int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id *id)
 {
-       struct saa7134_fh *fh = priv;
-       struct saa7134_dev *dev = fh->dev;
        unsigned long flags;
        unsigned int i;
        v4l2_std_id fixup;
        int err;
 
-       err = v4l2_prio_check(&dev->prio, &fh->prio);
-       if (0 != err)
-               return err;
+       /* When called from the empress code fh == NULL.
+          That needs to be fixed somehow, but for now this is
+          good enough. */
+       if (fh) {
+               err = v4l2_prio_check(&dev->prio, &fh->prio);
+               if (0 != err)
+                       return err;
+       } else if (res_locked(dev, RESOURCE_OVERLAY)) {
+               /* Don't change the std from the mpeg device
+                  if overlay is active. */
+               return -EBUSY;
+       }
 
        for (i = 0; i < TVNORMS; i++)
                if (*id == tvnorms[i].id)
@@ -1829,7 +1851,7 @@ static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id *id)
        *id = tvnorms[i].id;
 
        mutex_lock(&dev->lock);
-       if (res_check(fh, RESOURCE_OVERLAY)) {
+       if (fh && res_check(fh, RESOURCE_OVERLAY)) {
                spin_lock_irqsave(&dev->slock, flags);
                stop_preview(dev, fh);
                spin_unlock_irqrestore(&dev->slock, flags);
@@ -1846,6 +1868,23 @@ static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id *id)
        mutex_unlock(&dev->lock);
        return 0;
 }
+EXPORT_SYMBOL_GPL(saa7134_s_std_internal);
+
+static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id *id)
+{
+       struct saa7134_fh *fh = priv;
+
+       return saa7134_s_std_internal(fh->dev, fh, id);
+}
+
+static int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id)
+{
+       struct saa7134_fh *fh = priv;
+       struct saa7134_dev *dev = fh->dev;
+
+       *id = dev->tvnorm->id;
+       return 0;
+}
 
 static int saa7134_cropcap(struct file *file, void *priv,
                                        struct v4l2_cropcap *cap)
@@ -2003,7 +2042,7 @@ static int saa7134_s_frequency(struct file *file, void *priv,
        mutex_lock(&dev->lock);
        dev->ctl_freq = f->frequency;
 
-       saa7134_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
+       saa_call_all(dev, tuner, s_frequency, f);
 
        saa7134_tvaudio_do_scan(dev);
        mutex_unlock(&dev->lock);
@@ -2039,7 +2078,7 @@ static int saa7134_s_priority(struct file *file, void *f,
        return v4l2_prio_change(&dev->prio, &fh->prio, prio);
 }
 
-static int saa7134_enum_fmt_cap(struct file *file, void  *priv,
+static int saa7134_enum_fmt_vid_cap(struct file *file, void  *priv,
                                        struct v4l2_fmtdesc *f)
 {
        if (f->index >= FORMATS)
@@ -2053,7 +2092,7 @@ static int saa7134_enum_fmt_cap(struct file *file, void  *priv,
        return 0;
 }
 
-static int saa7134_enum_fmt_overlay(struct file *file, void  *priv,
+static int saa7134_enum_fmt_vid_overlay(struct file *file, void  *priv,
                                        struct v4l2_fmtdesc *f)
 {
        if (saa7134_no_overlay > 0) {
@@ -2072,18 +2111,6 @@ static int saa7134_enum_fmt_overlay(struct file *file, void  *priv,
        return 0;
 }
 
-static int saa7134_enum_fmt_vbi(struct file *file, void  *priv,
-                                       struct v4l2_fmtdesc *f)
-{
-       if (0 != f->index)
-               return -EINVAL;
-
-       f->pixelformat = V4L2_PIX_FMT_GREY;
-       strcpy(f->description, "vbi data");
-
-       return 0;
-}
-
 static int saa7134_g_fbuf(struct file *file, void *f,
                                struct v4l2_framebuffer *fb)
 {
@@ -2219,6 +2246,33 @@ static int saa7134_g_parm(struct file *file, void *fh,
        return 0;
 }
 
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int vidioc_g_register (struct file *file, void *priv,
+                             struct v4l2_dbg_register *reg)
+{
+       struct saa7134_fh *fh = priv;
+       struct saa7134_dev *dev = fh->dev;
+
+       if (!v4l2_chip_match_host(&reg->match))
+               return -EINVAL;
+       reg->val = saa_readb(reg->reg);
+       reg->size = 1;
+       return 0;
+}
+
+static int vidioc_s_register (struct file *file, void *priv,
+                               struct v4l2_dbg_register *reg)
+{
+       struct saa7134_fh *fh = priv;
+       struct saa7134_dev *dev = fh->dev;
+
+       if (!v4l2_chip_match_host(&reg->match))
+               return -EINVAL;
+       saa_writeb(reg->reg&0xffffff, reg->val);
+       return 0;
+}
+#endif
+
 static int radio_querycap(struct file *file, void *priv,
                                        struct v4l2_capability *cap)
 {
@@ -2246,7 +2300,7 @@ static int radio_g_tuner(struct file *file, void *priv,
        strcpy(t->name, "Radio");
        t->type = V4L2_TUNER_RADIO;
 
-       saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
+       saa_call_all(dev, tuner, g_tuner, t);
        if (dev->input->amux == TV) {
                t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11);
                t->rxsubchans = (saa_readb(0x529) & 0x08) ?
@@ -2263,7 +2317,7 @@ static int radio_s_tuner(struct file *file, void *priv,
        if (0 != t->index)
                return -EINVAL;
 
-       saa7134_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
+       saa_call_all(dev, tuner, s_tuner, t);
        return 0;
 }
 
@@ -2325,7 +2379,7 @@ static int radio_queryctrl(struct file *file, void *priv,
        return 0;
 }
 
-static const struct file_operations video_fops =
+static const struct v4l2_file_operations video_fops =
 {
        .owner    = THIS_MODULE,
        .open     = video_open,
@@ -2334,43 +2388,21 @@ static const struct file_operations video_fops =
        .poll     = video_poll,
        .mmap     = video_mmap,
        .ioctl    = video_ioctl2,
-       .compat_ioctl   = v4l_compat_ioctl32,
-       .llseek   = no_llseek,
 };
 
-static const struct file_operations radio_fops =
-{
-       .owner    = THIS_MODULE,
-       .open     = video_open,
-       .release  = video_release,
-       .ioctl    = video_ioctl2,
-       .compat_ioctl   = v4l_compat_ioctl32,
-       .llseek   = no_llseek,
-};
-
-/* ----------------------------------------------------------- */
-/* exported stuff                                              */
-
-struct video_device saa7134_video_template =
-{
-       .name                           = "saa7134-video",
-       .type                           = VID_TYPE_CAPTURE|VID_TYPE_TUNER |
-                                       VID_TYPE_CLIPPING|VID_TYPE_SCALES,
-       .fops                           = &video_fops,
-       .minor                          = -1,
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
        .vidioc_querycap                = saa7134_querycap,
-       .vidioc_enum_fmt_cap            = saa7134_enum_fmt_cap,
-       .vidioc_g_fmt_cap               = saa7134_g_fmt_cap,
-       .vidioc_try_fmt_cap             = saa7134_try_fmt_cap,
-       .vidioc_s_fmt_cap               = saa7134_s_fmt_cap,
-       .vidioc_enum_fmt_overlay        = saa7134_enum_fmt_overlay,
-       .vidioc_g_fmt_overlay           = saa7134_g_fmt_overlay,
-       .vidioc_try_fmt_overlay         = saa7134_try_fmt_overlay,
-       .vidioc_s_fmt_overlay           = saa7134_s_fmt_overlay,
-       .vidioc_enum_fmt_vbi            = saa7134_enum_fmt_vbi,
-       .vidioc_g_fmt_vbi               = saa7134_try_get_set_fmt_vbi,
-       .vidioc_try_fmt_vbi             = saa7134_try_get_set_fmt_vbi,
-       .vidioc_s_fmt_vbi               = saa7134_try_get_set_fmt_vbi,
+       .vidioc_enum_fmt_vid_cap        = saa7134_enum_fmt_vid_cap,
+       .vidioc_g_fmt_vid_cap           = saa7134_g_fmt_vid_cap,
+       .vidioc_try_fmt_vid_cap         = saa7134_try_fmt_vid_cap,
+       .vidioc_s_fmt_vid_cap           = saa7134_s_fmt_vid_cap,
+       .vidioc_enum_fmt_vid_overlay    = saa7134_enum_fmt_vid_overlay,
+       .vidioc_g_fmt_vid_overlay       = saa7134_g_fmt_vid_overlay,
+       .vidioc_try_fmt_vid_overlay     = saa7134_try_fmt_vid_overlay,
+       .vidioc_s_fmt_vid_overlay       = saa7134_s_fmt_vid_overlay,
+       .vidioc_g_fmt_vbi_cap           = saa7134_try_get_set_fmt_vbi_cap,
+       .vidioc_try_fmt_vbi_cap         = saa7134_try_get_set_fmt_vbi_cap,
+       .vidioc_s_fmt_vbi_cap           = saa7134_try_get_set_fmt_vbi_cap,
        .vidioc_g_audio                 = saa7134_g_audio,
        .vidioc_s_audio                 = saa7134_s_audio,
        .vidioc_cropcap                 = saa7134_cropcap,
@@ -2379,6 +2411,7 @@ struct video_device saa7134_video_template =
        .vidioc_qbuf                    = saa7134_qbuf,
        .vidioc_dqbuf                   = saa7134_dqbuf,
        .vidioc_s_std                   = saa7134_s_std,
+       .vidioc_g_std                   = saa7134_g_std,
        .vidioc_enum_input              = saa7134_enum_input,
        .vidioc_g_input                 = saa7134_g_input,
        .vidioc_s_input                 = saa7134_s_input,
@@ -2402,24 +2435,20 @@ struct video_device saa7134_video_template =
        .vidioc_g_parm                  = saa7134_g_parm,
        .vidioc_g_frequency             = saa7134_g_frequency,
        .vidioc_s_frequency             = saa7134_s_frequency,
-       .tvnorms                        = SAA7134_NORMS,
-       .current_norm                   = V4L2_STD_PAL,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       .vidioc_g_register              = vidioc_g_register,
+       .vidioc_s_register              = vidioc_s_register,
+#endif
 };
 
-struct video_device saa7134_vbi_template =
-{
-       .name          = "saa7134-vbi",
-       .type          = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
-       .fops          = &video_fops,
-       .minor         = -1,
+static const struct v4l2_file_operations radio_fops = {
+       .owner    = THIS_MODULE,
+       .open     = video_open,
+       .release  = video_release,
+       .ioctl    = video_ioctl2,
 };
 
-struct video_device saa7134_radio_template =
-{
-       .name                   = "saa7134-radio",
-       .type                   = VID_TYPE_TUNER,
-       .fops                   = &radio_fops,
-       .minor                  = -1,
+static const struct v4l2_ioctl_ops radio_ioctl_ops = {
        .vidioc_querycap        = radio_querycap,
        .vidioc_g_tuner         = radio_g_tuner,
        .vidioc_enum_input      = radio_enum_input,
@@ -2436,6 +2465,25 @@ struct video_device saa7134_radio_template =
        .vidioc_s_frequency     = saa7134_s_frequency,
 };
 
+/* ----------------------------------------------------------- */
+/* exported stuff                                              */
+
+struct video_device saa7134_video_template = {
+       .name                           = "saa7134-video",
+       .fops                           = &video_fops,
+       .ioctl_ops                      = &video_ioctl_ops,
+       .minor                          = -1,
+       .tvnorms                        = SAA7134_NORMS,
+       .current_norm                   = V4L2_STD_PAL,
+};
+
+struct video_device saa7134_radio_template = {
+       .name                   = "saa7134-radio",
+       .fops                   = &radio_fops,
+       .ioctl_ops              = &radio_ioctl_ops,
+       .minor                  = -1,
+};
+
 int saa7134_video_init1(struct saa7134_dev *dev)
 {
        /* sanitycheck insmod options */
@@ -2477,13 +2525,14 @@ int saa7134_videoport_init(struct saa7134_dev *dev)
        int vo = saa7134_boards[dev->board].video_out;
        int video_reg;
        unsigned int vid_port_opts = saa7134_boards[dev->board].vid_port_opts;
+
+       /* Configure videoport */
        saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]);
        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]);
        video_reg = video_out[vo][5];
        if (vid_port_opts & SET_CLOCK_NOT_DELAYED)
@@ -2500,6 +2549,9 @@ int saa7134_videoport_init(struct saa7134_dev *dev)
        saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]);
        saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]);
 
+       /* Start videoport */
+       saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);
+
        return 0;
 }