diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-08-25 09:12:35 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-08-25 09:12:35 +0000 |
commit | c7fc24dc4420057f103afe8fc64524ebc25c5d37 (patch) | |
tree | 3682407a599b8f9f03fc096298134cafba1c9b2f /drivers/char/bttv.c | |
parent | 1d793fade8b063fde3cf275bf1a5c2d381292cd9 (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.c | 775 |
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); |