]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/video/bttv-driver.c
Merge HEAD from ../linux-2.6
[linux-2.6-omap-h63xx.git] / drivers / media / video / bttv-driver.c
index 1ddf9ba613ef96c3e8b142dd41d322c02391cb3c..c0415d6e7fee2164bda6731e15fccea8ff58a259 100644 (file)
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/kdev_t.h>
+#include "bttvp.h"
+#include <media/v4l2-common.h>
+
 #include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/byteorder.h>
 
-#include "bttvp.h"
-
 #include "rds.h"
 
 
 unsigned int bttv_num;                 /* number of Bt848s in use */
 struct bttv bttvs[BTTV_MAX];
 
-unsigned int bttv_debug = 0;
+unsigned int bttv_debug;
 unsigned int bttv_verbose = 1;
-unsigned int bttv_gpio = 0;
+unsigned int bttv_gpio;
 
 /* config variables */
 #ifdef __BIG_ENDIAN
 static unsigned int bigendian=1;
 #else
-static unsigned int bigendian=0;
+static unsigned int bigendian;
 #endif
 static unsigned int radio[BTTV_MAX];
-static unsigned int irq_debug = 0;
+static unsigned int irq_debug;
 static unsigned int gbuffers = 8;
 static unsigned int gbufsize = 0x208000;
 
 static int video_nr = -1;
 static int radio_nr = -1;
 static int vbi_nr = -1;
-static int debug_latency = 0;
+static int debug_latency;
 
-static unsigned int fdsr = 0;
+static unsigned int fdsr;
 
 /* options */
-static unsigned int combfilter  = 0;
-static unsigned int lumafilter  = 0;
+static unsigned int combfilter;
+static unsigned int lumafilter;
 static unsigned int automute    = 1;
-static unsigned int chroma_agc  = 0;
+static unsigned int chroma_agc;
 static unsigned int adc_crush   = 1;
 static unsigned int whitecrush_upper = 0xCF;
 static unsigned int whitecrush_lower = 0x7F;
-static unsigned int vcr_hack    = 0;
-static unsigned int irq_iswitch = 0;
+static unsigned int vcr_hack;
+static unsigned int irq_iswitch;
 static unsigned int uv_ratio    = 50;
-static unsigned int full_luma_range = 0;
-static unsigned int coring      = 0;
+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;
 
-
 /* insmod args */
 module_param(bttv_verbose,      int, 0644);
 module_param(bttv_gpio,         int, 0644);
@@ -210,8 +210,11 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                .vdelay         = 0x20,
                .vbipack        = 255,
                .sram           = 0,
+               /* ITU-R frame line number of the first VBI line
+                  we can capture, of the first and second field. */
+               .vbistart       = { 7,320 },
        },{
-               .v4l2_id        = V4L2_STD_NTSC_M,
+               .v4l2_id        = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
                .name           = "NTSC",
                .Fsc            = 28636363,
                .swidth         = 768,
@@ -226,6 +229,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                .vdelay         = 0x1a,
                .vbipack        = 144,
                .sram           = 1,
+               .vbistart       = { 10, 273 },
        },{
                .v4l2_id        = V4L2_STD_SECAM,
                .name           = "SECAM",
@@ -242,6 +246,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                .vdelay         = 0x20,
                .vbipack        = 255,
                .sram           = 0, /* like PAL, correct? */
+               .vbistart       = { 7, 320 },
        },{
                .v4l2_id        = V4L2_STD_PAL_Nc,
                .name           = "PAL-Nc",
@@ -258,6 +263,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                .vdelay         = 0x1a,
                .vbipack        = 144,
                .sram           = -1,
+               .vbistart       = { 7, 320 },
        },{
                .v4l2_id        = V4L2_STD_PAL_M,
                .name           = "PAL-M",
@@ -274,6 +280,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                .vdelay         = 0x1a,
                .vbipack        = 144,
                .sram           = -1,
+               .vbistart       = { 10, 273 },
        },{
                .v4l2_id        = V4L2_STD_PAL_N,
                .name           = "PAL-N",
@@ -290,6 +297,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                .vdelay         = 0x20,
                .vbipack        = 144,
                .sram           = -1,
+               .vbistart       = { 7, 320},
        },{
                .v4l2_id        = V4L2_STD_NTSC_M_JP,
                .name           = "NTSC-JP",
@@ -306,6 +314,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                .vdelay         = 0x16,
                .vbipack        = 144,
                .sram           = -1,
+               .vbistart       = {10, 273},
        },{
                /* that one hopefully works with the strange timing
                 * which video recorders produce when playing a NTSC
@@ -326,6 +335,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                .vbipack        = 255,
                .vtotal         = 524,
                .sram           = -1,
+               .vbistart       = { 10, 273 },
        }
 };
 static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms);
@@ -674,16 +684,16 @@ int check_alloc_btres(struct bttv *btv, struct bttv_fh *fh, int bit)
                return 1;
 
        /* is it free? */
-       down(&btv->reslock);
+       mutex_lock(&btv->reslock);
        if (btv->resources & bit) {
                /* no, someone else uses it */
-               up(&btv->reslock);
+               mutex_unlock(&btv->reslock);
                return 0;
        }
        /* it's free, grab it */
        fh->resources  |= bit;
        btv->resources |= bit;
-       up(&btv->reslock);
+       mutex_unlock(&btv->reslock);
        return 1;
 }
 
@@ -706,10 +716,10 @@ void free_btres(struct bttv *btv, struct bttv_fh *fh, int bits)
                /* trying to free ressources not allocated by us ... */
                printk("bttv: BUG! (btres)\n");
        }
-       down(&btv->reslock);
+       mutex_lock(&btv->reslock);
        fh->resources  &= ~bits;
        btv->resources &= ~bits;
-       up(&btv->reslock);
+       mutex_unlock(&btv->reslock);
 }
 
 /* ----------------------------------------------------------------------- */
@@ -1510,14 +1520,6 @@ static struct videobuf_queue_ops bttv_video_qops = {
        .buf_release  = buffer_release,
 };
 
-static const char *v4l1_ioctls[] = {
-       "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
-       "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
-       "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
-       "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
-       "SMICROCODE", "GVBIFMT", "SVBIFMT" };
-#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
-
 static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
 {
        switch (cmd) {
@@ -1534,12 +1536,12 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
        case VIDIOCSFREQ:
        {
                unsigned long *freq = arg;
-               down(&btv->lock);
+               mutex_lock(&btv->lock);
                btv->freq=*freq;
                bttv_call_i2c_clients(btv,VIDIOCSFREQ,freq);
                if (btv->has_matchbox && btv->radio_user)
                        tea5757_set_freq(btv,*freq);
-               up(&btv->lock);
+               mutex_unlock(&btv->lock);
                return 0;
        }
 
@@ -1569,10 +1571,10 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
                if (v->mode >= BTTV_TVNORMS)
                        return -EINVAL;
 
-               down(&btv->lock);
+               mutex_lock(&btv->lock);
                set_tvnorm(btv,v->mode);
                bttv_call_i2c_clients(btv,cmd,v);
-               up(&btv->lock);
+               mutex_unlock(&btv->lock);
                return 0;
        }
 
@@ -1609,17 +1611,17 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
                if (v->norm >= BTTV_TVNORMS)
                        return -EINVAL;
 
-               down(&btv->lock);
+               mutex_lock(&btv->lock);
                if (channel == btv->input &&
                    v->norm == btv->tvnorm) {
                        /* nothing to do */
-                       up(&btv->lock);
+                       mutex_unlock(&btv->lock);
                        return 0;
                }
 
                btv->tvnorm = v->norm;
                set_input(btv,v->channel);
-               up(&btv->lock);
+               mutex_unlock(&btv->lock);
                return 0;
        }
 
@@ -1632,14 +1634,14 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
                v->flags |= VIDEO_AUDIO_MUTABLE;
                v->mode  = VIDEO_SOUND_MONO;
 
-               down(&btv->lock);
+               mutex_lock(&btv->lock);
                bttv_call_i2c_clients(btv,cmd,v);
 
                /* card specific hooks */
                if (btv->audio_hook)
                        btv->audio_hook(btv,v,0);
 
-               up(&btv->lock);
+               mutex_unlock(&btv->lock);
                return 0;
        }
        case VIDIOCSAUDIO:
@@ -1650,7 +1652,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
                if (audio >= bttv_tvcards[btv->c.type].audio_inputs)
                        return -EINVAL;
 
-               down(&btv->lock);
+               mutex_lock(&btv->lock);
                audio_mux(btv, (v->flags&VIDEO_AUDIO_MUTE) ? AUDIO_MUTE : AUDIO_UNMUTE);
                bttv_call_i2c_clients(btv,cmd,v);
 
@@ -1658,7 +1660,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
                if (btv->audio_hook)
                        btv->audio_hook(btv,v,1);
 
-               up(&btv->lock);
+               mutex_unlock(&btv->lock);
                return 0;
        }
 
@@ -1692,10 +1694,10 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
                if (i == BTTV_TVNORMS)
                        return -EINVAL;
 
-               down(&btv->lock);
+               mutex_lock(&btv->lock);
                set_tvnorm(btv,i);
                i2c_vidiocschan(btv);
-               up(&btv->lock);
+               mutex_unlock(&btv->lock);
                return 0;
        }
        case VIDIOC_QUERYSTD:
@@ -1753,9 +1755,9 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
 
                if (*i > bttv_tvcards[btv->c.type].video_inputs)
                        return -EINVAL;
-               down(&btv->lock);
+               mutex_lock(&btv->lock);
                set_input(btv,*i);
-               up(&btv->lock);
+               mutex_unlock(&btv->lock);
                return 0;
        }
 
@@ -1767,7 +1769,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
                        return -EINVAL;
                if (0 != t->index)
                        return -EINVAL;
-               down(&btv->lock);
+               mutex_lock(&btv->lock);
                memset(t,0,sizeof(*t));
                strcpy(t->name, "Television");
                t->type       = V4L2_TUNER_ANALOG_TV;
@@ -1802,7 +1804,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
                        }
                }
                /* FIXME: fill capability+audmode */
-               up(&btv->lock);
+               mutex_unlock(&btv->lock);
                return 0;
        }
        case VIDIOC_S_TUNER:
@@ -1813,7 +1815,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
                        return -EINVAL;
                if (0 != t->index)
                        return -EINVAL;
-               down(&btv->lock);
+               mutex_lock(&btv->lock);
                {
                        struct video_audio va;
                        memset(&va, 0, sizeof(struct video_audio));
@@ -1830,7 +1832,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
                        if (btv->audio_hook)
                                btv->audio_hook(btv,&va,1);
                }
-               up(&btv->lock);
+               mutex_unlock(&btv->lock);
                return 0;
        }
 
@@ -1851,12 +1853,12 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
                        return -EINVAL;
                if (unlikely (f->type != V4L2_TUNER_ANALOG_TV))
                        return -EINVAL;
-               down(&btv->lock);
+               mutex_lock(&btv->lock);
                btv->freq = f->frequency;
                bttv_call_i2c_clients(btv,VIDIOCSFREQ,&btv->freq);
                if (btv->has_matchbox && btv->radio_user)
                        tea5757_set_freq(btv,btv->freq);
-               up(&btv->lock);
+               mutex_unlock(&btv->lock);
                return 0;
        }
        case VIDIOC_LOG_STATUS:
@@ -1963,7 +1965,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
                BUG();
        }
 
-       down(&fh->cap.lock);
+       mutex_lock(&fh->cap.lock);
                kfree(fh->ov.clips);
        fh->ov.clips    = clips;
        fh->ov.nclips   = n;
@@ -1984,7 +1986,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
                bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
                retval = bttv_switch_overlay(btv,fh,new);
        }
-       up(&fh->cap.lock);
+       mutex_unlock(&fh->cap.lock);
        return retval;
 }
 
@@ -2164,7 +2166,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
                fmt = format_by_fourcc(f->fmt.pix.pixelformat);
 
                /* update our state informations */
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                fh->fmt              = fmt;
                fh->cap.field        = f->fmt.pix.field;
                fh->cap.last         = V4L2_FIELD_NONE;
@@ -2173,7 +2175,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
                btv->init.fmt        = fmt;
                btv->init.width      = f->fmt.pix.width;
                btv->init.height     = f->fmt.pix.height;
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
 
                return 0;
        }
@@ -2206,22 +2208,9 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
        unsigned long flags;
        int retval = 0;
 
-       if (bttv_debug > 1) {
-               switch (_IOC_TYPE(cmd)) {
-               case 'v':
-                       printk("bttv%d: ioctl 0x%x (v4l1, VIDIOC%s)\n",
-                              btv->c.nr, cmd, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
-                              v4l1_ioctls[_IOC_NR(cmd)] : "???");
-                       break;
-               case 'V':
-                       printk("bttv%d: ioctl 0x%x (v4l2, %s)\n",
-                              btv->c.nr, cmd,  v4l2_ioctl_names[_IOC_NR(cmd)]);
-                       break;
-               default:
-                       printk("bttv%d: ioctl 0x%x (???)\n",
-                              btv->c.nr, cmd);
-               }
-       }
+       if (bttv_debug > 1)
+               v4l_print_ioctl(btv->c.name, cmd);
+
        if (btv->errors)
                bttv_reinit_bt848(btv);
 
@@ -2293,7 +2282,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                fmt = format_by_palette(pic->palette);
                if (NULL == fmt)
                        return -EINVAL;
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                if (fmt->depth != pic->depth) {
                        retval = -EINVAL;
                        goto fh_unlock_and_return;
@@ -2324,7 +2313,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                bt848_contrast(btv,pic->contrast);
                bt848_hue(btv,pic->hue);
                bt848_sat(btv,pic->colour);
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                return 0;
        }
 
@@ -2390,7 +2379,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                        return -EPERM;
                end = (unsigned long)fbuf->base +
                        fbuf->height * fbuf->bytesperline;
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                retval = -EINVAL;
 
                switch (fbuf->depth) {
@@ -2428,7 +2417,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                        btv->fbuf.fmt.bytesperline = fbuf->bytesperline;
                else
                        btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fbuf->depth/8;
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                return 0;
        }
 
@@ -2451,7 +2440,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                if (!check_alloc_btres(btv,fh,RESOURCE_OVERLAY))
                        return -EBUSY;
 
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                if (*on) {
                        fh->ov.tvnorm = btv->tvnorm;
                        new = videobuf_alloc(sizeof(*new));
@@ -2462,7 +2451,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
 
                /* switch over */
                retval = bttv_switch_overlay(btv,fh,new);
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                return retval;
        }
 
@@ -2471,7 +2460,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                struct video_mbuf *mbuf = arg;
                unsigned int i;
 
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                retval = videobuf_mmap_setup(&fh->cap,gbuffers,gbufsize,
                                             V4L2_MEMORY_MMAP);
                if (retval < 0)
@@ -2481,7 +2470,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                mbuf->size   = gbuffers * gbufsize;
                for (i = 0; i < gbuffers; i++)
                        mbuf->offsets[i] = i * gbufsize;
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                return 0;
        }
        case VIDIOCMCAPTURE:
@@ -2493,7 +2482,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                if (vm->frame >= VIDEO_MAX_FRAME)
                        return -EINVAL;
 
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                retval = -EINVAL;
                buf = (struct bttv_buffer *)fh->cap.bufs[vm->frame];
                if (NULL == buf)
@@ -2515,7 +2504,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                spin_lock_irqsave(&btv->s_lock,flags);
                buffer_queue(&fh->cap,&buf->vb);
                spin_unlock_irqrestore(&btv->s_lock,flags);
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                return 0;
        }
        case VIDIOCSYNC:
@@ -2526,7 +2515,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                if (*frame >= VIDEO_MAX_FRAME)
                        return -EINVAL;
 
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                retval = -EINVAL;
                buf = (struct bttv_buffer *)fh->cap.bufs[*frame];
                if (NULL == buf)
@@ -2546,7 +2535,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                        retval = -EINVAL;
                        break;
                }
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                return retval;
        }
 
@@ -2570,10 +2559,10 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                fmt->count[0]         = fmt2.fmt.vbi.count[0];
                fmt->start[1]         = fmt2.fmt.vbi.start[1];
                fmt->count[1]         = fmt2.fmt.vbi.count[1];
-               if (fmt2.fmt.vbi.flags & VBI_UNSYNC)
-                       fmt->flags   |= V4L2_VBI_UNSYNC;
-               if (fmt2.fmt.vbi.flags & VBI_INTERLACED)
-                       fmt->flags   |= V4L2_VBI_INTERLACED;
+               if (fmt2.fmt.vbi.flags & V4L2_VBI_UNSYNC)
+                       fmt->flags   |= VBI_UNSYNC;
+               if (fmt2.fmt.vbi.flags & V4L2_VBI_INTERLACED)
+                       fmt->flags   |= VBI_INTERLACED;
                return 0;
        }
        case VIDIOCSVBIFMT:
@@ -2730,7 +2719,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                if (0 == (fmt->flags & FORMAT_FLAGS_PACKED))
                        return -EINVAL;
 
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                retval = -EINVAL;
                if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) {
                        if (fb->fmt.width > bttv_tvnorms[btv->tvnorm].swidth)
@@ -2770,7 +2759,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                                retval = bttv_switch_overlay(btv,fh,new);
                        }
                }
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                return retval;
        }
 
@@ -2901,7 +2890,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
        return 0;
 
  fh_unlock_and_return:
-       up(&fh->cap.lock);
+       mutex_unlock(&fh->cap.lock);
        return retval;
 }
 
@@ -2968,16 +2957,16 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
                buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);
        } else {
                /* read() capture */
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                if (NULL == fh->cap.read_buf) {
                        /* need to capture a new frame */
                        if (locked_btres(fh->btv,RESOURCE_VIDEO)) {
-                               up(&fh->cap.lock);
+                               mutex_unlock(&fh->cap.lock);
                                return POLLERR;
                        }
                        fh->cap.read_buf = videobuf_alloc(fh->cap.msize);
                        if (NULL == fh->cap.read_buf) {
-                               up(&fh->cap.lock);
+                               mutex_unlock(&fh->cap.lock);
                                return POLLERR;
                        }
                        fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR;
@@ -2985,13 +2974,13 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
                        if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) {
                                kfree (fh->cap.read_buf);
                                fh->cap.read_buf = NULL;
-                               up(&fh->cap.lock);
+                               mutex_unlock(&fh->cap.lock);
                                return POLLERR;
                        }
                        fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
                        fh->cap.read_off = 0;
                }
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                buf = (struct bttv_buffer*)fh->cap.read_buf;
        }
 
@@ -3120,6 +3109,7 @@ static struct file_operations bttv_fops =
        .open     = bttv_open,
        .release  = bttv_release,
        .ioctl    = bttv_ioctl,
+       .compat_ioctl   = v4l_compat_ioctl32,
        .llseek   = no_llseek,
        .read     = bttv_read,
        .mmap     = bttv_mmap,
@@ -3166,7 +3156,7 @@ static int radio_open(struct inode *inode, struct file *file)
                return -ENODEV;
 
        dprintk("bttv%d: open called (radio)\n",btv->c.nr);
-       down(&btv->lock);
+       mutex_lock(&btv->lock);
 
        btv->radio_user++;
 
@@ -3175,7 +3165,7 @@ static int radio_open(struct inode *inode, struct file *file)
        bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type);
        audio_mux(btv,AUDIO_RADIO);
 
-       up(&btv->lock);
+       mutex_unlock(&btv->lock);
        return 0;
 }
 
@@ -3229,6 +3219,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
        case VIDIOCSFREQ:
        case VIDIOCGAUDIO:
        case VIDIOCSAUDIO:
+       case VIDIOC_LOG_STATUS:
                return bttv_common_ioctls(btv,cmd,arg);
 
        default:
@@ -3701,8 +3692,8 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
 
        btv=(struct bttv *)dev_id;
 
-       if (btv->any_irq)
-               handled = bttv_any_irq(&btv->c);
+       if (btv->custom_irq)
+               handled = btv->custom_irq(btv);
 
        count=0;
        while (1) {
@@ -3738,9 +3729,9 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
                if (astat&BT848_INT_VSYNC)
                        btv->field_count++;
 
-               if (astat & BT848_INT_GPINT) {
+               if ((astat & BT848_INT_GPINT) && btv->remote) {
                        wake_up(&btv->gpioq);
-                       bttv_gpio_irq(&btv->c);
+                       bttv_input_irq(btv);
                }
 
                if (astat & BT848_INT_I2CDONE) {
@@ -3929,8 +3920,8 @@ static int __devinit bttv_probe(struct pci_dev *dev,
        sprintf(btv->c.name,"bttv%d",btv->c.nr);
 
        /* initialize structs / fill in defaults */
-       init_MUTEX(&btv->lock);
-       init_MUTEX(&btv->reslock);
+       mutex_init(&btv->lock);
+       mutex_init(&btv->reslock);
        spin_lock_init(&btv->s_lock);
        spin_lock_init(&btv->gpio_lock);
        init_waitqueue_head(&btv->gpioq);
@@ -3946,7 +3937,6 @@ static int __devinit bttv_probe(struct pci_dev *dev,
 
        btv->i2c_rc = -1;
        btv->tuner_type  = UNSET;
-       btv->pinnacle_id = UNSET;
        btv->new_input   = UNSET;
        btv->has_radio=radio[btv->c.nr];
 
@@ -4065,11 +4055,11 @@ static int __devinit bttv_probe(struct pci_dev *dev,
        }
 
        /* add subdevices */
-       if (btv->has_remote)
-               bttv_sub_add_device(&btv->c, "remote");
        if (bttv_tvcards[btv->c.type].has_dvb)
                bttv_sub_add_device(&btv->c, "dvb");
 
+       bttv_input_init(btv);
+
        /* everything is fine */
        bttv_num++;
        return 0;
@@ -4104,6 +4094,7 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
        /* tell gpio modules we are leaving ... */
        btv->shutdown=1;
        wake_up(&btv->gpioq);
+       bttv_input_fini(btv);
        bttv_sub_del_devices(&btv->c);
 
        /* unregister i2c_bus + input */
@@ -4253,7 +4244,7 @@ static int bttv_init_module(void)
        bttv_check_chipset();
 
        bus_register(&bttv_sub_bus_type);
-       return pci_module_init(&bttv_pci_driver);
+       return pci_register_driver(&bttv_pci_driver);
 }
 
 static void bttv_cleanup_module(void)