patch-2.3.25 linux/drivers/usb/cpia.c
Next file: linux/drivers/usb/cpia.h
Previous file: linux/drivers/usb/audio.c
Back to the patch index
Back to the overall index
- Lines: 459
- Date:
Mon Nov 1 11:30:29 1999
- Orig file:
v2.3.24/linux/drivers/usb/cpia.c
- Orig date:
Wed Oct 27 16:34:12 1999
diff -u --recursive --new-file v2.3.24/linux/drivers/usb/cpia.c linux/drivers/usb/cpia.c
@@ -29,6 +29,7 @@
#define CPIA_DEBUG /* Gobs of debugging info */
/* Video Size 384 x 288 x 3 bytes for RGB */
+/* 384 because xawtv tries to grab 384 even though we tell it 352 is our max */
#define MAX_FRAME_SIZE (384 * 288 * 3)
/*******************************/
@@ -37,6 +38,8 @@
#define MDEBUG(x) do { } while(0) /* Debug memory management */
+static struct usb_driver cpia_driver;
+
/* Given PGD from the address space's page table, return the kernel
* virtual mapping of the physical memory mapped at ADR.
*/
@@ -207,8 +210,8 @@
static int usb_cpia_upload_frame(struct usb_device *dev, int forceupload)
{
return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- USB_REQ_CPIA_UPLOAD_FRAME,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE, forceupload, 0, NULL, 0, HZ);
+ USB_REQ_CPIA_UPLOAD_FRAME, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ forceupload, 0, NULL, 0, HZ);
}
static int usb_cpia_set_grab_mode(struct usb_device *dev, int continuousgrab)
@@ -245,6 +248,16 @@
}
#ifdef NOTUSED
+static int usb_cpia_set_compression_target(struct usb_device *dev, int target, int targetfr, int targetq)
+{
+ return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ USB_REQ_CPIA_SET_COMPRESSION_TARGET,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ (targetfr << 8) + target, targetq, NULL, 0, HZ);
+}
+#endif
+
+#ifdef NOTUSED
static int usb_cpia_initstreamcap(struct usb_device *dev, int skipframes, int streamstartline)
{
return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
@@ -284,6 +297,7 @@
unsigned char *data = cpia->scratch;
unsigned long l;
+ /* Grab the current frame and the previous frame */
frame = &cpia->frame[cpia->curframe];
pframe = &cpia->frame[(cpia->curframe - 1 + CPIA_NUMFRAMES) % CPIA_NUMFRAMES];
@@ -314,9 +328,9 @@
/* See if we found the end of the frame */
while (scratch_left(data) >= 4) {
if (*((__u32 *)data) == 0xFFFFFFFF) {
-printk("found end of frame\n");
data += 4;
-goto error;
+ printk(KERN_INFO "cpia: EOF while scanning for magic\n");
+ goto error;
}
data++;
}
@@ -347,7 +361,6 @@
frame->scanstate = STATE_LINES;
frame->curline = 0;
-
break;
case STATE_LINES:
{
@@ -363,10 +376,9 @@
/* Grab the length */
len = data[0] + (data[1] << 8);
-printk("line %d, %d bytes long\n", frame->curline, len);
/* Check to make sure it's nothing outrageous */
if (len > (frame->hdrwidth * 2) + 1) {
- printk(KERN_INFO "cpia: bad length, resynching\n");
+ printk(KERN_INFO "cpia: bad length, resynching (expected %d, got %d)\n", (frame->hdrwidth * 2) + 1, len);
goto error;
}
@@ -380,12 +392,6 @@
/* Is the end of the line there */
if (data[len - 1] != 0xFD) {
printk(KERN_INFO "cpia: lost synch\n");
-end = data + len - 1 - 4;
-printk("%02X %02X %02X %02X %02X %02X %02X %02X\n",
-end[0], end[1],
-end[2], end[3],
-end[4], end[5],
-end[6], end[7]);
goto error;
}
@@ -426,12 +432,6 @@
*f++ = LIMIT(b + y); *f++ = LIMIT(g + y); *f++ = LIMIT(r + y);
*f++ = LIMIT(b + y1); *f++ = LIMIT(g + y1); *f++ = LIMIT(r + y1);
fp += 6;
-/*
- f[0] = f[1] = f[2] = *data;
- f += 3;
- data += 2;
- fp += 3;
-*/
}
}
} else {
@@ -469,10 +469,11 @@
}
nextframe:
- if (scratch_left(data) >= 4 && *((__u32 *)data) == 0xFFFFFFFF) {
+#ifdef CPIA_DEBUG
+ printk("cpia: marking as success\n");
+#endif
+ if (scratch_left(data) >= 4 && *((__u32 *)data) == 0xFFFFFFFF)
data += 4;
-printk("end of frame found normally\n");
-}
frame->grabstate = FRAME_DONE;
cpia->curframe = -1;
@@ -484,6 +485,9 @@
goto out;
error:
+#ifdef CPIA_DEBUG
+ printk("cpia: marking as error\n");
+#endif
frame->grabstate = FRAME_ERROR;
cpia->curframe = -1;
cpia->compress = 0;
@@ -493,7 +497,6 @@
wake_up_interruptible(&frame->wq);
out:
-printk("scanned %d bytes, %d left\n", data - cpia->scratch, scratch_left(data));
/* Grab the remaining */
l = scratch_left(data);
memmove(cpia->scratch, data, l);
@@ -544,7 +547,7 @@
int i;
if (!cpia->streaming) {
- printk("oops, not streaming, but interrupt\n");
+ printk("cpia: oops, not streaming, but interrupt\n");
return 0;
}
@@ -554,7 +557,6 @@
/* Copy the data received into our scratch buffer */
len = cpia_compress_isochronous(cpia, sbuf->isodesc);
-printk("%d bytes received\n", len);
/* If we don't have a frame we're current working on, complain */
if (len) {
if (cpia->curframe < 0)
@@ -587,7 +589,7 @@
/* Alternate interface 3 is is the biggest frame size */
if (usb_set_interface(cpia->dev, 1, 3) < 0) {
- printk("usb_set_interface error\n");
+ printk(KERN_ERR "usb_set_interface error\n");
return -EBUSY;
}
@@ -642,21 +644,7 @@
if (err)
printk(KERN_ERR "CPiA USB driver error (%d) on usb_run_isoc\n", err);
-#ifdef CPIA_DEBUG
- printk("done scheduling\n");
-#endif
-
-#if 0
- if (usb_cpia_grab_frame(dev, 120) < 0) {
- printk(KERN_INFO "cpia_grab_frame error\n");
- return -EBUSY;
- }
-#endif
-
cpia->streaming = 1;
-#ifdef CPIA_DEBUG
- printk("now streaming\n");
-#endif
return 0;
}
@@ -666,21 +654,12 @@
if (!cpia->streaming)
return;
- cpia->streaming = 0;
-
/* Turn off continuous grab */
if (usb_cpia_set_grab_mode(cpia->dev, 0) < 0) {
printk(KERN_INFO "cpia_set_grab_mode error\n");
return /* -EBUSY */;
}
-#if 0
- if (usb_cpia_grab_frame(cpia->dev, 0) < 0) {
- printk(KERN_INFO "cpia_grab_frame error\n");
- return /* -EBUSY */;
- }
-#endif
-
/* Set packet size to 0 */
if (usb_set_interface(cpia->dev, 1, 0) < 0) {
printk(KERN_INFO "usb_set_interface error\n");
@@ -691,6 +670,8 @@
usb_kill_isoc(cpia->sbuf[1].isodesc);
usb_kill_isoc(cpia->sbuf[0].isodesc);
+ cpia->streaming = 0;
+
/* Delete them all */
usb_free_isoc(cpia->sbuf[1].isodesc);
usb_free_isoc(cpia->sbuf[0].isodesc);
@@ -701,29 +682,23 @@
struct cpia_frame *frame;
int width, height;
-printk("new frame %d\n", framenum);
- if (framenum == -1) {
- int i;
- for (i = 0; i < CPIA_NUMFRAMES; i++)
- if (cpia->frame[i].grabstate == FRAME_READY)
- break;
-
- if (i >= CPIA_NUMFRAMES) {
- printk("no frame ready\n");
- return 0;
- }
-
- framenum = i;
-printk("using frame %d\n", framenum);
- }
-
- if (cpia->curframe != -1 && cpia->curframe != framenum)
+ /* If we're not grabbing a frame right now and the other frame is */
+ /* ready to be grabbed into, then use it instead */
+ if (cpia->curframe == -1) {
+ if (cpia->frame[(framenum - 1 + CPIA_NUMFRAMES) % CPIA_NUMFRAMES].grabstate == FRAME_READY)
+ framenum = (framenum - 1 + CPIA_NUMFRAMES) % CPIA_NUMFRAMES;
+ } else
return 0;
frame = &cpia->frame[framenum];
width = frame->width;
height = frame->height;
+ frame->grabstate = FRAME_GRABBING;
+ frame->scanstate = STATE_SCANNING;
+
+ cpia->curframe = framenum;
+
/* Make sure it's not too big */
if (width > 352)
width = 352;
@@ -737,7 +712,8 @@
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 ? 1 : 0, 0) < 0) {
+ if (usb_cpia_set_compression(cpia->dev, cpia->compress ?
+ COMP_AUTO : COMP_DISABLED, DONT_DECIMATE) < 0) {
printk(KERN_INFO "cpia_set_compression error\n");
return -EBUSY;
}
@@ -746,16 +722,11 @@
cpia->compress = (cpia->compress + 1) % 30;
/* Grab the frame */
- if (usb_cpia_upload_frame(cpia->dev, 1) < 0) {
+ if (usb_cpia_upload_frame(cpia->dev, WAIT_FOR_NEXT_FRAME) < 0) {
printk(KERN_INFO "cpia_upload_frame error\n");
return -EBUSY;
}
- frame->grabstate = FRAME_GRABBING;
- frame->scanstate = STATE_SCANNING;
-
- cpia->curframe = framenum;
-
return 0;
}
@@ -862,8 +833,8 @@
b.audios = 0;
b.maxwidth = 352; /* CIF */
b.maxheight = 288; /* " */
- b.minwidth = 176; /* QCIF */
- b.minheight = 144; /* " */
+ b.minwidth = 8;
+ b.minheight = 4;
if (copy_to_user(arg, &b, sizeof(b)))
return -EFAULT;
@@ -1065,11 +1036,11 @@
return -EINVAL;
case FRAME_READY:
case FRAME_GRABBING:
+ case FRAME_ERROR:
redo:
do {
-printk("enter sleeping\n");
+ init_waitqueue_head(&cpia->frame[frame].wq);
interruptible_sleep_on(&cpia->frame[frame].wq);
-printk("back from sleeping\n");
if (signal_pending(current))
return -EINTR;
} while (cpia->frame[frame].grabstate ==
@@ -1091,8 +1062,9 @@
#ifdef CPIA_DEBUG
printk("cpia: finished, synced to frame %d\n", frame);
#endif
+ cpia->frame[frame].grabstate = FRAME_UNUSED;
- return cpia_new_frame(cpia, -1);
+ return 0;
}
case VIDIOCGFBUF:
{
@@ -1195,12 +1167,11 @@
struct usb_device *dev = cpia->dev;
unsigned char version[4];
- if (usb_set_configuration(dev, dev->config[0].bConfigurationValue) < 0) {
- printk(KERN_INFO "cpia: usb_set_configuration failed\n");
- return -EBUSY;
- }
+ /* claim interface 1 */
+ usb_driver_claim_interface(&cpia_driver,
+ &dev->actconfig->interface[1], cpia);
- /* Set packet size to 0 */
+ /* Set altsetting 0 on interface 1 */
if (usb_set_interface(dev, 1, 0) < 0) {
printk(KERN_INFO "usb_set_interface error\n");
return -EBUSY;
@@ -1211,7 +1182,7 @@
return -EBUSY;
}
- printk("cpia: Firmware v%d.%d, VC Hardware v%d.%d\n",
+ printk(KERN_DEBUG "cpia: Firmware v%d.%d, VC Hardware v%d.%d\n",
version[0], version[1], version[2], version[3]);
memcpy(&cpia->vdev, &cpia_template, sizeof(cpia_template));
@@ -1234,8 +1205,8 @@
goto error;
}
- printk("cpia: VP v%d rev %d\n", version[0], version[1]);
- printk("cpia: Camera Head ID %04X\n", (version[3] << 8) + version[2]);
+ printk(KERN_DEBUG "cpia: VP v%d rev %d\n", version[0], version[1]);
+ printk(KERN_DEBUG "cpia: Camera Head ID %04X\n", (version[3] << 8) + version[2]);
/* Turn on continuous grab */
if (usb_cpia_set_grab_mode(dev, 1) < 0) {
@@ -1250,13 +1221,14 @@
}
/* Set video into CIF mode, and order into YUYV mode */
- if (usb_cpia_set_format(dev, CPIA_CIF, 1, CPIA_YUYV) < 0) {
+ if (usb_cpia_set_format(dev, FORMAT_CIF, FORMAT_422,
+ FORMAT_YUYV) < 0) {
printk(KERN_INFO "cpia_set_format error\n");
goto error;
}
/* Turn off compression */
- if (usb_cpia_set_compression(dev, 0, 0) < 0) {
+ if (usb_cpia_set_compression(dev, COMP_DISABLED, DONT_DECIMATE) < 0) {
printk(KERN_INFO "cpia_set_compression error\n");
goto error;
}
@@ -1267,56 +1239,62 @@
error:
video_unregister_device(&cpia->vdev);
+ usb_driver_release_interface(&cpia_driver,
+ &dev->actconfig->interface[1]);
kfree(cpia);
return -EBUSY;
}
-static int cpia_probe(struct usb_device *dev)
+static void * cpia_probe(struct usb_device *dev, unsigned int ifnum)
{
struct usb_interface_descriptor *interface;
struct usb_cpia *cpia;
/* We don't handle multi-config cameras */
if (dev->descriptor.bNumConfigurations != 1)
- return -1;
+ return NULL;
- interface = &dev->config[0].interface[0].altsetting[0];
+ interface = &dev->actconfig->interface[ifnum].altsetting[0];
/* Is it a CPiA? */
if (dev->descriptor.idVendor != 0x0553)
- return -1;
+ return NULL;
if (dev->descriptor.idProduct != 0x0002)
- return -1;
+ return NULL;
/* Checking vendor/product should be enough, but what the hell */
if (interface->bInterfaceClass != 0xFF)
- return -1;
+ return NULL;
if (interface->bInterfaceSubClass != 0x00)
- return -1;
+ return NULL;
/* We found a CPiA */
- printk("USB CPiA camera found\n");
+ printk(KERN_INFO "USB CPiA camera found\n");
if ((cpia = kmalloc(sizeof(*cpia), GFP_KERNEL)) == NULL) {
- printk("couldn't kmalloc cpia struct\n");
- return -1;
+ printk(KERN_ERR "couldn't kmalloc cpia struct\n");
+ return NULL;
}
memset(cpia, 0, sizeof(*cpia));
- dev->private = cpia;
cpia->dev = dev;
- return usb_cpia_configure(cpia);
+ if (!usb_cpia_configure(cpia)) {
+ return cpia;
+ } else return NULL;
}
-static void cpia_disconnect(struct usb_device *dev)
+static void cpia_disconnect(struct usb_device *dev, void *ptr)
{
- struct usb_cpia *cpia = dev->private;
+ struct usb_cpia *cpia = (struct usb_cpia *) ptr;
video_unregister_device(&cpia->vdev);
+
+ usb_driver_release_interface(&cpia_driver,
+ &cpia->dev->actconfig->interface[1]);
/* Free the memory */
kfree(cpia);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)