diff options
Diffstat (limited to 'drivers/usb/misc/emi26.c')
| -rw-r--r-- | drivers/usb/misc/emi26.c | 96 | 
1 files changed, 66 insertions, 30 deletions
diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c index 4b9dc81b845..4b994a0cd27 100644 --- a/drivers/usb/misc/emi26.c +++ b/drivers/usb/misc/emi26.c @@ -16,18 +16,8 @@  #include <linux/init.h>  #include <linux/usb.h>  #include <linux/delay.h> - -#define MAX_INTEL_HEX_RECORD_LENGTH 16 -typedef struct _INTEL_HEX_RECORD -{ -	__u32	length; -	__u32	address; -	__u32	type; -	__u8	data[MAX_INTEL_HEX_RECORD_LENGTH]; -} INTEL_HEX_RECORD, *PINTEL_HEX_RECORD; - -/* include firmware (variables) */ -#include "emi26_fw.h" +#include <linux/firmware.h> +#include <linux/ihex.h>  #define EMI26_VENDOR_ID 		0x086a  /* Emagic Soft-und Hardware GmBH */  #define EMI26_PRODUCT_ID		0x0100	/* EMI 2|6 without firmware */ @@ -40,7 +30,9 @@ typedef struct _INTEL_HEX_RECORD  #define CPUCS_REG		0x7F92  /* EZ-USB Control and Status Register.  Bit 0 controls 8051 reset */   #define INTERNAL_RAM(address)   (address <= MAX_INTERNAL_ADDRESS) -static int emi26_writememory( struct usb_device *dev, int address, unsigned char *data, int length, __u8 bRequest); +static int emi26_writememory( struct usb_device *dev, int address, +			      const unsigned char *data, int length, +			      __u8 bRequest);  static int emi26_set_reset(struct usb_device *dev, unsigned char reset_bit);  static int emi26_load_firmware (struct usb_device *dev);  static int emi26_probe(struct usb_interface *intf, const struct usb_device_id *id); @@ -50,7 +42,9 @@ static void __exit emi26_exit (void);  /* thanks to drivers/usb/serial/keyspan_pda.c code */ -static int emi26_writememory (struct usb_device *dev, int address, unsigned char *data, int length, __u8 request) +static int emi26_writememory (struct usb_device *dev, int address, +			      const unsigned char *data, int length, +			      __u8 request)  {  	int result;  	unsigned char *buffer =  kmemdup(data, length, GFP_KERNEL); @@ -83,9 +77,12 @@ static int emi26_set_reset (struct usb_device *dev, unsigned char reset_bit)  static int emi26_load_firmware (struct usb_device *dev)  { +	const struct firmware *loader_fw = NULL; +	const struct firmware *bitstream_fw = NULL; +	const struct firmware *firmware_fw = NULL; +	const struct ihex_binrec *rec;  	int err;  	int i; -	int pos = 0;	/* Position in hex record */  	__u32 addr;	/* Address to write */  	__u8 *buf; @@ -96,6 +93,23 @@ static int emi26_load_firmware (struct usb_device *dev)  		goto wraperr;  	} +	err = request_ihex_firmware(&loader_fw, "emi26/loader.fw", &dev->dev); +	if (err) +		goto nofw; + +	err = request_ihex_firmware(&bitstream_fw, "emi26/bitstream.fw", +				    &dev->dev); +	if (err) +		goto nofw; + +	err = request_ihex_firmware(&firmware_fw, "emi26/firmware.fw", +				    &dev->dev); +	if (err) { +	nofw: +		err( "%s - request_firmware() failed", __func__); +		goto wraperr; +	} +  	/* Assert reset (stop the CPU in the EMI) */  	err = emi26_set_reset(dev,1);  	if (err < 0) { @@ -103,13 +117,17 @@ static int emi26_load_firmware (struct usb_device *dev)  		goto wraperr;  	} +	rec = (const struct ihex_binrec *)loader_fw->data;  	/* 1. We need to put the loader for the FPGA into the EZ-USB */ -	for (i=0; g_Loader[i].type == 0; i++) { -		err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL); +	while (rec) { +		err = emi26_writememory(dev, be32_to_cpu(rec->addr), +					rec->data, be16_to_cpu(rec->len), +					ANCHOR_LOAD_INTERNAL);  		if (err < 0) {  			err("%s - error loading firmware: error = %d", __func__, err);  			goto wraperr;  		} +		rec = ihex_next_binrec(rec);  	}  	/* De-assert reset (let the CPU run) */ @@ -123,15 +141,16 @@ static int emi26_load_firmware (struct usb_device *dev)  	/* 2. We upload the FPGA firmware into the EMI  	 * Note: collect up to 1023 (yes!) bytes and send them with  	 * a single request. This is _much_ faster! */ +	rec = (const struct ihex_binrec *)bitstream_fw->data;  	do {  		i = 0; -		addr = g_bitstream[pos].address; +		addr = be32_to_cpu(rec->addr);  		/* intel hex records are terminated with type 0 element */ -		while ((g_bitstream[pos].type == 0) && (i + g_bitstream[pos].length < FW_LOAD_SIZE)) { -			memcpy(buf + i, g_bitstream[pos].data, g_bitstream[pos].length); -			i += g_bitstream[pos].length; -			pos++; +		while (rec && (i + be16_to_cpu(rec->len) < FW_LOAD_SIZE)) { +			memcpy(buf + i, rec->data, be16_to_cpu(rec->len)); +			i += be16_to_cpu(rec->len); +			rec = ihex_next_binrec(rec);  		}  		err = emi26_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA);  		if (err < 0) { @@ -148,8 +167,11 @@ static int emi26_load_firmware (struct usb_device *dev)  	}  	/* 3. We need to put the loader for the firmware into the EZ-USB (again...) */ -	for (i=0; g_Loader[i].type == 0; i++) { -		err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL); +	for (rec = (const struct ihex_binrec *)loader_fw->data; +	     rec; rec = ihex_next_binrec(rec)) { +		err = emi26_writememory(dev, be32_to_cpu(rec->addr), +					rec->data, be16_to_cpu(rec->len), +					ANCHOR_LOAD_INTERNAL);  		if (err < 0) {  			err("%s - error loading firmware: error = %d", __func__, err);  			goto wraperr; @@ -165,9 +187,13 @@ static int emi26_load_firmware (struct usb_device *dev)  	}  	/* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */ -	for (i=0; g_Firmware[i].type == 0; i++) { -		if (!INTERNAL_RAM(g_Firmware[i].address)) { -			err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_EXTERNAL); + +	for (rec = (const struct ihex_binrec *)firmware_fw->data; +	     rec; rec = ihex_next_binrec(rec)) { +		if (!INTERNAL_RAM(be32_to_cpu(rec->addr))) { +			err = emi26_writememory(dev, be32_to_cpu(rec->addr), +						rec->data, be16_to_cpu(rec->len), +						ANCHOR_LOAD_EXTERNAL);  			if (err < 0) {  				err("%s - error loading firmware: error = %d", __func__, err);  				goto wraperr; @@ -182,9 +208,12 @@ static int emi26_load_firmware (struct usb_device *dev)  		goto wraperr;  	} -	for (i=0; g_Firmware[i].type == 0; i++) { -		if (INTERNAL_RAM(g_Firmware[i].address)) { -			err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_INTERNAL); +	for (rec = (const struct ihex_binrec *)firmware_fw->data; +	     rec; rec = ihex_next_binrec(rec)) { +		if (INTERNAL_RAM(be32_to_cpu(rec->addr))) { +			err = emi26_writememory(dev, be32_to_cpu(rec->addr), +						rec->data, be16_to_cpu(rec->len), +						ANCHOR_LOAD_INTERNAL);  			if (err < 0) {  				err("%s - error loading firmware: error = %d", __func__, err);  				goto wraperr; @@ -205,6 +234,10 @@ static int emi26_load_firmware (struct usb_device *dev)  	err = 1;  wraperr: +	release_firmware(loader_fw); +	release_firmware(bitstream_fw); +	release_firmware(firmware_fw); +  	kfree(buf);  	return err;  } @@ -257,5 +290,8 @@ MODULE_AUTHOR("Tapio Laxström");  MODULE_DESCRIPTION("Emagic EMI 2|6 firmware loader.");  MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("emi26/loader.fw"); +MODULE_FIRMWARE("emi26/bitstream.fw"); +MODULE_FIRMWARE("emi26/firmware.fw");  /* vi:ai:syntax=c:sw=8:ts=8:tw=80   */  |