[patch] v4l: #3 - bttv driver update

From: Gerd Knorr (kraxel@bytesex.org)
Date: Mon May 12 2003 - 12:14:17 EST


  Hi,

This patch is a update for the bttv driver. It is a big one because
alot of changes accumulated over time -- partly because submitting
updates in the past didn't work and partly because of some extra
work with merging the changes due to the i2c cleanups back into my
tree.

Changes:
 * splitted some code which can be shared with another driver into
   the btcx-risc module.
 * some new features (field rate capture support for example).
 * tv card list updates.
 * various bugfixes.
 * merged i2c changes back into my tree, there are some no-op
   changes due to this.

Please apply,

  Gerd

diff -u linux-2.5.69/drivers/media/video/Makefile linux/drivers/media/video/Makefile
--- linux-2.5.69/drivers/media/video/Makefile 2003-05-08 13:30:31.000000000 +0200
+++ linux/drivers/media/video/Makefile 2003-05-08 13:55:11.000000000 +0200
@@ -36,4 +36,5 @@
 
 obj-$(CONFIG_VIDEO_TUNER) += tuner.o tda9887.o
 obj-$(CONFIG_VIDEO_BUF) += video-buf.o
+obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
 
diff -u linux-2.5.69/drivers/media/video/bt848.h linux/drivers/media/video/bt848.h
--- linux-2.5.69/drivers/media/video/bt848.h 2003-05-08 13:30:20.000000000 +0200
+++ linux/drivers/media/video/bt848.h 2003-05-08 13:55:11.000000000 +0200
@@ -204,6 +204,9 @@
 #define BT848_COLOR_FMT_YCrCb411 0x99
 #define BT848_COLOR_FMT_RAW 0xee
 
+#define BT848_VTOTAL_LO 0xB0
+#define BT848_VTOTAL_HI 0xB4
+
 #define BT848_COLOR_CTL 0x0D8
 #define BT848_COLOR_CTL_EXT_FRMRATE (1<<7)
 #define BT848_COLOR_CTL_COLOR_BARS (1<<6)
@@ -311,29 +314,28 @@
 
 /* WRITE and SKIP */
 /* disable which bytes of each DWORD */
-#define BT848_RISC_BYTE0 (1<<12)
-#define BT848_RISC_BYTE1 (1<<13)
-#define BT848_RISC_BYTE2 (1<<14)
-#define BT848_RISC_BYTE3 (1<<15)
-#define BT848_RISC_BYTE_ALL (0x0f<<12)
+#define BT848_RISC_BYTE0 (1U<<12)
+#define BT848_RISC_BYTE1 (1U<<13)
+#define BT848_RISC_BYTE2 (1U<<14)
+#define BT848_RISC_BYTE3 (1U<<15)
+#define BT848_RISC_BYTE_ALL (0x0fU<<12)
 #define BT848_RISC_BYTE_NONE 0
 /* cause RISCI */
-#define BT848_RISC_IRQ (1<<24)
+#define BT848_RISC_IRQ (1U<<24)
 /* RISC command is last one in this line */
-#define BT848_RISC_EOL (1<<26)
+#define BT848_RISC_EOL (1U<<26)
 /* RISC command is first one in this line */
-#define BT848_RISC_SOL (1<<27)
-
-#define BT848_RISC_WRITE (0x01<<28)
-#define BT848_RISC_SKIP (0x02<<28)
-#define BT848_RISC_WRITEC (0x05<<28)
-#define BT848_RISC_JUMP (0x07<<28)
-#define BT848_RISC_SYNC (0x08<<28)
-
-#define BT848_RISC_WRITE123 (0x09<<28)
-#define BT848_RISC_SKIP123 (0x0a<<28)
-#define BT848_RISC_WRITE1S23 (0x0b<<28)
+#define BT848_RISC_SOL (1U<<27)
 
+#define BT848_RISC_WRITE (0x01U<<28)
+#define BT848_RISC_SKIP (0x02U<<28)
+#define BT848_RISC_WRITEC (0x05U<<28)
+#define BT848_RISC_JUMP (0x07U<<28)
+#define BT848_RISC_SYNC (0x08U<<28)
+
+#define BT848_RISC_WRITE123 (0x09U<<28)
+#define BT848_RISC_SKIP123 (0x0aU<<28)
+#define BT848_RISC_WRITE1S23 (0x0bU<<28)
 
 
 /* Bt848A and higher only !! */
diff -u linux-2.5.69/drivers/media/video/btcx-risc.c linux/drivers/media/video/btcx-risc.c
--- linux-2.5.69/drivers/media/video/btcx-risc.c 2003-05-08 13:55:11.000000000 +0200
+++ linux/drivers/media/video/btcx-risc.c 2003-05-08 13:55:11.000000000 +0200
@@ -0,0 +1,266 @@
+/*
+ btcx-risc.c
+
+ bt848/bt878/cx2388x risc code generator.
+
+ (c) 2000-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/videodev2.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include "btcx-risc.h"
+
+MODULE_DESCRIPTION("some code shared by bttv and cx88xx drivers");
+MODULE_AUTHOR("Gerd Knorr");
+MODULE_LICENSE("GPL");
+
+static unsigned int debug = 0;
+MODULE_PARM(debug,"i");
+MODULE_PARM_DESC(debug,"debug messages, default is 0 (no)");
+
+/* ---------------------------------------------------------- */
+/* allocate/free risc memory */
+
+static int memcnt;
+
+int btcx_riscmem_alloc(struct pci_dev *pci,
+ struct btcx_riscmem *risc,
+ unsigned int size)
+{
+ u32 *cpu;
+ dma_addr_t dma;
+
+ cpu = pci_alloc_consistent(pci, size, &dma);
+ if (NULL == cpu)
+ return -ENOMEM;
+ memset(cpu,0,size);
+
+#if 0
+ if (risc->cpu && risc->size < size) {
+ /* realloc (enlarge buffer) -- copy old stuff */
+ memcpy(cpu,risc->cpu,risc->size);
+ btcx_riscmem_free(pci,risc);
+ }
+#else
+ BUG_ON(NULL != risc->cpu);
+#endif
+ risc->cpu = cpu;
+ risc->dma = dma;
+ risc->size = size;
+
+ if (debug) {
+ memcnt++;
+ printk("btcx: riscmem alloc size=%d [%d]\n",size,memcnt);
+ }
+
+ return 0;
+}
+
+void btcx_riscmem_free(struct pci_dev *pci,
+ struct btcx_riscmem *risc)
+{
+ if (NULL == risc->cpu)
+ return;
+ pci_free_consistent(pci, risc->size, risc->cpu, risc->dma);
+ memset(risc,0,sizeof(*risc));
+ if (debug) {
+ memcnt--;
+ printk("btcx: riscmem free [%d]\n",memcnt);
+ }
+}
+
+/* ---------------------------------------------------------- */
+/* screen overlay helpers */
+
+int
+btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
+ struct v4l2_clip *clips, unsigned int n)
+{
+ if (win->left < 0) {
+ /* left */
+ clips[n].c.left = 0;
+ clips[n].c.top = 0;
+ clips[n].c.width = -win->left;
+ clips[n].c.height = win->height;
+ n++;
+ }
+ if (win->left + win->width > swidth) {
+ /* right */
+ clips[n].c.left = swidth - win->left;
+ clips[n].c.top = 0;
+ clips[n].c.width = win->width - clips[n].c.left;
+ clips[n].c.height = win->height;
+ n++;
+ }
+ if (win->top < 0) {
+ /* top */
+ clips[n].c.left = 0;
+ clips[n].c.top = 0;
+ clips[n].c.width = win->width;
+ clips[n].c.height = -win->top;
+ n++;
+ }
+ if (win->top + win->height > sheight) {
+ /* bottom */
+ clips[n].c.left = 0;
+ clips[n].c.top = sheight - win->top;
+ clips[n].c.width = win->width;
+ clips[n].c.height = win->height - clips[n].c.top;
+ n++;
+ }
+ return n;
+}
+
+int
+btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, unsigned int n, int mask)
+{
+ s32 nx,nw,dx;
+ unsigned int i;
+
+ /* fixup window */
+ nx = (win->left + mask) & ~mask;
+ nw = (win->width) & ~mask;
+ if (nx + nw > win->left + win->width)
+ nw -= mask+1;
+ dx = nx - win->left;
+ win->left = nx;
+ win->width = nw;
+ if (debug)
+ printk(KERN_DEBUG "btcx: window align %dx%d+%d+%d [dx=%d]\n",
+ win->width, win->height, win->left, win->top, dx);
+
+ /* fixup clips */
+ for (i = 0; i < n; i++) {
+ nx = (clips[i].c.left-dx) & ~mask;
+ nw = (clips[i].c.width) & ~mask;
+ if (nx + nw < clips[i].c.left-dx + clips[i].c.width)
+ nw += mask+1;
+ clips[i].c.left = nx;
+ clips[i].c.width = nw;
+ if (debug)
+ printk(KERN_DEBUG "btcx: clip align %dx%d+%d+%d\n",
+ clips[i].c.width, clips[i].c.height,
+ clips[i].c.left, clips[i].c.top);
+ }
+ return 0;
+}
+
+void
+btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips)
+{
+ struct v4l2_clip swap;
+ int i,j,n;
+
+ if (nclips < 2)
+ return;
+ for (i = nclips-2; i >= 0; i--) {
+ for (n = 0, j = 0; j <= i; j++) {
+ if (clips[j].c.left > clips[j+1].c.left) {
+ swap = clips[j];
+ clips[j] = clips[j+1];
+ clips[j+1] = swap;
+ n++;
+ }
+ }
+ if (0 == n)
+ break;
+ }
+}
+
+void
+btcx_calc_skips(int line, int width, unsigned int *maxy,
+ struct btcx_skiplist *skips, unsigned int *nskips,
+ const struct v4l2_clip *clips, unsigned int nclips)
+{
+ unsigned int clip,skip;
+ int end,maxline;
+
+ skip=0;
+ maxline = 9999;
+ for (clip = 0; clip < nclips; clip++) {
+
+ /* sanity checks */
+ if (clips[clip].c.left + clips[clip].c.width <= 0)
+ continue;
+ if (clips[clip].c.left > (signed)width)
+ break;
+
+ /* vertical range */
+ if (line > clips[clip].c.top+clips[clip].c.height-1)
+ continue;
+ if (line < clips[clip].c.top) {
+ if (maxline > clips[clip].c.top-1)
+ maxline = clips[clip].c.top-1;
+ continue;
+ }
+ if (maxline > clips[clip].c.top+clips[clip].c.height-1)
+ maxline = clips[clip].c.top+clips[clip].c.height-1;
+
+ /* horizontal range */
+ if (0 == skip || clips[clip].c.left > skips[skip-1].end) {
+ /* new one */
+ skips[skip].start = clips[clip].c.left;
+ if (skips[skip].start < 0)
+ skips[skip].start = 0;
+ skips[skip].end = clips[clip].c.left + clips[clip].c.width;
+ if (skips[skip].end > width)
+ skips[skip].end = width;
+ skip++;
+ } else {
+ /* overlaps -- expand last one */
+ end = clips[clip].c.left + clips[clip].c.width;
+ if (skips[skip-1].end < end)
+ skips[skip-1].end = end;
+ if (skips[skip-1].end > width)
+ skips[skip-1].end = width;
+ }
+ }
+ *nskips = skip;
+ *maxy = maxline;
+
+ if (debug) {
+ printk(KERN_DEBUG "btcx: skips line %d-%d:",line,maxline);
+ for (skip = 0; skip < *nskips; skip++) {
+ printk(" %d-%d",skips[skip].start,skips[skip].end);
+ }
+ printk("\n");
+ }
+}
+
+/* ---------------------------------------------------------- */
+
+EXPORT_SYMBOL(btcx_riscmem_alloc);
+EXPORT_SYMBOL(btcx_riscmem_free);
+
+EXPORT_SYMBOL(btcx_screen_clips);
+EXPORT_SYMBOL(btcx_align);
+EXPORT_SYMBOL(btcx_sort_clips);
+EXPORT_SYMBOL(btcx_calc_skips);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -u linux-2.5.69/drivers/media/video/btcx-risc.h linux/drivers/media/video/btcx-risc.h
--- linux-2.5.69/drivers/media/video/btcx-risc.h 2003-05-08 13:55:11.000000000 +0200
+++ linux/drivers/media/video/btcx-risc.h 2003-05-08 13:55:11.000000000 +0200
@@ -0,0 +1,33 @@
+
+struct btcx_riscmem {
+ unsigned int size;
+ u32 *cpu;
+ u32 *jmp;
+ dma_addr_t dma;
+};
+
+struct btcx_skiplist {
+ int start;
+ int end;
+};
+
+int btcx_riscmem_alloc(struct pci_dev *pci,
+ struct btcx_riscmem *risc,
+ unsigned int size);
+void btcx_riscmem_free(struct pci_dev *pci,
+ struct btcx_riscmem *risc);
+
+int btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
+ struct v4l2_clip *clips, unsigned int n);
+int btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips,
+ unsigned int n, int mask);
+void btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips);
+void btcx_calc_skips(int line, int width, unsigned int *maxy,
+ struct btcx_skiplist *skips, unsigned int *nskips,
+ const struct v4l2_clip *clips, unsigned int nclips);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -u linux-2.5.69/drivers/media/video/bttv-cards.c linux/drivers/media/video/bttv-cards.c
--- linux-2.5.69/drivers/media/video/bttv-cards.c 2003-05-08 13:30:55.000000000 +0200
+++ linux/drivers/media/video/bttv-cards.c 2003-05-08 13:55:11.000000000 +0200
@@ -21,7 +21,7 @@
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
+
 */
 
 #include <linux/version.h>
@@ -30,6 +30,7 @@
 #include <linux/kmod.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/vmalloc.h>
 
 #include <asm/io.h>
 
@@ -55,32 +56,34 @@
 static void pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set);
 static void fv2000s_audio(struct bttv *btv, struct video_audio *v, int set);
 static void windvr_audio(struct bttv *btv, struct video_audio *v, int set);
+static void adtvk503_audio(struct bttv *btv, struct video_audio *v, int set);
 static void rv605_muxsel(struct bttv *btv, unsigned int input);
 static void eagle_muxsel(struct bttv *btv, unsigned int input);
+static void xguard_muxsel(struct bttv *btv, unsigned int input);
 
 static int terratec_active_radio_upgrade(struct bttv *btv);
 static int tea5757_read(struct bttv *btv);
 static int tea5757_write(struct bttv *btv, int value);
-int is_MM20xPCTV(unsigned char eeprom_data[256]);
-
+static void identify_by_eeprom(struct bttv *btv,
+ unsigned char eeprom_data[256]);
 
 /* config variables */
-static int triton1=0;
-static int vsfx=0;
-static int no_overlay=-1;
-static int latency = -1;
-
-static unsigned int card[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = -1};
-static unsigned int pll[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = -1};
-static unsigned int tuner[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = -1};
+static unsigned int triton1=0;
+static unsigned int vsfx=0;
+static unsigned int latency = UNSET;
+unsigned int no_overlay=-1;
+
+static unsigned int card[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET};
+static unsigned int pll[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET};
+static unsigned int tuner[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET};
 #ifdef MODULE
 static unsigned int autoload = 1;
 #else
 static unsigned int autoload = 0;
 #endif
-static unsigned int gpiomask = -1;
-static unsigned int audioall = -1;
-static unsigned int audiomux[5] = { -1, -1, -1, -1, -1 };
+static unsigned int gpiomask = UNSET;
+static unsigned int audioall = UNSET;
+static unsigned int audiomux[5] = { [ 0 ... 4 ] = UNSET };
 
 /* insmod options */
 MODULE_PARM(triton1,"i");
@@ -153,9 +156,11 @@
         { 0x405010fc, BTTV_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" },
         { 0x407010fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
 
- { 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV" },
         { 0x001211bd, BTTV_PINNACLE, "Pinnacle PCTV" },
         { 0x001c11bd, BTTV_PINNACLESAT, "Pinnacle PCTV Sat" },
+ // some cards ship with byteswapped IDs ...
+ { 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" },
+ { 0xff00bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" },
 
         { 0x3000121a, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
         { 0x3060121a, BTTV_STB2, "3Dfx VoodooTV 100/ STB OEM" },
@@ -163,6 +168,7 @@
         { 0x3000144f, BTTV_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" },
         { 0x3002144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" },
         { 0x3005144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" },
+ { 0x5000144f, BTTV_MAGICTVIEW061, "Askey CPH050" },
         
         { 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
         { 0x00021461, BTTV_AVERMEDIA98, "AVermedia TVCapture 98" },
@@ -192,6 +198,23 @@
         { 0x401015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
         { 0x401615b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
 
+ { 0x1460aa00, BTTV_PV150, "Provideo PV150A-1" },
+ { 0x1461aa01, BTTV_PV150, "Provideo PV150A-2" },
+ { 0x1462aa02, BTTV_PV150, "Provideo PV150A-3" },
+ { 0x1463aa03, BTTV_PV150, "Provideo PV150A-4" },
+ { 0x1464aa04, BTTV_PV150, "Provideo PV150B-1" },
+ { 0x1465aa05, BTTV_PV150, "Provideo PV150B-2" },
+ { 0x1466aa06, BTTV_PV150, "Provideo PV150B-3" },
+ { 0x1467aa07, BTTV_PV150, "Provideo PV150B-4" },
+
+ { 0xa1550000, BTTV_IVC200, "IVC-200" },
+ { 0xa1550001, BTTV_IVC200, "IVC-200" },
+ { 0xa1550002, BTTV_IVC200, "IVC-200" },
+ { 0xa1550003, BTTV_IVC200, "IVC-200" },
+
+ { 0x41424344, BTTV_GRANDTEC, "GrandTec Multi Capture" },
+ { 0x01020304, BTTV_XGUARD, "Grandtec Grand X-Guard" },
+
             { 0x010115cb, BTTV_GMV1, "AG GMV1" },
         { 0x010114c7, BTTV_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" },
         { 0x18501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
@@ -202,8 +225,11 @@
         { 0x03116000, BTTV_SENSORAY311, "Sensoray 311" },
         { 0x00790e11, BTTV_WINDVR, "Canopus WinDVR PCI" },
         { 0xa0fca1a0, BTTV_ZOLTRIX, "Face to Face Tvmax" },
- { 0xa0fca04f, BTTV_MAGICTVIEW063, "Guillemot Maxi TV Video 3" },
+ { 0x01010071, BTTV_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
 
+ // likely broken, vendor id doesn't match the other magic views ...
+ //{ 0xa0fca04f, BTTV_MAGICTVIEW063, "Guillemot Maxi TV Video 3" },
+
         { 0, -1, NULL }
 };
 
@@ -376,6 +402,7 @@
         .muxsel = { 2, 3, 1, 1},
         .audiomux = { 13, 14, 11, 7, 0, 0},
         .needs_tvaudio = 1,
+ .msp34xx_alt = 1,
         .pll = PLL_28,
         .tuner_type = TUNER_PHILIPS_PAL,
 },{
@@ -613,7 +640,7 @@
         .pll = PLL_28,
         .tuner_type = -1,
 },{
- .name = "Formac iProTV",
+ .name = "Formac iProTV, Formac ProTV I (bt848)",
         .video_inputs = 4,
         .audio_inputs = 1,
         .tuner = 0,
@@ -763,6 +790,7 @@
         .pll = PLL_28,
         .tuner_type = -1,
         .has_radio = 1,
+ .audio_hook = avermedia_tvphone_audio,
 },{
         .name = "ProVideo PV951", /* pic16c54 */
         .video_inputs = 3,
@@ -904,10 +932,10 @@
 /* ---- card 0x34 ---------------------------------- */
         /* David Härdeman <david@2gen.com> */
         .name = "Pinnacle PCTV Studio Pro",
- .video_inputs = 3,
+ .video_inputs = 4,
         .audio_inputs = 1,
         .tuner = 0,
- .svhs = 2,
+ .svhs = 3,
         .gpiomask = 0x03000F,
         .muxsel = { 2, 3, 1, 1},
         .audiomux = { 1, 0xd0001, 0, 0, 10},
@@ -1535,7 +1563,7 @@
         .needs_tvaudio = 0,
         .pll = PLL_28,
 },{
- .name = "Formac ProTV II",
+ .name = "Formac ProTV II (bt878)",
         .video_inputs = 4,
         .audio_inputs = 1,
         .tuner = 0,
@@ -1554,8 +1582,8 @@
          not soldered here, though unknown wiring.
          Card lacks: external audio in, pci subsystem id.
        */
-
 },{
+
         /* ---- card 0x60 ---------------------------------- */
         .name = "MachTV",
         .video_inputs = 3,
@@ -1580,9 +1608,119 @@
         .no_tda7432 = 1,
         .muxsel = { 2, 0, 1},
         .pll = PLL_28,
+},{
+ /* Luc Van Hoeylandt <luc@e-magic.be> */
+ .name = "ProVideo PV150", /* 0x4f */
+ .video_inputs = 2,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .gpiomask = 0,
+ .muxsel = { 2, 3 },
+ .audiomux = { 0 },
+ .needs_tvaudio = 0,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+},{
+ /* Hiroshi Takekawa <sian@big.or.jp> */
+ /* This card lacks subsystem ID */
+ .name = "AD-TVK503", /* 0x63 */
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x001e8007,
+ .muxsel = { 2, 3, 1, 0 },
+ /* Tuner, Radio, external, internal, mute, stereo */
+ .audiomux = { 0x00060000, 0x000, 0x000000, 0x000000, 0x07, 0x0000 }, /* Sub: 0x00180000 */
+ .needs_tvaudio = 0,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = 2,
+ .audio_hook = adtvk503_audio,
+},{
+
+ /* ---- card 0x64 ---------------------------------- */
+ .name = "Hercules Smart TV Stereo",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x00,
+ .muxsel = { 2, 3, 1, 1 },
+ .needs_tvaudio = 1,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = 5,
+ /* Notes:
+ - card lacks subsystem ID
+ - stereo variant w/ daughter board with tda9874a @0xb0
+ - Audio Routing:
+ always from tda9874 independent of GPIO (?)
+ external line in: unknown
+ - Other chips: em78p156elp @ 0x96 (probably IR remote control)
+ hef4053 (instead 4052) for unknown function
+ */
+},{
+ .name = "Pace TV & Radio Card",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .muxsel = { 2, 3, 1, 1}, // Tuner, CVid, SVid, CVid over SVid connector
+ .gpiomask = 0,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .tuner_type = 1,
+ .has_radio = 1,
+ .pll = PLL_28,
+ /* Bt878, Bt832, FI1246 tuner; no pci subsystem id
+ only internal line out: (4pin header) RGGL
+ Radio must be decoded by msp3410d (not routed through)*/
+ // .digital_mode = DIGITAL_MODE_CAMERA, // todo!
+},{
+ /* Chris Willing <chris@vislab.usyd.edu.au> */
+ .name = "IVC-200",
+ .video_inputs = 1,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .tuner_type = -1,
+ .svhs = -1,
+ .gpiomask = 0xdf,
+ .muxsel = { 2 },
+ .pll = PLL_28,
+},{
+ .name = "Grand X-Guard / Trust 814PCI",
+ .video_inputs = 16,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .tuner_type = 4,
+ .gpiomask2 = 0xff,
+ .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 },
+ .muxsel_hook = xguard_muxsel,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .pll = PLL_28,
+},{
+
+ /* ---- card 0x68 ---------------------------------- */
+ .name = "Nebula Electronics DigiTV",
+ .video_inputs = 0,
+ .audio_inputs = 0,
+ .svhs = -1,
+ .muxsel = { 2, 3, 1, 0},
+ .needs_tvaudio = 0,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
 }};
 
-const int bttv_num_tvcards = (sizeof(bttv_tvcards)/sizeof(struct tvcard));
+const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
 
 /* ----------------------------------------------------------------------- */
 
@@ -1614,19 +1752,21 @@
                         printk(KERN_INFO "bttv%d: detected: %s [card=%d], "
                                "PCI subsystem ID is %04x:%04x\n",
                                btv->nr,cards[type].name,cards[type].cardnr,
- btv->cardid & 0xffff, btv->cardid >> 16);
+ btv->cardid & 0xffff,
+ (btv->cardid >> 16) & 0xffff);
                         btv->type = cards[type].cardnr;
                 } else {
                         /* 404 */
                         printk(KERN_INFO "bttv%d: subsystem: %04x:%04x (UNKNOWN)\n",
- btv->nr, btv->cardid&0xffff, btv->cardid>>16);
+ btv->nr, btv->cardid & 0xffff,
+ (btv->cardid >> 16) & 0xffff);
                         printk(KERN_DEBUG "please mail id, board name and "
                                "the correct card= insmod option to kraxel@bytesex.org\n");
                 }
         }
 
         /* let the user override the autodetected type */
- if (card[btv->nr] >= 0 && card[btv->nr] < bttv_num_tvcards)
+ if (card[btv->nr] < bttv_num_tvcards)
                 btv->type=card[btv->nr];
         
         /* print which card config we are using */
@@ -1636,14 +1776,14 @@
                 bttv_tvcards[btv->type].name);
         printk(KERN_INFO "bttv%d: using: %s [card=%d,%s]\n",btv->nr,
                btv->video_dev.name,btv->type,
- (card[btv->nr] >= 0 && card[btv->nr] < bttv_num_tvcards) ?
- "insmod option" : "autodetected");
+ card[btv->nr] < bttv_num_tvcards
+ ? "insmod option" : "autodetected");
 
         /* overwrite gpio stuff ?? */
- if (-1 == audioall && -1 == audiomux[0])
+ if (UNSET == audioall && UNSET == audiomux[0])
                 return;
 
- if (-1 != audiomux[0]) {
+ if (UNSET != audiomux[0]) {
                 gpiobits = 0;
                 for (i = 0; i < 5; i++) {
                         bttv_tvcards[btv->type].audiomux[i] = audiomux[i];
@@ -1655,7 +1795,7 @@
                         bttv_tvcards[btv->type].audiomux[i] = audioall;
                 }
         }
- bttv_tvcards[btv->type].gpiomask = (-1 != gpiomask) ? gpiomask : gpiobits;
+ bttv_tvcards[btv->type].gpiomask = (UNSET != gpiomask) ? gpiomask : gpiobits;
         printk(KERN_INFO "bttv%d: gpio config override: mask=0x%x, mux=",
                btv->nr,bttv_tvcards[btv->type].gpiomask);
         for (i = 0; i < 5; i++) {
@@ -1669,13 +1809,22 @@
  */
 
 /* Some Modular Technology cards have an eeprom, but no subsystem ID */
-int is_MM20xPCTV(unsigned char eeprom_data[256])
+void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256])
 {
- if (0 == strncmp(eeprom_data,"GET.MM20xPCTV",13)) {
- printk("bttv: GET.MM20xPCTV found\n");
- return 1; // found
+ int type = -1;
+
+ if (0 == strncmp(eeprom_data,"GET.MM20xPCTV",13))
+ type = BTTV_MODTEC_205;
+ else if (0 == strncmp(eeprom_data+20,"Picolo",7))
+ type = BTTV_EURESYS_PICOLO;
+ else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0)
+ type = BTTV_HAUPPAUGE; /* old bt848 */
+
+ if (-1 != type) {
+ btv->type = type;
+ printk("bttv%d: detected by eeprom: %s [card=%d]\n",
+ btv->nr, bttv_tvcards[btv->type].name, btv->type);
         }
- return 0;
 }
 
 static void flyvideo_gpio(struct bttv *btv)
@@ -1779,7 +1928,8 @@
                         if (btv->type == BTTV_PINNACLE)
                                 btv->type = BTTV_PINNACLEPRO;
                 }
- printk(KERN_INFO "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n",
+ printk(KERN_INFO
+ "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n",
                        btv->nr, id+1, btv->tuner_type,
                        !btv->has_radio ? "no" :
                        (btv->has_matchbox ? "matchbox" : "fmtuner"),
@@ -1813,13 +1963,13 @@
                         info = "oops: unknown card";
                         break;
                 }
+ if (-1 != msp)
+ btv->type = BTTV_PINNACLEPRO;
                 printk(KERN_INFO
                        "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n",
                        btv->nr, id, info, btv->has_radio ? "yes" : "no");
- btv->tuner_type = 33;
- if (autoload)
- request_module("tda9887");
- bttv_call_i2c_clients(btv,AUDC_CONFIG_PINNACLE,&id);
+ btv->tuner_type = 33;
+ btv->pinnacle_id = id;
         }
 }
 
@@ -1885,6 +2035,9 @@
         case BTTV_VOODOOTV_FM:
                 boot_msp34xx(btv,20);
                 break;
+ case BTTV_AVERMEDIA98:
+ boot_msp34xx(btv,11);
+ break;
         case BTTV_HAUPPAUGEPVR:
                 pvr_boot(btv);
                 break;
@@ -1897,13 +2050,8 @@
         btv->tuner_type = -1;
 
         if (BTTV_UNKNOWN == btv->type) {
- printk("bttv%d: Looking for eeprom\n",btv->nr);
                 bttv_readee(btv,eeprom_data,0xa0);
- if(is_MM20xPCTV(eeprom_data)) {
- btv->type = BTTV_MODTEC_205;
- printk("bttv%d: Autodetect by eeprom:(%s) [card=%d]\n",
- btv->nr, bttv_tvcards[btv->type].name, btv->type);
- }
+ identify_by_eeprom(btv,eeprom_data);
         }
 
         switch (btv->type) {
@@ -2027,18 +2175,20 @@
         btv->pll.pll_current = -1;
 
         /* tuner configuration (from card list / autodetect / insmod option) */
- if (-1 != bttv_tvcards[btv->type].tuner_type)
- if( -1 == btv->tuner_type)
+ if (UNSET != bttv_tvcards[btv->type].tuner_type)
+ if(UNSET == btv->tuner_type)
                         btv->tuner_type = bttv_tvcards[btv->type].tuner_type;
- if (-1 != tuner[btv->nr])
+ if (UNSET != tuner[btv->nr])
                 btv->tuner_type = tuner[btv->nr];
- if (btv->tuner_type != -1)
- bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
         printk("bttv%d: using tuner=%d\n",btv->nr,btv->tuner_type);
+ if (btv->pinnacle_id != UNSET)
+ bttv_call_i2c_clients(btv,AUDC_CONFIG_PINNACLE,
+ &btv->pinnacle_id);
+ if (btv->tuner_type != UNSET)
+ bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
 
         if (bttv_tvcards[btv->type].has_radio)
                 btv->has_radio=1;
-
         if (bttv_tvcards[btv->type].audio_hook)
                 btv->audio_hook=bttv_tvcards[btv->type].audio_hook;
 
@@ -2056,6 +2206,12 @@
                         request_module("msp3400");
         }
 
+ if (bttv_tvcards[btv->type].msp34xx_alt &&
+ bttv_I2CRead(btv, I2C_MSP3400_ALT, "MSP34xx (alternate address)") >=0) {
+ if (autoload)
+ request_module("msp3400");
+ }
+
         if (!bttv_tvcards[btv->type].no_tda9875 &&
             bttv_I2CRead(btv, I2C_TDA9875, "TDA9875") >=0) {
                 if (autoload)
@@ -2073,7 +2229,12 @@
                         request_module("tvaudio");
         }
 
- if (bttv_tvcards[btv->type].tuner != -1) {
+ /* tuner modules */
+ if (btv->pinnacle_id != UNSET) {
+ if (autoload)
+ request_module("tda9887");
+ }
+ if (btv->tuner_type != UNSET) {
                 if (autoload)
                         request_module("tuner");
         }
@@ -2136,9 +2297,9 @@
         { TUNER_TEMIC_4046FM5, "Temic 4046FM5" },
         { TUNER_TEMIC_4009FN5_MULTI_PAL_FM, "Temic 4009FN5" },
         { TUNER_ABSENT, "Philips TD1536D_FH_44"},
- { TUNER_LG_NTSC_FM, "LG TP18NSR01F"},
- { TUNER_LG_PAL_FM, "LG TP18PSB01D"},
- { TUNER_LG_PAL, "LG TP18PSB11D"},
+ { TUNER_LG_NTSC_FM, "LG TPI8NSR01F"},
+ { TUNER_LG_PAL_FM, "LG TPI8PSB01D"},
+ { TUNER_LG_PAL, "LG TPI8PSB11D"},
         { TUNER_LG_PAL_I_FM, "LG TAPC-I001D"},
         { TUNER_LG_PAL_I, "LG TAPC-I701D"}
 };
@@ -2147,15 +2308,17 @@
 {
         if( strncmp(&(eeprom_data[0x1e]),"Temic 4066 FY5",14) ==0) {
                 btv->tuner_type=TUNER_TEMIC_4066FY5_PAL_I;
- printk("bttv Modtec: Tuner autodetected %s\n",&eeprom_data[0x1e]);
+ printk("bttv Modtec: Tuner autodetected %s\n",
+ &eeprom_data[0x1e]);
+ } else {
+ printk("bttv Modtec: Unknown TunerString:%s\n",
+ &eeprom_data[0x1e]);
         }
- else
- printk("bttv Modtec: Unknown TunerString:%s\n",&eeprom_data[0x1e]);
 }
 
 static void __devinit hauppauge_eeprom(struct bttv *btv)
 {
- int blk2,tuner,radio,model;
+ unsigned int blk2,tuner,radio,model;
 
         if (eeprom_data[0] != 0x84 || eeprom_data[2] != 0)
                 printk(KERN_WARNING "bttv%d: Hauppauge eeprom: invalid\n",
@@ -2169,9 +2332,8 @@
         tuner = eeprom_data[9];
         radio = eeprom_data[blk2-1] & 0x01;
         
- if (tuner >= ARRAY_SIZE(hauppauge_tuner))
- tuner = 0;
- btv->tuner_type = hauppauge_tuner[tuner].id;
+ if (tuner < ARRAY_SIZE(hauppauge_tuner))
+ btv->tuner_type = hauppauge_tuner[tuner].id;
         if (radio)
                 btv->has_radio = 1;
         
@@ -2540,7 +2702,8 @@
         static int vals[] __devinitdata = { 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0d,
                                             0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
                                             0x00 };
- int i,tmp;
+ unsigned int i;
+ int tmp;
 
         /* Initialise GPIO-connevted stuff */
         btwrite(1<<13,BT848_GPIO_OUT_EN); /* Reset pin only */
@@ -2573,7 +2736,7 @@
         
         printk(KERN_INFO "Initialising 12C508 PIC chip ...\n");
 
- for (i = 0; i < sizeof(vals)/sizeof(int); i++) {
+ for (i = 0; i < ARRAY_SIZE(vals); i++) {
                 tmp=bttv_I2CWrite(btv,0x1E,vals[i],0,1);
                 printk(KERN_INFO "I2C Write(0x08) = %i\nI2C Read () = %x\n\n",
                        tmp,bttv_I2CRead(btv,0x1F,NULL));
@@ -2670,8 +2833,8 @@
 /* Low-level stuff */
 static int tea5757_read(struct bttv *btv)
 {
+ unsigned long timeout;
         int value = 0;
- long timeout;
         int i;
         
         /* better safe than sorry */
@@ -2754,12 +2917,13 @@
 
 void tea5757_set_freq(struct bttv *btv, unsigned short freq)
 {
- int value;
-
         dprintk("tea5757_set_freq %d\n",freq);
         tea5757_write(btv, 5 * freq + 0x358); /* add 10.7MHz (see docs) */
+#if 0
+ /* breaks Miro PCTV */
         value = tea5757_read(btv);
- dprintk("bttv%d: tea5757 readback =0x%x\n",btv->nr,value);
+ dprintk("bttv%d: tea5757 readback=0x%x\n",btv->nr,value);
+#endif
 }
 
 
@@ -3051,6 +3215,38 @@
         }
 }
 
+/*
+ * sound control for AD-TVK503
+ * Hiroshi Takekawa <sian@big.or.jp>
+ */
+static void
+adtvk503_audio(struct bttv *btv, struct video_audio *v, int set)
+{
+ unsigned int con = 0xffffff;
+
+ //btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN);
+
+ if (set) {
+ //btor(***, BT848_GPIO_OUT_EN);
+ if (v->mode & VIDEO_SOUND_LANG1)
+ con = 0x00000000;
+ if (v->mode & VIDEO_SOUND_LANG2)
+ con = 0x00180000;
+ if (v->mode & VIDEO_SOUND_STEREO)
+ con = 0x00000000;
+ if (v->mode & VIDEO_SOUND_MONO)
+ con = 0x00060000;
+ if (con != 0xffffff) {
+ btaor(con, ~0x1e0000, BT848_GPIO_DATA);
+ if (bttv_gpio)
+ bttv_gpio_tracking(btv, "adtvk503");
+ }
+ } else {
+ v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
+ VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
+ }
+}
+
 /* RemoteVision MX (rv605) muxsel helper [Miguel Freitas]
  *
  * This is needed because rv605 don't use a normal multiplex, but a crosspoint
@@ -3091,6 +3287,34 @@
         mdelay(1);
 }
 
+// The Grandtec X-Guard framegrabber card uses two Dual 4-channel
+// video multiplexers to provide up to 16 video inputs. These
+// multiplexers are controlled by the lower 8 GPIO pins of the
+// bt878. The multiplexers probably Pericom PI5V331Q or similar.
+
+// xxx0 is pin xxx of multiplexer U5,
+// yyy1 is pin yyy of multiplexer U2
+
+#define ENA0 0x01
+#define ENB0 0x02
+#define ENA1 0x04
+#define ENB1 0x08
+
+#define IN10 0x10
+#define IN00 0x20
+#define IN11 0x40
+#define IN01 0x80
+
+static void xguard_muxsel(struct bttv *btv, unsigned int input)
+{
+ static const int masks[] = {
+ ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10,
+ ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10,
+ ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11,
+ ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11,
+ };
+ btwrite(masks[input%16], BT848_GPIO_DATA);
+}
 
 /* ----------------------------------------------------------------------- */
 /* motherboard chipset specific stuff */
@@ -3122,12 +3346,12 @@
                 printk(KERN_INFO "bttv: Host bridge needs VSFX enabled.\n");
         if (pcipci_fail) {
                 printk(KERN_WARNING "bttv: BT848 and your chipset may not work together.\n");
- if (-1 == no_overlay) {
+ if (UNSET == no_overlay) {
                         printk(KERN_WARNING "bttv: going to disable overlay.\n");
                         no_overlay = 1;
                 }
         }
- if (-1 != latency)
+ if (UNSET != latency)
                 printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency);
 
         while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL,
@@ -3144,7 +3368,7 @@
 {
          unsigned char command;
 
- if (!triton1 && !vsfx && -1 == latency)
+ if (!triton1 && !vsfx && UNSET == latency)
                 return 0;
 
         if (bttv_verbose) {
@@ -3152,7 +3376,7 @@
                         printk(KERN_INFO "bttv%d: enabling ETBF (430FX/VP3 compatibilty)\n",btv->nr);
                 if (vsfx && btv->id >= 878)
                         printk(KERN_INFO "bttv%d: enabling VSFX\n",btv->nr);
- if (-1 != latency)
+ if (UNSET != latency)
                         printk(KERN_INFO "bttv%d: setting pci timer to %d\n",
                                btv->nr,latency);
         }
@@ -3170,7 +3394,7 @@
                         command |= BT878_EN_VSFX;
                 pci_write_config_byte(btv->dev, BT878_DEVCTRL, command);
         }
- if (-1 != latency)
+ if (UNSET != latency)
                 pci_write_config_byte(btv->dev, PCI_LATENCY_TIMER, latency);
         return 0;
 }
diff -u linux-2.5.69/drivers/media/video/bttv-driver.c linux/drivers/media/video/bttv-driver.c
--- linux-2.5.69/drivers/media/video/bttv-driver.c 2003-05-08 13:31:37.000000000 +0200
+++ linux/drivers/media/video/bttv-driver.c 2003-05-08 13:55:11.000000000 +0200
@@ -35,10 +35,11 @@
 #include <linux/kdev_t.h>
 
 #include <asm/io.h>
+#include <asm/byteorder.h>
 
 #include "bttvp.h"
 
-int bttv_num; /* number of Bt848s in use */
+unsigned int bttv_num; /* number of Bt848s in use */
 struct bttv bttvs[BTTV_MAX];
 
 unsigned int bttv_debug = 0;
@@ -46,7 +47,7 @@
 unsigned int bttv_gpio = 0;
 
 /* config variables */
-#if defined(__sparc__) || defined(__powerpc__) || defined(__hppa__)
+#ifdef __BIG_ENDIAN
 static unsigned int bigendian=1;
 #else
 static unsigned int bigendian=0;
@@ -275,9 +276,29 @@
                 .vdelay = 0x16,
                 .vbipack = 144,
                 .sram = -1,
+ },{
+ /* that one hopefully works with the strange timing
+ * which video recorders produce when playing a NTSC
+ * tape on a PAL TV ... */
+ .v4l2_id = V4L2_STD_PAL_60,
+ .name = "PAL-60",
+ .Fsc = 35468950,
+ .swidth = 924,
+ .sheight = 480,
+ .totalwidth = 1135,
+ .adelay = 0x7f,
+ .bdelay = 0x72,
+ .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
+ .scaledtwidth = 1135,
+ .hdelayx1 = 186,
+ .hactivex1 = 924,
+ .vdelay = 0x1a,
+ .vbipack = 255,
+ .vtotal = 524,
+ .sram = -1,
         }
 };
-const int BTTV_TVNORMS = (sizeof(bttv_tvnorms)/sizeof(struct bttv_tvnorm));
+const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms);
 
 /* ----------------------------------------------------------------------- */
 /* bttv format list
@@ -434,7 +455,7 @@
                 .flags = FORMAT_FLAGS_RAW,
         }
 };
-const int BTTV_FORMATS = (sizeof(bttv_formats)/sizeof(struct bttv_format));
+const unsigned int BTTV_FORMATS = ARRAY_SIZE(bttv_formats);
 
 /* ----------------------------------------------------------------------- */
 
@@ -557,7 +578,7 @@
                 .type = V4L2_CTRL_TYPE_BOOLEAN,
         }
 };
-const int BTTV_CTLS = (sizeof(bttv_ctls)/sizeof(struct v4l2_queryctrl));
+const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls);
 
 /* ----------------------------------------------------------------------- */
 /* resource management */
@@ -1159,7 +1180,7 @@
 static const struct bttv_format*
 format_by_palette(int palette)
 {
- int i;
+ unsigned int i;
 
         for (i = 0; i < BTTV_FORMATS; i++) {
                 if (-1 == bttv_formats[i].palette)
@@ -1173,7 +1194,7 @@
 static const struct bttv_format*
 format_by_fourcc(int fourcc)
 {
- int i;
+ unsigned int i;
 
         for (i = 0; i < BTTV_FORMATS; i++) {
                 if (-1 == bttv_formats[i].fourcc)
@@ -1195,6 +1216,7 @@
         unsigned long flags;
         int retval = 0;
 
+ dprintk("switch_overlay: enter [new=%p]\n",new);
         if (new)
                 new->vb.state = STATE_DONE;
         spin_lock_irqsave(&btv->s_lock,flags);
@@ -1204,8 +1226,12 @@
         spin_unlock_irqrestore(&btv->s_lock,flags);
         if (NULL == new)
                 free_btres(btv,fh,RESOURCE_OVERLAY);
- if (NULL != old)
+ if (NULL != old) {
+ dprintk("switch_overlay: old=%p state is %d\n",old,old->vb.state);
                 bttv_dma_free(btv, old);
+ kfree(old);
+ }
+ dprintk("switch_overlay: done\n");
         return retval;
 }
 
@@ -1214,7 +1240,7 @@
 
 static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
                                 const struct bttv_format *fmt,
- int width, int height,
+ unsigned int width, unsigned int height,
                                enum v4l2_field field)
 {
         int redo_dma_risc = 0;
@@ -1252,13 +1278,6 @@
                 redo_dma_risc = 1;
         }
 
-#if 0
- if (STATE_NEEDS_INIT == buf->vb.state) {
- if (redo_dma_risc)
- bttv_dma_free(btv,buf);
- }
-#endif
-
         /* alloc risc memory */
         if (STATE_NEEDS_INIT == buf->vb.state) {
                 redo_dma_risc = 1;
@@ -1334,7 +1353,7 @@
         "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
         "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
         "SMICROCODE", "GVBIFMT", "SVBIFMT" };
-#define V4L1_IOCTLS (sizeof(v4l1_ioctls)/sizeof(char*))
+#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
 
 int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
 {
@@ -1365,7 +1384,7 @@
         {
                 struct video_tuner *v = arg;
                 
- if (-1 == bttv_tvcards[btv->type].tuner)
+ if (UNSET == bttv_tvcards[btv->type].tuner)
                         return -EINVAL;
                 if (v->tuner) /* Only tuner 0 */
                         return -EINVAL;
@@ -1397,38 +1416,39 @@
         case VIDIOCGCHAN:
         {
                 struct video_channel *v = arg;
+ unsigned int channel = v->channel;
 
- if (v->channel >= bttv_tvcards[btv->type].video_inputs)
+ if (channel >= bttv_tvcards[btv->type].video_inputs)
                         return -EINVAL;
                 v->tuners=0;
                 v->flags = VIDEO_VC_AUDIO;
                 v->type = VIDEO_TYPE_CAMERA;
                 v->norm = btv->tvnorm;
- 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 {
- sprintf(v->name,"Composite%d",v->channel);
+ sprintf(v->name,"Composite%d",channel);
                 }
                 return 0;
         }
         case VIDIOCSCHAN:
         {
                 struct video_channel *v = arg;
+ unsigned int channel = v->channel;
 
- if (v->channel < 0 ||
- v->channel >= bttv_tvcards[btv->type].video_inputs)
+ if (channel >= bttv_tvcards[btv->type].video_inputs)
                         return -EINVAL;
                 if (v->norm >= BTTV_TVNORMS)
                         return -EINVAL;
 
                 down(&btv->lock);
- if (v->channel == btv->input &&
- v->norm == btv->tvnorm) {
+ if (channel == btv->input &&
+ v->norm == btv->tvnorm) {
                         /* nothing to do */
                         up(&btv->lock);
                         return 0;
@@ -1462,9 +1482,9 @@
         case VIDIOCSAUDIO:
         {
                 struct video_audio *v = arg;
+ unsigned int audio = v->audio;
 
- if(v->audio < 0 ||
- v->audio >= bttv_tvcards[btv->type].audio_inputs)
+ if (audio >= bttv_tvcards[btv->type].audio_inputs)
                         return -EINVAL;
 
                 down(&btv->lock);
@@ -1483,11 +1503,13 @@
         case VIDIOC_ENUMSTD:
         {
                 struct v4l2_standard *e = arg;
+ unsigned int index = e->index;
                 
- if (e->index < 0 || e->index >= BTTV_TVNORMS)
+ if (index >= BTTV_TVNORMS)
                         return -EINVAL;
                 v4l2_video_std_construct(e, bttv_tvnorms[e->index].v4l2_id,
                                          bttv_tvnorms[e->index].name);
+ e->index = index;
                 return 0;
         }
         case VIDIOC_G_STD:
@@ -1499,7 +1521,7 @@
         case VIDIOC_S_STD:
         {
                 v4l2_std_id *id = arg;
- int i;
+ unsigned int i;
 
                 for (i = 0; i < BTTV_TVNORMS; i++)
                         if (*id & bttv_tvnorms[i].v4l2_id)
@@ -1527,7 +1549,7 @@
         case VIDIOC_ENUMINPUT:
         {
                 struct v4l2_input *i = arg;
- int n;
+ unsigned int n;
                 
                 n = i->index;
                 if (n >= bttv_tvcards[btv->type].video_inputs)
@@ -1564,9 +1586,9 @@
         }
         case VIDIOC_S_INPUT:
         {
- int *i = arg;
+ unsigned int *i = arg;
                 
- if (*i < 0 || *i > bttv_tvcards[btv->type].video_inputs)
+ if (*i > bttv_tvcards[btv->type].video_inputs)
                         return -EINVAL;
                 down(&btv->lock);
                 set_input(btv,*i);
@@ -1579,7 +1601,7 @@
         {
                 struct v4l2_tuner *t = arg;
 
- if (-1 == bttv_tvcards[btv->type].tuner)
+ if (UNSET == bttv_tvcards[btv->type].tuner)
                         return -EINVAL;
                 if (0 != t->index)
                         return -EINVAL;
@@ -1587,8 +1609,8 @@
                 memset(t,0,sizeof(*t));
                 strcpy(t->name, "Television");
                 t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM;
                 t->rangehigh = 0xffffffffUL;
+ t->capability = V4L2_TUNER_CAP_NORM;
                 t->rxsubchans = V4L2_TUNER_SUB_MONO;
                 if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC)
                         t->signal = 0xffff;
@@ -1599,12 +1621,15 @@
                         bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
                         if (btv->audio_hook)
                                 btv->audio_hook(btv,&va,0);
- if(va.mode & VIDEO_SOUND_STEREO)
+ if(va.mode & VIDEO_SOUND_STEREO) {
+ t->audmode = V4L2_TUNER_MODE_STEREO;
                                 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
- if(va.mode & VIDEO_SOUND_LANG1)
- t->rxsubchans |= V4L2_TUNER_SUB_LANG1;
- if(va.mode & VIDEO_SOUND_LANG2)
- t->rxsubchans |= V4L2_TUNER_SUB_LANG2;
+ }
+ if(va.mode & VIDEO_SOUND_LANG1) {
+ t->audmode = V4L2_TUNER_MODE_LANG1;
+ t->rxsubchans = V4L2_TUNER_SUB_LANG1
+ | V4L2_TUNER_SUB_LANG2;
+ }
                 }
                 /* FIXME: fill capability+audmode */
                 up(&btv->lock);
@@ -1614,7 +1639,7 @@
         {
                 struct v4l2_tuner *t = arg;
 
- if (-1 == bttv_tvcards[btv->type].tuner)
+ if (UNSET == bttv_tvcards[btv->type].tuner)
                         return -EINVAL;
                 if (0 != t->index)
                         return -EINVAL;
@@ -1622,6 +1647,7 @@
                 {
                         struct video_audio va;
                         memset(&va, 0, sizeof(struct video_audio));
+ bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
                         if (t->audmode == V4L2_TUNER_MODE_MONO)
                                 va.mode = VIDEO_SOUND_MONO;
                         else if (t->audmode == V4L2_TUNER_MODE_STEREO)
@@ -1676,7 +1702,7 @@
 {
         enum v4l2_field field;
         int maxw, maxh;
-
+
         if (win->w.width < 48 || win->w.height < 32)
                 return -EINVAL;
         if (win->clipcount > 2048)
@@ -1705,15 +1731,6 @@
         if (!fixup && (win->w.width > maxw || win->w.height > maxh))
                 return -EINVAL;
 
- if (1 /* depth < 4bpp */) {
- /* adjust and align writes */
- int left = (win->w.left + 3) & ~3;
- int width = win->w.width & ~3;
- while (left + width > win->w.left + win->w.width)
- width -= 4;
- win->w.left = left;
- win->w.width = width;
- }
         if (win->w.width > maxw)
                 win->w.width = maxw;
         if (win->w.height > maxh)
@@ -1728,6 +1745,8 @@
         struct v4l2_clip *clips = NULL;
         int n,size,retval = 0;
 
+ if (NULL == fh->ovfmt)
+ return -EINVAL;
         retval = verify_window(&bttv_tvnorms[btv->tvnorm],win,fixup);
         if (0 != retval)
                 return retval;
@@ -1735,33 +1754,50 @@
         /* copy clips -- luckily v4l1 + v4l2 are binary
            compatible here ...*/
         n = win->clipcount;
- size = sizeof(struct video_clip)*(n+4);
+ size = sizeof(*clips)*(n+4);
         clips = kmalloc(size,GFP_KERNEL);
         if (NULL == clips)
                 return -ENOMEM;
         if (n > 0) {
- if (copy_from_user(clips,win->clips,
- sizeof(struct v4l2_clip)*win->clipcount)) {
+ if (copy_from_user(clips,win->clips,sizeof(struct v4l2_clip)*n)) {
                         kfree(clips);
                         return -EFAULT;
                 }
         }
         /* clip against screen */
         if (NULL != btv->fbuf.base)
- n = bttv_screen_clips(btv->fbuf.width, btv->fbuf.width,
+ n = btcx_screen_clips(btv->fbuf.width, btv->fbuf.width,
                                       &win->w, clips, n);
- bttv_sort_clips(clips,n);
+ btcx_sort_clips(clips,n);
+
+ /* 4-byte alignments */
+ switch (fh->ovfmt->depth) {
+ case 8:
+ case 24:
+ btcx_align(&win->w, clips, n, 3);
+ break;
+ case 16:
+ btcx_align(&win->w, clips, n, 1);
+ break;
+ case 32:
+ /* no alignment fixups needed */
+ break;
+ default:
+ BUG();
+ }
         
         down(&fh->cap.lock);
         if (fh->ov.clips)
                 kfree(fh->ov.clips);
- fh->ov.clips = clips;
- fh->ov.nclips = n;
+ fh->ov.clips = clips;
+ fh->ov.nclips = n;
         
- fh->ov.w = win->w;
- fh->ov.field = win->field;
+ fh->ov.w = win->w;
+ fh->ov.field = win->field;
+ fh->ov.setup_ok = 1;
         btv->init.ov.w.width = win->w.width;
         btv->init.ov.w.height = win->w.height;
+ btv->init.ov.field = win->field;
         
         /* update overlay if needed */
         retval = 0;
@@ -1834,8 +1870,10 @@
                 f->fmt.pix.height = fh->height;
                 f->fmt.pix.field = fh->cap.field;
                 f->fmt.pix.pixelformat = fh->fmt->fourcc;
- f->fmt.pix.sizeimage =
- (fh->width * fh->height * fh->fmt->depth)/8;
+ f->fmt.pix.bytesperline =
+ (f->fmt.pix.width * fh->fmt->depth) >> 3;
+ f->fmt.pix.sizeimage =
+ f->fmt.pix.height * f->fmt.pix.bytesperline;
                 return 0;
         case V4L2_BUF_TYPE_VIDEO_OVERLAY:
                 memset(&f->fmt.win,0,sizeof(struct v4l2_window));
@@ -1843,7 +1881,7 @@
                 f->fmt.win.field = fh->ov.field;
                 return 0;
         case V4L2_BUF_TYPE_VBI_CAPTURE:
- bttv_vbi_fmt(fh,f);
+ bttv_vbi_get_fmt(fh,f);
                 return 0;
         default:
                 return -EINVAL;
@@ -1858,14 +1896,11 @@
         {
                 const struct bttv_format *fmt;
                 enum v4l2_field field;
- int maxw,maxh;
+ unsigned int maxw,maxh;
 
                 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
                 if (NULL == fmt)
                         return -EINVAL;
- if (0 != f->fmt.pix.bytesperline)
- /* FIXME -- not implemented yet */
- return -EINVAL;
 
                 /* fixup format */
                 maxw = bttv_tvnorms[btv->tvnorm].swidth;
@@ -1880,6 +1915,7 @@
                 switch (field) {
                 case V4L2_FIELD_TOP:
                 case V4L2_FIELD_BOTTOM:
+ case V4L2_FIELD_ALTERNATE:
                         maxh = maxh/2;
                         break;
                 case V4L2_FIELD_INTERLACED:
@@ -1887,6 +1923,7 @@
                 case V4L2_FIELD_SEQ_TB:
                         if (fmt->flags & FORMAT_FLAGS_PLANAR)
                                 return -EINVAL;
+ break;
                 default:
                         return -EINVAL;
                 }
@@ -1901,25 +1938,19 @@
                         f->fmt.pix.width = maxw;
                 if (f->fmt.pix.height > maxh)
                         f->fmt.pix.height = maxh;
+ f->fmt.pix.bytesperline =
+ (f->fmt.pix.width * fmt->depth) >> 3;
                 f->fmt.pix.sizeimage =
- (fh->width * fh->height * fmt->depth)/8;
+ f->fmt.pix.height * f->fmt.pix.bytesperline;
                 
                 return 0;
         }
         case V4L2_BUF_TYPE_VIDEO_OVERLAY:
                 return verify_window(&bttv_tvnorms[btv->tvnorm],
                                      &f->fmt.win, 1);
-#if 0
         case V4L2_BUF_TYPE_VBI_CAPTURE:
- retval = bttv_switch_type(fh,f->type);
- if (0 != retval)
- return retval;
- if (fh->vbi.reading || fh->vbi.streaming)
- return -EBUSY;
- bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]);
- bttv_vbi_fmt(fh,f);
+ bttv_vbi_try_fmt(fh,f);
                 return 0;
-#endif
         default:
                 return -EINVAL;
         }
@@ -1947,6 +1978,7 @@
                 down(&fh->cap.lock);
                 fh->fmt = fmt;
                 fh->cap.field = f->fmt.pix.field;
+ fh->cap.last = V4L2_FIELD_NONE;
                 fh->width = f->fmt.pix.width;
                 fh->height = f->fmt.pix.height;
                 btv->init.fmt = fmt;
@@ -1962,10 +1994,11 @@
                 retval = bttv_switch_type(fh,f->type);
                 if (0 != retval)
                         return retval;
- if (fh->vbi.reading || fh->vbi.streaming)
- return -EBUSY;
+ if (locked_btres(fh->btv, RESOURCE_VBI))
+ return -EBUSY;
+ bttv_vbi_try_fmt(fh,f);
                 bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]);
- bttv_vbi_fmt(fh,f);
+ bttv_vbi_get_fmt(fh,f);
                 return 0;
         default:
                 return -EINVAL;
@@ -1978,7 +2011,7 @@
         struct bttv_fh *fh = file->private_data;
         struct bttv *btv = fh->btv;
         unsigned long flags;
- int retval;
+ int retval = 0;
 
         if (bttv_debug > 1) {
                 switch (_IOC_TYPE(cmd)) {
@@ -2092,7 +2125,7 @@
                 struct video_window *win = arg;
                 struct v4l2_window w2;
 
- w2.field = V4L2_FIELD_ANY;
+ w2.field = V4L2_FIELD_ANY;
                 w2.w.left = win->x;
                 w2.w.top = win->y;
                 w2.w.width = win->width;
@@ -2181,11 +2214,7 @@
                         /* verify args */
                         if (NULL == btv->fbuf.base)
                                 return -EINVAL;
- if (fh->ov.w.width <48 ||
- fh->ov.w.height<32 ||
- fh->ov.w.width >bttv_tvnorms[btv->tvnorm].swidth ||
- fh->ov.w.height>bttv_tvnorms[btv->tvnorm].sheight||
- NULL == fh->ovfmt)
+ if (!fh->ov.setup_ok)
                                 return -EINVAL;
                 }
 
@@ -2210,7 +2239,7 @@
         case VIDIOCGMBUF:
         {
                 struct video_mbuf *mbuf = arg;
- int i;
+ unsigned int i;
 
                 down(&fh->cap.lock);
                 retval = videobuf_mmap_setup(file,&fh->cap,gbuffers,gbufsize);
@@ -2290,6 +2319,53 @@
                 return retval;
         }
 
+ case VIDIOCGVBIFMT:
+ {
+ struct vbi_format *fmt = (void *) arg;
+ struct v4l2_format fmt2;
+
+ retval = bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE);
+ if (0 != retval)
+ return retval;
+ bttv_vbi_get_fmt(fh, &fmt2);
+
+ fmt->sampling_rate = fmt2.fmt.vbi.sampling_rate;
+ fmt->samples_per_line = fmt2.fmt.vbi.samples_per_line;
+ fmt->sample_format = VIDEO_PALETTE_RAW;
+ fmt->start[0] = fmt2.fmt.vbi.start[0];
+ fmt->count[0] = fmt2.fmt.vbi.count[0];
+ fmt->start[1] = fmt2.fmt.vbi.start[1];
+ fmt->count[1] = fmt2.fmt.vbi.count[1];
+ if (fmt2.fmt.vbi.flags & VBI_UNSYNC)
+ fmt->flags |= V4L2_VBI_UNSYNC;
+ if (fmt2.fmt.vbi.flags & VBI_INTERLACED)
+ fmt->flags |= V4L2_VBI_INTERLACED;
+ return 0;
+ }
+ case VIDIOCSVBIFMT:
+ {
+ struct vbi_format *fmt = (void *) arg;
+ struct v4l2_format fmt2;
+
+ retval = bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE);
+ if (0 != retval)
+ return retval;
+ bttv_vbi_get_fmt(fh, &fmt2);
+
+ if (fmt->sampling_rate != fmt2.fmt.vbi.sampling_rate ||
+ fmt->samples_per_line != fmt2.fmt.vbi.samples_per_line ||
+ fmt->sample_format != VIDEO_PALETTE_RAW ||
+ fmt->start[0] != fmt2.fmt.vbi.start[0] ||
+ fmt->start[1] != fmt2.fmt.vbi.start[1] ||
+ fmt->count[0] != fmt->count[1] ||
+ fmt->count[0] < 1 ||
+ fmt->count[0] > 32 /* VBI_MAXLINES */)
+ return -EINVAL;
+
+ bttv_vbi_setlines(fh,btv,fmt->count[0]);
+ return 0;
+ }
+
         case BTTV_VERSION:
         case VIDIOCGFREQ:
         case VIDIOCSFREQ:
@@ -2326,7 +2402,8 @@
         {
                 struct v4l2_fmtdesc *f = arg;
                 enum v4l2_buf_type type;
- int i, index;
+ unsigned int i;
+ int index;
 
                 type = f->type;
                 if (V4L2_BUF_TYPE_VBI_CAPTURE == type) {
@@ -2347,7 +2424,7 @@
                 for (i = 0; i < BTTV_FORMATS; i++) {
                         if (bttv_formats[i].fourcc != -1)
                                 index++;
- if (index == f->index)
+ if ((unsigned int)index == f->index)
                                 break;
                 }
                 if (BTTV_FORMATS == i)
@@ -2604,8 +2681,8 @@
 
         if (fh->btv->errors)
                 bttv_reinit_bt848(fh->btv);
- dprintk("read count=%d type=%s\n",
- (int)count,v4l2_type_names[fh->type]);
+ dprintk("bttv%d: read count=%d type=%s\n",
+ fh->btv->nr,(int)count,v4l2_type_names[fh->type]);
 
         switch (fh->type) {
         case V4L2_BUF_TYPE_VIDEO_CAPTURE:
@@ -2628,6 +2705,7 @@
 {
         struct bttv_fh *fh = file->private_data;
         struct bttv_buffer *buf;
+ enum v4l2_field field;
 
         if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
                 if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI))
@@ -2654,7 +2732,8 @@
                                 up(&fh->cap.lock);
                                 return POLLERR;
                         }
- if (0 != fh->cap.ops->buf_prepare(file,fh->cap.read_buf,fh->cap.field)) {
+ field = videobuf_next_field(&fh->cap);
+ if (0 != fh->cap.ops->buf_prepare(file,fh->cap.read_buf,field)) {
                                 up(&fh->cap.lock);
                                 return POLLERR;
                         }
@@ -2674,11 +2753,11 @@
 
 static int bttv_open(struct inode *inode, struct file *file)
 {
- unsigned int minor = minor(inode->i_rdev);
+ int minor = minor(inode->i_rdev);
         struct bttv *btv = NULL;
         struct bttv_fh *fh;
         enum v4l2_buf_type type = 0;
- int i;
+ unsigned int i;
 
         dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor);
 
@@ -2707,6 +2786,7 @@
         file->private_data = fh;
         *fh = btv->init;
         fh->type = type;
+ fh->ov.setup_ok = 0;
         videobuf_queue_init(&fh->cap, &bttv_video_qops,
                             btv->dev, &btv->s_lock,
                             V4L2_BUF_TYPE_VIDEO_CAPTURE,
@@ -2720,6 +2800,8 @@
         i2c_vidiocschan(btv);
 
         btv->users++;
+ if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
+ bttv_vbi_setlines(fh,btv,16);
         bttv_field_count(btv);
         return 0;
 }
@@ -2807,10 +2889,10 @@
 
 static int radio_open(struct inode *inode, struct file *file)
 {
- unsigned int minor = minor(inode->i_rdev);
+ int minor = minor(inode->i_rdev);
         struct bttv *btv = NULL;
- unsigned long v = 400*16;
- int i;
+ u32 v = 400*16;
+ unsigned int i;
 
         dprintk("bttv: open minor=%d\n",minor);
 
@@ -2934,10 +3016,10 @@
 
 static void bttv_print_irqbits(u32 print, u32 mark)
 {
- int i;
+ unsigned int i;
         
         printk("bits:");
- for (i = 0; i < (sizeof(irq_name)/sizeof(char*)); i++) {
+ for (i = 0; i < ARRAY_SIZE(irq_name); i++) {
                 if (print & (1 << i))
                         printk(" %s",irq_name[i]);
                 if (mark & (1 << i))
@@ -2950,22 +3032,132 @@
         printk(" main: %08Lx\n",
                (u64)btv->main.dma);
         printk(" vbi : o=%08Lx e=%08Lx\n",
- btv->vcurr ? (u64)btv->vcurr->top.dma : 0,
- btv->vcurr ? (u64)btv->vcurr->bottom.dma : 0);
+ btv->curr.vbi ? (u64)btv->curr.vbi->top.dma : 0,
+ btv->curr.vbi ? (u64)btv->curr.vbi->bottom.dma : 0);
         printk(" cap : o=%08Lx e=%08Lx\n",
- btv->top ? (u64)btv->top->top.dma : 0,
- btv->bottom ? (u64)btv->bottom->bottom.dma : 0);
+ btv->curr.top ? (u64)btv->curr.top->top.dma : 0,
+ btv->curr.bottom ? (u64)btv->curr.bottom->bottom.dma : 0);
         printk(" scr : o=%08Lx e=%08Lx\n",
                btv->screen ? (u64)btv->screen->top.dma : 0,
                btv->screen ? (u64)btv->screen->bottom.dma : 0);
 }
 
+static int
+bttv_irq_next_set(struct bttv *btv, struct bttv_buffer_set *set)
+{
+ struct bttv_buffer *item;
+
+ memset(set,0,sizeof(*set));
+
+ /* vbi request ? */
+ if (!list_empty(&btv->vcapture)) {
+ set->irqflags = 1;
+ set->vbi = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue);
+ }
+
+ /* capture request ? */
+ if (!list_empty(&btv->capture)) {
+ set->irqflags = 1;
+ item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
+ if (V4L2_FIELD_HAS_TOP(item->vb.field))
+ set->top = item;
+ if (V4L2_FIELD_HAS_BOTTOM(item->vb.field))
+ set->bottom = item;
+
+ /* capture request for other field ? */
+ if (!V4L2_FIELD_HAS_BOTH(item->vb.field) &&
+ (item->vb.queue.next != &btv->capture)) {
+ item = list_entry(item->vb.queue.next, struct bttv_buffer, vb.queue);
+ if (!V4L2_FIELD_HAS_BOTH(item->vb.field)) {
+ if (NULL == set->top &&
+ V4L2_FIELD_TOP == item->vb.field) {
+ set->top = item;
+ }
+ if (NULL == set->bottom &&
+ V4L2_FIELD_BOTTOM == item->vb.field) {
+ set->bottom = item;
+ }
+ if (NULL != set->top && NULL != set->bottom)
+ set->topirq = 2;
+ }
+ }
+ }
+
+ /* screen overlay ? */
+ if (NULL != btv->screen) {
+ if (V4L2_FIELD_HAS_BOTH(btv->screen->vb.field)) {
+ if (NULL == set->top && NULL == set->bottom) {
+ set->top = btv->screen;
+ set->bottom = btv->screen;
+ }
+ } else {
+ if (V4L2_FIELD_TOP == btv->screen->vb.field &&
+ NULL == set->top) {
+ set->top = btv->screen;
+ }
+ if (V4L2_FIELD_BOTTOM == btv->screen->vb.field &&
+ NULL == set->bottom) {
+ set->bottom = btv->screen;
+ }
+ }
+ }
+
+ dprintk("bttv%d: next set: top=%p bottom=%p vbi=%p "
+ "[screen=%p,irq=%d,%d]\n",
+ btv->nr,set->top, set->bottom, set->vbi,
+ btv->screen,set->irqflags,set->topirq);
+ return 0;
+}
+
+static void
+bttv_irq_wakeup_set(struct bttv *btv, struct bttv_buffer_set *wakeup,
+ struct bttv_buffer_set *curr, unsigned int state)
+{
+ struct timeval ts;
+
+ do_gettimeofday(&ts);
+
+ if (NULL != wakeup->vbi) {
+ wakeup->vbi->vb.ts = ts;
+ wakeup->vbi->vb.field_count = btv->field_count;
+ wakeup->vbi->vb.state = state;
+ wake_up(&wakeup->vbi->vb.done);
+ }
+ if (wakeup->top == wakeup->bottom) {
+ if (NULL != wakeup->top && curr->top != wakeup->top) {
+ if (irq_debug)
+ printk("bttv%d: wakeup: both=%p\n",btv->nr,wakeup->top);
+ wakeup->top->vb.ts = ts;
+ wakeup->top->vb.field_count = btv->field_count;
+ wakeup->top->vb.state = state;
+ wake_up(&wakeup->top->vb.done);
+ }
+ } else {
+ if (NULL != wakeup->top && curr->top != wakeup->top) {
+ if (irq_debug)
+ printk("bttv%d: wakeup: top=%p\n",btv->nr,wakeup->top);
+ wakeup->top->vb.ts = ts;
+ wakeup->top->vb.field_count = btv->field_count;
+ wakeup->top->vb.state = state;
+ wake_up(&wakeup->top->vb.done);
+ }
+ if (NULL != wakeup->bottom && curr->bottom != wakeup->bottom) {
+ if (irq_debug)
+ printk("bttv%d: wakeup: bottom=%p\n",btv->nr,wakeup->bottom);
+ wakeup->bottom->vb.ts = ts;
+ wakeup->bottom->vb.field_count = btv->field_count;
+ wakeup->bottom->vb.state = state;
+ wake_up(&wakeup->bottom->vb.done);
+ }
+ }
+}
+
 static void bttv_irq_timeout(unsigned long data)
 {
         struct bttv *btv = (struct bttv *)data;
- struct bttv_buffer *o_bottom,*o_top,*o_vcurr;
- struct bttv_buffer *capture;
-
+ struct bttv_buffer_set old,new;
+ struct bttv_buffer *item;
+
         if (bttv_verbose) {
                 printk(KERN_INFO "bttv%d: timeout: risc=%08x, ",
                        btv->nr,btread(BT848_RISC_COUNT));
@@ -2974,53 +3166,29 @@
         }
 
         spin_lock(&btv->s_lock);
- o_top = btv->top;
- o_bottom = btv->bottom;
- o_vcurr = btv->vcurr;
- btv->top = NULL;
- btv->bottom = NULL;
- btv->vcurr = NULL;
         
         /* deactivate stuff */
- bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
- bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
- bttv_risc_hook(btv, RISC_SLOT_O_VBI, NULL, 0);
- bttv_risc_hook(btv, RISC_SLOT_E_VBI, NULL, 0);
+ memset(&new,0,sizeof(new));
+ old = btv->curr;
+ btv->curr = new;
+ bttv_buffer_set_activate(btv, &new);
         bttv_set_dma(btv, 0, 0);
 
- /* wake up + free */
- if (o_top == o_bottom) {
- if (NULL != o_top) {
- o_top->vb.state = STATE_ERROR;
- wake_up(&o_top->vb.done);
- }
- } else {
- if (NULL != o_top) {
- o_top->vb.state = STATE_ERROR;
- wake_up(&o_top->vb.done);
- }
- if (NULL != o_bottom) {
- o_bottom->vb.state = STATE_ERROR;
- wake_up(&o_bottom->vb.done);
- }
- }
- if (NULL != o_vcurr) {
- o_vcurr->vb.state = STATE_ERROR;
- wake_up(&o_vcurr->vb.done);
- }
+ /* wake up */
+ bttv_irq_wakeup_set(btv, &old, &new, STATE_ERROR);
 
         /* cancel all outstanding capture / vbi requests */
         while (!list_empty(&btv->capture)) {
- capture = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
- list_del(&capture->vb.queue);
- capture->vb.state = STATE_ERROR;
- wake_up(&capture->vb.done);
+ item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
+ list_del(&item->vb.queue);
+ item->vb.state = STATE_ERROR;
+ wake_up(&item->vb.done);
         }
         while (!list_empty(&btv->vcapture)) {
- capture = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue);
- list_del(&capture->vb.queue);
- capture->vb.state = STATE_ERROR;
- wake_up(&capture->vb.done);
+ item = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue);
+ list_del(&item->vb.queue);
+ item->vb.state = STATE_ERROR;
+ wake_up(&item->vb.done);
         }
         
         btv->errors++;
@@ -3028,131 +3196,53 @@
 }
 
 static void
-bttv_irq_switch_fields(struct bttv *btv)
+bttv_irq_wakeup_top(struct bttv *btv)
 {
- struct bttv_buffer *o_bottom,*o_top,*o_vcurr;
- struct bttv_buffer *capture;
- dma_addr_t rc;
- int irqflags = 0;
- struct timeval ts;
+ struct bttv_buffer *wakeup = btv->curr.top;
 
- spin_lock(&btv->s_lock);
- o_top = btv->top;
- o_bottom = btv->bottom;
- o_vcurr = btv->vcurr;
- btv->top = NULL;
- btv->bottom = NULL;
- btv->vcurr = NULL;
+ if (NULL == wakeup)
+ return;
 
- /* vbi request ? */
- if (!list_empty(&btv->vcapture)) {
- irqflags = 1;
- btv->vcurr = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue);
- list_del(&btv->vcurr->vb.queue);
- }
-
- /* capture request ? */
- if (!list_empty(&btv->capture)) {
- irqflags = 1;
- capture = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
- list_del(&capture->vb.queue);
- if (V4L2_FIELD_HAS_TOP(capture->vb.field))
- btv->top = capture;
- if (V4L2_FIELD_HAS_BOTTOM(capture->vb.field))
- btv->bottom = capture;
+ spin_lock(&btv->s_lock);
+ btv->curr.topirq = 0;
+ btv->curr.top = NULL;
+ bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
 
- /* capture request for other field ? */
- if (!V4L2_FIELD_HAS_BOTH(capture->vb.field) &&
- !list_empty(&btv->capture)) {
- capture = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
- if (!V4L2_FIELD_HAS_BOTH(capture->vb.field)) {
- if (NULL == btv->top &&
- V4L2_FIELD_TOP == capture->vb.field) {
- btv->top = capture;
- list_del(&capture->vb.queue);
- }
- if (NULL == btv->bottom &&
- V4L2_FIELD_BOTTOM == capture->vb.field) {
- btv->bottom = capture;
- list_del(&capture->vb.queue);
- }
- }
- }
- }
+ do_gettimeofday(&wakeup->vb.ts);
+ wakeup->vb.field_count = btv->field_count;
+ wakeup->vb.state = STATE_DONE;
+ wake_up(&wakeup->vb.done);
+ spin_unlock(&btv->s_lock);
+}
 
- /* screen overlay ? */
- if (NULL != btv->screen) {
- if (V4L2_FIELD_HAS_BOTH(btv->screen->vb.field)) {
- if (NULL == btv->top && NULL == btv->bottom) {
- btv->top = btv->screen;
- btv->bottom = btv->screen;
- }
- } else {
- if (V4L2_FIELD_TOP == btv->screen->vb.field &&
- NULL == btv->top) {
- btv->top = btv->screen;
- }
- if (V4L2_FIELD_BOTTOM == btv->screen->vb.field &&
- NULL == btv->bottom) {
- btv->bottom = btv->screen;
- }
- }
- }
+static void
+bttv_irq_switch_fields(struct bttv *btv)
+{
+ struct bttv_buffer_set new;
+ struct bttv_buffer_set old;
+ dma_addr_t rc;
 
- if (irq_debug)
- printk(KERN_DEBUG "bttv%d: irq top=0x%08x bottom=0x%08x"
- " vbi=0x%08x/0x%08x\n", btv->nr,
- btv->top ? btv->top->top.dma : 0,
- btv->bottom ? btv->bottom->bottom.dma : 0,
- btv->vcurr ? btv->vcurr->top.dma : 0,
- btv->vcurr ? btv->vcurr->bottom.dma : 0);
+ spin_lock(&btv->s_lock);
 
+ /* new buffer set */
+ bttv_irq_next_set(btv, &new);
         rc = btread(BT848_RISC_COUNT);
- if (rc < btv->main.dma || rc > btv->main.dma + 0x100)
- printk("bttv%d: Huh? IRQ latency? main=0x%x rc=0x%x\n",
- btv->nr,btv->main.dma,rc);
-
- /* activate new fields */
- bttv_buffer_activate(btv,btv->top,btv->bottom);
- if (btv->vcurr) {
- btv->vcurr->vb.state = STATE_ACTIVE;
- bttv_risc_hook(btv, RISC_SLOT_O_VBI, &btv->vcurr->top, 0);
- bttv_risc_hook(btv, RISC_SLOT_E_VBI, &btv->vcurr->bottom, 0);
- } else {
- bttv_risc_hook(btv, RISC_SLOT_O_VBI, NULL, 0);
- bttv_risc_hook(btv, RISC_SLOT_E_VBI, NULL, 0);
- }
- bttv_set_dma(btv, 0, irqflags);
-
- /* wake up + free */
- do_gettimeofday(&ts);
- if (o_top == o_bottom) {
- if (NULL != o_top && btv->top != o_top) {
- o_top->vb.ts = ts;
- o_top->vb.field_count = btv->field_count;
- o_top->vb.state = STATE_DONE;
- wake_up(&o_top->vb.done);
- }
- } else {
- if (NULL != o_top && btv->top != o_top) {
- o_top->vb.ts = ts;
- o_top->vb.field_count = btv->field_count;
- o_top->vb.state = STATE_DONE;
- wake_up(&o_top->vb.done);
- }
- if (NULL != o_bottom && btv->bottom != o_bottom) {
- o_bottom->vb.ts = ts;
- o_bottom->vb.field_count = btv->field_count;
- o_bottom->vb.state = STATE_DONE;
- wake_up(&o_bottom->vb.done);
- }
- }
- if (NULL != o_vcurr) {
- o_vcurr->vb.ts = ts;
- o_vcurr->vb.field_count = btv->field_count;
- o_vcurr->vb.state = STATE_DONE;
- wake_up(&o_vcurr->vb.done);
- }
+ if (rc < btv->main.dma || rc > btv->main.dma + 0x100) {
+ if (1 /* irq_debug */)
+ printk("bttv%d: skipped frame. no signal? high irq latency?\n",
+ btv->nr);
+ spin_unlock(&btv->s_lock);
+ return;
+ }
+
+ /* switch over */
+ old = btv->curr;
+ btv->curr = new;
+ bttv_buffer_set_activate(btv, &new);
+ bttv_set_dma(btv, 0, new.irqflags);
+
+ /* wake up finished buffers */
+ bttv_irq_wakeup_set(btv, &old, &new, STATE_DONE);
         spin_unlock(&btv->s_lock);
 }
 
@@ -3178,7 +3268,7 @@
                 /* get device status bits */
                 dstat=btread(BT848_DSTATUS);
 
- if (irq_debug) {
+ if (0 /*irq_debug*/) {
                         printk(KERN_DEBUG "bttv%d: irq loop=%d fc=%d "
                                "riscs=%x, riscc=%08x, ",
                                btv->nr, count, btv->field_count,
@@ -3201,7 +3291,10 @@
 
                 if (astat & BT848_INT_GPINT)
                         wake_up(&btv->gpioq);
-
+
+ if ((astat & BT848_INT_RISCI) && (stat & (2<<28)))
+ bttv_irq_wakeup_top(btv);
+
                 if ((astat & BT848_INT_RISCI) && (stat & (1<<28)))
                         bttv_irq_switch_fields(btv);
 
@@ -3308,7 +3401,8 @@
         btv->timeout.data = (unsigned long)btv;
         
         btv->i2c_rc = -1;
- btv->tuner_type = -1;
+ btv->tuner_type = UNSET;
+ btv->pinnacle_id = UNSET;
 
         memcpy(&btv->video_dev, &bttv_video_template, sizeof(bttv_video_template));
         memcpy(&btv->radio_dev, &radio_template, sizeof(radio_template));
@@ -3485,7 +3579,7 @@
                 video_unregister_device(&btv->vbi_dev);
 
         /* free allocated memory */
- bttv_riscmem_free(btv->dev,&btv->main);
+ btcx_riscmem_free(btv->dev,&btv->main);
 
         /* free ressources */
         free_irq(btv->dev->irq,btv);
@@ -3519,6 +3613,7 @@
 
 static int bttv_init_module(void)
 {
+ int rc;
         bttv_num = 0;
 
         printk(KERN_INFO "bttv: driver version %d.%d.%d loaded\n",
@@ -3536,7 +3631,13 @@
 
         bttv_check_chipset();
 
- return pci_module_init(&bttv_pci_driver);
+ rc = pci_module_init(&bttv_pci_driver);
+ if (-ENODEV == rc) {
+ /* plenty of people trying to use bttv for the cx2388x ... */
+ if (NULL != pci_find_device(0x14f1, 0x8800, NULL))
+ printk("bttv doesn't support your Conexant 2388x card.\n");
+ }
+ return rc;
 }
 
 static void bttv_cleanup_module(void)
diff -u linux-2.5.69/drivers/media/video/bttv-if.c linux/drivers/media/video/bttv-if.c
--- linux-2.5.69/drivers/media/video/bttv-if.c 2003-05-08 13:29:56.000000000 +0200
+++ linux/drivers/media/video/bttv-if.c 2003-05-08 13:55:11.000000000 +0200
@@ -198,6 +198,9 @@
 
         if (btv->tuner_type != UNSET)
                 bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
+ if (btv->pinnacle_id != UNSET)
+ bttv_call_i2c_clients(btv,AUDC_CONFIG_PINNACLE,
+ &btv->pinnacle_id);
 
         if (bttv_debug)
                 printk("bttv%d: i2c attach [client=%s]\n",
@@ -231,9 +234,9 @@
 
 static struct i2c_adapter bttv_i2c_adap_template = {
         .owner = THIS_MODULE,
+ .class = I2C_ADAP_CLASS_TV_ANALOG,
         I2C_DEVNAME("bt848"),
         .id = I2C_HW_B_BT848,
- .class = I2C_ADAP_CLASS_TV_ANALOG,
         .client_register = attach_inform,
 };
 
diff -u linux-2.5.69/drivers/media/video/bttv-risc.c linux/drivers/media/video/bttv-risc.c
--- linux-2.5.69/drivers/media/video/bttv-risc.c 2003-05-08 13:30:56.000000000 +0200
+++ linux/drivers/media/video/bttv-risc.c 2003-05-08 13:55:11.000000000 +0200
@@ -35,58 +35,24 @@
 #include "bttvp.h"
 
 /* ---------------------------------------------------------- */
-/* allocate/free risc memory */
-
-int bttv_riscmem_alloc(struct pci_dev *pci,
- struct bttv_riscmem *risc,
- unsigned int size)
-{
- u32 *cpu;
- dma_addr_t dma;
-
- cpu = pci_alloc_consistent(pci, size, &dma);
- if (NULL == cpu)
- return -ENOMEM;
- memset(cpu,0,size);
-
- if (risc->cpu && risc->size < size) {
- /* realloc (enlarge buffer) -- copy old stuff */
- memcpy(cpu,risc->cpu,risc->size);
- bttv_riscmem_free(pci,risc);
- }
- risc->cpu = cpu;
- risc->dma = dma;
- risc->size = size;
-
- return 0;
-}
-
-void bttv_riscmem_free(struct pci_dev *pci,
- struct bttv_riscmem *risc)
-{
- if (NULL == risc->cpu)
- return;
- pci_free_consistent(pci, risc->size, risc->cpu, risc->dma);
- memset(risc,0,sizeof(*risc));
-}
-
-/* ---------------------------------------------------------- */
 /* risc code generators */
 
 int
-bttv_risc_packed(struct bttv *btv, struct bttv_riscmem *risc,
+bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
                  struct scatterlist *sglist,
- int offset, int bpl, int padding, int lines)
+ unsigned int offset, unsigned int bpl,
+ unsigned int padding, unsigned int lines)
 {
- int instructions,rc,line,todo;
+ u32 instructions,line,todo;
         struct scatterlist *sg;
         u32 *rp;
+ int rc;
 
         /* estimate risc mem: worst case is one write per page border +
            one write per scan line + sync + jump (all 2 dwords) */
         instructions = (bpl * lines) / PAGE_SIZE + lines;
         instructions += 2;
- if ((rc = bttv_riscmem_alloc(btv->dev,risc,instructions*8)) < 0)
+ if ((rc = btcx_riscmem_alloc(btv->dev,risc,instructions*8)) < 0)
                 return rc;
 
         /* sync instruction */
@@ -130,6 +96,7 @@
                 }
                 offset += padding;
         }
+ dprintk("bttv%d: risc planar: %d sglist elems\n", btv->nr, (int)(sg-sglist));
 
         /* save pointer to jmp instruction address */
         risc->jmp = rp;
@@ -137,24 +104,27 @@
 }
 
 int
-bttv_risc_planar(struct bttv *btv, struct bttv_riscmem *risc,
+bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
                  struct scatterlist *sglist,
- int yoffset, int ybpl, int ypadding, int ylines,
- int uoffset, int voffset, int hshift, int vshift,
- int cpadding)
+ unsigned int yoffset, unsigned int ybpl,
+ unsigned int ypadding, unsigned int ylines,
+ unsigned int uoffset, unsigned int voffset,
+ unsigned int hshift, unsigned int vshift,
+ unsigned int cpadding)
 {
- int instructions,rc,line,todo,ylen,chroma;
+ unsigned int instructions,line,todo,ylen,chroma;
         u32 *rp,ri;
         struct scatterlist *ysg;
         struct scatterlist *usg;
         struct scatterlist *vsg;
+ int rc;
 
         /* estimate risc mem: worst case is one write per page border +
            one write per scan line (5 dwords)
            plus sync + jump (2 dwords) */
         instructions = (ybpl * ylines * 2) / PAGE_SIZE + ylines;
         instructions += 2;
- if ((rc = bttv_riscmem_alloc(btv->dev,risc,instructions*4*5)) < 0)
+ if ((rc = btcx_riscmem_alloc(btv->dev,risc,instructions*4*5)) < 0)
                 return rc;
 
         /* sync instruction */
@@ -231,138 +201,13 @@
         return 0;
 }
 
-/* ---------------------------------------------------------- */
-
-struct SKIPLIST {
- int start;
- int end;
-};
-
 int
-bttv_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
- struct v4l2_clip *clips, int n)
-{
- if (win->left < 0) {
- /* left */
- clips[n].c.left = 0;
- clips[n].c.top = 0;
- clips[n].c.width = -win->left;
- clips[n].c.height = win->height;
- n++;
- }
- if (win->left + win->width > swidth) {
- /* right */
- clips[n].c.left = swidth - win->left;
- clips[n].c.top = 0;
- clips[n].c.width = win->width - clips[n].c.left;
- clips[n].c.height = win->height;
- n++;
- }
- if (win->top < 0) {
- /* top */
- clips[n].c.left = 0;
- clips[n].c.top = 0;
- clips[n].c.width = win->width;
- clips[n].c.height = -win->top;
- n++;
- }
- if (win->top + win->height > sheight) {
- /* bottom */
- clips[n].c.left = 0;
- clips[n].c.top = sheight - win->top;
- clips[n].c.width = win->width;
- clips[n].c.height = win->height - clips[n].c.top;
- n++;
- }
- return n;
-}
-
-void
-bttv_sort_clips(struct v4l2_clip *clips, int nclips)
-{
- struct v4l2_clip swap;
- int i,j,n;
-
- for (i = nclips-2; i >= 0; i--) {
- for (n = 0, j = 0; j <= i; j++) {
- if (clips[j].c.left > clips[j+1].c.left) {
- swap = clips[j];
- clips[j] = clips[j+1];
- clips[j+1] = swap;
- n++;
- }
- }
- if (0 == n)
- break;
- }
-}
-
-static void
-calc_skips(int line, int width, int *maxy,
- struct SKIPLIST *skips, int *nskips,
- const struct v4l2_clip *clips, int nclips)
-{
- int clip,skip,maxline,end;
-
- skip=0;
- maxline = 9999;
- for (clip = 0; clip < nclips; clip++) {
-
- /* sanity checks */
- if (clips[clip].c.left + clips[clip].c.width <= 0)
- continue;
- if (clips[clip].c.left > width)
- break;
-
- /* vertical range */
- if (line > clips[clip].c.top+clips[clip].c.height-1)
- continue;
- if (line < clips[clip].c.top) {
- if (maxline > clips[clip].c.top-1)
- maxline = clips[clip].c.top-1;
- continue;
- }
- if (maxline > clips[clip].c.top+clips[clip].c.height-1)
- maxline = clips[clip].c.top+clips[clip].c.height-1;
-
- /* horizontal range */
- if (0 == skip || clips[clip].c.left > skips[skip-1].end) {
- /* new one */
- skips[skip].start = clips[clip].c.left;
- if (skips[skip].start < 0)
- skips[skip].start = 0;
- skips[skip].end = clips[clip].c.left + clips[clip].c.width;
- if (skips[skip].end > width)
- skips[skip].end = width;
- skip++;
- } else {
- /* overlaps -- expand last one */
- end = clips[clip].c.left + clips[clip].c.width;
- if (skips[skip-1].end < end)
- skips[skip-1].end = end;
- if (skips[skip-1].end > width)
- skips[skip-1].end = width;
- }
- }
- *nskips = skip;
- *maxy = maxline;
-
- if (bttv_debug) {
- printk(KERN_DEBUG "bttv: skips line %d-%d:",line,maxline);
- for (skip = 0; skip < *nskips; skip++) {
- printk(" %d-%d",skips[skip].start,skips[skip].end);
- }
- printk("\n");
- }
-}
-
-int
-bttv_risc_overlay(struct bttv *btv, struct bttv_riscmem *risc,
+bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
                   const struct bttv_format *fmt, struct bttv_overlay *ov,
                   int skip_even, int skip_odd)
 {
         int instructions,rc,line,maxy,start,end,skip,nskips;
- struct SKIPLIST *skips;
+ struct btcx_skiplist *skips;
         u32 *rp,ri,ra;
         u32 addr;
 
@@ -375,7 +220,7 @@
         instructions = (ov->nclips + 1) *
                 ((skip_even || skip_odd) ? ov->w.height>>1 : ov->w.height);
         instructions += 2;
- if ((rc = bttv_riscmem_alloc(btv->dev,risc,instructions*8)) < 0)
+ if ((rc = btcx_riscmem_alloc(btv->dev,risc,instructions*8)) < 0)
                 return rc;
 
         /* sync instruction */
@@ -397,8 +242,8 @@
 
                 /* calculate clipping */
                 if (line > maxy)
- calc_skips(line, ov->w.width, &maxy,
- skips, &nskips, ov->clips, ov->nclips);
+ btcx_calc_skips(line, ov->w.width, &maxy,
+ skips, &nskips, ov->clips, ov->nclips);
 
                 /* write out risc code */
                 for (start = 0, skip = 0; start < ov->w.width; start = end) {
@@ -432,7 +277,6 @@
 
         /* save pointer to jmp instruction address */
         risc->jmp = rp;
-
         kfree(skips);
         return 0;
 }
@@ -476,6 +320,7 @@
         geo->vdelay = vdelay;
         geo->width = width;
         geo->sheight = tvnorm->sheight;
+ geo->vtotal = tvnorm->vtotal;
 
         if (btv->opt_combfilter) {
                 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
@@ -506,6 +351,8 @@
         btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
         btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
         btwrite(geo->crop, BT848_E_CROP+off);
+ btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
+ btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
 }
 
 /* ---------------------------------------------------------- */
@@ -518,9 +365,9 @@
         int capctl;
 
         btv->cap_ctl = 0;
- if (NULL != btv->top) btv->cap_ctl |= 0x02;
- if (NULL != btv->bottom) btv->cap_ctl |= 0x01;
- if (NULL != btv->vcurr) btv->cap_ctl |= 0x0c;
+ if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
+ if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
+ if (NULL != btv->curr.vbi) btv->cap_ctl |= 0x0c;
 
         capctl = 0;
         capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
@@ -530,14 +377,16 @@
         d2printk(KERN_DEBUG
                  "bttv%d: capctl=%x irq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
                  btv->nr,capctl,irqflags,
- btv->vcurr ? (u64)btv->vcurr->top.dma : 0,
- btv->top ? (u64)btv->top->top.dma : 0,
- btv->vcurr ? (u64)btv->vcurr->bottom.dma : 0,
- btv->bottom ? (u64)btv->bottom->bottom.dma : 0);
+ btv->curr.vbi ? (u64)btv->curr.vbi->top.dma : 0,
+ btv->curr.top ? (u64)btv->curr.top->top.dma : 0,
+ btv->curr.vbi ? (u64)btv->curr.vbi->bottom.dma : 0,
+ btv->curr.bottom ? (u64)btv->curr.bottom->bottom.dma : 0);
         
         cmd = BT848_RISC_JUMP;
         if (irqflags) {
- cmd |= BT848_RISC_IRQ | (irqflags << 16);
+ cmd |= BT848_RISC_IRQ;
+ cmd |= (irqflags & 0x0f) << 16;
+ cmd |= (~irqflags & 0x0f) << 20;
                 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
         } else {
                 del_timer(&btv->timeout);
@@ -565,7 +414,7 @@
 {
         int rc;
         
- if ((rc = bttv_riscmem_alloc(btv->dev,&btv->main,PAGE_SIZE)) < 0)
+ if ((rc = btcx_riscmem_alloc(btv->dev,&btv->main,PAGE_SIZE)) < 0)
                 return rc;
         dprintk(KERN_DEBUG "bttv%d: risc main @ %08Lx\n",
                 btv->nr,(u64)btv->main.dma);
@@ -600,7 +449,7 @@
 }
 
 int
-bttv_risc_hook(struct bttv *btv, int slot, struct bttv_riscmem *risc,
+bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
                int irqflags)
 {
         unsigned long cmd;
@@ -614,8 +463,11 @@
                 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n",
                          btv->nr,risc,slot,(u64)risc->dma,irqflags);
                 cmd = BT848_RISC_JUMP;
- if (irqflags)
- cmd |= BT848_RISC_IRQ | (irqflags << 16);
+ if (irqflags) {
+ cmd |= BT848_RISC_IRQ;
+ cmd |= (irqflags & 0x0f) << 16;
+ cmd |= (~irqflags & 0x0f) << 20;
+ }
                 risc->jmp[0] = cpu_to_le32(cmd);
                 risc->jmp[1] = cpu_to_le32(next);
                 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
@@ -631,43 +483,68 @@
         videobuf_waiton(&buf->vb,0,0);
         videobuf_dma_pci_unmap(btv->dev, &buf->vb.dma);
         videobuf_dma_free(&buf->vb.dma);
- bttv_riscmem_free(btv->dev,&buf->bottom);
- bttv_riscmem_free(btv->dev,&buf->top);
+ btcx_riscmem_free(btv->dev,&buf->bottom);
+ btcx_riscmem_free(btv->dev,&buf->top);
         buf->vb.state = STATE_NEEDS_INIT;
 }
 
 int
-bttv_buffer_activate(struct bttv *btv,
- struct bttv_buffer *top,
- struct bttv_buffer *bottom)
-{
- if (NULL != top && NULL != bottom) {
- top->vb.state = STATE_ACTIVE;
- bottom->vb.state = STATE_ACTIVE;
- bttv_apply_geo(btv, &top->geo, 1);
- bttv_apply_geo(btv, &bottom->geo,0);
- bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &top->top, 0);
- bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &bottom->bottom, 0);
- btaor((top->btformat & 0xf0) | (bottom->btformat & 0x0f),
+bttv_buffer_set_activate(struct bttv *btv,
+ struct bttv_buffer_set *set)
+{
+ /* vbi capture */
+ if (set->vbi) {
+ set->vbi->vb.state = STATE_ACTIVE;
+ list_del(&set->vbi->vb.queue);
+ bttv_risc_hook(btv, RISC_SLOT_O_VBI, &set->vbi->top, 0);
+ bttv_risc_hook(btv, RISC_SLOT_E_VBI, &set->vbi->bottom, 0);
+ } else {
+ bttv_risc_hook(btv, RISC_SLOT_O_VBI, NULL, 0);
+ bttv_risc_hook(btv, RISC_SLOT_E_VBI, NULL, 0);
+ }
+
+ /* video capture */
+ if (NULL != set->top && NULL != set->bottom) {
+ if (set->top == set->bottom) {
+ set->top->vb.state = STATE_ACTIVE;
+ if (set->top->vb.queue.next)
+ list_del(&set->top->vb.queue);
+ } else {
+ set->top->vb.state = STATE_ACTIVE;
+ set->bottom->vb.state = STATE_ACTIVE;
+ if (set->top->vb.queue.next)
+ list_del(&set->top->vb.queue);
+ if (set->bottom->vb.queue.next)
+ list_del(&set->bottom->vb.queue);
+ }
+ bttv_apply_geo(btv, &set->top->geo, 1);
+ bttv_apply_geo(btv, &set->bottom->geo,0);
+ bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, set->topirq);
+ bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, 0);
+ btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
                       ~0xff, BT848_COLOR_FMT);
- btaor((top->btswap & 0x0a) | (bottom->btswap & 0x05),
+ btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
                       ~0x0f, BT848_COLOR_CTL);
- } else if (NULL != top) {
- top->vb.state = STATE_ACTIVE;
- bttv_apply_geo(btv, &top->geo,1);
- bttv_apply_geo(btv, &top->geo,0);
- bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &top->top, 0);
- bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
- btaor(top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
- btaor(top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
- } else if (NULL != bottom) {
- bottom->vb.state = STATE_ACTIVE;
- bttv_apply_geo(btv, &bottom->geo,1);
- bttv_apply_geo(btv, &bottom->geo,0);
- bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
- bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &bottom->bottom, 0);
- btaor(bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
- btaor(bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
+ } else if (NULL != set->top) {
+ set->top->vb.state = STATE_ACTIVE;
+ if (set->top->vb.queue.next)
+ list_del(&set->top->vb.queue);
+ bttv_apply_geo(btv, &set->top->geo,1);
+ bttv_apply_geo(btv, &set->top->geo,0);
+ bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, 0);
+ bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
+ btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
+ btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
+ } else if (NULL != set->bottom) {
+ set->bottom->vb.state = STATE_ACTIVE;
+ if (set->bottom->vb.queue.next)
+ list_del(&set->bottom->vb.queue);
+ bttv_apply_geo(btv, &set->bottom->geo,1);
+ bttv_apply_geo(btv, &set->bottom->geo,0);
+ bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
+ bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, 0);
+ btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
+ btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
         } else {
                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
@@ -734,12 +611,12 @@
                         /* Y-Cr-Cb plane order */
                         uoffset >>= buf->fmt->hshift;
                         uoffset >>= buf->fmt->vshift;
- uoffset += voffset;
+ uoffset += voffset;
                 } else {
                         /* Y-Cb-Cr plane order */
                         voffset >>= buf->fmt->hshift;
                         voffset >>= buf->fmt->vshift;
- voffset += uoffset;
+ voffset += uoffset;
                 }
 
                 switch (buf->vb.field) {
@@ -781,6 +658,29 @@
                                          buf->fmt->vshift,
                                          cpadding);
                         break;
+ case V4L2_FIELD_SEQ_TB:
+ bttv_calc_geo(btv,&buf->geo,buf->vb.width,
+ buf->vb.height,1,buf->tvnorm);
+ lines = buf->vb.height >> 1;
+ ypadding = buf->vb.width;
+ cpadding = buf->vb.width >> buf->fmt->hshift;
+ bttv_risc_planar(btv,&buf->top,
+ buf->vb.dma.sglist,
+ 0,buf->vb.width,0,lines,
+ uoffset >> 1,
+ voffset >> 1,
+ buf->fmt->hshift,
+ buf->fmt->vshift,
+ 0);
+ bttv_risc_planar(btv,&buf->bottom,
+ buf->vb.dma.sglist,
+ lines * ypadding,buf->vb.width,0,lines,
+ lines * ypadding + (uoffset >> 1),
+ lines * ypadding + (voffset >> 1),
+ buf->fmt->hshift,
+ buf->fmt->vshift,
+ 0);
+ break;
                 default:
                         BUG();
                 }
diff -u linux-2.5.69/drivers/media/video/bttv-vbi.c linux/drivers/media/video/bttv-vbi.c
--- linux-2.5.69/drivers/media/video/bttv-vbi.c 2003-05-08 13:31:15.000000000 +0200
+++ linux/drivers/media/video/bttv-vbi.c 2003-05-08 13:55:11.000000000 +0200
@@ -63,7 +63,7 @@
 }
 
 static int vbi_buffer_setup(struct file *file,
- unsigned int *count, unsigned int *size)
+ unsigned int *count, unsigned int *size)
 {
         struct bttv_fh *fh = file->private_data;
         struct bttv *btv = fh->btv;
@@ -155,7 +155,43 @@
         }
 }
 
-void bttv_vbi_fmt(struct bttv_fh *fh, struct v4l2_format *f)
+void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f)
+{
+ u32 start0,start1,count0,count1,count;
+
+ f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
+ f->fmt.vbi.sampling_rate = 35468950;
+ f->fmt.vbi.samples_per_line = 2048;
+ f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
+ f->fmt.vbi.offset = 244;
+ f->fmt.vbi.flags = 0;
+ switch (fh->btv->tvnorm) {
+ case 1: /* NTSC */
+ start0 = 10;
+ start1 = 273;
+ break;
+ case 0: /* PAL */
+ case 2: /* SECAM */
+ default:
+ start0 = 7;
+ start1 = 319;
+ }
+
+ count0 = (f->fmt.vbi.start[0] + f->fmt.vbi.count[0]) - start0;
+ count1 = (f->fmt.vbi.start[1] + f->fmt.vbi.count[1]) - start1;
+ count = max(count0,count1);
+ if (count > VBI_MAXLINES)
+ count = VBI_MAXLINES;
+ if (count < 1)
+ count = 1;
+
+ f->fmt.vbi.start[0] = start0;
+ f->fmt.vbi.start[1] = start1;
+ f->fmt.vbi.count[0] = count;
+ f->fmt.vbi.count[1] = count;
+}
+
+void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f)
 {
         memset(f,0,sizeof(*f));
         f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
diff -u linux-2.5.69/drivers/media/video/bttv.h linux/drivers/media/video/bttv.h
--- linux-2.5.69/drivers/media/video/bttv.h 2003-05-08 13:29:56.000000000 +0200
+++ linux/drivers/media/video/bttv.h 2003-05-08 13:55:11.000000000 +0200
@@ -90,6 +90,7 @@
 #define BTTV_SENSORAY311 0x49
 #define BTTV_RV605 0x4a
 #define BTTV_WINDVR 0x4c
+#define BTTV_GRANDTEC 0x4d
 #define BTTV_KWORLD 0x4e
 #define BTTV_HAUPPAUGEPVR 0x50
 #define BTTV_GVBCTV5PCI 0x51
@@ -108,6 +109,11 @@
 #define BTTV_PINNACLESAT 0x5e
 #define BTTV_FORMAC_PROTV 0x5f
 #define BTTV_EURESYS_PICOLO 0x61
+#define BTTV_PV150 0x62
+#define BTTV_AD_TVK503 0x63
+#define BTTV_IVC200 0x66
+#define BTTV_XGUARD 0x67
+#define BTTV_NEBULA_DIGITV 0x68
 
 /* i2c address list */
 #define I2C_TSA5522 0xc2
@@ -123,6 +129,7 @@
 #define I2C_STBEE 0xae
 #define I2C_VHX 0xc0
 #define I2C_MSP3400 0x80
+#define I2C_MSP3400_ALT 0x88
 #define I2C_TEA6300 0x80
 #define I2C_DPL3518 0x84
 #define I2C_TDA9887 0x86
@@ -145,36 +152,37 @@
 struct tvcard
 {
         char *name;
- int video_inputs;
- int audio_inputs;
- int tuner;
- int svhs;
- int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
+ unsigned int video_inputs;
+ unsigned int audio_inputs;
+ unsigned int tuner;
+ unsigned int svhs;
+ unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
         u32 gpiomask;
         u32 muxsel[16];
         u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
         u32 gpiomask2; /* GPIO MUX mask */
 
         /* i2c audio flags */
- int no_msp34xx:1;
- int no_tda9875:1;
- int no_tda7432:1;
- int needs_tvaudio:1;
+ unsigned int no_msp34xx:1;
+ unsigned int no_tda9875:1;
+ unsigned int no_tda7432:1;
+ unsigned int needs_tvaudio:1;
+ unsigned int msp34xx_alt:1;
 
         /* other settings */
- int pll;
+ unsigned int pll;
 #define PLL_NONE 0
 #define PLL_28 1
 #define PLL_35 2
 
- int tuner_type;
- int has_radio;
+ unsigned int tuner_type;
+ unsigned int has_radio;
         void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set);
         void (*muxsel_hook)(struct bttv *btv, unsigned int input);
 };
 
 extern struct tvcard bttv_tvcards[];
-extern const int bttv_num_tvcards;
+extern const unsigned int bttv_num_tvcards;
 
 /* identification / initialization of the card */
 extern void bttv_idcard(struct bttv *btv);
diff -u linux-2.5.69/drivers/media/video/bttvp.h linux/drivers/media/video/bttvp.h
--- linux-2.5.69/drivers/media/video/bttvp.h 2003-05-08 13:30:32.000000000 +0200
+++ linux/drivers/media/video/bttvp.h 2003-05-08 13:55:11.000000000 +0200
@@ -24,7 +24,7 @@
 #ifndef _BTTVP_H_
 #define _BTTVP_H_
 
-#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,4)
+#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,11)
 
 #include <linux/types.h>
 #include <linux/wait.h>
@@ -40,6 +40,7 @@
 
 #include "bt848.h"
 #include "bttv.h"
+#include "btcx-risc.h"
 
 #ifdef __KERNEL__
 
@@ -66,8 +67,7 @@
 
 /* ---------------------------------------------------------- */
 
-struct bttv_tvnorm
-{
+struct bttv_tvnorm {
         int v4l2_id;
         char *name;
         u32 Fsc;
@@ -78,10 +78,11 @@
         u16 hdelayx1, hactivex1;
         u16 vdelay;
         u8 vbipack;
+ u16 vtotal;
         int sram;
 };
 extern const struct bttv_tvnorm bttv_tvnorms[];
-extern const int BTTV_TVNORMS;
+extern const unsigned int BTTV_TVNORMS;
 
 struct bttv_format {
         char *name;
@@ -94,21 +95,14 @@
         int hshift,vshift; /* for planar modes */
 };
 extern const struct bttv_format bttv_formats[];
-extern const int BTTV_FORMATS;
+extern const unsigned int BTTV_FORMATS;
 
 /* ---------------------------------------------------------- */
 
 struct bttv_geometry {
         u8 vtc,crop,comb;
         u16 width,hscale,hdelay;
- u16 sheight,vscale,vdelay;
-};
-
-struct bttv_riscmem {
- unsigned int size;
- u32 *cpu;
- u32 *jmp;
- dma_addr_t dma;
+ u16 sheight,vscale,vdelay,vtotal;
 };
 
 struct bttv_buffer {
@@ -121,16 +115,25 @@
         int btformat;
         int btswap;
         struct bttv_geometry geo;
- struct bttv_riscmem top;
- struct bttv_riscmem bottom;
+ struct btcx_riscmem top;
+ struct btcx_riscmem bottom;
+};
+
+struct bttv_buffer_set {
+ struct bttv_buffer *top; /* top field buffer */
+ struct bttv_buffer *bottom; /* bottom field buffer */
+ struct bttv_buffer *vbi; /* vbi buffer */
+ unsigned int irqflags;
+ unsigned int topirq;
 };
 
 struct bttv_overlay {
- int tvnorm;
+ int tvnorm;
         struct v4l2_rect w;
         enum v4l2_field field;
         struct v4l2_clip *clips;
         int nclips;
+ int setup_ok;
 };
 
 struct bttv_fh {
@@ -140,7 +143,6 @@
 
         /* video capture */
         struct videobuf_queue cap;
- /* struct bttv_buffer buf; */
         const struct bttv_format *fmt;
         int width;
         int height;
@@ -157,28 +159,19 @@
 /* ---------------------------------------------------------- */
 /* bttv-risc.c */
 
-/* alloc/free memory */
-int bttv_riscmem_alloc(struct pci_dev *pci,
- struct bttv_riscmem *risc,
- unsigned int size);
-void bttv_riscmem_free(struct pci_dev *pci,
- struct bttv_riscmem *risc);
-
 /* risc code generators - capture */
-int bttv_risc_packed(struct bttv *btv, struct bttv_riscmem *risc,
+int bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
                      struct scatterlist *sglist,
- int offset, int bpl, int pitch, int lines);
-int bttv_risc_planar(struct bttv *btv, struct bttv_riscmem *risc,
+ unsigned int offset, unsigned int bpl,
+ unsigned int pitch, unsigned int lines);
+int bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
                      struct scatterlist *sglist,
- int yoffset, int ybpl, int ypadding, int ylines,
- int uoffset, int voffset, int hshift, int vshift,
- int cpadding);
-
-/* risc code generator + helpers - screen overlay */
-int bttv_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
- struct v4l2_clip *clips, int n);
-void bttv_sort_clips(struct v4l2_clip *clips, int nclips);
-int bttv_risc_overlay(struct bttv *btv, struct bttv_riscmem *risc,
+ unsigned int yoffset, unsigned int ybpl,
+ unsigned int ypadding, unsigned int ylines,
+ unsigned int uoffset, unsigned int voffset,
+ unsigned int hshift, unsigned int vshift,
+ unsigned int cpadding);
+int bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
                       const struct bttv_format *fmt,
                       struct bttv_overlay *ov,
                       int skip_top, int skip_bottom);
@@ -191,13 +184,13 @@
 /* control dma register + risc main loop */
 void bttv_set_dma(struct bttv *btv, int override, int irqflags);
 int bttv_risc_init_main(struct bttv *btv);
-int bttv_risc_hook(struct bttv *btv, int slot, struct bttv_riscmem *risc,
+int bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
                    int irqflags);
 
 /* capture buffer handling */
 int bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf);
-int bttv_buffer_activate(struct bttv *btv, struct bttv_buffer *top,
- struct bttv_buffer *bottom);
+int bttv_buffer_set_activate(struct bttv *btv,
+ struct bttv_buffer_set *set);
 void bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf);
 
 /* overlay handling */
@@ -209,7 +202,8 @@
 /* ---------------------------------------------------------- */
 /* bttv-vbi.c */
 
-void bttv_vbi_fmt(struct bttv_fh *fh, struct v4l2_format *f);
+void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f);
+void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f);
 void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines);
 
 extern struct videobuf_queue_ops bttv_vbi_qops;
@@ -236,7 +230,7 @@
 
 /* our devices */
 #define BTTV_MAX 4
-extern int bttv_num;
+extern unsigned int bttv_num;
 extern struct bttv bttvs[BTTV_MAX];
 
 #define BTTV_MAX_FBUF 0x208000
@@ -263,8 +257,9 @@
         unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */
         char name[8]; /* dev name */
         unsigned int cardid; /* pci subsystem id (bt878 based ones) */
- int type; /* card type (pointer into tvcards[]) */
- int tuner_type; /* tuner chip type */
+ unsigned int type; /* card type (pointer into tvcards[]) */
+ unsigned int tuner_type; /* tuner chip type */
+ unsigned int pinnacle_id;
         struct bttv_pll_info pll;
         int triton1;
 
@@ -291,12 +286,12 @@
         struct semaphore reslock;
 
         /* video state */
- int input;
- int audio;
+ unsigned int input;
+ unsigned int audio;
         unsigned long freq;
         int tvnorm,hue,contrast,bright,saturation;
         struct video_buffer fbuf;
- int field_count;
+ unsigned int field_count;
 
         /* various options */
         int opt_combfilter;
@@ -325,21 +320,19 @@
 
         /* risc memory management data
            - must aquire s_lock before changing these
- - only the irq handler is supported to touch odd + even */
- struct bttv_riscmem main;
- struct bttv_buffer *top; /* current active top field */
- struct bttv_buffer *bottom; /* current active bottom field */
- struct bttv_buffer *screen; /* overlay */
- struct list_head capture; /* capture buffer queue */
- struct bttv_buffer *vcurr;
- struct list_head vcapture;
+ - only the irq handler is supported to touch top + bottom + vcurr */
+ struct btcx_riscmem main;
+ struct bttv_buffer *screen; /* overlay */
+ struct list_head capture; /* video capture queue */
+ struct list_head vcapture; /* vbi capture queue */
+ struct bttv_buffer_set curr; /* active buffers */
 
         unsigned long cap_ctl;
         unsigned long dma_on;
         struct timer_list timeout;
- int errors;
+ unsigned int errors;
 
- int users;
+ unsigned int users;
         struct bttv_fh init;
 };
 

-- 
sigfault
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu May 15 2003 - 22:00:40 EST