Hi,

The following is the patch applied to the Debian version to make logitech and 
iSight to co-exist.

For the firmware loading, I'm thinking of using extract.c to extract
the firmware data to /usr/lib/firmware, and then using firmware loader
infrastructure afterwards to load the firmware, but I have not yet
gotten around to doing it, yet.



#! /bin/sh /usr/share/dpatch/dpatch-run
## 07_with_isight.dpatch Nobuhiro Iwamatsu <[EMAIL PROTECTED]>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: Workaround to get iSight and normal UVC devices function.

@DPATCH@
diff -urNad linux-uvc~/uvcvideo.c linux-uvc/uvcvideo.c
--- linux-uvc~/uvcvideo.c       2006-09-24 11:56:16.401464775 +0900
+++ linux-uvc/uvcvideo.c        2006-09-24 11:56:27.654754015 +0900
@@ -290,6 +290,11 @@
        UVC_BUF_STATE_ERROR      = 4,
 };
 
+enum uvc_dev_type{
+       UVC_DEV_ISIGHT          = 0 ,   /* Apple iSight */
+       UVC_DEV_QCAM_FUSION     = 1 ,   /* Qcam Fusion  */
+};
+
 struct uvc_buffer {
        unsigned int size;
        unsigned long vma_use_count;
@@ -381,6 +386,7 @@
 
 static void uvc_delete(struct kref *kref);
 
+static int dev_type ;/* device type */
 /* ------------------------------------------------------------------------
  * Control, formats, ...
  */
@@ -1295,14 +1301,23 @@
         * - bHeaderLength value must be at least 2 bytes (see above)
         * - bHeaderLength value can't be larger than the packet size.
         */
-       if ((len >= 14 && memcmp (&data[3], hdr, 12) == 0) ||
-           (len >= 13 && memcmp (&data[2], hdr, 12) == 0)) {
-               uvc_trace(UVC_TRACE_FRAME, "Detecting new header");
-               hlen = (data[3] == 0x11) ? data[1] : data[0];
-               if (hlen > len - 1 || hlen < 2)
+       if( dev_type != UVC_DEV_ISIGHT ){
+               if (len < 2 || data[0] < 2 || data[0] > len){
                        return -EINVAL;
-               flags = (data[3] == 0x11) ? data[2] : data[1];
-               is_header = 1;
+               }
+
+               hlen  = data[0];
+               flags = data[1];
+       }else{
+               if ((len >= 14 && memcmp (&data[3], hdr, 12) == 0) ||
+               (len >= 13 && memcmp (&data[2], hdr, 12) == 0)) {
+                       uvc_trace(UVC_TRACE_FRAME, "Detecting new header");
+                       hlen = (data[3] == 0x11) ? data[1] : data[0];
+                       if (hlen > len - 1 || hlen < 2)
+                               return -EINVAL;
+                       flags = (data[3] == 0x11) ? data[2] : data[1];
+                       is_header = 1;
+               }
        }
 
        /* Skip payloads marked with the error bit ("error frames"). */
@@ -1370,7 +1385,14 @@
        /* Copy the video data to the buffer. */
        len -= hlen;
        maxlen = buf->buf.length - buf->buf.bytesused;
-       if (!is_header) { /* we skip headers, they do not contain data */
+
+       if(dev_type != UVC_DEV_ISIGHT){
+               mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused;
+               nbytes = min(len, maxlen);
+               memcpy(mem, data + hlen, nbytes);
+               buf->buf.bytesused += nbytes;
+       }else if((dev_type == UVC_DEV_ISIGHT)&& (!is_header)) {
+               /* we skip headers, they do not contain data */
                mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused;
                nbytes = min(len - hlen, maxlen);
                memmove(mem, data + hlen, nbytes);
@@ -1378,11 +1400,19 @@
        }
 
        /* Drop the current frame if the buffer size was exceeded. */
-       if (len - hlen > maxlen || buf->buf.bytesused == buf->buf.length) {
-               uvc_trace(UVC_TRACE_FRAME, "Frame complete (overflow).\n");
-               buf->state = UVC_BUF_STATE_DONE;
+       if ( dev_type != UVC_DEV_ISIGHT ){
+               if (len > maxlen) {
+                       uvc_trace(UVC_TRACE_FRAME, "Frame complete 
(overflow).\n");
+                       buf->state = UVC_BUF_STATE_DONE;
+               }
+       }else{
+               if (len - hlen > maxlen || buf->buf.bytesused == 
buf->buf.length) {
+                       uvc_trace(UVC_TRACE_FRAME, "Frame complete 
(overflow).\n");
+                       buf->state = UVC_BUF_STATE_DONE;
+               }
        }
 
+
        /* Mark the buffer as done if the EOF marker is set. */
        if (hlen != 0 && (flags & UVC_STREAM_EOF && buf->buf.bytesused != 0)) {
                uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n");
@@ -3649,8 +3679,15 @@
                        }
                }
 
-               if (found)
+               if (found){
+                       if (dev->udev->descriptor.idVendor == 0x05ac &&
+                               dev->udev->descriptor.idProduct == 0x8501) {
+                               dev_type = UVC_DEV_ISIGHT ;
+                       }else{
+                               dev_type = UVC_DEV_QCAM_FUSION ;
+                       }
                        break;
+               }
        }
 
        if (!found) {
_______________________________________________
Linux-uvc-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel

Reply via email to