From: Gerd Knorr <kraxel@bytesex.org>

  Hi,

Yet another big one (due to not being updated for a long time) --
saa7134 driver update.  Changes:

 * various bugfixes / cleanups.
 * new cards added to the cardlist.
 * started support for saa7133/35 chips.
 * make the driver check pci quirks.

Please apply,

  Gerd

diff -u linux-2.5.69/drivers/media/video/saa7134/saa7134-cards.c linux/drivers/media/video/saa7134/saa7134-cards.c


 25-akpm/drivers/media/video/saa7134/saa7134-cards.c   |  202 +++++-
 25-akpm/drivers/media/video/saa7134/saa7134-core.c    |  217 ++++--
 25-akpm/drivers/media/video/saa7134/saa7134-i2c.c     |    9 
 25-akpm/drivers/media/video/saa7134/saa7134-oss.c     |  188 +++--
 25-akpm/drivers/media/video/saa7134/saa7134-reg.h     |   13 
 25-akpm/drivers/media/video/saa7134/saa7134-ts.c      |   18 
 25-akpm/drivers/media/video/saa7134/saa7134-tvaudio.c |  591 ++++++++++++++----
 25-akpm/drivers/media/video/saa7134/saa7134-vbi.c     |    9 
 25-akpm/drivers/media/video/saa7134/saa7134-video.c   |  237 ++++---
 25-akpm/drivers/media/video/saa7134/saa7134.h         |  170 ++---
 10 files changed, 1230 insertions(+), 424 deletions(-)

diff -puN drivers/media/video/saa7134/saa7134-cards.c~v4l-7 drivers/media/video/saa7134/saa7134-cards.c
--- 25/drivers/media/video/saa7134/saa7134-cards.c~v4l-7	Mon May 12 15:33:16 2003
+++ 25-akpm/drivers/media/video/saa7134/saa7134-cards.c	Mon May 12 15:33:16 2003
@@ -29,6 +29,7 @@
 static char name_mute[]    = "mute";
 static char name_radio[]   = "Radio";
 static char name_tv[]      = "Television";
+static char name_tv_mono[] = "TV (mono only)";
 static char name_comp1[]   = "Composite1";
 static char name_comp2[]   = "Composite2";
 static char name_svideo[]  = "S-Video";
@@ -61,6 +62,11 @@ struct saa7134_board saa7134_boards[] = 
 			.vmux = 1,
 			.amux = TV,
 			.tv   = 1,
+		},{
+			.name = name_tv_mono,
+			.vmux = 1,
+			.amux = LINE2,
+			.tv   = 1,
 		}},
 	},
 	[SAA7134_BOARD_FLYVIDEO3000] = {
@@ -68,27 +74,39 @@ struct saa7134_board saa7134_boards[] = 
 		.name		= "LifeView FlyVIDEO3000",
 		.audio_clock	= 0x00200000,
 		.tuner_type	= TUNER_PHILIPS_PAL,
+		.gpiomask       = 0xe000,
 		.inputs         = {{
 			.name = name_tv,
 			.vmux = 1,
 			.amux = TV,
+			.gpio = 0x8000,
+			.tv   = 1,
+                },{
+			.name = name_tv_mono,
+			.vmux = 1,
+			.amux = LINE2,
+			.gpio = 0x0000,
 			.tv   = 1,
 		},{
 			.name = name_comp1,
 			.vmux = 0,
-			.amux = LINE1,
+			.amux = LINE2,
+			.gpio = 0x4000,
 		},{
 			.name = name_comp2,
 			.vmux = 3,
-			.amux = LINE1,
+			.amux = LINE2,
+			.gpio = 0x4000,
 		},{
 			.name = name_svideo,
 			.vmux = 8,
-			.amux = LINE1,
+			.amux = LINE2,
+			.gpio = 0x4000,
 		}},
 		.radio = {
 			.name = name_radio,
 			.amux = LINE2,
+			.gpio = 0x2000,
 		},
 	},
 	[SAA7134_BOARD_FLYVIDEO2000] = {
@@ -96,7 +114,7 @@ struct saa7134_board saa7134_boards[] = 
 		.name           = "LifeView FlyVIDEO2000",
 		.audio_clock    = 0x00200000,
 		.tuner_type     = TUNER_LG_PAL_NEW_TAPC,
-		.gpiomask       = 0x6000,
+		.gpiomask       = 0xe000,
 		.inputs         = {{
 			.name = name_tv,
 			.vmux = 1,
@@ -122,10 +140,12 @@ struct saa7134_board saa7134_boards[] = 
                 .radio = {
                         .name = name_radio,
                         .amux = LINE2,
+			.gpio = 0x2000,
                 },
 		.mute = {
 			.name = name_mute,
-			.amux = LINE1,
+                        .amux = LINE2,
+			.gpio = 0x8000,
 		},
 	},
 	[SAA7134_BOARD_EMPRESS] = {
@@ -190,7 +210,7 @@ struct saa7134_board saa7134_boards[] = 
 			.tv   = 1,
 		},{
 			/* workaround for problems with normal TV sound */
-			.name = "TV (mono only)",
+			.name = name_tv_mono,
 			.vmux = 1,
 			.amux = LINE2,
 			.tv   = 1,
@@ -270,6 +290,12 @@ struct saa7134_board saa7134_boards[] = 
 			.amux = TV,
 			.tv   = 1,
 		},{
+			/* workaround for problems with normal TV sound */
+			.name = name_tv_mono,
+			.vmux = 1,
+			.amux = LINE2,
+			.tv   = 1,
+		},{
 			.name = name_comp1,
 			.vmux = 0,
 			.amux = LINE2,
@@ -302,7 +328,7 @@ struct saa7134_board saa7134_boards[] = 
                 },{
                         .name = name_tv,
                         .vmux = 1,
-                        .amux = TV,
+                        .amux = LINE2,
                         .tv   = 1,
                 }},
         },
@@ -332,7 +358,6 @@ struct saa7134_board saa7134_boards[] = 
 			.name = name_radio,
 			.amux = LINE2,
                },
-
         },
 	[SAA7134_BOARD_MD7134] = {
 		.name           = "Medion 7134",
@@ -343,7 +368,7 @@ struct saa7134_board saa7134_boards[] = 
 			.name   = name_tv,
 			.vmux   = 1,
 			.amux   = LINE2,
-			.tv     =   1,
+			.tv     = 1,
 		},{
 			.name   = name_comp1,
 			.vmux   = 0,
@@ -361,9 +386,67 @@ struct saa7134_board saa7134_boards[] = 
 			.name   = name_radio,
 			.amux   = LINE2,
 		},
-      },
+	},
+	[SAA7134_BOARD_TYPHOON_90031] = {
+		.name           = "Typhoon TV+Radio 90031",
+		.audio_clock    = 0x00200000,
+		.tuner_type     = TUNER_PHILIPS_PAL,
+		.inputs         = {{
+			.name   = name_tv,
+			.vmux   = 1,
+			.amux   = TV,
+			.tv     = 1,
+		},{
+			.name   = name_comp1,
+			.vmux   = 3,
+			.amux   = LINE1,
+		},{
+			.name   = name_svideo,
+			.vmux   = 8,
+			.amux   = LINE1,
+		}},
+		.radio = {
+			.name   = name_radio,
+			.amux   = LINE2,
+		},
+	},
+	[SAA7134_BOARD_ELSA] = {
+		.name           = "ELSA EX-VISION 300TV",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_HITACHI_NTSC,
+		.inputs         = {{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		},{
+			.name   = name_comp1,
+			.vmux   = 0,
+			.amux   = LINE1,
+		},{
+			.name = name_tv,
+			.vmux = 4,
+			.amux = LINE2,
+			.tv   = 1,
+		}},
+        },
+	[SAA7134_BOARD_ELSA_500TV] = {
+		.name           = "ELSA EX-VISION 500TV",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_HITACHI_NTSC,
+		.inputs         = {{
+			.name = name_svideo,
+			.vmux = 7,
+			.amux = LINE1,
+		},{
+			.name = name_tv,
+			.vmux = 8,
+			.amux = TV,
+			.tv   = 1,
+		}},
+        },
+	
 };
-const int saa7134_bcount = (sizeof(saa7134_boards)/sizeof(struct saa7134_board));
+const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
 
 /* ------------------------------------------------------------------ */
 /* PCI ids + subsystem IDs                                            */
@@ -377,6 +460,12 @@ struct pci_device_id __devinitdata saa71
 		.driver_data  = SAA7134_BOARD_PROTEUS_PRO,
         },{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = PCI_VENDOR_ID_PHILIPS,
+		.subdevice    = 0x2001,
+		.driver_data  = SAA7134_BOARD_PROTEUS_PRO,
+        },{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
 		.subvendor    = PCI_VENDOR_ID_PHILIPS,
 		.subdevice    = 0x6752,
@@ -407,11 +496,29 @@ struct pci_device_id __devinitdata saa71
 		.driver_data  = SAA7134_BOARD_FLYVIDEO3000,
         },{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+		.subvendor    = 0x5168,
+		.subdevice    = 0x0138,
+		.driver_data  = SAA7134_BOARD_FLYVIDEO2000,
+        },{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
 		.subvendor    = 0x16be,
 		.subdevice    = 0x0003,
 		.driver_data  = SAA7134_BOARD_MD7134,
 	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+		.subvendor    = 0x1048,
+		.subdevice    = 0x226b,
+		.driver_data  = SAA7134_BOARD_ELSA,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+		.subvendor    = 0x1048,
+		.subdevice    = 0x226b,
+		.driver_data  = SAA7134_BOARD_ELSA_500TV,
+	},{
 		
 		/* --- boards without eeprom + subsystem ID --- */
                 .vendor       = PCI_VENDOR_ID_PHILIPS,
@@ -435,10 +542,22 @@ struct pci_device_id __devinitdata saa71
 		.driver_data  = SAA7134_BOARD_UNKNOWN,
         },{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+                .subvendor    = PCI_ANY_ID,
+                .subdevice    = PCI_ANY_ID,
+		.driver_data  = SAA7134_BOARD_UNKNOWN,
+        },{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
                 .subvendor    = PCI_ANY_ID,
                 .subdevice    = PCI_ANY_ID,
 		.driver_data  = SAA7134_BOARD_UNKNOWN,
+        },{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7135,
+                .subvendor    = PCI_ANY_ID,
+                .subdevice    = PCI_ANY_ID,
+		.driver_data  = SAA7134_BOARD_UNKNOWN,
 	},{
 		/* --- end of list --- */
 	}
@@ -446,6 +565,67 @@ struct pci_device_id __devinitdata saa71
 MODULE_DEVICE_TABLE(pci, saa7134_pci_tbl);
 
 /* ----------------------------------------------------------- */
+/* flyvideo tweaks                                             */
+
+#if 0
+static struct {
+	char  *model;
+	int   tuner_type;
+} fly_list[0x20] = {
+	/* default catch ... */
+	[ 0 ... 0x1f ] = {
+		.model      = "UNKNOWN",
+		.tuner_type = TUNER_ABSENT,
+	},
+	/* ... the ones known so far */
+	[ 0x05 ] = {
+		.model      = "PAL-BG",
+		.tuner_type = TUNER_LG_PAL_NEW_TAPC,
+	},
+	[ 0x10 ] = {
+		.model      = "PAL-BG / PAL-DK",
+		.tuner_type = TUNER_PHILIPS_PAL,
+	},
+	[ 0x15 ] = {
+		.model      = "NTSC",
+		.tuner_type = TUNER_ABSENT /* FIXME */,
+	},
+};
+#endif
+
+static void board_flyvideo(struct saa7134_dev *dev)
+{
+	u32 value;
+	int index;
+
+	saa_writel(SAA7134_GPIO_GPMODE0 >> 2,   0);
+	value = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
+#if 0
+	index = (value & 0x1f00) >> 8;
+	printk(KERN_INFO "%s: flyvideo: gpio is 0x%x [model=%s,tuner=%d]\n",
+	       dev->name, value, fly_list[index].model,
+	       fly_list[index].tuner_type);
+	dev->tuner_type = fly_list[index].tuner_type;
+#else
+	printk(KERN_INFO "%s: flyvideo: gpio is 0x%x\n",
+	       dev->name, value);
+#endif
+}
+
+/* ----------------------------------------------------------- */
+
+int saa7134_board_init(struct saa7134_dev *dev)
+{
+	switch (dev->board) {
+	case SAA7134_BOARD_FLYVIDEO2000:
+	case SAA7134_BOARD_FLYVIDEO3000:
+		board_flyvideo(dev);
+		break;
+	}
+	return 0;
+}
+
+/* ----------------------------------------------------------- */
 /*
  * Local variables:
  * c-basic-offset: 8
diff -puN drivers/media/video/saa7134/saa7134-core.c~v4l-7 drivers/media/video/saa7134/saa7134-core.c
--- 25/drivers/media/video/saa7134/saa7134-core.c~v4l-7	Mon May 12 15:33:16 2003
+++ 25-akpm/drivers/media/video/saa7134/saa7134-core.c	Mon May 12 15:33:16 2003
@@ -2,7 +2,7 @@
  * device driver for philips saa7134 based TV cards
  * driver core
  *
- * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+ * (c) 2001-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
@@ -67,6 +67,10 @@ static unsigned int radio_nr = -1;
 MODULE_PARM(radio_nr,"i");
 MODULE_PARM_DESC(radio_nr,"radio device number");
 
+static unsigned int oss = 0;
+MODULE_PARM(oss,"i");
+MODULE_PARM_DESC(oss,"register oss devices (default: no)");
+
 static unsigned int dsp_nr = -1;
 MODULE_PARM(dsp_nr,"i");
 MODULE_PARM_DESC(dsp_nr,"oss dsp device number");
@@ -75,20 +79,20 @@ static unsigned int mixer_nr = -1;
 MODULE_PARM(mixer_nr,"i");
 MODULE_PARM_DESC(mixer_nr,"oss mixer device number");
 
-static int tuner[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = -1};
+static unsigned int tuner[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
 MODULE_PARM(tuner,"1-" __stringify(SAA7134_MAXBOARDS) "i");
 MODULE_PARM_DESC(tuner,"tuner type");
 
-static int card[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = -1};
+static unsigned int card[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
 MODULE_PARM(card,"1-" __stringify(SAA7134_MAXBOARDS) "i");
 MODULE_PARM_DESC(card,"card type");
 
-static int latency = -1;
+static unsigned int latency = UNSET;
 MODULE_PARM(latency,"i");
 MODULE_PARM_DESC(latency,"pci latency timer");
 
 struct list_head  saa7134_devlist;
-int               saa7134_devcount;
+unsigned int      saa7134_devcount;
 
 #define dprintk(fmt, arg...)	if (core_debug) \
 	printk(KERN_DEBUG "%s/core: " fmt, dev->name, ## arg)
@@ -102,7 +106,7 @@ static const char *v4l1_ioctls[] = {
 	"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)
 
 static const char *v4l2_ioctls[] = {
 	"QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
@@ -116,7 +120,7 @@ static const char *v4l2_ioctls[] = {
 	"S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
 	"S_MODULATOR"
 };
-#define V4L2_IOCTLS (sizeof(v4l2_ioctls)/sizeof(char*))
+#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
 
 static const char *osspcm_ioctls[] = {
 	"RESET", "SYNC", "SPEED", "STEREO", "GETBLKSIZE", "SETFMT",
@@ -125,7 +129,7 @@ static const char *osspcm_ioctls[] = {
 	"GETIPTR", "GETOPTR", "MAPINBUF", "MAPOUTBUF", "SETSYNCRO",
 	"SETDUPLEX", "GETODELAY"
 };
-#define OSSPCM_IOCTLS (sizeof(v4l2_ioctls)/sizeof(char*))
+#define OSSPCM_IOCTLS ARRAY_SIZE(v4l2_ioctls)
 
 void saa7134_print_ioctl(char *name, unsigned int cmd)
 {
@@ -236,9 +240,9 @@ int saa7134_buffer_pages(int size)
 
 /* calc max # of buffers from size (must not exceed the 4MB virtual
  * address space per DMA channel) */
-int saa7134_buffer_count(int size, int count)
+int saa7134_buffer_count(unsigned int size, unsigned int count)
 {
-	int maxcount;
+	unsigned int maxcount;
 	
 	maxcount = 1024 / saa7134_buffer_pages(size);
 	if (count > maxcount)
@@ -277,11 +281,11 @@ int saa7134_pgtable_alloc(struct pci_dev
 }
 
 int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
-			  struct scatterlist *list, int length,
-			  int startpage)
+			  struct scatterlist *list, unsigned int length,
+			  unsigned int startpage)
 {
-	u32   *ptr;
-	int   i,p;
+	u32           *ptr;
+	unsigned int  i,p;
 
 	BUG_ON(NULL == pt || NULL == pt->cpu);
 
@@ -319,14 +323,25 @@ int saa7134_buffer_queue(struct saa7134_
 			 struct saa7134_dmaqueue *q,
 			 struct saa7134_buf *buf)
 {
+	struct saa7134_buf *next = NULL;
 #if DEBUG_SPINLOCKS
 	BUG_ON(!spin_is_locked(&dev->slock));
 #endif
 	
 	dprintk("buffer_queue %p\n",buf);
 	if (NULL == q->curr) {
-		q->curr = buf;
-		buf->activate(dev,buf,NULL);
+		if (!q->need_two) {
+			q->curr = buf;
+			buf->activate(dev,buf,NULL);
+		} else if (list_empty(&q->queue)) {
+			list_add_tail(&buf->vb.queue,&q->queue);
+			buf->vb.state = STATE_QUEUED;
+		} else {
+			next = list_entry(q->queue.next,struct saa7134_buf,
+					  vb.queue);
+			q->curr = buf;
+			buf->activate(dev,buf,next);
+		}
 	} else {
 		list_add_tail(&buf->vb.queue,&q->queue);
 		buf->vb.state = STATE_QUEUED;
@@ -336,7 +351,7 @@ int saa7134_buffer_queue(struct saa7134_
 
 void saa7134_buffer_finish(struct saa7134_dev *dev,
 			   struct saa7134_dmaqueue *q,
-			   int state)
+			   unsigned int state)
 {
 #if DEBUG_SPINLOCKS
 	BUG_ON(!spin_is_locked(&dev->slock));
@@ -388,6 +403,14 @@ void saa7134_buffer_timeout(unsigned lon
 	unsigned long flags;
 
 	spin_lock_irqsave(&dev->slock,flags);
+
+	/* try to reset the hardware (SWRST) */
+	saa_writeb(SAA7134_REGION_ENABLE, 0x00);
+	saa_writeb(SAA7134_REGION_ENABLE, 0x80);
+	saa_writeb(SAA7134_REGION_ENABLE, 0x00);
+
+	/* flag current buffer as failed,
+	   try to start over with the next one. */
 	if (q->curr) {
 		dprintk("timeout on %p\n",q->curr);
 		saa7134_buffer_finish(dev,q,STATE_ERROR);
@@ -400,7 +423,7 @@ void saa7134_buffer_timeout(unsigned lon
 
 int saa7134_set_dmabits(struct saa7134_dev *dev)
 {
-	unsigned long task=0, ctrl=0, irq=0, split = 0;
+	u32 split, task=0, ctrl=0, irq=0;
 	enum v4l2_field cap = V4L2_FIELD_ANY;
 	enum v4l2_field ov  = V4L2_FIELD_ANY;
 
@@ -460,12 +483,12 @@ int saa7134_set_dmabits(struct saa7134_d
 	
 	/* set task conditions + field handling */
 	if (V4L2_FIELD_HAS_BOTH(cap) || V4L2_FIELD_HAS_BOTH(ov) || cap == ov) {
-		/* default config -- use full frames:
-		   odd A, even A, odd B, even B, repeat */
+		/* default config -- use full frames */
 		saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0d);
 		saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0d);
 		saa_writeb(SAA7134_FIELD_HANDLING(TASK_A),  0x02);
 		saa_writeb(SAA7134_FIELD_HANDLING(TASK_B),  0x02);
+		split = 0;
 	} else {
 		/* split fields between tasks */
 		if (V4L2_FIELD_TOP == cap) {
@@ -494,7 +517,7 @@ int saa7134_set_dmabits(struct saa7134_d
 		   SAA7134_MAIN_CTRL_TE5 |
 		   SAA7134_MAIN_CTRL_TE6,
 		   ctrl);
-	dprintk("dmabits: task=0x%02lx ctrl=0x%02lx irq=0x%lx split=%s\n",
+	dprintk("dmabits: task=0x%02x ctrl=0x%02x irq=0x%x split=%s\n",
 		task, ctrl, irq, split ? "no" : "yes");
 
 	return 0;
@@ -508,12 +531,12 @@ static char *irqbits[] = {
 	"AR", "PE", "PWR_ON", "RDCAP", "INTL", "FIDT", "MMC",
 	"TRIG_ERR", "CONF_ERR", "LOAD_ERR"
 };
-#define IRQBITS (sizeof(irqbits)/sizeof(char*))
+#define IRQBITS ARRAY_SIZE(irqbits)
 
 static void print_irqstatus(struct saa7134_dev *dev, int loop,
 			    unsigned long report, unsigned long status)
 {
-	int i;
+	unsigned int i;
 	
 	printk(KERN_DEBUG "%s/irq[%d,%ld]: r=0x%lx s=0x%02lx",
 	       dev->name,loop,jiffies,report,status);
@@ -536,18 +559,19 @@ static irqreturn_t saa7134_irq(int irq, 
 {
 	struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
 	unsigned long report,status;
-	int loop;
+	int loop, handled = 0;
 
 	for (loop = 0; loop < 10; loop++) {
 		report = saa_readl(SAA7134_IRQ_REPORT);
 		status = saa_readl(SAA7134_IRQ_STATUS);
-		saa_writel(SAA7134_IRQ_REPORT,report);
 		if (0 == report) {
 			if (irq_debug > 1)
 				printk(KERN_DEBUG "%s/irq: no (more) work\n",
 				       dev->name);
 			goto out;
 		}
+		handled = 1;
+		saa_writel(SAA7134_IRQ_REPORT,report);
 		if (irq_debug)
 			print_irqstatus(dev,loop,report,status);
 
@@ -582,8 +606,9 @@ static irqreturn_t saa7134_irq(int irq, 
 		saa_writel(SAA7134_IRQ1,0);
 		saa_writel(SAA7134_IRQ2,0);
 	}
-out:
-	return IRQ_HANDLED;
+
+ out:
+	return IRQ_RETVAL(handled);
 }
 
 /* ------------------------------------------------------------------ */
@@ -599,8 +624,14 @@ static int saa7134_hwinit(struct saa7134
 	saa7134_vbi_init(dev);
 	if (card_has_ts(dev))
 		saa7134_ts_init(dev);
-	if (card_has_audio(dev))
+
+	switch (dev->pci->device) {
+	case PCI_DEVICE_ID_PHILIPS_SAA7134:
+	case PCI_DEVICE_ID_PHILIPS_SAA7133:
+	case PCI_DEVICE_ID_PHILIPS_SAA7135:
 		saa7134_oss_init(dev);
+		break;
+	}
 	
 	/* RAM FIFO config */
 	saa_writel(SAA7134_FIFO_SIZE, 0x08070503);
@@ -634,12 +665,15 @@ static int saa7134_hwinit(struct saa7134
 	/* enable peripheral devices */
 	saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
 
+	/* set vertical line numbering start (vbi needs this) */
+	saa_writeb(SAA7134_SOURCE_TIMING2, 0x20);
+	
 	return 0;
 }
 
 static void __devinit must_configure_manually(void)
 {
-	int i,p;
+	unsigned int i,p;
 
 	printk(KERN_WARNING
 	       "saa7134: <rant>\n"
@@ -675,18 +709,39 @@ static int __devinit saa7134_initdev(str
 		return -ENOMEM;
 	memset(dev,0,sizeof(*dev));
 
-	/* pci stuff */
+	/* pci init */
 	dev->pci = pci_dev;
 	if (pci_enable_device(pci_dev)) {
 		err = -EIO;
 		goto fail1;
 	}
 	sprintf(dev->name,"saa%x[%d]",pci_dev->device,saa7134_devcount);
-	if (-1 != latency) {
+
+	/* pci quirks */
+	if (pci_pci_problems) {
+		if (pci_pci_problems & PCIPCI_TRITON)
+			printk(KERN_INFO "%s: quirk: PCIPCI_TRITON\n", dev->name);
+		if (pci_pci_problems & PCIPCI_NATOMA)
+			printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA\n", dev->name);
+		if (pci_pci_problems & PCIPCI_VIAETBF)
+			printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF\n", dev->name);
+		if (pci_pci_problems & PCIPCI_VSFX)
+			printk(KERN_INFO "%s: quirk: PCIPCI_VSFX\n",dev->name);
+#ifdef PCIPCI_ALIMAGIK
+		if (pci_pci_problems & PCIPCI_ALIMAGIK) {
+			printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n",
+			       dev->name);
+			latency = 0x0A;
+		}
+#endif
+	}
+	if (UNSET != latency) {
 		printk(KERN_INFO "%s: setting pci latency timer to %d\n",
 		       dev->name,latency);
 		pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency);
 	}
+
+	/* print pci info */
 	pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
         pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER,  &dev->pci_lat);
         printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, "
@@ -710,7 +765,7 @@ static int __devinit saa7134_initdev(str
 		dev->board = SAA7134_BOARD_UNKNOWN;
 	}
 	dev->tuner_type = saa7134_boards[dev->board].tuner_type;
-	if (-1 != tuner[saa7134_devcount])
+	if (UNSET != tuner[saa7134_devcount])
 		dev->tuner_type = tuner[saa7134_devcount];
         printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
 	       dev->name,pci_dev->subsystem_vendor,
@@ -730,6 +785,13 @@ static int __devinit saa7134_initdev(str
 	dev->lmmio = ioremap(pci_resource_start(pci_dev,0), 0x1000);
 	dev->bmmio = (__u8*)dev->lmmio;
 
+	/* register i2c bus */
+	saa7134_i2c_register(dev);
+
+	/* initialize hardware */
+	saa7134_board_init(dev);
+	saa7134_hwinit(dev);
+
 	/* get irq */
 	err = request_irq(pci_dev->irq, saa7134_irq,
 			  SA_SHIRQ | SA_INTERRUPT, dev->name, dev);
@@ -739,12 +801,8 @@ static int __devinit saa7134_initdev(str
 		goto fail2;
 	}
 
-	/* initialize hardware */
-	saa7134_hwinit(dev);
-
-	/* register i2c bus + load i2c helpers */
-	saa7134_i2c_register(dev);
-	if (TUNER_ABSENT != card(dev).tuner_type)
+	/* load i2c helpers */
+	if (TUNER_ABSENT != dev->tuner_type)
 		request_module("tuner");
 	if (saa7134_boards[dev->board].need_tda9887)
 		request_module("tda9887");
@@ -793,19 +851,27 @@ static int __devinit saa7134_initdev(str
 	}
 
 	/* register oss devices */
-	if (card_has_audio(dev)) {
-		dev->oss.minor_dsp = register_sound_dsp(&saa7134_dsp_fops,dsp_nr);
-		if (dev->oss.minor_dsp < 0)
-			goto fail7;
-		printk(KERN_INFO "%s: registered device dsp%d\n",
-		       dev->name,dev->oss.minor_dsp >> 4);
-		
-		dev->oss.minor_mixer =
-			register_sound_mixer(&saa7134_mixer_fops,mixer_nr);
-		if (dev->oss.minor_mixer < 0)
-			goto fail8;
-		printk(KERN_INFO "%s: registered device mixer%d\n",
-		       dev->name,dev->oss.minor_mixer >> 4);
+	switch (dev->pci->device) {
+	case PCI_DEVICE_ID_PHILIPS_SAA7134:
+	case PCI_DEVICE_ID_PHILIPS_SAA7133:
+	case PCI_DEVICE_ID_PHILIPS_SAA7135:
+		if (oss) {
+			err = dev->oss.minor_dsp =
+				register_sound_dsp(&saa7134_dsp_fops,dsp_nr);
+			if (err < 0) {
+				goto fail7;
+			}
+			printk(KERN_INFO "%s: registered device dsp%d\n",
+			       dev->name,dev->oss.minor_dsp >> 4);
+			
+			err = dev->oss.minor_mixer =
+				register_sound_mixer(&saa7134_mixer_fops,mixer_nr);
+			if (err < 0)
+				goto fail8;
+			printk(KERN_INFO "%s: registered device mixer%d\n",
+			       dev->name,dev->oss.minor_mixer >> 4);
+		}
+		break;
 	}
 
 	/* everything worked */
@@ -815,8 +881,14 @@ static int __devinit saa7134_initdev(str
 	return 0;
 
  fail8:
-	if (card_has_audio(dev))
-		unregister_sound_dsp(dev->oss.minor_dsp);
+	switch (dev->pci->device) {
+	case PCI_DEVICE_ID_PHILIPS_SAA7134:
+	case PCI_DEVICE_ID_PHILIPS_SAA7133:
+	case PCI_DEVICE_ID_PHILIPS_SAA7135:
+		if (oss)
+			unregister_sound_dsp(dev->oss.minor_dsp);
+		break;
+	}
  fail7:
 	if (card_has_radio(dev))
 		video_unregister_device(&dev->radio_dev);
@@ -828,16 +900,21 @@ static int __devinit saa7134_initdev(str
  fail4:
 	video_unregister_device(&dev->video_dev);
  fail3:
-	if (card_has_audio(dev))
+	saa7134_i2c_unregister(dev);
+	free_irq(pci_dev->irq, dev);
+ fail2:
+	switch (dev->pci->device) {
+	case PCI_DEVICE_ID_PHILIPS_SAA7134:
+	case PCI_DEVICE_ID_PHILIPS_SAA7133:
+	case PCI_DEVICE_ID_PHILIPS_SAA7135:
 		saa7134_oss_fini(dev);
+		break;
+	}
 	if (card_has_ts(dev))
 		saa7134_ts_fini(dev);
 	saa7134_vbi_fini(dev);
 	saa7134_video_fini(dev);
 	saa7134_tvaudio_fini(dev);
-	saa7134_i2c_unregister(dev);
-	free_irq(pci_dev->irq, dev);
- fail2:
 	release_mem_region(pci_resource_start(pci_dev,0),
 			   pci_resource_len(pci_dev,0));
  fail1:
@@ -849,6 +926,13 @@ static void __devexit saa7134_finidev(st
 {
         struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
 
+	/* debugging ... */
+	if (irq_debug) {
+		u32 report = saa_readl(SAA7134_IRQ_REPORT);
+		u32 status = saa_readl(SAA7134_IRQ_STATUS);
+		print_irqstatus(dev,42,report,status);
+	}
+
 	/* disable peripheral devices */
 	saa_writeb(SAA7134_SPECIAL_MODE,0);
 
@@ -858,8 +942,13 @@ static void __devexit saa7134_finidev(st
 	saa_writel(SAA7134_MAIN_CTRL,0);
 
 	/* shutdown subsystems */
-	if (card_has_audio(dev))
+	switch (dev->pci->device) {
+	case PCI_DEVICE_ID_PHILIPS_SAA7134:
+	case PCI_DEVICE_ID_PHILIPS_SAA7133:
+	case PCI_DEVICE_ID_PHILIPS_SAA7135:
 		saa7134_oss_fini(dev);
+		break;
+	}
 	if (card_has_ts(dev))
 		saa7134_ts_fini(dev);
 	saa7134_vbi_fini(dev);
@@ -874,9 +963,15 @@ static void __devexit saa7134_finidev(st
 
 	/* unregister */
 	saa7134_i2c_unregister(dev);
-	if (card_has_audio(dev)) {
-		unregister_sound_mixer(dev->oss.minor_mixer);
-		unregister_sound_dsp(dev->oss.minor_dsp);
+	switch (dev->pci->device) {
+	case PCI_DEVICE_ID_PHILIPS_SAA7134:
+	case PCI_DEVICE_ID_PHILIPS_SAA7133:
+	case PCI_DEVICE_ID_PHILIPS_SAA7135:
+		if (oss) {
+			unregister_sound_mixer(dev->oss.minor_mixer);
+			unregister_sound_dsp(dev->oss.minor_dsp);
+		}
+		break;
 	}
 	if (card_has_radio(dev))
 		video_unregister_device(&dev->radio_dev);
diff -puN drivers/media/video/saa7134/saa7134.h~v4l-7 drivers/media/video/saa7134/saa7134.h
--- 25/drivers/media/video/saa7134/saa7134.h~v4l-7	Mon May 12 15:33:16 2003
+++ 25-akpm/drivers/media/video/saa7134/saa7134.h	Mon May 12 15:33:17 2003
@@ -28,7 +28,7 @@
 #include <media/audiochip.h>
 #include <media/id.h>
 
-#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,2)
+#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,8)
 
 #ifndef TRUE
 # define TRUE (1==1)
@@ -36,6 +36,7 @@
 #ifndef FALSE
 # define FALSE (1==0)
 #endif
+#define UNSET (-1U)
 
 /* 2.4 / 2.5 driver compatibility stuff */
 
@@ -67,50 +68,52 @@ enum saa7134_video_out {
 struct saa7134_tvnorm {
 	char          *name;
 	v4l2_std_id   id;
-	int           width;
-	int           height;
+	unsigned int  width;
+	unsigned int  height;
 
 	/* video decoder */
-	int           sync_control;
-	int           luma_control;
-	int           chroma_ctrl1;
-	int           chroma_gain;
-	int           chroma_ctrl2;
+	unsigned int  sync_control;
+	unsigned int  luma_control;
+	unsigned int  chroma_ctrl1;
+	unsigned int  chroma_gain;
+	unsigned int  chroma_ctrl2;
+	unsigned int  vgate_misc;
 
 	/* video scaler */
-	int           h_start;
-	int           h_stop;
-	int           video_v_start;
-	int           video_v_stop;
-	int           vbi_v_start;
-	int           vbi_v_stop;
+	unsigned int  h_start;
+	unsigned int  h_stop;
+	unsigned int  video_v_start;
+	unsigned int  video_v_stop;
+	unsigned int  vbi_v_start;
+	unsigned int  vbi_v_stop;
+	unsigned int  src_timing;
 };
 
 struct saa7134_tvaudio {
-	char  *name;
-	int   std;
-	enum  saa7134_tvaudio_mode mode;
-	int   carr1;
-	int   carr2;
+	char         *name;
+	v4l2_std_id  std;
+	enum         saa7134_tvaudio_mode mode;
+	int          carr1;
+	int          carr2;
 };
 
 struct saa7134_format {
-	char  *name;
-	int   fourcc;
-	int   depth;
-	int   pm;
-	int   vshift;   /* vertical downsampling (for planar yuv) */
-	int   hshift;   /* horizontal downsampling (for planar yuv) */
-	int   bswap:1;
-	int   wswap:1;
-	int   yuv:1;
-	int   planar:1;
+	char           *name;
+	unsigned int   fourcc;
+	unsigned int   depth;
+	unsigned int   pm;
+	unsigned int   vshift;   /* vertical downsampling (for planar yuv) */
+	unsigned int   hshift;   /* horizontal downsampling (for planar yuv) */
+	unsigned int   bswap:1;
+	unsigned int   wswap:1;
+	unsigned int   yuv:1;
+	unsigned int   planar:1;
 };
 
 /* ----------------------------------------------------------- */
 /* card configuration                                          */
 
-#define SAA7134_BOARD_NOAUTO           -1
+#define SAA7134_BOARD_NOAUTO        UNSET
 #define SAA7134_BOARD_UNKNOWN           0
 #define SAA7134_BOARD_PROTEUS_PRO       1
 #define SAA7134_BOARD_FLYVIDEO3000      2
@@ -124,38 +127,40 @@ struct saa7134_format {
 #define SAA7134_BOARD_KWORLD           10
 #define SAA7134_BOARD_CINERGY600       11
 #define SAA7134_BOARD_MD7134           12
+#define SAA7134_BOARD_TYPHOON_90031    13
+#define SAA7134_BOARD_ELSA             14
+#define SAA7134_BOARD_ELSA_500TV       15
 
 #define SAA7134_INPUT_MAX 8
 
 struct saa7134_input {
 	char                    *name;
-	int                     vmux;
+	unsigned int            vmux;
 	enum saa7134_audio_in   amux;
-	int                     gpio;
-	int                     tv:1;
+	unsigned int            gpio;
+	unsigned int            tv:1;
 };
 
 struct saa7134_board {
 	char                    *name;
-	int                     audio_clock;
+	unsigned int            audio_clock;
 
 	/* input switching */
-	int                     gpiomask;
+	unsigned int            gpiomask;
 	struct saa7134_input    inputs[SAA7134_INPUT_MAX];
 	struct saa7134_input    radio;
 	struct saa7134_input    mute;
 	
 	/* peripheral I/O */
-	int                     i2s_rate;
-	int                     has_ts;
+	unsigned int            i2s_rate;
+	unsigned int            has_ts;
 	enum saa7134_video_out  video_out;
 
 	/* i2c chip info */
-	int                     tuner_type;
-	int                     need_tda9887:1;
+	unsigned int            tuner_type;
+	unsigned int            need_tda9887:1;
 };
 
-#define card_has_audio(dev)   (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7134)
 #define card_has_radio(dev)   (NULL != saa7134_boards[dev->board].radio.name)
 #define card_has_ts(dev)      (saa7134_boards[dev->board].has_ts)
 #define card(dev)             (saa7134_boards[dev->board])
@@ -189,9 +194,9 @@ struct saa7134_thread {
 	struct task_struct         *task;
 	wait_queue_head_t          wq;
 	struct semaphore           *notify;
-	int                        exit;
-	int                        scan1;
-	int                        scan2;
+	unsigned int               exit;
+	unsigned int               scan1;
+	unsigned int               scan2;
 };
 
 /* buffer for one video/vbi/ts frame */
@@ -201,7 +206,7 @@ struct saa7134_buf {
 
 	/* saa7134 specific */
 	struct saa7134_format   *fmt;
-	int                     top_seen;
+	unsigned int            top_seen;
 	int (*activate)(struct saa7134_dev *dev,
 			struct saa7134_buf *buf,
 			struct saa7134_buf *next);
@@ -215,22 +220,23 @@ struct saa7134_dmaqueue {
 	struct saa7134_buf         *curr;
 	struct list_head           queue;
 	struct timer_list          timeout;
+	unsigned int               need_two;
 };
 
 /* video filehandle status */
 struct saa7134_fh {
 	struct saa7134_dev         *dev;
-	int                        radio;
+	unsigned int               radio;
 	enum v4l2_buf_type         type;
 
 	struct v4l2_window         win;
 	struct v4l2_clip           clips[8];
-	int                        nclips;
-	int                        resources;
+	unsigned int               nclips;
+	unsigned int               resources;
 
 	/* video capture */
 	struct saa7134_format      *fmt;
-	int                        width,height;
+	unsigned int               width,height;
 	struct videobuf_queue      cap;
 	struct saa7134_pgtable     pt_cap;
 
@@ -241,7 +247,7 @@ struct saa7134_fh {
 
 /* TS status */
 struct saa7134_ts {
-	int                        users;
+	unsigned int               users;
 
 	/* TS capture */
 	struct videobuf_queue      ts;
@@ -253,28 +259,28 @@ struct saa7134_oss {
         struct semaphore           lock;
 	int                        minor_mixer;
 	int                        minor_dsp;
-	int                        users_dsp;
+	unsigned int               users_dsp;
 
 	/* mixer */
 	enum saa7134_audio_in      input;
-	int                        count;
-	int                        line1;
-	int                        line2;
+	unsigned int               count;
+	unsigned int               line1;
+	unsigned int               line2;
 
 	/* dsp */
-	int                        afmt;
-	int                        rate;
-	int                        channels;
-	int                        recording;
-	int                        blocks;
-	int                        blksize;
-	int                        bufsize;
+	unsigned int               afmt;
+	unsigned int               rate;
+	unsigned int               channels;
+	unsigned int               recording;
+	unsigned int               blocks;
+	unsigned int               blksize;
+	unsigned int               bufsize;
 	struct saa7134_pgtable     pt;
 	struct videobuf_dmabuf     dma;
 	wait_queue_head_t          wq;
-	int                        dma_blk;
-	int                        read_offset;
-	int                        read_count;
+	unsigned int               dma_blk;
+	unsigned int               read_offset;
+	unsigned int               read_count;
 };
 
 /* global device status */
@@ -284,7 +290,7 @@ struct saa7134_dev {
        	spinlock_t                 slock;
 
 	/* various device info */
-	int                        resources;
+	unsigned int               resources;
 	struct video_device        video_dev;
 	struct video_device        ts_dev;
 	struct video_device        radio_dev;
@@ -300,8 +306,8 @@ struct saa7134_dev {
 	__u8                       *bmmio;
 
 	/* config info */
-	int                        board;
-	int                        tuner_type;
+	unsigned int               board;
+	unsigned int               tuner_type;
 
 	/* i2c i/o */
 	struct i2c_adapter         i2c_adap;
@@ -311,19 +317,19 @@ struct saa7134_dev {
 	/* video overlay */
 	struct v4l2_framebuffer    ovbuf;
 	struct saa7134_format      *ovfmt;
-	int                        ovenable;
+	unsigned int               ovenable;
 	enum v4l2_field            ovfield;
 
 	/* video+ts+vbi capture */
 	struct saa7134_dmaqueue    video_q;
 	struct saa7134_dmaqueue    ts_q;
 	struct saa7134_dmaqueue    vbi_q;
-	int                        vbi_fieldcount;
+	unsigned int               vbi_fieldcount;
 
 	/* various v4l controls */
 	struct saa7134_tvnorm      *tvnorm;              /* video */
 	struct saa7134_tvaudio     *tvaudio;
-	int                        ctl_input;
+	unsigned int               ctl_input;
 	int                        ctl_bright;
 	int                        ctl_contrast;
 	int                        ctl_hue;
@@ -337,11 +343,12 @@ struct saa7134_dev {
 	int                        ctl_y_even;
 
 	/* other global state info */
-	int                        automute;
+	unsigned int               automute;
 	struct saa7134_thread      thread;
 	struct saa7134_input       *input;
 	struct saa7134_input       *hw_input;
-	int                        hw_mute;
+	unsigned int               hw_mute;
+	int                        last_carrier;
 };
 
 /* ----------------------------------------------------------- */
@@ -362,12 +369,13 @@ struct saa7134_dev {
 #define saa_setb(reg,bit)          saa_andorb((reg),(bit),(bit))
 #define saa_clearb(reg,bit)        saa_andorb((reg),(bit),0)
 
+#define saa_wait(d) { if (need_resched()) schedule(); else udelay(d);}
 
 /* ----------------------------------------------------------- */
 /* saa7134-core.c                                              */
 
 extern struct list_head  saa7134_devlist;
-extern int               saa7134_devcount;
+extern unsigned int      saa7134_devcount;
 
 void saa7134_print_ioctl(char *name, unsigned int cmd);
 void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
@@ -376,18 +384,18 @@ void saa7134_track_gpio(struct saa7134_d
 
 int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt);
 int  saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
-			   struct scatterlist *list, int length,
-			   int startpage);
+			   struct scatterlist *list, unsigned int length,
+			   unsigned int startpage);
 void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt);
 
-int saa7134_buffer_count(int size, int count);
+int saa7134_buffer_count(unsigned int size, unsigned int count);
 int saa7134_buffer_startpage(struct saa7134_buf *buf);
 unsigned long saa7134_buffer_base(struct saa7134_buf *buf);
 
 int saa7134_buffer_queue(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,
 			 struct saa7134_buf *buf);
 void saa7134_buffer_finish(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,
-			   int state);
+			   unsigned int state);
 void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q);
 void saa7134_buffer_timeout(unsigned long data);
 void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf);
@@ -398,9 +406,11 @@ int saa7134_set_dmabits(struct saa7134_d
 /* saa7134-cards.c                                             */
 
 extern struct saa7134_board saa7134_boards[];
-extern const int saa7134_bcount;
+extern const unsigned int saa7134_bcount;
 extern struct pci_device_id __devinitdata saa7134_pci_tbl[];
 
+extern int saa7134_board_init(struct saa7134_dev *dev);
+
 
 /* ----------------------------------------------------------- */
 /* saa7134-i2c.c                                               */
@@ -449,17 +459,19 @@ void saa7134_irq_vbi_done(struct saa7134
 /* ----------------------------------------------------------- */
 /* saa7134-tvaudio.c                                           */
 
+int saa7134_tvaudio_rx2mode(u32 rx);
+
 void saa7134_tvaudio_setmute(struct saa7134_dev *dev);
 void saa7134_tvaudio_setinput(struct saa7134_dev *dev,
 			      struct saa7134_input *in);
 void saa7134_tvaudio_setvolume(struct saa7134_dev *dev, int level);
-int saa7134_tvaudio_getstereo(struct saa7134_dev *dev,
-			      struct saa7134_tvaudio *audio);
+int saa7134_tvaudio_getstereo(struct saa7134_dev *dev);
 
 int saa7134_tvaudio_init(struct saa7134_dev *dev);
 int saa7134_tvaudio_fini(struct saa7134_dev *dev);
 int saa7134_tvaudio_do_scan(struct saa7134_dev *dev);
 
+int saa_dsp_writel(struct saa7134_dev *dev, int reg, u32 value);
 
 /* ----------------------------------------------------------- */
 /* saa7134-oss.c                                               */
diff -puN drivers/media/video/saa7134/saa7134-i2c.c~v4l-7 drivers/media/video/saa7134/saa7134-i2c.c
--- 25/drivers/media/video/saa7134/saa7134-i2c.c~v4l-7	Mon May 12 15:33:16 2003
+++ 25-akpm/drivers/media/video/saa7134/saa7134-i2c.c	Mon May 12 15:33:16 2003
@@ -153,10 +153,7 @@ static int i2c_is_busy_wait(struct saa71
 		status = i2c_get_status(dev);
 		if (!i2c_is_busy(status))
 			break;
-		if (need_resched())
-                        schedule();
-		else
-			udelay(I2C_WAIT_DELAY);
+		saa_wait(I2C_WAIT_DELAY);
 	}
 	if (I2C_WAIT_RETRY == count)
 		return FALSE;
@@ -318,7 +315,7 @@ static u32 functionality(struct i2c_adap
 static int attach_inform(struct i2c_client *client)
 {
         struct saa7134_dev *dev = client->adapter->algo_data;
-	int tuner = card(dev).tuner_type;
+	int tuner = dev->tuner_type;
 
 	saa7134_i2c_call_clients(dev,TUNER_SET_TYPE,&tuner);
         return 0;
@@ -334,9 +331,9 @@ static struct i2c_algorithm saa7134_algo
 
 static struct i2c_adapter saa7134_adap_template = {
 	.owner         = THIS_MODULE,
+	.class         = I2C_ADAP_CLASS_TV_ANALOG,
 	I2C_DEVNAME("saa7134"),
 	.id            = I2C_ALGO_SAA7134,
-	.class         = I2C_ADAP_CLASS_TV_ANALOG,
 	.algo          = &saa7134_algo,
 	.client_register = attach_inform,
 };
diff -puN drivers/media/video/saa7134/saa7134-oss.c~v4l-7 drivers/media/video/saa7134/saa7134-oss.c
--- 25/drivers/media/video/saa7134/saa7134-oss.c~v4l-7	Mon May 12 15:33:16 2003
+++ 25-akpm/drivers/media/video/saa7134/saa7134-oss.c	Mon May 12 15:33:16 2003
@@ -94,8 +94,9 @@ static int dsp_buffer_free(struct saa713
 
 static int dsp_rec_start(struct saa7134_dev *dev)
 {
-	int err, fmt, bswap, wswap;
-	unsigned long control,flags;
+	int err, bswap, sign;
+	u32 fmt, control;
+	unsigned long flags;
 
 	/* prepare buffer */
 	if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->oss.dma)))
@@ -110,45 +111,60 @@ static int dsp_rec_start(struct saa7134_
 
 	/* sample format */
 	switch (dev->oss.afmt) {
-	case AFMT_U8:     fmt = 0x00;         break;
-	case AFMT_S8:     fmt = 0x00 | 0x04;  break;
+	case AFMT_U8:
+	case AFMT_S8:     fmt = 0x00;  break;
 	case AFMT_U16_LE:
-	case AFMT_U16_BE: fmt = 0x01;         break;
+	case AFMT_U16_BE:
 	case AFMT_S16_LE:
-	case AFMT_S16_BE: fmt = 0x01 | 0x04;  break;
-/* 4front API specs mention these ones,
-   the (2.4.15) kernel header hasn't them ... */
-#ifdef AFMT_S32_LE
-	case AFMT_S32_LE:
-	case AFMT_S32_BE: fmt = 0x02 | 0x04;  break;
-#endif
+	case AFMT_S16_BE: fmt = 0x01;  break;
 	default:
 		err = -EINVAL;
 		goto fail2;
 	}
 
 	switch (dev->oss.afmt) {
+	case AFMT_S8:     
+	case AFMT_S16_LE:
+	case AFMT_S16_BE: sign = 1; break;
+	default:          sign = 0; break;
+	}
+
+	switch (dev->oss.afmt) {
 	case AFMT_U16_BE:
-	case AFMT_S16_BE: bswap = 1; wswap = 0; break;
-#ifdef AFMT_S32_LE
-	case AFMT_S32_BE: bswap = 1; wswap = 1; break;
-#endif
-	default:          bswap = 0; wswap = 0; break;
+	case AFMT_S16_BE: bswap = 1; break;
+	default:          bswap = 0; break;
 	}
 
-	if (1 == dev->oss.channels)
-		fmt |= (1 << 3);
-	if (2 == dev->oss.channels)
-		fmt |= (3 << 3);
-	fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80;
-	
-	saa_writeb(SAA7134_NUM_SAMPLES0, (dev->oss.blksize & 0x0000ff));
-	saa_writeb(SAA7134_NUM_SAMPLES1, (dev->oss.blksize & 0x00ff00) >>  8);
-	saa_writeb(SAA7134_NUM_SAMPLES2, (dev->oss.blksize & 0xff0000) >> 16);
-	saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
-	dprintk("rec_start: afmt=%d ch=%d  =>  fmt=0x%x swap=%c%c\n",
+	switch (dev->pci->device) {
+	case PCI_DEVICE_ID_PHILIPS_SAA7134:
+		if (1 == dev->oss.channels)
+			fmt |= (1 << 3);
+		if (2 == dev->oss.channels)
+			fmt |= (3 << 3);
+		if (sign)
+			fmt |= 0x04;
+		fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80;
+		
+		saa_writeb(SAA7134_NUM_SAMPLES0, (dev->oss.blksize & 0x0000ff));
+		saa_writeb(SAA7134_NUM_SAMPLES1, (dev->oss.blksize & 0x00ff00) >>  8);
+		saa_writeb(SAA7134_NUM_SAMPLES2, (dev->oss.blksize & 0xff0000) >> 16);
+		saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
+		break;
+	case PCI_DEVICE_ID_PHILIPS_SAA7133:
+	case PCI_DEVICE_ID_PHILIPS_SAA7135:
+		if (1 == dev->oss.channels)
+			fmt |= (1 << 4);
+		if (2 == dev->oss.channels)
+			fmt |= (2 << 4);
+		if (!sign)
+			fmt |= 0x04;
+		saa_writel(0x588 >> 2, dev->oss.blksize);
+		saa_writel(0x58c >> 2, 0x543210 | (fmt << 24));
+		break;
+	}
+	dprintk("rec_start: afmt=%d ch=%d  =>  fmt=0x%x swap=%c\n",
 		dev->oss.afmt, dev->oss.channels, fmt,
-		bswap ? 'b' : '-', wswap ? 'w' : '-');
+		bswap ? 'b' : '-');
 
 	/* dma: setup channel 6 (= AUDIO) */
 	control = SAA7134_RS_CONTROL_BURST_16 |
@@ -156,8 +172,6 @@ static int dsp_rec_start(struct saa7134_
 		(dev->oss.pt.dma >> 12);
 	if (bswap)
 		control |= SAA7134_RS_CONTROL_BSWAP;
-	if (wswap)
-		control |= SAA7134_RS_CONTROL_WSWAP;
 	saa_writel(SAA7134_RS_BA1(6),0);
 	saa_writel(SAA7134_RS_BA2(6),dev->oss.blksize);
 	saa_writel(SAA7134_RS_PITCH(6),0);
@@ -201,7 +215,7 @@ static int dsp_rec_stop(struct saa7134_d
 
 static int dsp_open(struct inode *inode, struct file *file)
 {
-	unsigned int minor = minor(inode->i_rdev);
+	int minor = minor(inode->i_rdev);
 	struct saa7134_dev *h,*dev = NULL;
 	struct list_head *list;
 	int err;
@@ -259,7 +273,8 @@ static ssize_t dsp_read(struct file *fil
 {
 	struct saa7134_dev *dev = file->private_data;
 	DECLARE_WAITQUEUE(wait, current);
-	int bytes,err,ret = 0;
+	unsigned int bytes;
+	int err,ret = 0;
 
 	add_wait_queue(&dev->oss.wq, &wait);
 	down(&dev->oss.lock);
@@ -390,10 +405,6 @@ static int dsp_ioctl(struct inode *inode
 		case AFMT_U16_BE:
 		case AFMT_S16_LE:
 		case AFMT_S16_BE:
-#ifdef AFMT_S32_LE
-		case AFMT_S32_LE:
-		case AFMT_S32_BE:
-#endif
 			down(&dev->oss.lock);
 			dev->oss.afmt = val;
 			if (dev->oss.recording) {
@@ -416,11 +427,6 @@ static int dsp_ioctl(struct inode *inode
 		case AFMT_S16_LE:
 		case AFMT_S16_BE:
 			return put_user(16, (int*)arg);
-#ifdef AFMT_S32_LE
-		case AFMT_S32_LE:
-		case AFMT_S32_BE:
-			return put_user(20, (int*)arg);
-#endif
 		default:
 			return -EINVAL;
 		}
@@ -499,14 +505,10 @@ struct file_operations saa7134_dsp_fops 
 /* ------------------------------------------------------------------ */
 
 static int
-mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src)
+mixer_recsrc_7134(struct saa7134_dev *dev)
 {
-	static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" };
 	int analog_io,rate;
 	
-	dev->oss.count++;
-	dev->oss.input = src;
-	dprintk("mixer input = %s\n",iname[dev->oss.input]);
 	switch (dev->oss.input) {
 	case TV:
 		saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
@@ -525,27 +527,78 @@ mixer_recsrc(struct saa7134_dev *dev, en
 }
 
 static int
-mixer_level(struct saa7134_dev *dev, enum saa7134_audio_in src, int level)
+mixer_recsrc_7133(struct saa7134_dev *dev)
 {
-	switch (src) {
+	u32 value = 0xbbbbbb;
+	
+	switch (dev->oss.input) {
 	case TV:
-		/* nothing */
+		value = 0xbbbb10;  /* MAIN */
 		break;
 	case LINE1:
-		saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x10,
-			   (100 == level) ? 0x00 : 0x10);
+		value = 0xbbbb32;  /* AUX1 */
 		break;
 	case LINE2:
-		saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x20,
-			   (100 == level) ? 0x00 : 0x20);
+		value = 0xbbbb54;  /* AUX2 */
 		break;
 	}
+	saa_dsp_writel(dev, 0x46c >> 2, value);
 	return 0;
 }
 
+static int
+mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src)
+{
+	static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" };
+
+	dev->oss.count++;
+	dev->oss.input = src;
+	dprintk("mixer input = %s\n",iname[dev->oss.input]);
+
+	switch (dev->pci->device) {
+	case PCI_DEVICE_ID_PHILIPS_SAA7134:
+		mixer_recsrc_7134(dev);
+		break;
+	case PCI_DEVICE_ID_PHILIPS_SAA7133:
+	case PCI_DEVICE_ID_PHILIPS_SAA7135:
+		mixer_recsrc_7133(dev);
+		break;
+	}
+	return 0;
+}
+
+static int
+mixer_level(struct saa7134_dev *dev, enum saa7134_audio_in src, int level)
+{
+	switch (dev->pci->device) {
+	case PCI_DEVICE_ID_PHILIPS_SAA7134:
+		switch (src) {
+		case TV:
+			/* nothing */
+			break;
+		case LINE1:
+			saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x10,
+				   (100 == level) ? 0x00 : 0x10);
+			break;
+		case LINE2:
+			saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x20,
+				   (100 == level) ? 0x00 : 0x20);
+			break;
+		}
+		break;
+	case PCI_DEVICE_ID_PHILIPS_SAA7133:
+	case PCI_DEVICE_ID_PHILIPS_SAA7135:
+		/* nothing */
+		break;
+	}
+	return 0;
+}
+
+/* ------------------------------------------------------------------ */
+
 static int mixer_open(struct inode *inode, struct file *file)
 {
-	unsigned int minor = minor(inode->i_rdev);
+	int minor = minor(inode->i_rdev);
 	struct saa7134_dev *h,*dev = NULL;
 	struct list_head *list;
 
@@ -681,13 +734,20 @@ struct file_operations saa7134_mixer_fop
 
 int saa7134_oss_init(struct saa7134_dev *dev)
 {
+	/* general */
         init_MUTEX(&dev->oss.lock);
 	init_waitqueue_head(&dev->oss.wq);
-	dev->oss.line1 = 50;
-	dev->oss.line2 = 50;
-	mixer_level(dev,LINE1,dev->oss.line1);
-	mixer_level(dev,LINE2,dev->oss.line2);
-	
+
+	switch (dev->pci->device) {
+	case PCI_DEVICE_ID_PHILIPS_SAA7133:
+	case PCI_DEVICE_ID_PHILIPS_SAA7135:
+		saa_writel(0x588 >> 2, 0x00000fff);
+		saa_writel(0x58c >> 2, 0x00543210);
+		saa_dsp_writel(dev, 0x46c >> 2, 0xbbbbbb);
+		break;
+	}
+
+	/* dsp */
 	dev->oss.rate = 32000;
 	if (oss_rate)
 		dev->oss.rate = oss_rate;
@@ -695,7 +755,13 @@ int saa7134_oss_init(struct saa7134_dev 
 		dev->oss.rate = saa7134_boards[dev->board].i2s_rate;
 	dev->oss.rate = (dev->oss.rate > 40000) ? 48000 : 32000;
 
+	/* mixer */
+	dev->oss.line1 = 50;
+	dev->oss.line2 = 50;
+	mixer_level(dev,LINE1,dev->oss.line1);
+	mixer_level(dev,LINE2,dev->oss.line2);
 	mixer_recsrc(dev, (dev->oss.rate == 32000) ? TV : LINE2);
+	
 	return 0;
 }
 
@@ -710,7 +776,7 @@ void saa7134_irq_oss_done(struct saa7134
 	int next_blk, reg = 0;
 
 	spin_lock(&dev->slock);
-	if (-1 == dev->oss.dma_blk) {
+	if (UNSET == dev->oss.dma_blk) {
 		dprintk("irq: recording stopped%s\n","");
 		goto done;
 	}
diff -puN drivers/media/video/saa7134/saa7134-reg.h~v4l-7 drivers/media/video/saa7134/saa7134-reg.h
--- 25/drivers/media/video/saa7134/saa7134-reg.h~v4l-7	Mon May 12 15:33:16 2003
+++ 25-akpm/drivers/media/video/saa7134/saa7134-reg.h	Mon May 12 15:33:16 2003
@@ -9,9 +9,15 @@
 #ifndef PCI_DEVICE_ID_PHILIPS_SAA7130
 # define PCI_DEVICE_ID_PHILIPS_SAA7130 0x7130
 #endif
+#ifndef PCI_DEVICE_ID_PHILIPS_SAA7133
+# define PCI_DEVICE_ID_PHILIPS_SAA7133 0x7133
+#endif
 #ifndef PCI_DEVICE_ID_PHILIPS_SAA7134
 # define PCI_DEVICE_ID_PHILIPS_SAA7134 0x7134
 #endif
+#ifndef PCI_DEVICE_ID_PHILIPS_SAA7135
+# define PCI_DEVICE_ID_PHILIPS_SAA7135 0x7135
+#endif
 
 /* ------------------------------------------------------------------ */
 /*
@@ -329,6 +335,13 @@
 /* test modes */
 #define SAA7134_SPECIAL_MODE                    0x1d0
 
+/* audio -- saa7133 + saa7135 only */
+#define SAA7135_DSP_RWSTATE                     0x580
+#define SAA7135_DSP_RWSTATE_ERR                 (1 << 3)
+#define SAA7135_DSP_RWSTATE_IDA                 (1 << 2)
+#define SAA7135_DSP_RWSTATE_RDB                 (1 << 1)
+#define SAA7135_DSP_RWSTATE_WRR                 (1 << 0)
+
 /* ------------------------------------------------------------------ */
 /*
  * Local variables:
diff -puN drivers/media/video/saa7134/saa7134-ts.c~v4l-7 drivers/media/video/saa7134/saa7134-ts.c
--- 25/drivers/media/video/saa7134/saa7134-ts.c~v4l-7	Mon May 12 15:33:16 2003
+++ 25-akpm/drivers/media/video/saa7134/saa7134-ts.c	Mon May 12 15:33:16 2003
@@ -52,8 +52,9 @@ static int buffer_activate(struct saa713
 {
 	u32 control;
 	
-	dprintk("buffer_activate [%p]\n",buf);
+	dprintk("buffer_activate [%p]",buf);
 	buf->vb.state = STATE_ACTIVE;
+	buf->top_seen = 0;
 	
         /* dma: setup channel 5 (= TS) */
         control = SAA7134_RS_CONTROL_BURST_16 |
@@ -63,11 +64,11 @@ static int buffer_activate(struct saa713
 	if (NULL == next)
 		next = buf;
 	if (V4L2_FIELD_TOP == buf->vb.field) {
-		dprintk("[top]     buf=%p next=%p",buf,next);
+		dprintk("- [top]     buf=%p next=%p\n",buf,next);
 		saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf));
 		saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next));
 	} else {
-		dprintk("[bottom]  buf=%p next=%p",buf,next);
+		dprintk("- [bottom]  buf=%p next=%p\n",buf,next);
 		saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));
 		saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf));
 	}
@@ -86,8 +87,11 @@ static int buffer_prepare(struct file *f
 {
 	struct saa7134_dev *dev = file->private_data;
 	struct saa7134_buf *buf = (struct saa7134_buf *)vb;
-	int lines, llength, size, err;
+	unsigned int lines, llength, size;
+	int err;
 	
+	dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);
+
 	llength = TS_PACKET_SIZE;
 	lines = TS_NR_PACKETS;
 	
@@ -116,7 +120,6 @@ static int buffer_prepare(struct file *f
 			goto oops;
 	}
 	buf->vb.state = STATE_PREPARED;
-	buf->top_seen = 0;
 	buf->activate = buffer_activate;
 	buf->vb.field = field;
 	return 0;
@@ -163,7 +166,7 @@ static struct videobuf_queue_ops ts_qops
 
 static int ts_open(struct inode *inode, struct file *file)
 {
-	unsigned int minor = minor(inode->i_rdev);
+	int minor = minor(inode->i_rdev);
 	struct saa7134_dev *h,*dev = NULL;
 	struct list_head *list;
 	int err;
@@ -414,6 +417,7 @@ int saa7134_ts_init(struct saa7134_dev *
 	dev->ts_q.timeout.function = saa7134_buffer_timeout;
 	dev->ts_q.timeout.data     = (unsigned long)(&dev->ts_q);
 	dev->ts_q.dev              = dev;
+	dev->ts_q.need_two         = 1;
 	videobuf_queue_init(&dev->ts.ts, &ts_qops, dev->pci, &dev->slock,
 			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
 			    V4L2_FIELD_ALTERNATE,
@@ -445,7 +449,7 @@ void saa7134_irq_ts_done(struct saa7134_
 
 	spin_lock(&dev->slock);
 	if (dev->ts_q.curr) {
-		field = dev->video_q.curr->vb.field;
+		field = dev->ts_q.curr->vb.field;
 		if (field == V4L2_FIELD_TOP) {
 			if ((status & 0x100000) != 0x100000)
 				goto done;
diff -puN drivers/media/video/saa7134/saa7134-tvaudio.c~v4l-7 drivers/media/video/saa7134/saa7134-tvaudio.c
--- 25/drivers/media/video/saa7134/saa7134-tvaudio.c~v4l-7	Mon May 12 15:33:16 2003
+++ 25-akpm/drivers/media/video/saa7134/saa7134-tvaudio.c	Mon May 12 15:33:16 2003
@@ -37,13 +37,23 @@ static unsigned int audio_debug = 0;
 MODULE_PARM(audio_debug,"i");
 MODULE_PARM_DESC(audio_debug,"enable debug messages [tv audio]");
 
+static unsigned int audio_carrier = 0;
+MODULE_PARM(audio_carrier,"i");
+MODULE_PARM_DESC(audio_carrier,"audio carrier location");
+
 #define dprintk(fmt, arg...)	if (audio_debug) \
 	printk(KERN_DEBUG "%s/audio: " fmt, dev->name, ## arg)
+#define d2printk(fmt, arg...)	if (audio_debug > 1) \
+	printk(KERN_DEBUG "%s/audio: " fmt, dev->name, ## arg)
 
 #define print_regb(reg) printk("%s:   reg 0x%03x [%-16s]: 0x%02x\n", \
 		dev->name,(SAA7134_##reg),(#reg),saa_readb((SAA7134_##reg)))
 
+#define SCAN_INITIAL_DELAY  (HZ)
+#define SCAN_SAMPLE_DELAY   (HZ/10)
+
 /* ------------------------------------------------------------------ */
+/* saa7134 code                                                       */
 
 static struct saa7134_tvaudio tvaudio[] = {
 	{
@@ -95,6 +105,12 @@ static struct saa7134_tvaudio tvaudio[] 
 		.carr2         = 5850,
 		.mode          = TVAUDIO_NICAM_AM,
 	},{
+		.name          = "SECAM-D/K",
+		.std           = V4L2_STD_SECAM,
+		.carr1         = 6500,
+		.carr2         = -1,
+		.mode          = TVAUDIO_FM_MONO,
+	},{
 		.name          = "NTSC-M",
 		.std           = V4L2_STD_NTSC,
 		.carr1         = 4500,
@@ -122,7 +138,7 @@ static void tvaudio_init(struct saa7134_
 		schedule();
 	else
 		udelay(10);
-		
+
 	saa_writeb(SAA7134_AUDIO_CLOCK0,      clock        & 0xff);
 	saa_writeb(SAA7134_AUDIO_CLOCK1,     (clock >>  8) & 0xff);
 	saa_writeb(SAA7134_AUDIO_CLOCK2,     (clock >> 16) & 0xff);
@@ -134,9 +150,9 @@ static void tvaudio_init(struct saa7134_
 	saa_writeb(SAA7134_FM_DEMATRIX,      0x80);
 }
 
-static __u32 tvaudio_carr2reg(__u32 carrier)
+static u32 tvaudio_carr2reg(u32 carrier)
 {
-	__u64 a = carrier;
+	u64 a = carrier;
 
 	a <<= 24;
 	do_div(a,12288);
@@ -152,17 +168,19 @@ static void tvaudio_setcarrier(struct sa
 	saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary));
 }
 
-static void saa7134_tvaudio_do_mute_input(struct saa7134_dev *dev)
+static void mute_input_7134(struct saa7134_dev *dev)
 {
-	int mute;
+	unsigned int mute;
 	struct saa7134_input *in;
 	int reg = 0;
 	int mask;
 
 	/* look what is to do ... */
 	in   = dev->input;
-	mute = (dev->ctl_mute || dev->automute);
-	if (!card_has_audio(dev) && card(dev).mute.name) {
+	mute = (dev->ctl_mute ||
+		(dev->automute  &&  (&card(dev).radio) != in));
+	if (PCI_DEVICE_ID_PHILIPS_SAA7130 == dev->pci->device &&
+	    card(dev).mute.name) {
 		/* 7130 - we'll mute using some unconnected audio input */
 		if (mute)
 			in = &card(dev).mute;
@@ -171,14 +189,12 @@ static void saa7134_tvaudio_do_mute_inpu
 	    dev->hw_input == in)
 		return;
 
-#if 1
 	dprintk("ctl_mute=%d automute=%d input=%s  =>  mute=%d input=%s\n",
 		dev->ctl_mute,dev->automute,dev->input->name,mute,in->name);
-#endif
 	dev->hw_mute  = mute;
 	dev->hw_input = in;
 
-	if (card_has_audio(dev))
+	if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device)
 		/* 7134 mute */
 		saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ? 0xff : 0xbb);
 
@@ -199,25 +215,6 @@ static void saa7134_tvaudio_do_mute_inpu
 	saa7134_track_gpio(dev,in->name);
 }
 
-void saa7134_tvaudio_setmute(struct saa7134_dev *dev)
-{
-	saa7134_tvaudio_do_mute_input(dev);
-}
-
-void saa7134_tvaudio_setinput(struct saa7134_dev *dev,
-			      struct saa7134_input *in)
-{
-	dev->input = in;
-	saa7134_tvaudio_do_mute_input(dev);
-}
-
-void saa7134_tvaudio_setvolume(struct saa7134_dev *dev, int level)
-{
-	saa_writeb(SAA7134_CHANNEL1_LEVEL,     level & 0x1f);
-	saa_writeb(SAA7134_CHANNEL2_LEVEL,     level & 0x1f);
-	saa_writeb(SAA7134_NICAM_LEVEL_ADJUST, level & 0x1f);
-}
-
 static void tvaudio_setmode(struct saa7134_dev *dev,
 			    struct saa7134_tvaudio *audio,
 			    char *note)
@@ -274,8 +271,77 @@ static void tvaudio_setmode(struct saa71
 	saa_writel(0x174 >> 2, 0x0001e000); /* FIXME */
 }
 
-int saa7134_tvaudio_getstereo(struct saa7134_dev *dev,
-			      struct saa7134_tvaudio *audio)
+static int tvaudio_sleep(struct saa7134_dev *dev, int timeout)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	
+	add_wait_queue(&dev->thread.wq, &wait);
+	current->state = TASK_INTERRUPTIBLE;
+	schedule_timeout(timeout);
+	remove_wait_queue(&dev->thread.wq, &wait);
+	return dev->thread.scan1 != dev->thread.scan2;
+}
+
+static int tvaudio_checkcarrier(struct saa7134_dev *dev, int carrier)
+{
+	__s32 left,right,value;
+
+	if (audio_debug > 1) {
+		int i;
+		dprintk("debug %d:",carrier);
+		for (i = -150; i <= 150; i += 30) {
+			tvaudio_setcarrier(dev,carrier+i,carrier+i);
+			saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
+			if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY))
+				return -1;
+			value = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
+			if (0 == i)
+				printk("  #  %6d  # ",value >> 16);
+			else
+				printk(" %6d",value >> 16);
+		}
+		printk("\n");
+	}
+	
+	tvaudio_setcarrier(dev,carrier-90,carrier-90);
+	saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
+	if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY))
+		return -1;
+	left = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
+
+	tvaudio_setcarrier(dev,carrier+90,carrier+90);
+	saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
+	if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY))
+		return -1;
+	right = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
+
+	left >>= 16;
+        right >>= 16;
+	value = left > right ? left - right : right - left;
+	dprintk("scanning %d.%03d MHz =>  dc is %5d [%d/%d]\n",
+		carrier/1000,carrier%1000,value,left,right);
+	return value;
+}
+
+#if 0
+static void sifdebug_dump_regs(struct saa7134_dev *dev)
+{
+	print_regb(AUDIO_STATUS);
+	print_regb(IDENT_SIF);
+	print_regb(LEVEL_READOUT1);
+	print_regb(LEVEL_READOUT2);
+	print_regb(DCXO_IDENT_CTRL);
+	print_regb(DEMODULATOR);
+	print_regb(AGC_GAIN_SELECT);
+	print_regb(MONITOR_SELECT);
+	print_regb(FM_DEEMPHASIS);
+	print_regb(FM_DEMATRIX);
+	print_regb(SIF_SAMPLE_FREQ);
+	print_regb(ANALOG_IO_SELECT);
+}
+#endif
+
+static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *audio)
 {
 	__u32 idp,nicam;
 	int retval = -1;
@@ -321,62 +387,42 @@ int saa7134_tvaudio_getstereo(struct saa
 	return retval;
 }
 
-static int tvaudio_sleep(struct saa7134_dev *dev, int timeout)
+static int tvaudio_setstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *audio,
+			     u32 mode)
 {
-	DECLARE_WAITQUEUE(wait, current);
-	
-	add_wait_queue(&dev->thread.wq, &wait);
-	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(timeout);
-	remove_wait_queue(&dev->thread.wq, &wait);
-	return dev->thread.scan1 != dev->thread.scan2;
-}
-
-static int tvaudio_checkcarrier(struct saa7134_dev *dev, int carrier)
-{
-	__s32 left,right,value;
-	
-	tvaudio_setcarrier(dev,carrier-100,carrier-100);
-	if (tvaudio_sleep(dev,HZ/10))
-		return -1;
-	left = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
-	if (tvaudio_sleep(dev,HZ/10))
-		return -1;
-	left = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
-
-	tvaudio_setcarrier(dev,carrier+100,carrier+100);
-	if (tvaudio_sleep(dev,HZ/10))
-		return -1;
-        right = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
-	if (tvaudio_sleep(dev,HZ/10))
-		return -1;
-	right = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
+	static char *name[] = {
+		[ V4L2_TUNER_MODE_MONO   ] = "mono",
+		[ V4L2_TUNER_MODE_STEREO ] = "stereo",
+		[ V4L2_TUNER_MODE_LANG1  ] = "lang1",
+		[ V4L2_TUNER_MODE_LANG2  ] = "lang2",
+	};
+	static u32 fm[] = {
+		[ V4L2_TUNER_MODE_MONO   ] = 0x00,  /* ch1  */
+		[ V4L2_TUNER_MODE_STEREO ] = 0x80,  /* auto */
+		[ V4L2_TUNER_MODE_LANG1  ] = 0x00,  /* ch1  */
+		[ V4L2_TUNER_MODE_LANG2  ] = 0x01,  /* ch2  */
+	};
+	u32 reg;
 
-	left >>= 16;
-        right >>= 16;
-	value = left > right ? left - right : right - left;
-	dprintk("scanning %d.%03d MHz =>  dc is %5d [%d/%d]\n",
-		carrier/1000,carrier%1000,value,left,right);
-	return value;
-}
-
-#if 0
-static void sifdebug_dump_regs(struct saa7134_dev *dev)
-{
-	print_regb(AUDIO_STATUS);
-	print_regb(IDENT_SIF);
-	print_regb(LEVEL_READOUT1);
-	print_regb(LEVEL_READOUT2);
-	print_regb(DCXO_IDENT_CTRL);
-	print_regb(DEMODULATOR);
-	print_regb(AGC_GAIN_SELECT);
-	print_regb(MONITOR_SELECT);
-	print_regb(FM_DEEMPHASIS);
-	print_regb(FM_DEMATRIX);
-	print_regb(SIF_SAMPLE_FREQ);
-	print_regb(ANALOG_IO_SELECT);
+	switch (audio->mode) {
+	case TVAUDIO_FM_MONO:
+		/* nothing to do ... */
+		break;
+	case TVAUDIO_FM_K_STEREO:
+	case TVAUDIO_FM_BG_STEREO:
+		dprintk("setstereo [fm] => %s\n",
+			name[ mode % ARRAY_SIZE(name) ]);
+		reg = fm[ mode % ARRAY_SIZE(fm) ];
+		saa_writeb(SAA7134_FM_DEMATRIX, reg);
+		break;
+	case TVAUDIO_FM_SAT_STEREO:
+	case TVAUDIO_NICAM_AM:
+	case TVAUDIO_NICAM_FM:
+		/* FIXME */
+		break;
+	}
+	return 0;
 }
-#endif
 
 static int tvaudio_thread(void *data)
 {
@@ -388,7 +434,8 @@ static int tvaudio_thread(void *data)
 	struct saa7134_dev *dev = data;
 	const int *carr_scan;
 	int carr_vals[4];
-	int i,max,carrier,audio;
+	unsigned int i, audio;
+	int max1,max2,carrier,rx,mode;
 
 	lock_kernel();
 	daemonize("%s", dev->name);
@@ -410,10 +457,10 @@ static int tvaudio_thread(void *data)
 		dev->tvaudio  = NULL;
 		tvaudio_init(dev);
 		dev->automute = 1;
-		saa7134_tvaudio_setmute(dev);
+		mute_input_7134(dev);
 
 		/* give the tuner some time */
-		if (tvaudio_sleep(dev,HZ/2))
+		if (tvaudio_sleep(dev,SCAN_INITIAL_DELAY))
 			goto restart;
 
 		/* find the main carrier */
@@ -433,55 +480,280 @@ static int tvaudio_thread(void *data)
 			if (dev->thread.scan1 != dev->thread.scan2)
 				goto restart;
 		}
-		for (carrier = 0, max = 0, i = 0; i < MAX_SCAN; i++) {
+		for (carrier = 0, max1 = 0, max2 = 0, i = 0; i < MAX_SCAN; i++) {
 			if (!carr_scan[i])
 				continue;
-			if (max < carr_vals[i]) {
-				max = carr_vals[i];
+			if (max1 < carr_vals[i]) {
+				max2 = max1;
+				max1 = carr_vals[i];
 				carrier = carr_scan[i];
+			} else if (max2 < carr_vals[i]) {
+				max2 = carr_vals[i];
 			}
 		}
-		if (0 == carrier) {
-			/* Oops: autoscan didn't work for some reason :-/ */
-			printk(KERN_WARNING "%s/audio: oops: audio carrier "
-			       "scan failed\n", dev->name);
+
+		if (0 != carrier && max1 > 2000 && max1 > max2*3) {
+			/* found good carrier */
+			dprintk("found %s main sound carrier @ %d.%03d MHz [%d/%d]\n",
+				dev->tvnorm->name, carrier/1000, carrier%1000,
+				max1, max2);
+			dev->last_carrier = carrier;
+		} else if (0 != audio_carrier) {
+			/* no carrier -- try insmod option as fallback */
+			carrier = audio_carrier;
+			printk(KERN_WARNING "%s/audio: audio carrier scan failed, "
+			       "using %d.%03d MHz [insmod option]\n",
+			       dev->name, carrier/1000, carrier%1000);
+		} else if (0 != dev->last_carrier) {
+			/* no carrier -- try last detected one as fallback */
+			carrier = dev->last_carrier;
+			printk(KERN_WARNING "%s/audio: audio carrier scan failed, "
+			       "using %d.%03d MHz [last detected]\n",
+			       dev->name, carrier/1000, carrier%1000);
 		} else {
-			dprintk("found %s main sound carrier @ %d.%03d MHz\n",
-				dev->tvnorm->name,
-				carrier/1000,carrier%1000);
+			/* no carrier + no fallback -- try first in list */
+			carrier = carr_scan[0];
+			printk(KERN_WARNING "%s/audio: audio carrier scan failed, "
+			       "using %d.%03d MHz [default]\n",
+			       dev->name, carrier/1000, carrier%1000);
 		}
 		tvaudio_setcarrier(dev,carrier,carrier);
 		dev->automute = 0;
+		saa_andorb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0x30, 0x00);
 		saa7134_tvaudio_setmute(dev);
 
 		/* find the exact tv audio norm */
-		for (audio = -1, i = 0; i < TVAUDIO; i++) {
-			if (dev->tvnorm->id != -1 &&
+		for (audio = UNSET, i = 0; i < TVAUDIO; i++) {
+			if (dev->tvnorm->id != UNSET &&
 			    dev->tvnorm->id != tvaudio[i].std)
 				continue;
 			if (tvaudio[i].carr1 != carrier)
 				continue;
 
-			if (-1 == audio)
+			if (UNSET == audio)
 				audio = i;
 			tvaudio_setmode(dev,&tvaudio[i],"trying");
 			if (tvaudio_sleep(dev,HZ))
 				goto restart;
-			if (-1 != saa7134_tvaudio_getstereo(dev,&tvaudio[i])) {
+			if (-1 != tvaudio_getstereo(dev,&tvaudio[i])) {
 				audio = i;
 				break;
 			}
 		}
-		if (-1 == audio)
+		saa_andorb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0x30, 0x30);
+		if (UNSET == audio)
 			continue;
 		tvaudio_setmode(dev,&tvaudio[audio],"using");
+		tvaudio_setstereo(dev,&tvaudio[audio],V4L2_TUNER_MODE_MONO);
 		dev->tvaudio = &tvaudio[audio];
 
-#if 1
 		if (tvaudio_sleep(dev,3*HZ))
 			goto restart;
-		saa7134_tvaudio_getstereo(dev,&tvaudio[i]);
+		rx = tvaudio_getstereo(dev,&tvaudio[i]);
+		mode = saa7134_tvaudio_rx2mode(rx);
+		tvaudio_setstereo(dev,&tvaudio[audio],mode);
+	}
+
+ done:
+	dev->thread.task = NULL;
+	if(dev->thread.notify != NULL)
+		up(dev->thread.notify);
+	return 0;
+}
+
+/* ------------------------------------------------------------------ */
+/* saa7133 / saa7135 code                                             */
+
+static char *stdres[0x20] = {
+	[0x00] = "no standard detected",
+	[0x01] = "B/G (in progress)",
+	[0x02] = "D/K (in progress)",
+	[0x03] = "M (in progress)",
+
+	[0x04] = "B/G A2",
+	[0x05] = "B/G NICAM",
+	[0x06] = "D/K A2 (1)",
+	[0x07] = "D/K A2 (2)",
+	[0x08] = "D/K A2 (3)",
+	[0x09] = "D/K NICAM",
+	[0x0a] = "L NICAM",
+	[0x0b] = "I NICAM",
+	
+	[0x0c] = "M Korea",
+	[0x0d] = "M BTSC ",
+	[0x0e] = "M EIAJ",
+
+	[0x0f] = "FM radio / IF 10.7 / 50 deemp",
+	[0x10] = "FM radio / IF 10.7 / 75 deemp",
+	[0x11] = "FM radio / IF sel / 50 deemp",
+	[0x12] = "FM radio / IF sel / 75 deemp",
+
+	[0x13 ... 0x1e ] = "unknown",
+	[0x1f] = "??? [in progress]",
+};
+
+#define DSP_RETRY 16
+#define DSP_DELAY 16
+
+static inline int saa_dsp_wait_bit(struct saa7134_dev *dev, int bit)
+{
+	int state, count = DSP_RETRY;
+
+	state = saa_readb(SAA7135_DSP_RWSTATE);
+	if (unlikely(state & SAA7135_DSP_RWSTATE_ERR)) {
+		printk("%s: dsp access error\n",dev->name);
+		/* FIXME: send ack ... */
+		return -EIO;
+	}
+	while (0 == (state & bit)) {
+		if (unlikely(0 == count)) {
+			printk("%s: dsp access wait timeout [bit=%s]\n",
+			       dev->name,
+			       (bit & SAA7135_DSP_RWSTATE_WRR) ? "WRR" :
+			       (bit & SAA7135_DSP_RWSTATE_RDB) ? "RDB" :
+			       (bit & SAA7135_DSP_RWSTATE_IDA) ? "IDA" :
+			       "???");
+			return -EIO;
+		}
+		saa_wait(DSP_DELAY);
+		state = saa_readb(SAA7135_DSP_RWSTATE);
+		count--;
+	}
+	return 0;
+}
+
+#if 0
+static int saa_dsp_readl(struct saa7134_dev *dev, int reg, u32 *value)
+{
+	int err;
+
+	d2printk("dsp read reg 0x%x\n", reg<<2);
+	saa_readl(reg);
+	err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_RDB);
+	if (err < 0)
+		return err;
+	*value = saa_readl(reg);
+	d2printk("dsp read   => 0x%06x\n", *value & 0xffffff);
+	err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_IDA);
+	if (err < 0)
+		return err;
+	return 0;
+}
 #endif
+
+int saa_dsp_writel(struct saa7134_dev *dev, int reg, u32 value)
+{
+	int err;
+
+	d2printk("dsp write reg 0x%x = 0x%06x\n",reg<<2,value);
+	err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_WRR);
+	if (err < 0)
+		return err;
+	saa_writel(reg,value);
+	err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_WRR);
+	if (err < 0)
+		return err;
+	return 0;
+}
+
+static int getstereo_7133(struct saa7134_dev *dev)
+{
+	int retval = V4L2_TUNER_SUB_MONO;
+	u32 value;
+
+	value = saa_readl(0x528 >> 2);
+	if (value & 0x20)
+		retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+	if (value & 0x40)
+		retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+	return retval;
+}
+
+static int mute_input_7133(struct saa7134_dev *dev)
+{
+	u32 reg = 0;
+	
+	switch (dev->input->amux) {
+	case TV:    reg = 0x02; break;
+	case LINE1: reg = 0x00; break;
+	case LINE2: reg = 0x01; break;
+	}
+	if (dev->ctl_mute)
+		reg = 0x07;
+	saa_writel(0x594 >> 2, reg);
+	return 0;
+}
+
+static int tvaudio_thread_ddep(void *data)
+{
+	struct saa7134_dev *dev = data;
+	u32 value, norms;
+
+	lock_kernel();
+	daemonize("%s", dev->name);
+	dev->thread.task = current;
+	unlock_kernel();
+	if (dev->thread.notify != NULL)
+		up(dev->thread.notify);
+
+	/* unmute */
+	saa_dsp_writel(dev, 0x474 >> 2, 0x00);
+	saa_dsp_writel(dev, 0x450 >> 2, 0x00);
+
+	for (;;) {
+		if (dev->thread.exit || signal_pending(current))
+			goto done;
+		interruptible_sleep_on(&dev->thread.wq);
+		if (dev->thread.exit || signal_pending(current))
+			goto done;
+
+	restart:
+		dev->thread.scan1 = dev->thread.scan2;
+		dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
+
+		norms = 0;
+		if (dev->tvnorm->id & V4L2_STD_PAL)
+			norms |= 0x2c; /* B/G + D/K + I */
+		if (dev->tvnorm->id & V4L2_STD_NTSC)
+			norms |= 0x40; /* M */
+		if (dev->tvnorm->id & V4L2_STD_SECAM)
+			norms |= 0x18; /* L + D/K */
+		if (0 == norms)
+			norms = 0x0000007c;
+
+		/* quick & dirty -- to be fixed up later ... */
+		saa_dsp_writel(dev, 0x454 >> 2, 0);
+		saa_dsp_writel(dev, 0x454 >> 2, norms | 0x80);
+		saa_dsp_writel(dev, 0x464 >> 2, 0x000000);
+		saa_dsp_writel(dev, 0x470 >> 2, 0x101010);
+
+		if (tvaudio_sleep(dev,3*HZ))
+			goto restart;
+		value = saa_readl(0x528 >> 2) & 0xffffff;
+
+		dprintk("tvaudio thread status: 0x%x [%s%s%s]\n",
+			value, stdres[value & 0x1f],
+			(value & 0x000020) ? ",stereo" : "",
+			(value & 0x000040) ? ",dual"   : "");
+		dprintk("detailed status: "
+			"%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n",
+			(value & 0x000080) ? " A2/EIAJ pilot tone "     : "",
+			(value & 0x000100) ? " A2/EIAJ dual "           : "",
+			(value & 0x000200) ? " A2/EIAJ stereo "         : "",
+			(value & 0x000400) ? " A2/EIAJ noise mute "     : "",
+
+			(value & 0x000800) ? " BTSC/FM radio pilot "    : "",
+			(value & 0x001000) ? " SAP carrier "            : "",
+			(value & 0x002000) ? " BTSC stereo noise mute " : "",
+			(value & 0x004000) ? " SAP noise mute "         : "",
+			(value & 0x008000) ? " VDSP "                   : "",
+			
+			(value & 0x010000) ? " NICST "                  : "",
+			(value & 0x020000) ? " NICDU "                  : "",
+			(value & 0x040000) ? " NICAM muted "            : "",
+			(value & 0x080000) ? " NICAM reserve sound "    : "",
+			
+			(value & 0x100000) ? " init done "              : "");
 	}
 
  done:
@@ -492,14 +764,89 @@ static int tvaudio_thread(void *data)
 }
 
 /* ------------------------------------------------------------------ */
+/* common stuff + external entry points                               */
+
+int saa7134_tvaudio_rx2mode(u32 rx)
+{
+	u32 mode;
+	
+	mode = V4L2_TUNER_MODE_MONO;
+	if (rx & V4L2_TUNER_SUB_STEREO)
+		mode = V4L2_TUNER_MODE_STEREO;
+	else if (rx & V4L2_TUNER_SUB_LANG1)
+		mode = V4L2_TUNER_MODE_LANG1;
+	else if (rx & V4L2_TUNER_SUB_LANG2)
+		mode = V4L2_TUNER_MODE_LANG2;
+	return mode;
+}
+	
+void saa7134_tvaudio_setmute(struct saa7134_dev *dev)
+{
+	switch (dev->pci->device) {
+	case PCI_DEVICE_ID_PHILIPS_SAA7130:
+	case PCI_DEVICE_ID_PHILIPS_SAA7134:
+		mute_input_7134(dev);
+		break;
+	case PCI_DEVICE_ID_PHILIPS_SAA7133:
+	case PCI_DEVICE_ID_PHILIPS_SAA7135:
+		mute_input_7133(dev);
+		break;
+	}
+}
+
+void saa7134_tvaudio_setinput(struct saa7134_dev *dev,
+			      struct saa7134_input *in)
+{
+	dev->input = in;
+	switch (dev->pci->device) {
+	case PCI_DEVICE_ID_PHILIPS_SAA7130:
+	case PCI_DEVICE_ID_PHILIPS_SAA7134:
+		mute_input_7134(dev);
+		break;
+	case PCI_DEVICE_ID_PHILIPS_SAA7133:
+	case PCI_DEVICE_ID_PHILIPS_SAA7135:
+		mute_input_7133(dev);
+		break;
+	}
+}
+
+void saa7134_tvaudio_setvolume(struct saa7134_dev *dev, int level)
+{
+	switch (dev->pci->device) {
+	case PCI_DEVICE_ID_PHILIPS_SAA7134:
+		saa_writeb(SAA7134_CHANNEL1_LEVEL,     level & 0x1f);
+		saa_writeb(SAA7134_CHANNEL2_LEVEL,     level & 0x1f);
+		saa_writeb(SAA7134_NICAM_LEVEL_ADJUST, level & 0x1f);
+		break;
+	}
+}
+
+int saa7134_tvaudio_getstereo(struct saa7134_dev *dev)
+{
+	int retval = V4L2_TUNER_SUB_MONO;
+
+	switch (dev->pci->device) {
+	case PCI_DEVICE_ID_PHILIPS_SAA7134:
+		if (dev->tvaudio)
+			retval = tvaudio_getstereo(dev,dev->tvaudio);
+		break;
+	case PCI_DEVICE_ID_PHILIPS_SAA7133:
+	case PCI_DEVICE_ID_PHILIPS_SAA7135:
+		retval = getstereo_7133(dev);
+		break;
+	}
+	return retval;
+}
 
 int saa7134_tvaudio_init(struct saa7134_dev *dev)
 {
 	DECLARE_MUTEX_LOCKED(sem);
+	int (*my_thread)(void *data) = NULL;
 
 	/* enable I2S audio output */
 	if (saa7134_boards[dev->board].i2s_rate) {
-		int rate = (32000 == saa7134_boards[dev->board].i2s_rate) ? 0x01 : 0x03;
+		int rate = (32000 == saa7134_boards[dev->board].i2s_rate)
+			? 0x01 : 0x03;
 		
 		/* set rate */ 
 		saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
@@ -512,13 +859,24 @@ int saa7134_tvaudio_init(struct saa7134_
 		saa_writeb(SAA7134_I2S_AUDIO_OUTPUT,   0x01);
 	}
 
-	/* start tvaudio thread */
-	init_waitqueue_head(&dev->thread.wq);
-	dev->thread.notify = &sem;
-	kernel_thread(tvaudio_thread,dev,0);
-	down(&sem);
-	dev->thread.notify = NULL;
-	wake_up_interruptible(&dev->thread.wq);
+	switch (dev->pci->device) {
+	case PCI_DEVICE_ID_PHILIPS_SAA7134:
+		my_thread = tvaudio_thread;
+		break;
+	case PCI_DEVICE_ID_PHILIPS_SAA7133:
+	case PCI_DEVICE_ID_PHILIPS_SAA7135:
+		my_thread = tvaudio_thread_ddep;
+		break;
+	}
+	if (my_thread) {
+		/* start tvaudio thread */
+		init_waitqueue_head(&dev->thread.wq);
+		dev->thread.notify = &sem;
+		kernel_thread(my_thread,dev,0);
+		down(&sem);
+		dev->thread.notify = NULL;
+		wake_up_interruptible(&dev->thread.wq);
+	}
 
 	return 0;
 }
@@ -541,8 +899,13 @@ int saa7134_tvaudio_fini(struct saa7134_
 
 int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
 {
-	dev->thread.scan2++;
-	wake_up_interruptible(&dev->thread.wq);
+	if (dev->thread.task) {
+		dev->thread.scan2++;
+		wake_up_interruptible(&dev->thread.wq);
+	} else {
+		dev->automute = 0;
+		saa7134_tvaudio_setmute(dev);
+	}
 	return 0;
 }
 
diff -puN drivers/media/video/saa7134/saa7134-vbi.c~v4l-7 drivers/media/video/saa7134/saa7134-vbi.c
--- 25/drivers/media/video/saa7134/saa7134-vbi.c~v4l-7	Mon May 12 15:33:16 2003
+++ 25-akpm/drivers/media/video/saa7134/saa7134-vbi.c	Mon May 12 15:33:16 2003
@@ -85,6 +85,7 @@ static int buffer_activate(struct saa713
 
 	dprintk("buffer_activate [%p]\n",buf);
 	buf->vb.state = STATE_ACTIVE;
+	buf->top_seen = 0;
 
 	task_init(dev,buf,TASK_A);
 	task_init(dev,buf,TASK_B);
@@ -119,7 +120,8 @@ static int buffer_prepare(struct file *f
 	struct saa7134_dev *dev = fh->dev;
 	struct saa7134_buf *buf = (struct saa7134_buf *)vb;
 	struct saa7134_tvnorm *norm = dev->tvnorm;
-	int lines, llength, size, err;
+	unsigned int lines, llength, size;
+	int err;
 
 	lines   = norm->vbi_v_stop - norm->vbi_v_start +1;
 	if (lines > VBI_LINE_COUNT)
@@ -155,7 +157,6 @@ static int buffer_prepare(struct file *f
 			goto oops;
 	}
 	buf->vb.state = STATE_PREPARED;
-	buf->top_seen = 0;
 	buf->activate = buffer_activate;
 	buf->vb.field = field;
 	return 0;
@@ -166,7 +167,7 @@ static int buffer_prepare(struct file *f
 }
 
 static int
-buffer_setup(struct file *file, int *count, int *size)
+buffer_setup(struct file *file, unsigned int *count, unsigned int *size)
 {
 	struct saa7134_fh *fh   = file->private_data;
 	struct saa7134_dev *dev = fh->dev;
@@ -241,7 +242,7 @@ void saa7134_irq_vbi_done(struct saa7134
 	if (dev->vbi_q.curr) {
 		dev->vbi_fieldcount++;
 		/* make sure we have seen both fields */
-		if ((status & 0x10) == 0x10) {
+		if ((status & 0x10) == 0x00) {
 			dev->vbi_q.curr->top_seen = 1;
 			goto done;
 		}
diff -puN drivers/media/video/saa7134/saa7134-video.c~v4l-7 drivers/media/video/saa7134/saa7134-video.c
--- 25/drivers/media/video/saa7134/saa7134-video.c~v4l-7	Mon May 12 15:33:16 2003
+++ 25-akpm/drivers/media/video/saa7134/saa7134-video.c	Mon May 12 15:33:16 2003
@@ -2,7 +2,7 @@
  * device driver for philips saa7134 based TV cards
  * video4linux video interface
  *
- * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+ * (c) 2001-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
@@ -127,7 +127,7 @@ static struct saa7134_format formats[] =
 		.vshift   = 1,
 	}
 };
-#define FORMATS (sizeof(formats)/sizeof(struct saa7134_format))
+#define FORMATS ARRAY_SIZE(formats)
 
 static struct saa7134_tvnorm tvnorms[] = {
 	{
@@ -141,13 +141,15 @@ static struct saa7134_tvnorm tvnorms[] =
 		.chroma_ctrl1  = 0x81,
 		.chroma_gain   = 0x2a,
 		.chroma_ctrl2  = 0x06,
+		.vgate_misc    = 0x1c,
 
 		.h_start       = 0,
 		.h_stop        = 719,
 		.video_v_start = 24,
 		.video_v_stop  = 311,
-		.vbi_v_start   = 7-3,  /* FIXME */
-		.vbi_v_stop    = 22-3,
+		.vbi_v_start   = 7,
+		.vbi_v_stop    = 22,
+		.src_timing    = 4,
 	},{
 		.name          = "NTSC",
 		.id            = V4L2_STD_NTSC,
@@ -159,6 +161,7 @@ static struct saa7134_tvnorm tvnorms[] =
 		.chroma_ctrl1  = 0x89,
 		.chroma_gain   = 0x2a,
 		.chroma_ctrl2  = 0x0e,
+		.vgate_misc    = 0x18,
 
 		.h_start       = 0,
 		.h_stop        = 719,
@@ -166,17 +169,19 @@ static struct saa7134_tvnorm tvnorms[] =
 		.video_v_stop  = 22+240,
 		.vbi_v_start   = 10, /* FIXME */
 		.vbi_v_stop    = 21, /* FIXME */
+		.src_timing    = 1,
 	},{
 		.name          = "SECAM",
 		.id            = V4L2_STD_SECAM,
 		.width         = 720,
 		.height        = 576,
 
-		.sync_control  = 0x58,
+		.sync_control  = 0x18, /* old: 0x58, */
 		.luma_control  = 0x1b,
 		.chroma_ctrl1  = 0xd1,
 		.chroma_gain   = 0x80,
 		.chroma_ctrl2  = 0x00,
+		.vgate_misc    = 0x1c,
 
 		.h_start       = 0,
 		.h_stop        = 719,
@@ -184,6 +189,47 @@ static struct saa7134_tvnorm tvnorms[] =
 		.video_v_stop  = 311,
 		.vbi_v_start   = 7,
 		.vbi_v_stop    = 22,
+		.src_timing    = 4,
+	},{
+		.name          = "PAL-M",
+		.id            = V4L2_STD_PAL_M,
+		.width         = 720,
+		.height        = 480,
+
+		.sync_control  = 0x59,
+		.luma_control  = 0x40,
+		.chroma_ctrl1  = 0xb9,
+		.chroma_gain   = 0x2a,
+		.chroma_ctrl2  = 0x0e,
+		.vgate_misc    = 0x18,
+
+		.h_start       = 0,
+		.h_stop        = 719,
+		.video_v_start = 22,
+		.video_v_stop  = 22+240,
+		.vbi_v_start   = 10, /* FIXME */
+		.vbi_v_stop    = 21, /* FIXME */
+		.src_timing    = 1,
+	},{
+		.name          = "PAL-Nc",
+		.id            = V4L2_STD_PAL_Nc,
+		.width         = 720,
+		.height        = 576,
+
+		.sync_control  = 0x18,
+		.luma_control  = 0x40,
+		.chroma_ctrl1  = 0xa1,
+		.chroma_gain   = 0x2a,
+		.chroma_ctrl2  = 0x06,
+		.vgate_misc    = 0x1c,
+
+		.h_start       = 0,
+		.h_stop        = 719,
+		.video_v_start = 24,
+		.video_v_stop  = 311,
+		.vbi_v_start   = 7,
+		.vbi_v_stop    = 22,
+		.src_timing    = 4,
 #if 0
 	},{
 		.name          = "AUTO",
@@ -196,6 +242,7 @@ static struct saa7134_tvnorm tvnorms[] =
 		.chroma_ctrl1  = 0x8b,
 		.chroma_gain   = 0x00,
 		.chroma_ctrl2  = 0x00,
+		.vgate_misc    = 0x18,
 
 		.h_start       = 0,
 		.h_stop        = 719,
@@ -203,11 +250,11 @@ static struct saa7134_tvnorm tvnorms[] =
 		.video_v_stop  = 311,
 		.vbi_v_start   = 7,
 		.vbi_v_stop    = 22,
+		.src_timing    = 4,
 #endif
 	}
 };
-#define TVNORMS (sizeof(tvnorms)/sizeof(struct saa7134_tvnorm))
-
+#define TVNORMS ARRAY_SIZE(tvnorms)
 
 #define V4L2_CID_PRIVATE_INVERT      (V4L2_CID_PRIVATE_BASE + 0)
 #define V4L2_CID_PRIVATE_Y_ODD       (V4L2_CID_PRIVATE_BASE + 1)
@@ -298,11 +345,11 @@ static const struct v4l2_queryctrl video
 		.type          = V4L2_CTRL_TYPE_INTEGER,
 	}
 };
-const int CTRLS = (sizeof(video_ctrls)/sizeof(struct v4l2_queryctrl));
+static const unsigned int CTRLS = ARRAY_SIZE(video_ctrls);
 
-static const struct v4l2_queryctrl* ctrl_by_id(int id)
+static const struct v4l2_queryctrl* ctrl_by_id(unsigned int id)
 {
-	int i;
+	unsigned int i;
 	
 	for (i = 0; i < CTRLS; i++)
 		if (video_ctrls[i].id == id)
@@ -310,9 +357,9 @@ static const struct v4l2_queryctrl* ctrl
 	return NULL;
 }
 
-static struct saa7134_format* format_by_fourcc(int  fourcc)
+static struct saa7134_format* format_by_fourcc(unsigned int fourcc)
 {
-	int i;
+	unsigned int i;
 
 	for (i = 0; i < FORMATS; i++)
 		if (formats[i].fourcc == fourcc)
@@ -323,7 +370,7 @@ static struct saa7134_format* format_by_
 /* ----------------------------------------------------------------------- */
 /* resource management                                                     */
 
-static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, int bit)
+static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bit)
 {
 	if (fh->resources & bit)
 		/* have it already allocated */
@@ -345,19 +392,19 @@ static int res_get(struct saa7134_dev *d
 }
 
 static
-int res_check(struct saa7134_fh *fh, int bit)
+int res_check(struct saa7134_fh *fh, unsigned int bit)
 {
 	return (fh->resources & bit);
 }
 
 static
-int res_locked(struct saa7134_dev *dev, int bit)
+int res_locked(struct saa7134_dev *dev, unsigned int bit)
 {
 	return (dev->resources & bit);
 }
 
 static
-void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, int bits)
+void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits)
 {
 	if ((fh->resources & bits) != bits)
 		BUG();
@@ -393,7 +440,8 @@ static void set_tvnorm(struct saa7134_de
 	saa_writeb(SAA7134_ANALOG_IN_CTRL4,       0x90);
 	saa_writeb(SAA7134_HSYNC_START,           0xeb);
 	saa_writeb(SAA7134_HSYNC_STOP,            0xe0);
-
+	saa_writeb(SAA7134_SOURCE_TIMING1,        norm->src_timing);
+	
 	saa_writeb(SAA7134_SYNC_CTRL,             norm->sync_control);
 	saa_writeb(SAA7134_LUMA_CTRL,             luma_control);
 	saa_writeb(SAA7134_DEC_LUMA_BRIGHT,       dev->ctl_bright);
@@ -410,7 +458,7 @@ static void set_tvnorm(struct saa7134_de
 	saa_writeb(SAA7134_ANALOG_ADC,            0x01);
 	saa_writeb(SAA7134_VGATE_START,           0x11);
 	saa_writeb(SAA7134_VGATE_STOP,            0xfe);
-	saa_writeb(SAA7134_MISC_VGATE_MSB,        0x18); /* FIXME */
+	saa_writeb(SAA7134_MISC_VGATE_MSB,        norm->vgate_misc);
 	saa_writeb(SAA7134_RAW_DATA_GAIN,         0x40);
 	saa_writeb(SAA7134_RAW_DATA_OFFSET,       0x80);
 
@@ -454,7 +502,7 @@ static void set_h_prescale(struct saa713
 		{    9,  15,    0,    4,   3 },
 		{   10,  16,    1,    5,   3 },
 	};
-	static const int count = sizeof(vals)/sizeof(vals[0]);
+	static const int count = ARRAY_SIZE(vals);
 	int i;
 
 	for (i = 0; i < count; i++)
@@ -532,14 +580,14 @@ static void set_size(struct saa7134_dev 
 	/* deinterlace y offsets */
 	if (interlace) {
 		y_odd  = dev->ctl_y_odd;
-		y_even = dev->ctl_y_even + yscale / 32;
+		y_even = dev->ctl_y_even;
 		saa_writeb(SAA7134_V_PHASE_OFFSET0(task), y_odd);
 		saa_writeb(SAA7134_V_PHASE_OFFSET1(task), y_even);
 		saa_writeb(SAA7134_V_PHASE_OFFSET2(task), y_odd);
 		saa_writeb(SAA7134_V_PHASE_OFFSET3(task), y_even);
 	} else {
 		y_odd  = dev->ctl_y_odd;
-		y_even = dev->ctl_y_even + yscale / 64;
+		y_even = dev->ctl_y_even;
 		saa_writeb(SAA7134_V_PHASE_OFFSET0(task), y_odd);
 		saa_writeb(SAA7134_V_PHASE_OFFSET1(task), y_even);
 		saa_writeb(SAA7134_V_PHASE_OFFSET2(task), y_odd);
@@ -688,7 +736,8 @@ static int start_preview(struct saa7134_
 	err = verify_preview(dev,&fh->win);
 	if (0 != err)
 		return err;
-	
+
+	dev->ovfield = fh->win.field;
 	dprintk("start_preview %dx%d+%d+%d %s field=%s\n",
 		fh->win.w.width,fh->win.w.height,
 		fh->win.w.left,fh->win.w.top,
@@ -752,6 +801,7 @@ static int buffer_activate(struct saa713
 
 	dprintk("buffer_activate buf=%p\n",buf);
 	buf->vb.state = STATE_ACTIVE;
+	buf->top_seen = 0;
 	
 	set_size(dev,TASK_A,buf->vb.width,buf->vb.height,
 		 V4L2_FIELD_HAS_BOTH(buf->vb.field));
@@ -828,7 +878,8 @@ static int buffer_prepare(struct file *f
 	struct saa7134_fh *fh = file->private_data;
 	struct saa7134_dev *dev = fh->dev;
 	struct saa7134_buf *buf = (struct saa7134_buf *)vb;
-	int size,err;
+	unsigned int size;
+	int err;
 	
 	/* sanity checks */
 	if (NULL == fh->fmt)
@@ -842,8 +893,8 @@ static int buffer_prepare(struct file *f
 	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
 		return -EINVAL;
 
-	dprintk("buffer_prepare [size=%dx%d,bytes=%d,fields=%s,%s]\n",
-		fh->width,fh->height,size,v4l2_field_names[field],
+	dprintk("buffer_prepare [%d,size=%dx%d,bytes=%d,fields=%s,%s]\n",
+		vb->i,fh->width,fh->height,size,v4l2_field_names[field],
 		fh->fmt->name);
 	if (buf->vb.width  != fh->width  ||
 	    buf->vb.height != fh->height ||
@@ -872,7 +923,6 @@ static int buffer_prepare(struct file *f
 			goto oops;
 	}
 	buf->vb.state = STATE_PREPARED;
-	buf->top_seen = 0;
 	buf->activate = buffer_activate;
 	return 0;
 
@@ -1081,7 +1131,7 @@ static int saa7134_resource(struct saa71
 
 static int video_open(struct inode *inode, struct file *file)
 {
-	unsigned int minor = minor(inode->i_rdev);
+	int minor = minor(inode->i_rdev);
 	struct saa7134_dev *h,*dev = NULL;
 	struct saa7134_fh *fh;
 	struct list_head *list;
@@ -1117,8 +1167,8 @@ static int video_open(struct inode *inod
 	fh->radio    = radio;
 	fh->type     = type;
 	fh->fmt      = format_by_fourcc(V4L2_PIX_FMT_BGR24);
-	fh->width    = 320;
-	fh->height   = 240;
+	fh->width    = 768;
+	fh->height   = 576;
 
 	videobuf_queue_init(&fh->cap, &video_qops,
 			    dev->pci, &dev->slock,
@@ -1138,7 +1188,9 @@ static int video_open(struct inode *inod
 
 	if (fh->radio) {
 		/* switch to radio mode */
+		u32 v = 400*16;
 		saa7134_tvaudio_setinput(dev,&card(dev).radio);
+		saa7134_i2c_call_clients(dev,VIDIOCSFREQ,&v);
 		saa7134_i2c_call_clients(dev,AUDC_SET_RADIO,NULL);
 	} else {
 		/* switch to video/vbi mode */
@@ -1185,7 +1237,7 @@ video_poll(struct file *file, struct pol
 			buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
 	} else {
 		down(&fh->cap.lock);
-		if (-1 == fh->cap.read_off) {
+		if (UNSET == fh->cap.read_off) {
                         /* need to capture a new frame */
 			if (res_locked(fh->dev,RESOURCE_VIDEO)) {
                                 up(&fh->cap.lock);
@@ -1263,6 +1315,29 @@ video_mmap(struct file *file, struct vm_
 
 /* ------------------------------------------------------------------ */
 
+void saa7134_vbi_fmt(struct saa7134_dev *dev, struct v4l2_format *f)
+{
+	struct saa7134_tvnorm *norm = dev->tvnorm;
+
+	f->fmt.vbi.sampling_rate = 6750000 * 4;
+	f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */;
+	f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
+	f->fmt.vbi.offset = 64 * 4;
+	f->fmt.vbi.start[0] = norm->vbi_v_start;
+	f->fmt.vbi.count[0] = norm->vbi_v_stop - norm->vbi_v_start +1;
+	f->fmt.vbi.start[1] = norm->video_v_stop + norm->vbi_v_start +1;
+	f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
+	f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */;
+
+#if 0
+	if (V4L2_STD_PAL == norm->id) {
+		/* FIXME */
+		f->fmt.vbi.start[0] += 3;
+		f->fmt.vbi.start[1] += 3*2;
+	}
+#endif
+}
+
 int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
 		  struct v4l2_format *f)
 {
@@ -1273,27 +1348,17 @@ int saa7134_g_fmt(struct saa7134_dev *de
 		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:
 		f->fmt.win = fh->win;
 		return 0;
 	case V4L2_BUF_TYPE_VBI_CAPTURE:
-	{
-		struct saa7134_tvnorm *norm = fh->dev->tvnorm;
-			
-		f->fmt.vbi.sampling_rate = 6750000 * 4;
-		f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */;
-		f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
-		f->fmt.vbi.offset = 64 * 4;
-		f->fmt.vbi.start[0] = norm->vbi_v_start;
-		f->fmt.vbi.count[0] = norm->vbi_v_stop - norm->vbi_v_start +1;
-		f->fmt.vbi.start[1] = norm->video_v_stop + norm->vbi_v_start + 1;
-		f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
-		f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */;
+		saa7134_vbi_fmt(dev,f);
 		return 0;
-	}
 	default:
 		return -EINVAL;
 	}
@@ -1309,7 +1374,7 @@ int saa7134_try_fmt(struct saa7134_dev *
 	{
 		struct saa7134_format *fmt;
 		enum v4l2_field field;
-		int maxw, maxh;
+		unsigned int maxw, maxh;
 
 		fmt = format_by_fourcc(f->fmt.pix.pixelformat);
 		if (NULL == fmt)
@@ -1336,12 +1401,18 @@ int saa7134_try_fmt(struct saa7134_dev *
 		}
 
 		f->fmt.pix.field = field;
+		if (f->fmt.pix.width  < 48)
+			f->fmt.pix.width  = 48;
+		if (f->fmt.pix.height < 32)
+			f->fmt.pix.height = 32;
 		if (f->fmt.pix.width > maxw)
 			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;
 	}
@@ -1350,6 +1421,9 @@ int saa7134_try_fmt(struct saa7134_dev *
 		if (0 != err)
 			return err;
 		return 0;
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		saa7134_vbi_fmt(dev,f);
+		return 0;
 	default:
 		return -EINVAL;
 	}
@@ -1397,6 +1471,9 @@ int saa7134_s_fmt(struct saa7134_dev *de
 		up(&dev->lock);
 		return 0;
 		break;
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		saa7134_vbi_fmt(dev,f);
+		return 0;
 	default:
 		return -EINVAL;
 	}
@@ -1442,10 +1519,10 @@ static int video_do_ioctl(struct inode *
 	case VIDIOC_ENUMSTD:
 	{
 		struct v4l2_standard *e = arg;
-		int i;
+		unsigned int i;
 
 		i = e->index;
-		if (i < 0 || i >= TVNORMS)
+		if (i >= TVNORMS)
 			return -EINVAL;
 		err = v4l2_video_std_construct(e, tvnorms[e->index].id,
 					       tvnorms[e->index].name);
@@ -1464,7 +1541,7 @@ static int video_do_ioctl(struct inode *
 	case VIDIOC_S_STD:
 	{
 		v4l2_std_id *id = arg;
-		int i;
+		unsigned int i;
 
 		for(i = 0; i < TVNORMS; i++)
 			if (*id & tvnorms[i].id)
@@ -1489,7 +1566,7 @@ static int video_do_ioctl(struct inode *
 	case VIDIOC_ENUMINPUT:
 	{
 		struct v4l2_input *i = arg;
-		int n;
+		unsigned int n;
 
 		n = i->index;
 		if (n >= SAA7134_INPUT_MAX)
@@ -1557,22 +1634,8 @@ static int video_do_ioctl(struct inode *
 				V4L2_TUNER_CAP_LANG1 |
 				V4L2_TUNER_CAP_LANG2;
 			t->rangehigh = 0xffffffffUL;
-			t->rxsubchans = -1;
-			if (dev->tvaudio)
-				t->rxsubchans = saa7134_tvaudio_getstereo
-					(dev,dev->tvaudio);
-			if (-1 == t->rxsubchans)
-				t->rxsubchans = V4L2_TUNER_SUB_MONO;
-#if 1
-			/* fill audmode -- FIXME: allow manual switching */
-			t->audmode = V4L2_TUNER_MODE_MONO;
-			if (t->rxsubchans & V4L2_TUNER_SUB_STEREO)
-				t->audmode = V4L2_TUNER_MODE_STEREO;
-			else if (t->rxsubchans & V4L2_TUNER_SUB_LANG1)
-				t->audmode = V4L2_TUNER_MODE_LANG1;
-			else if (t->rxsubchans & V4L2_TUNER_SUB_LANG2)
-				t->audmode = V4L2_TUNER_MODE_LANG2;
-#endif
+			t->rxsubchans = saa7134_tvaudio_getstereo(dev);
+			t->audmode = saa7134_tvaudio_rx2mode(t->rxsubchans);
 		}
 		if (0 != (saa_readb(SAA7134_STATUS_VIDEO1) & 0x03))
 			t->signal = 0xffff;
@@ -1655,14 +1718,14 @@ static int video_do_ioctl(struct inode *
 	{
 		struct v4l2_fmtdesc *f = arg;
 		enum v4l2_buf_type type;
-		int index;
+		unsigned int index;
 
 		index = f->index;
 		type  = f->type;
 		switch (type) {
 		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-			if (index < 0 || index >= FORMATS)
+			if (index >= FORMATS)
 				return -EINVAL;
 			if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY &&
 			    formats[index].planar)
@@ -1760,21 +1823,23 @@ static int video_do_ioctl(struct inode *
 	{
 		struct video_mbuf *mbuf = arg;
 		struct videobuf_queue *q;
-		int i;
+		struct v4l2_requestbuffers req;
+		unsigned int i;
 
 		q = saa7134_queue(fh);
-		down(&q->lock);
-		err = videobuf_mmap_setup(file,q,gbuffers,gbufsize);
-		if (err < 0) {
-			up(&q->lock);
+		memset(&req,0,sizeof(req));
+		req.type  = q->type;
+		req.count = gbuffers;
+		err = videobuf_reqbufs(file,q,&req);
+		if (err < 0)
 			return err;
-		}
 		memset(mbuf,0,sizeof(*mbuf));
-		mbuf->frames = gbuffers;
-		mbuf->size   = gbuffers * gbufsize;
-		for (i = 0; i < gbuffers; i++)
-			mbuf->offsets[i] = i * gbufsize;
-		up(&q->lock);
+		mbuf->frames = req.count;
+		mbuf->size   = 0;
+		for (i = 0; i < mbuf->frames; i++) {
+			mbuf->offsets[i]  = q->bufs[i]->boff;
+			mbuf->size       += q->bufs[i]->bsize;
+		}
 		return 0;
 	}
 	case VIDIOC_REQBUFS:
@@ -1800,7 +1865,10 @@ static int video_do_ioctl(struct inode *
 	case VIDIOC_STREAMOFF:
 	{
 		int res = saa7134_resource(fh);
+
 		err = videobuf_streamoff(file,saa7134_queue(fh));
+		if (err < 0)
+			return err;
 		res_free(dev,fh,res);
 		return 0;
 	}
@@ -1879,9 +1947,16 @@ static int radio_do_ioctl(struct inode *
 		strcpy(a->name,"Radio");
 		return 0;
 	}
+	case VIDIOC_G_STD:
+	{
+		v4l2_std_id *id = arg;
+		*id = 0;
+		return 0;
+	}
 	case VIDIOC_S_AUDIO:
 	case VIDIOC_S_TUNER:
 	case VIDIOC_S_INPUT:
+	case VIDIOC_S_STD:
 		return 0;
 
 	case VIDIOC_QUERYCTRL:
@@ -2055,7 +2130,7 @@ void saa7134_irq_video_done(struct saa71
 		
 		if (V4L2_FIELD_HAS_BOTH(field)) {
 			/* make sure we have seen both fields */
-			if ((status & 0x10) == 0x10) {
+			if ((status & 0x10) == 0x00) {
 				dev->video_q.curr->top_seen = 1;
 				goto done;
 			}

_