diff -Naur linux-2.3.40-pre4-orig/Documentation/usb/ov511.txt linux/Documentation/usb/ov511.txt
--- linux-2.3.40-pre4-orig/Documentation/usb/ov511.txt	Sat Jan 15 01:16:16 2000
+++ linux/Documentation/usb/ov511.txt	Mon Jan 17 06:34:34 2000
@@ -2,22 +2,28 @@
 Readme for Linux device driver for the OmniVision OV511 USB to camera bridge IC
 -------------------------------------------------------------------------------
 
+Author: Mark McClelland
+Homepage: http://people.delphi.com/mmcclelland/linux/
+
 INTRODUCTION:
 
 This is a preliminary version of my OV511 Linux device driver. Currently, it can
-grab a frame in black-and-white at 640x480 using the vidcat utility. Color,
-variable image size, and compatibility with other apps are currently under
-development.
+grab a frame in color (YUV420) at 640x480 or 320x240 using either vidcat or
+xawtv. Other utilities may work but have not yet been tested.
+
+NOTE: 320x240 does not work reliably for me, and causes complete system crashes.
+      I recommend not using it until a later version, and if you do, run "sync"
+      first.
 
 SUPPORTED CAMERAS:
 ________________________________________________________
 Manufacturer     | Model          | Custom ID | Status
 -----------------+----------------+-----------+---------
 MediaForte       | MV300          | 0         | Untested
-D-Link           | DSB-C300	      | 3         | Working
+D-Link           | DSB-C300       | 3         | Working
 Creative Labs    | WebCam 3       | 21        | Working
-Lifeview         | RoboCam        |	100       | Untested
-AverMedia        | InterCam Elite | 102       | Untested
+Lifeview         | RoboCam        | 100       | Untested
+AverMedia        | InterCam Elite | 102       | Working
 --------------------------------------------------------
 
 Any camera using the OV511 and the OV7610 CCD should work with this driver. The
@@ -32,9 +38,55 @@
 - If you want to help with the development, get the chip's specification docs at
   http://www.ovt.com/omniusbp.html
 
-- A Video4Linux compatible frame grabber program (I recommend vidcat)
+- A Video4Linux compatible frame grabber program (I recommend vidcat and xawtv)
   (see: http://www.exploits.org/v4l/ )
-  
+
+HOW TO USE IT:
+
+You must have first compiled USB support, support for your specific USB host
+controller (UHCI or OHCI), and Video4Linux support for your kernel (I recommend
+making them modules.) 
+
+Next, (as root) from your appropriate modules directory (lib/modules/2.3.XX):
+
+	insmod usb/usbcore.o
+	insmod usb/usb-uhci.o  <OR>  insmod usb/ohci-hcd.o
+	insmod misc/videodev.o
+	insmod usb/ov511.o
+
+If it is not already there (it usually is), create the video device:
+
+	mknod /dev/video c 81 0
+	
+Now you are ready to run a video app! Both vidcat and xawtv work well for me
+at 640x480.
+	
+[Using vidcat:]
+
+	vidcat -s 640x480 > test.jpg
+	xview test.jpg
+	
+[Using xawtv:]
+
+You must make some modifications to the source and compile it before you use it.
+(Note: this may not be applicable to versions other than 3.06)
+
+In src/Xawtv.ad, change xawtv.tv.width to 640 and xawtv.tv.height to 480. Next,
+in src/grab-v4l.c, change SYNC_TIMEOUT from 1 to 2. Then, from the main xawtv
+directory:
+
+	make clean
+	./configure
+	make
+	make install
+
+Now you should be able to run xawtv. Right click for the options dialog.
+
+WORKING FEATURES:
+ o Color streaming/capture at 640x480 (reliably) and 320x240 (unreliably)
+ o YUV420 color
+ o Setting/getting of saturation, contrast and brightness (no color yet)
+
 WHAT NEEDS TO BE DONE:
 
 The rest of the work will involve implementing support for all the different
@@ -55,4 +107,4 @@
 The code is based in no small part on the CPiA driver by Johannes Erdfelt,
 Randy Dunlap, and others. Big thanks to them for their pioneering work on that
 and the USB stack. Thanks to Bret Wallach for getting camera reg IO , ISOC, and
-preliminary image capture working.
+image capture working.
diff -Naur linux-2.3.40-pre4-orig/drivers/usb/ov511.c linux/drivers/usb/ov511.c
--- linux-2.3.40-pre4-orig/drivers/usb/ov511.c	Sat Jan 15 01:19:44 2000
+++ linux/drivers/usb/ov511.c	Mon Jan 17 05:16:26 2000
@@ -11,8 +11,11 @@
  *    DEBUG - Debugging code.
  *    FIXME - Something that is broken or needs improvement.
  *
- * Version History:
- *    Version 1.00 - Initial version
+ * Version: 1.05
+ *
+ * Please see the file: linux/Documentation/usb/ov511.txt 
+ * and the website at:  http://people.delphi.com/mmcclelland/linux/ 
+ * for more info.
  */
 
 /*
@@ -63,6 +66,8 @@
 
 #define OV511_I2C_RETRIES 3
 
+#define OV7610_AUTO_ADJUST 1
+
 /* Video Size 640 x 480 x 3 bytes for RGB */
 #define MAX_FRAME_SIZE (640 * 480 * 3)
 
@@ -201,7 +206,7 @@
 		0, (__u16)reg, &value, 1, HZ);	
 			
 #if 0
-	PDEBUG("reg write: 0x%02X:0x%02X\n", reg, value);
+	PDEBUG("reg write: 0x%02X:0x%02X", reg, value);
 #endif
 			
 	return rc;
@@ -220,7 +225,7 @@
 		0, (__u16)reg, buffer, 1, HZ);
                                
 #if 0
-	PDEBUG("reg read: 0x%02X:0x%02X\n", reg, buffer[0]);
+	PDEBUG("reg read: 0x%02X:0x%02X", reg, buffer[0]);
 #endif
 	
 	if(rc < 0)
@@ -234,7 +239,7 @@
 	int rc, retries;
 
 #if 0
-	PDEBUG("i2c write: 0x%02X:0x%02X\n", reg, value);
+	PDEBUG("i2c write: 0x%02X:0x%02X", reg, value);
 #endif
 	/* Three byte write cycle */
 	for(retries = OV511_I2C_RETRIES;;) {
@@ -316,7 +321,7 @@
 
 	value = ov511_reg_read(dev, OV511_REG_I2C_DATA_PORT);
 #if 0
-	PDEBUG("i2c read: 0x%02X:0x%02X\n", reg, value);
+	PDEBUG("i2c read: 0x%02X:0x%02X", reg, value);
 #endif
 		
 	/* This is needed to make ov511_i2c_write() work */
@@ -334,14 +339,14 @@
 	for(i=reg1; i<=regn; i++) {
 	  rc = ov511_i2c_read(dev, i);
 #if 0
-	  PDEBUG("OV7610[0x%X] = 0x%X\n", i, rc);
+	  PDEBUG("OV7610[0x%X] = 0x%X", i, rc);
 #endif
 	}
 }
 
 static void ov511_dump_i2c_regs( struct usb_device *dev)
 {
-	PDEBUG("I2C REGS\n");
+	PDEBUG("I2C REGS");
 	ov511_dump_i2c_range(dev, 0x00, 0x38);
 }
 
@@ -351,27 +356,27 @@
 	int rc;
 	for(i=reg1; i<=regn; i++) {
 	  rc = ov511_reg_read(dev, i);
-	  PDEBUG("OV511[0x%X] = 0x%X\n", i, rc);
+	  PDEBUG("OV511[0x%X] = 0x%X", i, rc);
 	}
 }
 
 static void ov511_dump_regs( struct usb_device *dev)
 {
-	PDEBUG("CAMERA INTERFACE REGS\n");
+	PDEBUG("CAMERA INTERFACE REGS");
 	ov511_dump_reg_range(dev, 0x10, 0x1f);
-	PDEBUG("DRAM INTERFACE REGS\n");
+	PDEBUG("DRAM INTERFACE REGS");
 	ov511_dump_reg_range(dev, 0x20, 0x23);
-	PDEBUG("ISO FIFO REGS\n");
+	PDEBUG("ISO FIFO REGS");
 	ov511_dump_reg_range(dev, 0x30, 0x31);
-	PDEBUG("PIO REGS\n");
+	PDEBUG("PIO REGS");
 	ov511_dump_reg_range(dev, 0x38, 0x39);
 	ov511_dump_reg_range(dev, 0x3e, 0x3e);
-	PDEBUG("I2C REGS\n");
+	PDEBUG("I2C REGS");
 	ov511_dump_reg_range(dev, 0x40, 0x49);
-	PDEBUG("SYSTEM CONTROL REGS\n");
+	PDEBUG("SYSTEM CONTROL REGS");
 	ov511_dump_reg_range(dev, 0x50, 0x53);
 	ov511_dump_reg_range(dev, 0x5e, 0x5f);
-	PDEBUG("OmniCE REGS\n");
+	PDEBUG("OmniCE REGS");
 	ov511_dump_reg_range(dev, 0x70, 0x79);
 	ov511_dump_reg_range(dev, 0x80, 0x9f);
 	ov511_dump_reg_range(dev, 0xa0, 0xbf);
@@ -383,10 +388,10 @@
 {
 	int rc;
 
-	PDEBUG("Reset 7610\n");
+	PDEBUG("Reset 7610");
 	rc = ov511_i2c_write(dev, 0x12, 0x80);
 	if (rc < 0)
-		printk(KERN_ERR "ov511: i2c reset: command failed\n");
+		err("i2c reset: command failed");
 
 	return rc;
 }
@@ -395,24 +400,24 @@
 {
 	int rc;
 	
-	PDEBUG("Reset: type=0x%X\n", reset_type);
+	PDEBUG("Reset: type=0x%X", reset_type);
 	rc = ov511_reg_write(dev, OV511_REG_SYSTEM_RESET, reset_type);
 	if (rc < 0)
-		printk(KERN_ERR "ov511: reset: command failed\n");
+		err("reset: command failed");
 
 	rc = ov511_reg_write(dev, OV511_REG_SYSTEM_RESET, 0);
 	if (rc < 0)
-		printk(KERN_ERR "ov511: reset: command failed\n");
+		err("reset: command failed");
 
 	return rc;
 }
 
 int ov511_set_packet_size(struct usb_ov511 *ov511, int size)
 {
-	int alt, multiplier, err;
+	int alt, multiplier, rc;
 		
 #if 0
-	PDEBUG("set packet size: %d\n", size);
+	PDEBUG("set packet size: %d", size);
 #endif
 	
 	switch (size) {
@@ -449,21 +454,19 @@
 			multiplier = 1; // FIXME - is this correct?
 			break;
 		default:
-			printk(KERN_ERR "ov511_set_packet_size: invalid size (%d)\n",
-			       size);
+			err("Set packet size: invalid size (%d)", size);
 			return -EINVAL;
 	}
 
-	err = ov511_reg_write(ov511->dev, OV511_REG_FIFO_PACKET_SIZE,
-	                          multiplier);
-	if (err < 0) {
-		printk(KERN_ERR "ov511: Set packet size: Set FIFO size ret %d\n",
-		       err);
+	rc = ov511_reg_write(ov511->dev, OV511_REG_FIFO_PACKET_SIZE,
+	                     multiplier);
+	if (rc < 0) {
+		err("Set packet size: Set FIFO size ret %d", rc);
 		return -ENOMEM;
 	}
 	
 	if (usb_set_interface(ov511->dev, ov511->iface, alt) < 0) {
-		printk(KERN_ERR "ov511: Set packet size: set interface error\n");
+		err("Set packet size: set interface error");
 		return -EBUSY;
 	}
 
@@ -474,6 +477,43 @@
 	return 0;
 }
 
+static inline int ov7610_set_picture(struct usb_ov511 *ov511,
+                                     struct video_picture *p)
+{
+	if(ov511_i2c_write(ov511->dev, OV7610_REG_SAT, p->colour >> 8) < 0)
+		return -EIO;
+
+	if(ov511_i2c_write(ov511->dev, OV7610_REG_CNT, p->contrast >> 8) < 0)
+		return -EIO;
+
+	if(ov511_i2c_write(ov511->dev, OV7610_REG_BRT, p->brightness >> 8) < 0)
+		return -EIO;
+
+	return 0;
+}
+
+static inline int ov7610_get_picture(struct usb_ov511 *ov511,
+                                     struct video_picture *p)
+{
+	int ret;
+
+	if((ret = ov511_i2c_read(ov511->dev, OV7610_REG_SAT)) < 0) return -EIO;
+	p->colour = ret << 8;
+
+	if((ret = ov511_i2c_read(ov511->dev, OV7610_REG_CNT)) < 0) return -EIO;
+	p->contrast = ret << 8;
+
+	if((ret = ov511_i2c_read(ov511->dev, OV7610_REG_BRT)) < 0) return -EIO;
+	p->brightness = ret << 8;
+
+	p->hue = 0x8000;
+	p->whiteness = 105 << 8;
+	p->depth = 24;
+	p->palette = VIDEO_PALETTE_RGB24;
+
+	return 0;
+}
+
 static int ov511_mode_init_regs(struct usb_ov511 *ov511,
 				int width, int height, int mode)
 {
@@ -481,8 +521,7 @@
 	struct usb_device *dev = ov511->dev;
 
 #if 0
-	PDEBUG("ov511_mode_init_regs(ov511, %d, %d, %d)\n",
-	       width, height, mode);
+	PDEBUG("ov511_mode_init_regs(ov511, %d, %d, %d)", width, height, mode);
 #endif
 	ov511_set_packet_size(ov511, 0);
 
@@ -524,8 +563,7 @@
 		ov511_i2c_write(dev, 0x14, 0x24);
 		ov511_i2c_write(dev, 0x35, 0x1e);
 	} else {
-		PDEBUG("ov511: Unknown mode (%d, %d): %d\n",
-		       width, height, mode);
+		err("Unknown mode (%d, %d): %d", width, height, mode);
 		rc = -EINVAL;
 	}
 	ov511_set_packet_size(ov511, 993);
@@ -713,11 +751,8 @@
 
 		aPackNum[i] = n ? cdata[992] : -1;
 
-		if (st){ 
-			// Macro - must be in braces!
-			PDEBUG("data error: [%d] len=%d, status=%d\n",
-				i, n, st);
-		}
+		if (st)
+			PDEBUG("data error: [%d] len=%d, status=%d", i, n, st);
 
 		frame = &ov511->frame[ov511->curframe];
 		
@@ -727,14 +762,14 @@
 		    (cdata[8] & 8) && (cdata[8] & 0x80)) {
 
 #if 0
-		    PDEBUG("Found Frame End!, packnum = %d\n", (int)(cdata[992]));
-		    PDEBUG("Current frame = %d\n", ov511->curframe);
+		    PDEBUG("Found Frame End!, packnum = %d", (int)(cdata[992]));
+		    PDEBUG("Current frame = %d", ov511->curframe);
 #endif
 
 		    if (frame->scanstate == STATE_LINES) {
 		        if (waitqueue_active(&frame->wq)) {
 #if 0
-			  PDEBUG("About to wake up waiting processes\n");
+			  PDEBUG("About to wake up waiting processes");
 #endif
 			  frame->grabstate = FRAME_DONE;
 			  ov511->curframe = -1;
@@ -748,8 +783,8 @@
 			  cdata[4] | cdata[5] | cdata[6] | cdata[7]) == 0 &&
 			 (cdata[8] & 8)) {
 #if 0
-			PDEBUG("ov511: Found Frame Start!, packnum = %d\n", (int)(cdata[992]));
-			PDEBUG("ov511: Frame Header Byte = 0x%x\n", (int)(cdata[8]));
+			PDEBUG("ov511: Found Frame Start!, packnum = %d", (int)(cdata[992]));
+			PDEBUG("ov511: Frame Header Byte = 0x%x", (int)(cdata[8]));
 #endif
 		    frame->scanstate = STATE_LINES;
 			frame->segment = 0;
@@ -843,7 +878,7 @@
 	urb = usb_alloc_urb(FRAMES_PER_DESC);
 	
 	if (!urb) {
-		printk(KERN_ERR "ov511_init_isoc: usb_alloc_urb ret. NULL\n");
+		err("ov511_init_isoc: usb_alloc_urb ret. NULL");
 		return -ENOMEM;
 	}
 	ov511->sbuf[0].urb = urb;
@@ -862,7 +897,7 @@
 
 	urb = usb_alloc_urb(FRAMES_PER_DESC);
 	if (!urb) {
-		printk(KERN_ERR "ov511_init_isoc: usb_alloc_urb ret. NULL\n");
+		err("ov511_init_isoc: usb_alloc_urb ret. NULL");
 		return -ENOMEM;
 	}
 	ov511->sbuf[1].urb = urb;
@@ -884,12 +919,10 @@
 
 	err = usb_submit_urb(ov511->sbuf[0].urb);
 	if (err)
-		printk(KERN_ERR "ov511_init_isoc: usb_run_isoc(0) ret %d\n",
-			err);
+		err("ov511_init_isoc: usb_run_isoc(0) ret %d", err);
 	err = usb_submit_urb(ov511->sbuf[1].urb);
 	if (err)
-		printk(KERN_ERR "ov511_init_isoc: usb_run_isoc(1) ret %d\n",
-			err);
+		err("ov511_init_isoc: usb_run_isoc(1) ret %d\n", err);
 
 	ov511->streaming = 1;
 
@@ -961,7 +994,7 @@
 	int err = -EBUSY;
 	struct usb_ov511 *ov511 = (struct usb_ov511 *)dev;
 
-	PDEBUG("ov511_open\n");
+	PDEBUG("ov511_open");
 	
 	down(&ov511->lock);
 	if (ov511->user)
@@ -980,8 +1013,8 @@
 	ov511->frame[0].data = ov511->fbuf;
 	ov511->frame[1].data = ov511->fbuf + MAX_FRAME_SIZE;
 
-	PDEBUG("frame [0] @ %p\n", ov511->frame[0].data);
-	PDEBUG("frame [1] @ %p\n", ov511->frame[1].data);
+	PDEBUG("frame [0] @ %p", ov511->frame[0].data);
+	PDEBUG("frame [1] @ %p", ov511->frame[1].data);
 
 	ov511->sbuf[0].data = kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);
 	if (!ov511->sbuf[0].data)
@@ -990,8 +1023,8 @@
 	if (!ov511->sbuf[1].data)
 		goto open_err_on1;
 		
-	PDEBUG("sbuf[0] @ %p\n", ov511->sbuf[0].data);
-	PDEBUG("sbuf[1] @ %p\n", ov511->sbuf[1].data);
+	PDEBUG("sbuf[0] @ %p", ov511->sbuf[0].data);
+	PDEBUG("sbuf[1] @ %p", ov511->sbuf[1].data);
 
 	err = ov511_init_isoc(ov511);
 	if (err)
@@ -1022,7 +1055,7 @@
 {
 	struct usb_ov511 *ov511 = (struct usb_ov511 *)dev;
 
-	PDEBUG("ov511_close\n");
+	PDEBUG("ov511_close");
 	
 	down(&ov511->lock);	
 	ov511->user--;
@@ -1050,11 +1083,11 @@
 }
 
 // FIXME - Needs much work!!!
-static int ov511_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+static int ov511_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
 {
-	struct usb_ov511 *ov511 = (struct usb_ov511 *)dev;
+	struct usb_ov511 *ov511 = (struct usb_ov511 *)vdev;
 #if 0	
-	PDEBUG("IOCtl: 0x%X\n", cmd);
+	PDEBUG("IOCtl: 0x%X", cmd);
 #endif	
 	switch (cmd) {
 		case VIDIOCGCAP:
@@ -1111,14 +1144,9 @@
 		{
 			struct video_picture p;
 
-			p.colour = 0x8000;
-			p.hue = 0x8000;
-			p.brightness = 180 << 8;	/* XXX */
-			p.contrast = 192 << 8;		/* XXX */
-			p.whiteness = 105 << 8;		/* XXX */
-			p.depth = 24;
-			p.palette = VIDEO_PALETTE_RGB24;
-
+			if (ov7610_get_picture(ov511, &p))
+				return -EIO;
+							
 			if (copy_to_user(arg, &p, sizeof(p)))
 				return -EFAULT;
 
@@ -1130,6 +1158,9 @@
 
 			if (copy_from_user(&p, arg, sizeof(p)))
 				return -EFAULT;
+			
+			if (ov7610_set_picture(ov511, &p))
+				return -EIO;
 
 			return 0;
 		}
@@ -1191,8 +1222,8 @@
 				return -EFAULT;
 
 #if 0
-			PDEBUG("MCAPTURE\n");
-			PDEBUG("frame: %d, size: %dx%d, format: %d\n",
+			PDEBUG("MCAPTURE");
+			PDEBUG("frame: %d, size: %dx%d, format: %d",
 				vm.frame, vm.width, vm.height, vm.format);
 #endif
 
@@ -1212,7 +1243,7 @@
 				ov511_mode_init_regs(ov511,
 						     vm.width, vm.height, 0);
 #if 0
-				PDEBUG("ov511: Setting frame %d to (%d, %d) : %d\n",
+				PDEBUG("ov511: Setting frame %d to (%d, %d) : %d",
 				       vm.frame, vm.width, vm.height, 0);
 #endif
 			}
@@ -1233,7 +1264,7 @@
 				return -EFAULT;
 
 #if 0
-			PDEBUG("syncing to frame %d\n", frame);
+			PDEBUG("syncing to frame %d", frame);
 #endif
 			switch (ov511->frame[frame].grabstate) {
 				case FRAME_UNUSED:
@@ -1306,7 +1337,7 @@
 	int frmx = -1;
 	volatile struct ov511_frame *frame;
 
-	PDEBUG("ov511_read: %ld bytes, noblock=%d\n", count, noblock);
+	PDEBUG("ov511_read: %ld bytes, noblock=%d", count, noblock);
 
 	if (!dev || !buf)
 		return -EFAULT;
@@ -1344,13 +1375,13 @@
 
 	if (frame->grabstate == FRAME_ERROR) {
 		frame->bytes_read = 0;
-		printk(KERN_ERR "ov511_read: errored frame %d\n", ov511->curframe);
+		err("ov511_read: errored frame %d", ov511->curframe);
 		if (ov511_new_frame(ov511, frmx))
-			printk(KERN_ERR "ov511_read: ov511_new_frame error\n");
+			err("ov511_read: ov511_new_frame error");
 		goto restart;
 	}
 
-	PDEBUG("ov511_read: frmx=%d, bytes_read=%ld, scanlength=%ld\n", frmx,
+	PDEBUG("ov511_read: frmx=%d, bytes_read=%ld, scanlength=%ld", frmx,
 		frame->bytes_read, frame->scanlength);
 
 	/* copy bytes to user space; we allow for partials reads */
@@ -1361,7 +1392,7 @@
 		return -EFAULT;
 
 	frame->bytes_read += count;
-	PDEBUG("ov511_read: {copy} count used=%ld, new bytes_read=%ld\n",
+	PDEBUG("ov511_read: {copy} count used=%ld, new bytes_read=%ld",
 		count, frame->bytes_read);
 
 	if (frame->bytes_read >= frame->scanlength) { /* All data has been read */
@@ -1370,7 +1401,7 @@
 		/* Mark it as available to be used again. */
 		ov511->frame[frmx].grabstate = FRAME_UNUSED;
 		if (ov511_new_frame(ov511, frmx ? 0 : 1))
-			printk(KERN_ERR "ov511_read: ov511_new_frame returned error\n");
+			err("ov511_read: ov511_new_frame returned error");
 	}
 
 	return count;
@@ -1382,7 +1413,7 @@
 	unsigned long start = (unsigned long)adr;
 	unsigned long page, pos;
 
-	PDEBUG("mmap: %ld (%lX) bytes\n", size, size);
+	PDEBUG("mmap: %ld (%lX) bytes", size, size);
 
 	if (size > (((2 * MAX_FRAME_SIZE) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
 		return -EINVAL;
@@ -1450,12 +1481,11 @@
 		return -1;
 	
 
-	if((ov511_i2c_read(dev, 0x1C) != 0x7F) ||
-	   (ov511_i2c_read(dev, 0x1D) != 0xA2)) {
-		printk(KERN_ERR "ov511: Failed to read OV7610 ID. You might\n");
-		printk(KERN_ERR "ov511: not have an OV7610, or it may be\n");
-		printk(KERN_ERR "ov511: not responding. Report this to\n");
-		printk(KERN_ERR "ov511: mmcclelland@delphi.com\n");
+	if((ov511_i2c_read(dev, OV7610_REG_ID_HIGH) != 0x7F) ||
+	   (ov511_i2c_read(dev, OV7610_REG_ID_LOW) != 0xA2)) {
+		err("Failed to read OV7610 ID. You might not have an OV7610,");
+		err("or it may be not responding. Report this to");
+		err("mmcclelland@delphi.com");
 		return -1;
 	}
 
@@ -1468,7 +1498,7 @@
 
 	/* Set altsetting 0 */
 	if (usb_set_interface(dev, ov511->iface, 0) < 0) {
-		printk(KERN_ERR "ov511: usb_set_interface error\n");
+		err("usb_set_interface error");
 		return -EBUSY;
 	}
 
@@ -1478,7 +1508,7 @@
 	init_waitqueue_head(&ov511->frame[1].wq);
 
 	if (video_register_device(&ov511->vdev, VFL_TYPE_GRABBER) == -1) {
-		printk(KERN_ERR "ov511: video_register_device failed\n");
+		err("video_register_device failed");
 		return -EBUSY;
 	}
 
@@ -1488,7 +1518,7 @@
 
 	/* Initialize system */
 	if (ov511_reg_write(dev, OV511_REG_SYSTEM_INIT, 0x01) < 0) {
-		printk(KERN_ERR "ov511: enable system: command failed\n");
+		err("enable system: command failed");
 		goto error;
 	}
 
@@ -1497,13 +1527,13 @@
 		goto error;
 
 	if(ov7610_configure(dev) < 0) {
-		printk(KERN_ERR "ov511: failed to configure OV7610\n");
+		err("failed to configure OV7610");
  		goto error;	
 	}
 
 	/* Disable compression */
 	if (ov511_reg_write(dev, OV511_OMNICE_ENABLE, 0x00) < 0) {
-		printk(KERN_ERR "ov511: disable compression: command failed\n");
+		err("disable compression: command failed");
 		goto error;
 	}
 
@@ -1539,7 +1569,7 @@
 	struct usb_ov511 *ov511;
 	int rc;
 
-	PDEBUG("probing for device...\n");
+	PDEBUG("probing for device...");
 
 	/* We don't handle multi-config cameras */
 	if (dev->descriptor.bNumConfigurations != 1)
@@ -1563,7 +1593,7 @@
 	printk(KERN_INFO "ov511: USB OV511-based camera found\n");
 
 	if ((ov511 = kmalloc(sizeof(*ov511), GFP_KERNEL)) == NULL) {
-		printk(KERN_ERR "ov511: couldn't kmalloc ov511 struct\n");
+		err("couldn't kmalloc ov511 struct");
 		return NULL;
 	}
 
@@ -1574,7 +1604,7 @@
 
 	rc = ov511_reg_read(dev, OV511_REG_SYSTEM_CUSTOM_ID);
 	if (rc < 0) {
-		printk("ov511: Unable to read camera bridge registers\n");
+		err("Unable to read camera bridge registers");
 		return NULL;
 	}
 	
@@ -1595,9 +1625,9 @@
 		printk("ov511: Camera is a AverMedia InterCam Elite\n");
 		break;
 	default:
-		printk("ov511: Specific camera type (%d) not recognized\n", rc);
-		printk("ov511: Please contact mmcclelland@delphi.com to request\n");
-		printk("ov511: support for your camera.\n");
+		err("Specific camera type (%d) not recognized", rc);
+		err("Please contact mmcclelland@delphi.com to request");
+		err("support for your camera.");
 		return NULL;
 	}
 
@@ -1607,7 +1637,7 @@
 		return ov511;
 	}
 	else {
-		printk(KERN_ERR "ov511: Failed to configure camera\n");
+		err("Failed to configure camera");
 		return NULL;
 	}
     	
@@ -1637,7 +1667,7 @@
 
 int usb_ov511_init(void)
 {
-	PDEBUG("usb_ov511_init()\n");
+	PDEBUG("usb_ov511_init()");
 	
 	EXPORT_NO_SYMBOLS;
 	
@@ -1659,7 +1689,7 @@
 {
 	usb_ov511_cleanup();
 	
-	PDEBUG("Module unloaded\n");
+	PDEBUG("Module unloaded");
 }
 #endif
 
diff -Naur linux-2.3.40-pre4-orig/drivers/usb/ov511.h linux/drivers/usb/ov511.h
--- linux-2.3.40-pre4-orig/drivers/usb/ov511.h	Sat Jan 15 01:16:23 2000
+++ linux/drivers/usb/ov511.h	Mon Jan 17 05:16:31 2000
@@ -6,9 +6,9 @@
 #define OV511_DEBUG	/* Turn on debug messages */
 
 #ifdef OV511_DEBUG
-#  define PDEBUG(fmt, args...) printk("ov511: " fmt, ## args)
+#  define PDEBUG(fmt, args...) printk("ov511: " fmt "\n" , ## args)
 #else
-#  define PDEBUG(fmt, args...) /* Nothing */
+#  define PDEBUG(fmt, args...) do {} while(0)
 #endif
 
 /* Camera interface register numbers */
@@ -102,6 +102,50 @@
 #define OV511_ALTERNATE_SIZE_513	5
 #define OV511_ALTERNATE_SIZE_257	6
 #define OV511_ALTERNATE_SIZE_0		7
+
+/* ov7610 registers */
+#define OV7610_REG_GAIN          0x00
+#define OV7610_REG_BLUE          0x01
+#define OV7610_REG_RED           0x02
+#define OV7610_REG_SAT           0x03
+#define OV7610_REG_CNT           0x05
+#define OV7610_REG_BRT           0x06
+#define OV7610_REG_BLUE_BIAS     0x0C
+#define OV7610_REG_RED_BIAS      0x0D
+#define OV7610_REG_GAMMA_COEFF   0x0E
+#define OV7610_REG_WB_RANGE      0x0F
+#define OV7610_REG_EXP           0x10
+#define OV7610_REG_CLOCK         0x11
+#define OV7610_REG_COM_A         0x12
+#define OV7610_REG_COM_B         0x13
+#define OV7610_REG_COM_C         0x14
+#define OV7610_REG_COM_D         0x15
+#define OV7610_REG_FIELD_DIVIDE  0x16
+#define OV7610_REG_HWIN_START    0x17
+#define OV7610_REG_HWIN_END      0x18
+#define OV7610_REG_VWIN_START    0x19
+#define OV7610_REG_VWIN_END      0x1A
+#define OV7610_REG_PIXEL_SHIFT   0x1B
+#define OV7610_REG_ID_HIGH       0x1C
+#define OV7610_REG_ID_LOW        0x1D
+#define OV7610_REG_COM_E         0x20
+#define OV7610_REG_YOFFSET       0x21
+#define OV7610_REG_UOFFSET       0x22
+#define OV7610_REG_ECW           0x24
+#define OV7610_REG_ECB           0x25
+#define OV7610_REG_COM_F         0x26
+#define OV7610_REG_COM_G         0x27
+#define OV7610_REG_COM_H         0x28
+#define OV7610_REG_COM_I         0x29
+#define OV7610_REG_FRAMERATE_H   0x2A
+#define OV7610_REG_FRAMERATE_L   0x2B
+#define OV7610_REG_ALC           0x2C
+#define OV7610_REG_COM_J         0x2D
+#define OV7610_REG_VOFFSET       0x2E
+#define OV7610_REG_YGAMMA        0x33
+#define OV7610_REG_BIAS_ADJUST   0x34
+#define OV7610_REG_COM_L         0x35
+#define OV7610_REG_COM_K         0x38
 
 
 #define STREAM_BUF_SIZE	(PAGE_SIZE * 4)
