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)
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"); request_module("tda9887");
} if (btv->tuner_type != UNSET)
if (btv->tuner_type != UNSET) {
if (autoload)
request_module("tuner"); 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
......
This diff is collapsed.
/* /*
$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);
...@@ -582,7 +585,8 @@ bttv_buffer_activate_video(struct bttv *btv, ...@@ -582,7 +585,8 @@ bttv_buffer_activate_video(struct bttv *btv,
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