]> err.no Git - linux-2.6/blobdiff - drivers/media/video/saa7134/saa7134-video.c
V4L/DVB (6735): Reorder functions to make easier to compare with the previous code
[linux-2.6] / drivers / media / video / saa7134 / saa7134-video.c
index 9c317ed6b210af29db192eef46249a3858df60fd..76b841dd7ec0159410f47a58274a4163086f1a6c 100644 (file)
@@ -40,7 +40,7 @@
 
 static unsigned int video_debug   = 0;
 static unsigned int gbuffers      = 8;
-static unsigned int noninterlaced = 1;
+static unsigned int noninterlaced = 0;
 static unsigned int gbufsize      = 720*576*4;
 static unsigned int gbufsize_max  = 720*576*4;
 static char secam[] = "--";
@@ -542,20 +542,10 @@ void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits)
 
 static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
 {
-       int luma_control,sync_control,mux;
 
        dprintk("set tv norm = %s\n",norm->name);
        dev->tvnorm = norm;
 
-       mux = card_in(dev,dev->ctl_input).vmux;
-       luma_control = norm->luma_control;
-       sync_control = norm->sync_control;
-
-       if (mux > 5)
-               luma_control |= 0x80; /* svideo */
-       if (noninterlaced || dev->nosignal)
-               sync_control |= 0x20;
-
        /* setup cropping */
        dev->crop_bounds.left    = norm->h_start;
        dev->crop_defrect.left   = norm->h_start;
@@ -570,6 +560,34 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
 
        dev->crop_current = dev->crop_defrect;
 
+       saa7134_set_tvnorm_hw(dev);
+
+}
+
+static void video_mux(struct saa7134_dev *dev, int input)
+{
+       dprintk("video input = %d [%s]\n", input, card_in(dev, input).name);
+       dev->ctl_input = input;
+       set_tvnorm(dev, dev->tvnorm);
+       saa7134_tvaudio_setinput(dev, &card_in(dev, input));
+}
+
+
+static void saa7134_set_decoder(struct saa7134_dev *dev)
+{
+       int luma_control, sync_control, mux;
+
+       struct saa7134_tvnorm *norm = dev->tvnorm;
+       mux = card_in(dev, dev->ctl_input).vmux;
+
+       luma_control = norm->luma_control;
+       sync_control = norm->sync_control;
+
+       if (mux > 5)
+               luma_control |= 0x80; /* svideo */
+       if (noninterlaced || dev->nosignal)
+               sync_control |= 0x20;
+
        /* setup video decoder */
        saa_writeb(SAA7134_INCR_DELAY,            0x08);
        saa_writeb(SAA7134_ANALOG_IN_CTRL1,       0xc0 | mux);
@@ -584,9 +602,13 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
        saa_writeb(SAA7134_SYNC_CTRL,             sync_control);
        saa_writeb(SAA7134_LUMA_CTRL,             luma_control);
        saa_writeb(SAA7134_DEC_LUMA_BRIGHT,       dev->ctl_bright);
-       saa_writeb(SAA7134_DEC_LUMA_CONTRAST,     dev->ctl_contrast);
 
-       saa_writeb(SAA7134_DEC_CHROMA_SATURATION, dev->ctl_saturation);
+       saa_writeb(SAA7134_DEC_LUMA_CONTRAST,
+               dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);
+
+       saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
+               dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
+
        saa_writeb(SAA7134_DEC_CHROMA_HUE,        dev->ctl_hue);
        saa_writeb(SAA7134_CHROMA_CTRL1,          norm->chroma_ctrl1);
        saa_writeb(SAA7134_CHROMA_GAIN,           norm->chroma_gain);
@@ -600,25 +622,21 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
        saa_writeb(SAA7134_MISC_VGATE_MSB,        norm->vgate_misc);
        saa_writeb(SAA7134_RAW_DATA_GAIN,         0x40);
        saa_writeb(SAA7134_RAW_DATA_OFFSET,       0x80);
+}
 
-       /* only tell the tuner if this is a tv input */
-       if (card_in(dev,dev->ctl_input).tv) {
+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,&norm->id);
+               saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id);
        }
 }
 
-static void video_mux(struct saa7134_dev *dev, int input)
-{
-       dprintk("video input = %d [%s]\n",input,card_in(dev,input).name);
-       dev->ctl_input = input;
-       set_tvnorm(dev,dev->tvnorm);
-       saa7134_tvaudio_setinput(dev,&card_in(dev,input));
-}
-
 static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
 {
        static const struct {
@@ -927,7 +945,7 @@ static int buffer_activate(struct saa7134_dev *dev,
        unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */
 
        dprintk("buffer_activate buf=%p\n",buf);
-       buf->vb.state = STATE_ACTIVE;
+       buf->vb.state = VIDEOBUF_ACTIVE;
        buf->top_seen = 0;
 
        set_size(dev,TASK_A,buf->vb.width,buf->vb.height,
@@ -1036,7 +1054,9 @@ static int buffer_prepare(struct videobuf_queue *q,
                saa7134_dma_free(q,buf);
        }
 
-       if (STATE_NEEDS_INIT == buf->vb.state) {
+       if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
+               struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
+
                buf->vb.width  = fh->width;
                buf->vb.height = fh->height;
                buf->vb.size   = size;
@@ -1048,13 +1068,13 @@ static int buffer_prepare(struct videobuf_queue *q,
                if (err)
                        goto oops;
                err = saa7134_pgtable_build(dev->pci,buf->pt,
-                                           buf->vb.dma.sglist,
-                                           buf->vb.dma.sglen,
+                                           dma->sglist,
+                                           dma->sglen,
                                            saa7134_buffer_startpage(buf));
                if (err)
                        goto oops;
        }
-       buf->vb.state = STATE_PREPARED;
+       buf->vb.state = VIDEOBUF_PREPARED;
        buf->activate = buffer_activate;
        return 0;
 
@@ -1099,8 +1119,11 @@ static struct videobuf_queue_ops video_qops = {
 
 /* ------------------------------------------------------------------ */
 
-static int get_control(struct saa7134_dev *dev, struct v4l2_control *c)
+static int vidioc_g_ctrl(struct file *file, void *priv,
+                                       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);
@@ -1146,13 +1169,16 @@ static int get_control(struct saa7134_dev *dev, struct v4l2_control *c)
        return 0;
 }
 
-static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh,
-                      struct v4l2_control *c)
+static int vidioc_s_ctrl(struct file *file, void *f,
+                                       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;
 
+       mutex_lock(&dev->lock);
        ctrl = ctrl_by_id(c->id);
        if (NULL == ctrl)
                return -EINVAL;
@@ -1216,17 +1242,26 @@ static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh,
                restart_overlay = 1;
                break;
        case V4L2_CID_PRIVATE_AUTOMUTE:
+       {
+               struct v4l2_priv_tun_config tda9887_cfg;
+
+               tda9887_cfg.tuner = TUNER_TDA9887;
+               tda9887_cfg.priv = &dev->tda9887_conf;
+
                dev->ctl_automute = c->value;
                if (dev->tda9887_conf) {
                        if (dev->ctl_automute)
                                dev->tda9887_conf |= TDA9887_AUTOMUTE;
                        else
                                dev->tda9887_conf &= ~TDA9887_AUTOMUTE;
-                       saa7134_i2c_call_clients(dev, TDA9887_SET_CONFIG,
-                                                &dev->tda9887_conf);
+
+                       saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG,
+                                                &tda9887_cfg);
                }
                break;
+       }
        default:
+               mutex_unlock(&dev->lock);
                return -EINVAL;
        }
        if (restart_overlay && fh && res_check(fh, RESOURCE_OVERLAY)) {
@@ -1235,6 +1270,7 @@ static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh,
                start_preview(dev,fh);
                spin_unlock_irqrestore(&dev->slock,flags);
        }
+       mutex_unlock(&dev->lock);
        return 0;
 }
 
@@ -1272,26 +1308,24 @@ static int saa7134_resource(struct saa7134_fh *fh)
 static int video_open(struct inode *inode, struct file *file)
 {
        int minor = iminor(inode);
-       struct saa7134_dev *h,*dev = NULL;
+       struct saa7134_dev *dev;
        struct saa7134_fh *fh;
-       struct list_head *list;
        enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        int radio = 0;
-       list_for_each(list,&saa7134_devlist) {
-               h = list_entry(list, struct saa7134_dev, devlist);
-               if (h->video_dev && (h->video_dev->minor == minor))
-                       dev = h;
-               if (h->radio_dev && (h->radio_dev->minor == minor)) {
+       list_for_each_entry(dev, &saa7134_devlist, devlist) {
+               if (dev->video_dev && (dev->video_dev->minor == minor))
+                       goto found;
+               if (dev->radio_dev && (dev->radio_dev->minor == minor)) {
                        radio = 1;
-                       dev = h;
+                       goto found;
                }
-               if (h->vbi_dev && (h->vbi_dev->minor == minor)) {
+               if (dev->vbi_dev && (dev->vbi_dev->minor == minor)) {
                        type = V4L2_BUF_TYPE_VBI_CAPTURE;
-                       dev = h;
+                       goto found;
                }
        }
-       if (NULL == dev)
-               return -ENODEV;
+       return -ENODEV;
+ found:
 
        dprintk("open minor=%d radio=%d type=%s\n",minor,radio,
                v4l2_type_names[type]);
@@ -1309,13 +1343,13 @@ static int video_open(struct inode *inode, struct file *file)
        fh->height   = 576;
        v4l2_prio_open(&dev->prio,&fh->prio);
 
-       videobuf_queue_init(&fh->cap, &video_qops,
+       videobuf_queue_pci_init(&fh->cap, &video_qops,
                            dev->pci, &dev->slock,
                            V4L2_BUF_TYPE_VIDEO_CAPTURE,
                            V4L2_FIELD_INTERLACED,
                            sizeof(struct saa7134_buf),
                            fh);
-       videobuf_queue_init(&fh->vbi, &saa7134_vbi_qops,
+       videobuf_queue_pci_init(&fh->vbi, &saa7134_vbi_qops,
                            dev->pci, &dev->slock,
                            V4L2_BUF_TYPE_VBI_CAPTURE,
                            V4L2_FIELD_SEQ_TB,
@@ -1395,8 +1429,8 @@ video_poll(struct file *file, struct poll_table_struct *wait)
                return POLLERR;
 
        poll_wait(file, &buf->done, wait);
-       if (buf->state == STATE_DONE ||
-           buf->state == STATE_ERROR)
+       if (buf->state == VIDEOBUF_DONE ||
+           buf->state == VIDEOBUF_ERROR)
                return POLLIN|POLLRDNORM;
        return 0;
 }
@@ -1427,10 +1461,7 @@ static int video_release(struct inode *inode, struct file *file)
 
        /* stop vbi capture */
        if (res_check(fh, RESOURCE_VBI)) {
-               if (fh->vbi.streaming)
-                       videobuf_streamoff(&fh->vbi);
-               if (fh->vbi.reading)
-                       videobuf_read_stop(&fh->vbi);
+               videobuf_stop(&fh->vbi);
                res_free(dev,fh,RESOURCE_VBI);
        }
 
@@ -1479,9 +1510,12 @@ static void saa7134_vbi_fmt(struct saa7134_dev *dev, struct v4l2_format *f)
 
 }
 
-static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
-                        struct v4l2_format *f)
+static int vidioc_g_fmt_cap(struct file *file, void *priv,
+                               struct v4l2_format *f)
 {
+       struct saa7134_fh *fh = priv;
+       struct saa7134_dev *dev = fh->dev;
+
        switch (f->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
                memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
@@ -1509,9 +1543,11 @@ static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
        }
 }
 
-static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
-                          struct v4l2_format *f)
+static int vidioc_try_fmt_cap(struct file *file, void *priv,
+                                               struct v4l2_format *f)
 {
+       struct saa7134_fh *fh = priv;
+       struct saa7134_dev *dev = fh->dev;
        int err;
 
        switch (f->type) {
@@ -1579,15 +1615,17 @@ static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
        }
 }
 
-static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
-                        struct v4l2_format *f)
+static int vidioc_s_fmt_cap(struct file *file, void *priv,
+                                       struct v4l2_format *f)
 {
+       struct saa7134_fh *fh = priv;
+       struct saa7134_dev *dev = fh->dev;
        unsigned long flags;
        int err;
 
        switch (f->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-               err = saa7134_try_fmt(dev,fh,f);
+               err = vidioc_try_fmt_cap(file, priv, f);
                if (0 != err)
                        return err;
 
@@ -1632,700 +1670,625 @@ static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
        }
 }
 
-int saa7134_common_ioctl(struct saa7134_dev *dev,
-                        unsigned int cmd, void *arg)
+static int vidioc_queryctrl(struct file *file, void *priv,
+                                       struct v4l2_queryctrl *c)
 {
-       int err;
-
-       switch (cmd) {
-       case VIDIOC_QUERYCTRL:
-       {
-               const struct v4l2_queryctrl *ctrl;
-               struct v4l2_queryctrl *c = arg;
+       const struct v4l2_queryctrl *ctrl;
 
-               if ((c->id <  V4L2_CID_BASE ||
-                    c->id >= V4L2_CID_LASTP1) &&
-                   (c->id <  V4L2_CID_PRIVATE_BASE ||
-                    c->id >= V4L2_CID_PRIVATE_LASTP1))
-                       return -EINVAL;
-               ctrl = ctrl_by_id(c->id);
-               *c = (NULL != ctrl) ? *ctrl : no_ctrl;
-               return 0;
-       }
-       case VIDIOC_G_CTRL:
-               return get_control(dev,arg);
-       case VIDIOC_S_CTRL:
-       {
-               mutex_lock(&dev->lock);
-               err = set_control(dev,NULL,arg);
-               mutex_unlock(&dev->lock);
-               return err;
-       }
-       /* --- input switching --------------------------------------- */
-       case VIDIOC_ENUMINPUT:
-       {
-               struct v4l2_input *i = arg;
-               unsigned int n;
-
-               n = i->index;
-               if (n >= SAA7134_INPUT_MAX)
-                       return -EINVAL;
-               if (NULL == card_in(dev,i->index).name)
-                       return -EINVAL;
-               memset(i,0,sizeof(*i));
-               i->index = n;
-               i->type  = V4L2_INPUT_TYPE_CAMERA;
-               strcpy(i->name,card_in(dev,n).name);
-               if (card_in(dev,n).tv)
-                       i->type = V4L2_INPUT_TYPE_TUNER;
-               i->audioset = 1;
-               if (n == dev->ctl_input) {
-                       int v1 = saa_readb(SAA7134_STATUS_VIDEO1);
-                       int v2 = saa_readb(SAA7134_STATUS_VIDEO2);
-
-                       if (0 != (v1 & 0x40))
-                               i->status |= V4L2_IN_ST_NO_H_LOCK;
-                       if (0 != (v2 & 0x40))
-                               i->status |= V4L2_IN_ST_NO_SYNC;
-                       if (0 != (v2 & 0x0e))
-                               i->status |= V4L2_IN_ST_MACROVISION;
-               }
-               for (n = 0; n < TVNORMS; n++)
-                       i->std |= tvnorms[n].id;
-               return 0;
-       }
-       case VIDIOC_G_INPUT:
-       {
-               int *i = arg;
-               *i = dev->ctl_input;
-               return 0;
-       }
-       case VIDIOC_S_INPUT:
-       {
-               int *i = arg;
-
-               if (*i < 0  ||  *i >= SAA7134_INPUT_MAX)
-                       return -EINVAL;
-               if (NULL == card_in(dev,*i).name)
-                       return -EINVAL;
-               mutex_lock(&dev->lock);
-               video_mux(dev,*i);
-               mutex_unlock(&dev->lock);
-               return 0;
-       }
-
-       }
+       if ((c->id <  V4L2_CID_BASE ||
+            c->id >= V4L2_CID_LASTP1) &&
+           (c->id <  V4L2_CID_PRIVATE_BASE ||
+            c->id >= V4L2_CID_PRIVATE_LASTP1))
+               return -EINVAL;
+       ctrl = ctrl_by_id(c->id);
+       *c = (NULL != ctrl) ? *ctrl : no_ctrl;
        return 0;
 }
-EXPORT_SYMBOL(saa7134_common_ioctl);
 
-/*
- * This function is _not_ called directly, but from
- * video_generic_ioctl (and maybe others).  userspace
- * copying is done already, arg is a kernel pointer.
- */
-static int video_do_ioctl(struct inode *inode, struct file *file,
-                         unsigned int cmd, void *arg)
+static int vidioc_enum_input(struct file *file, void *priv,
+                                       struct v4l2_input *i)
 {
-       struct saa7134_fh *fh = file->private_data;
+       struct saa7134_fh *fh = priv;
        struct saa7134_dev *dev = fh->dev;
-       unsigned long flags;
-       int err;
+       unsigned int n;
 
-       if (video_debug > 1)
-               v4l_print_ioctl(dev->name,cmd);
+       n = i->index;
+       if (n >= SAA7134_INPUT_MAX)
+               return -EINVAL;
+       if (NULL == card_in(dev, i->index).name)
+               return -EINVAL;
+       memset(i, 0, sizeof(*i));
+       i->index = n;
+       i->type  = V4L2_INPUT_TYPE_CAMERA;
+       strcpy(i->name, card_in(dev, n).name);
+       if (card_in(dev, n).tv)
+               i->type = V4L2_INPUT_TYPE_TUNER;
+       i->audioset = 1;
+       if (n == dev->ctl_input) {
+               int v1 = saa_readb(SAA7134_STATUS_VIDEO1);
+               int v2 = saa_readb(SAA7134_STATUS_VIDEO2);
+
+               if (0 != (v1 & 0x40))
+                       i->status |= V4L2_IN_ST_NO_H_LOCK;
+               if (0 != (v2 & 0x40))
+                       i->status |= V4L2_IN_ST_NO_SYNC;
+               if (0 != (v2 & 0x0e))
+                       i->status |= V4L2_IN_ST_MACROVISION;
+       }
+       for (n = 0; n < TVNORMS; n++)
+               i->std |= tvnorms[n].id;
+       return 0;
+}
 
-       switch (cmd) {
-       case VIDIOC_S_CTRL:
-       case VIDIOC_S_STD:
-       case VIDIOC_S_INPUT:
-       case VIDIOC_S_TUNER:
-       case VIDIOC_S_FREQUENCY:
-               err = v4l2_prio_check(&dev->prio,&fh->prio);
-               if (0 != err)
-                       return err;
-       }
+static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+{
+       struct saa7134_fh *fh = priv;
+       struct saa7134_dev *dev = fh->dev;
 
-       switch (cmd) {
-       case VIDIOC_QUERYCAP:
-       {
-               struct v4l2_capability *cap = arg;
-               unsigned int tuner_type = dev->tuner_type;
-
-               memset(cap,0,sizeof(*cap));
-               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_VBI_CAPTURE |
-                       V4L2_CAP_READWRITE |
-                       V4L2_CAP_STREAMING |
-                       V4L2_CAP_TUNER;
-               if (saa7134_no_overlay <= 0) {
-                       cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
-               }
+       *i = dev->ctl_input;
+       return 0;
+}
 
-               if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET))
-                       cap->capabilities &= ~V4L2_CAP_TUNER;
+static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+       struct saa7134_fh *fh = priv;
+       struct saa7134_dev *dev = fh->dev;
 
-               return 0;
-       }
+       if (i < 0  ||  i >= SAA7134_INPUT_MAX)
+               return -EINVAL;
+       if (NULL == card_in(dev, i).name)
+               return -EINVAL;
+       mutex_lock(&dev->lock);
+       video_mux(dev, i);
+       mutex_unlock(&dev->lock);
+       return 0;
+}
 
-       /* --- tv standards ------------------------------------------ */
-       case VIDIOC_ENUMSTD:
-       {
-               struct v4l2_standard *e = arg;
-               unsigned int i;
+static int vidioc_querycap(struct file *file, void  *priv,
+                                       struct v4l2_capability *cap)
+{
+       struct saa7134_fh *fh = priv;
+       struct saa7134_dev *dev = fh->dev;
 
-               i = e->index;
-               if (i >= TVNORMS)
-                       return -EINVAL;
-               err = v4l2_video_std_construct(e, tvnorms[e->index].id,
-                                              tvnorms[e->index].name);
-               e->index = i;
-               if (err < 0)
-                       return err;
+       unsigned int tuner_type = dev->tuner_type;
+
+       memset(cap, 0, sizeof(*cap));
+       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_VBI_CAPTURE |
+               V4L2_CAP_READWRITE |
+               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;
-       }
-       case VIDIOC_G_STD:
-       {
-               v4l2_std_id *id = arg;
+}
 
-               *id = dev->tvnorm->id;
-               return 0;
-       }
-       case VIDIOC_S_STD:
-       {
-               v4l2_std_id *id = arg;
-               unsigned int i;
-               v4l2_std_id fixup;
+static int vidioc_s_std(struct file *file, void *priv, 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;
 
+       for (i = 0; i < TVNORMS; i++)
+               if (*id == tvnorms[i].id)
+                       break;
+       if (i == TVNORMS)
                for (i = 0; i < TVNORMS; i++)
-                       if (*id == tvnorms[i].id)
+                       if (*id & tvnorms[i].id)
                                break;
-               if (i == TVNORMS)
-                       for (i = 0; i < TVNORMS; i++)
-                               if (*id & tvnorms[i].id)
-                                       break;
-               if (i == TVNORMS)
-                       return -EINVAL;
-               if ((*id & V4L2_STD_SECAM) && (secam[0] != '-')) {
-                       if (secam[0] == 'L' || secam[0] == 'l') {
-                               if (secam[1] == 'C' || secam[1] == 'c')
-                                       fixup = V4L2_STD_SECAM_LC;
-                               else
-                                       fixup = V4L2_STD_SECAM_L;
-                       } else {
-                               if (secam[0] == 'D' || secam[0] == 'd')
-                                       fixup = V4L2_STD_SECAM_DK;
-                               else
-                                       fixup = V4L2_STD_SECAM;
-                       }
-                       for (i = 0; i < TVNORMS; i++)
-                               if (fixup == tvnorms[i].id)
-                                       break;
+       if (i == TVNORMS)
+               return -EINVAL;
+       if ((*id & V4L2_STD_SECAM) && (secam[0] != '-')) {
+               if (secam[0] == 'L' || secam[0] == 'l') {
+                       if (secam[1] == 'C' || secam[1] == 'c')
+                               fixup = V4L2_STD_SECAM_LC;
+                       else
+                               fixup = V4L2_STD_SECAM_L;
+               } else {
+                       if (secam[0] == 'D' || secam[0] == 'd')
+                               fixup = V4L2_STD_SECAM_DK;
+                       else
+                               fixup = V4L2_STD_SECAM;
                }
-               mutex_lock(&dev->lock);
-               if (res_check(fh, RESOURCE_OVERLAY)) {
-                       spin_lock_irqsave(&dev->slock,flags);
-                       stop_preview(dev,fh);
-                       set_tvnorm(dev,&tvnorms[i]);
-                       start_preview(dev,fh);
-                       spin_unlock_irqrestore(&dev->slock,flags);
-               } else
-                       set_tvnorm(dev,&tvnorms[i]);
-               saa7134_tvaudio_do_scan(dev);
-               mutex_unlock(&dev->lock);
-               return 0;
+               for (i = 0; i < TVNORMS; i++)
+                       if (fixup == tvnorms[i].id)
+                               break;
        }
+       mutex_lock(&dev->lock);
+       if (res_check(fh, RESOURCE_OVERLAY)) {
+               spin_lock_irqsave(&dev->slock, flags);
+               stop_preview(dev, fh);
+               spin_unlock_irqrestore(&dev->slock, flags);
+
+               set_tvnorm(dev, &tvnorms[i]);
+
+               spin_lock_irqsave(&dev->slock, flags);
+               start_preview(dev, fh);
+               spin_unlock_irqrestore(&dev->slock, flags);
+       } else
+               set_tvnorm(dev, &tvnorms[i]);
+       saa7134_tvaudio_do_scan(dev);
+       mutex_unlock(&dev->lock);
+       return 0;
+}
 
-       case VIDIOC_CROPCAP:
-       {
-               struct v4l2_cropcap *cap = arg;
+static int vidioc_cropcap(struct file *file, void *priv,
+                                       struct v4l2_cropcap *cap)
+{
+       struct saa7134_fh *fh = priv;
+       struct saa7134_dev *dev = fh->dev;
 
-               if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
-                   cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
-                       return -EINVAL;
-               cap->bounds  = dev->crop_bounds;
-               cap->defrect = dev->crop_defrect;
-               cap->pixelaspect.numerator   = 1;
-               cap->pixelaspect.denominator = 1;
-               if (dev->tvnorm->id & V4L2_STD_525_60) {
-                       cap->pixelaspect.numerator   = 11;
-                       cap->pixelaspect.denominator = 10;
-               }
-               if (dev->tvnorm->id & V4L2_STD_625_50) {
-                       cap->pixelaspect.numerator   = 54;
-                       cap->pixelaspect.denominator = 59;
-               }
-               return 0;
+       if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+           cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
+               return -EINVAL;
+       cap->bounds  = dev->crop_bounds;
+       cap->defrect = dev->crop_defrect;
+       cap->pixelaspect.numerator   = 1;
+       cap->pixelaspect.denominator = 1;
+       if (dev->tvnorm->id & V4L2_STD_525_60) {
+               cap->pixelaspect.numerator   = 11;
+               cap->pixelaspect.denominator = 10;
+       }
+       if (dev->tvnorm->id & V4L2_STD_625_50) {
+               cap->pixelaspect.numerator   = 54;
+               cap->pixelaspect.denominator = 59;
        }
+       return 0;
+}
 
-       case VIDIOC_G_CROP:
-       {
-               struct v4l2_crop * crop = arg;
+static int vidioc_g_crop(struct file *file, void *f, struct v4l2_crop *crop)
+{
+       struct saa7134_fh *fh = f;
+       struct saa7134_dev *dev = fh->dev;
 
-               if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
-                   crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
-                       return -EINVAL;
-               crop->c = dev->crop_current;
-               return 0;
-       }
-       case VIDIOC_S_CROP:
-       {
-               struct v4l2_crop *crop = arg;
-               struct v4l2_rect *b = &dev->crop_bounds;
+       if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+           crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
+               return -EINVAL;
+       crop->c = dev->crop_current;
+       return 0;
+}
 
-               if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
-                   crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
-                       return -EINVAL;
-               if (crop->c.height < 0)
-                       return -EINVAL;
-               if (crop->c.width < 0)
-                       return -EINVAL;
+static int vidioc_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
+{
+       struct saa7134_fh *fh = f;
+       struct saa7134_dev *dev = fh->dev;
+       struct v4l2_rect *b = &dev->crop_bounds;
 
-               if (res_locked(fh->dev,RESOURCE_OVERLAY))
-                       return -EBUSY;
-               if (res_locked(fh->dev,RESOURCE_VIDEO))
-                       return -EBUSY;
+       if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+           crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
+               return -EINVAL;
+       if (crop->c.height < 0)
+               return -EINVAL;
+       if (crop->c.width < 0)
+               return -EINVAL;
 
-               if (crop->c.top < b->top)
-                       crop->c.top = b->top;
-               if (crop->c.top > b->top + b->height)
-                       crop->c.top = b->top + b->height;
-               if (crop->c.height > b->top - crop->c.top + b->height)
-                       crop->c.height = b->top - crop->c.top + b->height;
-
-               if (crop->c.left < b->left)
-                       crop->c.left = b->left;
-               if (crop->c.left > 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;
-
-               dev->crop_current = crop->c;
-               return 0;
-       }
+       if (res_locked(fh->dev, RESOURCE_OVERLAY))
+               return -EBUSY;
+       if (res_locked(fh->dev, RESOURCE_VIDEO))
+               return -EBUSY;
+
+       if (crop->c.top < b->top)
+               crop->c.top = b->top;
+       if (crop->c.top > b->top + b->height)
+               crop->c.top = b->top + b->height;
+       if (crop->c.height > b->top - crop->c.top + b->height)
+               crop->c.height = b->top - crop->c.top + b->height;
+
+       if (crop->c.left < b->left)
+               crop->c.left = b->left;
+       if (crop->c.left > 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;
+
+       dev->crop_current = crop->c;
+       return 0;
+}
 
-       /* --- tuner ioctls ------------------------------------------ */
-       case VIDIOC_G_TUNER:
-       {
-               struct v4l2_tuner *t = arg;
-               int n;
+static int vidioc_g_tuner(struct file *file, void *priv,
+                                       struct v4l2_tuner *t)
+{
+       struct saa7134_fh *fh = priv;
+       struct saa7134_dev *dev = fh->dev;
+       int n;
 
-               if (0 != t->index)
-                       return -EINVAL;
-               memset(t,0,sizeof(*t));
-               for (n = 0; n < SAA7134_INPUT_MAX; n++)
-                       if (card_in(dev,n).tv)
-                               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 |
-                               V4L2_TUNER_CAP_LANG2;
-                       t->rangehigh = 0xffffffffUL;
-                       t->rxsubchans = saa7134_tvaudio_getstereo(dev);
-                       t->audmode = saa7134_tvaudio_rx2mode(t->rxsubchans);
-               }
-               if (0 != (saa_readb(SAA7134_STATUS_VIDEO1) & 0x03))
-                       t->signal = 0xffff;
-               return 0;
-       }
-       case VIDIOC_S_TUNER:
-       {
-               struct v4l2_tuner *t = arg;
-               int rx,mode;
+       if (0 != t->index)
+               return -EINVAL;
+       memset(t, 0, sizeof(*t));
+       for (n = 0; n < SAA7134_INPUT_MAX; n++)
+               if (card_in(dev, n).tv)
+                       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 |
+                       V4L2_TUNER_CAP_LANG2;
+               t->rangehigh = 0xffffffffUL;
+               t->rxsubchans = saa7134_tvaudio_getstereo(dev);
+               t->audmode = saa7134_tvaudio_rx2mode(t->rxsubchans);
+       }
+       if (0 != (saa_readb(SAA7134_STATUS_VIDEO1) & 0x03))
+               t->signal = 0xffff;
+       return 0;
+}
 
-               mode = dev->thread.mode;
-               if (UNSET == mode) {
-                       rx   = saa7134_tvaudio_getstereo(dev);
-                       mode = saa7134_tvaudio_rx2mode(t->rxsubchans);
-               }
-               if (mode != t->audmode) {
-                       dev->thread.mode = t->audmode;
-               }
-               return 0;
-       }
-       case VIDIOC_G_FREQUENCY:
-       {
-               struct v4l2_frequency *f = arg;
+static int vidioc_s_tuner(struct file *file, void *priv,
+                                       struct v4l2_tuner *t)
+{
+       struct saa7134_fh *fh = priv;
+       struct saa7134_dev *dev = fh->dev;
+       int rx, mode;
 
-               memset(f,0,sizeof(*f));
-               f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
-               f->frequency = dev->ctl_freq;
-               return 0;
+       mode = dev->thread.mode;
+       if (UNSET == mode) {
+               rx   = saa7134_tvaudio_getstereo(dev);
+               mode = saa7134_tvaudio_rx2mode(t->rxsubchans);
        }
-       case VIDIOC_S_FREQUENCY:
-       {
-               struct v4l2_frequency *f = arg;
+       if (mode != t->audmode)
+               dev->thread.mode = t->audmode;
+       return 0;
+}
 
-               if (0 != f->tuner)
-                       return -EINVAL;
-               if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type)
-                       return -EINVAL;
-               if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
-                       return -EINVAL;
-               mutex_lock(&dev->lock);
-               dev->ctl_freq = f->frequency;
+static int vidioc_g_frequency(struct file *file, void *priv,
+                                       struct v4l2_frequency *f)
+{
+       struct saa7134_fh *fh = priv;
+       struct saa7134_dev *dev = fh->dev;
 
-               saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f);
+       memset(f, 0, sizeof(*f));
+       f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+       f->frequency = dev->ctl_freq;
+       return 0;
+}
 
-               saa7134_tvaudio_do_scan(dev);
-               mutex_unlock(&dev->lock);
-               return 0;
-       }
+static int vidioc_s_frequency(struct file *file, void *priv,
+                                       struct v4l2_frequency *f)
+{
+       struct saa7134_fh *fh = priv;
+       struct saa7134_dev *dev = fh->dev;
 
-       /* --- control ioctls ---------------------------------------- */
-       case VIDIOC_ENUMINPUT:
-       case VIDIOC_G_INPUT:
-       case VIDIOC_S_INPUT:
-       case VIDIOC_QUERYCTRL:
-       case VIDIOC_G_CTRL:
-       case VIDIOC_S_CTRL:
-               return saa7134_common_ioctl(dev, cmd, arg);
+       if (0 != f->tuner)
+               return -EINVAL;
+       if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type)
+               return -EINVAL;
+       if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
+               return -EINVAL;
+       mutex_lock(&dev->lock);
+       dev->ctl_freq = f->frequency;
 
-       case VIDIOC_G_AUDIO:
-       {
-               struct v4l2_audio *a = arg;
+       saa7134_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
 
-               memset(a,0,sizeof(*a));
-               strcpy(a->name,"audio");
-               return 0;
-       }
-       case VIDIOC_S_AUDIO:
-               return 0;
-       case VIDIOC_G_PARM:
-       {
-               struct v4l2_captureparm *parm = arg;
-               memset(parm,0,sizeof(*parm));
-               return 0;
-       }
+       saa7134_tvaudio_do_scan(dev);
+       mutex_unlock(&dev->lock);
+       return 0;
+}
 
-       case VIDIOC_G_PRIORITY:
-       {
-               enum v4l2_priority *p = arg;
+static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+       memset(a, 0, sizeof(*a));
+       strcpy(a->name, "audio");
+       return 0;
+}
 
-               *p = v4l2_prio_max(&dev->prio);
-               return 0;
-       }
-       case VIDIOC_S_PRIORITY:
-       {
-               enum v4l2_priority *prio = arg;
+static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+       return 0;
+}
 
-               return v4l2_prio_change(&dev->prio, &fh->prio, *prio);
-       }
+static int vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p)
+{
+       struct saa7134_fh *fh = f;
+       struct saa7134_dev *dev = fh->dev;
 
-       /* --- preview ioctls ---------------------------------------- */
-       case VIDIOC_ENUM_FMT:
-       {
-               struct v4l2_fmtdesc *f = arg;
-               enum v4l2_buf_type type;
-               unsigned int index;
-
-               index = f->index;
-               type  = f->type;
-               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 &&
-                           formats[index].planar)
-                               return -EINVAL;
-                       memset(f,0,sizeof(*f));
-                       f->index = index;
-                       f->type  = type;
-                       strlcpy(f->description,formats[index].name,sizeof(f->description));
-                       f->pixelformat = formats[index].fourcc;
-                       break;
-               case V4L2_BUF_TYPE_VBI_CAPTURE:
-                       if (0 != index)
-                               return -EINVAL;
-                       memset(f,0,sizeof(*f));
-                       f->index = index;
-                       f->type  = type;
-                       f->pixelformat = V4L2_PIX_FMT_GREY;
-                       strcpy(f->description,"vbi data");
-                       break;
-               default:
-                       return -EINVAL;
-               }
-               return 0;
-       }
-       case VIDIOC_G_FBUF:
-       {
-               struct v4l2_framebuffer *fb = arg;
+       *p = v4l2_prio_max(&dev->prio);
+       return 0;
+}
 
-               *fb = dev->ovbuf;
-               fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
-               return 0;
-       }
-       case VIDIOC_S_FBUF:
-       {
-               struct v4l2_framebuffer *fb = arg;
-               struct saa7134_format *fmt;
+static int vidioc_s_priority(struct file *file, void *f,
+                                       enum v4l2_priority prio)
+{
+       struct saa7134_fh *fh = f;
+       struct saa7134_dev *dev = fh->dev;
 
-               if(!capable(CAP_SYS_ADMIN) &&
-                  !capable(CAP_SYS_RAWIO))
-                       return -EPERM;
+       return v4l2_prio_change(&dev->prio, &fh->prio, prio);
+}
 
-               /* check args */
-               fmt = format_by_fourcc(fb->fmt.pixelformat);
-               if (NULL == fmt)
+static int vidioc_enum_fmt_cap(struct file *file, void  *priv,
+                                       struct v4l2_fmtdesc *f)
+{
+       enum v4l2_buf_type type;
+       unsigned int index;
+
+       index = f->index;
+       type  = f->type;
+       switch (type) {
+       case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+       case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+               if (saa7134_no_overlay > 0)
                        return -EINVAL;
 
-               /* ok, accept it */
-               dev->ovbuf = *fb;
-               dev->ovfmt = fmt;
-               if (0 == dev->ovbuf.fmt.bytesperline)
-                       dev->ovbuf.fmt.bytesperline =
-                               dev->ovbuf.fmt.width*fmt->depth/8;
-               return 0;
+               if (index >= FORMATS)
+                       return -EINVAL;
+
+               if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY &&
+                   formats[index].planar)
+                       return -EINVAL;
+               memset(f, 0, sizeof(*f));
+               f->index = index;
+               f->type  = type;
+               strlcpy(f->description, formats[index].name,
+                               sizeof(f->description));
+               f->pixelformat = formats[index].fourcc;
+               break;
+       case V4L2_BUF_TYPE_VBI_CAPTURE:
+               if (0 != index)
+                       return -EINVAL;
+               memset(f, 0, sizeof(*f));
+               f->index = index;
+               f->type  = type;
+               f->pixelformat = V4L2_PIX_FMT_GREY;
+               strcpy(f->description, "vbi data");
+               break;
+       default:
+               return -EINVAL;
        }
-       case VIDIOC_OVERLAY:
-       {
-               int *on = arg;
+       return 0;
+}
 
-               if (*on) {
-                       if (saa7134_no_overlay > 0) {
-                               printk ("no_overlay\n");
-                               return -EINVAL;
-                       }
+static int vidioc_g_fbuf(struct file *file, void *f,
+                               struct v4l2_framebuffer *fb)
+{
+       struct saa7134_fh *fh = f;
+       struct saa7134_dev *dev = fh->dev;
 
-                       if (!res_get(dev,fh,RESOURCE_OVERLAY))
-                               return -EBUSY;
-                       spin_lock_irqsave(&dev->slock,flags);
-                       start_preview(dev,fh);
-                       spin_unlock_irqrestore(&dev->slock,flags);
-               }
-               if (!*on) {
-                       if (!res_check(fh, RESOURCE_OVERLAY))
-                               return -EINVAL;
-                       spin_lock_irqsave(&dev->slock,flags);
-                       stop_preview(dev,fh);
-                       spin_unlock_irqrestore(&dev->slock,flags);
-                       res_free(dev,fh,RESOURCE_OVERLAY);
+       *fb = dev->ovbuf;
+       fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
+
+       return 0;
+}
+
+static int vidioc_s_fbuf(struct file *file, void *f,
+                                       struct v4l2_framebuffer *fb)
+{
+       struct saa7134_fh *fh = f;
+       struct saa7134_dev *dev = fh->dev;
+       struct saa7134_format *fmt;
+
+       if (!capable(CAP_SYS_ADMIN) &&
+          !capable(CAP_SYS_RAWIO))
+               return -EPERM;
+
+       /* check args */
+       fmt = format_by_fourcc(fb->fmt.pixelformat);
+       if (NULL == fmt)
+               return -EINVAL;
+
+       /* ok, accept it */
+       dev->ovbuf = *fb;
+       dev->ovfmt = fmt;
+       if (0 == dev->ovbuf.fmt.bytesperline)
+               dev->ovbuf.fmt.bytesperline =
+                       dev->ovbuf.fmt.width*fmt->depth/8;
+       return 0;
+}
+
+static int vidioc_overlay(struct file *file, void *f, unsigned int on)
+{
+       struct saa7134_fh *fh = f;
+       struct saa7134_dev *dev = fh->dev;
+       unsigned long flags;
+
+       if (on) {
+               if (saa7134_no_overlay > 0) {
+                       dprintk("no_overlay\n");
+                       return -EINVAL;
                }
-               return 0;
-       }
 
-       /* --- capture ioctls ---------------------------------------- */
-       case VIDIOC_G_FMT:
-       {
-               struct v4l2_format *f = arg;
-               return saa7134_g_fmt(dev,fh,f);
-       }
-       case VIDIOC_S_FMT:
-       {
-               struct v4l2_format *f = arg;
-               return saa7134_s_fmt(dev,fh,f);
+               if (!res_get(dev, fh, RESOURCE_OVERLAY))
+                       return -EBUSY;
+               spin_lock_irqsave(&dev->slock, flags);
+               start_preview(dev, fh);
+               spin_unlock_irqrestore(&dev->slock, flags);
        }
-       case VIDIOC_TRY_FMT:
-       {
-               struct v4l2_format *f = arg;
-               return saa7134_try_fmt(dev,fh,f);
+       if (!on) {
+               if (!res_check(fh, RESOURCE_OVERLAY))
+                       return -EINVAL;
+               spin_lock_irqsave(&dev->slock, flags);
+               stop_preview(dev, fh);
+               spin_unlock_irqrestore(&dev->slock, flags);
+               res_free(dev, fh, RESOURCE_OVERLAY);
        }
+       return 0;
+}
+
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
-       case VIDIOCGMBUF:
-       {
-               struct video_mbuf *mbuf = arg;
-               struct videobuf_queue *q;
-               struct v4l2_requestbuffers req;
-               unsigned int i;
-
-               q = saa7134_queue(fh);
-               memset(&req,0,sizeof(req));
-               req.type   = q->type;
-               req.count  = gbuffers;
-               req.memory = V4L2_MEMORY_MMAP;
-               err = videobuf_reqbufs(q,&req);
-               if (err < 0)
-                       return err;
-               memset(mbuf,0,sizeof(*mbuf));
-               mbuf->frames = req.count;
-               mbuf->size   = 0;
-               for (i = 0; i < mbuf->frames; i++) {
-                       mbuf->offsets[i]  = q->bufs[i]->boff;
-                       mbuf->size       += q->bufs[i]->bsize;
-               }
-               return 0;
-       }
+static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
+{
+       struct saa7134_fh *fh = file->private_data;
+       return videobuf_cgmbuf(saa7134_queue(fh), mbuf, 8);
+}
 #endif
-       case VIDIOC_REQBUFS:
-               return videobuf_reqbufs(saa7134_queue(fh),arg);
 
-       case VIDIOC_QUERYBUF:
-               return videobuf_querybuf(saa7134_queue(fh),arg);
+static int vidioc_reqbufs(struct file *file, void *priv,
+                                       struct v4l2_requestbuffers *p)
+{
+       struct saa7134_fh *fh = priv;
+       return videobuf_reqbufs(saa7134_queue(fh), p);
+}
 
-       case VIDIOC_QBUF:
-               return videobuf_qbuf(saa7134_queue(fh),arg);
+static int vidioc_querybuf(struct file *file, void *priv,
+                                       struct v4l2_buffer *b)
+{
+       struct saa7134_fh *fh = priv;
+       return videobuf_querybuf(saa7134_queue(fh), b);
+}
 
-       case VIDIOC_DQBUF:
-               return videobuf_dqbuf(saa7134_queue(fh),arg,
-                                     file->f_flags & O_NONBLOCK);
+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+       struct saa7134_fh *fh = priv;
+       return videobuf_qbuf(saa7134_queue(fh), b);
+}
 
-       case VIDIOC_STREAMON:
-       {
-               int res = saa7134_resource(fh);
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+       struct saa7134_fh *fh = priv;
+       return videobuf_dqbuf(saa7134_queue(fh), b,
+                               file->f_flags & O_NONBLOCK);
+}
 
-               if (!res_get(dev,fh,res))
-                       return -EBUSY;
-               return videobuf_streamon(saa7134_queue(fh));
-       }
-       case VIDIOC_STREAMOFF:
-       {
-               int res = saa7134_resource(fh);
+static int vidioc_streamon(struct file *file, void *priv,
+                                       enum v4l2_buf_type type)
+{
+       struct saa7134_fh *fh = priv;
+       struct saa7134_dev *dev = fh->dev;
+       int res = saa7134_resource(fh);
 
-               err = videobuf_streamoff(saa7134_queue(fh));
-               if (err < 0)
-                       return err;
-               res_free(dev,fh,res);
-               return 0;
-       }
+       if (!res_get(dev, fh, res))
+               return -EBUSY;
 
-       default:
-               return v4l_compat_translate_ioctl(inode,file,cmd,arg,
-                                                 video_do_ioctl);
-       }
+       return videobuf_streamon(saa7134_queue(fh));
+}
+
+static int vidioc_streamoff(struct file *file, void *priv,
+                                       enum v4l2_buf_type type)
+{
+       int err;
+       struct saa7134_fh *fh = priv;
+       struct saa7134_dev *dev = fh->dev;
+       int res = saa7134_resource(fh);
+
+       err = videobuf_streamoff(saa7134_queue(fh));
+       if (err < 0)
+               return err;
+       res_free(dev, fh, res);
        return 0;
 }
 
-static int video_ioctl(struct inode *inode, struct file *file,
-                      unsigned int cmd, unsigned long arg)
+static int vidioc_g_parm(struct file *file, void *fh,
+                               struct v4l2_streamparm *parm)
 {
-       return video_usercopy(inode, file, cmd, arg, video_do_ioctl);
+       memset(parm, 0, sizeof(*parm));
+       return 0;
 }
 
-static int radio_do_ioctl(struct inode *inode, struct file *file,
-                         unsigned int cmd, void *arg)
+static int radio_querycap(struct file *file, void *priv,
+                                       struct v4l2_capability *cap)
 {
        struct saa7134_fh *fh = file->private_data;
        struct saa7134_dev *dev = fh->dev;
 
-       if (video_debug > 1)
-               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");
-               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_TUNER;
-               return 0;
-       }
-       case VIDIOC_G_TUNER:
-       {
-               struct v4l2_tuner *t = arg;
+       memset(cap, 0, sizeof(*cap));
+       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_TUNER;
+       return 0;
+}
 
-               if (0 != t->index)
-                       return -EINVAL;
+static int radio_g_tuner(struct file *file, void *priv,
+                                       struct v4l2_tuner *t)
+{
+       struct saa7134_fh *fh = file->private_data;
+       struct saa7134_dev *dev = fh->dev;
 
-               memset(t,0,sizeof(*t));
-               strcpy(t->name, "Radio");
-               t->type = V4L2_TUNER_RADIO;
+       if (0 != t->index)
+               return -EINVAL;
 
-               saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
-               if (dev->input->amux == TV) {
-                       t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11);
-                       t->rxsubchans = (saa_readb(0x529) & 0x08) ?
-                                       V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
-               }
-               return 0;
+       memset(t, 0, sizeof(*t));
+       strcpy(t->name, "Radio");
+       t->type = V4L2_TUNER_RADIO;
+
+       saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
+       if (dev->input->amux == TV) {
+               t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11);
+               t->rxsubchans = (saa_readb(0x529) & 0x08) ?
+                               V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
        }
-       case VIDIOC_S_TUNER:
-       {
-               struct v4l2_tuner *t = arg;
+       return 0;
+}
+static int radio_s_tuner(struct file *file, void *priv,
+                                       struct v4l2_tuner *t)
+{
+       struct saa7134_fh *fh = file->private_data;
+       struct saa7134_dev *dev = fh->dev;
 
-               if (0 != t->index)
-                       return -EINVAL;
+       if (0 != t->index)
+               return -EINVAL;
 
-               saa7134_i2c_call_clients(dev,VIDIOC_S_TUNER,t);
+       saa7134_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
+       return 0;
+}
 
-               return 0;
-       }
-       case VIDIOC_ENUMINPUT:
-       {
-               struct v4l2_input *i = arg;
+static int radio_enum_input(struct file *file, void *priv,
+                                       struct v4l2_input *i)
+{
+       if (i->index != 0)
+               return -EINVAL;
 
-               if (i->index != 0)
-                       return -EINVAL;
-               strcpy(i->name,"Radio");
-               i->type = V4L2_INPUT_TYPE_TUNER;
-               return 0;
-       }
-       case VIDIOC_G_INPUT:
-       {
-               int *i = arg;
-               *i = 0;
-               return 0;
-       }
-       case VIDIOC_G_AUDIO:
-       {
-               struct v4l2_audio *a = arg;
+       strcpy(i->name, "Radio");
+       i->type = V4L2_INPUT_TYPE_TUNER;
 
-               memset(a,0,sizeof(*a));
-               strcpy(a->name,"Radio");
-               return 0;
-       }
-       case VIDIOC_G_STD:
-       {
-               v4l2_std_id *id = arg;
-               *id = 0;
-               return 0;
-       }
-       case VIDIOC_S_AUDIO:
-       case VIDIOC_S_INPUT:
-       case VIDIOC_S_STD:
-               return 0;
+       return 0;
+}
 
-       case VIDIOC_QUERYCTRL:
-       {
-               const struct v4l2_queryctrl *ctrl;
-               struct v4l2_queryctrl *c = arg;
+static int radio_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+       *i = 0;
+       return 0;
+}
 
-               if (c->id <  V4L2_CID_BASE ||
-                   c->id >= V4L2_CID_LASTP1)
-                       return -EINVAL;
-               if (c->id == V4L2_CID_AUDIO_MUTE) {
-                       ctrl = ctrl_by_id(c->id);
-                       *c = *ctrl;
-               } else
-                       *c = no_ctrl;
-               return 0;
-       }
+static int radio_g_audio(struct file *file, void *priv,
+                                       struct v4l2_audio *a)
+{
+       memset(a, 0, sizeof(*a));
+       strcpy(a->name, "Radio");
+       return 0;
+}
+
+static int radio_s_audio(struct file *file, void *priv,
+                                       struct v4l2_audio *a)
+{
+       return 0;
+}
 
-       case VIDIOC_G_CTRL:
-       case VIDIOC_S_CTRL:
-       case VIDIOC_G_FREQUENCY:
-       case VIDIOC_S_FREQUENCY:
-               return video_do_ioctl(inode,file,cmd,arg);
+static int radio_s_input(struct file *filp, void *priv, unsigned int i)
+{
+       return 0;
+}
 
-       default:
-               return v4l_compat_translate_ioctl(inode,file,cmd,arg,
-                                                 radio_do_ioctl);
-       }
+static int radio_s_std(struct file *file, void *fh, v4l2_std_id *norm)
+{
        return 0;
 }
 
-static int radio_ioctl(struct inode *inode, struct file *file,
-                      unsigned int cmd, unsigned long arg)
+static int radio_queryctrl(struct file *file, void *priv,
+                                       struct v4l2_queryctrl *c)
 {
-       return video_usercopy(inode, file, cmd, arg, radio_do_ioctl);
+       const struct v4l2_queryctrl *ctrl;
+
+       if (c->id <  V4L2_CID_BASE ||
+           c->id >= V4L2_CID_LASTP1)
+               return -EINVAL;
+       if (c->id == V4L2_CID_AUDIO_MUTE) {
+               ctrl = ctrl_by_id(c->id);
+               *c = *ctrl;
+       } else
+               *c = no_ctrl;
+       return 0;
 }
 
 static const struct file_operations video_fops =
@@ -2336,7 +2299,7 @@ static const struct file_operations video_fops =
        .read     = video_read,
        .poll     = video_poll,
        .mmap     = video_mmap,
-       .ioctl    = video_ioctl,
+       .ioctl    = video_ioctl2,
        .compat_ioctl   = v4l_compat_ioctl32,
        .llseek   = no_llseek,
 };
@@ -2346,7 +2309,7 @@ static const struct file_operations radio_fops =
        .owner    = THIS_MODULE,
        .open     = video_open,
        .release  = video_release,
-       .ioctl    = radio_ioctl,
+       .ioctl    = video_ioctl2,
        .compat_ioctl   = v4l_compat_ioctl32,
        .llseek   = no_llseek,
 };
@@ -2356,19 +2319,53 @@ static const struct file_operations radio_fops =
 
 struct video_device saa7134_video_template =
 {
-       .name          = "saa7134-video",
-       .type          = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
-                        VID_TYPE_CLIPPING|VID_TYPE_SCALES,
-       .hardware      = 0,
-       .fops          = &video_fops,
-       .minor         = -1,
+       .name                           = "saa7134-video",
+       .type                           = VID_TYPE_CAPTURE|VID_TYPE_TUNER |
+                                       VID_TYPE_CLIPPING|VID_TYPE_SCALES,
+       .fops                           = &video_fops,
+       .minor                          = -1,
+       .vidioc_querycap                = vidioc_querycap,
+       .vidioc_enum_fmt_cap            = vidioc_enum_fmt_cap,
+       .vidioc_g_fmt_cap               = vidioc_g_fmt_cap,
+       .vidioc_try_fmt_cap             = vidioc_try_fmt_cap,
+       .vidioc_s_fmt_cap               = vidioc_s_fmt_cap,
+       .vidioc_g_audio                 = vidioc_g_audio,
+       .vidioc_s_audio                 = vidioc_s_audio,
+       .vidioc_cropcap                 = vidioc_cropcap,
+       .vidioc_reqbufs                 = vidioc_reqbufs,
+       .vidioc_querybuf                = vidioc_querybuf,
+       .vidioc_qbuf                    = vidioc_qbuf,
+       .vidioc_dqbuf                   = vidioc_dqbuf,
+       .vidioc_s_std                   = vidioc_s_std,
+       .vidioc_enum_input              = vidioc_enum_input,
+       .vidioc_g_input                 = vidioc_g_input,
+       .vidioc_s_input                 = vidioc_s_input,
+       .vidioc_queryctrl               = vidioc_queryctrl,
+       .vidioc_g_ctrl                  = vidioc_g_ctrl,
+       .vidioc_s_ctrl                  = vidioc_s_ctrl,
+       .vidioc_streamon                = vidioc_streamon,
+       .vidioc_streamoff               = vidioc_streamoff,
+       .vidioc_g_tuner                 = vidioc_g_tuner,
+       .vidioc_s_tuner                 = vidioc_s_tuner,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+       .vidiocgmbuf                    = vidiocgmbuf,
+#endif
+       .vidioc_g_crop                  = vidioc_g_crop,
+       .vidioc_s_crop                  = vidioc_s_crop,
+       .vidioc_g_fbuf                  = vidioc_g_fbuf,
+       .vidioc_s_fbuf                  = vidioc_s_fbuf,
+       .vidioc_overlay                 = vidioc_overlay,
+       .vidioc_g_priority              = vidioc_g_priority,
+       .vidioc_s_priority              = vidioc_s_priority,
+       .vidioc_g_parm                  = vidioc_g_parm,
+       .vidioc_g_frequency             = vidioc_g_frequency,
+       .vidioc_s_frequency             = vidioc_s_frequency,
 };
 
 struct video_device saa7134_vbi_template =
 {
        .name          = "saa7134-vbi",
        .type          = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
-       .hardware      = 0,
        .fops          = &video_fops,
        .minor         = -1,
 };
@@ -2377,9 +2374,22 @@ struct video_device saa7134_radio_template =
 {
        .name          = "saa7134-radio",
        .type          = VID_TYPE_TUNER,
-       .hardware      = 0,
        .fops          = &radio_fops,
        .minor         = -1,
+       .vidioc_querycap        = radio_querycap,
+       .vidioc_g_tuner         = radio_g_tuner,
+       .vidioc_enum_input      = radio_enum_input,
+       .vidioc_g_audio         = radio_g_audio,
+       .vidioc_s_tuner         = radio_s_tuner,
+       .vidioc_s_audio         = radio_s_audio,
+       .vidioc_s_input         = radio_s_input,
+       .vidioc_s_std           = radio_s_std,
+       .vidioc_queryctrl       = radio_queryctrl,
+       .vidioc_g_input         = radio_g_input,
+       .vidioc_g_ctrl          = vidioc_g_ctrl,
+       .vidioc_s_ctrl          = vidioc_s_ctrl,
+       .vidioc_g_frequency     = vidioc_g_frequency,
+       .vidioc_s_frequency     = vidioc_s_frequency,
 };
 
 int saa7134_video_init1(struct saa7134_dev *dev)
@@ -2411,34 +2421,40 @@ int saa7134_video_init1(struct saa7134_dev *dev)
        dev->video_q.timeout.data     = (unsigned long)(&dev->video_q);
        dev->video_q.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]);
-               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)
-                       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]);
-       }
+       if (saa7134_boards[dev->board].video_out)
+               saa7134_videoport_init(dev);
+
+       return 0;
+}
+
+int saa7134_videoport_init(struct saa7134_dev *dev)
+{
+       /* 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]);
+       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)
+               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]);
 
        return 0;
 }
@@ -2453,7 +2469,7 @@ int saa7134_video_init2(struct saa7134_dev *dev)
        return 0;
 }
 
-void saa7134_irq_video_intl(struct saa7134_dev *dev)
+void saa7134_irq_video_signalchange(struct saa7134_dev *dev)
 {
        static const char *st[] = {
                "(no signal)", "NTSC", "PAL", "SECAM" };
@@ -2465,24 +2481,28 @@ void saa7134_irq_video_intl(struct saa7134_dev *dev)
                (st1 & 0x40) ? "not locked" : "locked",
                (st2 & 0x40) ? "no"         : "yes",
                st[st1 & 0x03]);
-       dev->nosignal = (st1 & 0x40) || (st2 & 0x40);
+       dev->nosignal = (st1 & 0x40) || (st2 & 0x40)  || !(st2 & 0x1);
 
        if (dev->nosignal) {
                /* no video signal -> mute audio */
                if (dev->ctl_automute)
                        dev->automute = 1;
                saa7134_tvaudio_setmute(dev);
-               saa_setb(SAA7134_SYNC_CTRL, 0x20);
        } else {
                /* wake up tvaudio audio carrier scan thread */
                saa7134_tvaudio_do_scan(dev);
-               if (!noninterlaced)
-                       saa_clearb(SAA7134_SYNC_CTRL, 0x20);
        }
+
+       if ((st2 & 0x80) && !noninterlaced && !dev->nosignal)
+               saa_clearb(SAA7134_SYNC_CTRL, 0x20);
+       else
+               saa_setb(SAA7134_SYNC_CTRL, 0x20);
+
        if (dev->mops && dev->mops->signal_change)
                dev->mops->signal_change(dev);
 }
 
+
 void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status)
 {
        enum v4l2_field field;
@@ -2507,7 +2527,7 @@ void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status)
                                goto done;
                }
                dev->video_q.curr->vb.field_count = dev->video_fieldcount;
-               saa7134_buffer_finish(dev,&dev->video_q,STATE_DONE);
+               saa7134_buffer_finish(dev,&dev->video_q,VIDEOBUF_DONE);
        }
        saa7134_buffer_next(dev,&dev->video_q);