Commit e87c3d55 authored by Gerd Knorr's avatar Gerd Knorr Committed by Linus Torvalds

[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: default avatarGerd Knorr <kraxel@bytesex.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 1259636c
...@@ -9,7 +9,7 @@ comment "Video Adapters" ...@@ -9,7 +9,7 @@ comment "Video Adapters"
config VIDEO_BT848 config VIDEO_BT848
tristate "BT848 Video For Linux" tristate "BT848 Video For Linux"
depends on VIDEO_DEV && PCI && I2C && SOUND depends on VIDEO_DEV && PCI && I2C && FW_LOADER
select I2C_ALGOBIT select I2C_ALGOBIT
---help--- ---help---
Support for BT848 based frame grabber/overlay boards. This includes 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 btcx-risc.c
bt848/bt878/cx2388x risc code generator. bt848/bt878/cx2388x risc code generator.
......
/*
* $Id: btcx-risc.h,v 1.2 2004/09/15 16:15:24 kraxel Exp $
*/
struct btcx_riscmem { struct btcx_riscmem {
unsigned int size; unsigned int size;
u32 *cpu; u32 *cpu;
......
/* /*
$Id: bttv-cards.c,v 1.28 2004/10/06 13:45:14 kraxel Exp $
bttv-cards.c bttv-cards.c
this file has configuration informations - card-specific stuff this file has configuration informations - card-specific stuff
...@@ -308,6 +310,7 @@ static struct CARD { ...@@ -308,6 +310,7 @@ static struct CARD {
{ 0x00011822, BTTV_TWINHAN_DST, "Twinhan VisionPlus DVB-T" }, { 0x00011822, BTTV_TWINHAN_DST, "Twinhan VisionPlus DVB-T" },
{ 0xfc00270f, BTTV_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, { 0xfc00270f, BTTV_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" },
{ 0x07711461, BTTV_AVDVBT_771, "AVermedia DVB-T 771" }, { 0x07711461, BTTV_AVDVBT_771, "AVermedia DVB-T 771" },
{ 0xdb1018ac, BTTV_DVICO_DVBT_LITE, "DVICO FusionHDTV DVB-T Lite" },
{ 0, -1, NULL } { 0, -1, NULL }
}; };
...@@ -2089,10 +2092,10 @@ struct tvcard bttv_tvcards[] = { ...@@ -2089,10 +2092,10 @@ struct tvcard bttv_tvcards[] = {
/* Matt Jesson <dvb@jesson.eclipse.co.uk> */ /* 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 */ /* 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", .name = "AverMedia AverTV DVB-T 761",
.video_inputs = 1, .video_inputs = 2,
.tuner = -1, .tuner = -1,
.svhs = -1, .svhs = 1,
.muxsel = { 2, 3, 1, 0}, .muxsel = { 3, 1, 2, 0}, /* Comp0, S-Video, ?, ? */
.no_msp34xx = 1, .no_msp34xx = 1,
.no_tda9875 = 1, .no_tda9875 = 1,
.no_tda7432 = 1, .no_tda7432 = 1,
...@@ -2147,6 +2150,34 @@ struct tvcard bttv_tvcards[] = { ...@@ -2147,6 +2150,34 @@ struct tvcard bttv_tvcards[] = {
.tuner_type = TUNER_PHILIPS_PAL, .tuner_type = TUNER_PHILIPS_PAL,
.has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */ .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */
.has_radio = 1, /* not every card has radio */ .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); const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
...@@ -2538,6 +2569,7 @@ void __devinit bttv_init_card1(struct bttv *btv) ...@@ -2538,6 +2569,7 @@ void __devinit bttv_init_card1(struct bttv *btv)
/* initialization part two -- after registering i2c bus */ /* initialization part two -- after registering i2c bus */
void __devinit bttv_init_card2(struct bttv *btv) void __devinit bttv_init_card2(struct bttv *btv)
{ {
int tda9887;
btv->tuner_type = -1; btv->tuner_type = -1;
if (BTTV_UNKNOWN == btv->c.type) { if (BTTV_UNKNOWN == btv->c.type) {
...@@ -2705,45 +2737,40 @@ void __devinit bttv_init_card2(struct bttv *btv) ...@@ -2705,45 +2737,40 @@ void __devinit bttv_init_card2(struct bttv *btv)
boot_bt832(btv); boot_bt832(btv);
} }
if (!autoload)
return;
/* try to detect audio/fader chips */ /* try to detect audio/fader chips */
if (!bttv_tvcards[btv->c.type].no_msp34xx && if (!bttv_tvcards[btv->c.type].no_msp34xx &&
bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx") >=0) { bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx") >=0)
if (autoload) request_module("msp3400");
request_module("msp3400");
}
if (bttv_tvcards[btv->c.type].msp34xx_alt && if (bttv_tvcards[btv->c.type].msp34xx_alt &&
bttv_I2CRead(btv, I2C_MSP3400_ALT, "MSP34xx (alternate address)") >=0) { bttv_I2CRead(btv, I2C_MSP3400_ALT, "MSP34xx (alternate address)") >=0)
if (autoload) request_module("msp3400");
request_module("msp3400");
}
if (!bttv_tvcards[btv->c.type].no_tda9875 && if (!bttv_tvcards[btv->c.type].no_tda9875 &&
bttv_I2CRead(btv, I2C_TDA9875, "TDA9875") >=0) { bttv_I2CRead(btv, I2C_TDA9875, "TDA9875") >=0)
if (autoload) request_module("tda9875");
request_module("tda9875");
}
if (!bttv_tvcards[btv->c.type].no_tda7432 && if (!bttv_tvcards[btv->c.type].no_tda7432 &&
bttv_I2CRead(btv, I2C_TDA7432, "TDA7432") >=0) { bttv_I2CRead(btv, I2C_TDA7432, "TDA7432") >=0)
if (autoload) request_module("tda7432");
request_module("tda7432");
}
if (bttv_tvcards[btv->c.type].needs_tvaudio) { if (bttv_tvcards[btv->c.type].needs_tvaudio)
if (autoload) request_module("tvaudio");
request_module("tvaudio");
}
/* tuner modules */ /* tuner modules */
if (btv->pinnacle_id != UNSET) { tda9887 = 0;
if (autoload) if (btv->pinnacle_id != UNSET)
request_module("tda9887"); tda9887 = 1;
} if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb &&
if (btv->tuner_type != UNSET) { bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0)
if (autoload) tda9887 = 1;
request_module("tuner"); 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) ...@@ -2854,7 +2881,8 @@ static void __devinit hauppauge_eeprom(struct bttv *btv)
if (bttv_verbose) if (bttv_verbose)
printk(KERN_INFO "bttv%d: Hauppauge eeprom: model=%d, " printk(KERN_INFO "bttv%d: Hauppauge eeprom: model=%d, "
"tuner=%s (%d), radio=%s\n", "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"); btv->tuner_type, radio ? "yes" : "no");
} }
...@@ -4024,6 +4052,86 @@ static void ivc120_muxsel(struct bttv *btv, unsigned int input) ...@@ -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 */ /* motherboard chipset specific stuff */
...@@ -4110,86 +4218,6 @@ int __devinit bttv_handle_chipset(struct bttv *btv) ...@@ -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: * Local variables:
* c-basic-offset: 8 * c-basic-offset: 8
......
/* /*
$Id: bttv-driver.c,v 1.22 2004/10/12 07:33:22 kraxel Exp $
bttv - Bt848 frame grabber driver bttv - Bt848 frame grabber driver
Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de> Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de>
...@@ -743,8 +746,7 @@ static void set_pll(struct bttv *btv) ...@@ -743,8 +746,7 @@ static void set_pll(struct bttv *btv)
for (i=0; i<10; i++) { for (i=0; i<10; i++) {
/* Let other people run while the PLL stabilizes */ /* Let other people run while the PLL stabilizes */
vprintk("."); vprintk(".");
set_current_state(TASK_INTERRUPTIBLE); msleep(10);
schedule_timeout(HZ/50);
if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) { if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) {
btwrite(0,BT848_DSTATUS); btwrite(0,BT848_DSTATUS);
...@@ -979,7 +981,7 @@ set_input(struct bttv *btv, unsigned int input) ...@@ -979,7 +981,7 @@ set_input(struct bttv *btv, unsigned int input)
btv->input = input; btv->input = input;
if (irq_iswitch) { if (irq_iswitch) {
spin_lock_irqsave(&btv->s_lock,flags); spin_lock_irqsave(&btv->s_lock,flags);
if (btv->curr.irqflags) { if (btv->curr.frame_irq) {
/* active capture -> delayed input switch */ /* active capture -> delayed input switch */
btv->new_input = input; btv->new_input = input;
} else { } else {
...@@ -992,6 +994,7 @@ set_input(struct bttv *btv, unsigned int input) ...@@ -992,6 +994,7 @@ set_input(struct bttv *btv, unsigned int input)
audio_mux(btv,(input == bttv_tvcards[btv->c.type].tuner ? audio_mux(btv,(input == bttv_tvcards[btv->c.type].tuner ?
AUDIO_TUNER : AUDIO_EXTERN)); AUDIO_TUNER : AUDIO_EXTERN));
set_tvnorm(btv,btv->tvnorm); set_tvnorm(btv,btv->tvnorm);
i2c_vidiocschan(btv);
} }
static void init_irqreg(struct bttv *btv) static void init_irqreg(struct bttv *btv)
...@@ -1076,7 +1079,7 @@ void bttv_reinit_bt848(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); printk(KERN_INFO "bttv%d: reset, reinitialize\n",btv->c.nr);
spin_lock_irqsave(&btv->s_lock,flags); spin_lock_irqsave(&btv->s_lock,flags);
btv->errors=0; btv->errors=0;
bttv_set_dma(btv,0,0); bttv_set_dma(btv,0);
spin_unlock_irqrestore(&btv->s_lock,flags); spin_unlock_irqrestore(&btv->s_lock,flags);
init_bt848(btv); init_bt848(btv);
...@@ -1334,8 +1337,8 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh, ...@@ -1334,8 +1337,8 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
spin_lock_irqsave(&btv->s_lock,flags); spin_lock_irqsave(&btv->s_lock,flags);
old = btv->screen; old = btv->screen;
btv->screen = new; btv->screen = new;
btv->curr.irqflags |= 1; btv->loop_irq |= 1;
bttv_set_dma(btv, 0x03, btv->curr.irqflags); bttv_set_dma(btv, 0x03);
spin_unlock_irqrestore(&btv->s_lock,flags); spin_unlock_irqrestore(&btv->s_lock,flags);
if (NULL == new) if (NULL == new)
free_btres(btv,fh,RESOURCE_OVERLAY); free_btres(btv,fh,RESOURCE_OVERLAY);
...@@ -1411,9 +1414,9 @@ static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf, ...@@ -1411,9 +1414,9 @@ static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
} }
static int 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; *size = fh->fmt->depth*fh->width*fh->height >> 3;
if (0 == *count) if (0 == *count)
...@@ -1424,32 +1427,35 @@ buffer_setup(struct file *file, unsigned int *count, unsigned int *size) ...@@ -1424,32 +1427,35 @@ buffer_setup(struct file *file, unsigned int *count, unsigned int *size)
} }
static int static int
buffer_prepare(struct file *file, struct videobuf_buffer *vb, buffer_prepare(void *priv, struct videobuf_buffer *vb,
enum v4l2_field field) enum v4l2_field field)
{ {
struct bttv_buffer *buf = (struct bttv_buffer*)vb; 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, return bttv_prepare_buffer(fh->btv, buf, fh->fmt,
fh->width, fh->height, field); fh->width, fh->height, field);
} }
static void 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_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; buf->vb.state = STATE_QUEUED;
list_add_tail(&buf->vb.queue,&fh->btv->capture); list_add_tail(&buf->vb.queue,&btv->capture);
fh->btv->curr.irqflags |= 1; if (!btv->curr.frame_irq) {
bttv_set_dma(fh->btv, 0x03, fh->btv->curr.irqflags); 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_buffer *buf = (struct bttv_buffer*)vb;
struct bttv_fh *fh = file->private_data; struct bttv_fh *fh = priv;
bttv_dma_free(fh->btv,buf); bttv_dma_free(fh->btv,buf);
} }
...@@ -1706,7 +1712,6 @@ int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) ...@@ -1706,7 +1712,6 @@ int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
return -EINVAL; return -EINVAL;
down(&btv->lock); down(&btv->lock);
set_input(btv,*i); set_input(btv,*i);
i2c_vidiocschan(btv);
up(&btv->lock); up(&btv->lock);
return 0; return 0;
} }
...@@ -2381,7 +2386,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, ...@@ -2381,7 +2386,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
unsigned int i; unsigned int i;
down(&fh->cap.lock); 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); V4L2_MEMORY_MMAP);
if (retval < 0) if (retval < 0)
goto fh_unlock_and_return; goto fh_unlock_and_return;
...@@ -2422,7 +2428,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, ...@@ -2422,7 +2428,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
if (0 != retval) if (0 != retval)
goto fh_unlock_and_return; goto fh_unlock_and_return;
spin_lock_irqsave(&btv->s_lock,flags); 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); spin_unlock_irqrestore(&btv->s_lock,flags);
up(&fh->cap.lock); up(&fh->cap.lock);
return 0; return 0;
...@@ -2679,16 +2685,17 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, ...@@ -2679,16 +2685,17 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
} }
case VIDIOC_REQBUFS: case VIDIOC_REQBUFS:
return videobuf_reqbufs(file,bttv_queue(fh),arg); return videobuf_reqbufs(file->private_data,bttv_queue(fh),arg);
case VIDIOC_QUERYBUF: case VIDIOC_QUERYBUF:
return videobuf_querybuf(bttv_queue(fh),arg); return videobuf_querybuf(bttv_queue(fh),arg);
case VIDIOC_QBUF: case VIDIOC_QBUF:
return videobuf_qbuf(file,bttv_queue(fh),arg); return videobuf_qbuf(file->private_data,bttv_queue(fh),arg);
case VIDIOC_DQBUF: 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: case VIDIOC_STREAMON:
{ {
...@@ -2696,13 +2703,13 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, ...@@ -2696,13 +2703,13 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
if (!check_alloc_btres(btv,fh,res)) if (!check_alloc_btres(btv,fh,res))
return -EBUSY; return -EBUSY;
return videobuf_streamon(file,bttv_queue(fh)); return videobuf_streamon(file->private_data,bttv_queue(fh));
} }
case VIDIOC_STREAMOFF: case VIDIOC_STREAMOFF:
{ {
int res = bttv_resource(fh); int res = bttv_resource(fh);
retval = videobuf_streamoff(file,bttv_queue(fh)); retval = videobuf_streamoff(file->private_data,bttv_queue(fh));
if (retval < 0) if (retval < 0)
return retval; return retval;
free_btres(btv,fh,res); free_btres(btv,fh,res);
...@@ -2839,12 +2846,16 @@ static ssize_t bttv_read(struct file *file, char __user *data, ...@@ -2839,12 +2846,16 @@ static ssize_t bttv_read(struct file *file, char __user *data,
case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_CAPTURE:
if (locked_btres(fh->btv,RESOURCE_VIDEO)) if (locked_btres(fh->btv,RESOURCE_VIDEO))
return -EBUSY; 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; break;
case V4L2_BUF_TYPE_VBI_CAPTURE: case V4L2_BUF_TYPE_VBI_CAPTURE:
if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI)) if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI))
return -EBUSY; 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; break;
default: default:
BUG(); BUG();
...@@ -2860,8 +2871,9 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) ...@@ -2860,8 +2871,9 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI)) if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI))
return -EBUSY; return POLLERR;
return videobuf_poll_stream(file, &fh->vbi, wait); return videobuf_poll_stream(file, file->private_data,
&fh->vbi, wait);
} }
if (check_btres(fh,RESOURCE_VIDEO)) { if (check_btres(fh,RESOURCE_VIDEO)) {
...@@ -2885,11 +2897,11 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) ...@@ -2885,11 +2897,11 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
} }
fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR; fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR;
field = videobuf_next_field(&fh->cap); 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); up(&fh->cap.lock);
return POLLERR; 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; fh->cap.read_off = 0;
} }
up(&fh->cap.lock); up(&fh->cap.lock);
...@@ -2975,20 +2987,20 @@ static int bttv_release(struct inode *inode, struct file *file) ...@@ -2975,20 +2987,20 @@ static int bttv_release(struct inode *inode, struct file *file)
/* stop video capture */ /* stop video capture */
if (check_btres(fh, RESOURCE_VIDEO)) { if (check_btres(fh, RESOURCE_VIDEO)) {
videobuf_streamoff(file,&fh->cap); videobuf_streamoff(file->private_data,&fh->cap);
free_btres(btv,fh,RESOURCE_VIDEO); free_btres(btv,fh,RESOURCE_VIDEO);
} }
if (fh->cap.read_buf) { 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); kfree(fh->cap.read_buf);
} }
/* stop vbi capture */ /* stop vbi capture */
if (check_btres(fh, RESOURCE_VBI)) { if (check_btres(fh, RESOURCE_VBI)) {
if (fh->vbi.streaming) if (fh->vbi.streaming)
videobuf_streamoff(file,&fh->vbi); videobuf_streamoff(file->private_data,&fh->vbi);
if (fh->vbi.reading) if (fh->vbi.reading)
videobuf_read_stop(file,&fh->vbi); videobuf_read_stop(file->private_data,&fh->vbi);
free_btres(btv,fh,RESOURCE_VBI); free_btres(btv,fh,RESOURCE_VBI);
} }
...@@ -3249,7 +3261,7 @@ bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set) ...@@ -3249,7 +3261,7 @@ bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set)
/* capture request ? */ /* capture request ? */
if (!list_empty(&btv->capture)) { if (!list_empty(&btv->capture)) {
set->irqflags = 1; set->frame_irq = 1;
item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue); item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
if (V4L2_FIELD_HAS_TOP(item->vb.field)) if (V4L2_FIELD_HAS_TOP(item->vb.field))
set->top = item; set->top = item;
...@@ -3270,7 +3282,7 @@ bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set) ...@@ -3270,7 +3282,7 @@ bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set)
set->bottom = item; set->bottom = item;
} }
if (NULL != set->top && NULL != set->bottom) 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) ...@@ -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", dprintk("bttv%d: next set: top=%p bottom=%p [screen=%p,irq=%d,%d]\n",
btv->c.nr,set->top, set->bottom, btv->c.nr,set->top, set->bottom,
btv->screen,set->irqflags,set->topirq); btv->screen,set->frame_irq,set->top_irq);
return 0; return 0;
} }
...@@ -3377,9 +3389,10 @@ static void bttv_irq_timeout(unsigned long data) ...@@ -3377,9 +3389,10 @@ static void bttv_irq_timeout(unsigned long data)
ovbi = btv->cvbi; ovbi = btv->cvbi;
btv->curr = new; btv->curr = new;
btv->cvbi = NULL; btv->cvbi = NULL;
btv->loop_irq = 0;
bttv_buffer_activate_video(btv, &new); bttv_buffer_activate_video(btv, &new);
bttv_buffer_activate_vbi(btv, NULL); bttv_buffer_activate_vbi(btv, NULL);
bttv_set_dma(btv, 0, 0); bttv_set_dma(btv, 0);
/* wake up */ /* wake up */
bttv_irq_wakeup_video(btv, &old, &new, STATE_ERROR); bttv_irq_wakeup_video(btv, &old, &new, STATE_ERROR);
...@@ -3412,7 +3425,7 @@ bttv_irq_wakeup_top(struct bttv *btv) ...@@ -3412,7 +3425,7 @@ bttv_irq_wakeup_top(struct bttv *btv)
return; return;
spin_lock(&btv->s_lock); spin_lock(&btv->s_lock);
btv->curr.topirq = 0; btv->curr.top_irq = 0;
btv->curr.top = NULL; btv->curr.top = NULL;
bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0); bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
...@@ -3456,8 +3469,9 @@ bttv_irq_switch_video(struct bttv *btv) ...@@ -3456,8 +3469,9 @@ bttv_irq_switch_video(struct bttv *btv)
/* switch over */ /* switch over */
old = btv->curr; old = btv->curr;
btv->curr = new; btv->curr = new;
btv->loop_irq &= ~1;
bttv_buffer_activate_video(btv, &new); bttv_buffer_activate_video(btv, &new);
bttv_set_dma(btv, 0, new.irqflags); bttv_set_dma(btv, 0);
/* switch input */ /* switch input */
if (UNSET != btv->new_input) { if (UNSET != btv->new_input) {
...@@ -3495,8 +3509,9 @@ bttv_irq_switch_vbi(struct bttv *btv) ...@@ -3495,8 +3509,9 @@ bttv_irq_switch_vbi(struct bttv *btv)
/* switch */ /* switch */
btv->cvbi = new; btv->cvbi = new;
btv->loop_irq &= ~4;
bttv_buffer_activate_vbi(btv, new); 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); bttv_irq_wakeup_vbi(btv, old, STATE_DONE);
spin_unlock(&btv->s_lock); spin_unlock(&btv->s_lock);
...@@ -3925,17 +3940,19 @@ static int bttv_suspend(struct pci_dev *pci_dev, u32 state) ...@@ -3925,17 +3940,19 @@ static int bttv_suspend(struct pci_dev *pci_dev, u32 state)
struct bttv_buffer_set idle; struct bttv_buffer_set idle;
unsigned long flags; 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 */ /* stop dma + irqs */
spin_lock_irqsave(&btv->s_lock,flags); spin_lock_irqsave(&btv->s_lock,flags);
memset(&idle, 0, sizeof(idle)); memset(&idle, 0, sizeof(idle));
btv->state.video = btv->curr; btv->state.video = btv->curr;
btv->state.vbi = btv->cvbi; btv->state.vbi = btv->cvbi;
btv->state.loop_irq = btv->loop_irq;
btv->curr = idle; btv->curr = idle;
btv->loop_irq = 0;
bttv_buffer_activate_video(btv, &idle); bttv_buffer_activate_video(btv, &idle);
bttv_buffer_activate_vbi(btv, NULL); bttv_buffer_activate_vbi(btv, NULL);
bttv_set_dma(btv, 0, 0); bttv_set_dma(btv, 0);
btwrite(0, BT848_INT_MASK); btwrite(0, BT848_INT_MASK);
spin_unlock_irqrestore(&btv->s_lock,flags); spin_unlock_irqrestore(&btv->s_lock,flags);
...@@ -3957,7 +3974,7 @@ static int bttv_resume(struct pci_dev *pci_dev) ...@@ -3957,7 +3974,7 @@ static int bttv_resume(struct pci_dev *pci_dev)
struct bttv *btv = pci_get_drvdata(pci_dev); struct bttv *btv = pci_get_drvdata(pci_dev);
unsigned long flags; unsigned long flags;
printk("bttv%d: resume\n", btv->c.nr); dprintk("bttv%d: resume\n", btv->c.nr);
/* restore pci state */ /* restore pci state */
if (btv->state.disabled) { if (btv->state.disabled) {
...@@ -3976,9 +3993,10 @@ static int bttv_resume(struct pci_dev *pci_dev) ...@@ -3976,9 +3993,10 @@ static int bttv_resume(struct pci_dev *pci_dev)
spin_lock_irqsave(&btv->s_lock,flags); spin_lock_irqsave(&btv->s_lock,flags);
btv->curr = btv->state.video; btv->curr = btv->state.video;
btv->cvbi = btv->state.vbi; btv->cvbi = btv->state.vbi;
btv->loop_irq = btv->state.loop_irq;
bttv_buffer_activate_video(btv, &btv->curr); bttv_buffer_activate_video(btv, &btv->curr);
bttv_buffer_activate_vbi(btv, btv->cvbi); 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); spin_unlock_irqrestore(&btv->s_lock,flags);
return 0; return 0;
} }
...@@ -4002,14 +4020,12 @@ static struct pci_driver bttv_pci_driver = { ...@@ -4002,14 +4020,12 @@ static struct pci_driver bttv_pci_driver = {
.id_table = bttv_pci_tbl, .id_table = bttv_pci_tbl,
.probe = bttv_probe, .probe = bttv_probe,
.remove = __devexit_p(bttv_remove), .remove = __devexit_p(bttv_remove),
.suspend = bttv_suspend,
.suspend = bttv_suspend, .resume = bttv_resume,
.resume = bttv_resume,
}; };
static int bttv_init_module(void) static int bttv_init_module(void)
{ {
int rc;
bttv_num = 0; bttv_num = 0;
printk(KERN_INFO "bttv: driver version %d.%d.%d loaded\n", printk(KERN_INFO "bttv: driver version %d.%d.%d loaded\n",
...@@ -4032,13 +4048,7 @@ static int bttv_init_module(void) ...@@ -4032,13 +4048,7 @@ static int bttv_init_module(void)
bttv_check_chipset(); bttv_check_chipset();
bus_register(&bttv_sub_bus_type); bus_register(&bttv_sub_bus_type);
rc = pci_module_init(&bttv_pci_driver); return 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;
} }
static void bttv_cleanup_module(void) 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 bttv-gpio.c -- gpio sub drivers
sysfs-based sub driver interface for bttv 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-i2c.c -- all the i2c code is here
bttv - Bt848 frame grabber driver bttv - Bt848 frame grabber driver
...@@ -44,8 +46,11 @@ static int detach_inform(struct i2c_client *client); ...@@ -44,8 +46,11 @@ static int detach_inform(struct i2c_client *client);
static int i2c_debug = 0; static int i2c_debug = 0;
static int i2c_hw = 0; static int i2c_hw = 0;
static int i2c_scan = 0;
MODULE_PARM(i2c_debug,"i"); MODULE_PARM(i2c_debug,"i");
MODULE_PARM(i2c_hw,"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) */ /* I2C functions - bitbanging adapter (software i2c) */
...@@ -139,10 +144,8 @@ bttv_i2c_wait_done(struct bttv *btv) ...@@ -139,10 +144,8 @@ bttv_i2c_wait_done(struct bttv *btv)
int rc = 0; int rc = 0;
add_wait_queue(&btv->i2c_queue, &wait); add_wait_queue(&btv->i2c_queue, &wait);
set_current_state(TASK_INTERRUPTIBLE);
if (0 == btv->i2c_done) if (0 == btv->i2c_done)
schedule_timeout(HZ/50+1); msleep_interruptible(20);
set_current_state(TASK_RUNNING);
remove_wait_queue(&btv->i2c_queue, &wait); remove_wait_queue(&btv->i2c_queue, &wait);
if (0 == btv->i2c_done) if (0 == btv->i2c_done)
...@@ -423,6 +426,30 @@ void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr) ...@@ -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 */ /* init + register i2c algo-bit adapter */
int __devinit init_bttv_i2c(struct bttv *btv) int __devinit init_bttv_i2c(struct bttv *btv)
{ {
...@@ -453,6 +480,13 @@ 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); i2c_set_adapdata(&btv->c.i2c_adap, btv);
btv->i2c_client.adapter = &btv->c.i2c_adap; 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) { if (btv->use_i2c_hw) {
btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap); btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap);
} else { } else {
...@@ -460,6 +494,8 @@ int __devinit init_bttv_i2c(struct bttv *btv) ...@@ -460,6 +494,8 @@ int __devinit init_bttv_i2c(struct bttv *btv)
bttv_bit_setsda(btv,1); bttv_bit_setsda(btv,1);
btv->i2c_rc = i2c_bit_add_bus(&btv->c.i2c_adap); 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; 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 bttv-if.c -- old gpio interface to other kernel modules
don't use in new code, will go away in 2.7 don't use in new code, will go away in 2.7
have a look at bttv-gpio.c instead. 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.c -- interfaces to other kernel modules
bttv risc code handling bttv risc code handling
...@@ -55,8 +57,6 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, ...@@ -55,8 +57,6 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
instructions += 2; instructions += 2;
if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0)
return rc; 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 */ /* sync instruction */
rp = risc->cpu; rp = risc->cpu;
...@@ -101,13 +101,11 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, ...@@ -101,13 +101,11 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
offset += todo; offset += todo;
} }
offset += padding; 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 */ /* save pointer to jmp instruction address */
risc->jmp = rp; risc->jmp = rp;
BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
return 0; return 0;
} }
...@@ -155,15 +153,15 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc, ...@@ -155,15 +153,15 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
break; break;
case 1: case 1:
if (topfield) if (topfield)
chroma = (line & 1) == 0; chroma = ((line & 1) == 0);
else else
chroma = (line & 1) == 1; chroma = ((line & 1) == 1);
break; break;
case 2: case 2:
if (topfield) if (topfield)
chroma = (line & 3) == 0; chroma = ((line & 3) == 0);
else else
chroma = (line & 3) == 2; chroma = ((line & 3) == 2);
break; break;
default: default:
chroma = 0; chroma = 0;
...@@ -225,6 +223,7 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc, ...@@ -225,6 +223,7 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
/* save pointer to jmp instruction address */ /* save pointer to jmp instruction address */
risc->jmp = rp; risc->jmp = rp;
BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
return 0; return 0;
} }
...@@ -309,6 +308,7 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, ...@@ -309,6 +308,7 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
/* save pointer to jmp instruction address */ /* save pointer to jmp instruction address */
risc->jmp = rp; risc->jmp = rp;
BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
kfree(skips); kfree(skips);
return 0; return 0;
} }
...@@ -391,7 +391,7 @@ bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd) ...@@ -391,7 +391,7 @@ bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
/* risc group / risc main loop / dma management */ /* risc group / risc main loop / dma management */
void void
bttv_set_dma(struct bttv *btv, int override, int irqflags) bttv_set_dma(struct bttv *btv, int override)
{ {
unsigned long cmd; unsigned long cmd;
int capctl; int capctl;
...@@ -407,20 +407,20 @@ bttv_set_dma(struct bttv *btv, int override, int irqflags) ...@@ -407,20 +407,20 @@ bttv_set_dma(struct bttv *btv, int override, int irqflags)
capctl |= override; capctl |= override;
d2printk(KERN_DEBUG d2printk(KERN_DEBUG
"bttv%d: capctl=%x irq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n", "bttv%d: capctl=%x lirq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
btv->c.nr,capctl,irqflags, btv->c.nr,capctl,btv->loop_irq,
btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0, btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
btv->curr.top ? (unsigned long long)btv->curr.top->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->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0); btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
cmd = BT848_RISC_JUMP; cmd = BT848_RISC_JUMP;
if (irqflags) { if (btv->loop_irq) {
cmd |= BT848_RISC_IRQ; cmd |= BT848_RISC_IRQ;
cmd |= (irqflags & 0x0f) << 16; cmd |= (btv->loop_irq & 0x0f) << 16;
cmd |= (~irqflags & 0x0f) << 20; 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); mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
} else { } else {
del_timer(&btv->timeout); del_timer(&btv->timeout);
...@@ -559,8 +559,10 @@ bttv_buffer_activate_video(struct bttv *btv, ...@@ -559,8 +559,10 @@ bttv_buffer_activate_video(struct bttv *btv,
} }
bttv_apply_geo(btv, &set->top->geo, 1); bttv_apply_geo(btv, &set->top->geo, 1);
bttv_apply_geo(btv, &set->bottom->geo,0); 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_O_FIELD, &set->top->top,
bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, 0); 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), btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
~0xff, BT848_COLOR_FMT); ~0xff, BT848_COLOR_FMT);
btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05), btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
...@@ -571,7 +573,8 @@ bttv_buffer_activate_video(struct bttv *btv, ...@@ -571,7 +573,8 @@ bttv_buffer_activate_video(struct bttv *btv,
list_del(&set->top->vb.queue); list_del(&set->top->vb.queue);
bttv_apply_geo(btv, &set->top->geo,1); bttv_apply_geo(btv, &set->top->geo,1);
bttv_apply_geo(btv, &set->top->geo,0); 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); bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT); btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL); btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
...@@ -581,8 +584,9 @@ bttv_buffer_activate_video(struct bttv *btv, ...@@ -581,8 +584,9 @@ bttv_buffer_activate_video(struct bttv *btv,
list_del(&set->bottom->vb.queue); list_del(&set->bottom->vb.queue);
bttv_apply_geo(btv, &set->bottom->geo,1); bttv_apply_geo(btv, &set->bottom->geo,1);
bttv_apply_geo(btv, &set->bottom->geo,0); bttv_apply_geo(btv, &set->bottom->geo,0);
bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 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_E_FIELD, &set->bottom->bottom,
set->frame_irq);
btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT); btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL); btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
} else { } else {
......
/* /*
$Id: bttv-vbi.c,v 1.5 2004/10/06 17:30:51 kraxel Exp $
bttv - Bt848 frame grabber driver bttv - Bt848 frame grabber driver
vbi interface vbi interface
...@@ -61,10 +63,10 @@ vbi_buffer_risc(struct bttv *btv, struct bttv_buffer *buf, int lines) ...@@ -61,10 +63,10 @@ vbi_buffer_risc(struct bttv *btv, struct bttv_buffer *buf, int lines)
return 0; return 0;
} }
static int vbi_buffer_setup(struct file *file, static int vbi_buffer_setup(void *priv,
unsigned int *count, unsigned int *size) unsigned int *count, unsigned int *size)
{ {
struct bttv_fh *fh = file->private_data; struct bttv_fh *fh = priv;
struct bttv *btv = fh->btv; struct bttv *btv = fh->btv;
if (0 == *count) if (0 == *count)
...@@ -74,10 +76,10 @@ static int vbi_buffer_setup(struct file *file, ...@@ -74,10 +76,10 @@ static int vbi_buffer_setup(struct file *file,
return 0; 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) enum v4l2_field field)
{ {
struct bttv_fh *fh = file->private_data; struct bttv_fh *fh = priv;
struct bttv *btv = fh->btv; struct bttv *btv = fh->btv;
struct bttv_buffer *buf = (struct bttv_buffer*)vb; struct bttv_buffer *buf = (struct bttv_buffer*)vb;
int rc; int rc;
...@@ -105,9 +107,9 @@ static int vbi_buffer_prepare(struct file *file, struct videobuf_buffer *vb, ...@@ -105,9 +107,9 @@ static int vbi_buffer_prepare(struct file *file, struct videobuf_buffer *vb,
} }
static void 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 *btv = fh->btv;
struct bttv_buffer *buf = (struct bttv_buffer*)vb; struct bttv_buffer *buf = (struct bttv_buffer*)vb;
...@@ -115,14 +117,14 @@ vbi_buffer_queue(struct file *file, struct videobuf_buffer *vb) ...@@ -115,14 +117,14 @@ vbi_buffer_queue(struct file *file, struct videobuf_buffer *vb)
buf->vb.state = STATE_QUEUED; buf->vb.state = STATE_QUEUED;
list_add_tail(&buf->vb.queue,&btv->vcapture); list_add_tail(&buf->vb.queue,&btv->vcapture);
if (NULL == btv->cvbi) { if (NULL == btv->cvbi) {
fh->btv->curr.irqflags |= 4; fh->btv->loop_irq |= 4;
bttv_set_dma(btv,0x0c,fh->btv->curr.irqflags); 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 *btv = fh->btv;
struct bttv_buffer *buf = (struct bttv_buffer*)vb; 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 * bttv - Bt848 frame grabber driver
* *
* card ID's and external interfaces of the bttv driver * card ID's and external interfaces of the bttv driver
...@@ -130,6 +132,7 @@ ...@@ -130,6 +132,7 @@
#define BTTV_MATRIX_VISIONSQ 0x7d #define BTTV_MATRIX_VISIONSQ 0x7d
#define BTTV_MATRIX_VISIONSLC 0x7e #define BTTV_MATRIX_VISIONSLC 0x7e
#define BTTV_APAC_VIEWCOMP 0x7f #define BTTV_APAC_VIEWCOMP 0x7f
#define BTTV_DVICO_DVBT_LITE 0x80
/* i2c address list */ /* i2c address list */
#define I2C_TSA5522 0xc2 #define I2C_TSA5522 0xc2
......
/* /*
$Id: bttvp.h,v 1.10 2004/10/06 17:30:51 kraxel Exp $
bttv - Bt848 frame grabber driver bttv - Bt848 frame grabber driver
bttv's *private* header file -- nobody other than bttv itself bttv's *private* header file -- nobody other than bttv itself
...@@ -127,8 +129,8 @@ struct bttv_buffer { ...@@ -127,8 +129,8 @@ struct bttv_buffer {
struct bttv_buffer_set { struct bttv_buffer_set {
struct bttv_buffer *top; /* top field buffer */ struct bttv_buffer *top; /* top field buffer */
struct bttv_buffer *bottom; /* bottom field buffer */ struct bttv_buffer *bottom; /* bottom field buffer */
unsigned int irqflags; unsigned int top_irq;
unsigned int topirq; unsigned int frame_irq;
}; };
struct bttv_overlay { struct bttv_overlay {
...@@ -189,7 +191,7 @@ void bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo, ...@@ -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); void bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int top);
/* control dma register + risc main loop */ /* 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_init_main(struct bttv *btv);
int bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc, int bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
int irqflags); int irqflags);
...@@ -280,6 +282,7 @@ struct bttv_suspend_state { ...@@ -280,6 +282,7 @@ struct bttv_suspend_state {
u32 gpio_enable; u32 gpio_enable;
u32 gpio_data; u32 gpio_data;
int disabled; int disabled;
int loop_irq;
struct bttv_buffer_set video; struct bttv_buffer_set video;
struct bttv_buffer *vbi; struct bttv_buffer *vbi;
}; };
...@@ -380,6 +383,7 @@ struct bttv { ...@@ -380,6 +383,7 @@ struct bttv {
struct list_head vcapture; /* vbi capture queue */ struct list_head vcapture; /* vbi capture queue */
struct bttv_buffer_set curr; /* active buffers */ struct bttv_buffer_set curr; /* active buffers */
struct bttv_buffer *cvbi; /* active vbi buffer */ struct bttv_buffer *cvbi; /* active vbi buffer */
int loop_irq;
int new_input; int new_input;
unsigned long cap_ctl; unsigned long cap_ctl;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment