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
/*
+ $Id: btcx-risc.c,v 1.2 2004/09/15 16:15:24 kraxel Exp $
+
btcx-risc.c
bt848/bt878/cx2388x risc code generator.
-
+/*
+ * $Id: btcx-risc.h,v 1.2 2004/09/15 16:15:24 kraxel Exp $
+ */
struct btcx_riscmem {
unsigned int size;
u32 *cpu;
/*
+ $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
{ 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 }
};
/* Matt Jesson <dvb@jesson.eclipse.co.uk> */
/* 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,
.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 <c.pascoe@itee.uq.edu.au> */
+ .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 <photon38@pchome.com.tw> */
+ .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);
/* 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) {
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");
}
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");
}
}
+/* 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 */
}
-/* 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
+
/*
+ $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 <rjkm@thp.uni-koeln.de>
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);
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 {
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)
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);
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);
}
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)
}
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);
}
return -EINVAL;
down(&btv->lock);
set_input(btv,*i);
- i2c_vidiocschan(btv);
up(&btv->lock);
return 0;
}
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;
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;
}
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:
{
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);
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();
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)) {
}
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);
/* 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);
}
/* 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;
set->bottom = item;
}
if (NULL != set->top && NULL != set->bottom)
- set->topirq = 2;
+ set->top_irq = 2;
}
}
}
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;
}
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);
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);
/* 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) {
/* 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);
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);
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) {
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;
}
.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",
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)
/*
+ $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
/*
+ $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
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) */
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)
}
}
+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)
{
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 {
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;
}
/*
+ $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.
/*
+ $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
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;
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;
}
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;
/* save pointer to jmp instruction address */
risc->jmp = rp;
+ BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
return 0;
}
/* save pointer to jmp instruction address */
risc->jmp = rp;
+ BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
kfree(skips);
return 0;
}
/* 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;
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);
}
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),
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);
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 {
/*
+ $Id: bttv-vbi.c,v 1.5 2004/10/06 17:30:51 kraxel Exp $
+
bttv - Bt848 frame grabber driver
vbi interface
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)
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;
}
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;
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;
/*
+ * $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
#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
/*
+ $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
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 {
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);
u32 gpio_enable;
u32 gpio_data;
int disabled;
+ int loop_irq;
struct bttv_buffer_set video;
struct bttv_buffer *vbi;
};
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;