public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Firmware loader driver for USB Apple iSight camera
@ 2008-05-20 19:06 Matthew Garrett
  2008-05-20 21:59 ` Oliver Neukum
  2008-06-02 19:21 ` Ingo Molnar
  0 siblings, 2 replies; 6+ messages in thread
From: Matthew Garrett @ 2008-05-20 19:06 UTC (permalink / raw)
  To: linux-usb, linux-kernel; +Cc: gregkh, bersace03, johannes

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 <mjg@redhat.com>

---

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 <mjg@redhat.com>
+ *
+ * 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
+ * <johannes@sipsolutions.de>, and this driver is based on code by Ronald
+ * Bultje <rbultje@ronald.bitfreak.net>
+ */
+
+#include <linux/usb.h>
+#include <linux/firmware.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+
+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 <mjg@redhat.com>");

-- 
Matthew Garrett | mjg59@srcf.ucam.org

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] Firmware loader driver for USB Apple iSight camera
  2008-05-20 19:06 [PATCH] Firmware loader driver for USB Apple iSight camera Matthew Garrett
@ 2008-05-20 21:59 ` Oliver Neukum
  2008-05-20 22:03   ` Matthew Garrett
  2008-06-02 19:21 ` Ingo Molnar
  1 sibling, 1 reply; 6+ messages in thread
From: Oliver Neukum @ 2008-05-20 21:59 UTC (permalink / raw)
  To: Matthew Garrett; +Cc: linux-usb, linux-kernel, gregkh, bersace03, johannes

Am Dienstag 20 Mai 2008 21:06:28 schrieb 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

How does that simplify suspend/resume?
If the device looses its firmware due to suspend you must implement
this support in uvc, or a user space driver will be as good as this solution.

	Regards
		Oliver


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Firmware loader driver for USB Apple iSight camera
  2008-05-20 21:59 ` Oliver Neukum
@ 2008-05-20 22:03   ` Matthew Garrett
  2008-05-20 22:08     ` Oliver Neukum
  0 siblings, 1 reply; 6+ messages in thread
From: Matthew Garrett @ 2008-05-20 22:03 UTC (permalink / raw)
  To: Oliver Neukum; +Cc: linux-usb, linux-kernel, gregkh, bersace03, johannes

On Tue, May 20, 2008 at 11:59:05PM +0200, Oliver Neukum wrote:

> How does that simplify suspend/resume?
> If the device looses its firmware due to suspend you must implement
> this support in uvc, or a user space driver will be as good as this solution.

If it loses its firmwrare, it'll reattach with the old ID.

-- 
Matthew Garrett | mjg59@srcf.ucam.org

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Firmware loader driver for USB Apple iSight camera
  2008-05-20 22:03   ` Matthew Garrett
@ 2008-05-20 22:08     ` Oliver Neukum
  0 siblings, 0 replies; 6+ messages in thread
From: Oliver Neukum @ 2008-05-20 22:08 UTC (permalink / raw)
  To: Matthew Garrett; +Cc: linux-usb, linux-kernel, gregkh, bersace03, johannes

Am Mittwoch 21 Mai 2008 00:03:04 schrieb Matthew Garrett:
> On Tue, May 20, 2008 at 11:59:05PM +0200, Oliver Neukum wrote:
> 
> > How does that simplify suspend/resume?
> > If the device looses its firmware due to suspend you must implement
> > this support in uvc, or a user space driver will be as good as this solution.
> 
> If it loses its firmwrare, it'll reattach with the old ID.

Thereby breaking the binding to the uvc driver. It'll be considered
a new device. You might just as well load the firmware through usbfs
triggered by udev.

If you really want to fix this you'd have to extend the persist
infrastructure first.

	Regards
		Oliver


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Firmware loader driver for USB Apple iSight camera
  2008-05-20 19:06 [PATCH] Firmware loader driver for USB Apple iSight camera Matthew Garrett
  2008-05-20 21:59 ` Oliver Neukum
@ 2008-06-02 19:21 ` Ingo Molnar
  2008-06-04  5:38   ` Greg KH
  1 sibling, 1 reply; 6+ messages in thread
From: Ingo Molnar @ 2008-06-02 19:21 UTC (permalink / raw)
  To: Matthew Garrett; +Cc: linux-usb, linux-kernel, gregkh, bersace03, johannes


* Matthew Garrett <mjg59@srcf.ucam.org> wrote:

> 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.

this caused a build failure - find the fix below. (fix can also be 
pulled/cherry-picked from -tip's tip/out-of-tree topic branch)

	Ingo

-------------------->
commit 1f910d33b2084d03267db20359472891f95b45b4
Author: Ingo Molnar <mingo@elte.hu>
Date:   Mon Jun 2 21:07:27 2008 +0200

    USB: fix build bug in USB_ISIGHTFW
    
    -tip tree testing found this build bug:
    
      drivers/built-in.o: In function `isight_firmware_load':
      isight_firmware.c:(.text+0x1ade08): undefined reference to `request_firmware'
      isight_firmware.c:(.text+0x1adf9c): undefined reference to `release_firmware'
    
    select FW_LOADER in USB_ISIGHTFW.

diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index eb6c069..001789c 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -272,6 +272,7 @@ config USB_TEST
 config USB_ISIGHTFW
 	tristate "iSight firmware loading support"
 	depends on USB
+	select FW_LOADER
 	help
 	  This driver loads firmware for USB Apple iSight cameras, allowing
 	  them to be driven by the USB video class driver available at

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] Firmware loader driver for USB Apple iSight camera
  2008-06-02 19:21 ` Ingo Molnar
@ 2008-06-04  5:38   ` Greg KH
  0 siblings, 0 replies; 6+ messages in thread
From: Greg KH @ 2008-06-04  5:38 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Matthew Garrett, linux-usb, linux-kernel, gregkh, bersace03,
	johannes

On Mon, Jun 02, 2008 at 09:21:03PM +0200, Ingo Molnar wrote:
> 
> * Matthew Garrett <mjg59@srcf.ucam.org> wrote:
> 
> > 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.
> 
> this caused a build failure - find the fix below. (fix can also be 
> pulled/cherry-picked from -tip's tip/out-of-tree topic branch)
> 
> 	Ingo
> 
> -------------------->
> commit 1f910d33b2084d03267db20359472891f95b45b4
> Author: Ingo Molnar <mingo@elte.hu>
> Date:   Mon Jun 2 21:07:27 2008 +0200
> 
>     USB: fix build bug in USB_ISIGHTFW
>     
>     -tip tree testing found this build bug:
>     
>       drivers/built-in.o: In function `isight_firmware_load':
>       isight_firmware.c:(.text+0x1ade08): undefined reference to `request_firmware'
>       isight_firmware.c:(.text+0x1adf9c): undefined reference to `release_firmware'
>     
>     select FW_LOADER in USB_ISIGHTFW.

Thanks, I'll add this to my queue.

greg k-h

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2008-06-04  6:08 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-20 19:06 [PATCH] Firmware loader driver for USB Apple iSight camera Matthew Garrett
2008-05-20 21:59 ` Oliver Neukum
2008-05-20 22:03   ` Matthew Garrett
2008-05-20 22:08     ` Oliver Neukum
2008-06-02 19:21 ` Ingo Molnar
2008-06-04  5:38   ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox