Update to new source with new isight version. Thanks to Philippe Marti <philippe...
authorStefan Schweizer <genstef@gentoo.org>
Mon, 4 Dec 2006 18:47:56 +0000 (18:47 +0000)
committerStefan Schweizer <genstef@gentoo.org>
Mon, 4 Dec 2006 18:47:56 +0000 (18:47 +0000)
Package-Manager: portage-2.1.2_rc2-r5

media-video/linux-uvc/ChangeLog
media-video/linux-uvc/Manifest
media-video/linux-uvc/files/digest-linux-uvc-0.1.0e [new file with mode: 0644]
media-video/linux-uvc/files/isight.patch [new file with mode: 0644]
media-video/linux-uvc/linux-uvc-0.1.0e.ebuild [new file with mode: 0644]

index eba9aef14148b5e30577a3ce828646468fadb835..ef6d776aecc47074fa006fe57b37efd6bc919da8 100644 (file)
@@ -1,6 +1,13 @@
 # ChangeLog for media-video/linux-uvc
 # Copyright 1999-2006 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/media-video/linux-uvc/ChangeLog,v 1.5 2006/10/13 12:30:27 blubb Exp $
+# $Header: /var/cvsroot/gentoo-x86/media-video/linux-uvc/ChangeLog,v 1.6 2006/12/04 18:47:56 genstef Exp $
+
+*linux-uvc-0.1.0e (04 Dec 2006)
+
+  04 Dec 2006; Stefan Schweizer <genstef@gentoo.org> +files/isight.patch,
+  +linux-uvc-0.1.0e.ebuild:
+  Update to new source with new isight version. Thanks to Philippe Marti
+  <philippe.marti@gmail.com> in bug 157022
 
   13 Oct 2006; Simon Stelling <blubb@gentoo.org>
   linux-uvc-0.0.1_pre51.ebuild:
index 99701d7970bc54c8d3693da33ddc0777c736e29f..95752aa976678050f09f763ded9b3f2713298f13 100644 (file)
@@ -2,19 +2,28 @@ AUX 41-001-isight.patch 13123 RMD160 1a780ddfaaa60db6b2ac2741a94327850c8b37af SH
 MD5 f5b1df5db31a07bde88226cb90f2332c files/41-001-isight.patch 13123
 RMD160 1a780ddfaaa60db6b2ac2741a94327850c8b37af files/41-001-isight.patch 13123
 SHA256 65aaa98ec517f12ccf51341c753823135ba3454b9b2b20345b5128050d5d81d1 files/41-001-isight.patch 13123
+AUX isight.patch 14724 RMD160 e795c48822ab04d025318ac0be1b91659fdf0ff7 SHA1 166b63a6d862535c7c33653df72381b299c60115 SHA256 be30a6d2dfcce7a9b81528342f9a7e7d92e3f1e908a6569aeb14d87af5206c75
+MD5 d68a691d070fc96bafe658cc96c5c2c1 files/isight.patch 14724
+RMD160 e795c48822ab04d025318ac0be1b91659fdf0ff7 files/isight.patch 14724
+SHA256 be30a6d2dfcce7a9b81528342f9a7e7d92e3f1e908a6569aeb14d87af5206c75 files/isight.patch 14724
 AUX uvc-2.6.18.diff 3244 RMD160 6788ce3caa061f2371d79da7dcb5e2376185d9ad SHA1 b215834f643f94c4cd4d791caa7c082120fd29e0 SHA256 15083d47f21f38d1288e77060660c4c69123aa0545fb9d6e1a36173600be9ef1
 MD5 c6f79bef00ad99972c3630991c78c1af files/uvc-2.6.18.diff 3244
 RMD160 6788ce3caa061f2371d79da7dcb5e2376185d9ad files/uvc-2.6.18.diff 3244
 SHA256 15083d47f21f38d1288e77060660c4c69123aa0545fb9d6e1a36173600be9ef1 files/uvc-2.6.18.diff 3244
 DIST linux-uvc-0.0.1_pre51.tar.bz2 25114 RMD160 37f7f314eff9a22b3b2b3bfaa160290018de526b SHA1 d590e25694e857a7d74d584138b069c6f062c7db SHA256 f66f162528332a819d3facf28ebc6ae1f8f5fa85799c06f43f5c7fc952fc1c07
+DIST linux-uvc-0.1.0-e.tar.gz 30756 RMD160 f1140ade7aa4cf64397d795cc09778953721b208 SHA1 367210a20d711eb2242835042e8518882463c910 SHA256 ca6db3bc99879f9f327c10c4052e38479eea588d29804956a25a66ef0de19e08
 EBUILD linux-uvc-0.0.1_pre51.ebuild 2069 RMD160 075bfe8436075e1ccf9db5a8278b3ba3cb2ce078 SHA1 4bd35738ac66a030ea93969bc7c56a42c382b288 SHA256 373040c44726cabfad5e3dbd453b4c24dc6ca04ebf2f7071f49780071ca6b410
 MD5 046863170d3d7ba09208c399943bbd26 linux-uvc-0.0.1_pre51.ebuild 2069
 RMD160 075bfe8436075e1ccf9db5a8278b3ba3cb2ce078 linux-uvc-0.0.1_pre51.ebuild 2069
 SHA256 373040c44726cabfad5e3dbd453b4c24dc6ca04ebf2f7071f49780071ca6b410 linux-uvc-0.0.1_pre51.ebuild 2069
-MISC ChangeLog 1211 RMD160 dbd335f9572f25de73c026eb2b74bf81bd5af1e8 SHA1 c5f2dd076077e2b3d5b4f2ac5e32d06b00f416cc SHA256 3099e598c59c1a63719ffaf4aa96abc3cbfaab9ffd974a1d1523d8baec8f2976
-MD5 579a15f3e1d926371e9b9f844674ff18 ChangeLog 1211
-RMD160 dbd335f9572f25de73c026eb2b74bf81bd5af1e8 ChangeLog 1211
-SHA256 3099e598c59c1a63719ffaf4aa96abc3cbfaab9ffd974a1d1523d8baec8f2976 ChangeLog 1211
+EBUILD linux-uvc-0.1.0e.ebuild 1936 RMD160 a24176de48b5e1d7794b927c7af77cf4d75caee9 SHA1 6bd03d3ebd8f29639fa4721f8ff95005a05bb907 SHA256 5cd6830a7e8be6ea58703593309879967f2dadff3a921a93952cc4459cb99a0b
+MD5 7de2132d6062239975f563167b4147b2 linux-uvc-0.1.0e.ebuild 1936
+RMD160 a24176de48b5e1d7794b927c7af77cf4d75caee9 linux-uvc-0.1.0e.ebuild 1936
+SHA256 5cd6830a7e8be6ea58703593309879967f2dadff3a921a93952cc4459cb99a0b linux-uvc-0.1.0e.ebuild 1936
+MISC ChangeLog 1465 RMD160 776297ef99180eef3616f2f89b7bdf732b8ae8e3 SHA1 f8af3f0edae8bc8f47a5ef4c2a47b649d5877635 SHA256 e22c87c51db97dfd8b1df8ae25ee2906933498c402c940a2bd27601264bac166
+MD5 e617410a9754d542ba57b7065705800e ChangeLog 1465
+RMD160 776297ef99180eef3616f2f89b7bdf732b8ae8e3 ChangeLog 1465
+SHA256 e22c87c51db97dfd8b1df8ae25ee2906933498c402c940a2bd27601264bac166 ChangeLog 1465
 MISC metadata.xml 201 RMD160 cab717fcec0a2c638d65949ef3fbbc7178b7d9ca SHA1 18c17ef2d08198657f786bff811e74e03edcf296 SHA256 07bcae025fd428cc29b1b0ed914d6014ef3e95344562d6b464ca5f773defa8ee
 MD5 e17250777e685637b92f26f197959acc metadata.xml 201
 RMD160 cab717fcec0a2c638d65949ef3fbbc7178b7d9ca metadata.xml 201
@@ -22,3 +31,6 @@ SHA256 07bcae025fd428cc29b1b0ed914d6014ef3e95344562d6b464ca5f773defa8ee metadata
 MD5 1ba7a95a5d43b8a2260ae165b80bb70e files/digest-linux-uvc-0.0.1_pre51 265
 RMD160 0786a3afcc24afa8a239f60ad722345bee7b264a files/digest-linux-uvc-0.0.1_pre51 265
 SHA256 885b9618aa6d97d7f43f39b790ba5d1cb3795e8f03b1638716a93b0debca58bf files/digest-linux-uvc-0.0.1_pre51 265
+MD5 4db566b314d8cece23e84e6295828643 files/digest-linux-uvc-0.1.0e 250
+RMD160 f4a198bd9db02bbd0a32808aa80b63191ce79cf1 files/digest-linux-uvc-0.1.0e 250
+SHA256 94fd9a8de4f382629d5b1ee5e9dd2f7b3d0601cd5dd37606223a815603eae5a6 files/digest-linux-uvc-0.1.0e 250
diff --git a/media-video/linux-uvc/files/digest-linux-uvc-0.1.0e b/media-video/linux-uvc/files/digest-linux-uvc-0.1.0e
new file mode 100644 (file)
index 0000000..400c7b3
--- /dev/null
@@ -0,0 +1,3 @@
+MD5 41f52c0476928d7f99e56f0b7b08355b linux-uvc-0.1.0-e.tar.gz 30756
+RMD160 f1140ade7aa4cf64397d795cc09778953721b208 linux-uvc-0.1.0-e.tar.gz 30756
+SHA256 ca6db3bc99879f9f327c10c4052e38479eea588d29804956a25a66ef0de19e08 linux-uvc-0.1.0-e.tar.gz 30756
diff --git a/media-video/linux-uvc/files/isight.patch b/media-video/linux-uvc/files/isight.patch
new file mode 100644 (file)
index 0000000..0913299
--- /dev/null
@@ -0,0 +1,486 @@
+Index: uvcvideo.c
+===================================================================
+--- uvcvideo.c (revision 40)
++++ uvcvideo.c (working copy)
+@@ -49,7 +49,7 @@
+ #define DRIVER_AUTHOR         "Laurent Pinchart <laurent.pinchart@skynet.be>"
+ #define DRIVER_DESC           "USB Video Class driver"
+-#define DRIVER_VERSION                "0.1.0"
++#define DRIVER_VERSION                "0.1.0-e"
+ #define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 1, 0)
+ #define UVC_CTRL_TIMEOUT      300
+@@ -73,6 +73,10 @@
+                                0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+ #define UVC_GUID_FORMAT_YUY2  {0x59, 0x55, 0x59, 0x32, 0x00, 0x00, 0x10, 0x00, \
+                                0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
++#define UVC_GUID_FORMAT_YUY2A {0x59, 0x55, 0x59, 0x32, 0x00, 0x00, 0x10, 0x00, \
++                               0x00, 0x80, 0x71, 0x9b, 0x38, 0x00, 0xaa, 0x00}
++#define UVC_GUID_FORMAT_UYVY    {0x55, 0x59, 0x56, 0x59, 0x00, 0x00, 0x10, 0x00, \
++                               0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+ #define UVC_GUID_FORMAT_NV12  {0x4e, 0x56, 0x31, 0x32, 0x00, 0x00, 0x10, 0x00, \
+                                0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+@@ -564,10 +568,14 @@
+               .fcc            = V4L2_PIX_FMT_YUYV,
+       },
+       {
+-              .guid           = UVC_GUID_FORMAT_YUY2,
+-              .fcc            = V4L2_PIX_FMT_YUYV,
++              .guid           = UVC_GUID_FORMAT_YUY2A,
++              .fcc            = V4L2_PIX_FMT_UYVY,
+       },
+       {
++              .guid           = UVC_GUID_FORMAT_UYVY,
++              .fcc            = V4L2_PIX_FMT_UYVY,
++      },
++      {
+               .guid           = UVC_GUID_FORMAT_NV12,
+               .fcc            = V4L2_PIX_FMT_NV12,
+       },
+@@ -1271,24 +1279,38 @@
+               struct uvc_buffer *buf, const __u8 *data, unsigned int len)
+ {
+       unsigned int maxlen, nbytes;
+-      void *mem;
+-      __u8 fid;
++      __u8 *mem;
++      __u8 fid = queue->last_fid;
++      int hlen = 0, flags = 0, is_header = 0;
++      static const __u8 hdr[] = { 0x11, 0x22, 0x33, 0x44,
++                                  0xde, 0xad, 0xbe, 0xef,
++                                  0xde, 0xad, 0xfa, 0xce };
+       /* Sanity checks:
+        * - packet must be at least 2 bytes long
+        * - bHeaderLength value must be at least 2 bytes (see above)
+        * - bHeaderLength value can't be larger than the packet size.
+        */
+-      if (len < 2 || data[0] < 2 || data[0] > len)
+-              return -EINVAL;
++      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"). */
+-      if (data[1] & UVC_STREAM_ERR) {
++      if (hlen != 0 && flags & UVC_STREAM_ERR) {
+               uvc_trace(UVC_TRACE_FRAME, "Dropping packet (error bit set).\n");
+-              return 0;
++
++              //return 0;
+       }
+-      fid = data[1] & UVC_STREAM_FID;
++      if (hlen != 0) {
++              fid = flags & UVC_STREAM_FID;
++      }
+       /* Store the packet FID bit and return immediately when the buffer is
+        * NULL.
+@@ -1334,28 +1356,33 @@
+                               "toggled).\n");
+               buf->state = UVC_BUF_STATE_DONE;
+               return -EAGAIN;
++      } else if (is_header && buf->buf.bytesused > 0) {
++              buf->state = UVC_BUF_STATE_DONE;
++              return -EAGAIN;
+       }
+       queue->last_fid = fid;
+       /* Copy the video data to the buffer. */
+-      len -= data[0];
++      len -= hlen;
+       maxlen = buf->buf.length - buf->buf.bytesused;
+-      mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused;
+-      nbytes = min(len, maxlen);
+-      memcpy(mem, data + data[0], nbytes);
+-      buf->buf.bytesused += nbytes;
++      if (!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);
++              buf->buf.bytesused += nbytes;
++      }
+       /* Drop the current frame if the buffer size was exceeded. */
+-      if (len > maxlen) {
++      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 (data[1] & UVC_STREAM_EOF && buf->buf.bytesused != 0) {
++      if (hlen != 0 && (flags & UVC_STREAM_EOF && buf->buf.bytesused != 0)) {
+               uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n");
+-              if (data[0] == len)
++              if (hlen != 0 && hlen == len)
+                       printk("EOF in empty packet.\n");
+               buf->state = UVC_BUF_STATE_DONE;
+       }
+@@ -1593,7 +1620,7 @@
+       if (ret != size) {
+               uvc_printk(KERN_ERR, "Failed to query (%u) UVC control %u "
+-                      "(unit %u) : %d.\n", query, cs, unit, ret);
++                      "(unit %u) : %d (exp: %u).\n", query, cs, unit, ret, size);
+               return -EIO;
+       }
+@@ -1883,8 +1910,10 @@
+       /* Get the minimum and maximum values for compression settings. */
+       if ((ret = uvc_get_video_ctrl(video, &probe_min, 1, GET_MIN)) < 0 ||
+-          (ret = uvc_get_video_ctrl(video, &probe_max, 1, GET_MAX)) < 0)
++          (ret = uvc_get_video_ctrl(video, &probe_max, 1, GET_MAX)) < 0) {
++              ret = 0;
+               goto done;
++      }
+       probe->wCompQuality = probe_max.wCompQuality;
+@@ -1942,7 +1971,7 @@
+               return ret;
+       /* Retrieve the default format and commit it. */
+-      if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_DEF)) < 0)
++      if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0)
+               return ret;
+       if ((ret = uvc_set_video_ctrl(video, probe, 0)) < 0)
+               return ret;
+@@ -2214,6 +2243,11 @@
+       if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0)
+               return ret;
++      if (probe.dwMaxVideoFrameSize == 0)
++              probe.dwMaxVideoFrameSize =
++                      video->streaming->format[probe.bFormatIndex - 1].
++                              frame[probe.bFrameIndex - 1].dwMaxVideoFrameBufferSize;
++
+       memcpy(&video->streaming->ctrl, &probe, sizeof probe);
+       video->streaming->cur_format = format;
+       video->streaming->cur_frame = frame;
+@@ -3506,6 +3540,13 @@
+       if (!found) {
+               uvc_printk(KERN_INFO, "No valid video chain found.\n");
++              if (dev->udev->descriptor.idVendor == 0x05ac &&
++                  dev->udev->descriptor.idProduct == 0x8300) {
++                      uvc_printk (KERN_ERR, "Possible an Apple iSight "
++                                  "without firmware loaded; please read "
++                                  "the documentation, load the firmware "
++                                  "and re-load the driver.");
++              }
+               return -1;
+       }
+@@ -3757,6 +3798,19 @@
+         .bInterfaceClass      = USB_CLASS_VENDOR_SPEC,
+         .bInterfaceSubClass   = 1,
+         .bInterfaceProtocol   = 0 },
++      /* Apple iSight (built-in in Macintels) */
++      { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE,
++        .idVendor             = 0x05ac,
++        .idProduct            = 0x8501 },
++      /* same, but without firmware loaded (will give useful warning)
++       * when the firmware is not loaded in the pre-instal step). */
++      { .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 },
+       /* Generic USB Video Class */
+       { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
+       {}
+Index: Makefile
+===================================================================
+--- Makefile   (revision 40)
++++ Makefile   (working copy)
+@@ -1,7 +1,7 @@
+ KERNEL_VERSION        := `uname -r`
+ KERNEL_DIR    := /lib/modules/$(KERNEL_VERSION)/build
+ INSTALL_MOD_DIR       := usb/media
+-
++DRIVER_VERSION        := `grep DRIVER_VERSION uvcvideo.c | grep define | grep -v DRIVER_VERSION_NUMBER | cut -d"\"" -f2`
+ PWD           := $(shell pwd)
+ obj-m         := uvcvideo.o
+@@ -9,7 +9,7 @@
+ %.o : %.c
+       gcc $(TEST_CFLAGS) -c -o $@ $<
+-all: uvcvideo
++all: uvcvideo extract
+ uvcvideo:
+       @echo "Building USB Video Class driver..."
+@@ -24,3 +24,12 @@
+       -rm -f *.o *.ko .*.cmd .*.flags *.mod.c Modules.symvers
+       -rm -rf .tmp_versions
++extract: extract.c
++      gcc -Wall -g `pkg-config --cflags --libs libusb glib-2.0` -lgcrypt -o extract extract.c
++
++dist:
++      rm -fr linux-uvc-${DRIVER_VERSION}
++      mkdir linux-uvc-${DRIVER_VERSION}
++      cp uvcvideo.[ch] Makefile extract.c linux-uvc-${DRIVER_VERSION}/
++      tar -zcf linux-uvc-${DRIVER_VERSION}.tar.gz linux-uvc-${DRIVER_VERSION}
++      rm -fr linux-uvc-${DRIVER_VERSION}
+--- /extract.c
++++ extract.c
+@@ -0,0 +1,243 @@
++/*
++ * Apple iSight (the one built in the screen of Macbooks) firmware loader
++ * Copyright (C) 2006 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
++ *
++ * Special thanks to Johannes Berg <johannes@sipsolutions.net> for helping
++ * to find out how to load the firmware; see his website on
++ * http://johannes.sipsolutions.net/MacBook/iSight for details.
++ * Basic structure of firmware data: <len:2><off:2><data:len>, where
++ * the $data of size $len is to be put at position $off in the device.
++ *
++ * 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 <stdlib.h>
++#include <stdio.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <errno.h>
++#include <string.h>
++#include <gcrypt.h>
++#include <glib.h>
++
++#include <usb.h>
++#define TIMEOUT 300
++
++static int
++read_fw (struct usb_dev_handle *dev, char *filename, long off)
++{
++      int fd, len, req, llen, res, ret = -1;
++      unsigned char data[4], rdata[1024], *ptr;
++
++      if ((fd = open (filename, O_RDONLY)) == -1) {
++              perror ("Opening file");
++              return -1;
++      } else if (lseek (fd, off, SEEK_SET) != off) {
++              perror ("Seeking");
++              close (fd);
++              return -1;
++      }
++
++      if ((res = usb_control_msg (dev, 0x40, 0xA0, 0xe600, 0,
++                                  "\1", 1, TIMEOUT)) != 1) {
++              perror ("Firmware load init failed");
++              close (fd);
++              return -1;
++      }
++      while (1) {
++              if ((len = read (fd, data, 4)) != 4) {
++                      if (len == 0) {
++                              fprintf (stderr,
++                                       "Unexpected eos - corrupt driver?\n");
++                              goto end;
++                      } else {
++                              perror("Reading firmware header chunk failed");
++                              goto end;
++                      }
++              }
++              len = (data[0] << 8) | data[1];
++              req = (data[2] << 8) | data[3];
++              if (len == 0x8001)
++                      break; /* success */
++              else if (len == 0)
++                      continue;
++              else if (len < 0 || len >= 1024) {
++                      fprintf (stderr,
++                               "Invalid firmware data_length %d, load aborted\n",
++                               len);
++                      goto end;
++              } else if (read (fd, rdata, len) != len) {
++                      perror ("Error reading firmware data");
++                      goto end;
++              }
++
++              /* upload to usb bus */
++              for (ptr = rdata; len > 0; req += 50, ptr += 50) {
++                      llen = len > 50 ? 50 : len;
++                      len -= llen;
++
++                      if ((res = usb_control_msg (dev, 0x40, 0xA0, req, 0,
++                                                  (char *) ptr, llen,
++                                                  TIMEOUT)) != llen) {
++                              fprintf (stderr,
++                                       "firmware load req=0x%x failed: %s\n",
++                                       req, strerror (errno));
++                              goto end;
++                      }
++              }
++      }
++
++      ret = 0;
++end:
++      if ((res = usb_control_msg (dev, 0x40, 0xA0, 0xe600, 0,
++                                  "\0", 1, TIMEOUT)) != 1) {
++              perror ("Firmware finish-up failed");
++              ret = -1;
++      }
++
++      close (fd);
++
++      return ret;
++}
++
++static int
++probe_dev (struct usb_device *dev, char *fw_filename, long off)
++{
++      int n, total = 0, res;
++
++      if (dev->descriptor.idVendor == 0x05ac &&
++          dev->descriptor.idProduct == 0x8300 &&
++          dev->descriptor.bDeviceClass == 0xff &&
++          dev->descriptor.bDeviceSubClass == 0xff &&
++          dev->descriptor.bDeviceProtocol == 0xff) {
++              usb_dev_handle *h;
++
++              /* load firmware */
++              if (!(h = usb_open (dev))) {
++                      perror ("Opening iSight");
++                      return -1;
++              }
++              printf ("Loading firmware for iSight...\n");
++              if (read_fw (h, fw_filename, off) == 0) {
++                      printf ("done\n");
++                      total++;
++              }
++              usb_close (h);
++      } else if (dev->descriptor.idVendor == 0x05ac &&
++                 dev->descriptor.idProduct == 0x8501) {
++              printf ("Apple iSight with firmware already loaded found\n");
++              total++;
++      }
++
++      for (n = 0; n < dev->num_children; n++) {
++              res = probe_dev (dev->children[n], fw_filename, off);
++              if (res != -1)
++                      total += res;
++      }
++
++      return total;
++}
++
++int
++main (int argc, char *argv[])
++{
++      int n, found = 0, res, err = 0;
++      unsigned char *digest;
++      GMappedFile *file;
++      GError *gerr = NULL;
++      struct usb_bus *bus;
++      struct usb_device *dev;
++      static const struct {
++              unsigned char sha1sum[20];
++              long off;
++      } 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 },
++      }, *offset;
++
++      if (argc != 2) {
++              fprintf(stderr, "Usage: %s <firmware file>\n", argv[0]);
++              fprintf(stderr, "Firmware can usually be found on your Mac "
++                      "partition in /System/Library/Extensions/"
++                      "IOUSBFamily.kext/Contents/PlugIns/"
++                      "AppleUSBVideoSupport.kext/Contents/MacOS/"
++                      "AppleUSBVideoSupport\n");
++              return -1;
++      }
++      
++      /* check sha1sum on firmware, to prevent loading crap into the
++       * iSight and thus possibly damaging it. */
++      digest = malloc (gcry_md_get_algo_dlen (GCRY_MD_SHA1));
++      if (!(file = g_mapped_file_new (argv[1], FALSE, &gerr))) {
++              fprintf (stderr, "Error opening firmware file: %s\n",
++                       gerr ? gerr->message : "?");
++              return -1;
++      }
++      gcry_md_hash_buffer (GCRY_MD_SHA1, digest,
++                           g_mapped_file_get_contents (file),
++                           g_mapped_file_get_length (file));
++      g_mapped_file_free (file);
++      for (n = 0; n < G_N_ELEMENTS (offsets); n++)
++              if (!memcmp (offsets[n].sha1sum, digest, 20))
++                      break;
++      free (digest);
++      if (n == G_N_ELEMENTS (offsets)) {
++              fprintf (stderr, "Sha1sum check on firmware file failed\n");
++              return -1;
++      }
++      offset = &offsets[n];
++
++      /* init usb */
++      usb_init ();
++      if (usb_find_busses () == 0) {
++              fprintf (stderr, "No USB busses found\n");
++              return -1;
++      } else if (usb_find_devices () == 0) {
++              fprintf (stderr, "No USB devices found\n");
++              return -1;
++      }
++
++      /* find iSight */
++      for (bus = usb_busses; bus != NULL; bus = bus->next) {
++              if (bus->devices != NULL) {
++                      for (dev = bus->devices; dev != NULL;
++                           dev = dev->next) {
++                              res += probe_dev (dev, argv[1], offset->off);
++                              if (res == -1)
++                                      err++;
++                              else
++                                      found += res;
++                      }
++              }
++      }
++      if (found == 0 && err == 0) {
++              fprintf (stderr, "No Apple iSight found!\n");
++              return -1;
++      }
++
++      return 0;
++}
diff --git a/media-video/linux-uvc/linux-uvc-0.1.0e.ebuild b/media-video/linux-uvc/linux-uvc-0.1.0e.ebuild
new file mode 100644 (file)
index 0000000..6e067d8
--- /dev/null
@@ -0,0 +1,69 @@
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/media-video/linux-uvc/linux-uvc-0.1.0e.ebuild,v 1.1 2006/12/04 18:47:56 genstef Exp $
+
+inherit eutils linux-mod
+
+MY_P="${P/.0/.0-}"
+
+DESCRIPTION="Linux driver and user-space tools for USB Video Class devices."
+HOMEPAGE="http://linux-uvc.berlios.de/
+       http://people.freedesktop.org/~rbultje/"
+SRC_URI="http://people.freedesktop.org/~rbultje/${MY_P}.tar.gz"
+#ESVN_REPO_URI="http://svn.berlios.de/svnroot/repos/linux-uvc/linux-uvc/trunk/"
+#ESVN_OPTIONS="-r ${PV/*_pre}"
+
+
+LICENSE="GPL-2"
+KEYWORDS="~amd64 ~x86"
+SLOT="0"
+IUSE="isight"
+DEPEND=">=dev-libs/libusb-0.1.12"
+
+MODULE_NAMES="uvcvideo(usb/media)"
+BUILD_TARGETS="uvcvideo"
+CONFIG_CHECK="VIDEO_DEV"
+S=${WORKDIR}/${MY_P}
+
+pkg_setup() {
+       linux-mod_pkg_setup
+
+       BUILD_PARAMS="KERNEL_DIR=${KV_DIR}"
+       if use isight; then
+               MODULESD_UVCVIDEO_ENABLED="yes"
+               MODULESD_UVCVIDEO_ADDITIONS=( "pre-install uvcvideo /sbin/isight-firmware-tool /lib/firmware/AppleUSBVideoSupport; sleep 2" )
+       fi
+}
+
+src_unpack() {
+       unpack ${A}
+       cd ${S}
+       EPATCH_OPTS="-g0 -E --no-backup-if-mismatch -R"
+       use isight || epatch ${FILESDIR}/isight.patch
+}
+
+src_compile() {
+       use isight && emake extract
+
+       linux-mod_src_compile
+}
+
+src_install() {
+       into /
+       use isight && newsbin extract isight-firmware-tool
+
+       linux-mod_src_install
+}
+
+pkg_postinst() {
+       linux-mod_pkg_postinst
+       ewarn "If something is broken, you should get involved, and report"
+       ewarn "back to the mailing list linux-uvc-devel@lists.berlios.de"
+
+       if use isight; then
+               elog "Using iSight cameras, you *must* install the firmware to /lib/firmware, for e.g:"
+               elog "  mkdir -p /lib/firmware"
+               elog "  cp /\${OSX_MOUNT}/System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBVideoSupport.kext/Contents/MacOS/AppleUSBVideoSupport /lib/firmware"
+               elog "Check /etc/modules.d/uvcvideo for more info."
+       fi
+}