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