patch-2.3.37 linux/drivers/usb/ov511.c
Next file: linux/drivers/usb/ov511.h
Previous file: linux/drivers/usb/ohci-hcd.c
Back to the patch index
Back to the overall index
- Lines: 666
- Date:
Wed Jan 5 08:44:47 2000
- Orig file:
v2.3.36/linux/drivers/usb/ov511.c
- Orig date:
Tue Jan 4 13:57:17 2000
diff -u --recursive --new-file v2.3.36/linux/drivers/usb/ov511.c linux/drivers/usb/ov511.c
@@ -14,7 +14,22 @@
* Version History:
* Version 1.00 - Initial version
*/
-
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
#define __NO_VERSION__
@@ -46,13 +61,15 @@
#include "usb.h"
#include "ov511.h"
+#define OV511_I2C_RETRIES 3
+
/* Video Size 384 x 288 x 3 bytes for RGB */
-#define MAX_FRAME_SIZE (384 * 288 * 3)
+#define MAX_FRAME_SIZE (320 * 240 * 3)
// FIXME - Force CIF to make some apps happy for the moment. Should find a
// better way to do this.
-#define DEFAULT_WIDTH 384
-#define DEFAULT_HEIGHT 288
+#define DEFAULT_WIDTH 320
+#define DEFAULT_HEIGHT 240
char kernel_version[] = UTS_RELEASE;
@@ -173,7 +190,7 @@
vfree(mem);
}
-int usb_ov511_reg_write(struct usb_device *dev, unsigned char reg, unsigned char value)
+int ov511_reg_write(struct usb_device *dev, unsigned char reg, unsigned char value)
{
int rc;
@@ -183,13 +200,13 @@
USB_TYPE_CLASS | USB_RECIP_DEVICE,
0, (__u16)reg, &value, 1, HZ);
- PDEBUG("reg write: 0x%X:0x%X\n", reg, value);
+ PDEBUG("reg write: 0x%02X:0x%02X\n", reg, value);
return rc;
}
/* returns: negative is error, pos or zero is data */
-int usb_ov511_reg_read(struct usb_device *dev, unsigned char reg)
+int ov511_reg_read(struct usb_device *dev, unsigned char reg)
{
int rc;
unsigned char buffer[1];
@@ -200,7 +217,7 @@
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_DEVICE,
0, (__u16)reg, buffer, 1, HZ);
- PDEBUG("reg read: 0x%X:0x%X\n", reg, buffer[0]);
+ PDEBUG("reg read: 0x%02X:0x%02X\n", reg, buffer[0]);
if(rc < 0)
return rc;
@@ -208,89 +225,116 @@
return buffer[0];
}
-int usb_ov511_cam_reg_write(struct usb_device *dev, unsigned char reg, unsigned char value)
+int ov511_i2c_write(struct usb_device *dev, unsigned char reg, unsigned char value)
{
- int rc;
-
- // Three byte write cycle
-
- // Set slave ID (This might only need to be done once)
- // (CAMERA SPECIFIC (OV7610/OV7110))
- rc = usb_ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE,
- OV7610_I2C_WRITE_ID);
- if (rc < 0) return rc;
-
- // Select camera register (I2C sub-address)
- rc = usb_ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_3_BYTE, reg);
- if (rc < 0) return rc;
+ int rc, retries;
- // Write "value" to I2C data port of OV511
- rc = usb_ov511_reg_write(dev, OV511_REG_I2C_DATA_PORT, value);
- if (rc < 0) return rc;
-
- // FIXME - should ensure bus is idle before continuing
-
- // Initiate 3-byte write cycle
- rc = usb_ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x01);
+ PDEBUG("i2c write: 0x%02X:0x%02X\n", reg, value);
+ /* Three byte write cycle */
+ for(retries = OV511_I2C_RETRIES;;) {
+ /* Select camera register */
+ rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_3_BYTE, reg);
+ if (rc < 0) return rc;
+
+ /* Write "value" to I2C data port of OV511 */
+ rc = ov511_reg_write(dev, OV511_REG_I2C_DATA_PORT, value);
+ if (rc < 0) return rc;
+
+ /* Initiate 3-byte write cycle */
+ rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x01);
+ if (rc < 0) return rc;
+
+ do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
+ while(rc > 0 && ((rc&1) == 0)); /* Retry until idle */
+ if (rc < 0) return rc;
- return rc;
+ if((rc&2) == 0) /* Ack? */
+ break;
+
+ /* I2C abort */
+ ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
+
+ if (--retries < 0) return -1;
+ }
+
+ return 0;
}
/* returns: negative is error, pos or zero is data */
-int usb_ov511_cam_reg_read(struct usb_device *dev, unsigned char reg)
+int ov511_i2c_read(struct usb_device *dev, unsigned char reg)
{
- int rc;
+ int rc, value, retries;
- // Two byte write cycle
-
- // Set slave ID (This might only need to be done once)
- // (CAMERA SPECIFIC (OV7610/OV7110))
- rc = usb_ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE, OV7610_I2C_WRITE_ID);
- if (rc < 0) return rc;
-
- // Select camera register (I2C sub-address)
- rc = usb_ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_2_BYTE, reg);
- if (rc < 0) return rc;
-
- // Initiate 2-byte write cycle
- rc = usb_ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x03);
- if (rc < 0) return rc;
-
- // Two byte read cycle
-
- // Set slave ID (This might only need to be done once)
- // (CAMERA SPECIFIC (OV7610/OV7110))
- rc = usb_ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ,
- OV7610_I2C_READ_ID);
- if (rc < 0) return rc;
-
- // Initiate 2-byte read cycle
- rc = usb_ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x05);
+ /* Two byte write cycle */
+ for(retries = OV511_I2C_RETRIES;;) {
+ /* Select camera register */
+ rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_2_BYTE, reg);
+ if (rc < 0) return rc;
+
+ /* Initiate 2-byte write cycle */
+ rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x03);
+ if (rc < 0) return rc;
+
+ do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
+ while(rc > 0 && ((rc&1) == 0)); /* Retry until idle */
+ if (rc < 0) return rc;
+
+ if((rc&2) == 0) /* Ack? */
+ break;
+
+ /* I2C abort */
+ ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
+
+ if (--retries < 0) return -1;
+ }
+
+ /* Two byte read cycle */
+ for(retries = OV511_I2C_RETRIES;;) {
+ /* Initiate 2-byte read cycle */
+ rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x05);
+ if (rc < 0) return rc;
+
+ do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
+ while(rc > 0 && ((rc&1) == 0)); /* Retry until idle */
+ if (rc < 0) return rc;
+
+ if((rc&2) == 0) /* Ack? */
+ break;
+
+ /* I2C abort */
+ rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
+ if (rc < 0) return rc;
+
+ if (--retries < 0) return -1;
+ }
+
+ value = ov511_reg_read(dev, OV511_REG_I2C_DATA_PORT);
+ PDEBUG("i2c read: 0x%02X:0x%02X\n", reg, value);
+
+ /* This is needed to make ov511_i2c_write() work */
+ rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x05);
if (rc < 0) return rc;
- // FIXME - should check I2C bus status here before reading data!
-
- // Write "value" to I2C data port of OV511
- return usb_ov511_reg_read(dev, OV511_REG_I2C_DATA_PORT);
+ return (value);
}
-int usb_ov511_reset(struct usb_device *dev, unsigned char reset_type)
+int ov511_reset(struct usb_device *dev, unsigned char reset_type)
{
int rc;
PDEBUG("Reset: type=0x%X\n", reset_type);
- rc = usb_ov511_reg_write(dev, OV511_REG_SYSTEM_RESET, reset_type);
+ rc = ov511_reg_write(dev, OV511_REG_SYSTEM_RESET, reset_type);
if (rc < 0)
printk(KERN_ERR "ov511: reset: command failed\n");
- rc = usb_ov511_reg_write(dev, OV511_REG_SYSTEM_RESET, 0);
+ rc = ov511_reg_write(dev, OV511_REG_SYSTEM_RESET, 0);
if (rc < 0)
printk(KERN_ERR "ov511: reset: command failed\n");
return rc;
}
-int usb_ov511_set_packet_size(struct usb_ov511 *ov511, int size)
+int ov511_set_packet_size(struct usb_ov511 *ov511, int size)
{
int alt, multiplier, err;
@@ -303,7 +347,7 @@
break;
case 993:
alt = 1;
- multiplier = 32;
+ multiplier = 31;
break;
case 768:
alt = 2;
@@ -311,7 +355,7 @@
break;
case 769:
alt = 3;
- multiplier = 25;
+ multiplier = 24;
break;
case 512:
alt = 4;
@@ -319,11 +363,11 @@
break;
case 513:
alt = 5;
- multiplier = 17;
+ multiplier = 16;
break;
case 257:
alt = 6;
- multiplier = 9;
+ multiplier = 8;
break;
case 0:
alt = 7;
@@ -335,7 +379,7 @@
return -EINVAL;
}
- err = usb_ov511_reg_write(ov511->dev, OV511_REG_FIFO_PACKET_SIZE,
+ 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",
@@ -349,7 +393,7 @@
}
// FIXME - Should we only reset the FIFO?
- if (usb_ov511_reset(ov511->dev, OV511_RESET_NOREGS) < 0)
+ if (ov511_reset(ov511->dev, OV511_RESET_NOREGS) < 0)
return -ENOMEM;
return 0;
@@ -358,43 +402,85 @@
/* How much data is left in the scratch buf? */
#define scratch_left(x) (ov511->scratchlen - (int)((char *)x - (char *)ov511->scratch))
-// FIXME - Useless stub
-static void ov511_parse_data(struct usb_ov511 *ov511)
+static int ov511_move_data(struct usb_ov511 *ov511, urb_t *urb)
{
- PDEBUG("ov511_parse_data not implemented\n"); // TEMPORARY CODE
-}
-
-static int ov511_compress_isochronous(struct usb_ov511 *ov511, urb_t *urb)
-{
- unsigned char *cdata, *data;
+ unsigned char *cdata;
int i, totlen = 0;
+ int aPackNum[10];
+ struct ov511_frame *frame;
+
+ if (ov511->curframe == -1) {
+ return 0;
+ }
- data = ov511->scratch + ov511->scratchlen;
for (i = 0; i < urb->number_of_packets; i++) {
int n = urb->iso_frame_desc[i].actual_length;
int st = urb->iso_frame_desc[i].status;
cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
- if (st) {
+ if (!n) continue;
+
+ aPackNum[i] = n ? cdata[512] : -1;
+
+ if (st){
// Macro - must be in braces!
PDEBUG("data error: [%d] len=%d, status=%d\n",
i, n, st);
- }
+ }
+
+ frame = &ov511->frame[ov511->curframe];
+
+ /* Can we find a frame end */
+ if ((cdata[0] | cdata[1] | cdata[2] | cdata[3] |
+ cdata[4] | cdata[5] | cdata[6] | cdata[7]) == 0 &&
+ (cdata[8] & 8) && (cdata[8] & 0x80)) {
+
+ PDEBUG("Found Frame End!, packnum = %d\n", (int)(cdata[512]));
+ PDEBUG("Current frame = %d\n", ov511->curframe);
+
+ if (frame->scanstate == STATE_LINES) {
+ if (waitqueue_active(&frame->wq)) {
+ PDEBUG("About to wake up waiting processes\n");
+ frame->grabstate = FRAME_DONE;
+ wake_up_interruptible(&frame->wq);
+ }
+ }
+ }
- if ((ov511->scratchlen + n) > SCRATCH_BUF_SIZE) {
- PDEBUG("scratch buf overflow!scr_len: %d, n: %d\n", ov511->scratchlen, n );
- return totlen;
+ /* Can we find a frame start */
+ else if ((cdata[0] | cdata[1] | cdata[2] | cdata[3] |
+ cdata[4] | cdata[5] | cdata[6] | cdata[7]) == 0 &&
+ (cdata[8] & 8)) {
+ PDEBUG("ov511: Found Frame Start!, packnum = %d\n", (int)(cdata[512]));
+ frame->scanstate = STATE_LINES;
+ frame->curpix = 0;
}
- if (n) {
- memmove(data, cdata, n);
- data += n;
- totlen += n;
- ov511->scratchlen += n;
+ /* Are we in a frame? */
+ else if (frame->scanstate == STATE_LINES) {
+ unsigned char *f = frame->data + 3 * frame->curpix;
+ int i;
+ if (frame->curpix <= 320 * 240 - 256) {
+ for (i=0; i<256; i++) {
+ *f++ = *cdata;
+ *f++ = *cdata;
+ *f++ = *cdata++;
+ *f++ = *cdata;
+ *f++ = *cdata;
+ *f++ = *cdata++;
+ }
+ frame->curpix += 512;
+ } else {
+ PDEBUG("Too many pixels!\n");
+ }
}
+
}
+ PDEBUG("pn: %d %d %d %d %d %d %d %d %d %d\n",
+ aPackNum[0], aPackNum[1], aPackNum[2], aPackNum[3], aPackNum[4],
+ aPackNum[5],aPackNum[6], aPackNum[7], aPackNum[8], aPackNum[9]);
return totlen;
}
@@ -405,7 +491,17 @@
struct ov511_sbuf *sbuf;
int i;
- PDEBUG("ov511_isoc_irq: %p status %d, errcount = %d, length = %d\n", urb, urb->status, urb->error_count, urb->actual_length);
+#if 0
+ static int last_status, last_error_count, last_actual_length;
+ if (last_status != urb->status ||
+ last_error_count != urb->error_count ||
+ last_actual_length != urb->actual_length) {
+ PDEBUG("ov511_isoc_irq: %p status %d, errcount = %d, length = %d\n", urb, urb->status, urb->error_count, urb->actual_length);
+ last_status = urb->status;
+ last_error_count = urb->error_count;
+ last_actual_length = urb->actual_length;
+ }
+#endif
if (!ov511->streaming) {
PDEBUG("hmmm... not streaming, but got interrupt\n");
@@ -413,11 +509,10 @@
}
sbuf = &ov511->sbuf[ov511->cursbuf];
-// usb_kill_isoc(sbuf->isodesc);
/* Copy the data received into our scratch buffer */
- len = ov511_compress_isochronous(ov511, urb);
-
+ len = ov511_move_data(ov511, urb);
+#if 0
/* If we don't have a frame we're current working on, complain */
if (ov511->scratchlen) {
if (ov511->curframe < 0) {
@@ -426,7 +521,7 @@
} else
ov511_parse_data(ov511);
}
-
+#endif
for (i = 0; i < FRAMES_PER_DESC; i++) {
sbuf->urb->iso_frame_desc[i].status = 0;
sbuf->urb->iso_frame_desc[i].actual_length = 0;
@@ -435,9 +530,6 @@
/* Move to the next sbuf */
ov511->cursbuf = (ov511->cursbuf + 1) % OV511_NUMSBUF;
- /* Reschedule this block of Isochronous desc */
-// usb_run_isoc(sbuf->isodesc, ov511->sbuf[ov511->cursbuf].isodesc);
-
return;
}
@@ -452,9 +544,25 @@
ov511->cursbuf = 0;
ov511->scratchlen = 0;
- // FIXME - is this the proper size?
- usb_ov511_set_packet_size(ov511, 512);
+ ov511_set_packet_size(ov511, 512);
+#define OV511_COLOR_BAR_TEST
+#ifdef OV511_COLOR_BAR_TEST
+ {
+ int rc;
+ rc = ov511_i2c_read(ov511->dev, 0x12);
+ rc = ov511_i2c_write(ov511->dev, 0x12, 0x3f);
+ rc = ov511_i2c_read(ov511->dev, 0x12);
+ rc = ov511_i2c_read(ov511->dev, 0x13);
+ rc = ov511_i2c_write(ov511->dev, 0x14, 0x4);
+ rc = ov511_i2c_read(ov511->dev, 0x14);
+ rc = ov511_i2c_write(ov511->dev, 0x28, 0x60);
+ rc = ov511_i2c_read(ov511->dev, 0x28);
+ ov511_reg_write(ov511->dev, OV511_REG_CAMERA_DATA_INPUT_SELECT,
+ 0);
+ }
+#endif
+
/* We double buffer the Iso lists */
urb = usb_alloc_urb(FRAMES_PER_DESC);
@@ -494,7 +602,7 @@
urb->iso_frame_desc[fx].offset = FRAME_SIZE_PER_DESC * fx;
urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC;
}
-
+
ov511->sbuf[1].urb->next = ov511->sbuf[0].urb;
ov511->sbuf[0].urb->next = ov511->sbuf[1].urb;
@@ -509,7 +617,7 @@
ov511->streaming = 1;
- return 0;
+ return 0;
}
@@ -518,14 +626,7 @@
if (!ov511->streaming)
return;
-// FIXME - Figure out how to do this with the ov511 (Does the below do it?)
-// /* Turn off continuous grab */
-// if (usb_cpia_set_grab_mode(cpia->dev, 0) < 0) {
-// printk(KERN_ERR "cpia_set_grab_mode error\n");
-// return /* -EBUSY */;
-// }
-
- usb_ov511_set_packet_size(ov511, 0);
+ ov511_set_packet_size(ov511, 0);
/* Unschedule all of the iso td's */
usb_unlink_urb(ov511->sbuf[1].urb);
@@ -570,25 +671,8 @@
height = DEFAULT_HEIGHT;
height = (height / 4) * 4; /* Multiple of 4 */
-// FIXME - Don't know how to implement the equivalent of this for the ov511
-// /* Set the ROI they want */
-// if (usb_cpia_set_roi(cpia->dev, 0, width / 8, 0, height / 4) < 0)
-// return -EBUSY;
-
-// if (usb_cpia_set_compression(cpia->dev, cpia->compress ?
-// COMP_AUTO : COMP_DISABLED, DONT_DECIMATE) < 0) {
-// printk(KERN_ERR "cpia_set_compression error\n");
-// return -EBUSY;
-// }
-
- /* We want a fresh frame every 30 we get */
- ov511->compress = (ov511->compress + 1) % 30;
-
-// /* Grab the frame */
-// if (usb_cpia_upload_frame(cpia->dev, WAIT_FOR_NEXT_FRAME) < 0) {
-// printk(KERN_ERR "cpia_upload_frame error\n");
-// return -EBUSY;
-// }
+// /* We want a fresh frame every 30 we get */
+// ov511->compress = (ov511->compress + 1) % 30;
return 0;
}
@@ -1061,48 +1145,69 @@
0
};
-static int usb_ov511_configure(struct usb_ov511 *ov511)
+static int ov511_configure(struct usb_ov511 *ov511)
{
struct usb_device *dev = ov511->dev;
int temprc; // DEBUG CODE
-
+
/* Set altsetting 0 */
if (usb_set_interface(dev, ov511->iface, 0) < 0) {
printk(KERN_ERR "ov511: usb_set_interface error\n");
return -EBUSY;
}
-
+
memcpy(&ov511->vdev, &ov511_template, sizeof(ov511_template));
init_waitqueue_head(&ov511->frame[0].wq);
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");
return -EBUSY;
}
- // Disable compression
- if (usb_ov511_reg_write(dev, OV511_OMNICE_ENABLE, 0x00) < 0) {
- printk(KERN_ERR "ov511: disable compression: command failed\n");
+ /* Reset in case driver was unloaded and reloaded without unplug */
+ if (ov511_reset(dev, OV511_RESET_ALL) < 0)
goto error;
- }
-
- // Initialize system
- // FIXME - This should be moved to a function
- if (usb_ov511_reg_write(dev, OV511_REG_SYSTEM_INIT, 0x01) < 0) {
+
+ /* Initialize system */
+ if (ov511_reg_write(dev, OV511_REG_SYSTEM_INIT, 0x01) < 0) {
printk(KERN_ERR "ov511: enable system: command failed\n");
goto error;
}
+
+ /* This seems to be necessary */
+ if (ov511_reset(dev, OV511_RESET_ALL) < 0)
+ goto error;
+
+ /* Disable compression */
+ if (ov511_reg_write(dev, OV511_OMNICE_ENABLE, 0x00) < 0) {
+ printk(KERN_ERR "ov511: disable compression: command failed\n");
+ goto error;
+ }
+
+// FIXME - error checking needed
+ ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE,
+ OV7610_I2C_WRITE_ID);
+ ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ,
+ OV7610_I2C_READ_ID);
+
+// DEBUG CODE
+// usb_ov511_reg_write(dev, OV511_REG_I2C_CLOCK_PRESCALER,
+// OV511_I2C_CLOCK_PRESCALER);
- if (usb_ov511_reset(dev, OV511_RESET_NOREGS) < 0)
+ if (ov511_reset(dev, OV511_RESET_NOREGS) < 0)
goto error;
+ /* Dummy read to sync I2C */
+ ov511_i2c_read(dev, 0x1C);
+
// DEBUG - TEST CODE FOR CAMERA REG READ
- temprc = usb_ov511_cam_reg_read(dev, 0x1D);
- PDEBUG("Camera reg 0x1D: 0x%X\n", temprc);
-// END DEBUG CODE
+ temprc = ov511_i2c_read(dev, 0x1C);
+ temprc = ov511_i2c_read(dev, 0x1D);
+// END DEBUG CODE
+
ov511->compress = 0;
return 0;
@@ -1156,14 +1261,14 @@
ov511->dev = dev;
ov511->iface = interface->bInterfaceNumber;
- rc = usb_ov511_reg_read(dev, OV511_REG_SYSTEM_CUSTOM_ID);
+ rc = ov511_reg_read(dev, OV511_REG_SYSTEM_CUSTOM_ID);
if (rc < 0) {
printk("ov511: Unable to read camera bridge registers\n");
return NULL;
- } else if (rc == 3) { // D-Link DSB-C300
+ } else if (rc == 3) { /* D-Link DSB-C300 */
printk("ov511: Camera is a D-Link DSB-C300\n");
ov511->customid = 3;
- } else if (rc == 21) { // Creative Labs WebCam 3
+ } else if (rc == 21) { /* Creative Labs WebCam 3 */
printk("ov511: Camera is a Creative Labs WebCam 3\n");
ov511->customid = 21;
} else {
@@ -1173,11 +1278,7 @@
return NULL;
}
- // Reset in case driver was unloaded and reloaded without unplug
- if (usb_ov511_reset(dev, OV511_RESET_ALL) < 0)
- return NULL;
-
- if (!usb_ov511_configure(ov511)) {
+ if (!ov511_configure(ov511)) {
ov511->user=0;
init_MUTEX(&ov511->lock); /* to 1 == available */
return ov511;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)