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