vicam: use request_firmware()

Although it wasn't actually using ihex records before, we use the Intel
HEX record format for this firmware -- because that gives us a simple
way to split it into separate chunks internally as we need, without
loading each part as a separate file.

Signed-off-by: Jaswinder Singh <jaswinder@infradead.org>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c
index 17f542d..40d053e 100644
--- a/drivers/media/video/usbvideo/vicam.c
+++ b/drivers/media/video/usbvideo/vicam.c
@@ -43,6 +43,8 @@
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
 #include <linux/mutex.h>
+#include <linux/firmware.h>
+#include <linux/ihex.h>
 #include "usbvideo.h"
 
 // #define VICAM_DEBUG
@@ -70,284 +72,6 @@
 
 #define VICAM_HEADER_SIZE       64
 
-/* Not sure what all the bytes in these char
- * arrays do, but they're necessary to make
- * the camera work.
- */
-
-static unsigned char setup1[] = {
-	0xB6, 0xC3, 0x1F, 0x00, 0x02, 0x64, 0xE7, 0x67,
-	0xFD, 0xFF, 0x0E, 0xC0, 0xE7, 0x09, 0xDE, 0x00,
-	0x8E, 0x00, 0xC0, 0x09, 0x40, 0x03, 0xC0, 0x17,
-	0x44, 0x03, 0x4B, 0xAF, 0xC0, 0x07, 0x00, 0x00,
-	0x4B, 0xAF, 0x97, 0xCF, 0x00, 0x00
-};
-
-static unsigned char setup2[] = {
-	0xB6, 0xC3, 0x03, 0x00, 0x03, 0x64, 0x18, 0x00,
-	0x00, 0x00
-};
-
-static unsigned char setup3[] = {
-	0xB6, 0xC3, 0x01, 0x00, 0x06, 0x64, 0x00, 0x00
-};
-
-static unsigned char setup4[] = {
-	0xB6, 0xC3, 0x8F, 0x06, 0x02, 0x64, 0xE7, 0x07,
-	0x00, 0x00, 0x08, 0xC0, 0xE7, 0x07, 0x00, 0x00,
-	0x3E, 0xC0, 0xE7, 0x07, 0x54, 0x01, 0xAA, 0x00,
-	0xE7, 0x07, 0xC8, 0x05, 0xB6, 0x00, 0xE7, 0x07,
-	0x42, 0x01, 0xD2, 0x00, 0xE7, 0x07, 0x7C, 0x00,
-	0x16, 0x00, 0xE7, 0x07, 0x56, 0x00, 0x18, 0x00,
-	0xE7, 0x07, 0x06, 0x00, 0x92, 0xC0, 0xE7, 0x07,
-	0x00, 0x00, 0x1E, 0xC0, 0xE7, 0x07, 0xFF, 0xFF,
-	0x22, 0xC0, 0xE7, 0x07, 0x04, 0x00, 0x24, 0xC0,
-	0xE7, 0x07, 0xEC, 0x27, 0x28, 0xC0, 0xE7, 0x07,
-	0x16, 0x01, 0x8E, 0x00, 0xE7, 0x87, 0x01, 0x00,
-	0x0E, 0xC0, 0x97, 0xCF, 0xD7, 0x09, 0x00, 0xC0,
-	0xE7, 0x77, 0x01, 0x00, 0x92, 0xC0, 0x09, 0xC1,
-	0xE7, 0x09, 0xFE, 0x05, 0x24, 0x01, 0xE7, 0x09,
-	0x04, 0x06, 0x26, 0x01, 0xE7, 0x07, 0x07, 0x00,
-	0x92, 0xC0, 0xE7, 0x05, 0x00, 0xC0, 0xC0, 0xDF,
-	0x97, 0xCF, 0x17, 0x00, 0x57, 0x00, 0x17, 0x02,
-	0xD7, 0x09, 0x00, 0xC0, 0xE7, 0x77, 0x01, 0x00,
-	0x92, 0xC0, 0x0A, 0xC1, 0xE7, 0x57, 0xFF, 0xFF,
-	0xFA, 0x05, 0x0D, 0xC0, 0xE7, 0x57, 0x00, 0x00,
-	0xFA, 0x05, 0x0F, 0xC0, 0x9F, 0xAF, 0xC6, 0x00,
-	0xE7, 0x05, 0x00, 0xC0, 0xC8, 0x05, 0xC1, 0x05,
-	0xC0, 0x05, 0xC0, 0xDF, 0x97, 0xCF, 0x27, 0xDA,
-	0xFA, 0x05, 0xEF, 0x07, 0x01, 0x00, 0x0B, 0x06,
-	0x73, 0xCF, 0x9F, 0xAF, 0x78, 0x01, 0x9F, 0xAF,
-	0x1A, 0x03, 0x6E, 0xCF, 0xE7, 0x09, 0xFC, 0x05,
-	0x24, 0x01, 0xE7, 0x09, 0x02, 0x06, 0x26, 0x01,
-	0xE7, 0x07, 0x07, 0x00, 0x92, 0xC0, 0xE7, 0x09,
-	0xFC, 0x05, 0xFE, 0x05, 0xE7, 0x09, 0x02, 0x06,
-	0x04, 0x06, 0xE7, 0x09, 0x00, 0x06, 0xFC, 0x05,
-	0xE7, 0x09, 0xFE, 0x05, 0x00, 0x06, 0x27, 0xDA,
-	0xFA, 0x05, 0xE7, 0x57, 0x01, 0x00, 0xFA, 0x05,
-	0x02, 0xCA, 0x04, 0xC0, 0x97, 0xCF, 0x9F, 0xAF,
-	0x66, 0x05, 0x97, 0xCF, 0xE7, 0x07, 0x40, 0x00,
-	0x02, 0x06, 0xC8, 0x09, 0xFC, 0x05, 0x9F, 0xAF,
-	0xDA, 0x02, 0x97, 0xCF, 0xCF, 0x17, 0x02, 0x00,
-	0xEF, 0x57, 0x81, 0x00, 0x09, 0x06, 0x9F, 0xA0,
-	0xB6, 0x01, 0xEF, 0x57, 0x80, 0x00, 0x09, 0x06,
-	0x9F, 0xA0, 0x40, 0x02, 0xEF, 0x57, 0x01, 0x00,
-	0x0B, 0x06, 0x9F, 0xA0, 0x46, 0x03, 0xE7, 0x07,
-	0x01, 0x00, 0x0A, 0xC0, 0x46, 0xAF, 0x47, 0xAF,
-	0x9F, 0xAF, 0x40, 0x02, 0xE7, 0x07, 0x2E, 0x00,
-	0x0A, 0xC0, 0xEF, 0x87, 0x80, 0x00, 0x09, 0x06,
-	0x97, 0xCF, 0x00, 0x0E, 0x01, 0x00, 0xC0, 0x57,
-	0x51, 0x00, 0x9F, 0xC0, 0x9E, 0x02, 0xC0, 0x57,
-	0x50, 0x00, 0x20, 0xC0, 0xC0, 0x57, 0x55, 0x00,
-	0x12, 0xC0, 0xC0, 0x57, 0x56, 0x00, 0x9F, 0xC0,
-	0x72, 0x02, 0x9F, 0xCF, 0xD6, 0x02, 0xC1, 0x0B,
-	0x08, 0x06, 0x01, 0xD0, 0x6F, 0x90, 0x08, 0x06,
-	0xC0, 0x07, 0x08, 0x00, 0xC1, 0x0B, 0x08, 0x06,
-	0x9F, 0xAF, 0x28, 0x05, 0x97, 0xCF, 0x2F, 0x0E,
-	0x02, 0x00, 0x08, 0x06, 0xC0, 0x07, 0x08, 0x00,
-	0xC1, 0x0B, 0x08, 0x06, 0x9F, 0xAF, 0x28, 0x05,
-	0x9F, 0xCF, 0xD6, 0x02, 0x2F, 0x0E, 0x02, 0x00,
-	0x09, 0x06, 0xEF, 0x87, 0x80, 0x00, 0x09, 0x06,
-	0x9F, 0xCF, 0xD6, 0x02, 0xEF, 0x67, 0x7F, 0xFF,
-	0x09, 0x06, 0xE7, 0x67, 0xFF, 0xFD, 0x22, 0xC0,
-	0xE7, 0x67, 0xEF, 0xFF, 0x24, 0xC0, 0xE7, 0x87,
-	0x10, 0x00, 0x28, 0xC0, 0x9F, 0xAF, 0xB8, 0x05,
-	0xE7, 0x87, 0xE0, 0x21, 0x24, 0xC0, 0x9F, 0xAF,
-	0xA8, 0x05, 0xE7, 0x87, 0x08, 0x00, 0x24, 0xC0,
-	0xE7, 0x67, 0xDF, 0xFF, 0x24, 0xC0, 0xC8, 0x07,
-	0x0A, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xC1, 0x07,
-	0x01, 0x00, 0x9F, 0xAF, 0x28, 0x05, 0x9F, 0xAF,
-	0xB8, 0x05, 0xC0, 0x07, 0x9E, 0x00, 0x9F, 0xAF,
-	0x44, 0x05, 0xE7, 0x67, 0xFF, 0xFE, 0x24, 0xC0,
-	0xC0, 0x09, 0x20, 0xC0, 0xE7, 0x87, 0x00, 0x01,
-	0x24, 0xC0, 0xC0, 0x77, 0x00, 0x02, 0x0F, 0xC1,
-	0xE7, 0x67, 0xF7, 0xFF, 0x24, 0xC0, 0xE7, 0x67,
-	0xF7, 0xFF, 0x24, 0xC0, 0xE7, 0x87, 0x08, 0x00,
-	0x24, 0xC0, 0x08, 0xDA, 0x5E, 0xC1, 0xEF, 0x07,
-	0x80, 0x00, 0x09, 0x06, 0x97, 0xCF, 0xEF, 0x07,
-	0x01, 0x00, 0x0A, 0x06, 0x97, 0xCF, 0xEF, 0x07,
-	0x00, 0x00, 0x0B, 0x06, 0xEF, 0x07, 0x00, 0x00,
-	0x0A, 0x06, 0xEF, 0x67, 0x7F, 0xFF, 0x09, 0x06,
-	0xEF, 0x07, 0x00, 0x00, 0x0D, 0x06, 0xE7, 0x67,
-	0xEF, 0xFF, 0x28, 0xC0, 0xE7, 0x67, 0x17, 0xD8,
-	0x24, 0xC0, 0xE7, 0x07, 0x00, 0x00, 0x1E, 0xC0,
-	0xE7, 0x07, 0xFF, 0xFF, 0x22, 0xC0, 0x97, 0xCF,
-	0xC8, 0x07, 0x0E, 0x06, 0x9F, 0xAF, 0xDA, 0x02,
-	0xE7, 0x07, 0x00, 0x00, 0xF2, 0x05, 0xE7, 0x07,
-	0x10, 0x00, 0xF6, 0x05, 0xE7, 0x07, 0x0E, 0x06,
-	0xF4, 0x05, 0xE7, 0x07, 0xD6, 0x02, 0xF8, 0x05,
-	0xC8, 0x07, 0xF2, 0x05, 0xC1, 0x07, 0x00, 0x80,
-	0x50, 0xAF, 0x97, 0xCF, 0x2F, 0x0C, 0x02, 0x00,
-	0x07, 0x06, 0x2F, 0x0C, 0x04, 0x00, 0x06, 0x06,
-	0xE7, 0x07, 0x00, 0x00, 0xF2, 0x05, 0xE7, 0x07,
-	0x10, 0x00, 0xF6, 0x05, 0xE7, 0x07, 0xE2, 0x05,
-	0xF4, 0x05, 0xE7, 0x07, 0xCE, 0x02, 0xF8, 0x05,
-	0xC8, 0x07, 0xF2, 0x05, 0xC1, 0x07, 0x00, 0x80,
-	0x51, 0xAF, 0x97, 0xCF, 0x9F, 0xAF, 0x66, 0x04,
-	0x9F, 0xAF, 0x1A, 0x03, 0x59, 0xAF, 0x97, 0xCF,
-	0xC0, 0x07, 0x0E, 0x00, 0xC1, 0x0B, 0x0C, 0x06,
-	0x41, 0xD1, 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07,
-	0x3C, 0x00, 0x9F, 0xAF, 0x44, 0x05, 0x68, 0x00,
-	0xC0, 0x07, 0x3B, 0x00, 0x9F, 0xAF, 0x44, 0x05,
-	0x6F, 0x00, 0x0C, 0x06, 0x68, 0x00, 0xE0, 0x07,
-	0x04, 0x01, 0xE8, 0x0B, 0x0A, 0x06, 0xE8, 0x07,
-	0x00, 0x00, 0xE0, 0x07, 0x00, 0x02, 0xE0, 0x07,
-	0xEC, 0x01, 0xE0, 0x07, 0xFC, 0xFF, 0x97, 0xCF,
-	0xE7, 0x07, 0xFF, 0xFF, 0xFA, 0x05, 0xEF, 0x07,
-	0x00, 0x00, 0x0B, 0x06, 0xE7, 0x07, 0x0E, 0x06,
-	0x24, 0x01, 0xE7, 0x07, 0x0E, 0x06, 0xFE, 0x05,
-	0xE7, 0x07, 0x40, 0x00, 0x26, 0x01, 0xE7, 0x07,
-	0x40, 0x00, 0x04, 0x06, 0xE7, 0x07, 0x07, 0x00,
-	0x92, 0xC0, 0x97, 0xCF, 0xEF, 0x07, 0x02, 0x00,
-	0x0B, 0x06, 0x9F, 0xAF, 0x78, 0x01, 0xEF, 0x77,
-	0x80, 0x00, 0x07, 0x06, 0x9F, 0xC0, 0x14, 0x04,
-	0xEF, 0x77, 0x01, 0x00, 0x07, 0x06, 0x37, 0xC0,
-	0xEF, 0x77, 0x01, 0x00, 0x0D, 0x06, 0x0F, 0xC1,
-	0xEF, 0x07, 0x01, 0x00, 0x0D, 0x06, 0xC0, 0x07,
-	0x02, 0x00, 0xC1, 0x07, 0x30, 0x00, 0x9F, 0xAF,
-	0x28, 0x05, 0xC0, 0x07, 0x01, 0x00, 0xC1, 0x07,
-	0x02, 0x00, 0x9F, 0xAF, 0x28, 0x05, 0xC8, 0x07,
-	0xFF, 0x4F, 0x9F, 0xAF, 0xA8, 0x05, 0xC0, 0x07,
-	0x38, 0x00, 0x9F, 0xAF, 0x44, 0x05, 0xC1, 0x77,
-	0x03, 0x00, 0x02, 0xC1, 0x08, 0xDA, 0x75, 0xC1,
-	0xC1, 0x77, 0x01, 0x00, 0x0A, 0xC1, 0xC0, 0x07,
-	0x01, 0x00, 0xC1, 0x07, 0x02, 0x00, 0x9F, 0xAF,
-	0x28, 0x05, 0xEF, 0x07, 0x01, 0x00, 0x06, 0x06,
-	0x2C, 0xCF, 0xC0, 0x07, 0x01, 0x00, 0xC1, 0x07,
-	0x04, 0x00, 0x9F, 0xAF, 0x28, 0x05, 0xEF, 0x07,
-	0x00, 0x00, 0x06, 0x06, 0x22, 0xCF, 0xEF, 0x07,
-	0x00, 0x00, 0x0D, 0x06, 0xEF, 0x57, 0x01, 0x00,
-	0x06, 0x06, 0x1B, 0xC0, 0xC0, 0x07, 0x01, 0x00,
-	0xC1, 0x07, 0x01, 0x00, 0x9F, 0xAF, 0x28, 0x05,
-	0xC0, 0x07, 0x02, 0x00, 0xC1, 0x07, 0x30, 0x00,
-	0x9F, 0xAF, 0x28, 0x05, 0xC8, 0x07, 0xFF, 0x4F,
-	0x9F, 0xAF, 0xA8, 0x05, 0xC0, 0x07, 0x38, 0x00,
-	0x9F, 0xAF, 0x44, 0x05, 0xC1, 0x67, 0x03, 0x00,
-	0xC1, 0x57, 0x03, 0x00, 0x02, 0xC0, 0x08, 0xDA,
-	0x73, 0xC1, 0xC0, 0x07, 0x02, 0x00, 0xC1, 0x07,
-	0x12, 0x00, 0xEF, 0x57, 0x00, 0x00, 0x06, 0x06,
-	0x02, 0xC0, 0xC1, 0x07, 0x23, 0x00, 0x9F, 0xAF,
-	0x28, 0x05, 0xC0, 0x07, 0x14, 0x00, 0xC1, 0x0B,
-	0xEA, 0x05, 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07,
-	0x3E, 0x00, 0x9F, 0xAF, 0x0A, 0x05, 0xE7, 0x09,
-	0xE4, 0x05, 0xFA, 0x05, 0x27, 0xD8, 0xFA, 0x05,
-	0xE7, 0x07, 0x0E, 0x06, 0xFC, 0x05, 0xE7, 0x07,
-	0x4E, 0x06, 0x00, 0x06, 0xE7, 0x07, 0x40, 0x00,
-	0x02, 0x06, 0x9F, 0xAF, 0x66, 0x05, 0x9F, 0xAF,
-	0xC6, 0x00, 0x97, 0xCF, 0xC1, 0x0B, 0xE2, 0x05,
-	0x41, 0xD0, 0x01, 0xD2, 0xC1, 0x17, 0x23, 0x00,
-	0x9F, 0xAF, 0xDC, 0x04, 0xC0, 0x07, 0x04, 0x00,
-	0xC1, 0x0B, 0xE3, 0x05, 0x9F, 0xAF, 0x28, 0x05,
-	0xC0, 0x07, 0x06, 0x00, 0xC1, 0x09, 0xE6, 0x05,
-	0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07, 0x07, 0x00,
-	0xC1, 0x09, 0xE6, 0x05, 0xC1, 0xD1, 0x9F, 0xAF,
-	0x28, 0x05, 0xC0, 0x07, 0x0B, 0x00, 0xC1, 0x09,
-	0xE8, 0x05, 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07,
-	0x0C, 0x00, 0xC1, 0x09, 0xE8, 0x05, 0xC1, 0xD1,
-	0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07, 0x0D, 0x00,
-	0xC1, 0x07, 0x09, 0x00, 0x9F, 0xAF, 0x28, 0x05,
-	0xC0, 0x07, 0x03, 0x00, 0xC1, 0x07, 0x32, 0x00,
-	0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07, 0x0F, 0x00,
-	0xC1, 0x07, 0x00, 0x00, 0x9F, 0xAF, 0x28, 0x05,
-	0x97, 0xCF, 0xE7, 0x67, 0xFF, 0xD9, 0x24, 0xC0,
-	0xC8, 0x07, 0x0A, 0x00, 0x40, 0x00, 0xC0, 0x67,
-	0x00, 0x02, 0x27, 0x80, 0x24, 0xC0, 0xE7, 0x87,
-	0x00, 0x04, 0x24, 0xC0, 0xE7, 0x67, 0xFF, 0xF9,
-	0x24, 0xC0, 0x01, 0xD2, 0x08, 0xDA, 0x72, 0xC1,
-	0xE7, 0x87, 0x00, 0x20, 0x24, 0xC0, 0x97, 0xCF,
-	0x27, 0x00, 0x1E, 0xC0, 0xE7, 0x87, 0xFF, 0x00,
-	0x22, 0xC0, 0xE7, 0x67, 0x7F, 0xFF, 0x24, 0xC0,
-	0xE7, 0x87, 0x80, 0x00, 0x24, 0xC0, 0xE7, 0x87,
-	0x80, 0x00, 0x24, 0xC0, 0x97, 0xCF, 0x9F, 0xAF,
-	0x0A, 0x05, 0x67, 0x00, 0x1E, 0xC0, 0xE7, 0x67,
-	0xBF, 0xFF, 0x24, 0xC0, 0xE7, 0x87, 0x40, 0x00,
-	0x24, 0xC0, 0xE7, 0x87, 0x40, 0x00, 0x24, 0xC0,
-	0x97, 0xCF, 0x9F, 0xAF, 0x0A, 0x05, 0xE7, 0x67,
-	0x00, 0xFF, 0x22, 0xC0, 0xE7, 0x67, 0xFF, 0xFE,
-	0x24, 0xC0, 0xE7, 0x67, 0xFF, 0xFE, 0x24, 0xC0,
-	0xC1, 0x09, 0x20, 0xC0, 0xE7, 0x87, 0x00, 0x01,
-	0x24, 0xC0, 0x97, 0xCF, 0xC0, 0x07, 0x40, 0x00,
-	0xC8, 0x09, 0xFC, 0x05, 0xE7, 0x67, 0x00, 0xFF,
-	0x22, 0xC0, 0xE7, 0x67, 0xFF, 0xFE, 0x24, 0xC0,
-	0xE7, 0x67, 0xBF, 0xFF, 0x24, 0xC0, 0xE7, 0x67,
-	0xBF, 0xFF, 0x24, 0xC0, 0x00, 0xDA, 0xE8, 0x09,
-	0x20, 0xC0, 0xE7, 0x87, 0x40, 0x00, 0x24, 0xC0,
-	0xE7, 0x87, 0x40, 0x00, 0x24, 0xC0, 0x00, 0xDA,
-	0xE8, 0x09, 0x20, 0xC0, 0x6D, 0xC1, 0xE7, 0x87,
-	0x00, 0x01, 0x24, 0xC0, 0x97, 0xCF, 0xE7, 0x07,
-	0x32, 0x00, 0x12, 0xC0, 0xE7, 0x77, 0x00, 0x80,
-	0x12, 0xC0, 0x7C, 0xC0, 0x97, 0xCF, 0xE7, 0x07,
-	0x20, 0x4E, 0x12, 0xC0, 0xE7, 0x77, 0x00, 0x80,
-	0x12, 0xC0, 0x7C, 0xC0, 0x97, 0xCF, 0x09, 0x02,
-	0x19, 0x00, 0x01, 0x01, 0x00, 0x80, 0x96, 0x09,
-	0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
-	0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-static unsigned char setup5[] = {
-	0xB6, 0xC3, 0x2F, 0x01, 0x03, 0x64, 0x0E, 0x00,
-	0x14, 0x00, 0x1A, 0x00, 0x20, 0x00, 0x26, 0x00,
-	0x4A, 0x00, 0x64, 0x00, 0x6A, 0x00, 0x92, 0x00,
-	0x9A, 0x00, 0xA0, 0x00, 0xB2, 0x00, 0xB8, 0x00,
-	0xBE, 0x00, 0xC2, 0x00, 0xC8, 0x00, 0xCE, 0x00,
-	0xDC, 0x00, 0xDA, 0x00, 0xE2, 0x00, 0xE0, 0x00,
-	0xE8, 0x00, 0xE6, 0x00, 0xEE, 0x00, 0xEC, 0x00,
-	0xF2, 0x00, 0xF8, 0x00, 0x02, 0x01, 0x0A, 0x01,
-	0x0E, 0x01, 0x12, 0x01, 0x1E, 0x01, 0x22, 0x01,
-	0x28, 0x01, 0x2C, 0x01, 0x32, 0x01, 0x36, 0x01,
-	0x44, 0x01, 0x50, 0x01, 0x5E, 0x01, 0x72, 0x01,
-	0x76, 0x01, 0x7A, 0x01, 0x80, 0x01, 0x88, 0x01,
-	0x8C, 0x01, 0x94, 0x01, 0x9C, 0x01, 0xA0, 0x01,
-	0xA4, 0x01, 0xAA, 0x01, 0xB0, 0x01, 0xB4, 0x01,
-	0xBA, 0x01, 0xD0, 0x01, 0xDA, 0x01, 0xF6, 0x01,
-	0xFA, 0x01, 0x02, 0x02, 0x34, 0x02, 0x3C, 0x02,
-	0x44, 0x02, 0x4A, 0x02, 0x50, 0x02, 0x56, 0x02,
-	0x74, 0x02, 0x78, 0x02, 0x7E, 0x02, 0x84, 0x02,
-	0x8A, 0x02, 0x88, 0x02, 0x90, 0x02, 0x8E, 0x02,
-	0x94, 0x02, 0xA2, 0x02, 0xA8, 0x02, 0xAE, 0x02,
-	0xB4, 0x02, 0xBA, 0x02, 0xB8, 0x02, 0xC0, 0x02,
-	0xBE, 0x02, 0xC4, 0x02, 0xD0, 0x02, 0xD4, 0x02,
-	0xE0, 0x02, 0xE6, 0x02, 0xEE, 0x02, 0xF8, 0x02,
-	0xFC, 0x02, 0x06, 0x03, 0x1E, 0x03, 0x24, 0x03,
-	0x28, 0x03, 0x30, 0x03, 0x2E, 0x03, 0x3C, 0x03,
-	0x4A, 0x03, 0x4E, 0x03, 0x54, 0x03, 0x58, 0x03,
-	0x5E, 0x03, 0x66, 0x03, 0x6E, 0x03, 0x7A, 0x03,
-	0x86, 0x03, 0x8E, 0x03, 0x96, 0x03, 0xB2, 0x03,
-	0xB8, 0x03, 0xC6, 0x03, 0xCC, 0x03, 0xD4, 0x03,
-	0xDA, 0x03, 0xE8, 0x03, 0xF4, 0x03, 0xFC, 0x03,
-	0x04, 0x04, 0x20, 0x04, 0x2A, 0x04, 0x32, 0x04,
-	0x36, 0x04, 0x3E, 0x04, 0x44, 0x04, 0x42, 0x04,
-	0x48, 0x04, 0x4E, 0x04, 0x4C, 0x04, 0x54, 0x04,
-	0x52, 0x04, 0x5A, 0x04, 0x5E, 0x04, 0x62, 0x04,
-	0x68, 0x04, 0x74, 0x04, 0x7C, 0x04, 0x80, 0x04,
-	0x88, 0x04, 0x8C, 0x04, 0x94, 0x04, 0x9A, 0x04,
-	0xA2, 0x04, 0xA6, 0x04, 0xAE, 0x04, 0xB4, 0x04,
-	0xC0, 0x04, 0xCC, 0x04, 0xD8, 0x04, 0x2A, 0x05,
-	0x46, 0x05, 0x6C, 0x05, 0x00, 0x00
-};
-
 /* rvmalloc / rvfree copied from usbvideo.c
  *
  * Not sure why these are not yet non-statics which I can reference through
@@ -464,28 +188,28 @@
 static int
 initialize_camera(struct vicam_camera *cam)
 {
-	const struct {
-		u8 *data;
-		u32 size;
-	} firmware[] = {
-		{ .data = setup1, .size = sizeof(setup1) },
-		{ .data = setup2, .size = sizeof(setup2) },
-		{ .data = setup3, .size = sizeof(setup3) },
-		{ .data = setup4, .size = sizeof(setup4) },
-		{ .data = setup5, .size = sizeof(setup5) },
-		{ .data = setup3, .size = sizeof(setup3) },
-		{ .data = NULL, .size = 0 }
-	};
+	int err;
+	const struct ihex_binrec *rec;
+	const struct firmware *fw;
 
-	int err, i;
+	err = request_ihex_firmware(&fw, "vicam/firmware.fw", &cam->udev->dev);
+	if (err) {
+		printk(KERN_ERR "Failed to load \"vicam/firmware.fw\": %d\n",
+		       err);
+		return err;
+	}
 
-	for (i = 0, err = 0; firmware[i].data && !err; i++) {
-		memcpy(cam->cntrlbuf, firmware[i].data, firmware[i].size);
+	for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
+		memcpy(cam->cntrlbuf, rec->data, be16_to_cpu(rec->len));
 
 		err = send_control_msg(cam, 0xff, 0, 0,
-				       cam->cntrlbuf, firmware[i].size);
+				       cam->cntrlbuf, be16_to_cpu(rec->len));
+		if (err)
+			break;
 	}
 
+	release_firmware(fw);
+
 	return err;
 }
 
@@ -1226,3 +950,4 @@
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
+MODULE_FIRMWARE("vicam/firmware.fw");
diff --git a/firmware/Makefile b/firmware/Makefile
index 331d10c..5ed36ae 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -63,6 +63,7 @@
 					   # whiteheat_loader_debug.fw
 fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda/keyspan_pda.fw
 fw-shipped-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda/xircom_pgs.fw
+fw-shipped-$(CONFIG_USB_VICAM) += vicam/firmware.fw
 fw-shipped-$(CONFIG_VIDEO_CPIA2) += cpia2/stv0672_vp4.bin
 
 fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-)
diff --git a/firmware/WHENCE b/firmware/WHENCE
index 8784565..b14b86c 100644
--- a/firmware/WHENCE
+++ b/firmware/WHENCE
@@ -265,3 +265,13 @@
  * modification.
 
 --------------------------------------------------------------------------
+
+Driver: USB_VICAM -- USB 3com HomeConnect (aka vicam)
+
+File: vicam/firmware.fw
+
+Licence: Unknown
+
+Found in hex form in kernel source.
+
+--------------------------------------------------------------------------
diff --git a/firmware/vicam/firmware.H16 b/firmware/vicam/firmware.H16
new file mode 100644
index 0000000..cac0cba
--- /dev/null
+++ b/firmware/vicam/firmware.H16
@@ -0,0 +1,7 @@
+:0026000000B6C31F000264E767FDFF0EC0E709DE008E00C0094003C01744034BAFC00700004BAF97CF00001D
+:000A000000B6C30300036418000000FB
+:0008000000B6C301000664000014
+:0696000000B6C38F060264E707000008C0E70700003EC0E7075401AA00E707C805B600E7074201D200E7077C001600E70756001800E707060092C0E70700001EC0E707FFFF22C0E707040024C0E707EC2728C0E70716018E00E78701000EC097CFD70900C0E777010092C009C1E709FE052401E70904062601E707070092C0E70500C0C0DF97CF170057001702D70900C0E777010092C00AC1E757FFFFFA050DC0E7570000FA050FC09FAFC600E70500C0C805C105C005C0DF97CF27DAFA05EF0701000B0673CF9FAF78019FAF1A036ECFE709FC052401E70902062601E707070092C0E709FC05FE05E70902060406E7090006FC05E709FE05000627DAFA05E7570100FA0502CA04C097CF9FAF660597CFE70740000206C809FC059FAFDA0297CFCF170200EF57810009069FA0B601EF57800009069FA04002EF5701000B069FA04603E70701000AC046AF47AF9FAF4002E7072E000AC0EF878000090697CF000E0100C05751009FC09E02C057500020C0C057550012C0C05756009FC072029FCFD602C10B080601D06F900806C0070800C10B08069FAF280597CF2F0E02000806C0070800C10B08069FAF28059FCFD6022F0E02000906EF87800009069FCFD602EF677FFF0906E767FFFD22C0E767EFFF24C0E787100028C09FAFB805E787E02124C09FAFA805E787080024C0E767DFFF24C0C8070A00C0070000C10701009FAF28059FAFB805C0079E009FAF4405E767FFFE24C0C00920C0E787000124C0C07700020FC1E767F7FF24C0E767F7FF24C0E787080024C008DA5EC1EF078000090697CFEF0701000A0697CFEF0700000B06EF0700000A06EF677FFF0906EF0700000D06E767EFFF28C0E76717D824C0E70700001EC0E707FFFF22C097CFC8070E069FAFDA02E7070000F205E7071000F605E7070E06F405E707D602F805C807F205C107008050AF97CF2F0C020007062F0C04000606E7070000F205E7071000F605E707E205F405E707CE02F805C807F205C107008051AF97CF9FAF66049FAF1A0359AF97CFC0070E00C10B0C0641D19FAF2805C0073C009FAF44056800C0073B009FAF44056F000C066800E0070401E80B0A06E8070000E0070002E007EC01E007FCFF97CFE707FFFFFA05EF0700000B06E7070E062401E7070E06FE05E70740002601E70740000406E707070092C097CFEF0702000B069FAF7801EF77800007069FC01404EF770100070637C0EF7701000D060FC1EF0701000D06C0070200C10730009FAF2805C0070100C10702009FAF2805C807FF4F9FAFA805C00738009FAF4405C177030002C108DA75C1C17701000AC1C0070100C10702009FAF2805EF07010006062CCFC0070100C10704009FAF2805EF070000060622CFEF0700000D06EF57010006061BC0C0070100C10701009FAF2805C0070200C10730009FAF2805C807FF4F9FAFA805C00738009FAF4405C1670300C157030002C008DA73C1C0070200C1071200EF570000060602C0C10723009FAF2805C0071400C10BEA059FAF2805C0073E009FAF0A05E709E405FA0527D8FA05E7070E06FC05E7074E060006E707400002069FAF66059FAFC60097CFC10BE20541D001D2C11723009FAFDC04C0070400C10BE3059FAF2805C0070600C109E6059FAF2805C0070700C109E605C1D19FAF2805C0070B00C109E8059FAF2805C0070C00C109E805C1D19FAF2805C0070D00C10709009FAF2805C0070300C10732009FAF2805C0070F00C10700009FAF280597CFE767FFD924C0C8070A004000C0670002278024C0E787000424C0E767FFF924C001D208DA72C1E787002024C097CF27001EC0E787FF0022C0E7677FFF24C0E787800024C0E787800024C097CF9FAF0A0567001EC0E767BFFF24C0E787400024C0E787400024C097CF9FAF0A05E76700FF22C0E767FFFE24C0E767FFFE24C0C10920C0E787000124C097CFC0074000C809FC05E76700FF22C0E767FFFE24C0E767BFFF24C0E767BFFF24C000DAE80920C0E787400024C0E787400024C000DAE80920C06DC1E787000124C097CFE707320012C0E777008012C07CC097CFE707204E12C0E777008012C07CC097CF0902190001010080960904000001000000000705810240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A1
+:0136000000B6C32F0103640E0014001A00200026004A0064006A0092009A00A000B200B800BE00C200C800CE00DC00DA00E200E000E800E600EE00EC00F200F80002010A010E0112011E01220128012C0132013601440150015E01720176017A01800188018C0194019C01A001A401AA01B001B401BA01D001DA01F601FA01020234023C0244024A0250025602740278027E0284028A02880290028E029402A202A802AE02B402BA02B802C002BE02C402D002D402E002E602EE02F802FC0206031E032403280330032E033C034A034E03540358035E0366036E037A0386038E039603B203B803C603CC03D403DA03E803F403FC03040420042A04320436043E044404420448044E044C04540452045A045E046204680474047C04800488048C0494049A04A204A604AE04B404C004CC04D8042A0546056C0500005E
+:0008000000B6C301000664000014
+:0000000001FF