From e87c3d553d141de7a3a710c07e056c27bc1d8cc5 Mon Sep 17 00:00:00 2001 From: Gerd Knorr Date: Tue, 19 Oct 2004 18:18:09 -0700 Subject: [PATCH] [PATCH] v4l: bttv driver update This update for the bttv driver. Changes: * adapt the driver to video-buf changes. * It also added sanity checks for the bt878 risc code buffer sizes. * adds support for new tv cards. * cleanup i2c driver autoload. * misc cleanups (msleep, ...). * fix IRQ bug when stopping vbi capture. * drop check for cx2388x (bt878 successor) and the printk saying bttv doesn't support these. * set i2c class correctly for dvb cards. Signed-off-by: Gerd Knorr Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/Kconfig | 2 +- drivers/media/video/btcx-risc.c | 2 + drivers/media/video/btcx-risc.h | 4 +- drivers/media/video/bttv-cards.c | 252 +++++++++++++++++------------- drivers/media/video/bttv-driver.c | 124 ++++++++------- drivers/media/video/bttv-gpio.c | 2 + drivers/media/video/bttv-i2c.c | 42 ++++- drivers/media/video/bttv-if.c | 2 + drivers/media/video/bttv-risc.c | 46 +++--- drivers/media/video/bttv-vbi.c | 22 +-- drivers/media/video/bttv.h | 3 + drivers/media/video/bttvp.h | 10 +- 12 files changed, 303 insertions(+), 208 deletions(-) diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 28f0eb5afe0d2..932640ff0981e 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -9,7 +9,7 @@ comment "Video Adapters" config VIDEO_BT848 tristate "BT848 Video For Linux" - depends on VIDEO_DEV && PCI && I2C && SOUND + depends on VIDEO_DEV && PCI && I2C && FW_LOADER select I2C_ALGOBIT ---help--- Support for BT848 based frame grabber/overlay boards. This includes diff --git a/drivers/media/video/btcx-risc.c b/drivers/media/video/btcx-risc.c index 3a0320ecf52b5..6a30200cc02d3 100644 --- a/drivers/media/video/btcx-risc.c +++ b/drivers/media/video/btcx-risc.c @@ -1,4 +1,6 @@ /* + $Id: btcx-risc.c,v 1.2 2004/09/15 16:15:24 kraxel Exp $ + btcx-risc.c bt848/bt878/cx2388x risc code generator. diff --git a/drivers/media/video/btcx-risc.h b/drivers/media/video/btcx-risc.h index 49daaadb02df7..41f60395a5203 100644 --- a/drivers/media/video/btcx-risc.h +++ b/drivers/media/video/btcx-risc.h @@ -1,4 +1,6 @@ - +/* + * $Id: btcx-risc.h,v 1.2 2004/09/15 16:15:24 kraxel Exp $ + */ struct btcx_riscmem { unsigned int size; u32 *cpu; diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c index 0b6a1bc50ffad..d004ce5e325ca 100644 --- a/drivers/media/video/bttv-cards.c +++ b/drivers/media/video/bttv-cards.c @@ -1,4 +1,6 @@ /* + $Id: bttv-cards.c,v 1.28 2004/10/06 13:45:14 kraxel Exp $ + bttv-cards.c this file has configuration informations - card-specific stuff @@ -308,6 +310,7 @@ static struct CARD { { 0x00011822, BTTV_TWINHAN_DST, "Twinhan VisionPlus DVB-T" }, { 0xfc00270f, BTTV_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, { 0x07711461, BTTV_AVDVBT_771, "AVermedia DVB-T 771" }, + { 0xdb1018ac, BTTV_DVICO_DVBT_LITE, "DVICO FusionHDTV DVB-T Lite" }, { 0, -1, NULL } }; @@ -2089,10 +2092,10 @@ struct tvcard bttv_tvcards[] = { /* Matt Jesson */ /* Based on the Nebula card data - added remote and new card number - BTTV_AVDVBT_761, see also ir-kbd-gpio.c */ .name = "AverMedia AverTV DVB-T 761", - .video_inputs = 1, + .video_inputs = 2, .tuner = -1, - .svhs = -1, - .muxsel = { 2, 3, 1, 0}, + .svhs = 1, + .muxsel = { 3, 1, 2, 0}, /* Comp0, S-Video, ?, ? */ .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -2147,6 +2150,34 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_PHILIPS_PAL, .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */ .has_radio = 1, /* not every card has radio */ +},{ + + /* ---- card 0x80 ---------------------------------- */ + /* Chris Pascoe */ + .name = "DVICO FusionHDTV DVB-T Lite", + .tuner = -1, + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, + .pll = PLL_28, + .no_video = 1, + .has_dvb = 1, + .tuner_type = -1, +},{ + /* Steven */ + .name = "V-Gear MyVCD", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x3f, + .muxsel = {2, 3, 1, 0}, + .audiomux = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31}, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = TUNER_PHILIPS_NTSC_M, + .has_radio = 0, + // .has_remote = 1, }}; const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); @@ -2538,6 +2569,7 @@ void __devinit bttv_init_card1(struct bttv *btv) /* initialization part two -- after registering i2c bus */ void __devinit bttv_init_card2(struct bttv *btv) { + int tda9887; btv->tuner_type = -1; if (BTTV_UNKNOWN == btv->c.type) { @@ -2705,45 +2737,40 @@ void __devinit bttv_init_card2(struct bttv *btv) boot_bt832(btv); } + if (!autoload) + return; + /* try to detect audio/fader chips */ if (!bttv_tvcards[btv->c.type].no_msp34xx && - bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx") >=0) { - if (autoload) - request_module("msp3400"); - } + bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx") >=0) + request_module("msp3400"); if (bttv_tvcards[btv->c.type].msp34xx_alt && - bttv_I2CRead(btv, I2C_MSP3400_ALT, "MSP34xx (alternate address)") >=0) { - if (autoload) - request_module("msp3400"); - } + bttv_I2CRead(btv, I2C_MSP3400_ALT, "MSP34xx (alternate address)") >=0) + request_module("msp3400"); if (!bttv_tvcards[btv->c.type].no_tda9875 && - bttv_I2CRead(btv, I2C_TDA9875, "TDA9875") >=0) { - if (autoload) - request_module("tda9875"); - } + bttv_I2CRead(btv, I2C_TDA9875, "TDA9875") >=0) + request_module("tda9875"); if (!bttv_tvcards[btv->c.type].no_tda7432 && - bttv_I2CRead(btv, I2C_TDA7432, "TDA7432") >=0) { - if (autoload) - request_module("tda7432"); - } + bttv_I2CRead(btv, I2C_TDA7432, "TDA7432") >=0) + request_module("tda7432"); - if (bttv_tvcards[btv->c.type].needs_tvaudio) { - if (autoload) - request_module("tvaudio"); - } + if (bttv_tvcards[btv->c.type].needs_tvaudio) + request_module("tvaudio"); /* tuner modules */ - if (btv->pinnacle_id != UNSET) { - if (autoload) - request_module("tda9887"); - } - if (btv->tuner_type != UNSET) { - if (autoload) - request_module("tuner"); - } + tda9887 = 0; + if (btv->pinnacle_id != UNSET) + tda9887 = 1; + if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb && + bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0) + tda9887 = 1; + if (tda9887) + request_module("tda9887"); + if (btv->tuner_type != UNSET) + request_module("tuner"); } @@ -2854,7 +2881,8 @@ static void __devinit hauppauge_eeprom(struct bttv *btv) if (bttv_verbose) printk(KERN_INFO "bttv%d: Hauppauge eeprom: model=%d, " "tuner=%s (%d), radio=%s\n", - btv->c.nr, model, hauppauge_tuner[tuner].name, + btv->c.nr, model, (tuner < ARRAY_SIZE(hauppauge_tuner) + ? hauppauge_tuner[tuner].name : "?"), btv->tuner_type, radio ? "yes" : "no"); } @@ -4024,6 +4052,86 @@ static void ivc120_muxsel(struct bttv *btv, unsigned int input) } +/* PXC200 muxsel helper + * luke@syseng.anu.edu.au + * another transplant + * from Alessandro Rubini (rubini@linux.it) + * + * There are 4 kinds of cards: + * PXC200L which is bt848 + * PXC200F which is bt848 with PIC controlling mux + * PXC200AL which is bt878 + * PXC200AF which is bt878 with PIC controlling mux + */ +#define PX_CFG_PXC200F 0x01 +#define PX_FLAG_PXC200A 0x00001000 /* a pxc200A is bt-878 based */ +#define PX_I2C_PIC 0x0f +#define PX_PXC200A_CARDID 0x200a1295 +#define PX_I2C_CMD_CFG 0x00 + +static void PXC200_muxsel(struct bttv *btv, unsigned int input) +{ + int rc; + long mux; + int bitmask; + unsigned char buf[2]; + + /* Read PIC config to determine if this is a PXC200F */ + /* PX_I2C_CMD_CFG*/ + buf[0]=0; + buf[1]=0; + rc=bttv_I2CWrite(btv,(PX_I2C_PIC<<1),buf[0],buf[1],1); + if (rc) { + printk(KERN_DEBUG "bttv%d: PXC200_muxsel: pic cfg write failed:%d\n", btv->c.nr,rc); + /* not PXC ? do nothing */ + return; + } + + rc=bttv_I2CRead(btv,(PX_I2C_PIC<<1),NULL); + if (!(rc & PX_CFG_PXC200F)) { + printk(KERN_DEBUG "bttv%d: PXC200_muxsel: not PXC200F rc:%d \n", btv->c.nr,rc); + return; + } + + + /* The multiplexer in the 200F is handled by the GPIO port */ + /* get correct mapping between inputs */ + /* mux = bttv_tvcards[btv->type].muxsel[input] & 3; */ + /* ** not needed!? */ + mux = input; + + /* make sure output pins are enabled */ + /* bitmask=0x30f; */ + bitmask=0x302; + /* check whether we have a PXC200A */ + if (btv->cardid == PX_PXC200A_CARDID) { + bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */ + bitmask |= 7<<4; /* the DAC */ + } + btwrite(bitmask, BT848_GPIO_OUT_EN); + + bitmask = btread(BT848_GPIO_DATA); + if (btv->cardid == PX_PXC200A_CARDID) + bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7); + else /* older device */ + bitmask = (bitmask & ~0x300) | ((mux & 3) << 8); + btwrite(bitmask,BT848_GPIO_DATA); + + /* + * Was "to be safe, set the bt848 to input 0" + * Actually, since it's ok at load time, better not messing + * with these bits (on PXC200AF you need to set mux 2 here) + * + * needed because bttv-driver sets mux before calling this function + */ + if (btv->cardid == PX_PXC200A_CARDID) + btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM); + else /* older device */ + btand(~BT848_IFORM_MUXSEL,BT848_IFORM); + + printk(KERN_DEBUG "bttv%d: setting input channel to:%d\n", btv->c.nr,(int)mux); +} + /* ----------------------------------------------------------------------- */ /* motherboard chipset specific stuff */ @@ -4110,86 +4218,6 @@ int __devinit bttv_handle_chipset(struct bttv *btv) } -/* PXC200 muxsel helper - * luke@syseng.anu.edu.au - * another transplant - * from Alessandro Rubini (rubini@linux.it) - * - * There are 4 kinds of cards: - * PXC200L which is bt848 - * PXC200F which is bt848 with PIC controlling mux - * PXC200AL which is bt878 - * PXC200AF which is bt878 with PIC controlling mux - */ -#define PX_CFG_PXC200F 0x01 -#define PX_FLAG_PXC200A 0x00001000 /* a pxc200A is bt-878 based */ -#define PX_I2C_PIC 0x0f -#define PX_PXC200A_CARDID 0x200a1295 -#define PX_I2C_CMD_CFG 0x00 - -static void PXC200_muxsel(struct bttv *btv, unsigned int input) -{ - int rc; - long mux; - int bitmask; - unsigned char buf[2]; - - /* Read PIC config to determine if this is a PXC200F */ - /* PX_I2C_CMD_CFG*/ - buf[0]=0; - buf[1]=0; - rc=bttv_I2CWrite(btv,(PX_I2C_PIC<<1),buf[0],buf[1],1); - if (rc) { - printk(KERN_DEBUG "bttv%d: PXC200_muxsel: pic cfg write failed:%d\n", btv->c.nr,rc); - /* not PXC ? do nothing */ - return; - } - - rc=bttv_I2CRead(btv,(PX_I2C_PIC<<1),0); - if (!(rc & PX_CFG_PXC200F)) { - printk(KERN_DEBUG "bttv%d: PXC200_muxsel: not PXC200F rc:%d \n", btv->c.nr,rc); - return; - } - - - /* The multiplexer in the 200F is handled by the GPIO port */ - /* get correct mapping between inputs */ - /* mux = bttv_tvcards[btv->type].muxsel[input] & 3; */ - /* ** not needed!? */ - mux = input; - - /* make sure output pins are enabled */ - /* bitmask=0x30f; */ - bitmask=0x302; - /* check whether we have a PXC200A */ - if (btv->cardid == PX_PXC200A_CARDID) { - bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */ - bitmask |= 7<<4; /* the DAC */ - } - btwrite(bitmask, BT848_GPIO_OUT_EN); - - bitmask = btread(BT848_GPIO_DATA); - if (btv->cardid == PX_PXC200A_CARDID) - bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7); - else /* older device */ - bitmask = (bitmask & ~0x300) | ((mux & 3) << 8); - btwrite(bitmask,BT848_GPIO_DATA); - - /* - * Was "to be safe, set the bt848 to input 0" - * Actually, since it's ok at load time, better not messing - * with these bits (on PXC200AF you need to set mux 2 here) - * - * needed because bttv-driver sets mux before calling this function - */ - if (btv->cardid == PX_PXC200A_CARDID) - btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM); - else /* older device */ - btand(~BT848_IFORM_MUXSEL,BT848_IFORM); - - printk(KERN_DEBUG "bttv%d: setting input channel to:%d\n", btv->c.nr,(int)mux); -} - /* * Local variables: * c-basic-offset: 8 diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index 1fa3fbf211610..2642b424bfed3 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c @@ -1,4 +1,7 @@ + /* + $Id: bttv-driver.c,v 1.22 2004/10/12 07:33:22 kraxel Exp $ + bttv - Bt848 frame grabber driver Copyright (C) 1996,97,98 Ralph Metzler @@ -743,8 +746,7 @@ static void set_pll(struct bttv *btv) for (i=0; i<10; i++) { /* Let other people run while the PLL stabilizes */ vprintk("."); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ/50); + msleep(10); if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) { btwrite(0,BT848_DSTATUS); @@ -979,7 +981,7 @@ set_input(struct bttv *btv, unsigned int input) btv->input = input; if (irq_iswitch) { spin_lock_irqsave(&btv->s_lock,flags); - if (btv->curr.irqflags) { + if (btv->curr.frame_irq) { /* active capture -> delayed input switch */ btv->new_input = input; } else { @@ -992,6 +994,7 @@ set_input(struct bttv *btv, unsigned int input) audio_mux(btv,(input == bttv_tvcards[btv->c.type].tuner ? AUDIO_TUNER : AUDIO_EXTERN)); set_tvnorm(btv,btv->tvnorm); + i2c_vidiocschan(btv); } static void init_irqreg(struct bttv *btv) @@ -1076,7 +1079,7 @@ void bttv_reinit_bt848(struct bttv *btv) printk(KERN_INFO "bttv%d: reset, reinitialize\n",btv->c.nr); spin_lock_irqsave(&btv->s_lock,flags); btv->errors=0; - bttv_set_dma(btv,0,0); + bttv_set_dma(btv,0); spin_unlock_irqrestore(&btv->s_lock,flags); init_bt848(btv); @@ -1334,8 +1337,8 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh, spin_lock_irqsave(&btv->s_lock,flags); old = btv->screen; btv->screen = new; - btv->curr.irqflags |= 1; - bttv_set_dma(btv, 0x03, btv->curr.irqflags); + btv->loop_irq |= 1; + bttv_set_dma(btv, 0x03); spin_unlock_irqrestore(&btv->s_lock,flags); if (NULL == new) free_btres(btv,fh,RESOURCE_OVERLAY); @@ -1411,9 +1414,9 @@ static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf, } static int -buffer_setup(struct file *file, unsigned int *count, unsigned int *size) +buffer_setup(void *priv, unsigned int *count, unsigned int *size) { - struct bttv_fh *fh = file->private_data; + struct bttv_fh *fh = priv; *size = fh->fmt->depth*fh->width*fh->height >> 3; if (0 == *count) @@ -1424,32 +1427,35 @@ buffer_setup(struct file *file, unsigned int *count, unsigned int *size) } static int -buffer_prepare(struct file *file, struct videobuf_buffer *vb, +buffer_prepare(void *priv, struct videobuf_buffer *vb, enum v4l2_field field) { struct bttv_buffer *buf = (struct bttv_buffer*)vb; - struct bttv_fh *fh = file->private_data; + struct bttv_fh *fh = priv; return bttv_prepare_buffer(fh->btv, buf, fh->fmt, fh->width, fh->height, field); } static void -buffer_queue(struct file *file, struct videobuf_buffer *vb) +buffer_queue(void *priv, struct videobuf_buffer *vb) { struct bttv_buffer *buf = (struct bttv_buffer*)vb; - struct bttv_fh *fh = file->private_data; + struct bttv_fh *fh = priv; + struct bttv *btv = fh->btv; buf->vb.state = STATE_QUEUED; - list_add_tail(&buf->vb.queue,&fh->btv->capture); - fh->btv->curr.irqflags |= 1; - bttv_set_dma(fh->btv, 0x03, fh->btv->curr.irqflags); + list_add_tail(&buf->vb.queue,&btv->capture); + if (!btv->curr.frame_irq) { + btv->loop_irq |= 1; + bttv_set_dma(btv, 0x03); + } } -static void buffer_release(struct file *file, struct videobuf_buffer *vb) +static void buffer_release(void *priv, struct videobuf_buffer *vb) { struct bttv_buffer *buf = (struct bttv_buffer*)vb; - struct bttv_fh *fh = file->private_data; + struct bttv_fh *fh = priv; bttv_dma_free(fh->btv,buf); } @@ -1706,7 +1712,6 @@ int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) return -EINVAL; down(&btv->lock); set_input(btv,*i); - i2c_vidiocschan(btv); up(&btv->lock); return 0; } @@ -2381,7 +2386,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, unsigned int i; down(&fh->cap.lock); - retval = videobuf_mmap_setup(file,&fh->cap,gbuffers,gbufsize, + retval = videobuf_mmap_setup(file->private_data, + &fh->cap,gbuffers,gbufsize, V4L2_MEMORY_MMAP); if (retval < 0) goto fh_unlock_and_return; @@ -2422,7 +2428,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, if (0 != retval) goto fh_unlock_and_return; spin_lock_irqsave(&btv->s_lock,flags); - buffer_queue(file,&buf->vb); + buffer_queue(file->private_data,&buf->vb); spin_unlock_irqrestore(&btv->s_lock,flags); up(&fh->cap.lock); return 0; @@ -2679,16 +2685,17 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, } case VIDIOC_REQBUFS: - return videobuf_reqbufs(file,bttv_queue(fh),arg); + return videobuf_reqbufs(file->private_data,bttv_queue(fh),arg); case VIDIOC_QUERYBUF: return videobuf_querybuf(bttv_queue(fh),arg); case VIDIOC_QBUF: - return videobuf_qbuf(file,bttv_queue(fh),arg); + return videobuf_qbuf(file->private_data,bttv_queue(fh),arg); case VIDIOC_DQBUF: - return videobuf_dqbuf(file,bttv_queue(fh),arg); + return videobuf_dqbuf(file->private_data,bttv_queue(fh),arg, + file->f_flags & O_NONBLOCK); case VIDIOC_STREAMON: { @@ -2696,13 +2703,13 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, if (!check_alloc_btres(btv,fh,res)) return -EBUSY; - return videobuf_streamon(file,bttv_queue(fh)); + return videobuf_streamon(file->private_data,bttv_queue(fh)); } case VIDIOC_STREAMOFF: { int res = bttv_resource(fh); - retval = videobuf_streamoff(file,bttv_queue(fh)); + retval = videobuf_streamoff(file->private_data,bttv_queue(fh)); if (retval < 0) return retval; free_btres(btv,fh,res); @@ -2839,12 +2846,16 @@ static ssize_t bttv_read(struct file *file, char __user *data, case V4L2_BUF_TYPE_VIDEO_CAPTURE: if (locked_btres(fh->btv,RESOURCE_VIDEO)) return -EBUSY; - retval = videobuf_read_one(file, &fh->cap, data, count, ppos); + retval = videobuf_read_one(file->private_data, + &fh->cap, data, count, ppos, + file->f_flags & O_NONBLOCK); break; case V4L2_BUF_TYPE_VBI_CAPTURE: if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI)) return -EBUSY; - retval = videobuf_read_stream(file, &fh->vbi, data, count, ppos, 1); + retval = videobuf_read_stream(file->private_data, + &fh->vbi, data, count, ppos, 1, + file->f_flags & O_NONBLOCK); break; default: BUG(); @@ -2860,8 +2871,9 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI)) - return -EBUSY; - return videobuf_poll_stream(file, &fh->vbi, wait); + return POLLERR; + return videobuf_poll_stream(file, file->private_data, + &fh->vbi, wait); } if (check_btres(fh,RESOURCE_VIDEO)) { @@ -2885,11 +2897,11 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) } fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR; field = videobuf_next_field(&fh->cap); - if (0 != fh->cap.ops->buf_prepare(file,fh->cap.read_buf,field)) { + if (0 != fh->cap.ops->buf_prepare(file->private_data,fh->cap.read_buf,field)) { up(&fh->cap.lock); return POLLERR; } - fh->cap.ops->buf_queue(file,fh->cap.read_buf); + fh->cap.ops->buf_queue(file->private_data,fh->cap.read_buf); fh->cap.read_off = 0; } up(&fh->cap.lock); @@ -2975,20 +2987,20 @@ static int bttv_release(struct inode *inode, struct file *file) /* stop video capture */ if (check_btres(fh, RESOURCE_VIDEO)) { - videobuf_streamoff(file,&fh->cap); + videobuf_streamoff(file->private_data,&fh->cap); free_btres(btv,fh,RESOURCE_VIDEO); } if (fh->cap.read_buf) { - buffer_release(file,fh->cap.read_buf); + buffer_release(file->private_data,fh->cap.read_buf); kfree(fh->cap.read_buf); } /* stop vbi capture */ if (check_btres(fh, RESOURCE_VBI)) { if (fh->vbi.streaming) - videobuf_streamoff(file,&fh->vbi); + videobuf_streamoff(file->private_data,&fh->vbi); if (fh->vbi.reading) - videobuf_read_stop(file,&fh->vbi); + videobuf_read_stop(file->private_data,&fh->vbi); free_btres(btv,fh,RESOURCE_VBI); } @@ -3249,7 +3261,7 @@ bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set) /* capture request ? */ if (!list_empty(&btv->capture)) { - set->irqflags = 1; + set->frame_irq = 1; item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue); if (V4L2_FIELD_HAS_TOP(item->vb.field)) set->top = item; @@ -3270,7 +3282,7 @@ bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set) set->bottom = item; } if (NULL != set->top && NULL != set->bottom) - set->topirq = 2; + set->top_irq = 2; } } } @@ -3296,7 +3308,7 @@ bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set) dprintk("bttv%d: next set: top=%p bottom=%p [screen=%p,irq=%d,%d]\n", btv->c.nr,set->top, set->bottom, - btv->screen,set->irqflags,set->topirq); + btv->screen,set->frame_irq,set->top_irq); return 0; } @@ -3377,9 +3389,10 @@ static void bttv_irq_timeout(unsigned long data) ovbi = btv->cvbi; btv->curr = new; btv->cvbi = NULL; + btv->loop_irq = 0; bttv_buffer_activate_video(btv, &new); bttv_buffer_activate_vbi(btv, NULL); - bttv_set_dma(btv, 0, 0); + bttv_set_dma(btv, 0); /* wake up */ bttv_irq_wakeup_video(btv, &old, &new, STATE_ERROR); @@ -3412,7 +3425,7 @@ bttv_irq_wakeup_top(struct bttv *btv) return; spin_lock(&btv->s_lock); - btv->curr.topirq = 0; + btv->curr.top_irq = 0; btv->curr.top = NULL; bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0); @@ -3456,8 +3469,9 @@ bttv_irq_switch_video(struct bttv *btv) /* switch over */ old = btv->curr; btv->curr = new; + btv->loop_irq &= ~1; bttv_buffer_activate_video(btv, &new); - bttv_set_dma(btv, 0, new.irqflags); + bttv_set_dma(btv, 0); /* switch input */ if (UNSET != btv->new_input) { @@ -3495,8 +3509,9 @@ bttv_irq_switch_vbi(struct bttv *btv) /* switch */ btv->cvbi = new; + btv->loop_irq &= ~4; bttv_buffer_activate_vbi(btv, new); - bttv_set_dma(btv, 0, btv->curr.irqflags); + bttv_set_dma(btv, 0); bttv_irq_wakeup_vbi(btv, old, STATE_DONE); spin_unlock(&btv->s_lock); @@ -3925,17 +3940,19 @@ static int bttv_suspend(struct pci_dev *pci_dev, u32 state) struct bttv_buffer_set idle; unsigned long flags; - printk("bttv%d: suspend %d\n", btv->c.nr, state); + dprintk("bttv%d: suspend %d\n", btv->c.nr, state); /* stop dma + irqs */ spin_lock_irqsave(&btv->s_lock,flags); memset(&idle, 0, sizeof(idle)); btv->state.video = btv->curr; btv->state.vbi = btv->cvbi; + btv->state.loop_irq = btv->loop_irq; btv->curr = idle; + btv->loop_irq = 0; bttv_buffer_activate_video(btv, &idle); bttv_buffer_activate_vbi(btv, NULL); - bttv_set_dma(btv, 0, 0); + bttv_set_dma(btv, 0); btwrite(0, BT848_INT_MASK); spin_unlock_irqrestore(&btv->s_lock,flags); @@ -3957,7 +3974,7 @@ static int bttv_resume(struct pci_dev *pci_dev) struct bttv *btv = pci_get_drvdata(pci_dev); unsigned long flags; - printk("bttv%d: resume\n", btv->c.nr); + dprintk("bttv%d: resume\n", btv->c.nr); /* restore pci state */ if (btv->state.disabled) { @@ -3976,9 +3993,10 @@ static int bttv_resume(struct pci_dev *pci_dev) spin_lock_irqsave(&btv->s_lock,flags); btv->curr = btv->state.video; btv->cvbi = btv->state.vbi; + btv->loop_irq = btv->state.loop_irq; bttv_buffer_activate_video(btv, &btv->curr); bttv_buffer_activate_vbi(btv, btv->cvbi); - bttv_set_dma(btv, 0, btv->curr.irqflags); + bttv_set_dma(btv, 0); spin_unlock_irqrestore(&btv->s_lock,flags); return 0; } @@ -4002,14 +4020,12 @@ static struct pci_driver bttv_pci_driver = { .id_table = bttv_pci_tbl, .probe = bttv_probe, .remove = __devexit_p(bttv_remove), - - .suspend = bttv_suspend, - .resume = bttv_resume, + .suspend = bttv_suspend, + .resume = bttv_resume, }; static int bttv_init_module(void) { - int rc; bttv_num = 0; printk(KERN_INFO "bttv: driver version %d.%d.%d loaded\n", @@ -4032,13 +4048,7 @@ static int bttv_init_module(void) bttv_check_chipset(); bus_register(&bttv_sub_bus_type); - rc = pci_module_init(&bttv_pci_driver); - if (-ENODEV == rc) { - /* plenty of people trying to use bttv for the cx2388x ... */ - if (NULL != pci_find_device(0x14f1, 0x8800, NULL)) - printk("bttv doesn't support your Conexant 2388x card.\n"); - } - return rc; + return pci_module_init(&bttv_pci_driver); } static void bttv_cleanup_module(void) diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c index 585f67ddedb70..fbcaa08d123b9 100644 --- a/drivers/media/video/bttv-gpio.c +++ b/drivers/media/video/bttv-gpio.c @@ -1,4 +1,6 @@ /* + $Id: bttv-gpio.c,v 1.3 2004/09/15 16:15:24 kraxel Exp $ + bttv-gpio.c -- gpio sub drivers sysfs-based sub driver interface for bttv diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c index 5eb88fcadfa3c..e4bc3540bf2be 100644 --- a/drivers/media/video/bttv-i2c.c +++ b/drivers/media/video/bttv-i2c.c @@ -1,4 +1,6 @@ /* + $Id: bttv-i2c.c,v 1.10 2004/10/06 17:30:51 kraxel Exp $ + bttv-i2c.c -- all the i2c code is here bttv - Bt848 frame grabber driver @@ -44,8 +46,11 @@ static int detach_inform(struct i2c_client *client); static int i2c_debug = 0; static int i2c_hw = 0; +static int i2c_scan = 0; MODULE_PARM(i2c_debug,"i"); MODULE_PARM(i2c_hw,"i"); +MODULE_PARM(i2c_scan,"i"); +MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); /* ----------------------------------------------------------------------- */ /* I2C functions - bitbanging adapter (software i2c) */ @@ -139,10 +144,8 @@ bttv_i2c_wait_done(struct bttv *btv) int rc = 0; add_wait_queue(&btv->i2c_queue, &wait); - set_current_state(TASK_INTERRUPTIBLE); if (0 == btv->i2c_done) - schedule_timeout(HZ/50+1); - set_current_state(TASK_RUNNING); + msleep_interruptible(20); remove_wait_queue(&btv->i2c_queue, &wait); if (0 == btv->i2c_done) @@ -423,6 +426,30 @@ void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr) } } +static char *i2c_devs[128] = { + [ 0x30 >> 1 ] = "IR (hauppauge)", + [ 0x80 >> 1 ] = "msp34xx", + [ 0x86 >> 1 ] = "tda9887", + [ 0xa0 >> 1 ] = "eeprom", + [ 0xc0 >> 1 ] = "tuner (analog)", + [ 0xc2 >> 1 ] = "tuner (analog)", +}; + +static void do_i2c_scan(char *name, struct i2c_client *c) +{ + unsigned char buf; + int i,rc; + + for (i = 0; i < 128; i++) { + c->addr = i; + rc = i2c_master_recv(c,&buf,0); + if (rc < 0) + continue; + printk("%s: i2c scan: found device @ 0x%x [%s]\n", + name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); + } +} + /* init + register i2c algo-bit adapter */ int __devinit init_bttv_i2c(struct bttv *btv) { @@ -453,6 +480,13 @@ int __devinit init_bttv_i2c(struct bttv *btv) i2c_set_adapdata(&btv->c.i2c_adap, btv); btv->i2c_client.adapter = &btv->c.i2c_adap; +#ifdef I2C_CLASS_TV_ANALOG + if (bttv_tvcards[btv->c.type].no_video) + btv->c.i2c_adap.class &= ~I2C_CLASS_TV_ANALOG; + if (bttv_tvcards[btv->c.type].has_dvb) + btv->c.i2c_adap.class |= I2C_CLASS_TV_DIGITAL; +#endif + if (btv->use_i2c_hw) { btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap); } else { @@ -460,6 +494,8 @@ int __devinit init_bttv_i2c(struct bttv *btv) bttv_bit_setsda(btv,1); btv->i2c_rc = i2c_bit_add_bus(&btv->c.i2c_adap); } + if (0 == btv->i2c_rc && i2c_scan) + do_i2c_scan(btv->c.name,&btv->i2c_client); return btv->i2c_rc; } diff --git a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c index 74da71195ba81..da119042933b4 100644 --- a/drivers/media/video/bttv-if.c +++ b/drivers/media/video/bttv-if.c @@ -1,4 +1,6 @@ /* + $Id: bttv-if.c,v 1.2 2004/09/15 16:15:24 kraxel Exp $ + bttv-if.c -- old gpio interface to other kernel modules don't use in new code, will go away in 2.7 have a look at bttv-gpio.c instead. diff --git a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c index 3731d2c9a26c5..a9206afcdd18b 100644 --- a/drivers/media/video/bttv-risc.c +++ b/drivers/media/video/bttv-risc.c @@ -1,4 +1,6 @@ /* + $Id: bttv-risc.c,v 1.8 2004/10/06 17:30:51 kraxel Exp $ + bttv-risc.c -- interfaces to other kernel modules bttv risc code handling @@ -55,8 +57,6 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, instructions += 2; if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) return rc; - dprintk("bttv%d: risc packed: bpl %d lines %d instr %d size %d ptr %p\n", - btv->c.nr, bpl, lines, instructions, risc->size, risc->cpu); /* sync instruction */ rp = risc->cpu; @@ -101,13 +101,11 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, offset += todo; } offset += padding; - dprintk("bttv%d: risc packed: line %d ptr %p\n", - btv->c.nr, line, rp); } - dprintk("bttv%d: risc packed: %d sglist elems\n", btv->c.nr, (int)(sg-sglist)); /* save pointer to jmp instruction address */ risc->jmp = rp; + BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); return 0; } @@ -155,15 +153,15 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc, break; case 1: if (topfield) - chroma = (line & 1) == 0; + chroma = ((line & 1) == 0); else - chroma = (line & 1) == 1; + chroma = ((line & 1) == 1); break; case 2: if (topfield) - chroma = (line & 3) == 0; + chroma = ((line & 3) == 0); else - chroma = (line & 3) == 2; + chroma = ((line & 3) == 2); break; default: chroma = 0; @@ -225,6 +223,7 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc, /* save pointer to jmp instruction address */ risc->jmp = rp; + BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); return 0; } @@ -309,6 +308,7 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, /* save pointer to jmp instruction address */ risc->jmp = rp; + BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size); kfree(skips); return 0; } @@ -391,7 +391,7 @@ bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd) /* risc group / risc main loop / dma management */ void -bttv_set_dma(struct bttv *btv, int override, int irqflags) +bttv_set_dma(struct bttv *btv, int override) { unsigned long cmd; int capctl; @@ -407,20 +407,20 @@ bttv_set_dma(struct bttv *btv, int override, int irqflags) capctl |= override; d2printk(KERN_DEBUG - "bttv%d: capctl=%x irq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n", - btv->c.nr,capctl,irqflags, + "bttv%d: capctl=%x lirq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n", + btv->c.nr,capctl,btv->loop_irq, btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0, btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0, btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0, btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0); cmd = BT848_RISC_JUMP; - if (irqflags) { + if (btv->loop_irq) { cmd |= BT848_RISC_IRQ; - cmd |= (irqflags & 0x0f) << 16; - cmd |= (~irqflags & 0x0f) << 20; + cmd |= (btv->loop_irq & 0x0f) << 16; + cmd |= (~btv->loop_irq & 0x0f) << 20; } - if (irqflags || btv->cvbi) { + if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) { mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT); } else { del_timer(&btv->timeout); @@ -559,8 +559,10 @@ bttv_buffer_activate_video(struct bttv *btv, } bttv_apply_geo(btv, &set->top->geo, 1); bttv_apply_geo(btv, &set->bottom->geo,0); - bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, set->topirq); - bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, 0); + bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, + set->top_irq); + bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, + set->frame_irq); btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f), ~0xff, BT848_COLOR_FMT); btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05), @@ -571,7 +573,8 @@ bttv_buffer_activate_video(struct bttv *btv, list_del(&set->top->vb.queue); bttv_apply_geo(btv, &set->top->geo,1); bttv_apply_geo(btv, &set->top->geo,0); - bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, 0); + bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, + set->frame_irq); bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0); btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT); btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL); @@ -581,8 +584,9 @@ bttv_buffer_activate_video(struct bttv *btv, list_del(&set->bottom->vb.queue); bttv_apply_geo(btv, &set->bottom->geo,1); bttv_apply_geo(btv, &set->bottom->geo,0); - bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0); - bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, 0); + bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0); + bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, + set->frame_irq); btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT); btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL); } else { diff --git a/drivers/media/video/bttv-vbi.c b/drivers/media/video/bttv-vbi.c index ad655c8aa13fc..77365b45f027e 100644 --- a/drivers/media/video/bttv-vbi.c +++ b/drivers/media/video/bttv-vbi.c @@ -1,4 +1,6 @@ /* + $Id: bttv-vbi.c,v 1.5 2004/10/06 17:30:51 kraxel Exp $ + bttv - Bt848 frame grabber driver vbi interface @@ -61,10 +63,10 @@ vbi_buffer_risc(struct bttv *btv, struct bttv_buffer *buf, int lines) return 0; } -static int vbi_buffer_setup(struct file *file, +static int vbi_buffer_setup(void *priv, unsigned int *count, unsigned int *size) { - struct bttv_fh *fh = file->private_data; + struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; if (0 == *count) @@ -74,10 +76,10 @@ static int vbi_buffer_setup(struct file *file, return 0; } -static int vbi_buffer_prepare(struct file *file, struct videobuf_buffer *vb, +static int vbi_buffer_prepare(void *priv, struct videobuf_buffer *vb, enum v4l2_field field) { - struct bttv_fh *fh = file->private_data; + struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; struct bttv_buffer *buf = (struct bttv_buffer*)vb; int rc; @@ -105,9 +107,9 @@ static int vbi_buffer_prepare(struct file *file, struct videobuf_buffer *vb, } static void -vbi_buffer_queue(struct file *file, struct videobuf_buffer *vb) +vbi_buffer_queue(void *priv, struct videobuf_buffer *vb) { - struct bttv_fh *fh = file->private_data; + struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; struct bttv_buffer *buf = (struct bttv_buffer*)vb; @@ -115,14 +117,14 @@ vbi_buffer_queue(struct file *file, struct videobuf_buffer *vb) buf->vb.state = STATE_QUEUED; list_add_tail(&buf->vb.queue,&btv->vcapture); if (NULL == btv->cvbi) { - fh->btv->curr.irqflags |= 4; - bttv_set_dma(btv,0x0c,fh->btv->curr.irqflags); + fh->btv->loop_irq |= 4; + bttv_set_dma(btv,0x0c); } } -static void vbi_buffer_release(struct file *file, struct videobuf_buffer *vb) +static void vbi_buffer_release(void *priv, struct videobuf_buffer *vb) { - struct bttv_fh *fh = file->private_data; + struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; struct bttv_buffer *buf = (struct bttv_buffer*)vb; diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h index 5b8199b79420a..edbed4b30151b 100644 --- a/drivers/media/video/bttv.h +++ b/drivers/media/video/bttv.h @@ -1,4 +1,6 @@ /* + * $Id: bttv.h,v 1.9 2004/09/15 16:15:24 kraxel Exp $ + * * bttv - Bt848 frame grabber driver * * card ID's and external interfaces of the bttv driver @@ -130,6 +132,7 @@ #define BTTV_MATRIX_VISIONSQ 0x7d #define BTTV_MATRIX_VISIONSLC 0x7e #define BTTV_APAC_VIEWCOMP 0x7f +#define BTTV_DVICO_DVBT_LITE 0x80 /* i2c address list */ #define I2C_TSA5522 0xc2 diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h index bd5235944d7a5..35267092e6440 100644 --- a/drivers/media/video/bttvp.h +++ b/drivers/media/video/bttvp.h @@ -1,4 +1,6 @@ /* + $Id: bttvp.h,v 1.10 2004/10/06 17:30:51 kraxel Exp $ + bttv - Bt848 frame grabber driver bttv's *private* header file -- nobody other than bttv itself @@ -127,8 +129,8 @@ struct bttv_buffer { struct bttv_buffer_set { struct bttv_buffer *top; /* top field buffer */ struct bttv_buffer *bottom; /* bottom field buffer */ - unsigned int irqflags; - unsigned int topirq; + unsigned int top_irq; + unsigned int frame_irq; }; struct bttv_overlay { @@ -189,7 +191,7 @@ void bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo, void bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int top); /* control dma register + risc main loop */ -void bttv_set_dma(struct bttv *btv, int override, int irqflags); +void bttv_set_dma(struct bttv *btv, int override); int bttv_risc_init_main(struct bttv *btv); int bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc, int irqflags); @@ -280,6 +282,7 @@ struct bttv_suspend_state { u32 gpio_enable; u32 gpio_data; int disabled; + int loop_irq; struct bttv_buffer_set video; struct bttv_buffer *vbi; }; @@ -380,6 +383,7 @@ struct bttv { struct list_head vcapture; /* vbi capture queue */ struct bttv_buffer_set curr; /* active buffers */ struct bttv_buffer *cvbi; /* active vbi buffer */ + int loop_irq; int new_input; unsigned long cap_ctl; -- 2.53.0