summaryrefslogtreecommitdiffstats
path: root/drivers/char/bttv.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-08-25 09:12:35 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-08-25 09:12:35 +0000
commitc7fc24dc4420057f103afe8fc64524ebc25c5d37 (patch)
tree3682407a599b8f9f03fc096298134cafba1c9b2f /drivers/char/bttv.c
parent1d793fade8b063fde3cf275bf1a5c2d381292cd9 (diff)
o Merge with Linux 2.1.116.
o New Newport console code. o New G364 console code.
Diffstat (limited to 'drivers/char/bttv.c')
-rw-r--r--drivers/char/bttv.c775
1 files changed, 503 insertions, 272 deletions
diff --git a/drivers/char/bttv.c b/drivers/char/bttv.c
index 97d5794f1..8bb3f203e 100644
--- a/drivers/char/bttv.c
+++ b/drivers/char/bttv.c
@@ -24,22 +24,25 @@
TODO:
- * think of some good ioctls for Video4Linux to handle
- YUV, planar YUV, ... grabs and sell them to AC :-)
* move norm from tuner to channel struct!?
composite source from a satellite tuner can deliver different norms
depending on tuned channel
* mmap VBI data?
+ * use new PCI routines
+ * fix RAW Composite grabbing for NTSC
+ * allow for different VDELAY in RAW grabbing?
+ * extra modules for tda9850, tda8425, any volunteers???
+ * support 15bpp
*/
#include <linux/module.h>
-#include <linux/bios32.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/malloc.h>
+#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/signal.h>
@@ -55,7 +58,7 @@
#include <linux/version.h>
#include <asm/uaccess.h>
-#include "i2c.h"
+#include <linux/i2c.h>
#include "bttv.h"
#include "tuner.h"
@@ -153,6 +156,7 @@ static void * rvmalloc(unsigned long size)
mem=vmalloc(size);
if (mem)
{
+ memset(mem, 0, size); /* Clear the ram out, no junk to the user */
adr=(unsigned long) mem;
while (size > 0)
{
@@ -193,7 +197,7 @@ static void rvfree(void * mem, unsigned long size)
static int fbuffer_alloc(struct bttv *btv)
{
if(!btv->fbuffer)
- btv->fbuffer=(unsigned char *) rvmalloc(2*0x144000);
+ btv->fbuffer=(unsigned char *) rvmalloc(2*BTTV_MAX_FBUF);
else
printk(KERN_ERR "bttv: Double alloc of fbuffer!\n");
if(!btv->fbuffer)
@@ -242,7 +246,7 @@ static int I2CRead(struct i2c_bus *bus, unsigned char addr)
stat=btread(BT848_INT_STAT);
if (stat & BT848_INT_I2CDONE)
break;
- udelay(1000);
+ mdelay(1);
}
if (!i)
@@ -284,7 +288,7 @@ static int I2CWrite(struct i2c_bus *bus, unsigned char addr, unsigned char b1,
stat=btread(BT848_INT_STAT);
if (stat & BT848_INT_I2CDONE)
break;
- udelay(1000);
+ mdelay(1);
}
if (!i)
@@ -349,9 +353,9 @@ void attach_inform(struct i2c_bus *bus, int id)
break;
case I2C_DRIVERID_TUNER:
btv->have_tuner = 1;
- if (btv->type == BTTV_MIRO)
+ if (btv->tuner_type != -1)
{
- tunertype=((btread(BT848_GPIO_DATA)>>10)-1)&7;
+ tunertype=btv->tuner_type;
i2c_control_device(&(btv->i2c), I2C_DRIVERID_TUNER,
TUNER_SET_TYPE,&tunertype);
}
@@ -393,28 +397,50 @@ static struct i2c_bus bttv_i2c_bus_template =
/* ----------------------------------------------------------------------- */
+
+struct tvcard
+{
+ int inputs;
+ int tuner;
+ int svhs;
+ u32 gpiomask;
+ u32 muxsel[8];
+ u32 audiomux[6]; /* Tuner, Radio, internal, external, mute, stereo */
+};
+
+static struct tvcard tvcards[] =
+{
+ /* default */
+ { 3, 0, 2, 0, { 2, 3, 1, 1}, { 0, 0, 0, 0, 0}},
+ /* MIRO */
+ { 4, 0, 2,15, { 2, 3, 1, 1}, { 2, 0, 0, 0,10}},
+ /* Hauppauge */
+ { 3, 0, 2, 7, { 2, 3, 1, 1}, { 0, 1, 2, 3, 4}},
+ /* STB */
+ { 3, 0, 2, 7, { 2, 3, 1, 1}, { 4, 0, 2, 3, 1}},
+ /* Intel??? */
+ { 3, 0, 2, 7, { 2, 3, 1, 1}, { 0, 1, 2, 3, 4}},
+ /* Diamond DTV2000 */
+ { 3, 0, 2, 3, { 2, 3, 1, 1}, { 0, 1, 0, 1, 3}},
+ /* 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}},
+ /* 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, 0x02, 0x03, 0x04}, /* Diamond DTV2000 */
- { 0x0c, 0x00, 0x0b, 0x0b, 0x00}, /* AVerMedia TVPhone */
-};
-
static void audio(struct bttv *btv, int mode)
{
- /* enable least significant GPIO output nibble */
- btwrite(0x0f, BT848_GPIO_OUT_EN);
-
- /* select direct input */
- btwrite(0x00, BT848_GPIO_REG_INP);
+ btaor(tvcards[btv->type].gpiomask, ~tvcards[btv->type].gpiomask,
+ BT848_GPIO_OUT_EN);
switch (mode)
{
@@ -437,12 +463,17 @@ 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;
- btaor(audiomuxs[btv->type][mode] , ~0x0f, BT848_GPIO_DATA);
+ btaor(tvcards[btv->type].audiomux[mode],
+ ~tvcards[btv->type].gpiomask, BT848_GPIO_DATA);
}
@@ -469,14 +500,77 @@ static void bt848_cap(struct bttv *btv, uint state)
}
}
-static void bt848_muxsel(struct bttv *btv, uint input)
+
+/* If Bt848a or Bt849, use PLL for PAL/SECAM and crystal for NTSC*/
+
+static int set_pll(struct bttv *btv)
+{
+ int i;
+
+ if (!btv->pll)
+ return 0;
+ if ((btread(BT848_IFORM)&BT848_IFORM_XT0))
+ {
+ /* printk ("switching PLL off\n");*/
+ btwrite(0x00,BT848_TGCTRL);
+ btwrite(0x00,BT848_PLL_XCI);
+ btv->pll&=~2;
+ return 0;
+ }
+
+ /* do not set pll again if already active */
+ if (btv->pll&2)
+ return 1;
+
+ /* printk ("setting PLL for PAL/SECAM\n");*/
+
+ btwrite(0x00,BT848_TGCTRL);
+ btwrite(0xf9,BT848_PLL_F_LO);
+ btwrite(0xdc,BT848_PLL_F_HI);
+ btwrite(0x8e,BT848_PLL_XCI);
+
+ /* Ugh ugh ugh .. schedule ? */
+ udelay(100000);
+ for (i=0; i<100; i++)
+ {
+ if ((btread(BT848_DSTATUS)&BT848_DSTATUS_PLOCK))
+ btwrite(0,BT848_DSTATUS);
+ else
+ {
+ btwrite(0x08,BT848_TGCTRL);
+ btv->pll|=2;
+ return 1;
+ }
+ udelay(10000);
+ }
+ return -1;
+}
+
+static void bt848_muxsel(struct bttv *btv, unsigned int input)
{
- input&=3;
+ btwrite(tvcards[btv->type].gpiomask, BT848_GPIO_OUT_EN);
/* This seems to get rid of some synchronization problems */
btand(~(3<<5), BT848_IFORM);
- udelay(10000);
+ mdelay(10);
+ input %= tvcards[btv->type].inputs;
+ if (input==tvcards[btv->type].svhs)
+ {
+ 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);
+ }
+ btaor((tvcards[btv->type].muxsel[input&7]&3)<<5, ~(3<<5), BT848_IFORM);
+ 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 0
if (input==3)
{
btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
@@ -491,6 +585,7 @@ static void bt848_muxsel(struct bttv *btv, uint input)
input=3;
btaor(((input+2)&3)<<5, ~(3<<5), BT848_IFORM);
audio(btv, input ? AUDIO_EXTERN : AUDIO_TUNER);
+#endif
}
@@ -540,8 +635,60 @@ int fmtbppx2[16] = {
8, 6, 4, 4, 4, 3, 2, 2, 4, 3, 0, 0, 0, 0, 2, 0
};
-static int make_vrisctab(struct bttv *btv, unsigned int *ro, unsigned int *re,
- unsigned int *vbuf, unsigned short width, unsigned short height, unsigned short fmt)
+int palette2fmt[] = {
+ 0,
+ BT848_COLOR_FMT_Y8,
+ BT848_COLOR_FMT_RGB8,
+ BT848_COLOR_FMT_RGB16,
+ BT848_COLOR_FMT_RGB24,
+ BT848_COLOR_FMT_RGB32,
+ BT848_COLOR_FMT_RGB15,
+ BT848_COLOR_FMT_YUY2,
+ BT848_COLOR_FMT_BtYUV,
+ -1,
+ -1,
+ -1,
+ BT848_COLOR_FMT_RAW,
+ BT848_COLOR_FMT_YCrCb422,
+ BT848_COLOR_FMT_YCrCb411,
+};
+#define PALETTEFMT_MAX 11
+
+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 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 ... */
+
+ for (line=0; line < 640; line++)
+ {
+ *(ro++)=BT848_RISC_WRITE|bpl|BT848_RISC_SOL|BT848_RISC_EOL;
+ *(ro++)=kvirt_to_bus(vadr);
+ *(re++)=BT848_RISC_WRITE|bpl|BT848_RISC_SOL|BT848_RISC_EOL;
+ *(re++)=kvirt_to_bus(vadr+BTTV_MAX_FBUF/2);
+ vadr+=bpl;
+ }
+
+ *(ro++)=BT848_RISC_JUMP;
+ *(ro++)=btv->bus_vbi_even;
+ *(re++)=BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16);
+ *(re++)=btv->bus_vbi_odd;
+
+ return 0;
+}
+
+
+static int make_vrisctab(struct bttv *btv, unsigned int *ro,
+ unsigned int *re,
+ unsigned int *vbuf, unsigned short width,
+ unsigned short height, unsigned short fmt)
{
unsigned long line;
unsigned long bpl; /* bytes per line */
@@ -551,6 +698,9 @@ static int make_vrisctab(struct bttv *btv, unsigned int *ro, unsigned int *re,
int inter;
unsigned long vadr=(unsigned long) vbuf;
+ if (btv->gfmt==BT848_COLOR_FMT_RAW)
+ return make_rawrisctab(btv, ro, re, vbuf);
+
inter = (height>btv->win.cropheight/2) ? 1 : 0;
bpl=width*fmtbppx2[fmt&0xf]/2;
@@ -652,6 +802,7 @@ static inline void write_risc_segment(unsigned int **rp, unsigned long line_adr,
*x+=dx;
}
+
/*
* Set the registers for the size we have specified. Don't bother
* trying to understand this without the BT848 manual in front of
@@ -683,10 +834,16 @@ static struct tvnorm tvnorms[] = {
944, 186, 922, 0x20},
/* PAL-M */
{ 640, 480, 910, 0x68, 0x5d, (BT848_IFORM_PAL_M|BT848_IFORM_XT0),
- 780, 186, 922, 0x16},
+ 780, 135, 754, 0x16},
/* PAL-N */
{ 768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_N|BT848_IFORM_XT1),
944, 186, 922, 0x20},
+ /* PAL-NC */
+ { 768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_NC|BT848_IFORM_XT0),
+ 944, 186, 922, 0x20},
+ /* NTSC-Japan */
+ { 640, 480, 910, 0x68, 0x5d, (BT848_IFORM_NTSC_J|BT848_IFORM_XT0),
+ 780, 135, 754, 0x16},
};
#define TVNORMS (sizeof(tvnorms)/sizeof(tvnorm))
@@ -709,7 +866,7 @@ static inline void bt848_set_eogeo(struct bttv *btv, int odd, u8 vtc,
btwrite(vtc, BT848_E_VTC+off);
btwrite(hscale>>8, BT848_E_HSCALE_HI+off);
btwrite(hscale&0xff, BT848_E_HSCALE_LO+off);
- btaor((vscale>>8), 0xc0, BT848_E_VSCALE_HI+off);
+ btaor((vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
btwrite(vscale&0xff, BT848_E_VSCALE_LO+off);
btwrite(hactive&0xff, BT848_E_HACTIVE_LO+off);
btwrite(hdelay&0xff, BT848_E_HDELAY_LO+off);
@@ -747,6 +904,8 @@ static void bt848_set_geo(struct bttv *btv, u16 width, u16 height, u16 fmt)
btwrite(tvn->adelay, BT848_ADELAY);
btwrite(tvn->bdelay, BT848_BDELAY);
btaor(tvn->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH), BT848_IFORM);
+
+ set_pll(btv);
btwrite(fmt, BT848_COLOR_FMT);
hactive=width;
@@ -788,30 +947,22 @@ int bpp2fmt[4] = {
static void bt848_set_winsize(struct bttv *btv)
{
unsigned short format;
- int bpp;
- 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
+ * data sheet? [AC - because it's a standard format so I guess
+ * it never occurred to them]
+ * Enable dithering in this mode.
*/
+#if 0
if (format==BT848_COLOR_FMT_RGB8)
btand(~0x10, BT848_CAP_CTL);
else
btor(0x10, BT848_CAP_CTL);
-
+#endif
bt848_set_geo(btv,btv->win.width, btv->win.height, format);
}
@@ -876,6 +1027,8 @@ static int vgrab(struct bttv *btv, struct video_mmap *mp)
if(fbuffer_alloc(btv))
return -ENOBUFS;
}
+ if(btv->grabbing>1)
+ return -ENOBUFS;
/*
* No grabbing past the end of the buffer!
@@ -887,7 +1040,7 @@ static int vgrab(struct bttv *btv, struct video_mmap *mp)
if(mp->height <0 || mp->width <0)
return -EINVAL;
- if(mp->height>480 || mp->width>640)
+ if(mp->height>576 || mp->width>768)
return -EINVAL;
/*
@@ -900,20 +1053,30 @@ static int vgrab(struct bttv *btv, struct video_mmap *mp)
* Ok load up the BT848
*/
- vbuf=(unsigned int *)(btv->fbuffer+0x144000*mp->frame);
- if (!(btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC))
- return -EAGAIN;
- ro=btv->grisc+(((btv->grabcount++)&1) ? 2048 :0);
- re=ro+1024;
+ vbuf=(unsigned int *)(btv->fbuffer+BTTV_MAX_FBUF*mp->frame);
+/* if (!(btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC))
+ return -EAGAIN; */
+ ro=btv->grisc+(((btv->grabcount++)&1) ? 4096 :0);
+ re=ro+2048;
btv->gwidth=mp->width;
btv->gheight=mp->height;
- btv->gfmt=mp->format;
+ if (mp->format > PALETTEFMT_MAX)
+ return -EINVAL;
+ btv->gfmt=palette2fmt[mp->format];
+ if(btv->gfmt==-1)
+ return -EINVAL;
+
make_vrisctab(btv, ro, re, vbuf, btv->gwidth, btv->gheight, btv->gfmt);
/* bt848_set_risc_jmps(btv); */
btor(3, BT848_CAP_CTL);
btor(3, BT848_GPIO_DMA_CTL);
- btv->gro=virt_to_bus(ro);
- btv->gre=virt_to_bus(re);
+ if (btv->grabbing) {
+ btv->gro_next=virt_to_bus(ro);
+ btv->gre_next=virt_to_bus(re);
+ } else {
+ btv->gro=virt_to_bus(ro);
+ btv->gre=virt_to_bus(re);
+ }
if (!(btv->grabbing++))
btv->risc_jmp[12]=BT848_RISC_JUMP|(0x8<<16)|BT848_RISC_IRQ;
/* interruptible_sleep_on(&btv->capq); */
@@ -990,7 +1153,7 @@ static int bttv_open(struct video_device *dev, int flags)
find_vga();
btv->fbuffer=NULL;
if (!btv->fbuffer)
- btv->fbuffer=(unsigned char *) rvmalloc(2*0x144000);
+ btv->fbuffer=(unsigned char *) rvmalloc(2*BTTV_MAX_FBUF);
if (!btv->fbuffer)
{
btv->user--;
@@ -1014,7 +1177,7 @@ static void bttv_close(struct video_device *dev)
bt848_set_risc_jmps(btv);
if(btv->fbuffer)
- rvfree((void *) btv->fbuffer, 2*0x144000);
+ rvfree((void *) btv->fbuffer, 2*BTTV_MAX_FBUF);
btv->fbuffer=0;
MOD_DEC_USE_COUNT;
}
@@ -1411,8 +1574,9 @@ 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;
+ v.flags=VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
v.mode = btv->win.norm;
+ v.signal = (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) ? 0xFFFF : 0;
if(copy_to_user(arg,&v,sizeof(v)))
return -EFAULT;
return 0;
@@ -1439,13 +1603,15 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
case VIDIOCGPICT:
{
struct video_picture p=btv->picture;
- if(btv->win.bpp==1)
+ if(btv->win.depth==8)
p.palette=VIDEO_PALETTE_HI240;
- if(btv->win.bpp==2)
+ if(btv->win.depth==15)
+ p.palette=VIDEO_PALETTE_RGB555;
+ if(btv->win.depth==16)
p.palette=VIDEO_PALETTE_RGB565;
- if(btv->win.bpp==3)
+ if(btv->win.depth==24)
p.palette=VIDEO_PALETTE_RGB24;
- if(btv->win.bpp==4)
+ if(btv->win.depth==32)
p.palette=VIDEO_PALETTE_RGB32;
if(copy_to_user(arg, &p, sizeof(p)))
@@ -1455,6 +1621,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
case VIDIOCSPICT:
{
struct video_picture p;
+ int format;
if(copy_from_user(&p, arg,sizeof(p)))
return -EFAULT;
/* We want -128 to 127 we get 0-65535 */
@@ -1466,8 +1633,15 @@ 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;
- return 0;
+ btv->picture = p;
+
+ /* set palette if bpp matches */
+ if (p.palette < sizeof(palette2fmt)/sizeof(int)) {
+ format = palette2fmt[p.palette];
+ if (fmtbppx2[format&0x0f]/2 == btv->win.bpp)
+ btv->win.color_fmt = format;
+ }
+ return 0;
}
case VIDIOCSWIN:
{
@@ -1571,7 +1745,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
v.base=(void *)btv->win.vidadr;
v.height=btv->win.sheight;
v.width=btv->win.swidth;
- v.depth=btv->win.bpp*8;
+ v.depth=btv->win.depth;
v.bytesperline=btv->win.bpl;
if(copy_to_user(arg, &v,sizeof(v)))
return -EFAULT;
@@ -1585,18 +1759,13 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
return -EPERM;
if(copy_from_user(&v, arg,sizeof(v)))
return -EFAULT;
- if(v.depth!=8 && v.depth!=16 && v.depth!=24 && v.depth!=32)
+ if(v.depth!=8 && v.depth!=15 && v.depth!=16 && v.depth!=24 && v.depth!=32)
return -EINVAL;
- 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=(unsigned long)v.base;
btv->win.sheight=v.height;
btv->win.swidth=v.width;
- btv->win.bpp=v.depth/8;
+ btv->win.bpp=((v.depth+1)&0x38)/8;
+ btv->win.depth=v.depth;
btv->win.bpl=v.bytesperline;
DEBUG(printk("Display at %p is %d by %d, bytedepth %d, bpl %d\n",
@@ -1635,13 +1804,21 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
strcpy(v.name,"TV");
if (btv->have_msp3400)
{
- v.flags|=VIDEO_AUDIO_VOLUME;
- i2c_control_device(&(btv->i2c),
- I2C_DRIVERID_MSP3400,
- MSP_GET_VOLUME,&(v.volume));
- i2c_control_device(&(btv->i2c),
- I2C_DRIVERID_MSP3400,
- MSP_GET_STEREO,&(v.mode));
+ v.flags|=VIDEO_AUDIO_VOLUME |
+ VIDEO_AUDIO_BASS |
+ VIDEO_AUDIO_TREBLE;
+ i2c_control_device(&(btv->i2c),
+ I2C_DRIVERID_MSP3400,
+ MSP_GET_VOLUME,&(v.volume));
+ i2c_control_device(&(btv->i2c),
+ I2C_DRIVERID_MSP3400,
+ MSP_GET_BASS,&(v.bass));
+ i2c_control_device(&(btv->i2c),
+ I2C_DRIVERID_MSP3400,
+ MSP_GET_TREBLE,&(v.treble));
+ i2c_control_device(&(btv->i2c),
+ I2C_DRIVERID_MSP3400,
+ MSP_GET_STEREO,&(v.mode));
}
else v.mode = VIDEO_SOUND_MONO;
if(copy_to_user(arg,&v,sizeof(v)))
@@ -1655,28 +1832,37 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
return -EFAULT;
if(v.flags&VIDEO_AUDIO_MUTE)
audio(btv, AUDIO_MUTE);
- if(v.audio<0||v.audio>2)
+ /* 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)
{
- i2c_control_device(&(btv->i2c),
- I2C_DRIVERID_MSP3400,
- MSP_SET_VOLUME,&(v.volume));
- i2c_control_device(&(btv->i2c),
- I2C_DRIVERID_MSP3400,
- MSP_SET_STEREO,&(v.mode));
+ i2c_control_device(&(btv->i2c),
+ I2C_DRIVERID_MSP3400,
+ MSP_SET_VOLUME,&(v.volume));
+ i2c_control_device(&(btv->i2c),
+ I2C_DRIVERID_MSP3400,
+ MSP_SET_BASS,&(v.bass));
+ i2c_control_device(&(btv->i2c),
+ I2C_DRIVERID_MSP3400,
+ MSP_SET_TREBLE,&(v.treble));
+ i2c_control_device(&(btv->i2c),
+ I2C_DRIVERID_MSP3400,
+ MSP_SET_STEREO,&(v.mode));
}
btv->audio_dev=v;
return 0;
}
case VIDIOCSYNC:
- if (btv->grabbing && btv->grab==btv->lastgrab)
+ if (!btv->grabbing)
+ return -EAGAIN;
+ if (btv->grab==btv->lastgrab)
interruptible_sleep_on(&btv->capq);
- btv->lastgrab=btv->grab;
+ btv->lastgrab++;
return 0;
case BTTV_WRITEE:
@@ -1728,7 +1914,7 @@ static int bttv_mmap(struct video_device *dev, const char *adr, unsigned long si
unsigned long start=(unsigned long) adr;
unsigned long page,pos;
- if (size>2*0x144000)
+ if (size>2*BTTV_MAX_FBUF)
return -EINVAL;
if (!btv->fbuffer)
{
@@ -1757,6 +1943,7 @@ static struct video_device bttv_template=
bttv_close,
bttv_read,
bttv_write,
+ NULL, /* poll */
bttv_ioctl,
bttv_mmap,
bttv_init_done,
@@ -1810,6 +1997,20 @@ static long vbi_read(struct video_device *v, char *buf, unsigned long count,
return count;
}
+static unsigned int vbi_poll(struct video_device *dev, struct file *file,
+ poll_table *wait)
+{
+ struct bttv *btv=(struct bttv *)(dev-2);
+ unsigned int mask = 0;
+
+ poll_wait(file, &btv->vbiq, wait);
+
+ if (btv->vbip < VBIBUF_SIZE)
+ mask |= (POLLIN | POLLRDNORM);
+
+ return mask;
+}
+
static int vbi_open(struct video_device *dev, int flags)
{
struct bttv *btv=(struct bttv *)(dev-2);
@@ -1847,6 +2048,7 @@ static struct video_device vbi_template=
vbi_close,
vbi_read,
bttv_write,
+ vbi_poll,
vbi_ioctl,
NULL, /* no mmap yet */
bttv_init_done,
@@ -1943,6 +2145,7 @@ static struct video_device radio_template=
radio_close,
radio_read, /* just returns -EINVAL */
bttv_write, /* just returns -EINVAL */
+ NULL, /* no poll */
radio_ioctl,
NULL, /* no mmap */
bttv_init_done, /* just returns 0 */
@@ -1960,18 +2163,24 @@ struct vidbases
};
static struct vidbases vbs[] = {
- { PCI_VENDOR_ID_TSENG, 0, "TSENG", PCI_BASE_ADDRESS_0},
- { PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL,
- "Matrox Millennium", PCI_BASE_ADDRESS_1},
- { PCI_VENDOR_ID_MATROX, 0x051a, "Matrox Mystique", PCI_BASE_ADDRESS_1},
- { PCI_VENDOR_ID_S3, 0, "S3", PCI_BASE_ADDRESS_0},
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_210888GX,
"ATI MACH64 Winturbo", PCI_BASE_ADDRESS_0},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_215GT,
+ "ATI MACH64 GT", PCI_BASE_ADDRESS_0},
{ PCI_VENDOR_ID_CIRRUS, 0, "Cirrus Logic", PCI_BASE_ADDRESS_0},
- { PCI_VENDOR_ID_N9, PCI_DEVICE_ID_N9_I128,
- "Number Nine Imagine 128", PCI_BASE_ADDRESS_0},
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA,
"DEC DC21030", PCI_BASE_ADDRESS_0},
+ { PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL,
+ "Matrox Millennium", PCI_BASE_ADDRESS_1},
+ { PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2,
+ "Matrox Millennium II", PCI_BASE_ADDRESS_0},
+ { PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2_AGP,
+ "Matrox Millennium II AGP", PCI_BASE_ADDRESS_0},
+ { 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_S3, 0, "S3", PCI_BASE_ADDRESS_0},
+ { PCI_VENDOR_ID_TSENG, 0, "TSENG", PCI_BASE_ADDRESS_0},
};
@@ -1991,77 +2200,69 @@ static uint dec_offsets[4] = {
static int find_vga(void)
{
- unsigned int devfn, class, vendev;
- unsigned short vendor, device, badr;
- int found=0, bus=0, i, tga_type;
+ unsigned short badr;
+ int found = 0, i, tga_type;
unsigned int vidadr=0;
+ struct pci_dev *dev;
- for (devfn = 0; devfn < 0xff; devfn++)
+ for (dev = pci_devices; dev != NULL; dev = dev->next)
{
- if (PCI_FUNC(devfn) != 0)
+ if (dev->class != PCI_CLASS_NOT_DEFINED_VGA &&
+ ((dev->class) >> 16 != PCI_BASE_CLASS_DISPLAY))
+ {
continue;
- pcibios_read_config_dword(bus, devfn, PCI_VENDOR_ID, &vendev);
- if (vendev == 0xffffffff || vendev == 0x00000000)
+ }
+ if (PCI_FUNC(dev->devfn) != 0)
continue;
- pcibios_read_config_word(bus, devfn, PCI_VENDOR_ID, &vendor);
- pcibios_read_config_word(bus, devfn, PCI_DEVICE_ID, &device);
- pcibios_read_config_dword(bus, devfn, PCI_CLASS_REVISION, &class);
- class = class >> 16;
-/* if (class == PCI_CLASS_DISPLAY_VGA) {*/
- if ((class>>8) == PCI_BASE_CLASS_DISPLAY ||
- /* Number 9 GXE64Pro needs this */
- class == PCI_CLASS_NOT_DEFINED_VGA)
+
+ badr=0;
+ printk(KERN_INFO "bttv: PCI display adapter: ");
+ for (i=0; i<NR_CARDS; i++)
{
- badr=0;
- printk(KERN_INFO "bttv: PCI display adapter: ");
- for (i=0; i<NR_CARDS; i++)
- {
- if (vendor==vbs[i].vendor)
- {
- if (vbs[i].device)
- if (vbs[i].device!=device)
- continue;
- printk("%s.\n", vbs[i].name);
- badr=vbs[i].badr;
- break;
- }
- }
- if (!badr)
- {
- printk(KERN_ERR "bttv: Unknown video memory base address.\n");
- continue;
- }
- pcibios_read_config_dword(bus, devfn, badr, &vidadr);
- if (vidadr & PCI_BASE_ADDRESS_SPACE_IO)
- {
- printk(KERN_ERR "bttv: Memory seems to be I/O memory.\n");
- printk(KERN_ERR "bttv: Check entry for your card type in bttv.c vidbases struct.\n");
- continue;
- }
- vidadr &= PCI_BASE_ADDRESS_MEM_MASK;
- if (!vidadr)
+ if (dev->vendor == vbs[i].vendor)
{
- printk(KERN_ERR "bttv: Memory @ 0, must be something wrong!");
- continue;
+ if (vbs[i].device)
+ if (vbs[i].device!=dev->device)
+ continue;
+ printk("%s.\n", vbs[i].name);
+ badr=vbs[i].badr;
+ break;
}
-
- if (vendor==PCI_VENDOR_ID_DEC)
- if (device==PCI_DEVICE_ID_DEC_TGA)
+ }
+ if (!badr)
+ {
+ printk(KERN_ERR "bttv: Unknown video memory base address.\n");
+ continue;
+ }
+ pci_read_config_dword(dev, badr, &vidadr);
+ if (vidadr & PCI_BASE_ADDRESS_SPACE_IO)
+ {
+ printk(KERN_ERR "bttv: Memory seems to be I/O memory.\n");
+ printk(KERN_ERR "bttv: Check entry for your card type in bttv.c vidbases struct.\n");
+ continue;
+ }
+ vidadr &= PCI_BASE_ADDRESS_MEM_MASK;
+ if (!vidadr)
+ {
+ printk(KERN_ERR "bttv: Memory @ 0, must be something wrong!");
+ continue;
+ }
+
+ if (dev->vendor == PCI_VENDOR_ID_DEC &&
+ dev->device == PCI_DEVICE_ID_DEC_TGA)
+ {
+ tga_type = (readl((unsigned long)vidadr) >> 12) & 0x0f;
+ if (tga_type != 0 && tga_type != 1 && tga_type != 3)
{
- tga_type = (readl((unsigned long)vidadr) >> 12) & 0x0f;
- if (tga_type != 0 && tga_type != 1 && tga_type != 3)
- {
- printk(KERN_ERR "bttv: TGA type (0x%x) unrecognized!\n", tga_type);
- found--;
- }
- vidadr+=dec_offsets[tga_type];
+ printk(KERN_ERR "bttv: TGA type (0x%x) unrecognized!\n", tga_type);
+ found--;
}
-
- DEBUG(printk(KERN_DEBUG "bttv: memory @ 0x%08x, ", vidadr));
- DEBUG(printk(KERN_DEBUG "devfn: 0x%04x.\n", devfn));
- found++;
+ vidadr+=dec_offsets[tga_type];
}
+ DEBUG(printk(KERN_DEBUG "bttv: memory @ 0x%08x, ", vidadr));
+ DEBUG(printk(KERN_DEBUG "devfn: 0x%04x.\n", dev->devfn));
+ found++;
}
if (vidmem)
@@ -2086,79 +2287,77 @@ static int find_vga(void)
static void handle_chipset(void)
{
- int index;
+ struct pci_dev *dev = NULL;
/* Just in case some nut set this to something dangerous */
if (triton1)
triton1=BT848_INT_ETBF;
- for (index = 0; index < 8; index++)
+ while ((dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, dev)))
{
- unsigned char bus, devfn;
- unsigned char b;
-
/* Beware the SiS 85C496 my friend - rev 49 don't work with a bttv */
-
- if (!pcibios_find_device(PCI_VENDOR_ID_SI,
- PCI_DEVICE_ID_SI_496,
- index, &bus, &devfn))
- {
- printk(KERN_WARNING "BT848 and SIS 85C496 chipset don't always work together.\n");
- }
+ printk(KERN_WARNING "BT848 and SIS 85C496 chipset don't always work together.\n");
+ }
- if (!pcibios_find_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82441,
- index, &bus, &devfn))
- {
- pcibios_read_config_byte(bus, devfn, 0x53, &b);
- DEBUG(printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, "));
- DEBUG(printk("bufcon=0x%02x\n",b));
- }
+ /* dev == NULL */
- if (!pcibios_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437,
- index, &bus, &devfn))
- {
- printk(KERN_INFO "bttv: Host bridge 82437FX Triton PIIX\n");
- triton1=BT848_INT_ETBF;
-
-#if 0
- /* The ETBF bit SHOULD make all this unnecessary */
- /* 430FX (Triton I) freezes with bus concurrency on -> switch it off */
- {
- unsigned char bo;
+ while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, dev)))
+ {
+ unsigned char b;
+ pci_read_config_byte(dev, 0x53, &b);
+ DEBUG(printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, "));
+ DEBUG(printk("bufcon=0x%02x\n",b));
+ }
- pcibios_read_config_byte(bus, devfn, TRITON_PCON, &b);
- bo=b;
- DEBUG(printk(KERN_DEBUG "bttv: 82437FX: PCON: 0x%x\n",b));
+ while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, dev)))
+ {
+/* unsigned char b;
+ unsigned char bo;*/
- if(!(b & TRITON_BUS_CONCURRENCY))
- {
- printk(KERN_WARNING "bttv: 82437FX: disabling bus concurrency\n");
- b |= TRITON_BUS_CONCURRENCY;
- }
+ printk(KERN_INFO "bttv: Host bridge 82437FX Triton PIIX\n");
+ triton1=BT848_INT_ETBF;
+
+#if 0
+ /* The ETBF bit SHOULD make all this unnecessary */
+ /* 430FX (Triton I) freezes with bus concurrency on -> switch it off */
- if(b & TRITON_PEER_CONCURRENCY)
- {
- printk(KERN_WARNING "bttv: 82437FX: disabling peer concurrency\n");
- b &= ~TRITON_PEER_CONCURRENCY;
- }
- if(!(b & TRITON_STREAMING))
- {
- printk(KERN_WARNING "bttv: 82437FX: disabling streaming\n");
- b |= TRITON_STREAMING;
- }
+ pci_read_config_byte(dev, TRITON_PCON, &b);
+ bo=b;
+ DEBUG(printk(KERN_DEBUG "bttv: 82437FX: PCON: 0x%x\n",b));
+ if(!(b & TRITON_BUS_CONCURRENCY))
+ {
+ printk(KERN_WARNING "bttv: 82437FX: disabling bus concurrency\n");
+ b |= TRITON_BUS_CONCURRENCY;
+ }
+ if(b & TRITON_PEER_CONCURRENCY)
+ {
+ printk(KERN_WARNING "bttv: 82437FX: disabling peer concurrency\n");
+ b &= ~TRITON_PEER_CONCURRENCY;
+ }
+ if(!(b & TRITON_STREAMING))
+ {
+ printk(KERN_WARNING "bttv: 82437FX: disabling streaming\n");
+ b |= TRITON_STREAMING;
+ }
- if (b!=bo)
- {
- pcibios_write_config_byte(bus, devfn, TRITON_PCON, b);
- printk(KERN_DEBUG "bttv: 82437FX: PCON changed to: 0x%x\n",b);
- }
- }
-#endif
+ if (b!=bo)
+ {
+ pci_write_config_byte(dev, TRITON_PCON, b);
+ printk(KERN_DEBUG "bttv: 82437FX: PCON changed to: 0x%x\n",b);
}
+#endif
}
}
+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 */
+ I2CWrite(bus, I2C_TDA8425, TDA8425_TR, 0xF6, 1); /* treble 0dB */
+ I2CWrite(bus, I2C_TDA8425, TDA8425_S1, 0xCE, 1); /* mute off */
+}
+
static void init_tda9850(struct i2c_bus *bus)
{
@@ -2177,13 +2376,13 @@ static void init_tda9850(struct i2c_bus *bus)
static void idcard(struct bttv *btv)
{
- int tunertype;
btwrite(0, BT848_GPIO_OUT_EN);
DEBUG(printk(KERN_DEBUG "bttv: GPIO: 0x%08x\n", btread(BT848_GPIO_DATA)));
/* Default the card to the user-selected one. */
btv->type=card;
-
+ btv->tuner_type=-1; /* use default tuner type */
+
/* If we were asked to auto-detect, then do so!
Right now this will only recognize Miro, Hauppauge or STB
*/
@@ -2196,12 +2395,34 @@ static void idcard(struct bttv *btv)
else
if (I2CRead(&(btv->i2c), I2C_STBEE)>=0)
btv->type=BTTV_STB;
+
+ if (btv->type == BTTV_MIRO) {
+ /* auto detect tuner for MIRO cards */
+ btv->tuner_type=((btread(BT848_GPIO_DATA)>>10)-1)&7;
+ }
}
- btv->dbx = I2CRead(&(btv->i2c), I2C_TDA9850) ? 0 : 1;
+ if (I2CRead(&(btv->i2c), I2C_TDA9850) >=0)
+ {
+ btv->audio_chip = TDA9850;
+ printk(KERN_INFO "bttv: audio chip: TDA9850\n");
+ }
- if (btv->dbx)
- init_tda9850(&(btv->i2c));
+ if (I2CRead(&(btv->i2c), I2C_TDA8425) >=0)
+ {
+ btv->audio_chip = TDA8425;
+ printk("bttv: audio chip: TDA8425\n");
+ }
+
+ switch(btv->audio_chip)
+ {
+ case TDA9850:
+ init_tda9850(&(btv->i2c));
+ 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: ");
@@ -2209,13 +2430,6 @@ static void idcard(struct bttv *btv)
{
case BTTV_MIRO:
printk("MIRO\n");
- if (btv->have_tuner)
- {
- tunertype=((btread(BT848_GPIO_DATA)>>10)-1)&7;
- i2c_control_device(&(btv->i2c),
- I2C_DRIVERID_TUNER,
- TUNER_SET_TYPE,&tunertype);
- }
strcpy(btv->video_dev.name,"BT848(Miro)");
break;
case BTTV_HAUPPAUGE:
@@ -2238,6 +2452,10 @@ static void idcard(struct bttv *btv)
printk("AVerMedia\n");
strcpy(btv->video_dev.name,"BT848(AVerMedia)");
break;
+ case BTTV_MATRIX_VISION:
+ printk("MATRIX-Vision\n");
+ strcpy(btv->video_dev.name,"BT848(MATRIX-Vision)");
+ break;
}
audio(btv, AUDIO_MUTE);
}
@@ -2288,7 +2506,7 @@ static void bt848_set_risc_jmps(struct bttv *btv)
btv->risc_jmp[12]=BT848_RISC_JUMP;
btv->risc_jmp[13]=virt_to_bus(btv->risc_jmp);
- /* enable cpaturing and DMA */
+ /* enable capturing and DMA */
btaor(flags, ~0x0f, BT848_CAP_CTL);
if (flags&0x0f)
bt848_dma(btv, 3);
@@ -2321,6 +2539,7 @@ static int init_bt848(int i)
btv->win.cropx=0;
btv->win.cropy=0;
btv->win.bpp=2;
+ btv->win.depth=16;
btv->win.color_fmt=BT848_COLOR_FMT_RGB16;
btv->win.bpl=1024*btv->win.bpp;
btv->win.swidth=1024;
@@ -2359,9 +2578,11 @@ static int init_bt848(int i)
btv->vbibuf=(unsigned char *) vmalloc(VBIBUF_SIZE);
if (!btv->vbibuf)
return -1;
- if (!(btv->grisc=(unsigned int *) kmalloc(16384, GFP_KERNEL)))
+ if (!(btv->grisc=(unsigned int *) kmalloc(32768, GFP_KERNEL)))
return -1;
+ memset(btv->vbibuf, 0, VBIBUF_SIZE); /* We don't want to return random
+ memory to the user */
btv->fbuffer=NULL;
bt848_muxsel(btv, 1);
@@ -2372,7 +2593,11 @@ static int init_bt848(int i)
btwrite(0x00, BT848_CAP_CTL);
btwrite(0xfc, BT848_GPIO_DMA_CTL);
- btwrite(0x0ff, BT848_VBI_PACK_SIZE);
+ /* select direct input */
+ btwrite(0x00, BT848_GPIO_REG_INP);
+
+
+ btwrite(0xff, BT848_VBI_PACK_SIZE);
btwrite(1, BT848_VBI_PACK_DEL);
@@ -2502,10 +2727,11 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
/* captured full frame */
if (stat&(2<<28))
{
- btv->grab++;
wake_up_interruptible(&btv->capq);
if ((--btv->grabbing))
{
+ btv->gro = btv->gro_next;
+ btv->gre = btv->gre_next;
btv->risc_jmp[5]=btv->gro;
btv->risc_jmp[11]=btv->gre;
bt848_set_geo(btv, btv->gwidth,
@@ -2517,6 +2743,7 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
btv->win.height,
btv->win.color_fmt);
}
+ wake_up_interruptible(&btv->capq);
break;
}
if (stat&(8<<28))
@@ -2588,30 +2815,29 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
static int find_bt848(void)
{
- short pci_index;
unsigned char command, latency;
int result;
- unsigned char bus, devfn;
struct bttv *btv;
+ struct pci_dev *dev;
bttv_num=0;
if (!pcibios_present())
{
- DEBUG(printk(KERN_DEBUG "bttv: PCI-BIOS not present or not accessable!\n"));
+ DEBUG(printk(KERN_DEBUG "bttv: PCI-BIOS not present or not accessible!\n"));
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)
+ for (dev = pci_devices; dev != NULL; dev = dev->next)
{
+ if (dev->vendor != PCI_VENDOR_ID_BROOKTREE)
+ continue;
+ if (dev->device != PCI_DEVICE_ID_BT849 &&
+ dev->device != PCI_DEVICE_ID_BT848)
+ continue;
+
+ /* Ok, Bt848 or Bt849 found! */
btv=&bttvs[bttv_num];
- btv->bus=bus;
- btv->devfn=devfn;
+ btv->dev=dev;
btv->bt848_mem=NULL;
btv->vbibuf=NULL;
btv->risc_jmp=NULL;
@@ -2624,12 +2850,10 @@ static int find_bt848(void)
btv->vbip=VBIBUF_SIZE;
- pcibios_read_config_word(btv->bus, btv->devfn, PCI_DEVICE_ID,
- &btv->id);
- pcibios_read_config_byte(btv->bus, btv->devfn,
- PCI_INTERRUPT_LINE, &btv->irq);
- pcibios_read_config_dword(btv->bus, btv->devfn, PCI_BASE_ADDRESS_0,
- &btv->bt848_adr);
+ pci_read_config_word (btv->dev, PCI_DEVICE_ID, &btv->id);
+
+ /* pci_read_config_dword(btv->dev, PCI_BASE_ADDRESS_0, &btv->bt848_adr); */
+ btv->bt848_adr = btv->dev->base_address[0];
if (remap&&(!bttv_num))
{
@@ -2637,25 +2861,33 @@ static int find_bt848(void)
remap&=PCI_BASE_ADDRESS_MEM_MASK;
printk(KERN_INFO "Remapping to : 0x%08x.\n", remap);
remap|=btv->bt848_adr&(~PCI_BASE_ADDRESS_MEM_MASK);
- pcibios_write_config_dword(btv->bus, btv->devfn, PCI_BASE_ADDRESS_0,
- remap);
- pcibios_read_config_dword(btv->bus, btv->devfn, PCI_BASE_ADDRESS_0,
- &btv->bt848_adr);
+ pci_write_config_dword(btv->dev, PCI_BASE_ADDRESS_0, remap);
+ pci_read_config_dword(btv->dev, PCI_BASE_ADDRESS_0, &btv->bt848_adr);
+ btv->dev->base_address[0] = btv->bt848_adr;
}
btv->bt848_adr&=PCI_BASE_ADDRESS_MEM_MASK;
- pcibios_read_config_byte(btv->bus, btv->devfn, PCI_CLASS_REVISION,
+ pci_read_config_byte(btv->dev, PCI_CLASS_REVISION,
&btv->revision);
printk(KERN_INFO "bttv: Brooktree Bt%d (rev %d) ",
- btv->id, btv->revision);
+ btv->id, btv->revision);
printk("bus: %d, devfn: %d, ",
- btv->bus, btv->devfn);
- printk("irq: %d, ",btv->irq);
+ btv->dev->bus->number, btv->dev->devfn);
+ printk("irq: %d, ",btv->dev->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))
+ {
+ printk(KERN_INFO "bttv: internal PLL, single crystal operation enabled.\n");
+ btv->pll=1;
+ }
+#endif
+
btv->bt848_mem=ioremap(btv->bt848_adr, 0x1000);
- result = request_irq(btv->irq, bttv_irq,
+ result = request_irq(btv->dev->irq, bttv_irq,
SA_SHIRQ | SA_INTERRUPT,"bttv",(void *)btv);
if (result==-EINVAL)
{
@@ -2664,29 +2896,27 @@ static int find_bt848(void)
}
if (result==-EBUSY)
{
- printk(KERN_ERR "bttv: IRQ %d busy, change your PnP config in BIOS\n",btv->irq);
+ printk(KERN_ERR "bttv: IRQ %d busy, change your PnP config in BIOS\n",btv->dev->irq);
return result;
}
if (result < 0)
return result;
/* Enable bus-mastering */
- pcibios_read_config_byte(btv->bus, btv->devfn, PCI_COMMAND, &command);
+ pci_read_config_byte(btv->dev, PCI_COMMAND, &command);
command|=PCI_COMMAND_MASTER;
- pcibios_write_config_byte(btv->bus, btv->devfn, PCI_COMMAND, command);
- pcibios_read_config_byte(btv->bus, btv->devfn, PCI_COMMAND, &command);
+ pci_write_config_byte(btv->dev, PCI_COMMAND, command);
+ pci_read_config_byte(btv->dev, PCI_COMMAND, &command);
if (!(command&PCI_COMMAND_MASTER))
{
printk(KERN_ERR "bttv: PCI bus-mastering could not be enabled\n");
return -1;
}
- pcibios_read_config_byte(btv->bus, btv->devfn, PCI_LATENCY_TIMER,
- &latency);
+ pci_read_config_byte(btv->dev, PCI_LATENCY_TIMER, &latency);
if (!latency)
{
latency=32;
- pcibios_write_config_byte(btv->bus, btv->devfn,
- PCI_LATENCY_TIMER, latency);
+ pci_write_config_byte(btv->dev, PCI_LATENCY_TIMER, latency);
}
DEBUG(printk(KERN_DEBUG "bttv: latency: %02x\n", latency));
bttv_num++;
@@ -2720,9 +2950,10 @@ static void release_bttv(void)
i2c_unregister_bus((&btv->i2c));
/* disable PCI bus-mastering */
- pcibios_read_config_byte(btv->bus, btv->devfn, PCI_COMMAND, &command);
- command|=PCI_COMMAND_MASTER;
- pcibios_write_config_byte(btv->bus, btv->devfn, PCI_COMMAND, command);
+ pci_read_config_byte(btv->dev, PCI_COMMAND, &command);
+ /* Should this be &=~ ?? */
+ command|=PCI_COMMAND_MASTER;
+ pci_write_config_byte(btv->dev, PCI_COMMAND, command);
/* unmap and free memory */
if (btv->grisc)
@@ -2743,7 +2974,7 @@ static void release_bttv(void)
vfree((void *) btv->vbibuf);
- free_irq(btv->irq,btv);
+ free_irq(btv->dev->irq,btv);
DEBUG(printk(KERN_DEBUG "bt848_mem: 0x%08x.\n", btv->bt848_mem));
if (btv->bt848_mem)
iounmap(btv->bt848_mem);