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

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)