This is a backport of the ov511 driver from 2.5 to 2.4.21-pre2. This version has been in use for months and is known to be stable.

Please apply. Thanks!

--
Mark McClelland
[EMAIL PROTECTED]

===================================================================

 Documentation/usb/ov511.txt |   10 +
 drivers/usb/ov511.c         |  384 ++++++++++++++++++++++++++------------------
 drivers/usb/ov511.h         |   22 --
 3 files changed, 242 insertions, 174 deletions


# This is a BitKeeper generated patch for the following project:
# Project Name: greg k-h's linux 2.4 USB kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#                  ChangeSet    1.853   -> 1.854  
#        drivers/usb/ov511.h    1.8     -> 1.9    
#       Documentation/usb/ov511.txt     1.5     -> 1.6    
#        drivers/usb/ov511.c    1.22    -> 1.23   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/12/20      [EMAIL PROTECTED] 1.854
# Update ov511 to version 1.63. This is a backport of the 2.5 driver,
# which has been in use for months and is known to be stable.
# 
# Notable changes:
# * Make use of usb_make_path()
# * Fix an oops when snapshot mode is enabled
# * Get rid of automagic resubmit
# * OV518 is closer to working
# * Clean up OV6x30 register settings
# * Remove some dead code
# --------------------------------------------
#
diff -Nru a/Documentation/usb/ov511.txt b/Documentation/usb/ov511.txt
--- a/Documentation/usb/ov511.txt       Fri Dec 20 15:53:54 2002
+++ b/Documentation/usb/ov511.txt       Fri Dec 20 15:53:54 2002
@@ -276,6 +276,15 @@
        might be necessary if your camera has a custom lens assembly. This has
        no effect with video capture devices.
 
+  NAME: ov518_color
+  TYPE: integer (Boolean)
+  DEFAULT: 0 (off)
+  DESC: Enable OV518 color support. This is off by default since it doesn't
+       work most of the time. If you want to try it, you must also load
+       ov518_decomp with the "nouv=0" parameter. If you get improper colors or
+       diagonal lines through the image, restart your video app and try again.
+       Repeat as necessary.
+
 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
@@ -285,6 +294,7 @@
  o /proc status reporting
  o SAA7111A video capture support at 320x240 and 640x480
  o Compression support
+ o SMP compatibility
 
 HOW TO CONTACT ME:
 
diff -Nru a/drivers/usb/ov511.c b/drivers/usb/ov511.c
--- a/drivers/usb/ov511.c       Fri Dec 20 15:53:54 2002
+++ b/drivers/usb/ov511.c       Fri Dec 20 15:53:54 2002
@@ -11,6 +11,7 @@
  * Original SAA7111A code by Dave Perks <[EMAIL PROTECTED]>
  * URB error messages from pwc driver by Nemosoft
  * generic_ioctl() code from videodev.c by Gerd Knorr and Alan Cox
+ * Memory management (rvmalloc) code from bttv driver, by Gerd Knorr and others
  *
  * Based on the Linux CPiA driver written by Peter Pregler,
  * Scott J. Bertin and Johannes Erdfelt.
@@ -48,6 +49,7 @@
 #include <asm/semaphore.h>
 #include <asm/processor.h>
 #include <linux/wrapper.h>
+#include <linux/mm.h>
 
 #if defined (__i386__)
        #include <asm/cpufeature.h>
@@ -58,9 +60,9 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.61 for Linux 2.4"
+#define DRIVER_VERSION "v1.63 for Linux 2.4"
 #define EMAIL "[EMAIL PROTECTED]"
-#define DRIVER_AUTHOR "Mark McClelland <[EMAIL PROTECTED]> & Bret Wallach \
+#define DRIVER_AUTHOR "Mark McClelland <[EMAIL PROTECTED]> & Bret Wallach \
        & Orion Sky Lawlor <[EMAIL PROTECTED]> & Kevin Moore & Charl P. Botha \
        <[EMAIL PROTECTED]> & Claudio Matsuoka <[EMAIL PROTECTED]>"
 #define DRIVER_DESC "ov511 USB Camera Driver"
@@ -97,7 +99,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;
@@ -122,6 +123,7 @@
 static int unit_video[OV511_MAX_UNIT_VIDEO];
 static int remove_zeros;
 static int mirror;
+static int ov518_color;
 
 MODULE_PARM(autobright, "i");
 MODULE_PARM_DESC(autobright, "Sensor automatically changes brightness");
@@ -199,6 +201,8 @@
   "Remove zero-padding from uncompressed incoming data");
 MODULE_PARM(mirror, "i");
 MODULE_PARM_DESC(mirror, "Reverse image horizontally");
+MODULE_PARM(ov518_color, "i");
+MODULE_PARM_DESC(ov518_color, "Enable OV518 color (experimental)");
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
@@ -222,7 +226,7 @@
 /* MMX support is present in kernel and CPU. Checked upon decomp module load. */
 static int ov51x_mmx_available;
 
-static __devinitdata struct usb_device_id device_table [] = {
+static struct usb_device_id device_table [] = {
        { USB_DEVICE(VEND_OMNIVISION, PROD_OV511) },
        { USB_DEVICE(VEND_OMNIVISION, PROD_OV511PLUS) },
        { USB_DEVICE(VEND_OMNIVISION, PROD_OV518) },
@@ -261,7 +265,9 @@
        { 100, "Lifeview RoboCam" },
        { 102, "AverMedia InterCam Elite" },
        { 112, "MediaForte MV300" },    /* or OV7110 evaluation kit */
+       { 134, "Ezonics EZCam II" },
        { 192, "Webeye 2000B" },
+       { 253, "Alpha Vision Tech. AlphaCam SE" },
        {  -1, NULL }
 };
 
@@ -294,6 +300,7 @@
        { -1, NULL }
 };
 
+#if defined(CONFIG_VIDEO_PROC_FS)
 static struct symbolic_list senlist[] = {
        { SEN_OV76BE,   "OV76BE" },
        { SEN_OV7610,   "OV7610" },
@@ -309,6 +316,7 @@
        { SEN_SAA7111A, "SAA7111A" },
        { -1, NULL }
 };
+#endif
 
 /* URB error codes: */
 static struct symbolic_list urb_errlist[] = {
@@ -403,7 +411,7 @@
 extern struct proc_dir_entry *video_proc_entry;
 
 static struct file_operations ov511_control_fops = {
-       ioctl:          ov51x_control_ioctl,
+       .ioctl =        ov51x_control_ioctl,
 };
 
 #define YES_NO(x) ((x) ? "yes" : "no")
@@ -463,6 +471,8 @@
                       symbolic(senlist, ov->sensor));
        out += sprintf(out, "packet_size     : %d\n", ov->packet_size);
        out += sprintf(out, "framebuffer     : 0x%p\n", ov->fbuf);
+       out += sprintf(out, "packet_numbering: %d\n", ov->packet_numbering);
+       out += sprintf(out, "topology        : %s\n", ov->usb_path);
 
        len = out - page;
        len -= off;
@@ -554,8 +564,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);
@@ -1133,8 +1143,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,
@@ -1190,8 +1198,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)
@@ -1237,8 +1243,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);
@@ -1256,8 +1261,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);
@@ -1265,7 +1269,6 @@
        }
 }
 
-/* FIXME: Should there be an OV518 version of this? */
 static void
 ov511_dump_regs(struct usb_ov511 *ov)
 {
@@ -1291,6 +1294,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
 
 /*****************************************************************************/
@@ -1332,9 +1360,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 {
@@ -1379,7 +1407,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) &&
@@ -2014,10 +2042,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;
 }
 
@@ -2425,9 +2449,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?0xa0:0x80);
                break;
        default:
                err("Invalid sensor");
@@ -2441,13 +2466,33 @@
                        /* these aren't valid on the OV6620/OV7620/6630? */
                        i2c_w_mask(ov, 0x0e, 0x40, 0x40);
                }
-               i2c_w_mask(ov, 0x13, 0x20, 0x20);
+
+               if (ov->sensor == SEN_OV6630 && ov->bridge == BRG_OV518
+                   && ov518_color) {
+                       i2c_w_mask(ov, 0x12, 0x00, 0x10);
+                       i2c_w_mask(ov, 0x13, 0x00, 0x20);
+               } else {
+                       i2c_w_mask(ov, 0x13, 0x20, 0x20);
+               }
        } else {
                if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) {
                        /* not valid on the OV6620/OV7620/6630? */
                        i2c_w_mask(ov, 0x0e, 0x00, 0x40);
                }
-               i2c_w_mask(ov, 0x13, 0x00, 0x20);
+
+               /* The OV518 needs special treatment. Although both the OV518
+                * and the OV6630 support a 16-bit video bus, only the 8 bit Y
+                * bus is actually used. The UV bus is tied to ground.
+                * Therefore, the OV6630 needs to be in 8-bit multiplexed
+                * output mode */
+
+               if (ov->sensor == SEN_OV6630 && ov->bridge == BRG_OV518
+                   && ov518_color) {
+                       i2c_w_mask(ov, 0x12, 0x10, 0x10);
+                       i2c_w_mask(ov, 0x13, 0x20, 0x20);
+               } else {
+                       i2c_w_mask(ov, 0x13, 0x00, 0x20);
+               }
        }
 
        /******** Clock programming ********/
@@ -2505,19 +2550,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.
@@ -2706,7 +2743,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 */
@@ -2782,8 +2819,29 @@
        reg_w(ov, 0x3d, 0);
        reg_w(ov, 0x3e, 0);
 
-       reg_w(ov, 0x28, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80);
-       reg_w(ov, 0x38, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80);
+       if (ov->bridge == BRG_OV518 && ov518_color) {
+               /* OV518 needs U and V swapped */
+               i2c_w_mask(ov, 0x15, 0x00, 0x01);
+
+               if (mode == VIDEO_PALETTE_GREY) {
+                       /* Set 16-bit input format (UV data are ignored) */
+                       reg_w_mask(ov, 0x20, 0x00, 0x08);
+
+                       /* Set 8-bit (4:0:0) output format */
+                       reg_w_mask(ov, 0x28, 0x00, 0xf0);
+                       reg_w_mask(ov, 0x38, 0x00, 0xf0);
+               } else {
+                       /* Set 8-bit (YVYU) input format */
+                       reg_w_mask(ov, 0x20, 0x08, 0x08);
+
+                       /* Set 12-bit (4:2:0) output format */
+                       reg_w_mask(ov, 0x28, 0x80, 0xf0);
+                       reg_w_mask(ov, 0x38, 0x80, 0xf0);
+               }
+       } else {
+               reg_w(ov, 0x28, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80);
+               reg_w(ov, 0x38, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80);
+       }
 
        hsegs = width / 16;
        vsegs = height / 4;
@@ -3176,7 +3234,7 @@
 }
 
 /*
- * For RAW BW (YUV400) images, data shows up in 256 byte segments.
+ * For RAW BW (YUV 4:0:0) images, data show up in 256 byte segments.
  * The segments represent 4 squares of 8x8 pixels as follows:
  *
  *      0  1 ...  7    64  65 ...  71   ...  192 193 ... 199
@@ -3207,7 +3265,7 @@
 }
 
 /*
- * For YUV4:2:0 images, the data shows up in 384 byte segments.
+ * For YUV 4:2:0 images, the data show up in 384 byte segments.
  * The first 64 bytes of each segment are U, the next 64 are V.  The U and
  * V are arranged as follows:
  *
@@ -3226,8 +3284,8 @@
  *           ...              ...                    ...
  *     56 57 ... 63   120 121 ... 127   ...  248 249 ... 255
  *
- * Note that the U and V data in one segment represents a 16 x 16 pixel
- * area, but the Y data represents a 32 x 8 pixel area. If the width is not an
+ * Note that the U and V data in one segment represent a 16 x 16 pixel
+ * area, but the Y data represent a 32 x 8 pixel area. If the width is not an
  * even multiple of 32, the extra 8x8 blocks within a 32x8 block belong to the
  * next horizontal stripe.
  *
@@ -3235,7 +3293,7 @@
  * verbatim, in order, into the frame. When used with vidcat -f ppm -s 640x480
  * this puts the data on the standard output and can be analyzed with the
  * parseppm.c utility I wrote.  That's a much faster way for figuring out how
- * this data is scrambled.
+ * these data are scrambled.
  */
 
 /* Converts from raw, uncompressed segments at pIn0 to a YUV420P frame at pOut0.
@@ -4144,7 +4202,10 @@
                }
        }
 
+       /* Resubmit this URB */
        urb->dev = ov->dev;
+       if ((i = usb_submit_urb(urb)) != 0)
+               err("usb_submit_urb() ret %d", i);
 
        return;
 }
@@ -4216,6 +4277,7 @@
 
        for (n = 0; n < OV511_NUMSBUF; n++) {
                urb = usb_alloc_urb(FRAMES_PER_DESC);
+
                if (!urb) {
                        err("init isoc: usb_alloc_urb ret. NULL");
                        return -ENOMEM;
@@ -4229,6 +4291,7 @@
                urb->complete = ov51x_isoc_irq;
                urb->number_of_packets = FRAMES_PER_DESC;
                urb->transfer_buffer_length = ov->packet_size * FRAMES_PER_DESC;
+               urb->interval = 1;
                for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
                        urb->iso_frame_desc[fx].offset = ov->packet_size * fx;
                        urb->iso_frame_desc[fx].length = ov->packet_size;
@@ -4237,10 +4300,6 @@
 
        ov->streaming = 1;
 
-       ov->sbuf[OV511_NUMSBUF - 1].urb->next = ov->sbuf[0].urb;
-       for (n = 0; n < OV511_NUMSBUF - 1; n++)
-               ov->sbuf[n].urb->next = ov->sbuf[n+1].urb;
-
        for (n = 0; n < OV511_NUMSBUF; n++) {
                ov->sbuf[n].urb->dev = ov->dev;
                err = usb_submit_urb(ov->sbuf[n].urb);
@@ -4398,11 +4457,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;
 
@@ -4666,6 +4720,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:
@@ -4830,8 +4888,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;
                }
 
@@ -4852,8 +4910,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;
                }
 
@@ -4982,6 +5040,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;
@@ -5188,7 +5264,7 @@
        PDEBUG(4, "{copy} count used=%ld, new bytes_read=%ld",
                count, frame->bytes_read);
 
-       /* If all data has been read... */
+       /* If all data have been read... */
        if (frame->bytes_read
            >= get_frame_length(frame)) {
                frame->bytes_read = 0;
@@ -5450,8 +5526,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:
        {
@@ -5657,19 +5732,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");
-                       info("PLEASE REPORT THE EXISTENCE OF THIS SENSOR TO");
-                       info("THE DRIVER AUTHOR");
-               } 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;
@@ -5754,86 +5826,61 @@
                { OV511_I2C_BUS, 0x4f, 0x04 },
 // Do 50-53 have any effect?
 // Toggle 0x12[2] off and on here?
-               { OV511_DONE_BUS, 0x0, 0x00 },
+               { OV511_DONE_BUS, 0x0, 0x00 },  /* END MARKER */
        };
 
-       /* This chip is undocumented so many of these are guesses. OK=verified,
-        * A=Added since 6620, U=unknown function (not a 6620 reg) */
        static struct ov511_regvals aRegvalsNorm6x30[] = {
-       /*OK*/  { OV511_I2C_BUS, 0x12, 0x80 }, /* reset */
-       /*00?*/ { OV511_I2C_BUS, 0x11, 0x01 },
-       /*OK*/  { OV511_I2C_BUS, 0x03, 0x60 },
-       /*0A?*/ { OV511_I2C_BUS, 0x05, 0x7f }, /* For when autoadjust is off */
+               { OV511_I2C_BUS, 0x12, 0x80 }, /* reset */
+               { OV511_I2C_BUS, 0x11, 0x00 },
+               { OV511_I2C_BUS, 0x03, 0x60 },
+               { OV511_I2C_BUS, 0x05, 0x7f }, /* For when autoadjust is off */
                { OV511_I2C_BUS, 0x07, 0xa8 },
                /* The ratio of 0x0c and 0x0d  controls the white point */
-       /*OK*/  { OV511_I2C_BUS, 0x0c, 0x24 },
-       /*OK*/  { OV511_I2C_BUS, 0x0d, 0x24 },
-       /*A*/   { OV511_I2C_BUS, 0x0e, 0x20 },
-
-//     /*24?*/ { OV511_I2C_BUS, 0x12, 0x28 }, /* Enable AGC */
-//             { OV511_I2C_BUS, 0x12, 0x24 }, /* Enable AGC */
-
-//     /*A*/   { OV511_I2C_BUS, 0x13, 0x21 },
-//     /*A*/   { OV511_I2C_BUS, 0x13, 0x25 }, /* Tristate Y and UV busses */
-
-//     /*04?*/ { OV511_I2C_BUS, 0x14, 0x80 },
-               /* 0x16: 0x06 helps frame stability with moving objects */
-       /*03?*/ { OV511_I2C_BUS, 0x16, 0x06 },
-//     /*OK*/  { OV511_I2C_BUS, 0x20, 0x30 }, /* Aperture correction enable */
+               { OV511_I2C_BUS, 0x0c, 0x24 },
+               { OV511_I2C_BUS, 0x0d, 0x24 },
+               { OV511_I2C_BUS, 0x0e, 0x20 },
+//             { OV511_I2C_BUS, 0x14, 0x80 },
+               { OV511_I2C_BUS, 0x16, 0x03 },
+//             { OV511_I2C_BUS, 0x20, 0x30 }, /* Aperture correction enable */
                // 21 & 22? The suggested values look wrong. Go with default
-       /*A*/   { OV511_I2C_BUS, 0x23, 0xc0 },
-       /*A*/   { OV511_I2C_BUS, 0x25, 0x9a }, // Check this against default
-//     /*OK*/  { OV511_I2C_BUS, 0x26, 0xb2 }, /* BLC enable */
+               { OV511_I2C_BUS, 0x23, 0xc0 },
+               { OV511_I2C_BUS, 0x25, 0x9a }, // Check this against default
+//             { OV511_I2C_BUS, 0x26, 0xb2 }, /* BLC enable */
 
                /* 0x28: 0x05 Selects RGB format if RGB on */
-//     /*04?*/ { OV511_I2C_BUS, 0x28, 0x05 },
-//     /*04?*/ { OV511_I2C_BUS, 0x28, 0x45 }, // DEBUG: Tristate UV bus
+//             { OV511_I2C_BUS, 0x28, 0x05 },
+//             { OV511_I2C_BUS, 0x28, 0x45 }, // DEBUG: Tristate UV bus
 
-       /*OK*/  { OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */
-//     /*OK*/  { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */
-//     /*U*/   { OV511_I2C_BUS, 0x2c, 0xa0 },
+               { OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */
+//             { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */
                { OV511_I2C_BUS, 0x2d, 0x99 },
-//     /*A*/   { OV511_I2C_BUS, 0x33, 0x26 }, // Reserved bits on 6620
-//     /*d2?*/ { OV511_I2C_BUS, 0x34, 0x03 }, /* Max A/D range */
-//     /*U*/   { OV511_I2C_BUS, 0x36, 0x8f }, // May not be necessary
-//     /*U*/   { OV511_I2C_BUS, 0x37, 0x80 }, // May not be necessary
-//     /*8b?*/ { OV511_I2C_BUS, 0x38, 0x83 },
-//     /*40?*/ { OV511_I2C_BUS, 0x39, 0xc0 }, // 6630 adds bit 7
+//             { OV511_I2C_BUS, 0x33, 0x26 }, // Reserved bits on 6620
+//             { OV511_I2C_BUS, 0x34, 0x03 }, /* Max A/D range */
+//             { OV511_I2C_BUS, 0x38, 0x83 },
+//             { OV511_I2C_BUS, 0x39, 0xc0 }, // 6630 adds bit 7
 //             { OV511_I2C_BUS, 0x3c, 0x39 }, /* Enable AEC mode changing */
 //             { OV511_I2C_BUS, 0x3c, 0x3c }, /* Change AEC mode */
 //             { OV511_I2C_BUS, 0x3c, 0x24 }, /* Disable AEC mode changing */
-       /*OK*/  { OV511_I2C_BUS, 0x3d, 0x80 },
-//     /*A*/   { OV511_I2C_BUS, 0x3f, 0x0e },
-//     /*U*/   { OV511_I2C_BUS, 0x40, 0x00 },
-//     /*U*/   { OV511_I2C_BUS, 0x41, 0x00 },
-//     /*U*/   { OV511_I2C_BUS, 0x42, 0x80 },
-//     /*U*/   { OV511_I2C_BUS, 0x43, 0x3f },
-//     /*U*/   { OV511_I2C_BUS, 0x44, 0x80 },
-//     /*U*/   { OV511_I2C_BUS, 0x45, 0x20 },
-//     /*U*/   { OV511_I2C_BUS, 0x46, 0x20 },
-//     /*U*/   { OV511_I2C_BUS, 0x47, 0x80 },
-//     /*U*/   { OV511_I2C_BUS, 0x48, 0x7f },
-//     /*U*/   { OV511_I2C_BUS, 0x49, 0x00 },
+               { OV511_I2C_BUS, 0x3d, 0x80 },
+//             { OV511_I2C_BUS, 0x3f, 0x0e },
 
                /* These next two registers (0x4a, 0x4b) are undocumented. They
                 * control the color balance */
-//     /*OK?*/ { OV511_I2C_BUS, 0x4a, 0x80 }, // Check these
-//     /*OK?*/ { OV511_I2C_BUS, 0x4b, 0x80 },
-//     /*U*/   { OV511_I2C_BUS, 0x4c, 0xd0 },
-       /*d2?*/ { OV511_I2C_BUS, 0x4d, 0x10 }, /* This reduces noise a bit */
-       /*c1?*/ { OV511_I2C_BUS, 0x4e, 0x40 },
-       /*04?*/ { OV511_I2C_BUS, 0x4f, 0x07 },
-//     /*U*/   { OV511_I2C_BUS, 0x50, 0xff },
-       /*U*/   { OV511_I2C_BUS, 0x54, 0x23 },
-//     /*U*/   { OV511_I2C_BUS, 0x55, 0xff },
-//     /*U*/   { OV511_I2C_BUS, 0x56, 0x12 },
-       /*U*/   { OV511_I2C_BUS, 0x57, 0x81 },
-//     /*U*/   { OV511_I2C_BUS, 0x58, 0x75 },
-       /*U*/   { OV511_I2C_BUS, 0x59, 0x01 },
-       /*U*/   { OV511_I2C_BUS, 0x5a, 0x2c },
-       /*U*/   { OV511_I2C_BUS, 0x5b, 0x0f },
-//     /*U*/   { OV511_I2C_BUS, 0x5c, 0x10 },
-               { OV511_DONE_BUS, 0x0, 0x00 },
+//             { OV511_I2C_BUS, 0x4a, 0x80 }, // Check these
+//             { OV511_I2C_BUS, 0x4b, 0x80 },
+               { OV511_I2C_BUS, 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
+               { OV511_I2C_BUS, 0x4e, 0x40 },
+
+               /* UV average mode, color killer: strongest */
+               { OV511_I2C_BUS, 0x4f, 0x07 },
+
+               { OV511_I2C_BUS, 0x54, 0x23 }, /* Max AGC gain: 18dB */
+               { OV511_I2C_BUS, 0x57, 0x81 }, /* (default) */
+               { OV511_I2C_BUS, 0x59, 0x01 }, /* AGC dark current comp: +1 */
+               { OV511_I2C_BUS, 0x5a, 0x2c }, /* (undocumented) */
+               { OV511_I2C_BUS, 0x5b, 0x0f }, /* AWB chrominance levels */
+//             { OV511_I2C_BUS, 0x5c, 0x10 },
+               { OV511_DONE_BUS, 0x0, 0x00 },  /* END MARKER */
        };
 
        PDEBUG(4, "starting sensor configuration");
@@ -5854,16 +5901,19 @@
                return -1;
        }
 
-       if ((rc & 3) == 0)
+       if ((rc & 3) == 0) {
                ov->sensor = SEN_OV6630;
-       else if ((rc & 3) == 1)
+               info("Sensor is an OV6630");
+       } else if ((rc & 3) == 1) {
                ov->sensor = SEN_OV6620;
-       else if ((rc & 3) == 2)
+               info("Sensor is an OV6620");
+       } else if ((rc & 3) == 2) {
                ov->sensor = SEN_OV6630;
-       else if ((rc & 3) == 3)
+               info("Sensor is an OV6630AE");
+       } else if ((rc & 3) == 3) {
                ov->sensor = SEN_OV6630;
-
-       info("Sensor is an %s", symbolic(senlist, ov->sensor));
+               info("Sensor is an OV6630AF");
+       }
 
        /* Set sensor-specific vars */
        ov->maxwidth = 352;
@@ -6061,9 +6111,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 },
@@ -6072,9 +6122,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 },
@@ -6223,7 +6273,7 @@
                { OV511_REG_BUS, 0x5d,                  0x03 },
                { OV511_REG_BUS, 0x24,                  0x9f },
                { OV511_REG_BUS, 0x25,                  0x90 },
-               { OV511_REG_BUS, 0x20,                  0x00 }, /* Was 0x08 */
+               { OV511_REG_BUS, 0x20,                  0x00 },
                { OV511_REG_BUS, 0x51,                  0x04 },
                { OV511_REG_BUS, 0x71,                  0x19 },
                { OV511_DONE_BUS, 0x0, 0x00 },
@@ -6236,7 +6286,7 @@
                { OV511_REG_BUS, 0x5d,                  0x03 },
                { OV511_REG_BUS, 0x24,                  0x9f },
                { OV511_REG_BUS, 0x25,                  0x90 },
-               { OV511_REG_BUS, 0x20,                  0x60 }, /* Was 0x08 */
+               { OV511_REG_BUS, 0x20,                  0x60 },
                { OV511_REG_BUS, 0x51,                  0x02 },
                { OV511_REG_BUS, 0x71,                  0x19 },
                { OV511_REG_BUS, 0x40,                  0xff },
@@ -6286,11 +6336,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);
 
@@ -6450,7 +6509,13 @@
 
        ov->buf_state = BUF_NOT_ALLOCATED;
 
-       /* Must be kmalloc()'ed, for DMA accessibility */
+       if (usb_make_path(dev, ov->usb_path, OV511_USB_PATH_LEN) < 0) {
+               err("usb_make_path error");
+               goto error_dealloc;
+       }
+
+       /* Allocate control transfer buffer. */
+       /* Must be kmalloc()'ed, for DMA compatibility */
        ov->cbuf = kmalloc(OV511_CBUF_SIZE, GFP_KERNEL);
        if (!ov->cbuf)
                goto error;
@@ -6480,8 +6545,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));
@@ -6506,7 +6575,8 @@
                goto error;
        }
 
-       info("Device registered on minor %d", ov->vdev.minor);
+       info("Device at %s registered to minor %d", ov->usb_path,
+            ov->vdev.minor);
 
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
        create_proc_ov511_cam(ov);
@@ -6592,13 +6662,15 @@
        }
 
        MOD_DEC_USE_COUNT;
+
+       PDEBUG(3, "Disconnect complete");
 }
 
 static struct usb_driver ov511_driver = {
-       name:           "ov511",
-       id_table:       device_table,
-       probe:          ov51x_probe,
-       disconnect:     ov51x_disconnect
+       .name =         "ov511",
+       .id_table =     device_table,
+       .probe =        ov51x_probe,
+       .disconnect =   ov51x_disconnect
 };
 
 
diff -Nru a/drivers/usb/ov511.h b/drivers/usb/ov511.h
--- a/drivers/usb/ov511.h       Fri Dec 20 15:53:54 2002
+++ b/drivers/usb/ov511.h       Fri Dec 20 15:53:54 2002
@@ -253,6 +253,9 @@
 /* Control transfers use up to 4 bytes */
 #define OV511_CBUF_SIZE                4
 
+/* Size of usb_make_path() buffer */
+#define OV511_USB_PATH_LEN     64
+
 /* Bridge types */
 enum {
        BRG_UNKNOWN,
@@ -286,21 +289,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 +299,6 @@
 enum {
        BUF_NOT_ALLOCATED,
        BUF_ALLOCATED,
-       BUF_PEND_DEALLOC,       /* ov511->buf_timer is set */
 };
 
 /* --------- Definition of ioctl interface --------- */
@@ -466,6 +453,7 @@
        int customid;
        char *desc;
        unsigned char iface;
+       char usb_path[OV511_USB_PATH_LEN];
 
        /* Determined by sensor type */
        int maxwidth;
@@ -521,7 +509,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 +524,6 @@
        /* Framebuffer/sbuf management */
        int buf_state;
        struct semaphore buf_lock;
-       struct timer_list buf_timer;
 
        struct ov51x_decomp_ops *decomp_ops;
 

===================================================================


This BitKeeper patch contains the following changesets:
1.854
## Wrapped with gzip_uu ##


begin 664 bkpatch1375
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
M"VE0,8`5H!IS-I#T.;1:F^<,[email protected]*G\@@-W=]2NWEF+:(!I'K?\)&BI!,1>B
M;DUE"DV5PD_2%.Z&.F&J#5RL'5[$Y*4[7$"NHVBJLGDC5P:+N^'QE+OB8"S]
M2Q6*^.@`TBX.2C;RS,L:&`7/^X<'#WCDT&W7&Z1PFVBHE,Q^2C0,8MD%G^R1
MF^(\#:D)M2BU:+Z&LKIZ0T6+=:0\50D4'+?#C-GEX),2L4+-P/\F9@;<N_`7
M.KK`?,V9I.']4?\3]4.J:!!/#E2S:[L(J=8FFJ:JFIQB@4@+$)818)"49E2%
MP)UH&W&MI6H1/T?>M6CMM@5W3IY81I&9/J619F.I/\05UY)>@`*&<N4ZUN9B
MUW3:8%=W-@G<#.Y,8],\0V5F!`*BL#2]3D1-.$M[$Y+EK7BF.]V%Y#9B#)XQ
M4BM0I6TAR0O$(:UF.^9L&_DE?:[KUGRC][.DZAL2^:(]`<5$3$F1\'*QOEVT
MV"_#*))IDWKH"=WDV.Q1+269^H+F&A#;4J:^NOWO#@39;Q-I1K"_D;A=9WGH
M!6:EL/7J9H2&JD47'@K3!'3(X<_@H9`/T!%B4[S2-Q/@/3,6IE-!3"M.E)=%
MZ#HLWC=M$11:'_>%/T;R&<9<]D=RCNCZA*;;_G);ORM<ND7`5:/*RI'$O!!F
ME6HMC8IN@FH44`TVA:)IK/HQY%'CHLG##<ZB`GQ(2R]HJ6,I'I^@93Q)RUC0
M,@M:YM-\M3I/43,7U#@]QN@\0TWU?9&V.9K#D0KC_4C5Z[Q3&W"_UUHJ/<XA
MG@(UOAZ4J8*ANJT8JM?_;S!D&'PF58QK4#D[*-U#,1L*A<<G49P%BDN@&!ND
M54!%M-3U>RD_E9%<$PX]:JB%PRG\W@NJS@*)?WX2#\,1U6A+('RA3+W?GR$$
M3*ZG&94"0Q1W7I07Y\D(B#49!],$2(1[!1]URN=C9^&_Y>N%LSRCDV9NDV4J
MEU=G:&)YAK9R<6.[.)=.XI\*Y\E],9Y^3[B-.I<7ZP[B5*5;).2;8;37][HT
MBP;>*[Z_]X@QJB@0K1&H5^Z64"7OT'&9KLR`"A':,1KKRHW<OPP`$=\_]MLN
M]O3B;+]_VCI_WS_L'%>Y>&*FEH7_DH3`HR1EPRN-DCQ1W_N!Y*-S-L?/7#>U
MZ#ME.\6!I\B1+F1#F2*1&@[I;@H)E<()Y4(#*2[5Z7NE^I-$D*3#\/91Z_Z=
M$7:6#BIU5BX+Z:FC5LF'.:I5JAA?MD_]B)JMU#X]..3VJ5[L&ZWZ[C@QF5?O
M;]G]TT;UFD1LJ\XNC\;RR)`/I867BQ^SY5T'U9%'",%*N$UR3^YE5<_3LSEV
MI<9P5+L[-F>6$&+1%J##:N20$&.,')T%$LE<<J4&8.J>=%$N4NI7JL7(%,5>
MJ;3%"Z3&02T,BM/RO=+JX3F]FJ;)0"Y/IOD;/0[N9EN\NWNTX=[.^&OO[7SE
M);_G[^V,'][;T<RZ9?*]G<:W7]NQQ([N_CV7Y):7=HK[+\D@2VA'A9]Z4W[1
M"H*'MW@6!T=TA97O,#Y[/6;\7??E;(I;Y"KA-]=<)BJ,EPQQ<2?EL0,I.71Z
MUN9@8%,/F$\.+3[>+_EC+Q4+,_CC,?*?U(#@:REMVZ(FR/+BN$_Y=S:;[/DD
.:-/PR_\+@)%IS[4N````
`
end

Reply via email to