Home
Reading
Searching
Subscribe
Sponsors
Statistics
Posting
Contact
Spam
Lists
Links
About
Hosting
Filtering
Features Download
Marketing
Archives
FAQ
Blog
 
Gmane
From: Matthew Garrett <mjg59-1xO5oi07KQx4cg9Nei1l7Q <at> public.gmane.org>
Subject: [PATCH] Firmware loader driver for USB Apple iSight camera
Newsgroups: gmane.linux.usb.general
Date: Tuesday 20th May 2008 19:06:28 UTC (over 9 years ago)
Uninitialised Apple iSight drivers present with a distinctive USB ID. 
Once firmware has been uploaded, they disconnect and reconnect with a 
new ID. At this point they can be driven by the uvcvideo driver. As this 
is unique to the Apple cameras and not functionality shared by any other 
UVC devices, it makes sense to provide the firmware loading 
functionality in a separate driver. This driver will read an isight.fw 
file extracted from the Apple driver using the tools at 
http://bersace03.free.fr/ift/ and
upload it to the camera. It will also 
handle the case where the device loses its firmware during hibernation 
and must have it reloaded.

Signed-off-by: Matthew Garrett


---

I think this is a cleaner solution than adding support for the firmware 
loading directly to the uvcvideo driver, and doing it as a driver rather 
than a set of userspace callouts simplifies the suspend/resume case. The 
required firmware is, sadly, non-free and undistributable.

diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index a53db1d..0629e7a 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -269,3 +269,14 @@ config USB_TEST
 	  See <http://www.linux-usb.org/usbtest/>
for more information,
 	  including sample test device firmware and "how to use it".
 
+config USB_ISIGHTFW
+       tristate "iSight firmware loading support"
+       depends on USB
+       help
+         This driver loads firmware for USB Apple iSight cameras, allowing
+	 them to be driven by the USB video class driver available at
+	 http://linux-uvc.berlios.de
+
+	 The firmware for this driver must be extracted from the MacOS driver
+	 beforehand. Tools for doing so are available at 
+	 http://bersace03.free.fr
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index b68e6b7..aba091c 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_USB_EMI62)		+= emi62.o
 obj-$(CONFIG_USB_FTDI_ELAN)	+= ftdi-elan.o
 obj-$(CONFIG_USB_IDMOUSE)	+= idmouse.o
 obj-$(CONFIG_USB_IOWARRIOR)	+= iowarrior.o
+obj-$(CONFIG_USB_ISIGHTFW)	+= isight_firmware.o
 obj-$(CONFIG_USB_LCD)		+= usblcd.o
 obj-$(CONFIG_USB_LD)		+= ldusb.o
 obj-$(CONFIG_USB_LED)		+= usbled.o
diff --git a/drivers/usb/misc/isight_firmware.c
b/drivers/usb/misc/isight_firmware.c
new file mode 100644
index 0000000..c76da4a
--- /dev/null
+++ b/drivers/usb/misc/isight_firmware.c
@@ -0,0 +1,131 @@
+/*
+ * Driver for loading USB isight firmware
+ *
+ * Copyright (C) 2008 Matthew Garrett

+ *
+ * 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, version 2.
+ *
+ * The USB isight cameras in recent Apples are roughly compatible with the
USB
+ * video class specification, and can be driven by uvcvideo. However, they
+ * need firmware to be loaded beforehand. After firmware loading, the
device
+ * detaches from the USB bus and reattaches with a new device ID. It can
then
+ * be claimed by the uvc driver.
+ *
+ * The firmware is non-free and must be extracted by the user. Tools to do
this
+ * are available at http://bersace03.free.fr/ift/
+ *
+ * The isight firmware loading was reverse engineered by Johannes Berg
+ * , and this driver is
based on code by Ronald
+ * Bultje 
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+static struct usb_device_id id_table[] = {
+	{USB_DEVICE(0x05ac, 0x8300)},
+	{},
+};
+
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static int isight_firmware_load(struct usb_interface *intf,
+				const struct usb_device_id *id)
+{
+	struct usb_device *dev = interface_to_usbdev(intf);
+	int llen, len, req, ret = 0;
+	const struct firmware *firmware;
+	unsigned char *buf;
+	unsigned char data[4];
+	char *ptr;
+
+	if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) {
+		printk(KERN_ERR "Unable to load isight firmware\n");
+		return -ENODEV;
+	}
+
+	ptr = firmware->data;
+
+	if (usb_control_msg
+	    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\1", 1,
+	     300) != 1) {
+		printk(KERN_ERR
+		       "Failed to initialise isight firmware loader\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+	while (1) {
+		memcpy(data, ptr, 4);
+		len = (data[0] << 8 | data[1]);
+		req = (data[2] << 8 | data[3]);
+		ptr += 4;
+
+		if (len == 0x8001)
+			break;	/* success */
+		else if (len == 0)
+			continue;
+
+		for (; len > 0; req += 50) {
+			llen = len > 50 ? 50 : len;
+			len -= llen;
+
+			buf = kmalloc(llen, GFP_KERNEL);
+			memcpy(buf, ptr, llen);
+
+			ptr += llen;
+
+			if (usb_control_msg
+			    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, req, 0,
+			     buf, llen, 300) != llen) {
+				printk(KERN_ERR
+				       "Failed to load isight firmware\n");
+				kfree(buf);
+				ret = -ENODEV;
+				goto out;
+			}
+
+			kfree(buf);
+		}
+	}
+	if (usb_control_msg
+	    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1,
+	     300) != 1) {
+		printk(KERN_ERR "isight firmware loading completion failed\n");
+		ret = -ENODEV;
+	}
+out:
+	release_firmware(firmware);
+	return ret;
+}
+
+static void isight_firmware_disconnect(struct usb_interface *intf)
+{
+}
+
+static struct usb_driver isight_firmware_driver = {
+	.name = "isight_firmware",
+	.probe = isight_firmware_load,
+	.disconnect = isight_firmware_disconnect,
+	.id_table = id_table,
+};
+
+static int __init isight_firmware_init(void)
+{
+	return usb_register(&isight_firmware_driver);
+}
+
+static void __exit isight_firmware_exit(void)
+{
+	usb_deregister(&isight_firmware_driver);
+}
+
+module_init(isight_firmware_init);
+module_exit(isight_firmware_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Matthew Garrett
");

-- 
Matthew Garrett | [email protected]
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
 
CD: 5ms