# 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//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 & Bret Wallach \ +#define DRIVER_VERSION "v1.62 for Linux 2.5" +#define EMAIL "mark@alpha.dyndns.org" +#define DRIVER_AUTHOR "Mark McClelland & Bret Wallach \ & Orion Sky Lawlor & Kevin Moore & Charl P. Botha \ & Claudio Matsuoka " #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;