aboutsummaryrefslogtreecommitdiffstats
path: root/bttv/driver/bttv.c
diff options
context:
space:
mode:
Diffstat (limited to 'bttv/driver/bttv.c')
-rw-r--r--bttv/driver/bttv.c496
1 files changed, 263 insertions, 233 deletions
diff --git a/bttv/driver/bttv.c b/bttv/driver/bttv.c
index d858dcd..7d1185b 100644
--- a/bttv/driver/bttv.c
+++ b/bttv/driver/bttv.c
@@ -30,9 +30,12 @@
* mmap VBI data?
* use new PCI routines
* fix RAW Composite grabbing for NTSC
- * allow for different VDELAY in RAW grabbing?
+ * allow for different VDELAYs
+ (larger to get Videodat in VBI and smaller to get the whole
+ picture in RAW grabbing)
* extra modules for tda9850, tda8425, any volunteers???
- * support 15bpp
+ * right border clipping is still buggy
+ (decide which clipping code to use and throw the other out ...)
*/
#include <linux/module.h>
@@ -86,13 +89,6 @@ copy_from_user(void *to, const void *from, unsigned long n)
#define DEBUG(x) /* Debug driver */
#define IDEBUG(x) /* Debug interrupt handler */
-static unsigned int remap=0; /* remap Bt848 */
-static unsigned int vidmem=0; /* manually set video mem address */
-static int triton1=0;
-static int radio=0;
-
-static unsigned int card=CARD_DEFAULT;
-
#if LINUX_VERSION_CODE >= 0x020117
MODULE_PARM(remap,"i");
MODULE_PARM(vidmem,"i");
@@ -107,6 +103,13 @@ static void bt848_set_risc_jmps(struct bttv *btv);
/* Anybody who uses more than four? */
#define BTTV_MAX 4
+static unsigned int vidmem=0; /* manually set video mem address */
+static int triton1=0;
+
+static unsigned int remap[BTTV_MAX]; /* remap Bt848 */
+static unsigned int radio[BTTV_MAX];
+static unsigned int card[BTTV_MAX] = { CARD_DEFAULT };
+
static int bttv_num; /* number of Bt848s in use */
static struct bttv bttvs[BTTV_MAX];
@@ -221,7 +224,8 @@ static int fbuffer_alloc(struct bttv *btv)
if(!btv->fbuffer)
btv->fbuffer=(unsigned char *) rvmalloc(2*BTTV_MAX_FBUF);
else
- printk(KERN_ERR "bttv: Double alloc of fbuffer!\n");
+ printk(KERN_ERR "bttv%d: Double alloc of fbuffer!\n",
+ btv->nr);
if(!btv->fbuffer)
return -ENOBUFS;
return 0;
@@ -268,12 +272,17 @@ static int I2CRead(struct i2c_bus *bus, unsigned char addr)
stat=btread(BT848_INT_STAT);
if (stat & BT848_INT_I2CDONE)
break;
+#if LINUX_VERSION_CODE >= 0x020199
+ mdelay(1);
+#else
udelay(1000);
+#endif
}
if (!i)
{
- printk(KERN_DEBUG "bttv: I2CRead timeout\n");
+ printk(KERN_DEBUG "bttv%d: I2CRead timeout\n",
+ btv->nr);
return -1;
}
if (!(stat & BT848_INT_RACK))
@@ -310,12 +319,17 @@ static int I2CWrite(struct i2c_bus *bus, unsigned char addr, unsigned char b1,
stat=btread(BT848_INT_STAT);
if (stat & BT848_INT_I2CDONE)
break;
+#if LINUX_VERSION_CODE >= 0x020199
+ mdelay(1);
+#else
udelay(1000);
+#endif
}
if (!i)
{
- printk(KERN_DEBUG "bttv: I2CWrite timeout\n");
+ printk(KERN_DEBUG "bttv%d: I2CWrite timeout\n",
+ btv->nr);
return -1;
}
if (!(stat & BT848_INT_RACK))
@@ -430,7 +444,7 @@ struct tvcard
u32 gpiomask;
u32 muxsel[8];
u32 audiomux[6]; /* Tuner, Radio, internal, external, mute, stereo */
-
+ u32 gpiomask2; /* GPIO MUX mask */
};
static struct tvcard tvcards[] =
@@ -450,34 +464,18 @@ static struct tvcard tvcards[] =
/* AVerMedia TVPhone */
{ 3, 0, 2,15, { 2, 3, 1, 1}, {12, 0,11,11, 0}},
/* Matrix Vision MV-Delta */
- { 5,-1, 4, 0, { 2, 3, 1, 0, 0}},
+ { 5,-1, 3, 0, { 2, 3, 1, 0, 0}},
/* Fly Video II */
{ 3, 0, 2, 0xc00, { 2, 3, 1, 1},
{0, 0xc00, 0x800, 0x400, 0xc00, 0}},
};
#define TVCARDS (sizeof(tvcards)/sizeof(tvcard))
-/*
- * Tuner, Radio, internal, external and mute
- */
-
-static unsigned char audiomuxs[][5] =
-{
- { 0x00, 0x00, 0x00, 0x00, 0x00}, /* unknown */
- { 0x02, 0x00, 0x00, 0x00, 0x0a}, /* MIRO */
- { 0x00, 0x01, 0x02, 0x03, 0x04}, /* Hauppauge */
- { 0x04, 0x00, 0x02, 0x03, 0x01}, /* STB */
- { 0x00, 0x01, 0x02, 0x03, 0x04}, /* Intel??? */
- { 0x00, 0x01, 0x00, 0x01, 0x03}, /* Diamond DTV2000 */
- { 0x0c, 0x00, 0x0b, 0x0b, 0x00}, /* AVerMedia TVPhone */
-};
-
static void audio(struct bttv *btv, int mode)
{
btaor(tvcards[btv->type].gpiomask, ~tvcards[btv->type].gpiomask,
BT848_GPIO_OUT_EN);
-
switch (mode)
{
case AUDIO_MUTE:
@@ -499,8 +497,12 @@ static void audio(struct bttv *btv, int mode)
break;
}
/* if audio mute or not in H-lock, turn audio off */
- if ((btv->audio&AUDIO_MUTE) ||
- (!btv->radio && !(btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC)))
+ if ((btv->audio&AUDIO_MUTE)
+#if 0
+ ||
+ (!btv->radio && !(btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC))
+#endif
+ )
mode=AUDIO_OFF;
if ((mode == 0) && (btv->radio))
mode = 1;
@@ -561,6 +563,7 @@ static int set_pll(struct bttv *btv)
btwrite(0xdc,BT848_PLL_F_HI);
btwrite(0x8e,BT848_PLL_XCI);
+ /* Ugh ugh ugh .. schedule ? */
udelay(100000);
for (i=0; i<100; i++)
{
@@ -572,14 +575,19 @@ static int set_pll(struct bttv *btv)
btv->pll|=2;
return 1;
}
+#if LINUX_VERSION_CODE >= 0x020199
+ mdelay(10);
+#else
udelay(10000);
+#endif
}
return -1;
}
static void bt848_muxsel(struct bttv *btv, unsigned int input)
{
- btwrite(tvcards[btv->type].gpiomask, BT848_GPIO_OUT_EN);
+ btaor(tvcards[btv->type].gpiomask2,~tvcards[btv->type].gpiomask2,
+ BT848_GPIO_OUT_EN);
/* This seems to get rid of some synchronization problems */
btand(~(3<<5), BT848_IFORM);
@@ -601,24 +609,7 @@ static void bt848_muxsel(struct bttv *btv, unsigned int input)
audio(btv, (input!=tvcards[btv->type].tuner) ?
AUDIO_EXTERN : AUDIO_TUNER);
btaor(tvcards[btv->type].muxsel[input]>>4,
- ~tvcards[btv->type].gpiomask, BT848_GPIO_DATA);
-
-/*
- if (input==3)
- {
- btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
- btor(BT848_CONTROL_COMP, BT848_O_CONTROL);
- }
- else
- {
- btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
- btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
- }
- if (input==2)
- input=3;
- btaor(((input+2)&3)<<5, ~(3<<5), BT848_IFORM);
- audio(btv, input ? AUDIO_EXTERN : AUDIO_TUNER);
-*/
+ ~tvcards[btv->type].gpiomask2, BT848_GPIO_DATA);
}
@@ -681,14 +672,15 @@ static int make_rawrisctab(struct bttv *btv, unsigned int *ro,
unsigned int *re, unsigned int *vbuf)
{
unsigned long line;
- unsigned long bpl=1024;
+ unsigned long bpl=1024; /* bytes per line */
unsigned long vadr=(unsigned long) vbuf;
*(ro++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(ro++)=0;
*(re++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(re++)=0;
/* In PAL 650 blocks of 256 DWORDs are sampled, but only if VDELAY
- is 2. We'll have to handle this inside the IRQ handler ... */
+ is 2 and without separate VBI grabbing.
+ We'll have to handle this inside the IRQ handler ... */
for (line=0; line < 640; line++)
{
@@ -894,77 +886,77 @@ static void make_clip_tab(struct bttv *btv, struct cliprec *cr, int count)
*(re++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(re++)=0;
/* loop through all lines */
- for (yy=0; yy<(height<<inter); yy++) {
- y=yy>>inter;
- rp= (yy&1) ? &re : &ro;
+ for (yy=0; yy<(height<<inter); yy++)
+ {
+ y=yy>>inter;
+ rp= (yy&1) ? &re : &ro;
- /* remove rects with y2 > y */
- if ((cur=first2.next))
- {
- prev=&first2;
- do
- {
- if (cur->y2 < y)
- prev->next=cur->next;
- else
- prev=cur;
- }
- while ((cur=cur->next));
- }
-
- /* add rect to second (x-sorted) list if rect.y == y */
- if ((cur=first.next))
- {
- while ((cur) && (cur->y == y))
- {
- first.next=cur->next;
- cur2=&first2;
- while ((nx2=cur2->next) && (cur->x > cur2->next->x))
- cur2=nx2;
- cur2->next=cur;
- cur->next=nx2;
- cur=first.next;
- }
- }
- x=0;
- if ((btv->win.y+y<=0)||(btv->win.y+y>=btv->win.sheight))
- write_risc_segment(rp, adr, BT848_RISC_SKIP, &x,
- width, bpp, width);
- else
- {
- dx=cx;
- for (cur2=first2.next; cur2; cur2=cur2->next)
- {
- if (x+dx < cur2->x)
- {
- write_risc_segment(rp, adr, BT848_RISC_SKIP,
- &x, dx, bpp, width);
- dx=cur2->x-x;
- write_risc_segment(rp, adr, BT848_RISC_WRITEC,
- &x, dx, bpp, width);
- dx=cur2->x2-x+1;
- }
- else
- if (x+dx < cur2->x2)
- dx=cur2->x2-x+1;
- }
- if (cx2<width)
- {
- write_risc_segment(rp, adr, BT848_RISC_SKIP,
- &x, dx, bpp, width);
- write_risc_segment(rp, adr, BT848_RISC_WRITEC,
- &x, cx2-x, bpp, width);
- dx=width-x;
- }
- write_risc_segment(rp, adr, BT848_RISC_SKIP,
- &x, dx, bpp, width);
- write_risc_segment(rp, adr, BT848_RISC_WRITEC,
- &x, width-x, bpp, width);
- }
- if ((!inter)||(yy&1))
- adr+=bpl;
+ /* remove rects with y2 > y */
+ if ((cur=first2.next))
+ {
+ prev=&first2;
+ do
+ {
+ if (cur->y2 < y)
+ prev->next=cur->next;
+ else
+ prev=cur;
+ }
+ while ((cur=cur->next));
+ }
+
+ /* add rect to second (x-sorted) list if rect.y == y */
+ if ((cur=first.next))
+ {
+ while ((cur) && (cur->y == y))
+ {
+ first.next=cur->next;
+ cur2=&first2;
+ while ((nx2=cur2->next) && (cur->x > cur2->next->x))
+ cur2=nx2;
+ cur2->next=cur;
+ cur->next=nx2;
+ cur=first.next;
+ }
+ }
+ x=0;
+ if ((btv->win.y+y<=0)||(btv->win.y+y>=btv->win.sheight))
+ write_risc_segment(rp, adr, BT848_RISC_SKIP, &x,
+ width, bpp, width);
+ else
+ {
+ dx=cx;
+ for (cur2=first2.next; cur2; cur2=cur2->next)
+ {
+ if (x+dx < cur2->x)
+ {
+ write_risc_segment(rp, adr, BT848_RISC_SKIP,
+ &x, dx, bpp, width);
+ dx=cur2->x-x;
+ write_risc_segment(rp, adr, BT848_RISC_WRITEC,
+ &x, dx, bpp, width);
+ dx=cur2->x2-x+1;
+ }
+ else if (x+dx < cur2->x2)
+ dx=cur2->x2-x+1;
+ }
+ if (cx2<width)
+ {
+ write_risc_segment(rp, adr, BT848_RISC_SKIP,
+ &x, dx, bpp, width);
+ write_risc_segment(rp, adr, BT848_RISC_WRITEC,
+ &x, cx2-x, bpp, width);
+ dx=width-x;
+ }
+ write_risc_segment(rp, adr, BT848_RISC_SKIP,
+ &x, dx, bpp, width);
+ write_risc_segment(rp, adr, BT848_RISC_WRITEC,
+ &x, width-x, bpp, width);
+ }
+ if ((!inter)||(yy&1))
+ adr+=bpl;
}
-
+
*(ro++)=BT848_RISC_JUMP;
*(ro++)=btv->bus_vbi_even;
*(re++)=BT848_RISC_JUMP;
@@ -982,7 +974,7 @@ static void make_clip_tab(struct bttv *btv, struct cliprec *cr, int count)
struct tvnorm
{
- u16 cropwidth, cropheight;
+ u16 swidth, sheight; /* scaled standard width, height */
u16 totalwidth;
u8 adelay, bdelay, iform;
u32 scaledtwidth;
@@ -992,8 +984,15 @@ struct tvnorm
static struct tvnorm tvnorms[] = {
/* PAL-BDGHI */
+ //{ 1024, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
+ // 1135, 100, 1024, 0x20},
+
+ { 914, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
+ 1135, 186+16, 914, 0x20},
+/*
{ 768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
944, 186, 922, 0x20},
+*/
/* NTSC */
{ 640, 480, 910, 0x68, 0x5d, (BT848_IFORM_NTSC|BT848_IFORM_XT0),
780, 135, 754, 0x16},
@@ -1059,6 +1058,10 @@ static void bt848_set_geo(struct bttv *btv, u16 width, u16 height, u16 fmt)
tvn=&tvnorms[btv->win.norm];
+ btv->win.cropheight=tvn->sheight;
+ btv->win.cropwidth=tvn->swidth;
+
+/*
if (btv->win.cropwidth>tvn->cropwidth)
btv->win.cropwidth=tvn->cropwidth;
if (btv->win.cropheight>tvn->cropheight)
@@ -1068,7 +1071,7 @@ static void bt848_set_geo(struct bttv *btv, u16 width, u16 height, u16 fmt)
width=btv->win.cropwidth;
if (height>btv->win.cropheight)
height=btv->win.cropheight;
-
+*/
btwrite(tvn->adelay, BT848_ADELAY);
btwrite(tvn->bdelay, BT848_BDELAY);
btaor(tvn->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH), BT848_IFORM);
@@ -1115,35 +1118,23 @@ int bpp2fmt[4] = {
static void bt848_set_winsize(struct bttv *btv)
{
unsigned short format;
- int bpp;
- btv->win.color_fmt=format= (btv->win.depth==15) ? BT848_COLOR_FMT_RGB15 :
- bpp2fmt[(btv->win.bpp-1)&3];
-/*
- bpp=fmtbppx2[btv->win.color_fmt&0x0f]/2;
- if (btv->win.bpp == 0)
- {
- btv->win.bpp=bpp;
- format=btv->win.color_fmt;
- }
- else if (btv->win.bpp!=bpp)
- btv->win.color_fmt=format=bpp2fmt[(btv->win.bpp-1)&3];
- else
- format=btv->win.color_fmt;
-*/
+ btv->win.color_fmt = format =
+ (btv->win.depth==15) ? BT848_COLOR_FMT_RGB15 :
+ bpp2fmt[(btv->win.bpp-1)&3];
+
/* RGB8 seems to be a 9x5x5 GRB color cube starting at
* color 16. Why the h... can't they even mention this in the
* datasheet??? [AC - because its a standard format so I guess
* it never occured them]
* Enable dithering in this mode
*/
-/*
if (format==BT848_COLOR_FMT_RGB8)
- btand(~0x10, BT848_CAP_CTL);
+ btand(~BT848_CAP_CTL_DITH_FRAME, BT848_CAP_CTL);
else
- btor(0x10, BT848_CAP_CTL);
-*/
- bt848_set_geo(btv,btv->win.width, btv->win.height, format);
+ btor(BT848_CAP_CTL_DITH_FRAME, BT848_CAP_CTL);
+
+ bt848_set_geo(btv, btv->win.width, btv->win.height, format);
}
/*
@@ -1709,7 +1700,9 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
v.flags=VIDEO_VC_AUDIO;
v.tuners=0;
v.type=VIDEO_TYPE_CAMERA;
+#if 0
v.mode = btv->win.norm;
+#endif
switch(v.channel)
{
case 0:
@@ -1739,15 +1732,11 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
*/
case VIDIOCSCHAN:
{
- struct video_channel v;
+ int v;
if(copy_from_user(&v, arg, sizeof(v)))
return -EFAULT;
- bt848_muxsel(btv, v.channel);
- lastchan=v.channel;
-#if 0
- btv->win.norm = v.mode;
- bt848_set_winsize(btv);
-#endif
+ bt848_muxsel(btv, v);
+ lastchan=v;
return 0;
}
case VIDIOCGTUNER:
@@ -1760,8 +1749,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
strcpy(v.name, "Television");
v.rangelow=0;
v.rangehigh=0xFFFFFFFF;
- v.flags=VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|
- VIDEO_TUNER_SECAM;
+ v.flags=VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC;
v.mode = btv->win.norm;
if(copy_to_user(arg,&v,sizeof(v)))
return -EFAULT;
@@ -1770,18 +1758,19 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
/* We have but tuner 0 */
case VIDIOCSTUNER:
{
+ /* FIXME: norm should be in video_channel struct
+ composite source can have different norms too
+ */
+
struct video_tuner v;
if(copy_from_user(&v, arg, sizeof(v)))
return -EFAULT;
- /* Only channel 0 has a tuner */
- if(v.tuner!=0 || lastchan)
- return -EINVAL;
+ /* Only 1 channel has a tuner */
+ /*if(v.tuner!=tvcards[btv->type].tuner || lastchan)
+ return -EINVAL;*/
if(v.mode!=VIDEO_MODE_PAL&&v.mode!=VIDEO_MODE_NTSC
&&v.mode!=VIDEO_MODE_SECAM)
return -EOPNOTSUPP;
- /* FIXME: norm should be in video_channel struct
- composite source can have different norms too
- */
btv->win.norm = v.mode;
bt848_set_winsize(btv);
return 0;
@@ -1819,7 +1808,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
bt848_hue(btv, (p.hue>>8)-128);
/* 0-511 */
bt848_contrast(btv, p.contrast>>7);
- btv->picture=p;
+ btv->picture = p;
/* set palette if bpp matches */
if (p.palette < sizeof(palette2fmt)/sizeof(int)) {
@@ -1941,23 +1930,33 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
case VIDIOCSFBUF:
{
struct video_buffer v;
+#if LINUX_VERSION_CODE >= 0x020100
+ if(!capable(CAP_SYS_ADMIN))
+#else
if(!suser())
+#endif
return -EPERM;
if(copy_from_user(&v, arg,sizeof(v)))
return -EFAULT;
if(v.depth!=8 && v.depth!=16 && v.depth!=15
&& v.depth!=24 && v.depth!=32)
return -EINVAL;
- if (v.base)
+ if (v.base)
+ {
/* also handle virtual base addresses */
if ((unsigned int)v.base>=0xe0000000UL)
btv->win.vidadr=(uint)v.base;
else
- btv->win.vidadr=PAGE_OFFSET|
- uvirt_to_bus((uint)v.base);
+ btv->win.vidadr=
+#if LINUX_VERSION_CODE >= 0x020199
+ __va(uvirt_to_bus((uint)v.base));
+#else
+ PAGE_OFFSET|uvirt_to_bus((uint)v.base);
+#endif
+ }
btv->win.sheight=v.height;
btv->win.swidth=v.width;
- btv->win.bpp=((v.depth+1)&0x18)/8;
+ btv->win.bpp=((v.depth+7)&0x38)/8;
btv->win.depth=v.depth;
btv->win.bpl=v.bytesperline;
@@ -2023,11 +2022,12 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
struct video_audio v;
if(copy_from_user(&v,arg, sizeof(v)))
return -EFAULT;
- if(v.audio<0||v.audio>2)
- return -EINVAL;
- bt848_muxsel(btv,v.audio);
if(v.flags&VIDEO_AUDIO_MUTE)
audio(btv, AUDIO_MUTE);
+ /* One audio source per tuner */
+ if(v.audio!=0)
+ return -EINVAL;
+ bt848_muxsel(btv,v.audio);
if(!(v.flags&VIDEO_AUDIO_MUTE))
audio(btv, AUDIO_UNMUTE);
if (btv->have_msp3400)
@@ -2073,7 +2073,11 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
return 0;
case BTTV_WRITEE:
+#if LINUX_VERSION_CODE >= 0x020100
+ if(!capable(CAP_SYS_ADMIN))
+#else
if(!suser())
+#endif
return -EPERM;
if(copy_from_user((void *) eedata, (void *) arg, 256))
return -EFAULT;
@@ -2081,13 +2085,23 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
return 0;
case BTTV_READEE:
+#if LINUX_VERSION_CODE >= 0x020100
+ if(!capable(CAP_SYS_ADMIN))
+#else
if(!suser())
+#endif
return -EPERM;
readee(&(btv->i2c), eedata);
if(copy_to_user((void *) arg, (void *) eedata, 256))
return -EFAULT;
break;
+ case BTTV_FIELDNR:
+ if(copy_to_user((void *) arg, (void *) &btv->last_field,
+ sizeof(btv->last_field)))
+ return -EFAULT;
+ break;
+
case VIDIOCMCAPTURE:
{
struct video_mmap vm;
@@ -2358,7 +2372,6 @@ static struct vidbases vbs[] = {
/* This id is not defined in pci.h but this entry was mailed to me?!?
{ PCI_VENDOR_ID_ALLIANCE, PCI_DEVICE_ID_ALLIANCE_AT25,
"Alliance AT25", PCI_BASE_ADDRESS_0},
-
*/
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_210888GX,
"ATI MACH64 Winturbo", PCI_BASE_ADDRESS_0},
@@ -2372,6 +2385,8 @@ static struct vidbases vbs[] = {
{ PCI_VENDOR_ID_MATROX, 0x051a, "Matrox Mystique", PCI_BASE_ADDRESS_1},
{ PCI_VENDOR_ID_N9, PCI_DEVICE_ID_N9_I128,
"Number Nine Imagine 128", PCI_BASE_ADDRESS_0},
+ { PCI_VENDOR_ID_N9, PCI_DEVICE_ID_N9_I128_2,
+ "Number Nine Imagine 128 Series 2", PCI_BASE_ADDRESS_0},
{ PCI_VENDOR_ID_S3, 0, "S3", PCI_BASE_ADDRESS_0},
{ PCI_VENDOR_ID_TSENG, 0, "TSENG", PCI_BASE_ADDRESS_0},
};
@@ -2429,6 +2444,8 @@ static int find_vga(void)
break;
}
}
+ if (NR_CARDS == i)
+ printk("UNKNOWN.\n");
if (!badr)
{
printk(KERN_ERR "bttv: Unknown video memory base address.\n");
@@ -2444,7 +2461,7 @@ static int find_vga(void)
vidadr &= PCI_BASE_ADDRESS_MEM_MASK;
if (!vidadr)
{
- printk(KERN_ERR "bttv: Memory @ 0, must be something wrong!");
+ printk(KERN_ERR "bttv: Memory @ 0, must be something wrong!\n");
continue;
}
@@ -2468,7 +2485,10 @@ static int find_vga(void)
if (vidmem)
{
- vidadr=vidmem<<20;
+ if (vidmem < 0x1000)
+ vidadr=vidmem<<20;
+ else
+ vidadr=vidmem;
printk(KERN_INFO "bttv: Video memory override: 0x%08x\n", vidadr);
found=1;
}
@@ -2562,7 +2582,8 @@ static void handle_chipset(void)
}
-static void init_tda8425(struct i2c_bus *bus) {
+static void init_tda8425(struct i2c_bus *bus)
+{
I2CWrite(bus, I2C_TDA8425, TDA8425_VL, 0xFC, 1); /* volume left 0dB */
I2CWrite(bus, I2C_TDA8425, TDA8425_VR, 0xFC, 1); /* volume right 0dB */
I2CWrite(bus, I2C_TDA8425, TDA8425_BA, 0xF6, 1); /* bass 0dB */
@@ -2587,14 +2608,16 @@ static void init_tda9850(struct i2c_bus *bus)
/* Figure out card and tuner type */
-static void idcard(struct bttv *btv)
+static void idcard(int i)
{
+ struct bttv *btv = &bttvs[i];
+
int tunertype;
btwrite(0, BT848_GPIO_OUT_EN);
- DEBUG(printk(KERN_DEBUG "bttv: GPIO: 0x%08x\n", btread(BT848_GPIO_DATA)));
+ DEBUG(printk(KERN_DEBUG "bttv%d: GPIO: 0x%08x\n", i, btread(BT848_GPIO_DATA)));
/* Default the card to the user-selected one. */
- btv->type=card;
+ btv->type=card[i];
/* If we were asked to auto-detect, then do so!
Right now this will only recognize Miro, Hauppauge or STB
@@ -2612,28 +2635,28 @@ static void idcard(struct bttv *btv)
if (I2CRead(&(btv->i2c), I2C_TDA9850) >=0)
{
- btv->audio_chip = TDA9850;
- printk("bttv: audio chip: TDA9850\n");
+ btv->audio_chip = TDA9850;
+ printk(KERN_INFO "bttv%d: audio chip: TDA9850\n",btv->nr);
}
if (I2CRead(&(btv->i2c), I2C_TDA8425) >=0)
{
- btv->audio_chip = TDA8425;
- printk("bttv: audio chip: TDA8425\n");
+ btv->audio_chip = TDA8425;
+ printk(KERN_INFO "bttv%d: audio chip: TDA8425\n",btv->nr);
}
switch(btv->audio_chip)
{
case TDA9850:
init_tda9850(&(btv->i2c));
- break;
+ break;
case TDA8425:
init_tda8425(&(btv->i2c));
break;
}
-
+
/* How do I detect the tuner type for other cards but Miro ??? */
- printk(KERN_INFO "bttv: model: ");
+ printk(KERN_INFO "bttv%d: model: ",btv->nr);
switch (btv->type)
{
case BTTV_MIRO:
@@ -2729,8 +2752,6 @@ static void bt848_set_risc_jmps(struct bttv *btv)
bt848_dma(btv, 0);
}
-
-
static int init_bt848(int i)
{
struct bttv *btv = &bttvs[i];
@@ -2739,15 +2760,9 @@ static int init_bt848(int i)
/* reset the bt848 */
btwrite(0, BT848_SRESET);
-
-
- //set_pll(btv);
-
- DEBUG(printk(KERN_DEBUG "bttv: bt848_mem: 0x%08x\n",(unsigned int) btv->bt848_mem));
-
+ DEBUG(printk(KERN_DEBUG "bttv%d: bt848_mem: 0x%08x\n",i,(unsigned int) btv->bt848_mem));
/* default setup for max. PAL size in a 1024xXXX hicolor framebuffer */
-
btv->win.norm=0; /* change this to 1 for NTSC, 2 for SECAM */
btv->win.interlace=1;
btv->win.x=0;
@@ -2776,6 +2791,7 @@ static int init_bt848(int i)
btv->grabcount=0;
btv->grab=0;
btv->lastgrab=0;
+ btv->field=btv->last_field=0;
/* i2c */
memcpy(&(btv->i2c),&bttv_i2c_bus_template,sizeof(struct i2c_bus));
@@ -2825,8 +2841,8 @@ static int init_bt848(int i)
btwrite(0xd8, BT848_CONTRAST_LO);
bt848_bright(btv, 0x10);
- btwrite(0x60, BT848_E_VSCALE_HI);
- btwrite(0x60, BT848_O_VSCALE_HI);
+ btwrite(0x20, BT848_E_VSCALE_HI);
+ btwrite(0x20, BT848_O_VSCALE_HI);
btwrite(/*BT848_ADC_SYNC_T|*/
BT848_ADC_RESERVED|BT848_ADC_CRUSH, BT848_ADC);
@@ -2846,11 +2862,12 @@ static int init_bt848(int i)
/* set interrupt mask */
btwrite(triton1|
-/* BT848_INT_PABORT|BT848_INT_RIPERR|BT848_INT_PPERR|
- BT848_INT_FDSR|BT848_INT_FTRGT|BT848_INT_FBUS|*/
+ /*BT848_INT_PABORT|BT848_INT_RIPERR|BT848_INT_PPERR|
+ BT848_INT_FDSR|BT848_INT_FTRGT|eBT848_INT_FBUS|*/
+ BT848_INT_VSYNC|
BT848_INT_SCERR|
BT848_INT_RISCI|BT848_INT_OCERR|BT848_INT_VPRES|
- BT848_INT_FMTCHG|BT848_INT_HLOCK,
+ BT848_INT_FMTCHG|BT848_INT_HLOCK,
BT848_INT_MASK);
make_vbitab(btv);
@@ -2863,7 +2880,7 @@ static int init_bt848(int i)
memcpy(&btv->video_dev,&bttv_template, sizeof(bttv_template));
memcpy(&btv->vbi_dev,&vbi_template, sizeof(vbi_template));
memcpy(&btv->radio_dev,&radio_template,sizeof(radio_template));
- idcard(btv);
+ idcard(i);
if(video_register_device(&btv->video_dev,VFL_TYPE_GRABBER)<0)
return -1;
@@ -2903,28 +2920,29 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
if (!astat)
return;
btwrite(astat,BT848_INT_STAT);
- IDEBUG(printk ("bttv: astat %08x\n",astat));
- IDEBUG(printk ("bttv: stat %08x\n",stat));
+ IDEBUG(printk ("bttv%d: astat %08x\n", btv->nr,astat));
+ IDEBUG(printk ("bttv%d: stat %08x\n", btv->nr,stat));
/* get device status bits */
dstat=btread(BT848_DSTATUS);
if (astat&BT848_INT_FMTCHG)
{
- IDEBUG(printk ("bttv: IRQ_FMTCHG\n"));
+ IDEBUG(printk ("bttv%d: IRQ_FMTCHG\n", btv->nr));
/*btv->win.norm&=
(dstat&BT848_DSTATUS_NUML) ? (~1) : (~0); */
}
if (astat&BT848_INT_VPRES)
{
- IDEBUG(printk ("bttv: IRQ_VPRES\n"));
+ IDEBUG(printk ("bttv%d: IRQ_VPRES\n", btv->nr));
}
if (astat&BT848_INT_VSYNC)
{
- IDEBUG(printk ("bttv: IRQ_VSYNC\n"));
+ IDEBUG(printk ("bttv%d: IRQ_VSYNC\n",btv->nr));
+ btv->field++;
}
if (astat&BT848_INT_SCERR) {
- IDEBUG(printk ("bttv: IRQ_SCERR\n"));
+ IDEBUG(printk ("bttv%d: IRQ_SCERR\n", btv->nr));
bt848_dma(btv, 0);
bt848_dma(btv, 1);
wake_up_interruptible(&btv->vbiq);
@@ -2933,7 +2951,7 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
}
if (astat&BT848_INT_RISCI)
{
- IDEBUG(printk ("bttv: IRQ_RISCI\n"));
+ IDEBUG(printk ("bttv%d: IRQ_RISCI\n", btv->nr));
/* captured VBI frame */
if (stat&(1<<28))
@@ -2945,6 +2963,7 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
/* captured full frame */
if (stat&(2<<28))
{
+ btv->last_field=btv->field;
btv->grab++;
btv->frame_stat[btv->grf] = GBUFFER_DONE;
if ((--btv->grabbing))
@@ -2977,31 +2996,31 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
}
if (astat&BT848_INT_OCERR)
{
- IDEBUG(printk ("bttv: IRQ_OCERR\n"));
+ IDEBUG(printk ("bttv%d: IRQ_OCERR\n", btv->nr));
}
if (astat&BT848_INT_PABORT)
{
- IDEBUG(printk ("bttv: IRQ_PABORT\n"));
+ IDEBUG(printk ("bttv%d: IRQ_PABORT\n", btv->nr));
}
if (astat&BT848_INT_RIPERR)
{
- IDEBUG(printk ("bttv: IRQ_RIPERR\n"));
+ IDEBUG(printk ("bttv%d: IRQ_RIPERR\n", btv->nr));
}
if (astat&BT848_INT_PPERR)
{
- IDEBUG(printk ("bttv: IRQ_PPERR\n"));
+ IDEBUG(printk ("bttv%d: IRQ_PPERR\n", btv->nr));
}
if (astat&BT848_INT_FDSR)
{
- IDEBUG(printk ("bttv: IRQ_FDSR\n"));
+ IDEBUG(printk ("bttv%d: IRQ_FDSR\n", btv->nr));
}
if (astat&BT848_INT_FTRGT)
{
- IDEBUG(printk ("bttv: IRQ_FTRGT\n"));
+ IDEBUG(printk ("bttv%d: IRQ_FTRGT\n", btv->nr));
}
if (astat&BT848_INT_FBUS)
{
- IDEBUG(printk ("bttv: IRQ_FBUS\n"));
+ IDEBUG(printk ("bttv%d: IRQ_FBUS\n", btv->nr));
}
if (astat&BT848_INT_HLOCK)
{
@@ -3017,12 +3036,14 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
count++;
if (count > 10)
- printk (KERN_WARNING "bttv: irq loop %d\n", count);
+ printk (KERN_WARNING "bttv%d: irq loop %d\n",
+ btv->nr,count);
if (count > 20)
{
btwrite(0, BT848_INT_MASK);
printk(KERN_ERR
- "bttv: IRQ lockup, cleared int mask\n");
+ "bttv%d: IRQ lockup, cleared int mask\n",
+ btv->nr);
}
}
}
@@ -3045,18 +3066,23 @@ static int find_bt848(void)
if (!pcibios_present())
{
- DEBUG(printk(KERN_DEBUG "bttv: PCI-BIOS not present or not accessable!\n"));
+ DEBUG(printk(KERN_DEBUG "bttv%d: PCI-BIOS not present or not accessable!\n",bttv_num));
return 0;
}
for (pci_index = 0;
!pcibios_find_device(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
- pci_index, &bus, &devfn)
- ||!pcibios_find_device(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
- pci_index, &bus, &devfn);
- ++pci_index)
+ pci_index, &bus, &devfn)
+ ||!pcibios_find_device(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
+ pci_index, &bus, &devfn)
+ ||!pcibios_find_device(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878,
+ pci_index, &bus, &devfn)
+ ||!pcibios_find_device(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879,
+ pci_index, &bus, &devfn);
+ ++pci_index)
{
btv=&bttvs[bttv_num];
+ btv->nr = bttv_num;
btv->bus=bus;
btv->devfn=devfn;
btv->bt848_mem=NULL;
@@ -3078,14 +3104,16 @@ static int find_bt848(void)
pcibios_read_config_dword(btv->bus, btv->devfn, PCI_BASE_ADDRESS_0,
&btv->bt848_adr);
- if (remap&&(!bttv_num))
- {
- remap<<=20;
- remap&=PCI_BASE_ADDRESS_MEM_MASK;
- printk(KERN_INFO "Remapping to : 0x%08x.\n", remap);
- remap|=btv->bt848_adr&(~PCI_BASE_ADDRESS_MEM_MASK);
+ if (remap[bttv_num])
+ {
+ if (remap[bttv_num] < 0x1000)
+ remap[bttv_num]<<=20;
+ remap[bttv_num]&=PCI_BASE_ADDRESS_MEM_MASK;
+ printk(KERN_INFO "bttv%d: remapping to : 0x%08x.\n",
+ bttv_num,remap[bttv_num]);
+ remap[bttv_num]|=btv->bt848_adr&(~PCI_BASE_ADDRESS_MEM_MASK);
pcibios_write_config_dword(btv->bus, btv->devfn, PCI_BASE_ADDRESS_0,
- remap);
+ remap[bttv_num]);
pcibios_read_config_dword(btv->bus, btv->devfn, PCI_BASE_ADDRESS_0,
&btv->bt848_adr);
}
@@ -3093,18 +3121,18 @@ static int find_bt848(void)
btv->bt848_adr&=PCI_BASE_ADDRESS_MEM_MASK;
pcibios_read_config_byte(btv->bus, btv->devfn, PCI_CLASS_REVISION,
&btv->revision);
- printk(KERN_INFO "bttv: Brooktree Bt%d (rev %d) ",
- btv->id, btv->revision);
+ printk(KERN_INFO "bttv%d: Brooktree Bt%d (rev %d) ",
+ bttv_num,btv->id, btv->revision);
printk("bus: %d, devfn: %d, ",
- btv->bus, btv->devfn);
+ btv->bus, btv->devfn);
printk("irq: %d, ",btv->irq);
printk("memory: 0x%08x.\n", btv->bt848_adr);
btv->pll=0;
#ifdef USE_PLL
- if (btv->id==849 || (btv->id==848 && btv->revision==0x12))
+ if (!(btv->id==848 && btv->revision==0x11))
{
- printk("bttv: internal PLL, single crystal operation enabled\n");
+ printk(KERN_INFO "bttv%d: internal PLL, single crystal operation enabled\n",bttv_num);
btv->pll=1;
}
#endif
@@ -3115,12 +3143,13 @@ static int find_bt848(void)
SA_SHIRQ | SA_INTERRUPT,"bttv",(void *)btv);
if (result==-EINVAL)
{
- printk(KERN_ERR "bttv: Bad irq number or handler\n");
+ printk(KERN_ERR "bttv%d: Bad irq number or handler\n",
+ bttv_num);
return -EINVAL;
}
if (result==-EBUSY)
{
- printk(KERN_ERR "bttv: IRQ %d busy, change your PnP config in BIOS\n",btv->irq);
+ printk(KERN_ERR "bttv%d: IRQ %d busy, change your PnP config in BIOS\n",bttv_num,btv->irq);
return result;
}
if (result < 0)
@@ -3133,7 +3162,7 @@ static int find_bt848(void)
pcibios_read_config_byte(btv->bus, btv->devfn, PCI_COMMAND, &command);
if (!(command&PCI_COMMAND_MASTER))
{
- printk(KERN_ERR "bttv: PCI bus-mastering could not be enabled\n");
+ printk(KERN_ERR "bttv%d: PCI bus-mastering could not be enabled\n",bttv_num);
return -1;
}
pcibios_read_config_byte(btv->bus, btv->devfn, PCI_LATENCY_TIMER,
@@ -3144,7 +3173,8 @@ static int find_bt848(void)
pcibios_write_config_byte(btv->bus, btv->devfn,
PCI_LATENCY_TIMER, latency);
}
- DEBUG(printk(KERN_DEBUG "bttv: latency: %02x\n", latency));
+ DEBUG(printk(KERN_DEBUG "bttv%d: latency: %02x\n",
+ bttv_num, latency));
bttv_num++;
}
if(bttv_num)

Privacy Policy