V4L/DVB (8613): v4l: move BKL down to the driver level.
[safe/jmp/linux-2.6] / drivers / media / video / bt8xx / bttv-driver.c
index 5404fcc..c3526d0 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/kdev_t.h>
 #include "bttvp.h"
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/tvaudio.h>
 #include <media/msp3400.h>
 
@@ -95,7 +96,6 @@ static unsigned int irq_iswitch;
 static unsigned int uv_ratio    = 50;
 static unsigned int full_luma_range;
 static unsigned int coring;
-extern int no_overlay;
 
 /* API features (turn on/off stuff for testing) */
 static unsigned int v4l2        = 1;
@@ -163,8 +163,8 @@ MODULE_LICENSE("GPL");
 static ssize_t show_card(struct device *cd,
                         struct device_attribute *attr, char *buf)
 {
-       struct video_device *vfd = container_of(cd, struct video_device, class_dev);
-       struct bttv *btv = dev_get_drvdata(vfd->dev);
+       struct video_device *vfd = container_of(cd, struct video_device, dev);
+       struct bttv *btv = dev_get_drvdata(vfd->parent);
        return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET);
 }
 static DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
@@ -1990,7 +1990,7 @@ static int bttv_g_frequency(struct file *file, void *priv,
        if (0 != err)
                return err;
 
-       f->type = V4L2_TUNER_ANALOG_TV;
+       f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
        f->frequency = btv->freq;
 
        return 0;
@@ -2009,7 +2009,8 @@ static int bttv_s_frequency(struct file *file, void *priv,
 
        if (unlikely(f->tuner != 0))
                return -EINVAL;
-       if (unlikely(f->type != V4L2_TUNER_ANALOG_TV))
+       if (unlikely(f->type != (btv->radio_user
+               ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV)))
                return -EINVAL;
        mutex_lock(&btv->lock);
        btv->freq = f->frequency;
@@ -2371,7 +2372,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
        if (check_btres(fh, RESOURCE_OVERLAY)) {
                struct bttv_buffer *new;
 
-               new = videobuf_pci_alloc(sizeof(*new));
+               new = videobuf_sg_alloc(sizeof(*new));
                new->crop = btv->crop[!!fh->do_crop].rect;
                bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
                retval = bttv_switch_overlay(btv,fh,new);
@@ -2447,7 +2448,7 @@ pix_format_set_size     (struct v4l2_pix_format *       f,
        }
 }
 
-static int bttv_g_fmt_cap(struct file *file, void *priv,
+static int bttv_g_fmt_vid_cap(struct file *file, void *priv,
                                        struct v4l2_format *f)
 {
        struct bttv_fh *fh  = priv;
@@ -2460,7 +2461,7 @@ static int bttv_g_fmt_cap(struct file *file, void *priv,
        return 0;
 }
 
-static int bttv_g_fmt_overlay(struct file *file, void *priv,
+static int bttv_g_fmt_vid_overlay(struct file *file, void *priv,
                                        struct v4l2_format *f)
 {
        struct bttv_fh *fh  = priv;
@@ -2471,7 +2472,7 @@ static int bttv_g_fmt_overlay(struct file *file, void *priv,
        return 0;
 }
 
-static int bttv_try_fmt_cap(struct file *file, void *priv,
+static int bttv_try_fmt_vid_cap(struct file *file, void *priv,
                                                struct v4l2_format *f)
 {
        const struct bttv_format *fmt;
@@ -2531,7 +2532,7 @@ static int bttv_try_fmt_cap(struct file *file, void *priv,
        return 0;
 }
 
-static int bttv_try_fmt_overlay(struct file *file, void *priv,
+static int bttv_try_fmt_vid_overlay(struct file *file, void *priv,
                                                struct v4l2_format *f)
 {
        struct bttv_fh *fh = priv;
@@ -2541,7 +2542,7 @@ static int bttv_try_fmt_overlay(struct file *file, void *priv,
                        /* adjust_crop */ 0);
 }
 
-static int bttv_s_fmt_cap(struct file *file, void *priv,
+static int bttv_s_fmt_vid_cap(struct file *file, void *priv,
                                struct v4l2_format *f)
 {
        int retval;
@@ -2555,7 +2556,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv,
        if (0 != retval)
                return retval;
 
-       retval = bttv_try_fmt_cap(file, priv, f);
+       retval = bttv_try_fmt_vid_cap(file, priv, f);
        if (0 != retval)
                return retval;
 
@@ -2590,7 +2591,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv,
        return 0;
 }
 
-static int bttv_s_fmt_overlay(struct file *file, void *priv,
+static int bttv_s_fmt_vid_overlay(struct file *file, void *priv,
                                struct v4l2_format *f)
 {
        struct bttv_fh *fh = priv;
@@ -2612,7 +2613,7 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
        struct bttv_fh *fh = priv;
 
        mutex_lock(&fh->cap.vb_lock);
-       retval = videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize,
+       retval = __videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize,
                                     V4L2_MEMORY_MMAP);
        if (retval < 0) {
                mutex_unlock(&fh->cap.vb_lock);
@@ -2660,7 +2661,7 @@ static int bttv_querycap(struct file *file, void  *priv,
        return 0;
 }
 
-static int bttv_enum_fmt_vbi(struct file *file, void  *priv,
+static int bttv_enum_fmt_vbi_cap(struct file *file, void  *priv,
                                struct v4l2_fmtdesc *f)
 {
        if (0 != f->index)
@@ -2691,7 +2692,7 @@ static int bttv_enum_fmt_cap_ovr(struct v4l2_fmtdesc *f)
        return i;
 }
 
-static int bttv_enum_fmt_cap(struct file *file, void  *priv,
+static int bttv_enum_fmt_vid_cap(struct file *file, void  *priv,
                                struct v4l2_fmtdesc *f)
 {
        int rc = bttv_enum_fmt_cap_ovr(f);
@@ -2702,7 +2703,7 @@ static int bttv_enum_fmt_cap(struct file *file, void  *priv,
        return 0;
 }
 
-static int bttv_enum_fmt_overlay(struct file *file, void  *priv,
+static int bttv_enum_fmt_vid_overlay(struct file *file, void  *priv,
                                        struct v4l2_fmtdesc *f)
 {
        int rc;
@@ -2759,7 +2760,7 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
        mutex_lock(&fh->cap.vb_lock);
        if (on) {
                fh->ov.tvnorm = btv->tvnorm;
-               new = videobuf_pci_alloc(sizeof(*new));
+               new = videobuf_sg_alloc(sizeof(*new));
                new->crop = btv->crop[!!fh->do_crop].rect;
                bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
        } else {
@@ -2833,7 +2834,7 @@ static int bttv_s_fbuf(struct file *file, void *f,
                if (check_btres(fh, RESOURCE_OVERLAY)) {
                        struct bttv_buffer *new;
 
-                       new = videobuf_pci_alloc(sizeof(*new));
+                       new = videobuf_sg_alloc(sizeof(*new));
                        new->crop = btv->crop[!!fh->do_crop].rect;
                        bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
                        retval = bttv_switch_overlay(btv, fh, new);
@@ -3116,12 +3117,18 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
 
 static int bttv_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
 {
+       if (unlikely(a->index))
+               return -EINVAL;
+
        strcpy(a->name, "audio");
        return 0;
 }
 
 static int bttv_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
 {
+       if (unlikely(a->index))
+               return -EINVAL;
+
        return 0;
 }
 
@@ -3183,7 +3190,7 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
                        /* need to capture a new frame */
                        if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM))
                                goto err;
-                       fh->cap.read_buf = videobuf_pci_alloc(fh->cap.msize);
+                       fh->cap.read_buf = videobuf_sg_alloc(fh->cap.msize);
                        if (NULL == fh->cap.read_buf)
                                goto err;
                        fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR;
@@ -3220,6 +3227,7 @@ static int bttv_open(struct inode *inode, struct file *file)
 
        dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor);
 
+       lock_kernel();
        for (i = 0; i < bttv_num; i++) {
                if (bttvs[i].video_dev &&
                    bttvs[i].video_dev->minor == minor) {
@@ -3234,30 +3242,34 @@ static int bttv_open(struct inode *inode, struct file *file)
                        break;
                }
        }
-       if (NULL == btv)
+       if (NULL == btv) {
+               unlock_kernel();
                return -ENODEV;
+       }
 
        dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n",
                btv->c.nr,v4l2_type_names[type]);
 
        /* allocate per filehandle data */
        fh = kmalloc(sizeof(*fh),GFP_KERNEL);
-       if (NULL == fh)
+       if (NULL == fh) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        file->private_data = fh;
        *fh = btv->init;
        fh->type = type;
        fh->ov.setup_ok = 0;
        v4l2_prio_open(&btv->prio,&fh->prio);
 
-       videobuf_queue_pci_init(&fh->cap, &bttv_video_qops,
-                           btv->c.pci, &btv->s_lock,
+       videobuf_queue_sg_init(&fh->cap, &bttv_video_qops,
+                           &btv->c.pci->dev, &btv->s_lock,
                            V4L2_BUF_TYPE_VIDEO_CAPTURE,
                            V4L2_FIELD_INTERLACED,
                            sizeof(struct bttv_buffer),
                            fh);
-       videobuf_queue_pci_init(&fh->vbi, &bttv_vbi_qops,
-                           btv->c.pci, &btv->s_lock,
+       videobuf_queue_sg_init(&fh->vbi, &bttv_vbi_qops,
+                           &btv->c.pci->dev, &btv->s_lock,
                            V4L2_BUF_TYPE_VBI_CAPTURE,
                            V4L2_FIELD_SEQ_TB,
                            sizeof(struct bttv_buffer),
@@ -3283,6 +3295,7 @@ static int bttv_open(struct inode *inode, struct file *file)
        bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm);
 
        bttv_field_count(btv);
+       unlock_kernel();
        return 0;
 }
 
@@ -3350,23 +3363,20 @@ static const struct file_operations bttv_fops =
        .poll     = bttv_poll,
 };
 
-static struct video_device bttv_video_template =
-{
-       .fops     = &bttv_fops,
-       .minor    = -1,
+static const struct v4l2_ioctl_ops bttv_ioctl_ops = {
        .vidioc_querycap                = bttv_querycap,
-       .vidioc_enum_fmt_cap            = bttv_enum_fmt_cap,
-       .vidioc_g_fmt_cap               = bttv_g_fmt_cap,
-       .vidioc_try_fmt_cap             = bttv_try_fmt_cap,
-       .vidioc_s_fmt_cap               = bttv_s_fmt_cap,
-       .vidioc_enum_fmt_overlay        = bttv_enum_fmt_overlay,
-       .vidioc_g_fmt_overlay           = bttv_g_fmt_overlay,
-       .vidioc_try_fmt_overlay         = bttv_try_fmt_overlay,
-       .vidioc_s_fmt_overlay           = bttv_s_fmt_overlay,
-       .vidioc_enum_fmt_vbi            = bttv_enum_fmt_vbi,
-       .vidioc_g_fmt_vbi               = bttv_g_fmt_vbi,
-       .vidioc_try_fmt_vbi             = bttv_try_fmt_vbi,
-       .vidioc_s_fmt_vbi               = bttv_s_fmt_vbi,
+       .vidioc_enum_fmt_vid_cap        = bttv_enum_fmt_vid_cap,
+       .vidioc_g_fmt_vid_cap           = bttv_g_fmt_vid_cap,
+       .vidioc_try_fmt_vid_cap         = bttv_try_fmt_vid_cap,
+       .vidioc_s_fmt_vid_cap           = bttv_s_fmt_vid_cap,
+       .vidioc_enum_fmt_vid_overlay    = bttv_enum_fmt_vid_overlay,
+       .vidioc_g_fmt_vid_overlay       = bttv_g_fmt_vid_overlay,
+       .vidioc_try_fmt_vid_overlay     = bttv_try_fmt_vid_overlay,
+       .vidioc_s_fmt_vid_overlay       = bttv_s_fmt_vid_overlay,
+       .vidioc_enum_fmt_vbi_cap        = bttv_enum_fmt_vbi_cap,
+       .vidioc_g_fmt_vbi_cap           = bttv_g_fmt_vbi_cap,
+       .vidioc_try_fmt_vbi_cap         = bttv_try_fmt_vbi_cap,
+       .vidioc_s_fmt_vbi_cap           = bttv_s_fmt_vbi_cap,
        .vidioc_g_audio                 = bttv_g_audio,
        .vidioc_s_audio                 = bttv_s_audio,
        .vidioc_cropcap                 = bttv_cropcap,
@@ -3389,7 +3399,6 @@ static struct video_device bttv_video_template =
        .vidiocgmbuf                    = vidiocgmbuf,
 #endif
        .vidioc_g_crop                  = bttv_g_crop,
-       .vidioc_g_crop                  = bttv_g_crop,
        .vidioc_s_crop                  = bttv_s_crop,
        .vidioc_g_fbuf                  = bttv_g_fbuf,
        .vidioc_s_fbuf                  = bttv_s_fbuf,
@@ -3405,8 +3414,14 @@ static struct video_device bttv_video_template =
        .vidioc_g_register              = bttv_g_register,
        .vidioc_s_register              = bttv_s_register,
 #endif
-       .tvnorms                        = BTTV_NORMS,
-       .current_norm                   = V4L2_STD_PAL,
+};
+
+static struct video_device bttv_video_template = {
+       .fops         = &bttv_fops,
+       .minor        = -1,
+       .ioctl_ops    = &bttv_ioctl_ops,
+       .tvnorms      = BTTV_NORMS,
+       .current_norm = V4L2_STD_PAL,
 };
 
 /* ----------------------------------------------------------------------- */
@@ -3416,38 +3431,56 @@ static int radio_open(struct inode *inode, struct file *file)
 {
        int minor = iminor(inode);
        struct bttv *btv = NULL;
+       struct bttv_fh *fh;
        unsigned int i;
 
        dprintk("bttv: open minor=%d\n",minor);
 
+       lock_kernel();
        for (i = 0; i < bttv_num; i++) {
-               if (bttvs[i].radio_dev->minor == minor) {
+               if (bttvs[i].radio_dev && bttvs[i].radio_dev->minor == minor) {
                        btv = &bttvs[i];
                        break;
                }
        }
-       if (NULL == btv)
+       if (NULL == btv) {
+               unlock_kernel();
                return -ENODEV;
+       }
 
        dprintk("bttv%d: open called (radio)\n",btv->c.nr);
+
+       /* allocate per filehandle data */
+       fh = kmalloc(sizeof(*fh), GFP_KERNEL);
+       if (NULL == fh) {
+               unlock_kernel();
+               return -ENOMEM;
+       }
+       file->private_data = fh;
+       *fh = btv->init;
+       v4l2_prio_open(&btv->prio, &fh->prio);
+
        mutex_lock(&btv->lock);
 
        btv->radio_user++;
 
-       file->private_data = btv;
-
        bttv_call_i2c_clients(btv,AUDC_SET_RADIO,NULL);
        audio_input(btv,TVAUDIO_INPUT_RADIO);
 
        mutex_unlock(&btv->lock);
+       unlock_kernel();
        return 0;
 }
 
 static int radio_release(struct inode *inode, struct file *file)
 {
-       struct bttv *btv = file->private_data;
+       struct bttv_fh *fh = file->private_data;
+       struct bttv *btv = fh->btv;
        struct rds_command cmd;
 
+       file->private_data = NULL;
+       kfree(fh);
+
        btv->radio_user--;
 
        bttv_call_i2c_clients(btv, RDS_CMD_CLOSE, &cmd);
@@ -3501,7 +3534,7 @@ static int radio_enum_input(struct file *file, void *priv,
                return -EINVAL;
 
        strcpy(i->name, "Radio");
-        i->type = V4L2_INPUT_TYPE_TUNER;
+       i->type = V4L2_INPUT_TYPE_TUNER;
 
        return 0;
 }
@@ -3509,8 +3542,11 @@ static int radio_enum_input(struct file *file, void *priv,
 static int radio_g_audio(struct file *file, void *priv,
                                        struct v4l2_audio *a)
 {
-       memset(a, 0, sizeof(*a));
+       if (unlikely(a->index))
+               return -EINVAL;
+
        strcpy(a->name, "Radio");
+
        return 0;
 }
 
@@ -3530,11 +3566,17 @@ static int radio_s_tuner(struct file *file, void *priv,
 static int radio_s_audio(struct file *file, void *priv,
                                        struct v4l2_audio *a)
 {
+       if (unlikely(a->index))
+               return -EINVAL;
+
        return 0;
 }
 
 static int radio_s_input(struct file *filp, void *priv, unsigned int i)
 {
+       if (unlikely(i))
+               return -EINVAL;
+
        return 0;
 }
 
@@ -3570,7 +3612,8 @@ static int radio_g_input(struct file *filp, void *priv, unsigned int *i)
 static ssize_t radio_read(struct file *file, char __user *data,
                         size_t count, loff_t *ppos)
 {
-       struct bttv    *btv = file->private_data;
+       struct bttv_fh *fh = file->private_data;
+       struct bttv *btv = fh->btv;
        struct rds_command cmd;
        cmd.block_count = count/3;
        cmd.buffer = data;
@@ -3584,7 +3627,8 @@ static ssize_t radio_read(struct file *file, char __user *data,
 
 static unsigned int radio_poll(struct file *file, poll_table *wait)
 {
-       struct bttv    *btv = file->private_data;
+       struct bttv_fh *fh = file->private_data;
+       struct bttv *btv = fh->btv;
        struct rds_command cmd;
        cmd.instance = file;
        cmd.event_list = wait;
@@ -3600,15 +3644,13 @@ static const struct file_operations radio_fops =
        .open     = radio_open,
        .read     = radio_read,
        .release  = radio_release,
+       .compat_ioctl   = v4l_compat_ioctl32,
        .ioctl    = video_ioctl2,
        .llseek   = no_llseek,
        .poll     = radio_poll,
 };
 
-static struct video_device radio_template =
-{
-       .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,
@@ -3625,6 +3667,12 @@ static struct video_device radio_template =
        .vidioc_s_frequency     = bttv_s_frequency,
 };
 
+static struct video_device radio_template = {
+       .fops      = &radio_fops,
+       .minor     = -1,
+       .ioctl_ops = &radio_ioctl_ops,
+};
+
 /* ----------------------------------------------------------------------- */
 /* some debug code                                                         */
 
@@ -3675,7 +3723,7 @@ static void bttv_risc_disasm(struct bttv *btv,
        for (i = 0; i < (risc->size >> 2); i += n) {
                printk("%s:   0x%lx: ", btv->c.name,
                       (unsigned long)(risc->dma + (i<<2)));
-               n = bttv_risc_decode(risc->cpu[i]);
+               n = bttv_risc_decode(le32_to_cpu(risc->cpu[i]));
                for (j = 1; j < n; j++)
                        printk("%s:   0x%lx: 0x%08x [ arg #%d ]\n",
                               btv->c.name, (unsigned long)(risc->dma + ((i+j)<<2)),
@@ -3744,8 +3792,8 @@ static void bttv_irq_debug_low_latency(struct bttv *btv, u32 rc)
        printk("bttv%d: irq: skipped frame [main=%lx,o_vbi=%lx,o_field=%lx,rc=%lx]\n",
               btv->c.nr,
               (unsigned long)btv->main.dma,
-              (unsigned long)btv->main.cpu[RISC_SLOT_O_VBI+1],
-              (unsigned long)btv->main.cpu[RISC_SLOT_O_FIELD+1],
+              (unsigned long)le32_to_cpu(btv->main.cpu[RISC_SLOT_O_VBI+1]),
+              (unsigned long)le32_to_cpu(btv->main.cpu[RISC_SLOT_O_FIELD+1]),
               (unsigned long)rc);
 
        if (0 == (btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC)) {
@@ -4145,8 +4193,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id)
 
 static struct video_device *vdev_init(struct bttv *btv,
                                      const struct video_device *template,
-                                     const char *type_name,
-                                     const int type)
+                                     const char *type_name)
 {
        struct video_device *vfd;
 
@@ -4155,9 +4202,9 @@ static struct video_device *vdev_init(struct bttv *btv,
                return NULL;
        *vfd = *template;
        vfd->minor   = -1;
-       vfd->dev     = &btv->c.pci->dev;
+       vfd->parent  = &btv->c.pci->dev;
        vfd->release = video_device_release;
-       vfd->type    = type;
+       vfd->debug   = bttv_debug;
        snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
                 btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
                 type_name, bttv_tvcards[btv->c.type].name);
@@ -4192,20 +4239,11 @@ static void bttv_unregister_video(struct bttv *btv)
 /* register video4linux devices */
 static int __devinit bttv_register_video(struct bttv *btv)
 {
-       int video_type = VID_TYPE_CAPTURE |
-                        VID_TYPE_TUNER   |
-                        VID_TYPE_CLIPPING|
-                        VID_TYPE_SCALES;
-
-       if (no_overlay <= 0) {
-               bttv_video_template.type |= VID_TYPE_OVERLAY;
-       } else {
+       if (no_overlay > 0)
                printk("bttv: Overlay support disabled.\n");
-       }
 
        /* video */
-       btv->video_dev = vdev_init(btv, &bttv_video_template,
-                                  "video", video_type);
+       btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
 
        if (NULL == btv->video_dev)
                goto err;
@@ -4213,7 +4251,7 @@ static int __devinit bttv_register_video(struct bttv *btv)
                goto err;
        printk(KERN_INFO "bttv%d: registered device video%d\n",
               btv->c.nr,btv->video_dev->minor & 0x1f);
-       if (device_create_file(&btv->video_dev->class_dev,
+       if (device_create_file(&btv->video_dev->dev,
                                     &dev_attr_card)<0) {
                printk(KERN_ERR "bttv%d: device_create_file 'card' "
                       "failed\n", btv->c.nr);
@@ -4221,8 +4259,7 @@ static int __devinit bttv_register_video(struct bttv *btv)
        }
 
        /* vbi */
-       btv->vbi_dev = vdev_init(btv, &bttv_video_template,
-                                "vbi", VID_TYPE_TUNER | VID_TYPE_TELETEXT);
+       btv->vbi_dev = vdev_init(btv, &bttv_video_template, "vbi");
 
        if (NULL == btv->vbi_dev)
                goto err;
@@ -4234,8 +4271,7 @@ static int __devinit bttv_register_video(struct bttv *btv)
        if (!btv->has_radio)
                return 0;
        /* radio */
-       btv->radio_dev = vdev_init(btv, &radio_template,
-                                  "radio", VID_TYPE_TUNER);
+       btv->radio_dev = vdev_init(btv, &radio_template, "radio");
        if (NULL == btv->radio_dev)
                goto err;
        if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0)