Hi,

> On Thursday 04 October 2007 16:33, Stefan Schweizer wrote:
>> Daniel M. Newman wrote:
>>> I've been looking for an up-to-date patch for the Macbook Pro built-in
>>> iSight camera, and the most recent I can find is against uvcvideo
>>> version 117.  It seems fairly incompatible with the current uvcvideo
>>> svn.  Can anyone point me to a patch for revision 132?
>> for revision 126:
>>
>> http://thread.gmane.org/gmane.linux.drivers.uvc.devel/1507/focus=1508
>>
>> I wonder why this patch does not get added to linux-uvc svn - I do not
>> think it is possible to compile it separate from linux-uvc.
Stefan I generated a patch against revision 132 you just have to apply
this patch to uvcvideo-svn and it should work.

> I can't apply the patch as-is. It must be ported to the SVN head first, and 
> some hardcoded assumptions must be removed. If someone wants to do the job, 
> and if we can find a way to integrate the patch without disturbing too much 
> the driver (other UVC devices must still work :-) ), I could apply it.
Laruent: That sounds good but unfortunately I am not a C programmer. The
attached patch certainly is nothing to apply as is.

Could you please comment on this oops. Is it a bug in the patch or in
the uvcvideo svn as "if (intf->cur_altsetting->desc.bInterfaceSubClass
!= SC_VIDEOSTREAMING)" is never hit? To fix it I commented out
"continue" around line 854.

 [14698.572000] BUG: unable to handle kernel NULL pointer dereference at
virtual address 00000004
[14698.572000]  printing eip:
[14698.572000] f8f26ee4
[14698.572000] *pde = 00000000
[14698.572000] Oops: 0002 [#1]
[14698.572000] SMP
[14698.572000] last sysfs file: /block/sdb/size
[14698.572000] Modules linked in: uvcvideo nls_iso8859_1 nls_cp437 vfat
fat usb_storage iptable_filter ip_tables ip6_tables x_tables wlan_tkip
wlan_ccmp af_packet snd_pcm_oss snd_mixer_oss snd_seq snd_seq_device
cpufreq_conservative cpufreq_userspace cpufreq_powersave acpi_cpufreq
speedstep_lib fuse dm_crypt loop dm_mod sha1 firmware_class
compat_ioctl32 videodev ohci1394 v4l1_compat joydev appletouch battery
ac button rtc_cmos rtc_core wlan_scan_sta ide_cd v4l2_common
snd_hda_intel rtc_lib ieee1394 appleir iTCO_wdt ath_rate_sample ath_pci
iTCO_vendor_support wlan intel_agp ath_hal(P) i2c_i801 i2c_core snd_pcm
snd_timer snd soundcore snd_page_alloc agpgart sky2 usbhid hid
ff_memless ehci_hcd uhci_hcd usbcore edd ext3 mbcache jbd fan ata_piix
libata piix thermal processor sr_mod cdrom ide_disk ide_core sd_mod sg
scsi_mod
[14698.572000] CPU:    0
[14698.572000] EIP:    0060:[<f8f26ee4>]    Tainted: P      N VLI
[14698.572000] EFLAGS: 00210246   (2.6.22.5-29-default #1)
[14698.572000] EIP is at uvc_ctrl_cleanup_device+0x18/0x6c [uvcvideo]
[14698.572000] eax: 00000000   ebx: f740b000   ecx: df9f8689   edx: 00000000
[14698.572000] esi: f740b000   edi: f740b028   ebp: 000000e0   esp: d4733cac
[14698.572000] ds: 007b   es: 007b   fs: 00d8  gs: 0033  ss: 0068
[14698.572000] Process modprobe (pid: 20551, ti=d4732000 task=e180d030
task.ti=d4732000)
[14698.572000] Stack: f740b014 f740b000 f740b028 f8f22871 f740b014
f8f22831 f740b000 000000e0
[14698.572000]        c01cdcb8 df9f8670 00000059 00000003 df9f8676
00000003 df9f868b f8f24272
[14698.572000]        00000040 00000001 00000000 df8bbe40 000005ac
00008501 00000000 f25454e4
[14698.572000] Call Trace:
[14698.572000]  [<f8f22871>] uvc_delete+0x40/0x96 [uvcvideo]
[14698.572000]  [<f8f22831>] uvc_delete+0x0/0x96 [uvcvideo]
[14698.572000]  [<c01cdcb8>] kref_put+0x60/0x6d
[14698.572000]  [<f8f24272>] uvc_probe+0x1978/0x19c2 [uvcvideo]
[14698.572000]  [<f90bdc29>] do_get_write_access+0x488/0x4b5 [jbd]
[14698.572000]  [<c016cb86>] cache_alloc_refill+0x76/0x4c1
[14698.572000]  [<c01a9397>] __sysfs_new_dirent+0x20/0x4a
[14698.572000]  [<c01a949c>] sysfs_make_dirent+0x29/0x35
[14698.572000]  [<c01aa277>] sysfs_create_link+0x128/0x141
[14698.572000]  [<f911f2fe>] usb_match_one_id+0x1c/0x71 [usbcore]
[14698.572000]  [<f911fe28>] usb_probe_interface+0x67/0x86 [usbcore]
[14698.572000]  [<c023ec4f>] driver_probe_device+0xc8/0x14b
[14698.572000]  [<c023edbb>] __driver_attach+0x52/0x87
[14698.572000]  [<c023e248>] bus_for_each_dev+0x30/0x51
[14698.572000]  [<c023eacc>] driver_attach+0x16/0x18
[14698.572000]  [<c023ed69>] __driver_attach+0x0/0x87
[14698.572000]  [<c023e4e8>] bus_add_driver+0x6d/0x17d
[14698.572000]  [<f911f991>] usb_register_driver+0x6d/0xd4 [usbcore]
[14698.572000]  [<f8eb106d>] uvc_init+0x6d/0x84 [uvcvideo]
[14698.572000]  [<c0140f5b>] sys_init_module+0x172c/0x1802
[14698.572000]  [<c016fbba>] do_sync_read+0x0/0x10a
[14698.572000]  [<c016fc81>] do_sync_read+0xc7/0x10a
[14698.572000]  [<c0104ea2>] syscall_call+0x7/0xb
[14698.572000]  [<c02c0000>] unix_release_sock+0x58/0x1d0
[14698.572000]  =======================
[14698.572000] Code: 83 c0 08 39 c2 75 b6 45 3b 6e 78 72 9c 58 5b 5e 5f
5d c3 57 56 53 89 c3 b8 38 d4 f2 f8 e8 dc e0 39 c7 8b 43 1c 8d 7b 28 8b
53 18 <89> 42 04 89 10 b8 38 d4 f2 f8 c7 43 18 00 01 10 00 c7 43 1c 00
[14698.572000] EIP: [<f8f26ee4>] uvc_ctrl_cleanup_device+0x18/0x6c
[uvcvideo] SS:ESP 0068:d4733cac

How should the occurrences of "if
(intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOSTREAMING)" be
modified?

I am willing to test everything.

Thanks Laurent and I hope you get it working Stefan
Felix Möller
Index: uvc_video.c
===================================================================
--- uvc_video.c	(Revision 132)
+++ uvc_video.c	(Arbeitskopie)
@@ -22,6 +22,7 @@
 #include <asm/atomic.h>
 
 #include "uvcvideo.h"
+#include "isight.h"
 
 /* ------------------------------------------------------------------------
  * UVC Controls
@@ -460,7 +461,21 @@
 				"lost (%d).\n", urb->iso_frame_desc[i].status);
 			continue;
 		}
+	    if (is_isight(urb->dev) == 0) {
+		do {
+			ret = isight_decode_video(queue, buf,
+				urb->transfer_buffer + urb->iso_frame_desc[i].offset,
+				urb->iso_frame_desc[i].actual_length);
 
+			if (buf == NULL)
+				break;
+
+			if (buf->state == UVC_BUF_STATE_DONE ||
+			    buf->state == UVC_BUF_STATE_ERROR)
+				buf = uvc_queue_next_buffer(queue, buf);
+		} while (ret == -EAGAIN);
+	    } else {
+
 		/* Decode the payload header. */
 		mem = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
 		do {
@@ -483,6 +498,7 @@
 		if (buf->state == UVC_BUF_STATE_DONE ||
 		    buf->state == UVC_BUF_STATE_ERROR)
 			buf = uvc_queue_next_buffer(queue, buf);
+	    }
 	}
 }
 
@@ -492,6 +508,19 @@
 	u8 *mem;
 	int len, ret;
 
+    if (is_isight(urb->dev) == 0) {
+	do {
+		ret = isight_decode_video(queue, buf,
+			urb->transfer_buffer, urb->actual_length);
+
+		if (buf == NULL)
+			break;
+
+		if (buf->state == UVC_BUF_STATE_DONE ||
+		    buf->state == UVC_BUF_STATE_ERROR)
+			buf = uvc_queue_next_buffer(queue, buf);
+	} while (ret == -EAGAIN);
+    } else {
 	mem = urb->transfer_buffer;
 	len = urb->actual_length;
 	queue->bulk.payload_size += len;
@@ -545,6 +574,7 @@
 		queue->bulk.skip_payload = 0;
 		queue->bulk.payload_size = 0;
 	}
+    }
 }
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
Index: isight.c
===================================================================
--- isight.c	(Revision 0)
+++ isight.c	(Revision 0)
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2006 Ivan N. Zlatev <[EMAIL PROTECTED]>
+ *
+ * Based on extract.c by Ronald S. Bultje <[EMAIL PROTECTED]>
+ * Firmware loading specifics by Johannes Berg <[EMAIL PROTECTED]>
+ * at http://johannes.sipsolutions.net/MacBook/iSight
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA
+ */
+
+#include <linux/usb.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/crypto.h>
+#include <linux/firmware.h>
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+
+#include "isight.h"
+#include "uvcvideo.h"
+
+#define isight_printk(msg...) \
+	printk(KERN_DEBUG "uvcvideo: iSight: " msg)
+
+#define TIMEOUT 300
+#define N_ELEMENT(array) (sizeof (array) / sizeof ((array)[0]))
+
+static const struct {
+	unsigned char sha1sum[20];
+	long offset;
+} offsets[] = {
+	{ { 0x86, 0x43, 0x0c, 0x04, 0xf9, 0xb6, 0x7c, 0x5c,
+		  0x3d, 0x84, 0x40, 0x91, 0x38, 0xa7, 0x67, 0x98,
+		  0x27, 0x02, 0x5e, 0xc2 }, 5172 /* 0x1434 */ },
+	{ { 0xa1, 0x4c, 0x15, 0x9b, 0x17, 0x6d, 0x27, 0xa6,
+		  0xe9, 0x8d, 0xcb, 0x5d, 0xea, 0x5d, 0x78, 0xb8,
+		  0x1e, 0x15, 0xad, 0x41 }, 9176 /* 0x23D8 */ },
+	{ { 0xc6, 0xc9, 0x4d, 0xd7, 0x7b, 0x86, 0x4f, 0x8b,
+		  0x2d, 0x31, 0xab, 0xf3, 0xcb, 0x2d, 0xe4, 0xc9,
+		  0xd1, 0x39, 0xe1, 0xbf }, 0x1434 },
+	{ { 0x01, 0xe2, 0x91, 0xd5, 0x29, 0xe7, 0xc1, 0x8d,
+		  0xee, 0xa2, 0xeb, 0xa2, 0x52, 0xd1, 0x81, 0x14,
+		  0xe0, 0x96, 0x27, 0x6e }, 0x2060 },
+};
+
+
+
+/* A record looks like:
+   __be16 data_length;
+   __be16 value;
+   __u8   data[data_length];
+ */
+
+static int isight_upload_firmware (struct usb_device *dev, 
+				   unsigned char *data, size_t size, long offset)
+{
+	int position = 0, success = 0;
+	int record_size, record_val, chunk_size;
+	unsigned char *chunk_ptr;
+	unsigned char *data_k;
+
+	if (offset > size) {
+		return -1;
+	}
+
+	data_k = kmalloc (size, GFP_KERNEL);
+	if (data_k == NULL) {
+		isight_printk ("Unable to kalloc memory. \n");
+		return -1;
+	}
+	memcpy (data_k, data, size);
+	data = data_k;
+
+	data += offset;
+
+	if (usb_control_msg (dev, usb_rcvctrlpipe (dev, 0), 0xA0, 0x40, 0xe600, 0, 
+				"\1", 1, TIMEOUT) < 0) {
+		isight_printk ("firmware loading init failed\n");
+		success = -1;
+		goto end;
+	}
+
+	while (1) {
+		if (position > size) {
+			goto end;
+		}
+
+		record_size = (data[position + 0] << 8) | data[position + 1];
+		record_val = (data[position + 2] << 8) | data[position + 3];
+
+		position += 4;
+
+		if (record_size == 0x8001) { /* success */
+			goto end;
+		} 
+		else if (record_size == 0) {
+			continue;
+		}
+	       	else if (record_size < 0 || record_size >= 1024 || 
+				position + record_size > size) {
+			isight_printk ("invalid firmware record_size: %X \n", record_size);
+			success = -1;
+			goto end;
+		}
+		
+		/* Upload to usb bus in 50 bytes chunks, 
+		   where the last can be less than 50
+		 */
+		
+		chunk_ptr = &data[position];
+		position += record_size;
+
+		while (record_size > 0) {
+			chunk_size = record_size > 50 ? 50 : record_size;
+			record_size -= chunk_size;
+			if (usb_control_msg (dev, usb_sndctrlpipe (dev, 0), 0xA0, 0x40,  
+						record_val, 0, chunk_ptr, chunk_size,
+					       	TIMEOUT) != chunk_size) {
+				isight_printk ("firmware upload failed.\n");
+				success = -1;
+				goto end;
+			}
+			chunk_ptr += chunk_size;
+			record_val += 50;
+		}
+	}
+
+end:
+	if (usb_control_msg (dev, usb_sndctrlpipe (dev, 0), 0xA0, 0x40, 0xe600, 0,
+				    "\0", 1, TIMEOUT) < 0) {
+		isight_printk ("firmware loading finish-up failed.\n");
+		success = -1;
+	}
+
+	kfree (data_k);
+	return success;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+static void isight_sha1 (char *result, unsigned char *data, int size)
+{
+	struct crypto_tfm *tfm;
+	struct scatterlist sg[1];
+
+	if (result == NULL)
+		return;
+	memset (result, 0x00, 20);
+	sg_set_buf (sg, data, size);
+	tfm = crypto_alloc_tfm ("sha1", 0);
+	
+	if (tfm != NULL) {
+		crypto_digest_init (tfm);
+		crypto_digest_update (tfm, sg, 1);
+		crypto_digest_final (tfm, result);
+		crypto_free_tfm (tfm);
+	}
+}
+#else
+static void isight_sha1 (char *result, unsigned char *data, int size)
+{
+       struct hash_desc desc;
+       struct scatterlist sg[1];
+
+       if (result == NULL)
+               return;
+       memset (result, 0x00, 20);
+       sg_set_buf (sg, data, size);
+
+       desc.tfm = crypto_alloc_hash ("sha1", 0, CRYPTO_ALG_ASYNC);
+       desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+
+       if (desc.tfm != NULL) {
+               crypto_hash_init (&desc);
+               crypto_hash_update (&desc, sg, size);
+               crypto_hash_final (&desc, result);
+               crypto_free_hash (desc.tfm);
+       }
+}
+#endif
+
+/* returns the offset where the firmware blob starts, else -1 */
+static long isight_extract_firmware_offset (unsigned char *data, size_t size)
+{
+	char sha1sum[20];
+	int i, offset;
+
+	if (data == NULL ||size <= 0) {
+		return -1;
+	}
+
+	isight_sha1 (sha1sum, data, size);
+
+	offset = -1;
+	for (i=0; i < N_ELEMENT (offsets); i++) {
+		if (memcmp (offsets[i].sha1sum, sha1sum, 20) == 0) {
+			offset = offsets[i].offset;
+			break;
+		}
+	}
+
+	return offset;
+}
+
+
+int isight_load_firmware (struct usb_device *dev)
+{
+	long offset;
+	size_t size;
+	int success = -1;
+	const struct firmware *fw;
+	unsigned char *data_k = NULL;
+
+
+	if (dev->descriptor.idVendor == 0x05ac &&
+	    dev->descriptor.idProduct == 0x8300 &&
+	    dev->descriptor.bDeviceClass == 0xff &&
+	    dev->descriptor.bDeviceSubClass == 0xff &&
+	    dev->descriptor.bDeviceProtocol == 0xff) {
+
+		/* request firmware using the firmware_class kernel interface */
+		if (request_firmware (&fw, "AppleUSBVideoSupport", &dev->dev) != 0 ) {
+			isight_printk ("firmware file AppleUSBVideoSupport not found.\n");
+			return -1;
+		}
+		
+		/* copy to kernel memory - required*/
+		data_k = kmalloc (fw->size, GFP_KERNEL);
+		if (data_k == NULL) {
+			isight_printk ("can't kalloc memory.");
+			return -1;
+		}
+		memcpy (data_k, fw->data, fw->size);
+		size = fw->size;
+		release_firmware (fw);
+
+		offset = isight_extract_firmware_offset (data_k, size);
+		if (offset == -1) {
+			isight_printk ("invalid firmware file\n");
+		} 
+		else {
+			if (isight_upload_firmware (dev, data_k, size, offset) == 0) {
+				isight_printk ("firmware successfully loaded.\n");
+				success = 0;
+			}
+		}
+		kfree (data_k);
+	} 
+	else if (dev->descriptor.idVendor == 0x05ac &&
+	    	 dev->descriptor.idProduct == 0x8501) {
+		isight_printk ("firmware already loaded.\n");
+		success = 0;
+	}
+
+	return success;
+}
+
+
+int isight_decode_video (struct uvc_video_queue *queue, struct uvc_buffer *buf, 
+		const __u8 *data, unsigned int len)
+{
+	static const __u8 hdr[] = {
+		0x11, 0x22, 0x33, 0x44, 0xde, 0xad, 0xbe, 0xef,
+		0xde, 0xad, 0xfa, 0xce
+	};
+
+	unsigned int maxlen, nbytes;
+	__u8 *mem;
+	int is_header = 0;
+
+	if (buf == NULL)
+		return 0;
+
+	/* Built-in iSight webcams are completely broken. They implement most
+	 * of UVC 1.0, but the Apple engineers decided to use a completely
+	 * different packet format, although the video data is in YUV. Were
+	 * they on crack or just lazy ? As the hardware is 8051-based, it
+	 * might be interesting to write an open-source firmware.
+	 *
+	 * Instead of sending a header at the beginning of each isochronous
+	 * transfer payload, the webcam sends a single header per image (on
+	 * its own in a packet), followed by packets containing data only.
+	 *
+	 * Offset	Size (bytes)	Description
+	 * ------------------------------------------------------------------
+	 * 0x00		1		Header length
+	 * 0x01		1		Flags (UVC-compliant)
+	 * 0x02		4		Always equal to '11223344'
+	 * 0x06		8		Always equal to 'deadbeefdeadface'
+	 * 0x0e		16		Unknown
+	 *
+	 * The header can be prefixed by an optional, unknown-purpose byte.
+	 */
+
+	/* Detect the packet type. */
+	if ((len >= 14 && memcmp (&data[2], hdr, 12) == 0) ||
+	    (len >= 15 && memcmp (&data[3], hdr, 12) == 0)) {
+		uvc_trace(UVC_TRACE_FRAME, "iSight header found\n");
+		is_header = 1;
+	}
+
+	/* Synchronize to the input stream by waiting for a header packet. */
+	if (buf->state != UVC_BUF_STATE_ACTIVE) {
+		if (!is_header) {
+			uvc_trace(UVC_TRACE_FRAME, "Dropping packet (out of "
+				"sync).\n");
+			return 0;
+		}
+
+		buf->state = UVC_BUF_STATE_ACTIVE;
+	}
+
+	/* Mark the buffer as done if we're at the beginning of a new frame.
+	 *
+	 * Empty buffers (bytesused == 0) don't trigger end of frame detection
+	 * as it doesn't make sense to return an empty buffer.
+	 */
+	if (is_header && buf->buf.bytesused != 0) {
+		buf->state = UVC_BUF_STATE_DONE;
+		return -EAGAIN;
+	}
+
+	/* Copy the video data to the buffer. Skip header packets, as they
+	 * contain no data.
+	 */
+	if (!is_header) {
+		maxlen = buf->buf.length - buf->buf.bytesused;
+		mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused;
+		nbytes = min(len, maxlen);
+		memcpy(mem, data, nbytes);
+		buf->buf.bytesused += nbytes;
+
+		/* Drop the current frame if the buffer size was exceeded. */
+		if (len > maxlen || buf->buf.bytesused == buf->buf.length) {
+			uvc_trace(UVC_TRACE_FRAME, "Frame complete (overflow).\n");
+			buf->state = UVC_BUF_STATE_DONE;
+		}
+	}
+
+	return 0;
+}
+
+int is_isight (struct usb_device *dev)
+{
+	if (dev->descriptor.idVendor == 0x05ac &&
+	     (dev->descriptor.idProduct == 0x8300) &&
+	    dev->descriptor.bDeviceClass == 0xff &&
+	    dev->descriptor.bDeviceSubClass == 0xff &&
+	    dev->descriptor.bDeviceProtocol == 0xff) {
+		return 0;
+	} 
+	else if (dev->descriptor.idVendor == 0x05ac &&
+			dev->descriptor.idProduct == 0x8501) {
+		return 0;
+	}
+	return -1;
+}
Index: uvc_driver.c
===================================================================
--- uvc_driver.c	(Revision 132)
+++ uvc_driver.c	(Arbeitskopie)
@@ -43,6 +43,7 @@
 #endif
 
 #include "uvcvideo.h"
+#include "isight.h"
 
 #define DRIVER_AUTHOR		"Laurent Pinchart <[EMAIL PROTECTED]>"
 #define DRIVER_DESC		"USB Video Class driver"
@@ -83,6 +84,11 @@
 		.guid		= UVC_GUID_FORMAT_UYVY,
 		.fcc		= V4L2_PIX_FMT_UYVY,
 	},
+	{
+		.name		= "YUV 4:2:2 (MACOSX)",
+		.guid		= UVC_GUID_FORMAT_YUY2_MACOSX,
+		.fcc		= V4L2_PIX_FMT_UYVY,
+	},
 };
 
 #if 0
@@ -845,9 +851,8 @@
 						"interface %d isn't a video "
 						"streaming interface\n",
 						udev->devnum, i);
-					continue;
+//					continue;
 				}
-
 				if (usb_interface_claimed(intf)) {
 					uvc_trace(UVC_TRACE_DESCR, "device %d "
 						"interface %d is already claimed\n",
@@ -1503,6 +1508,16 @@
 	kfree(dev);
 }
 
+static int uvc_load_firmware (struct usb_device *dev)
+{
+	int success = 0;
+
+	if (is_isight (dev) == 0) {
+		success = isight_load_firmware (dev);
+	}
+	return success;
+}
+
 static int uvc_probe(struct usb_interface *intf,
 		     const struct usb_device_id *id)
 {
@@ -1522,6 +1537,9 @@
 	if ((dev = kzalloc(sizeof *dev, GFP_KERNEL)) == NULL)
 		return -ENOMEM;
 
+	if (uvc_load_firmware (udev) < 0)
+		return -ENODEV;
+
 	INIT_LIST_HEAD(&dev->entities);
 	INIT_LIST_HEAD(&dev->streaming);
 	kref_init(&dev->kref);
@@ -1578,7 +1596,7 @@
 	 */
 	usb_set_intfdata(intf, NULL);
 
-	if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOSTREAMING)
+//	if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOSTREAMING)
 		return;
 
 	/* uvc_v4l2_open() might race uvc_disconnect(). A static driver-wide
@@ -1605,9 +1623,9 @@
 
 	uvc_trace(UVC_TRACE_SUSPEND, "Suspending interface %u\n",
 		intf->cur_altsetting->desc.bInterfaceNumber);
-
+	
 	/* Controls are cached on the fly so they don't need to be saved. */
-	if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL)
+// 	if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL)
 		return 0;
 
 	if (dev->video.streaming->intf != intf) {
@@ -1626,7 +1644,7 @@
 	uvc_trace(UVC_TRACE_SUSPEND, "Resuming interface %u\n",
 		intf->cur_altsetting->desc.bInterfaceNumber);
 
-	if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL)
+//	if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL)
 		return uvc_ctrl_resume_device(dev);
 
 	if (dev->video.streaming->intf != intf) {
@@ -1755,6 +1773,22 @@
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_PROBE_MINMAX
 	},
+	/* Apple Built-In iSight - with firmware loaded */
+	{ .match_flags          = USB_DEVICE_ID_MATCH_DEVICE,
+	  .idVendor             = 0x05ac,
+	  .idProduct            = 0x8501,
+	  .driver_info          = UVC_QUIRK_PROBE_MINMAX
+	},
+	/* Apple Built-In iSight - no firmware loaded */
+	{ .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
+				  | USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor             = 0x05ac,
+	  .idProduct            = 0x8300,
+	  .bInterfaceClass      = USB_CLASS_VENDOR_SPEC,
+	  .bInterfaceSubClass   = 0xff,
+	  .bInterfaceProtocol   = 0xff,
+	  .driver_info          = UVC_QUIRK_PROBE_MINMAX
+	},
 	/* Generic USB Video Class */
 	{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
 	{}
Index: uvcvideo.h
===================================================================
--- uvcvideo.h	(Revision 132)
+++ uvcvideo.h	(Arbeitskopie)
@@ -282,6 +282,8 @@
 				 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
 #define UVC_GUID_FORMAT_UYVY	{ 'U',  'Y',  'V',  'Y', 0x00, 0x00, 0x10, 0x00, \
 				 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_YUY2_MACOSX	{ 'Y',  'U',  'Y',  '2', 0x00, 0x00, 0x10, 0x00, \
+				 0x00, 0x80, 0x71, 0x9b, 0x38, 0x00, 0xaa, 0x00}
 
 
 /* ------------------------------------------------------------------------
Index: Makefile
===================================================================
--- Makefile	(Revision 132)
+++ Makefile	(Arbeitskopie)
@@ -5,7 +5,7 @@
 PWD		:= $(shell pwd)
 
 obj-m		:= uvcvideo.o
-uvcvideo-objs   := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o
+uvcvideo-objs   := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o isight.o
 
 all: uvcvideo
 
Index: isight.h
===================================================================
--- isight.h	(Revision 0)
+++ isight.h	(Revision 0)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2006 Ivan N. Zlatev <[EMAIL PROTECTED]>
+ *
+ * Based on extract.c by Ronald S. Bultje <[EMAIL PROTECTED]>
+ * Firmware loading specifics by Johannes Berg <[EMAIL PROTECTED]>
+ * at http://johannes.sipsolutions.net/MacBook/iSight
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA
+ */
+
+#ifndef _ISIGHT_H_
+#define _ISIGHT_H_
+
+#include <linux/usb.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/crypto.h>
+#include <linux/firmware.h>
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+
+#include "uvcvideo.h"
+
+int is_isight (struct usb_device *dev);
+int isight_load_firmware (struct usb_device *dev);
+int isight_decode_video (struct uvc_video_queue *, struct uvc_buffer *, const __u8 *data, unsigned int len);
+
+#endif
+
_______________________________________________
Linux-uvc-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel

Reply via email to