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