# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.573   -> 1.574  
#	Documentation/usb/ov511.txt	1.5     -> 1.6    
#	drivers/usb/media/ov511.c	1.31    -> 1.32   
#	drivers/usb/media/ov511.h	1.8     -> 1.9    
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/16	mark@alpha.dyndns.org	1.574
# [PATCH] ov511 1.62 for 2.5.34
# 
#  Update the ov511 driver to version 1.62:
#  o Update email address
#  o Remove some dead code and fix some harmless typos
#  o New device: Alpha Vision Tech. AlphaCam SE
#  o Fix assignment of ov->proc_button->owner to not cause
#    NULL pointer deref (credit: Oleg K.)
#  o Support I2C read/write ioctl()s via V4L (credit: Oleg K.)
#  o Add OV518-specific register dump code
#  o New snapshot reset sequence; old one was causing
#    erroneous I2C writes (credit: Oleg K.)
#  o OV6630 needs different register 0x14 settings than OV6620
#  o Don't print palette errors by default
#  o Detect OV518 cameras that have packet numbering enabled
#    by default and set ov->packet_numbering accordingly. This
#    should fix the problems some users were having with babble
#    (USB error -75) and cameras not working at all.
# --------------------------------------------
#
diff -Nru a/Documentation/usb/ov511.txt b/Documentation/usb/ov511.txt
--- a/Documentation/usb/ov511.txt	Mon Sep 16 15:00:56 2002
+++ b/Documentation/usb/ov511.txt	Mon Sep 16 15:00:56 2002
@@ -105,15 +105,6 @@
           4=most function calls and data parsing messages
           5=highly repetitive mesgs
 
-  NAME: fix_rgb_offset
-  TYPE: integer (Boolean)
-  DEFAULT: 0
-  DESC: Some people have reported that the blue component of the image is one
-        or so lines higher than the red component. This is only apparent in 
-        images with white objects on black backgrounds at 640x480. Setting this
-        to 1 will realign the color planes correctly. NOTE: You will likely
-        need a fast (500 MHz) CPU.
-
   NAME: snapshot
   TYPE: integer (Boolean)
   DEFAULT: 0
@@ -121,13 +112,6 @@
 	the snapshot button is pressed. Note: enabling this mode disables
 	/proc/video/ov511/<minor#>/button
 
-  NAME: force_rgb	(Deprecated; may be removed in the future)
-  TYPE: integer (Boolean)
-  DEFAULT: 0
-  DESC: Force image to be read in RGB instead of BGR. This option allow
-        programs that expect RGB data (e.g. gqcam) to work with this driver. If
-        your colors look VERY wrong, you may want to change this.
-
   NAME: cams
   TYPE: integer (1-4 for OV511, 1-31 for OV511+)
   DEFAULT: 1
@@ -234,12 +218,7 @@
 	greyscale mode with a color camera, for example. Supported modes are:
 		0                           (Allows all the following formats)
 		1   VIDEO_PALETTE_GREY      (Linear greyscale)
-		3   VIDEO_PALETTE_RGB565    (565 16 bit RGB)
-		4   VIDEO_PALETTE_RGB24     (24bit RGB)
-		7   VIDEO_PALETTE_YUV422    (YUV422 capture)
-		8   VIDEO_PALETTE_YUYV      (YUV422 capture; same as 7)
 		10  VIDEO_PALETTE_YUV420    (YUV 4:2:0 Planar)
-		13  VIDEO_PALETTE_YUV422P   (YUV 4:2:2 Planar)
 		15  VIDEO_PALETTE_YUV420P   (YUV 4:2:0 Planar, same as 10)
 
   NAME: backlight
@@ -278,29 +257,17 @@
 
 WORKING FEATURES:
  o Color streaming/capture at most widths and heights that are multiples of 8.
- o RGB24, RGB565, YUV420/YUV420P, YUV422/YUYV, and YUV422P color
  o Monochrome (use force_palette=1 to enable)
  o Setting/getting of saturation, contrast, brightness, and hue (only some of
    them work the OV7620 and OV7620AE)
  o /proc status reporting
  o SAA7111A video capture support at 320x240 and 640x480
  o Compression support
-
-EXPERIMENTAL FEATURES:
- o OV518/OV518+ support
- o OV6630 sensor support
- o Banding filter
  o SMP compatibility
 
-TO-DO:
- o V4L2 support (This will be done after the next kernel patch release)
- o Setting of hue not working with OV7620
- o Setting of contrast and hue not working with OV7620AE
- o OV8600 sensor support (Not used in anything yet)
-
 HOW TO CONTACT ME:
 
-You can email me at mmcclell@bigfoot.com . Please prefix the subject line
+You can email me at mark@alpha.dyndns.org . Please prefix the subject line
 with "OV511: " so that I am certain to notice your message.
 
 CREDITS:
diff -Nru a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
--- a/drivers/usb/media/ov511.c	Mon Sep 16 15:00:56 2002
+++ b/drivers/usb/media/ov511.c	Mon Sep 16 15:00:56 2002
@@ -60,9 +60,9 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.61 for Linux 2.5"
-#define EMAIL "mmcclell@bigfoot.com"
-#define DRIVER_AUTHOR "Mark McClelland <mmcclell@bigfoot.com> & Bret Wallach \
+#define DRIVER_VERSION "v1.62 for Linux 2.5"
+#define EMAIL "mark@alpha.dyndns.org"
+#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org> & Bret Wallach \
 	& Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha \
 	<cpbotha@ieee.org> & Claudio Matsuoka <claudio@conectiva.com>"
 #define DRIVER_DESC "ov511 USB Camera Driver"
@@ -97,7 +97,6 @@
 static int cams			= 1;
 static int compress;
 static int testpat;
-static int sensor_gbr;
 static int dumppix;
 static int led 			= 1;
 static int dump_bridge;
@@ -113,16 +112,9 @@
 static int qvuv			= 0x04;
 static int lightfreq;
 static int bandingfilter;
-
-/* Pixel clock divisor */
 static int clockdiv		= -1;
-
-/* Isoc packet size */
 static int packetsize		= -1;
-
-/* Frame drop register (16h) */
 static int framedrop		= -1;
-
 static int fastset;
 static int force_palette;
 static int backlight;
@@ -268,6 +260,7 @@
 	{ 102, "AverMedia InterCam Elite" },
 	{ 112, "MediaForte MV300" },	/* or OV7110 evaluation kit */
 	{ 192, "Webeye 2000B" },
+	{ 253, "Alpha Vision Tech. AlphaCam SE" },
 	{  -1, NULL }
 };
 
@@ -558,8 +551,8 @@
 			ov511_read_proc_button, ov);
 		if (!ov->proc_button)
 			return;
+		ov->proc_button->owner = THIS_MODULE;
 	}
-	ov->proc_button->owner = THIS_MODULE;
 
 	/* Create "control" entry (ioctl() interface) */
 	PDEBUG(4, "creating /proc/video/ov511/%s/control", dirname);
@@ -1137,8 +1130,6 @@
 	return 0;
 }
 
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
-
 /* Write to a specific I2C slave ID and register, using the specified mask */
 static int
 i2c_w_slave(struct usb_ov511 *ov,
@@ -1194,8 +1185,6 @@
 	return rc;
 }
 
-#endif /* defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) */
-
 /* Sets I2C read and write slave IDs. Returns <0 for error */
 static int
 ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid)
@@ -1241,8 +1230,7 @@
 static void
 dump_i2c_range(struct usb_ov511 *ov, int reg1, int regn)
 {
-	int i;
-	int rc;
+	int i, rc;
 
 	for (i = reg1; i <= regn; i++) {
 		rc = i2c_r(ov, i);
@@ -1260,8 +1248,7 @@
 static void
 dump_reg_range(struct usb_ov511 *ov, int reg1, int regn)
 {
-	int i;
-	int rc;
+	int i, rc;
 
 	for (i = reg1; i <= regn; i++) {
 		rc = reg_r(ov, i);
@@ -1269,7 +1256,6 @@
 	}
 }
 
-/* FIXME: Should there be an OV518 version of this? */
 static void
 ov511_dump_regs(struct usb_ov511 *ov)
 {
@@ -1295,6 +1281,31 @@
 	dump_reg_range(ov, 0xa0, 0xbf);
 
 }
+
+static void
+ov518_dump_regs(struct usb_ov511 *ov)
+{
+	info("VIDEO MODE REGS");
+	dump_reg_range(ov, 0x20, 0x2f);
+	info("DATA PUMP AND SNAPSHOT REGS");
+	dump_reg_range(ov, 0x30, 0x3f);
+	info("I2C REGS");
+	dump_reg_range(ov, 0x40, 0x4f);
+	info("SYSTEM CONTROL AND VENDOR REGS");
+	dump_reg_range(ov, 0x50, 0x5f);
+	info("60 - 6F");
+	dump_reg_range(ov, 0x60, 0x6f);
+	info("70 - 7F");
+	dump_reg_range(ov, 0x70, 0x7f);
+	info("Y QUANTIZATION TABLE");
+	dump_reg_range(ov, 0x80, 0x8f);
+	info("UV QUANTIZATION TABLE");
+	dump_reg_range(ov, 0x90, 0x9f);
+	info("A0 - BF");
+	dump_reg_range(ov, 0xa0, 0xbf);
+	info("CBR");
+	dump_reg_range(ov, 0xc0, 0xcf);
+}
 #endif
 
 /*****************************************************************************/
@@ -1336,9 +1347,9 @@
 ov51x_clear_snapshot(struct usb_ov511 *ov)
 {
 	if (ov->bclass == BCL_OV511) {
-		reg_w(ov, R51x_SYS_SNAP, 0x01);
-		reg_w(ov, R51x_SYS_SNAP, 0x03);
-		reg_w(ov, R51x_SYS_SNAP, 0x01);
+		reg_w(ov, R51x_SYS_SNAP, 0x00);
+		reg_w(ov, R51x_SYS_SNAP, 0x02);
+		reg_w(ov, R51x_SYS_SNAP, 0x00);
 	} else if (ov->bclass == BCL_OV518) {
 		warn("snapshot reset not supported yet on OV518(+)");
 	} else {
@@ -1383,7 +1394,7 @@
 	if (i2c_w(ov, 0x12, 0x80) < 0) return -EIO;
 
 	/* Wait for it to initialize */
-	schedule_timeout (1 + 150 * HZ / 1000);
+	schedule_timeout(1 + 150 * HZ / 1000);
 
 	for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) {
 		if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) &&
@@ -2018,10 +2029,6 @@
 
 	p->whiteness = 105 << 8;
 
-	/* Can we get these from frame[0]? -claudio? */
-	p->depth = ov->frame[0].depth;
-	p->palette = ov->frame[0].format;
-
 	return 0;
 }
 
@@ -2424,9 +2431,10 @@
 #endif
 		break;
 	case SEN_OV6620:
-	case SEN_OV6630:
 		i2c_w(ov, 0x14, qvga?0x24:0x04);
-		/* No special settings yet */
+		break;
+	case SEN_OV6630:
+		i2c_w(ov, 0x14, qvga?0xa4:0x84);
 		break;
 	default:
 		err("Invalid sensor");
@@ -2504,19 +2512,11 @@
 	if (framedrop >= 0)
 		i2c_w(ov, 0x16, framedrop);
 
-	if (sensor_gbr)
-		i2c_w_mask(ov, 0x12, 0x08, 0x08);
-	else
-		i2c_w_mask(ov, 0x12, 0x00, 0x08);
-
 	/* Test Pattern */
 	i2c_w_mask(ov, 0x12, (testpat?0x02:0x00), 0x02);
 
-	/* Auto white balance */
-//	if (awb)
-		i2c_w_mask(ov, 0x12, 0x04, 0x04);
-//	else
-//		i2c_w_mask(ov, 0x12, 0x00, 0x04);
+	/* Enable auto white balance */
+	i2c_w_mask(ov, 0x12, 0x04, 0x04);
 
 	// This will go away as soon as ov51x_mode_init_sensor_regs()
 	// is fully tested.
@@ -2705,7 +2705,7 @@
 	reg_w(ov, R511_CAM_PXDIV, 0x00);
 	reg_w(ov, R511_CAM_LNDIV, 0x00);
 
-	/* YUV420, low pass filer on */
+	/* YUV420, low pass filter on */
 	reg_w(ov, R511_CAM_OPTS, 0x03);
 
 	/* Snapshot additions */
@@ -4120,11 +4120,6 @@
 	PDEBUG(4, "entered");
 	down(&ov->buf_lock);
 
-	if (ov->buf_state == BUF_PEND_DEALLOC) {
-		ov->buf_state = BUF_ALLOCATED;
-		del_timer(&ov->buf_timer);
-	}
-
 	if (ov->buf_state == BUF_ALLOCATED)
 		goto out;
 
@@ -4394,6 +4389,10 @@
 		if (sensor_get_picture(ov, p))
 			return -EIO;
 
+		/* Can we get these from frame[0]? -claudio? */
+		p->depth = ov->frame[0].depth;
+		p->palette = ov->frame[0].format;
+
 		return 0;
 	}
 	case VIDIOCSPICT:
@@ -4558,8 +4557,8 @@
 
 		depth = get_depth(vm->format);
 		if (!depth) {
-			err("VIDIOCMCAPTURE: invalid format (%s)",
-			    symbolic(v4l1_plist, vm->format));
+			PDEBUG(2, "VIDIOCMCAPTURE: invalid format (%s)",
+			       symbolic(v4l1_plist, vm->format));
 			return -EINVAL;
 		}
 
@@ -4580,8 +4579,8 @@
 		}
 
 		if (force_palette && (vm->format != force_palette)) {
-			info("palette rejected (%s)",
-			     symbolic(v4l1_plist, vm->format));
+			PDEBUG(2, "palette rejected (%s)",
+			       symbolic(v4l1_plist, vm->format));
 			return -EINVAL;
 		}
 
@@ -4710,6 +4709,24 @@
 
 		return 0;
 	}
+	case OV511IOC_WI2C:
+	{
+		struct ov511_i2c_struct *w = arg;
+
+		return i2c_w_slave(ov, w->slave, w->reg, w->value, w->mask);
+	}
+	case OV511IOC_RI2C:
+	{
+		struct ov511_i2c_struct *r = arg;
+		int rc;
+
+		rc = i2c_r_slave(ov, r->slave, r->reg);
+		if (rc < 0)
+			return rc;
+
+		r->value = rc;
+		return 0;
+	}
 	default:
 		PDEBUG(3, "Unsupported IOCtl: 0x%X", cmd);
 		return -ENOIOCTLCMD;
@@ -4934,11 +4951,11 @@
 static struct file_operations ov511_fops = {
 	.owner =	THIS_MODULE,
 	.open =		ov51x_v4l1_open,
-	.release =     	ov51x_v4l1_close,
+	.release =	ov51x_v4l1_close,
 	.read =		ov51x_v4l1_read,
 	.mmap =		ov51x_v4l1_mmap,
-	.ioctl =        ov51x_v4l1_ioctl,
-	.llseek =       no_llseek,
+	.ioctl =	ov51x_v4l1_ioctl,
+	.llseek =	no_llseek,
 };
 
 static struct video_device vdev_template = {
@@ -4946,7 +4963,7 @@
 	.name =		"OV511 USB Camera",
 	.type =		VID_TYPE_CAPTURE,
 	.hardware =	VID_HARDWARE_OV511,
-	.fops =         &ov511_fops,
+	.fops =		&ov511_fops,
 };
 
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
@@ -5136,8 +5153,7 @@
 		if (copy_from_user(&w, arg, sizeof(w)))
 			return -EFAULT;
 
-		return i2c_w_slave(ov, w.slave, w.reg, w.value,
-			w.mask);
+		return i2c_w_slave(ov, w.slave, w.reg, w.value,	w.mask);
 	}
 	case OV511IOC_RI2C:
 	{
@@ -5343,17 +5359,16 @@
 		ov->sensor = SEN_OV7610;
 	} else if ((rc & 3) == 1) {
 		/* I don't know what's different about the 76BE yet. */
-		if (i2c_r(ov, 0x15) & 1) {
+		if (i2c_r(ov, 0x15) & 1)
 			info("Sensor is an OV7620AE");
-		} else {
+		else
 			info("Sensor is an OV76BE");
-		}
 
 		/* OV511+ will return all zero isoc data unless we
 		 * configure the sensor as a 7620. Someone needs to
 		 * find the exact reg. setting that causes this. */
 		if (ov->bridge == BRG_OV511PLUS) {
-			info("Enabling 511+/76BE workaround");
+			info("Enabling 511+/7620AE workaround");
 			ov->sensor = SEN_OV7620;
 		} else {
 			ov->sensor = SEN_OV76BE;
@@ -5745,9 +5760,9 @@
 
 	static struct ov511_regvals aRegvalsNorm511[] = {
 		{ OV511_REG_BUS, R511_DRAM_FLOW_CTL, 	0x01 },
-		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x01 },
-		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x03 },
-		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x01 },
+		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x00 },
+		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x02 },
+		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x00 },
 		{ OV511_REG_BUS, R511_FIFO_OPTS,	0x1f },
 		{ OV511_REG_BUS, R511_COMP_EN,		0x00 },
 		{ OV511_REG_BUS, R511_COMP_LUT_EN,	0x03 },
@@ -5756,9 +5771,9 @@
 
 	static struct ov511_regvals aRegvalsNorm511Plus[] = {
 		{ OV511_REG_BUS, R511_DRAM_FLOW_CTL,	0xff },
-		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x01 },
-		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x03 },
-		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x01 },
+		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x00 },
+		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x02 },
+		{ OV511_REG_BUS, R51x_SYS_SNAP,		0x00 },
 		{ OV511_REG_BUS, R511_FIFO_OPTS,	0xff },
 		{ OV511_REG_BUS, R511_COMP_EN,		0x00 },
 		{ OV511_REG_BUS, R511_COMP_LUT_EN,	0x03 },
@@ -5970,11 +5985,20 @@
 
 	if (ov518_init_compression(ov)) goto error;
 
-	/* OV518+ has packet numbering turned on by default */
 	if (ov->bridge == BRG_OV518)
-		ov->packet_numbering = 0;
-	else
+	{
+		struct usb_interface *ifp = &ov->dev->config[0].interface[0];
+		__u16 mxps = ifp->altsetting[7].endpoint[0].wMaxPacketSize;
+
+		/* Some OV518s have packet numbering by default, some don't */
+		if (mxps == 897)
+			ov->packet_numbering = 1;
+		else
+			ov->packet_numbering = 0;
+	} else {
+		/* OV518+ has packet numbering turned on by default */
 		ov->packet_numbering = 1;
+	}
 
 	ov518_set_packet_size(ov, 0);
 
@@ -6126,7 +6150,8 @@
 
 	ov->buf_state = BUF_NOT_ALLOCATED;
 
-	/* Must be kmalloc()'ed, for DMA accessibility */
+	/* Allocate control transfer buffer. */
+	/* Must be kmalloc()'ed, for DMA compatibility */
 	ov->cbuf = kmalloc(OV511_CBUF_SIZE, GFP_KERNEL);
 	if (!ov->cbuf)
 		goto error;
@@ -6156,8 +6181,12 @@
 		goto error;
 
 #ifdef OV511_DEBUG
-	if (dump_bridge)
-		ov511_dump_regs(ov);
+	if (dump_bridge) {
+		if (ov->bclass == BCL_OV511)
+			ov511_dump_regs(ov);
+		else
+			ov518_dump_regs(ov);
+	}
 #endif
 
 	memcpy(&ov->vdev, &vdev_template, sizeof(vdev_template));
@@ -6259,12 +6288,14 @@
 		kfree(ov);
 		ov = NULL;
 	}
+
+	PDEBUG(3, "Disconnect complete");
 }
 
 static struct usb_driver ov511_driver = {
 	.owner =	THIS_MODULE,
 	.name =		"ov511",
-	.id_table =     device_table,
+	.id_table =	device_table,
 	.probe =	ov51x_probe,
 	.disconnect =	ov51x_disconnect
 };
diff -Nru a/drivers/usb/media/ov511.h b/drivers/usb/media/ov511.h
--- a/drivers/usb/media/ov511.h	Mon Sep 16 15:00:56 2002
+++ b/drivers/usb/media/ov511.h	Mon Sep 16 15:00:56 2002
@@ -286,21 +286,6 @@
 	SEN_SAA7111A,
 };
 
-// Not implemented yet
-#if 0
-/* Sensor classes */
-enum {
-	SCL_UNKNOWN,
-	SCL_OV7610,	/* 7610, 76BE, 7620AE (for now) */
-	SCL_OV7620,
-	SCL_OV6620,	
-	SCL_OV6630,	/* 6630, 6630AE, 6630AF */
-	SCL_OV8600,
-	SCL_KS0127,	/* SEN_KS0127, SEN_KS0127B */
-	SCL_SAA7111A,
-};
-#endif
-
 enum {
 	STATE_SCANNING,		/* Scanning for start */
 	STATE_HEADER,		/* Parsing header */
@@ -311,7 +296,6 @@
 enum {
 	BUF_NOT_ALLOCATED,
 	BUF_ALLOCATED,
-	BUF_PEND_DEALLOC,	/* ov511->buf_timer is set */
 };
 
 /* --------- Definition of ioctl interface --------- */
@@ -521,7 +505,6 @@
 	int bridge;		/* Type of bridge (BRG_*) */
 	int bclass;		/* Class of bridge (BCL_*) */
 	int sensor;		/* Type of image sensor chip (SEN_*) */
-	int sclass;		/* Type of image sensor chip (SCL_*) */
 
 	int packet_size;	/* Frame size per isoc desc */
 	int packet_numbering;	/* Is ISO frame numbering enabled? */
@@ -537,7 +520,6 @@
 	/* Framebuffer/sbuf management */
 	int buf_state;
 	struct semaphore buf_lock;
-	struct timer_list buf_timer;
 
 	struct ov51x_decomp_ops *decomp_ops;
 
