Преглед изворни кода

Merge branch 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb

* 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb:
  V4L/DVB (5939): dvb-pll: make struct dvb_pll_fcv1236d static
  V4L/DVB (5933): Dvb-usb/af9005-fe.c: error check fixes
  V4L/DVB (5932): Af9005 fix tuner module unload
  V4L/DVB (5920): ivtv: fix incorrect fw size report.
  V4L/DVB (5918): ivtv: fix TV-out VBI handling, only reset on last close.
  V4L/DVB (5917): ivtv: improve mailbox responsiveness.
  V4L/DVB (5916): ivtv: fix pause/continue/play handling
  V4L/DVB (5900): usbvision: fix bugs [sg]_register functions
  V4L/DVB (5899): bttv: Fix Viewcast Osprey 440 support
  V4L/DVB (5893): DVB: fix includes of video.h when __KERNEL__ is undefined
  V4L/DVB (5891): zr36067: Turn off raw capture properly
  V4L/DVB (5890): zr36067: Add UYVY, RGB555X, RGB565X, and RGB32 formats
  V4L/DVB (5888): zr36067: Driver was not returning correct image size
  V4L/DVB (5887): zr36067: Fix poll() operation
  V4L/DVB (5886): zr36067: Fix problem setting norms
Linus Torvalds пре 18 година
родитељ
комит
3a3485be68

+ 16 - 31
drivers/media/dvb/dvb-usb/af9005-fe.c

@@ -29,8 +29,6 @@
 
 struct af9005_fe_state {
 	struct dvb_usb_device *d;
-	struct dvb_frontend *tuner;
-
 	fe_status_t stat;
 
 	/* retraining parameters */
@@ -345,8 +343,8 @@ static int af9005_reset_pre_viterbi(struct dvb_frontend *fe)
 				       1 & 0xff);
 	if (ret)
 		return ret;
-	af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8,
-				   1 >> 8);
+	ret = af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8,
+					 1 >> 8);
 	if (ret)
 		return ret;
 	/* reset pre viterbi error count */
@@ -447,7 +445,7 @@ static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat)
 	u8 temp;
 	int ret;
 
-	if (state->tuner == NULL)
+	if (fe->ops.tuner_ops.release == NULL)
 		return -ENODEV;
 
 	*stat = 0;
@@ -493,7 +491,7 @@ static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat)
 static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber)
 {
 	struct af9005_fe_state *state = fe->demodulator_priv;
-	if (state->tuner == NULL)
+	if (fe->ops.tuner_ops.release  == NULL)
 		return -ENODEV;
 	af9005_fe_refresh_state(fe);
 	*ber = state->ber;
@@ -503,7 +501,7 @@ static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber)
 static int af9005_fe_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
 {
 	struct af9005_fe_state *state = fe->demodulator_priv;
-	if (state->tuner == NULL)
+	if (fe->ops.tuner_ops.release == NULL)
 		return -ENODEV;
 	af9005_fe_refresh_state(fe);
 	*unc = state->unc;
@@ -517,7 +515,7 @@ static int af9005_fe_read_signal_strength(struct dvb_frontend *fe,
 	int ret;
 	u8 if_gain, rf_gain;
 
-	if (state->tuner == NULL)
+	if (fe->ops.tuner_ops.release == NULL)
 		return -ENODEV;
 	ret =
 	    af9005_read_ofdm_register(state->d, xd_r_reg_aagc_rf_gain,
@@ -881,10 +879,8 @@ static int af9005_fe_init(struct dvb_frontend *fe)
 	     af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst,
 					reg_ofdm_rst_pos, reg_ofdm_rst_len, 1)))
 		return ret;
-	if ((ret =
-	     af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst,
-					reg_ofdm_rst_pos, reg_ofdm_rst_len, 0)))
-		return ret;
+	ret = af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst,
+					 reg_ofdm_rst_pos, reg_ofdm_rst_len, 0);
 
 	if (ret)
 		return ret;
@@ -1041,7 +1037,7 @@ static int af9005_fe_init(struct dvb_frontend *fe)
 		return ret;
 
 	/* attach tuner and init */
-	if (state->tuner == NULL) {
+	if (fe->ops.tuner_ops.release == NULL) {
 		/* read tuner and board id from eeprom */
 		ret = af9005_read_eeprom(adap->dev, 0xc6, buf, 2);
 		if (ret) {
@@ -1058,20 +1054,16 @@ static int af9005_fe_init(struct dvb_frontend *fe)
 				return ret;
 			}
 			if1 = (u16) (buf[0] << 8) + buf[1];
-			state->tuner =
-			    dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap,
-				       &af9005_mt2060_config, if1);
-			if (state->tuner == NULL) {
+			if (dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap,
+					 &af9005_mt2060_config, if1) == NULL) {
 				deb_info("MT2060 attach failed\n");
 				return -ENODEV;
 			}
 			break;
 		case 3:	/* QT1010 */
 		case 9:	/* QT1010B */
-			state->tuner =
-			    dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap,
-				       &af9005_qt1010_config);
-			if (state->tuner == NULL) {
+			if (dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap,
+					&af9005_qt1010_config) ==NULL) {
 				deb_info("QT1010 attach failed\n");
 				return -ENODEV;
 			}
@@ -1080,7 +1072,7 @@ static int af9005_fe_init(struct dvb_frontend *fe)
 			err("Unsupported tuner type %d", buf[0]);
 			return -ENODEV;
 		}
-		ret = state->tuner->ops.tuner_ops.init(state->tuner);
+		ret = fe->ops.tuner_ops.init(fe);
 		if (ret)
 			return ret;
 	}
@@ -1118,7 +1110,7 @@ static int af9005_fe_set_frontend(struct dvb_frontend *fe,
 
 	deb_info("af9005_fe_set_frontend freq %d bw %d\n", fep->frequency,
 		 fep->u.ofdm.bandwidth);
-	if (state->tuner == NULL) {
+	if (fe->ops.tuner_ops.release == NULL) {
 		err("Tuner not attached");
 		return -ENODEV;
 	}
@@ -1199,7 +1191,7 @@ static int af9005_fe_set_frontend(struct dvb_frontend *fe,
 		return ret;
 	/* set tuner */
 	deb_info("set tuner\n");
-	ret = state->tuner->ops.tuner_ops.set_params(state->tuner, fep);
+	ret = fe->ops.tuner_ops.set_params(fe, fep);
 	if (ret)
 		return ret;
 
@@ -1435,12 +1427,6 @@ static void af9005_fe_release(struct dvb_frontend *fe)
 {
 	struct af9005_fe_state *state =
 	    (struct af9005_fe_state *)fe->demodulator_priv;
-	if (state->tuner != NULL && state->tuner->ops.tuner_ops.release != NULL) {
-		state->tuner->ops.tuner_ops.release(state->tuner);
-#ifdef CONFIG_DVB_CORE_ATTACH
-		symbol_put_addr(state->tuner->ops.tuner_ops.release);
-#endif
-	}
 	kfree(state);
 }
 
@@ -1458,7 +1444,6 @@ struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d)
 	deb_info("attaching frontend af9005\n");
 
 	state->d = d;
-	state->tuner = NULL;
 	state->opened = 0;
 
 	memcpy(&state->frontend.ops, &af9005_fe_ops,

+ 1 - 1
drivers/media/dvb/frontends/dvb-pll.c

@@ -501,7 +501,7 @@ static struct dvb_pll_desc dvb_pll_opera1 = {
 
 /* Philips FCV1236D
  */
-struct dvb_pll_desc dvb_pll_fcv1236d = {
+static struct dvb_pll_desc dvb_pll_fcv1236d = {
 /* Bit_0: RF Input select
  * Bit_1: 0=digital, 1=analog
  */

+ 134 - 104
drivers/media/video/bt8xx/bttv-cards.c

@@ -33,6 +33,7 @@
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/firmware.h>
+#include <net/checksum.h>
 
 #include <asm/io.h>
 
@@ -45,7 +46,7 @@ static void boot_msp34xx(struct bttv *btv, int pin);
 static void boot_bt832(struct bttv *btv);
 static void hauppauge_eeprom(struct bttv *btv);
 static void avermedia_eeprom(struct bttv *btv);
-static void osprey_eeprom(struct bttv *btv);
+static void osprey_eeprom(struct bttv *btv, const u8 ee[256]);
 static void modtec_eeprom(struct bttv *btv);
 static void init_PXC200(struct bttv *btv);
 static void init_RTV24(struct bttv *btv);
@@ -2843,13 +2844,28 @@ struct tvcard bttv_tvcards[] = {
 		.has_remote     = 1,
 	},
 		/* ---- card 0x8c ---------------------------------- */
+	/* Has four Bt878 chips behind a PCI bridge, each chip has:
+	     one external BNC composite input (mux 2)
+	     three internal composite inputs (unknown muxes)
+	     an 18-bit stereo A/D (CS5331A), which has:
+	       one external stereo unblanced (RCA) audio connection
+	       one (or 3?) internal stereo balanced (XLR) audio connection
+	       input is selected via gpio to a 14052B mux
+		 (mask=0x300, unbal=0x000, bal=0x100, ??=0x200,0x300)
+	       gain is controlled via an X9221A chip on the I2C bus @0x28
+	       sample rate is controlled via gpio to an MK1413S
+		 (mask=0x3, 32kHz=0x0, 44.1kHz=0x1, 48kHz=0x2, ??=0x3)
+	     There is neither a tuner nor an svideo input. */
 	[BTTV_BOARD_OSPREY440]  = {
 		.name           = "Osprey 440",
-		.video_inputs   = 1,
-		.audio_inputs   = 1,
+		.video_inputs   = 4,
+		.audio_inputs   = 2, /* this is meaningless */
 		.tuner          = UNSET,
-		.svhs           = 1,
-		.muxsel         = { 2 },
+		.svhs           = UNSET,
+		.muxsel         = { 2, 3, 0, 1 }, /* 3,0,1 are guesses */
+		.gpiomask	= 0x303,
+		.gpiomute	= 0x000, /* int + 32kHz */
+		.gpiomux	= { 0, 0, 0x000, 0x100},
 		.pll            = PLL_28,
 		.tuner_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
@@ -3453,11 +3469,12 @@ void __devinit bttv_init_card2(struct bttv *btv)
 	case BTTV_BOARD_OSPREY2xx:
 	case BTTV_BOARD_OSPREY2x0_SVID:
 	case BTTV_BOARD_OSPREY2x0:
+	case BTTV_BOARD_OSPREY440:
 	case BTTV_BOARD_OSPREY500:
 	case BTTV_BOARD_OSPREY540:
 	case BTTV_BOARD_OSPREY2000:
 		bttv_readee(btv,eeprom_data,0xa0);
-		osprey_eeprom(btv);
+		osprey_eeprom(btv, eeprom_data);
 		break;
 	case BTTV_BOARD_IDS_EAGLE:
 		init_ids_eagle(btv);
@@ -3748,106 +3765,119 @@ static int __devinit pvr_boot(struct bttv *btv)
 /* ----------------------------------------------------------------------- */
 /* some osprey specific stuff                                              */
 
-static void __devinit osprey_eeprom(struct bttv *btv)
+static void __devinit osprey_eeprom(struct bttv *btv, const u8 ee[256])
 {
-       int i = 0;
-       unsigned char *ee = eeprom_data;
-       unsigned long serial = 0;
-
-       if (btv->c.type == 0) {
-	       /* this might be an antique... check for MMAC label in eeprom */
-	       if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) {
-		       unsigned char checksum = 0;
-		       for (i = 0; i < 21; i++)
-			       checksum += ee[i];
-		       if (checksum != ee[21])
-			       return;
-		       btv->c.type = BTTV_BOARD_OSPREY1x0_848;
-		       for (i = 12; i < 21; i++)
-			       serial *= 10, serial += ee[i] - '0';
-	       }
+	int i;
+	u32 serial = 0;
+	int cardid = -1;
+
+	/* This code will nevery actually get called in this case.... */
+	if (btv->c.type == BTTV_BOARD_UNKNOWN) {
+		/* this might be an antique... check for MMAC label in eeprom */
+		if (!strncmp(ee, "MMAC", 4)) {
+			u8 checksum = 0;
+			for (i = 0; i < 21; i++)
+				checksum += ee[i];
+			if (checksum != ee[21])
+				return;
+			cardid = BTTV_BOARD_OSPREY1x0_848;
+			for (i = 12; i < 21; i++)
+				serial *= 10, serial += ee[i] - '0';
+		}
        } else {
-	       unsigned short type;
-	       int offset = 4*16;
-
-	       for (; offset < 8*16; offset += 16) {
-		       unsigned short checksum = 0;
-		       /* verify the checksum */
-		       for (i = 0; i < 14; i++)
-				checksum += ee[i+offset];
-			checksum = ~checksum;  /* no idea why */
-			if ((((checksum>>8)&0x0FF) == ee[offset+14]) &&
-				   ((checksum & 0x0FF) == ee[offset+15])) {
-			       break;
-		       }
-	       }
-
-	       if (offset >= 8*16)
-		       return;
-
-	       /* found a valid descriptor */
-	       type = (ee[offset+4]<<8) | (ee[offset+5]);
-
-	       switch(type) {
-	       /* 848 based */
-	       case 0x0004:
-		       btv->c.type = BTTV_BOARD_OSPREY1x0_848;
-		       break;
-	       case 0x0005:
-		       btv->c.type = BTTV_BOARD_OSPREY101_848;
-		       break;
-
-	       /* 878 based */
-	       case 0x0012:
-	       case 0x0013:
-		       btv->c.type = BTTV_BOARD_OSPREY1x0;
-		       break;
-	       case 0x0014:
-	       case 0x0015:
-		       btv->c.type = BTTV_BOARD_OSPREY1x1;
-		       break;
-	       case 0x0016:
-	       case 0x0017:
-	       case 0x0020:
-		       btv->c.type = BTTV_BOARD_OSPREY1x1_SVID;
-		       break;
-	       case 0x0018:
-	       case 0x0019:
-	       case 0x001E:
-	       case 0x001F:
-		       btv->c.type = BTTV_BOARD_OSPREY2xx;
-		       break;
-	       case 0x001A:
-	       case 0x001B:
-		       btv->c.type = BTTV_BOARD_OSPREY2x0_SVID;
-		       break;
-	       case 0x0040:
-		       btv->c.type = BTTV_BOARD_OSPREY500;
-		       break;
-	       case 0x0050:
-	       case 0x0056:
-		       btv->c.type = BTTV_BOARD_OSPREY540;
-		       /* bttv_osprey_540_init(btv); */
-		       break;
-	       case 0x0060:
-	       case 0x0070:
-	       case 0x00A0:
-		       btv->c.type = BTTV_BOARD_OSPREY2x0;
-		       /* enable output on select control lines */
-		       gpio_inout(0xffffff,0x000303);
-		       break;
-	       default:
-		       /* unknown...leave generic, but get serial # */
-		       break;
-	       }
-	       serial =  (ee[offset+6] << 24)
-		       | (ee[offset+7] << 16)
-		       | (ee[offset+8] <<  8)
-		       | (ee[offset+9]);
-       }
-
-       printk(KERN_INFO "bttv%d: osprey eeprom: card=%d name=%s serial=%ld\n",
-	      btv->c.nr, btv->c.type, bttv_tvcards[btv->c.type].name,serial);
+		unsigned short type;
+
+		for (i = 4*16; i < 8*16; i += 16) {
+			u16 checksum = ip_compute_csum(ee + i, 16);
+
+			if ((checksum&0xff) + (checksum>>8) == 0xff)
+				break;
+		}
+		if (i >= 8*16)
+			return;
+		ee += i;
+
+		/* found a valid descriptor */
+		type = be16_to_cpup((u16*)(ee+4));
+
+		switch(type) {
+		/* 848 based */
+		case 0x0004:
+			cardid = BTTV_BOARD_OSPREY1x0_848;
+			break;
+		case 0x0005:
+			cardid = BTTV_BOARD_OSPREY101_848;
+			break;
+
+		/* 878 based */
+		case 0x0012:
+		case 0x0013:
+			cardid = BTTV_BOARD_OSPREY1x0;
+			break;
+		case 0x0014:
+		case 0x0015:
+			cardid = BTTV_BOARD_OSPREY1x1;
+			break;
+		case 0x0016:
+		case 0x0017:
+		case 0x0020:
+			cardid = BTTV_BOARD_OSPREY1x1_SVID;
+			break;
+		case 0x0018:
+		case 0x0019:
+		case 0x001E:
+		case 0x001F:
+			cardid = BTTV_BOARD_OSPREY2xx;
+			break;
+		case 0x001A:
+		case 0x001B:
+			cardid = BTTV_BOARD_OSPREY2x0_SVID;
+			break;
+		case 0x0040:
+			cardid = BTTV_BOARD_OSPREY500;
+			break;
+		case 0x0050:
+		case 0x0056:
+			cardid = BTTV_BOARD_OSPREY540;
+			/* bttv_osprey_540_init(btv); */
+			break;
+		case 0x0060:
+		case 0x0070:
+		case 0x00A0:
+			cardid = BTTV_BOARD_OSPREY2x0;
+			/* enable output on select control lines */
+			gpio_inout(0xffffff,0x000303);
+			break;
+		case 0x00D8:
+			cardid = BTTV_BOARD_OSPREY440;
+			break;
+		default:
+			/* unknown...leave generic, but get serial # */
+			printk(KERN_INFO "bttv%d: "
+			       "osprey eeprom: unknown card type 0x%04x\n",
+			       btv->c.nr, type);
+			break;
+		}
+		serial = be32_to_cpup((u32*)(ee+6));
+	}
+
+	printk(KERN_INFO "bttv%d: osprey eeprom: card=%d '%s' serial=%u\n",
+	       btv->c.nr, cardid,
+	       cardid>0 ? bttv_tvcards[cardid].name : "Unknown", serial);
+
+	if (cardid<0 || btv->c.type == cardid)
+		return;
+
+	/* card type isn't set correctly */
+	if (card[btv->c.nr] < bttv_num_tvcards) {
+		printk(KERN_WARNING "bttv%d: osprey eeprom: "
+		       "Not overriding user specified card type\n", btv->c.nr);
+	} else {
+		printk(KERN_INFO "bttv%d: osprey eeprom: "
+		       "Changing card type from %d to %d\n", btv->c.nr,
+		       btv->c.type, cardid);
+		btv->c.type = cardid;
+	}
 }
 
 /* ----------------------------------------------------------------------- */

+ 1 - 0
drivers/media/video/ivtv/ivtv-driver.h

@@ -417,6 +417,7 @@ struct ivtv_mailbox_data {
 #define IVTV_F_I_WORK_HANDLER_YUV  17	/* there is work to be done for YUV */
 #define IVTV_F_I_WORK_HANDLER_PIO  18	/* there is work to be done for PIO */
 #define IVTV_F_I_PIO		   19	/* PIO in progress */
+#define IVTV_F_I_DEC_PAUSED	   20 	/* the decoder is paused */
 
 /* Event notifications */
 #define IVTV_F_I_EV_DEC_STOPPED	   28	/* decoder stopped event */

+ 10 - 0
drivers/media/video/ivtv/ivtv-fileops.c

@@ -757,6 +757,7 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
 	    itv->output_mode = OUT_NONE;
 
 	itv->speed = 0;
+	clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
 	ivtv_release_stream(s);
 }
 
@@ -799,7 +800,16 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp)
 		ivtv_unmute(itv);
 		ivtv_release_stream(s);
 	} else if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) {
+		struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT];
+
 		ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0);
+
+		/* If all output streams are closed, and if the user doesn't have
+		   IVTV_DEC_STREAM_TYPE_VOUT open, then disable VBI on TV-out. */
+		if (itv->output_mode == OUT_NONE && !test_bit(IVTV_F_S_APPL_IO, &s_vout->s_flags)) {
+			/* disable VBI on TV-out */
+			ivtv_disable_vbi(itv);
+		}
 	} else {
 		ivtv_stop_capture(id, 0);
 	}

+ 1 - 1
drivers/media/video/ivtv/ivtv-firmware.c

@@ -72,8 +72,8 @@ retry:
 			dst++;
 			src++;
 		}
-		release_firmware(fw);
 		IVTV_INFO("Loaded %s firmware (%zd bytes)\n", fn, fw->size);
+		release_firmware(fw);
 		return size;
 	}
 	IVTV_ERR("Unable to open firmware %s (must be %ld bytes)\n", fn, size);

+ 9 - 2
drivers/media/video/ivtv/ivtv-ioctl.c

@@ -285,6 +285,10 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
 
 		if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
 			return -EBUSY;
+		if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
+			/* forces ivtv_set_speed to be called */
+			itv->speed = 0;
+		}
 		return ivtv_start_decoding(id, vc->play.speed);
 	}
 
@@ -309,6 +313,7 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
 		if (atomic_read(&itv->decoding) > 0) {
 			ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
 				(vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0);
+			set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
 		}
 		break;
 
@@ -317,8 +322,10 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
 		if (try) break;
 		if (itv->output_mode != OUT_MPG)
 			return -EBUSY;
-		if (atomic_read(&itv->decoding) > 0) {
-			ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, 0, 0);
+		if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
+			int speed = itv->speed;
+			itv->speed = 0;
+			return ivtv_start_decoding(id, speed);
 		}
 		break;
 

+ 11 - 3
drivers/media/video/ivtv/ivtv-mailbox.c

@@ -40,6 +40,7 @@
 #define API_HIGH_VOL 	 (1 << 5)	/* High volume command (i.e. called during encoding or decoding) */
 #define API_NO_WAIT_MB 	 (1 << 4)	/* Command may not wait for a free mailbox */
 #define API_NO_WAIT_RES	 (1 << 5)	/* Command may not wait for the result */
+#define API_NO_POLL	 (1 << 6)	/* Avoid pointless polling */
 
 struct ivtv_api_info {
 	int flags;		/* Flags, see above */
@@ -51,7 +52,7 @@ struct ivtv_api_info {
 static const struct ivtv_api_info api_info[256] = {
 	/* MPEG encoder API */
 	API_ENTRY(CX2341X_ENC_PING_FW, 			API_FAST_RESULT),
-	API_ENTRY(CX2341X_ENC_START_CAPTURE, 		API_RESULT),
+	API_ENTRY(CX2341X_ENC_START_CAPTURE, 		API_RESULT | API_NO_POLL),
 	API_ENTRY(CX2341X_ENC_STOP_CAPTURE, 		API_RESULT),
 	API_ENTRY(CX2341X_ENC_SET_AUDIO_ID, 		API_CACHE),
 	API_ENTRY(CX2341X_ENC_SET_VIDEO_ID, 		API_CACHE),
@@ -96,7 +97,7 @@ static const struct ivtv_api_info api_info[256] = {
 
 	/* MPEG decoder API */
 	API_ENTRY(CX2341X_DEC_PING_FW, 			API_FAST_RESULT),
-	API_ENTRY(CX2341X_DEC_START_PLAYBACK, 		API_RESULT),
+	API_ENTRY(CX2341X_DEC_START_PLAYBACK, 		API_RESULT | API_NO_POLL),
 	API_ENTRY(CX2341X_DEC_STOP_PLAYBACK, 		API_RESULT),
 	API_ENTRY(CX2341X_DEC_SET_PLAYBACK_SPEED, 	API_RESULT),
 	API_ENTRY(CX2341X_DEC_STEP_VIDEO, 		API_RESULT),
@@ -290,6 +291,13 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[])
 	/* Get results */
 	then = jiffies;
 
+	if (!(flags & API_NO_POLL)) {
+		/* First try to poll, then switch to delays */
+		for (i = 0; i < 100; i++) {
+			if (readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)
+				break;
+		}
+	}
 	while (!(readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)) {
 		if (jiffies - then > api_timeout) {
 			IVTV_DEBUG_WARN("Could not get result (%s)\n", api_info[cmd].name);
@@ -301,7 +309,7 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[])
 		if (flags & API_NO_WAIT_RES)
 			mdelay(1);
 		else
-			ivtv_msleep_timeout(10, 0);
+			ivtv_msleep_timeout(1, 0);
 	}
 	if (jiffies - then > msecs_to_jiffies(100))
 		IVTV_DEBUG_WARN("%s took %u jiffies\n",

+ 1 - 10
drivers/media/video/ivtv/ivtv-streams.c

@@ -603,10 +603,6 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
 
 	IVTV_DEBUG_INFO("Setting some initial decoder settings\n");
 
-	/* disable VBI signals, if the MPEG stream contains VBI data,
-	   then that data will be processed automatically for you. */
-	ivtv_disable_vbi(itv);
-
 	/* set audio mode to left/stereo  for dual/stereo mode. */
 	ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
 
@@ -639,7 +635,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
 	}
 	if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype,
 			itv->params.width, itv->params.height, itv->params.audio_properties)) {
-		IVTV_DEBUG_WARN("COULDN'T INITIALIZE DECODER SOURCE\n");
+		IVTV_DEBUG_WARN("Couldn't initialize decoder source\n");
 	}
 	return 0;
 }
@@ -909,11 +905,6 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
 	clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
 	ivtv_flush_queues(s);
 
-	if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) {
-		/* disable VBI on TV-out */
-		ivtv_disable_vbi(itv);
-	}
-
 	/* decrement decoding */
 	atomic_dec(&itv->decoding);
 

+ 3 - 2
drivers/media/video/usbvision/usbvision-video.c

@@ -517,6 +517,7 @@ static int vidioc_g_register (struct file *file, void *priv,
 		    __FUNCTION__, errCode);
 		return errCode;
 	}
+	reg->val = errCode;
 	return 0;
 }
 
@@ -531,8 +532,8 @@ static int vidioc_s_register (struct file *file, void *priv,
 	if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
 		return -EINVAL;
 	/* NT100x has a 8-bit register space */
-	reg->val = (u8)usbvision_write_reg(usbvision, reg->reg&0xff, reg->val);
-	if (reg->val < 0) {
+	errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val);
+	if (errCode < 0) {
 		err("%s: VIDIOC_DBG_S_REGISTER failed: error %d",
 		    __FUNCTION__, errCode);
 		return errCode;

+ 5 - 0
drivers/media/video/zoran.h

@@ -240,11 +240,16 @@ enum gpcs_type {
 
 struct zoran_format {
 	char *name;
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
 	int palette;
+#endif
+#ifdef CONFIG_VIDEO_V4L2
 	__u32 fourcc;
 	int colorspace;
+#endif
 	int depth;
 	__u32 flags;
+	__u32 vfespfr;
 };
 /* flags */
 #define ZORAN_FORMAT_COMPRESSED 1<<0

+ 13 - 37
drivers/media/video/zoran_device.c

@@ -429,8 +429,6 @@ zr36057_set_vfe (struct zoran              *zr,
 	reg |= (HorDcm << ZR36057_VFESPFR_HorDcm);
 	reg |= (VerDcm << ZR36057_VFESPFR_VerDcm);
 	reg |= (DispMode << ZR36057_VFESPFR_DispMode);
-	if (format->palette != VIDEO_PALETTE_YUV422 && format->palette != VIDEO_PALETTE_YUYV)
-		reg |= ZR36057_VFESPFR_LittleEndian;
 	/* RJ: I don't know, why the following has to be the opposite
 	 * of the corresponding ZR36060 setting, but only this way
 	 * we get the correct colors when uncompressing to the screen  */
@@ -439,36 +437,6 @@ zr36057_set_vfe (struct zoran              *zr,
 	if (zr->norm != VIDEO_MODE_NTSC)
 		reg |= ZR36057_VFESPFR_ExtFl;	// NEEDED!!!!!!! Wolfgang
 	reg |= ZR36057_VFESPFR_TopField;
-	switch (format->palette) {
-
-	case VIDEO_PALETTE_YUYV:
-	case VIDEO_PALETTE_YUV422:
-		reg |= ZR36057_VFESPFR_YUV422;
-		break;
-
-	case VIDEO_PALETTE_RGB555:
-		reg |= ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ErrDif;
-		break;
-
-	case VIDEO_PALETTE_RGB565:
-		reg |= ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ErrDif;
-		break;
-
-	case VIDEO_PALETTE_RGB24:
-		reg |= ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_Pack24;
-		break;
-
-	case VIDEO_PALETTE_RGB32:
-		reg |= ZR36057_VFESPFR_RGB888;
-		break;
-
-	default:
-		dprintk(1,
-			KERN_INFO "%s: set_vfe() - unknown color_fmt=%x\n",
-			ZR_DEVNAME(zr), format->palette);
-		return;
-
-	}
 	if (HorDcm >= 48) {
 		reg |= 3 << ZR36057_VFESPFR_HFilter;	/* 5 tap filter */
 	} else if (HorDcm >= 32) {
@@ -476,6 +444,7 @@ zr36057_set_vfe (struct zoran              *zr,
 	} else if (HorDcm >= 16) {
 		reg |= 1 << ZR36057_VFESPFR_HFilter;	/* 3 tap filter */
 	}
+	reg |= format->vfespfr;
 	btwrite(reg, ZR36057_VFESPFR);
 
 	/* display configuration */
@@ -651,11 +620,17 @@ zr36057_set_memgrab (struct zoran *zr,
 		     int           mode)
 {
 	if (mode) {
-		if (btread(ZR36057_VSSFGR) &
-		    (ZR36057_VSSFGR_SnapShot | ZR36057_VSSFGR_FrameGrab))
+		/* We only check SnapShot and not FrameGrab here.  SnapShot==1
+		 * means a capture is already in progress, but FrameGrab==1
+		 * doesn't necessary mean that.  It's more correct to say a 1
+		 * to 0 transition indicates a capture completed.  If a
+		 * capture is pending when capturing is tuned off, FrameGrab
+		 * will be stuck at 1 until capturing is turned back on.
+		 */
+		if (btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot)
 			dprintk(1,
 				KERN_WARNING
-				"%s: zr36057_set_memgrab(1) with SnapShot or FrameGrab on!?\n",
+				"%s: zr36057_set_memgrab(1) with SnapShot on!?\n",
 				ZR_DEVNAME(zr));
 
 		/* switch on VSync interrupts */
@@ -672,11 +647,12 @@ zr36057_set_memgrab (struct zoran *zr,
 
 		zr->v4l_memgrab_active = 1;
 	} else {
-		zr->v4l_memgrab_active = 0;
-
 		/* switch off VSync interrupts */
 		btand(~zr->card.vsync_int, ZR36057_ICR);	// SW
 
+		zr->v4l_memgrab_active = 0;
+		zr->v4l_grab_frame = NO_GRAB_ACTIVE;
+
 		/* reenable grabbing to screen if it was running */
 		if (zr->v4l_overlay_active) {
 			zr36057_overlay(zr, 1);

+ 135 - 98
drivers/media/video/zoran_driver.c

@@ -99,88 +99,103 @@
 
 #include <asm/byteorder.h>
 
-const struct zoran_format zoran_formats[] = {
-	{
-		.name = "15-bit RGB",
-		.palette = VIDEO_PALETTE_RGB555,
-#ifdef CONFIG_VIDEO_V4L2
-#ifdef __LITTLE_ENDIAN
-		.fourcc = V4L2_PIX_FMT_RGB555,
+#if defined(CONFIG_VIDEO_V4L2) && defined(CONFIG_VIDEO_V4L1_COMPAT)
+#define ZFMT(pal, fcc, cs) \
+	.palette = (pal), .fourcc = (fcc), .colorspace = (cs)
+#elif defined(CONFIG_VIDEO_V4L2)
+#define ZFMT(pal, fcc, cs) \
+	.fourcc = (fcc), .colorspace = (cs)
 #else
-		.fourcc = V4L2_PIX_FMT_RGB555X,
-#endif
-		.colorspace = V4L2_COLORSPACE_SRGB,
+#define ZFMT(pal, fcc, cs) \
+	.palette = (pal)
 #endif
+
+const struct zoran_format zoran_formats[] = {
+	{
+		.name = "15-bit RGB LE",
+		ZFMT(VIDEO_PALETTE_RGB555,
+		     V4L2_PIX_FMT_RGB555, V4L2_COLORSPACE_SRGB),
 		.depth = 15,
 		.flags = ZORAN_FORMAT_CAPTURE |
 			 ZORAN_FORMAT_OVERLAY,
+		.vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif|
+			   ZR36057_VFESPFR_LittleEndian,
 	}, {
-		.name = "16-bit RGB",
-		.palette = VIDEO_PALETTE_RGB565,
-#ifdef CONFIG_VIDEO_V4L2
-#ifdef __LITTLE_ENDIAN
-		.fourcc = V4L2_PIX_FMT_RGB565,
-#else
-		.fourcc = V4L2_PIX_FMT_RGB565X,
-#endif
-		.colorspace = V4L2_COLORSPACE_SRGB,
-#endif
+		.name = "15-bit RGB BE",
+		ZFMT(-1,
+		     V4L2_PIX_FMT_RGB555X, V4L2_COLORSPACE_SRGB),
+		.depth = 15,
+		.flags = ZORAN_FORMAT_CAPTURE |
+			 ZORAN_FORMAT_OVERLAY,
+		.vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif,
+	}, {
+		.name = "16-bit RGB LE",
+		ZFMT(VIDEO_PALETTE_RGB565,
+		     V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB),
 		.depth = 16,
 		.flags = ZORAN_FORMAT_CAPTURE |
 			 ZORAN_FORMAT_OVERLAY,
+		.vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif|
+			   ZR36057_VFESPFR_LittleEndian,
+	}, {
+		.name = "16-bit RGB BE",
+		ZFMT(-1,
+		     V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB),
+		.depth = 16,
+		.flags = ZORAN_FORMAT_CAPTURE |
+			 ZORAN_FORMAT_OVERLAY,
+		.vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif,
 	}, {
 		.name = "24-bit RGB",
-		.palette = VIDEO_PALETTE_RGB24,
-#ifdef CONFIG_VIDEO_V4L2
-#ifdef __LITTLE_ENDIAN
-		.fourcc = V4L2_PIX_FMT_BGR24,
-#else
-		.fourcc = V4L2_PIX_FMT_RGB24,
-#endif
-		.colorspace = V4L2_COLORSPACE_SRGB,
-#endif
+		ZFMT(VIDEO_PALETTE_RGB24,
+		     V4L2_PIX_FMT_BGR24, V4L2_COLORSPACE_SRGB),
 		.depth = 24,
 		.flags = ZORAN_FORMAT_CAPTURE |
 			 ZORAN_FORMAT_OVERLAY,
+		.vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_Pack24,
 	}, {
-		.name = "32-bit RGB",
-		.palette = VIDEO_PALETTE_RGB32,
-#ifdef CONFIG_VIDEO_V4L2
-#ifdef __LITTLE_ENDIAN
-		.fourcc = V4L2_PIX_FMT_BGR32,
-#else
-		.fourcc = V4L2_PIX_FMT_RGB32,
-#endif
-		.colorspace = V4L2_COLORSPACE_SRGB,
-#endif
+		.name = "32-bit RGB LE",
+		ZFMT(VIDEO_PALETTE_RGB32,
+		     V4L2_PIX_FMT_BGR32, V4L2_COLORSPACE_SRGB),
+		.depth = 32,
+		.flags = ZORAN_FORMAT_CAPTURE |
+			 ZORAN_FORMAT_OVERLAY,
+		.vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_LittleEndian,
+	}, {
+		.name = "32-bit RGB BE",
+		ZFMT(-1,
+		     V4L2_PIX_FMT_RGB32, V4L2_COLORSPACE_SRGB),
 		.depth = 32,
 		.flags = ZORAN_FORMAT_CAPTURE |
 			 ZORAN_FORMAT_OVERLAY,
+		.vfespfr = ZR36057_VFESPFR_RGB888,
 	}, {
 		.name = "4:2:2, packed, YUYV",
-		.palette = VIDEO_PALETTE_YUV422,
-#ifdef CONFIG_VIDEO_V4L2
-		.fourcc = V4L2_PIX_FMT_YUYV,
-		.colorspace = V4L2_COLORSPACE_SMPTE170M,
-#endif
+		ZFMT(VIDEO_PALETTE_YUV422,
+		     V4L2_PIX_FMT_YUYV, V4L2_COLORSPACE_SMPTE170M),
+		.depth = 16,
+		.flags = ZORAN_FORMAT_CAPTURE |
+			 ZORAN_FORMAT_OVERLAY,
+		.vfespfr = ZR36057_VFESPFR_YUV422,
+	}, {
+		.name = "4:2:2, packed, UYVY",
+		ZFMT(VIDEO_PALETTE_UYVY,
+		     V4L2_PIX_FMT_UYVY, V4L2_COLORSPACE_SMPTE170M),
 		.depth = 16,
 		.flags = ZORAN_FORMAT_CAPTURE |
 			 ZORAN_FORMAT_OVERLAY,
+		.vfespfr = ZR36057_VFESPFR_YUV422|ZR36057_VFESPFR_LittleEndian,
 	}, {
 		.name = "Hardware-encoded Motion-JPEG",
-		.palette = -1,
-#ifdef CONFIG_VIDEO_V4L2
-		.fourcc = V4L2_PIX_FMT_MJPEG,
-		.colorspace = V4L2_COLORSPACE_SMPTE170M,
-#endif
+		ZFMT(-1,
+		     V4L2_PIX_FMT_MJPEG, V4L2_COLORSPACE_SMPTE170M),
 		.depth = 0,
 		.flags = ZORAN_FORMAT_CAPTURE |
 			 ZORAN_FORMAT_PLAYBACK |
 			 ZORAN_FORMAT_COMPRESSED,
 	}
 };
-static const int zoran_num_formats =
-    (sizeof(zoran_formats) / sizeof(struct zoran_format));
+#define NUM_FORMATS ARRAY_SIZE(zoran_formats)
 
 // RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined
 
@@ -768,13 +783,13 @@ v4l_grab (struct file       *file,
 	struct zoran *zr = fh->zr;
 	int res = 0, i;
 
-	for (i = 0; i < zoran_num_formats; i++) {
+	for (i = 0; i < NUM_FORMATS; i++) {
 		if (zoran_formats[i].palette == mp->format &&
 		    zoran_formats[i].flags & ZORAN_FORMAT_CAPTURE &&
 		    !(zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED))
 			break;
 	}
-	if (i == zoran_num_formats || zoran_formats[i].depth == 0) {
+	if (i == NUM_FORMATS || zoran_formats[i].depth == 0) {
 		dprintk(1,
 			KERN_ERR
 			"%s: v4l_grab() - wrong bytes-per-pixel format\n",
@@ -1173,10 +1188,14 @@ zoran_close_end_session (struct file *file)
 
 	/* v4l capture */
 	if (fh->v4l_buffers.active != ZORAN_FREE) {
+		long flags;
+
+		spin_lock_irqsave(&zr->spinlock, flags);
 		zr36057_set_memgrab(zr, 0);
 		zr->v4l_buffers.allocated = 0;
 		zr->v4l_buffers.active = fh->v4l_buffers.active =
 		    ZORAN_FREE;
+		spin_unlock_irqrestore(&zr->spinlock, flags);
 	}
 
 	/* v4l buffers */
@@ -2107,7 +2126,7 @@ zoran_do_ioctl (struct inode *inode,
 			vpict->colour, vpict->contrast, vpict->depth,
 			vpict->palette);
 
-		for (i = 0; i < zoran_num_formats; i++) {
+		for (i = 0; i < NUM_FORMATS; i++) {
 			const struct zoran_format *fmt = &zoran_formats[i];
 
 			if (fmt->palette != -1 &&
@@ -2116,7 +2135,7 @@ zoran_do_ioctl (struct inode *inode,
 			    fmt->depth == vpict->depth)
 				break;
 		}
-		if (i == zoran_num_formats) {
+		if (i == NUM_FORMATS) {
 			dprintk(1,
 				KERN_ERR
 				"%s: VIDIOCSPICT - Invalid palette %d\n",
@@ -2220,10 +2239,10 @@ zoran_do_ioctl (struct inode *inode,
 			ZR_DEVNAME(zr), vbuf->base, vbuf->width,
 			vbuf->height, vbuf->depth, vbuf->bytesperline);
 
-		for (i = 0; i < zoran_num_formats; i++)
+		for (i = 0; i < NUM_FORMATS; i++)
 			if (zoran_formats[i].depth == vbuf->depth)
 				break;
-		if (i == zoran_num_formats) {
+		if (i == NUM_FORMATS) {
 			dprintk(1,
 				KERN_ERR
 				"%s: VIDIOCSFBUF - invalid fbuf depth %d\n",
@@ -2672,14 +2691,14 @@ zoran_do_ioctl (struct inode *inode,
 			return -EINVAL;
 		}
 
-		for (i = 0; i < zoran_num_formats; i++) {
+		for (i = 0; i < NUM_FORMATS; i++) {
 			if (zoran_formats[i].flags & flag)
 				num++;
 			if (num == fmt->index)
 				break;
 		}
 		if (fmt->index < 0 /* late, but not too late */  ||
-		    i == zoran_num_formats)
+		    i == NUM_FORMATS)
 			return -EINVAL;
 
 		memset(fmt, 0, sizeof(*fmt));
@@ -2737,7 +2756,8 @@ zoran_do_ioctl (struct inode *inode,
 				fmt->fmt.pix.height =
 				    fh->v4l_settings.height;
 				fmt->fmt.pix.sizeimage =
-				    fh->v4l_buffers.buffer_size;
+				    fh->v4l_settings.bytesperline *
+				    fh->v4l_settings.height;
 				fmt->fmt.pix.pixelformat =
 				    fh->v4l_settings.format->fourcc;
 				fmt->fmt.pix.colorspace =
@@ -2941,11 +2961,11 @@ zoran_do_ioctl (struct inode *inode,
 			sfmtjpg_unlock_and_return:
 				mutex_unlock(&zr->resource_lock);
 			} else {
-				for (i = 0; i < zoran_num_formats; i++)
+				for (i = 0; i < NUM_FORMATS; i++)
 					if (fmt->fmt.pix.pixelformat ==
 					    zoran_formats[i].fourcc)
 						break;
-				if (i == zoran_num_formats) {
+				if (i == NUM_FORMATS) {
 					dprintk(1,
 						KERN_ERR
 						"%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x (%4.4s)\n",
@@ -2984,8 +3004,9 @@ zoran_do_ioctl (struct inode *inode,
 
 				/* tell the user the
 				 * results/missing stuff */
-				fmt->fmt.pix.sizeimage = fh->v4l_buffers.buffer_size	/*zr->gbpl * zr->gheight */
-				    ;
+				fmt->fmt.pix.sizeimage =
+					fh->v4l_settings.height *
+					fh->v4l_settings.bytesperline;
 				if (BUZ_MAX_HEIGHT <
 				    (fh->v4l_settings.height * 2))
 					fmt->fmt.pix.field =
@@ -3053,10 +3074,10 @@ zoran_do_ioctl (struct inode *inode,
 			fb->fmt.bytesperline, fb->fmt.pixelformat,
 			(char *) &printformat);
 
-		for (i = 0; i < zoran_num_formats; i++)
+		for (i = 0; i < NUM_FORMATS; i++)
 			if (zoran_formats[i].fourcc == fb->fmt.pixelformat)
 				break;
-		if (i == zoran_num_formats) {
+		if (i == NUM_FORMATS) {
 			dprintk(1,
 				KERN_ERR
 				"%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n",
@@ -3439,8 +3460,13 @@ zoran_do_ioctl (struct inode *inode,
 				goto strmoff_unlock_and_return;
 
 			/* unload capture */
-			if (zr->v4l_memgrab_active)
+			if (zr->v4l_memgrab_active) {
+				long flags;
+
+				spin_lock_irqsave(&zr->spinlock, flags);
 				zr36057_set_memgrab(zr, 0);
+				spin_unlock_irqrestore(&zr->spinlock, flags);
+			}
 
 			for (i = 0; i < fh->v4l_buffers.num_buffers; i++)
 				zr->v4l_buffers.buffer[i].state =
@@ -3704,11 +3730,11 @@ zoran_do_ioctl (struct inode *inode,
 		dprintk(3, KERN_DEBUG "%s: VIDIOC_S_STD - norm=0x%llx\n",
 			ZR_DEVNAME(zr), (unsigned long long)*std);
 
-		if (*std == V4L2_STD_PAL)
+		if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL))
 			norm = VIDEO_MODE_PAL;
-		else if (*std == V4L2_STD_NTSC)
+		else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC))
 			norm = VIDEO_MODE_NTSC;
-		else if (*std == V4L2_STD_SECAM)
+		else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM))
 			norm = VIDEO_MODE_SECAM;
 		else if (*std == V4L2_STD_ALL)
 			norm = VIDEO_MODE_AUTO;
@@ -4149,11 +4175,11 @@ zoran_do_ioctl (struct inode *inode,
 				   V4L2_BUF_TYPE_VIDEO_CAPTURE) {
 				int i;
 
-				for (i = 0; i < zoran_num_formats; i++)
+				for (i = 0; i < NUM_FORMATS; i++)
 					if (zoran_formats[i].fourcc ==
 					    fmt->fmt.pix.pixelformat)
 						break;
-				if (i == zoran_num_formats) {
+				if (i == NUM_FORMATS) {
 					res = -EINVAL;
 					goto tryfmt_unlock_and_return;
 				}
@@ -4213,8 +4239,8 @@ zoran_poll (struct file *file,
 {
 	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
-	wait_queue_head_t *queue = NULL;
 	int res = 0, frame;
+	unsigned long flags;
 
 	/* we should check whether buffers are ready to be synced on
 	 * (w/o waits - O_NONBLOCK) here
@@ -4228,51 +4254,58 @@ zoran_poll (struct file *file,
 
 	switch (fh->map_mode) {
 	case ZORAN_MAP_MODE_RAW:
-		if (fh->v4l_buffers.active == ZORAN_FREE ||
-		    zr->v4l_pend_head == zr->v4l_pend_tail) {
-			dprintk(1,
-				"%s: zoran_poll() - no buffers queued\n",
-				ZR_DEVNAME(zr));
-			res = POLLNVAL;
-			goto poll_unlock_and_return;
-		}
-		queue = &zr->v4l_capq;
-		frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME];
-		poll_wait(file, queue, wait);
-		if (fh->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE)
+		poll_wait(file, &zr->v4l_capq, wait);
+		frame = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME];
+
+		spin_lock_irqsave(&zr->spinlock, flags);
+		dprintk(3,
+			KERN_DEBUG
+			"%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n",
+			ZR_DEVNAME(zr), __FUNCTION__,
+			"FAL"[fh->v4l_buffers.active], zr->v4l_sync_tail,
+			"UPMD"[zr->v4l_buffers.buffer[frame].state],
+			zr->v4l_pend_tail, zr->v4l_pend_head);
+		/* Process is the one capturing? */
+		if (fh->v4l_buffers.active != ZORAN_FREE &&
+		    /* Buffer ready to DQBUF? */
+		    zr->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE)
 			res = POLLIN | POLLRDNORM;
+		spin_unlock_irqrestore(&zr->spinlock, flags);
+
 		break;
 
 	case ZORAN_MAP_MODE_JPG_REC:
 	case ZORAN_MAP_MODE_JPG_PLAY:
-		if (fh->jpg_buffers.active == ZORAN_FREE ||
-		    zr->jpg_que_head == zr->jpg_que_tail) {
-			dprintk(1,
-				"%s: zoran_poll() - no buffers queued\n",
-				ZR_DEVNAME(zr));
-			res = POLLNVAL;
-			goto poll_unlock_and_return;
-		}
-		queue = &zr->jpg_capq;
+		poll_wait(file, &zr->jpg_capq, wait);
 		frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
-		poll_wait(file, queue, wait);
-		if (fh->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) {
+
+		spin_lock_irqsave(&zr->spinlock, flags);
+		dprintk(3,
+			KERN_DEBUG
+			"%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n",
+			ZR_DEVNAME(zr), __FUNCTION__,
+			"FAL"[fh->jpg_buffers.active], zr->jpg_que_tail,
+			"UPMD"[zr->jpg_buffers.buffer[frame].state],
+			zr->jpg_que_head, zr->jpg_dma_tail, zr->jpg_dma_head);
+		if (fh->jpg_buffers.active != ZORAN_FREE &&
+		    zr->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) {
 			if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC)
 				res = POLLIN | POLLRDNORM;
 			else
 				res = POLLOUT | POLLWRNORM;
 		}
+		spin_unlock_irqrestore(&zr->spinlock, flags);
+
 		break;
 
 	default:
 		dprintk(1,
+			KERN_ERR
 			"%s: zoran_poll() - internal error, unknown map_mode=%d\n",
 			ZR_DEVNAME(zr), fh->map_mode);
 		res = POLLNVAL;
-		goto poll_unlock_and_return;
 	}
 
-poll_unlock_and_return:
 	mutex_unlock(&zr->resource_lock);
 
 	return res;
@@ -4368,11 +4401,15 @@ zoran_vm_close (struct vm_area_struct *vma)
 				mutex_lock(&zr->resource_lock);
 
 				if (fh->v4l_buffers.active != ZORAN_FREE) {
+					long flags;
+
+					spin_lock_irqsave(&zr->spinlock, flags);
 					zr36057_set_memgrab(zr, 0);
 					zr->v4l_buffers.allocated = 0;
 					zr->v4l_buffers.active =
 					    fh->v4l_buffers.active =
 					    ZORAN_FREE;
+					spin_unlock_irqrestore(&zr->spinlock, flags);
 				}
 				//v4l_fbuffer_free(file);
 				fh->v4l_buffers.allocated = 0;

+ 1 - 0
include/linux/dvb/video.h

@@ -29,6 +29,7 @@
 #ifdef __KERNEL__
 #include <linux/types.h>
 #else
+#include <asm/types.h>
 #include <stdint.h>
 #include <time.h>
 #endif

+ 2 - 0
sound/pci/bt87x.c

@@ -781,6 +781,8 @@ static struct pci_device_id snd_bt87x_ids[] = {
 	BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000),
 	/* Viewcast Osprey 200 */
 	BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100),
+	/* Viewcast Osprey 440 (rate is configurable via gpio) */
+	BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff07, 32000),
 	/* ATI TV-Wonder */
 	BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, 32000),
 	/* Leadtek Winfast tv 2000xp delux */