patch-2.4.21 linux-2.4.21/drivers/media/video/bttv-driver.c
Next file: linux-2.4.21/drivers/media/video/bttv-if.c
Previous file: linux-2.4.21/drivers/media/video/bttv-cards.c
Back to the patch index
Back to the overall index
- Lines: 1151
- Date:
2003-06-13 07:51:34.000000000 -0700
- Orig file:
linux-2.4.20/drivers/media/video/bttv-driver.c
- Orig date:
2002-11-28 15:53:13.000000000 -0800
diff -urN linux-2.4.20/drivers/media/video/bttv-driver.c linux-2.4.21/drivers/media/video/bttv-driver.c
@@ -3,7 +3,7 @@
Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
& Marcus Metzler (mocm@thp.uni-koeln.de)
- (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
+ (c) 1999-2003 Gerd Knorr <kraxel@goldbach.in-berlin.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -52,9 +52,12 @@
#define MIN(a,b) (((a)>(b))?(b):(a))
#define MAX(a,b) (((a)>(b))?(a):(b))
+/* fwd decl */
static void bt848_set_risc_jmps(struct bttv *btv, int state);
+static void make_vbitab(struct bttv *btv);
+static void bt848_set_winsize(struct bttv *btv);
-int bttv_num; /* number of Bt848s in use */
+unsigned int bttv_num; /* number of Bt848s in use */
struct bttv bttvs[BTTV_MAX];
/* configuration variables */
@@ -65,10 +68,10 @@
#endif
static unsigned int radio[BTTV_MAX];
static unsigned int fieldnr = 0;
+static unsigned int gpint = 1;
static unsigned int irq_debug = 0;
static unsigned int gbuffers = 4;
static unsigned int gbufsize = BTTV_MAX_FBUF;
-static int latency = -1;
static unsigned int combfilter = 0;
static unsigned int lumafilter = 0;
@@ -101,8 +104,7 @@
MODULE_PARM_DESC(gbuffers,"number of capture buffers, default is 2 (64 max)");
MODULE_PARM(gbufsize,"i");
MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000");
-MODULE_PARM(latency,"i");
-MODULE_PARM_DESC(latency,"pci latency timer");
+MODULE_PARM(gpint,"i");
MODULE_PARM(combfilter,"i");
MODULE_PARM(lumafilter,"i");
@@ -327,78 +329,75 @@
btwrite(fi|BT848_PLL_X, BT848_PLL_XCI);
}
-static int set_pll(struct bttv *btv)
+static void set_pll(struct bttv *btv)
{
int i;
- unsigned long tv;
if (!btv->pll.pll_crystal)
- return 0;
+ return;
+
+ if (btv->pll.pll_ofreq == btv->pll.pll_current) {
+ dprintk("bttv%d: PLL: no change required\n",btv->nr);
+ return;
+ }
if (btv->pll.pll_ifreq == btv->pll.pll_ofreq) {
/* no PLL needed */
- if (btv->pll.pll_current == 0) {
- /* printk ("bttv%d: PLL: is off\n",btv->nr); */
- return 0;
- }
- if (bttv_verbose)
- printk ("bttv%d: PLL: switching off\n",btv->nr);
+ if (btv->pll.pll_current == 0)
+ return;
+ vprintk(KERN_INFO "bttv%d: PLL can sleep, using XTAL (%d).\n",
+ btv->nr,btv->pll.pll_ifreq);
btwrite(0x00,BT848_TGCTRL);
btwrite(0x00,BT848_PLL_XCI);
btv->pll.pll_current = 0;
- return 0;
- }
-
- if (btv->pll.pll_ofreq == btv->pll.pll_current) {
- /* printk("bttv%d: PLL: no change required\n",btv->nr); */
- return 1;
+ return;
}
- if (bttv_verbose)
- printk("bttv%d: PLL: %d => %d ... ",btv->nr,
- btv->pll.pll_ifreq, btv->pll.pll_ofreq);
-
+ vprintk(KERN_INFO "bttv%d: PLL: %d => %d ",btv->nr,
+ btv->pll.pll_ifreq, btv->pll.pll_ofreq);
set_pll_freq(btv, btv->pll.pll_ifreq, btv->pll.pll_ofreq);
- /* Let other people run while the PLL stabilizes */
- tv=jiffies+HZ/10; /* .1 seconds */
- do
- {
- schedule();
- }
- while(time_before(jiffies,tv));
-
- for (i=0; i<100; i++)
- {
- if ((btread(BT848_DSTATUS)&BT848_DSTATUS_PLOCK))
- btwrite(0,BT848_DSTATUS);
- else
- {
+ for (i=0; i<10; i++) {
+ /* Let other people run while the PLL stabilizes */
+ vprintk(".");
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(HZ/10);
+
+ if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) {
+ btwrite(0,BT848_DSTATUS);
+ } else {
btwrite(0x08,BT848_TGCTRL);
btv->pll.pll_current = btv->pll.pll_ofreq;
- if (bttv_verbose)
- printk("ok\n");
- return 1;
+ vprintk(" ok\n");
+ return;
}
- mdelay(10);
}
- btv->pll.pll_current = 0;
- if (bttv_verbose)
- printk("oops\n");
- return -1;
+ btv->pll.pll_current = -1;
+ vprintk("failed\n");
+ return;
}
static void bt848_muxsel(struct bttv *btv, unsigned int input)
{
+ dprintk("bttv%d: bt848_muxsel %d\n",btv->nr,input);
+
+ if (bttv_tvcards[btv->type].muxsel[input] < 0) {
+ dprintk("bttv%d: digital ccir muxsel\n", btv->nr);
+ btv->channel = input;
+ return;
+ }
+
/* needed by RemoteVideo MX */
if (bttv_tvcards[btv->type].gpiomask2)
btaor(bttv_tvcards[btv->type].gpiomask2,
~bttv_tvcards[btv->type].gpiomask2,
BT848_GPIO_OUT_EN);
+#if 0
/* This seems to get rid of some synchronization problems */
btand(~(3<<5), BT848_IFORM);
mdelay(10);
+#endif
input %= bttv_tvcards[btv->type].video_inputs;
if (input==bttv_tvcards[btv->type].svhs)
@@ -428,8 +427,42 @@
if (bttv_gpio)
bttv_gpio_tracking(btv,"muxsel");
+ btv->channel=input;
}
+/* special timing tables from conexant... */
+static u8 SRAM_Table[][60] =
+{
+ /* PAL digital input over GPIO[7:0] */
+ {
+ 45, // 45 bytes following
+ 0x36,0x11,0x01,0x00,0x90,0x02,0x05,0x10,0x04,0x16,
+ 0x12,0x05,0x11,0x00,0x04,0x12,0xC0,0x00,0x31,0x00,
+ 0x06,0x51,0x08,0x03,0x89,0x08,0x07,0xC0,0x44,0x00,
+ 0x81,0x01,0x01,0xA9,0x0D,0x02,0x02,0x50,0x03,0x37,
+ 0x37,0x00,0xAF,0x21,0x00
+ },
+ /* NTSC digital input over GPIO[7:0] */
+ {
+ 51, // 51 bytes following
+ 0x0C,0xC0,0x00,0x00,0x90,0x02,0x03,0x10,0x03,0x06,
+ 0x10,0x04,0x12,0x12,0x05,0x02,0x13,0x04,0x19,0x00,
+ 0x04,0x39,0x00,0x06,0x59,0x08,0x03,0x83,0x08,0x07,
+ 0x03,0x50,0x00,0xC0,0x40,0x00,0x86,0x01,0x01,0xA6,
+ 0x0D,0x02,0x03,0x11,0x01,0x05,0x37,0x00,0xAC,0x21,
+ 0x00,
+ },
+ // TGB_NTSC392 // quartzsight
+ // This table has been modified to be used for Fusion Rev D
+ {
+ 0x2A, // size of table = 42
+ 0x06, 0x08, 0x04, 0x0a, 0xc0, 0x00, 0x18, 0x08, 0x03, 0x24,
+ 0x08, 0x07, 0x02, 0x90, 0x02, 0x08, 0x10, 0x04, 0x0c, 0x10,
+ 0x05, 0x2c, 0x11, 0x04, 0x55, 0x48, 0x00, 0x05, 0x50, 0x00,
+ 0xbf, 0x0c, 0x02, 0x2f, 0x3d, 0x00, 0x2f, 0x3f, 0x00, 0xc3,
+ 0x20, 0x00
+ }
+};
struct tvnorm
{
@@ -441,57 +474,209 @@
u16 hdelayx1, hactivex1;
u16 vdelay;
u8 vbipack;
+ int sram; /* index into SRAM_Table */
};
static struct tvnorm tvnorms[] = {
/* PAL-BDGHI */
/* max. active video is actually 922, but 924 is divisible by 4 and 3! */
/* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */
- { 35468950,
- 924, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
- 1135, 186, 924,
+ {
+ .Fsc = 35468950,
+ .swidth = 924,
+ .sheight = 576,
+ .totalwidth = 1135,
+ .adelay = 0x7f,
+ .bdelay = 0x72,
+ .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
+ .scaledtwidth = 1135,
+ .hdelayx1 = 186,
+ .hactivex1 = 924,
#ifdef VIDEODAT_HACK
- VBI_MAXLINES*2,
+ .vdelay = VBI_MAXLINES*2,
#else
- 0x20,
+ .vdelay = 0x20,
#endif
- 255},
+ .vbipack = 255,
+ .sram = 0,
+ },{
+ /* NTSC */
+ .Fsc = 28636363,
+ .swidth = 768,
+ .sheight = 480,
+ .totalwidth = 910,
+ .adelay = 0x68,
+ .bdelay = 0x5d,
+ .iform = (BT848_IFORM_NTSC|BT848_IFORM_XT0),
+ .scaledtwidth = 910,
+ .hdelayx1 = 128,
+ .hactivex1 = 910,
+ .vdelay = 0x1a,
+ .vbipack = 144,
+ .sram = 1,
+ },{
+ /* SECAM L */
+ .Fsc = 35468950,
+ .swidth = 924,
+ .sheight = 576,
+ .totalwidth = 1135,
+ .adelay = 0x7f,
+ .bdelay = 0xb0,
+ .iform = (BT848_IFORM_SECAM|BT848_IFORM_XT1),
+ .scaledtwidth = 1135,
+ .hdelayx1 = 186,
+ .hactivex1 = 922,
+ .vdelay = 0x20,
+ .vbipack = 255,
+ .sram = 0, /* like PAL, correct? */
+ },{
+ /* PAL-NC */
+ .Fsc = 28636363,
+ .swidth = 640,
+ .sheight = 576,
+ .totalwidth = 910,
+ .adelay = 0x68,
+ .bdelay = 0x5d,
+ .iform = (BT848_IFORM_PAL_NC|BT848_IFORM_XT0),
+ .scaledtwidth = 780,
+ .hdelayx1 = 130,
+ .hactivex1 = 734,
+ .vdelay = 0x1a,
+ .vbipack = 144,
+ .sram = -1,
+ },{
+ /* PAL-M */
+ .Fsc = 28636363,
+ .swidth = 640,
+ .sheight = 480,
+ .totalwidth = 910,
+ .adelay = 0x68,
+ .bdelay = 0x5d,
+ .iform = (BT848_IFORM_PAL_M|BT848_IFORM_XT0),
+ .scaledtwidth = 780,
+ .hdelayx1 = 135,
+ .hactivex1 = 754,
+ .vdelay = 0x1a,
+ .vbipack = 144,
+ .sram = -1,
+ },{
+ /* PAL-N */
+ .Fsc 35468950,
+ .swidth = 768,
+ .sheight = 576,
+ .totalwidth = 1135,
+ .adelay = 0x7f,
+ .bdelay = 0x72,
+ .iform = (BT848_IFORM_PAL_N|BT848_IFORM_XT1),
+ .scaledtwidth = 944,
+ .hdelayx1 = 186,
+ .hactivex1 = 922,
+ .vdelay = 0x20,
+ .vbipack = 144,
+ .sram = -1,
+ },{
+ /* NTSC-Japan */
+ .Fsc = 28636363,
+ .swidth = 640,
+ .sheight = 480,
+ .totalwidth = 910,
+ .adelay = 0x68,
+ .bdelay = 0x5d,
+ .iform = (BT848_IFORM_NTSC_J|BT848_IFORM_XT0),
+ .scaledtwidth = 780,
+ .hdelayx1 = 135,
+ .hactivex1 = 754,
+ .vdelay = 0x16,
+ .vbipack = 144,
+ .sram = -1,
+ },{
+ /* Quartzsight digital camera
+ * From Bt832 datasheet: 393x304 pixel @30Hz,
+ * Visible: 352x288 pixel
+ */
+ .Fsc = 27000000,
+ .swidth = 352,
+ .sheight = 576, //2*288 ?
+ .totalwidth = 392,
+ .adelay = 0x68,
+ .bdelay = 0x5d,
+ .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
+ .scaledtwidth = 392,
+ .hdelayx1 = 0x20,
+ .hactivex1 = 352,
+ .vdelay = 0x08,
+ .vbipack = 0, //255
+ .sram = 2,
+ }
+};
+#define TVNORMS (sizeof(tvnorms)/sizeof(struct tvnorm))
+
+/* used to switch between the bt848's analog/digital video capture modes */
+void bt848A_set_timing(struct bttv *btv)
+{
+ int i, len;
+ int table_idx = tvnorms[btv->win.norm].sram;
+ int fsc = tvnorms[btv->win.norm].Fsc;
+
+ if (bttv_tvcards[btv->type].muxsel[btv->channel] < 0) {
+ dprintk("bttv%d: load digital timing table (table_idx=%d)\n",
+ btv->nr,table_idx);
+
+ /* timing change...reset timing generator address */
+ btwrite(0x00, BT848_TGCTRL);
+ btwrite(0x02, BT848_TGCTRL);
+ btwrite(0x00, BT848_TGCTRL);
+
+ len=SRAM_Table[table_idx][0];
+ for(i = 1; i <= len; i++)
+ btwrite(SRAM_Table[table_idx][i],BT848_TGLB);
+ btv->pll.pll_ofreq = 27000000;
+
+ set_pll(btv);
+ btwrite(0x11, BT848_TGCTRL);
+ btwrite(0x41, BT848_DVSIF);
+ } else {
+ btv->pll.pll_ofreq = fsc;
+ set_pll(btv);
+ btwrite(0x0, BT848_DVSIF);
+ }
+}
+
+static void bttv_set_norm(struct bttv *btv, int new_norm)
+{
+ unsigned long irq_flags;
- /* NTSC */
- { 28636363,
- 768, 480, 910, 0x68, 0x5d, (BT848_IFORM_NTSC|BT848_IFORM_XT0),
- 910, 128, 910, 0x1a, 144},
+ if (bttv_tvcards[btv->type].muxsel[btv->channel] < 0 &&
+ bttv_tvcards[btv->type].digital_mode == DIGITAL_MODE_CAMERA) {
+ //override norm by quartzsight mode
+ new_norm=7;
+ dprintk("bttv%d: set_norm fix-up digital: %d\n",
+ btv->nr, new_norm);
+ }
+
+ if (btv->win.norm != new_norm) {
+ btv->win.norm = new_norm;
+
+ make_vbitab(btv);
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
+ bt848_set_winsize(btv);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
+
+ bt848A_set_timing(btv);
+ switch (btv->type) {
+ case BTTV_VOODOOTV_FM:
+ bttv_tda9880_setnorm(btv,new_norm);
+ break;
#if 0
- /* SECAM EAST */
- { 35468950,
- 768, 576, 1135, 0x7f, 0xb0, (BT848_IFORM_SECAM|BT848_IFORM_XT1),
- 944, 186, 922, 0x20, 255},
-#else
- /* SECAM L */
- { 35468950,
- 924, 576, 1135, 0x7f, 0xb0, (BT848_IFORM_SECAM|BT848_IFORM_XT1),
- 1135, 186, 922, 0x20, 255},
+ case BTTV_OSPREY540:
+ osprey_540_set_norm(btv,new_norm);
+ break;
#endif
- /* PAL-NC */
- { 28636363,
- 640, 576, 910, 0x68, 0x5d, (BT848_IFORM_PAL_NC|BT848_IFORM_XT0),
- 780, 130, 734, 0x1a, 144},
- /* PAL-M */
- { 28636363,
- 640, 480, 910, 0x68, 0x5d, (BT848_IFORM_PAL_M|BT848_IFORM_XT0),
- 780, 135, 754, 0x1a, 144},
- /* PAL-N */
- { 35468950,
- 768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_N|BT848_IFORM_XT1),
- 944, 186, 922, 0x20, 144},
- /* NTSC-Japan */
- { 28636363,
- 640, 480, 910, 0x68, 0x5d, (BT848_IFORM_NTSC_J|BT848_IFORM_XT0),
- 780, 135, 754, 0x16, 144},
-};
-#define TVNORMS (sizeof(tvnorms)/sizeof(tvnorm))
-#define VBI_SPL 2044
+ }
+ }
+}
+#define VBI_SPL 2044
/* RISC command to write one VBI data line */
#define VBI_RISC BT848_RISC_WRITE|VBI_SPL|BT848_RISC_EOL|BT848_RISC_SOL
@@ -506,8 +691,7 @@
btv->nr,virt_to_bus(po), virt_to_bus(pe));
*(po++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(po++)=0;
- for (i=0; i<VBI_MAXLINES; i++)
- {
+ for (i=0; i<VBI_MAXLINES; i++) {
*(po++)=cpu_to_le32(VBI_RISC);
*(po++)=cpu_to_le32(kvirt_to_bus((unsigned long)btv->vbibuf+i*2048));
}
@@ -515,8 +699,7 @@
*(po++)=cpu_to_le32(virt_to_bus(btv->risc_jmp+4));
*(pe++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(pe++)=0;
- for (i=VBI_MAXLINES; i<VBI_MAXLINES*2; i++)
- {
+ for (i=VBI_MAXLINES; i<VBI_MAXLINES*2; i++) {
*(pe++)=cpu_to_le32(VBI_RISC);
*(pe++)=cpu_to_le32(kvirt_to_bus((unsigned long)btv->vbibuf+i*2048));
}
@@ -528,12 +711,12 @@
btv->nr,virt_to_bus(po), virt_to_bus(pe));
}
-static int fmtbppx2[16] = {
+static unsigned int fmtbppx2[16] = {
8, 6, 4, 4, 4, 3, 2, 2, 4, 3, 0, 0, 0, 0, 2, 0
};
-static int palette2fmt[] = {
- 0,
+static unsigned int palette2fmt[] = {
+ UNSET,
BT848_COLOR_FMT_Y8,
BT848_COLOR_FMT_RGB8,
BT848_COLOR_FMT_RGB16,
@@ -542,29 +725,28 @@
BT848_COLOR_FMT_RGB15,
BT848_COLOR_FMT_YUY2,
BT848_COLOR_FMT_YUY2,
- -1,
- -1,
- -1,
+ UNSET,
+ UNSET,
+ UNSET,
BT848_COLOR_FMT_RAW,
BT848_COLOR_FMT_YCrCb422,
BT848_COLOR_FMT_YCrCb411,
BT848_COLOR_FMT_YCrCb422,
BT848_COLOR_FMT_YCrCb411,
};
-#define PALETTEFMT_MAX (sizeof(palette2fmt)/sizeof(int))
+#define PALETTEFMT_MAX (sizeof(palette2fmt)/sizeof(palette2fmt[0]))
-static int make_rawrisctab(struct bttv *btv, unsigned int *ro,
- unsigned int *re, unsigned int *vbuf)
+static int make_rawrisctab(struct bttv *btv, u32 *ro, u32 *re, u32 *vbuf)
{
- unsigned long line;
- unsigned long bpl=1024; /* bytes per line */
+ u32 line;
+ u32 bpl=1024; /* bytes per line */
unsigned long vadr=(unsigned long) vbuf;
*(ro++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
*(ro++)=cpu_to_le32(0);
*(re++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
*(re++)=cpu_to_le32(0);
-
+
/* In PAL 650 blocks of 256 DWORDs are sampled, but only if VDELAY
is 2 and without separate VBI grabbing.
We'll have to handle this inside the IRQ handler ... */
@@ -586,19 +768,17 @@
return 0;
}
-static int make_prisctab(struct bttv *btv, unsigned int *ro,
- unsigned int *re,
- unsigned int *vbuf, unsigned short width,
- unsigned short height, unsigned short fmt)
+static int make_prisctab(struct bttv *btv, u32 *ro, u32 *re, u32 *vbuf,
+ u16 width, u16 height, u16 fmt)
{
- unsigned long line, lmask;
- unsigned long bl, blcr, blcb, rcmd;
- unsigned long todo;
- unsigned int **rp;
+ u16 line, lmask;
+ u32 bl, blcr, blcb, rcmd;
+ u32 todo;
+ u32 **rp;
int inter;
- unsigned long cbadr, cradr;
+ u32 cbadr, cradr;
unsigned long vadr=(unsigned long) vbuf;
- int shift, csize;
+ u32 shift, csize;
if (bttv_debug > 1)
printk("bttv%d: prisc1: ro=%08lx re=%08lx\n",
@@ -680,7 +860,7 @@
*((*rp)++)=cpu_to_le32(blcb|(blcr<<16));
*((*rp)++)=cpu_to_le32(kvirt_to_bus(vadr));
vadr+=bl;
- if((rcmd&(15<<28))==BT848_RISC_WRITE123)
+ if ((rcmd&(15<<28))==BT848_RISC_WRITE123)
{
*((*rp)++)=cpu_to_le32(kvirt_to_bus(cbadr));
cbadr+=blcb;
@@ -703,25 +883,22 @@
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 palette)
-{
- unsigned long line;
- unsigned long bpl; /* bytes per line */
- unsigned long bl;
- unsigned long todo;
- unsigned int **rp;
+
+static int make_vrisctab(struct bttv *btv, u32 *ro, u32 *re, u32 *vbuf,
+ u16 width, u16 height, u16 palette)
+{
+ u16 line;
+ u32 bpl; /* bytes per line */
+ u32 bl;
+ u32 todo;
+ u32 **rp;
int inter;
- unsigned long vadr=(unsigned long) vbuf;
+ unsigned long vadr=(unsigned long)vbuf;
if (palette==VIDEO_PALETTE_RAW)
return make_rawrisctab(btv, ro, re, vbuf);
if (palette>=VIDEO_PALETTE_PLANAR)
return make_prisctab(btv, ro, re, vbuf, width, height, palette);
-
if (bttv_debug > 1)
printk("bttv%d: vrisc1: ro=%08lx re=%08lx\n",
btv->nr,virt_to_bus(ro), virt_to_bus(re));
@@ -845,9 +1022,10 @@
static void make_clip_tab(struct bttv *btv, struct video_clip *cr, int ncr)
{
- int i, line, x, y, bpl, width, height, inter, maxw;
- unsigned int bpp, dx, sx, **rp, *ro, *re, flags, len;
- unsigned long adr;
+ u32 line, x, y, bpl, width, height, inter, maxw;
+ u32 bpp, dx, sx, **rp, *ro, *re, flags, len;
+ u32 adr;
+ int i;
unsigned char *clipmap, *clipline, cbit, lastbit, outofmem;
/* take care: bpp != btv->win.bpp is allowed here */
@@ -987,13 +1165,25 @@
u32 xsf, sr;
u16 hdelay;
u8 crop, vtc;
+
int inter = (height>tvn->sheight/2) ? 0 : 1;
int off = odd ? 0x80 : 0x00;
- xsf = (width*tvn->scaledtwidth)/tvn->swidth;
- hscale = ((tvn->totalwidth*4096UL)/xsf-4096);
+ int swidth = tvn->swidth;
+ int totalwidth = tvn->totalwidth;
+ int scaledtwidth = tvn->scaledtwidth;
+
+ if (bttv_tvcards[btv->type].muxsel[btv->channel] < 0) {
+ dprintk("bttv%d: DIGITAL_MODE_VIDEO override width\n",btv->nr);
+ swidth = 720;
+ totalwidth = 858;
+ scaledtwidth = 858;
+ }
+
+ xsf = (width*scaledtwidth)/swidth;
+ hscale = ((totalwidth*4096UL)/xsf-4096);
hdelay = tvn->hdelayx1;
- hdelay = (hdelay*width)/tvn->swidth;
+ hdelay = (hdelay*width)/swidth;
hdelay &= 0x3fe;
sr=((tvn->sheight>>inter)*512)/height-512;
vscale=(0x10000UL-sr)&0x1fff;
@@ -1038,7 +1228,10 @@
btwrite(tvn->bdelay, BT848_BDELAY);
btaor(tvn->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH), BT848_IFORM);
btwrite(tvn->vbipack, BT848_VBI_PACK_SIZE);
- btwrite(1, BT848_VBI_PACK_DEL);
+ if (bttv_tvcards[btv->type].muxsel[btv->channel] < 0)
+ btwrite(0x39, BT848_VBI_PACK_DEL);
+ else
+ btwrite(0x01, BT848_VBI_PACK_DEL);
btv->pll.pll_ofreq = tvn->Fsc;
if (!in_interrupt())
@@ -1142,8 +1335,8 @@
static int vgrab(struct bttv *btv, struct video_mmap *mp)
{
- unsigned int *ro, *re;
- unsigned int *vbuf;
+ u32 *ro, *re;
+ u32 *vbuf;
unsigned long flags;
if(btv->fbuffer==NULL)
@@ -1162,10 +1355,10 @@
if (mp->format >= PALETTEFMT_MAX)
return -EINVAL;
- if (mp->height*mp->width*fmtbppx2[palette2fmt[mp->format]&0x0f]/2
- > gbufsize)
+ if ((unsigned int)mp->height * mp->width *
+ fmtbppx2[palette2fmt[mp->format]&0x0f]/2 > gbufsize)
return -EINVAL;
- if (-1 == palette2fmt[mp->format])
+ if (UNSET == palette2fmt[mp->format])
return -EINVAL;
/*
@@ -1214,54 +1407,8 @@
static long bttv_read(struct video_device *v, char *buf, unsigned long count, int nonblock)
{
- struct bttv *btv= (struct bttv *)v;
- int q;
- unsigned long todo;
- DECLARE_WAITQUEUE(wait, current);
-
- /* BROKEN: RETURNS VBI WHEN IT SHOULD RETURN GRABBED VIDEO FRAME */
- todo=count;
- while (todo && todo>(q=VBIBUF_SIZE-btv->vbip))
- {
- if(copy_to_user((void *) buf, (void *) btv->vbibuf+btv->vbip, q))
- return -EFAULT;
- todo-=q;
- buf+=q;
-
- add_wait_queue(&btv->vbiq, &wait);
- current->state = TASK_INTERRUPTIBLE;
- if (todo && q==VBIBUF_SIZE-btv->vbip)
- {
- if(nonblock)
- {
- remove_wait_queue(&btv->vbiq, &wait);
- current->state = TASK_RUNNING;
- if(count==todo)
- return -EWOULDBLOCK;
- return count-todo;
- }
- schedule();
- if(signal_pending(current))
- {
- remove_wait_queue(&btv->vbiq, &wait);
- current->state = TASK_RUNNING;
-
- if(todo==count)
- return -EINTR;
- else
- return count-todo;
- }
- }
- remove_wait_queue(&btv->vbiq, &wait);
- current->state = TASK_RUNNING;
- }
- if (todo)
- {
- if(copy_to_user((void *) buf, (void *) btv->vbibuf+btv->vbip, todo))
- return -EFAULT;
- btv->vbip+=todo;
- }
- return count;
+ /* use bttv 0.9.x if you need capture via read() */
+ return -EINVAL;
}
static inline void burst(int on)
@@ -1281,7 +1428,7 @@
*/
static void bt848_offline(struct bttv *btv)
{
- int i;
+ unsigned int i;
spin_lock(&btv->s_lock);
/* cancel all outstanding grab requests */
@@ -1318,7 +1465,7 @@
BT848_RISC_STRT_ADD);
/* enforce pll reprogramming */
- btv->pll.pll_current = 0;
+ btv->pll.pll_current = -1;
set_pll(btv);
spin_lock_irqsave(&btv->s_lock, irq_flags);
@@ -1336,7 +1483,8 @@
static int bttv_open(struct video_device *dev, int flags)
{
struct bttv *btv = (struct bttv *)dev;
- int i,ret;
+ unsigned int i;
+ int ret;
ret = -EBUSY;
if (bttv_debug)
@@ -1472,7 +1620,7 @@
{
struct bttv *btv=(struct bttv *)dev;
unsigned long irq_flags;
- int i,ret = 0;
+ int ret = 0;
if (bttv_debug > 1)
printk("bttv%d: ioctl 0x%x\n",btv->nr,cmd);
@@ -1483,7 +1631,7 @@
struct video_capability b;
strcpy(b.name,btv->video_dev.name);
b.type = VID_TYPE_CAPTURE|
- ((bttv_tvcards[btv->type].tuner != -1) ? VID_TYPE_TUNER : 0) |
+ ((bttv_tvcards[btv->type].tuner != UNSET) ? VID_TYPE_TUNER : 0) |
VID_TYPE_OVERLAY|
VID_TYPE_CLIPPING|
VID_TYPE_FRAMERAM|
@@ -1501,23 +1649,28 @@
case VIDIOCGCHAN:
{
struct video_channel v;
+ unsigned int channel;
+
if(copy_from_user(&v, arg,sizeof(v)))
return -EFAULT;
+ channel = v.channel;
+ if (channel>=bttv_tvcards[btv->type].video_inputs)
+ return -EINVAL;
v.flags=VIDEO_VC_AUDIO;
v.tuners=0;
v.type=VIDEO_TYPE_CAMERA;
v.norm = btv->win.norm;
- if (v.channel>=bttv_tvcards[btv->type].video_inputs)
- return -EINVAL;
- if(v.channel==bttv_tvcards[btv->type].tuner)
+ if(channel==bttv_tvcards[btv->type].tuner)
{
strcpy(v.name,"Television");
v.flags|=VIDEO_VC_TUNER;
v.type=VIDEO_TYPE_TV;
v.tuners=1;
}
- else if(v.channel==bttv_tvcards[btv->type].svhs)
+ else if (channel==bttv_tvcards[btv->type].svhs)
strcpy(v.name,"S-Video");
+ else if (bttv_tvcards[btv->type].muxsel[v.channel] < 0)
+ strcpy(v.name,"Digital Video");
else
sprintf(v.name,"Composite%d",v.channel);
@@ -1531,27 +1684,21 @@
case VIDIOCSCHAN:
{
struct video_channel v;
+ unsigned int channel;
+
if(copy_from_user(&v, arg,sizeof(v)))
return -EFAULT;
+ channel = v.channel;
- if (v.channel>bttv_tvcards[btv->type].video_inputs)
+ if (channel>bttv_tvcards[btv->type].video_inputs)
return -EINVAL;
- if (v.norm > (sizeof(tvnorms)/sizeof(*tvnorms)))
+ if (v.norm > TVNORMS)
return -EOPNOTSUPP;
bttv_call_i2c_clients(btv,cmd,&v);
down(&btv->lock);
- bt848_muxsel(btv, v.channel);
- btv->channel=v.channel;
- if (btv->win.norm != v.norm) {
- if (btv->type == BTTV_VOODOOTV_FM)
- bttv_tda9880_setnorm(btv,v.norm);
- btv->win.norm = v.norm;
- make_vbitab(btv);
- spin_lock_irqsave(&btv->s_lock, irq_flags);
- bt848_set_winsize(btv);
- spin_unlock_irqrestore(&btv->s_lock, irq_flags);
- }
+ bt848_muxsel(btv, channel);
+ bttv_set_norm(btv, v.norm);
up(&btv->lock);
return 0;
}
@@ -1579,10 +1726,13 @@
case VIDIOCSTUNER:
{
struct video_tuner v;
+ unsigned int tuner;
+
if(copy_from_user(&v, arg, sizeof(v)))
return -EFAULT;
+ tuner = v.tuner;
/* Only one channel has a tuner */
- if(v.tuner!=bttv_tvcards[btv->type].tuner)
+ if(tuner!=bttv_tvcards[btv->type].tuner)
return -EINVAL;
if(v.mode!=VIDEO_MODE_PAL&&v.mode!=VIDEO_MODE_NTSC
@@ -1590,13 +1740,8 @@
return -EOPNOTSUPP;
bttv_call_i2c_clients(btv,cmd,&v);
if (btv->win.norm != v.mode) {
- btv->win.norm = v.mode;
down(&btv->lock);
- set_pll(btv);
- make_vbitab(btv);
- spin_lock_irqsave(&btv->s_lock, irq_flags);
- bt848_set_winsize(btv);
- spin_unlock_irqrestore(&btv->s_lock, irq_flags);
+ bttv_set_norm(btv,v.mode);
up(&btv->lock);
}
return 0;
@@ -1615,7 +1760,7 @@
return -EFAULT;
if (p.palette > PALETTEFMT_MAX)
return -EINVAL;
- if (-1 == palette2fmt[p.palette])
+ if (UNSET == palette2fmt[p.palette])
return -EINVAL;
down(&btv->lock);
/* We want -128 to 127 we get 0-65535 */
@@ -1845,17 +1990,16 @@
case VIDIOCSAUDIO:
{
struct video_audio v;
+ unsigned int n;
if(copy_from_user(&v,arg, sizeof(v)))
return -EFAULT;
+ n = v.audio;
+ if(n >= bttv_tvcards[btv->type].audio_inputs)
+ return -EINVAL;
down(&btv->lock);
if(v.flags&VIDEO_AUDIO_MUTE)
audio(btv, AUDIO_MUTE);
- /* One audio source per tuner -- huh? <GA> */
- if(v.audio<0 || v.audio >= bttv_tvcards[btv->type].audio_inputs) {
- up(&btv->lock);
- return -EINVAL;
- }
/* bt848_muxsel(btv,v.audio); */
if(!(v.flags&VIDEO_AUDIO_MUTE))
audio(btv, AUDIO_UNMUTE);
@@ -1874,10 +2018,11 @@
case VIDIOCSYNC:
{
DECLARE_WAITQUEUE(wait, current);
+ unsigned int i;
if(copy_from_user((void *)&i,arg,sizeof(int)))
return -EFAULT;
- if (i < 0 || i >= gbuffers)
+ if (i >= gbuffers)
return -EINVAL;
switch (btv->gbuf[i].stat) {
case GBUFFER_UNUSED:
@@ -1949,6 +2094,8 @@
case VIDIOCGMBUF:
{
struct video_mbuf vm;
+ unsigned int i;
+
memset(&vm, 0 , sizeof(vm));
vm.size=gbufsize*gbuffers;
vm.frames=gbuffers;
@@ -2050,17 +2197,17 @@
static struct video_device bttv_template=
{
- owner: THIS_MODULE,
- name: "UNSET",
- type: VID_TYPE_TUNER|VID_TYPE_CAPTURE|VID_TYPE_OVERLAY|VID_TYPE_TELETEXT,
- hardware: VID_HARDWARE_BT848,
- open: bttv_open,
- close: bttv_close,
- read: bttv_read,
- write: bttv_write,
- ioctl: bttv_ioctl,
- mmap: bttv_mmap,
- minor: -1,
+ .owner = THIS_MODULE,
+ .name = "UNSET",
+ .type = VID_TYPE_TUNER|VID_TYPE_CAPTURE|VID_TYPE_OVERLAY|VID_TYPE_TELETEXT,
+ .hardware = VID_HARDWARE_BT848,
+ .open = bttv_open,
+ .close = bttv_close,
+ .read = bttv_read,
+ .write = bttv_write,
+ .ioctl = bttv_ioctl,
+ .mmap = bttv_mmap,
+ .minor = -1,
};
@@ -2068,7 +2215,8 @@
int nonblock)
{
struct bttv *btv=(struct bttv *)(v-2);
- int q,todo;
+ unsigned long todo;
+ unsigned int q;
DECLARE_WAITQUEUE(wait, current);
todo=count;
@@ -2172,8 +2320,8 @@
{
struct video_capability b;
strcpy(b.name,btv->vbi_dev.name);
- b.type = ((bttv_tvcards[btv->type].tuner != -1) ? VID_TYPE_TUNER : 0) |
- VID_TYPE_TELETEXT;
+ b.type = ((bttv_tvcards[btv->type].tuner != UNSET) ? VID_TYPE_TUNER : 0)
+ | VID_TYPE_TELETEXT;
b.channels = 0;
b.audios = 0;
b.maxwidth = 0;
@@ -2202,17 +2350,17 @@
static struct video_device vbi_template=
{
- owner: THIS_MODULE,
- name: "bttv vbi",
- type: VID_TYPE_CAPTURE|VID_TYPE_TELETEXT,
- hardware: VID_HARDWARE_BT848,
- open: vbi_open,
- close: vbi_close,
- read: vbi_read,
- write: bttv_write,
- poll: vbi_poll,
- ioctl: vbi_ioctl,
- minor: -1,
+ .owner = THIS_MODULE,
+ .name = "bttv vbi",
+ .type = VID_TYPE_CAPTURE|VID_TYPE_TELETEXT,
+ .hardware = VID_HARDWARE_BT848,
+ .open = vbi_open,
+ .close = vbi_close,
+ .read = vbi_read,
+ .write = bttv_write,
+ .poll = vbi_poll,
+ .ioctl = vbi_ioctl,
+ .minor = -1,
};
@@ -2321,16 +2469,16 @@
static struct video_device radio_template=
{
- owner: THIS_MODULE,
- name: "bttv radio",
- type: VID_TYPE_TUNER,
- hardware: VID_HARDWARE_BT848,
- open: radio_open,
- close: radio_close,
- read: radio_read, /* just returns -EINVAL */
- write: bttv_write, /* just returns -EINVAL */
- ioctl: radio_ioctl,
- minor: -1,
+ .owner = THIS_MODULE,
+ .name = "bttv radio",
+ .type = VID_TYPE_TUNER,
+ .hardware = VID_HARDWARE_BT848,
+ .open = radio_open,
+ .close = radio_close,
+ .read = radio_read, /* just returns -EINVAL */
+ .write = bttv_write, /* just returns -EINVAL */
+ .ioctl = radio_ioctl,
+ .minor = -1,
};
@@ -2343,6 +2491,8 @@
flags |= 0x03;
if (btv->vbi_on)
flags |= 0x0c;
+ if (bttv_tvcards[btv->type].muxsel[btv->channel] < 0)
+ flags |= 0x0c;
#if 0
/* Hmm ... */
if ((0 != btv->risc_cap_even) ||
@@ -2472,7 +2622,8 @@
static int __devinit init_bt848(struct bttv *btv)
{
- int j,val;
+ int val;
+ unsigned int j;
unsigned long irq_flags;
btv->user=0;
@@ -2602,15 +2753,13 @@
btwrite(btv->triton1|
/*BT848_INT_PABORT|BT848_INT_RIPERR|BT848_INT_PPERR|
BT848_INT_FDSR|BT848_INT_FTRGT|BT848_INT_FBUS|*/
- (fieldnr ? BT848_INT_VSYNC : 0)|
- BT848_INT_GPINT|
+ (fieldnr ? BT848_INT_VSYNC : 0) |
+ (gpint ? BT848_INT_GPINT : 0) |
BT848_INT_SCERR|
BT848_INT_RISCI|BT848_INT_OCERR|BT848_INT_VPRES|
BT848_INT_FMTCHG|BT848_INT_HLOCK,
BT848_INT_MASK);
- bt848_muxsel(btv, 1);
- bt848_set_winsize(btv);
make_vbitab(btv);
spin_lock_irqsave(&btv->s_lock, irq_flags);
bt848_set_risc_jmps(btv,-1);
@@ -2620,12 +2769,16 @@
bttv_init_card1(btv);
/* register i2c */
- btv->tuner_type=-1;
+ btv->tuner_type = UNSET;
+ btv->pinnacle_id = UNSET;
init_bttv_i2c(btv);
/* some card-specific stuff (needs working i2c) */
bttv_init_card2(btv);
+ bt848_muxsel(btv, 1);
+ bt848_set_winsize(btv);
+
/*
* Now add the template and register the device unit.
*/
@@ -2663,7 +2816,7 @@
dstat=btread(BT848_DSTATUS);
if (irq_debug) {
- int i;
+ unsigned int i;
printk(KERN_DEBUG "bttv%d: irq loop=%d risc=%x, bits:",
btv->nr, count, stat>>28);
for (i = 0; i < (sizeof(irq_name)/sizeof(char*)); i++) {
@@ -2804,7 +2957,7 @@
static void bttv_remove(struct pci_dev *pci_dev)
{
u8 command;
- int j;
+ unsigned int j;
struct bttv *btv = pci_get_drvdata(pci_dev);
if (bttv_verbose)
@@ -2819,8 +2972,8 @@
/* first disable interrupts before unmapping the memory! */
btwrite(0, BT848_INT_MASK);
- btwrite(~0x0UL,BT848_INT_STAT);
- btwrite(0x0, BT848_GPIO_OUT_EN);
+ btwrite(~(u32)0,BT848_INT_STAT);
+ btwrite(0, BT848_GPIO_OUT_EN);
if (bttv_gpio)
bttv_gpio_tracking(btv,"cleanup");
@@ -2930,11 +3083,6 @@
else
btv->i2c_command=(I2C_TIMING | BT848_I2C_SCL | BT848_I2C_SDA);
- if (-1 != latency) {
- printk(KERN_INFO "bttv%d: setting pci latency timer to %d\n",
- bttv_num,latency);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency);
- }
pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %02x:%02x.%x, ",
@@ -3017,10 +3165,10 @@
MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
static struct pci_driver bttv_pci_driver = {
- name: "bttv",
- id_table: bttv_pci_tbl,
- probe: bttv_probe,
- remove: bttv_remove,
+ .name = "bttv",
+ .id_table = bttv_pci_tbl,
+ .probe = bttv_probe,
+ .remove = bttv_remove,
};
static int bttv_init_module(void)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)