Commit ae93a55b authored by David Woodhouse's avatar David Woodhouse Committed by David Woodhouse

emi26: use request_firmware()

Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
parent 3edbf98b
...@@ -16,18 +16,8 @@ ...@@ -16,18 +16,8 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/firmware.h>
#define MAX_INTEL_HEX_RECORD_LENGTH 16 #include <linux/ihex.h>
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"
#define EMI26_VENDOR_ID 0x086a /* Emagic Soft-und Hardware GmBH */ #define EMI26_VENDOR_ID 0x086a /* Emagic Soft-und Hardware GmBH */
#define EMI26_PRODUCT_ID 0x0100 /* EMI 2|6 without firmware */ #define EMI26_PRODUCT_ID 0x0100 /* EMI 2|6 without firmware */
...@@ -40,7 +30,9 @@ typedef struct _INTEL_HEX_RECORD ...@@ -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 CPUCS_REG 0x7F92 /* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */
#define INTERNAL_RAM(address) (address <= MAX_INTERNAL_ADDRESS) #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_set_reset(struct usb_device *dev, unsigned char reset_bit);
static int emi26_load_firmware (struct usb_device *dev); static int emi26_load_firmware (struct usb_device *dev);
static int emi26_probe(struct usb_interface *intf, const struct usb_device_id *id); static int emi26_probe(struct usb_interface *intf, const struct usb_device_id *id);
...@@ -50,7 +42,9 @@ static void __exit emi26_exit (void); ...@@ -50,7 +42,9 @@ static void __exit emi26_exit (void);
/* thanks to drivers/usb/serial/keyspan_pda.c code */ /* 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; int result;
unsigned char *buffer = kmemdup(data, length, GFP_KERNEL); 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) ...@@ -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) 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 err;
int i; int i;
int pos = 0; /* Position in hex record */
__u32 addr; /* Address to write */ __u32 addr; /* Address to write */
__u8 *buf; __u8 *buf;
...@@ -96,6 +93,23 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -96,6 +93,23 @@ static int emi26_load_firmware (struct usb_device *dev)
goto wraperr; 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) */ /* Assert reset (stop the CPU in the EMI) */
err = emi26_set_reset(dev,1); err = emi26_set_reset(dev,1);
if (err < 0) { if (err < 0) {
...@@ -103,13 +117,17 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -103,13 +117,17 @@ static int emi26_load_firmware (struct usb_device *dev)
goto wraperr; goto wraperr;
} }
rec = (const struct ihex_binrec *)loader_fw->data;
/* 1. We need to put the loader for the FPGA into the EZ-USB */ /* 1. We need to put the loader for the FPGA into the EZ-USB */
for (i=0; g_Loader[i].type == 0; i++) { while (rec) {
err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL); err = emi26_writememory(dev, be32_to_cpu(rec->addr),
rec->data, be16_to_cpu(rec->len),
ANCHOR_LOAD_INTERNAL);
if (err < 0) { if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err); err("%s - error loading firmware: error = %d", __func__, err);
goto wraperr; goto wraperr;
} }
rec = ihex_next_binrec(rec);
} }
/* De-assert reset (let the CPU run) */ /* De-assert reset (let the CPU run) */
...@@ -123,15 +141,16 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -123,15 +141,16 @@ static int emi26_load_firmware (struct usb_device *dev)
/* 2. We upload the FPGA firmware into the EMI /* 2. We upload the FPGA firmware into the EMI
* Note: collect up to 1023 (yes!) bytes and send them with * Note: collect up to 1023 (yes!) bytes and send them with
* a single request. This is _much_ faster! */ * a single request. This is _much_ faster! */
rec = (const struct ihex_binrec *)bitstream_fw->data;
do { do {
i = 0; i = 0;
addr = g_bitstream[pos].address; addr = be32_to_cpu(rec->addr);
/* intel hex records are terminated with type 0 element */ /* intel hex records are terminated with type 0 element */
while ((g_bitstream[pos].type == 0) && (i + g_bitstream[pos].length < FW_LOAD_SIZE)) { while (rec && (i + be16_to_cpu(rec->len) < FW_LOAD_SIZE)) {
memcpy(buf + i, g_bitstream[pos].data, g_bitstream[pos].length); memcpy(buf + i, rec->data, be16_to_cpu(rec->len));
i += g_bitstream[pos].length; i += be16_to_cpu(rec->len);
pos++; rec = ihex_next_binrec(rec);
} }
err = emi26_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA); err = emi26_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA);
if (err < 0) { if (err < 0) {
...@@ -148,8 +167,11 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -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...) */ /* 3. We need to put the loader for the firmware into the EZ-USB (again...) */
for (i=0; g_Loader[i].type == 0; i++) { for (rec = (const struct ihex_binrec *)loader_fw->data;
err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL); 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) { if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err); err("%s - error loading firmware: error = %d", __func__, err);
goto wraperr; goto wraperr;
...@@ -165,9 +187,13 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -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 */ /* 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)) { for (rec = (const struct ihex_binrec *)firmware_fw->data;
err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_EXTERNAL); 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) { if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err); err("%s - error loading firmware: error = %d", __func__, err);
goto wraperr; goto wraperr;
...@@ -182,9 +208,12 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -182,9 +208,12 @@ static int emi26_load_firmware (struct usb_device *dev)
goto wraperr; goto wraperr;
} }
for (i=0; g_Firmware[i].type == 0; i++) { for (rec = (const struct ihex_binrec *)firmware_fw->data;
if (INTERNAL_RAM(g_Firmware[i].address)) { rec; rec = ihex_next_binrec(rec)) {
err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_INTERNAL); 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) { if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err); err("%s - error loading firmware: error = %d", __func__, err);
goto wraperr; goto wraperr;
...@@ -205,6 +234,10 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -205,6 +234,10 @@ static int emi26_load_firmware (struct usb_device *dev)
err = 1; err = 1;
wraperr: wraperr:
release_firmware(loader_fw);
release_firmware(bitstream_fw);
release_firmware(firmware_fw);
kfree(buf); kfree(buf);
return err; return err;
} }
...@@ -257,5 +290,8 @@ MODULE_AUTHOR("Tapio Laxström"); ...@@ -257,5 +290,8 @@ MODULE_AUTHOR("Tapio Laxström");
MODULE_DESCRIPTION("Emagic EMI 2|6 firmware loader."); MODULE_DESCRIPTION("Emagic EMI 2|6 firmware loader.");
MODULE_LICENSE("GPL"); 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 /* vi:ai:syntax=c:sw=8:ts=8:tw=80
*/ */
This diff is collapsed.
...@@ -27,6 +27,8 @@ fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \ ...@@ -27,6 +27,8 @@ fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \
ess/maestro3_assp_minisrc.fw ess/maestro3_assp_minisrc.fw
fw-shipped-$(CONFIG_SND_YMFPCI) += yamaha/ds1_ctrl.fw yamaha/ds1_dsp.fw \ fw-shipped-$(CONFIG_SND_YMFPCI) += yamaha/ds1_ctrl.fw yamaha/ds1_dsp.fw \
yamaha/ds1e_ctrl.fw yamaha/ds1e_ctrl.fw
fw-shipped-$(CONFIG_USB_EMI26) += emi26/loader.fw emi26/firmware.fw \
emi26/bitstream.fw
fw-shipped-$(CONFIG_USB_KAWETH) += kaweth/new_code.bin kaweth/trigger_code.bin \ fw-shipped-$(CONFIG_USB_KAWETH) += kaweth/new_code.bin kaweth/trigger_code.bin \
kaweth/new_code_fix.bin \ kaweth/new_code_fix.bin \
kaweth/trigger_code_fix.bin kaweth/trigger_code_fix.bin
......
...@@ -133,3 +133,37 @@ Licence: GPLv2+ ...@@ -133,3 +133,37 @@ Licence: GPLv2+
Compiled from original 8051 source into Intel HEX, used in our binary ihex form. Compiled from original 8051 source into Intel HEX, used in our binary ihex form.
-------------------------------------------------------------------------- --------------------------------------------------------------------------
Driver: emi26 -- EMI 2|6 USB Audio interface
File: emi26/bitstream.fw
Info: VERSION=1.1.1.131 DATE=2001dec06
File: emi26/firmware.fw
Info: VERSION=1.0.2.916 DATE=12.02.2002
File: emi26/loader.fw
Converted from Intel HEX files, used in our binary representation of ihex.
Original licence information:
/*
* This firmware is for the Emagic EMI 2|6 Audio Interface
*
* The firmware contained herein is Copyright (c) 1999-2002 Emagic
* as an unpublished work. This notice does not imply unrestricted
* or public access to this firmware which is a trade secret of Emagic,
* and which may not be reproduced, used, sold or transferred to
* any third party without Emagic's written consent. All Rights Reserved.
*
* Permission is hereby granted for the distribution of this firmware
* image as part of a Linux or other Open Source operating system kernel
* in text or binary form as required.
*
* This firmware may not be modified and may only be used with the
* Emagic EMI 2|6 Audio Interface. Distribution and/or Modification of
* any driver which includes this firmware, in whole or in part,
* requires the inclusion of this statement.
*/
--------------------------------------------------------------------------
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
:0300000002031CDC
:03004300020400B4
:10010000907FE9E0245B6060240260030201BE90FE
:100110007FEAE0750A00F50BA3E0FEE4EE420A90E8
:100120007FEEE0751500F516A3E0FEE4EE4215E55E
:1001300016451570030201BEE4907FC5F0907FB4B0
:10014000E020E3F9907FC5E0F50C120277AF0C7E5A
:1001500000EF250BF50BEE350AF50AC3E5169FF502
:1001600016E5159EF51580C7907FEAE0750A00F543
:100170000BA3E0FEE4EE420A907FEEE0751500F579
:1001800016A3E0FEE4EE4215E51645156030E49056
:100190007FC5F0907FB4E020E3F9907FC5E0F50CD7
:1001A00012028FAF0C7E00EF250BF50BEE350AF532
:0F01B0000AC3E5169FF516E5159EF51580CAC31F
:0101BF00221D
:1001C000C220D2E843D820907FAB74FFF0907FA983
:1001D000F0907FAAF05391EF907F95E044C0F090AB
:1001E0007F98E044C0F0907F9EE044C0F0E4907FB0
:1001F00094F0907F9DE0440FF0907F97E054F0F0F2
:10020000907FAFE04401F0907FAEE0440DF0D2AFBC
:10021000907F97E054F0F020204275140075130091
:100220007512007511007F487E927D007C00AB1432
:10023000AA13A912A811C312049A50DB2020D87A5D
:100240000079007800E5142401F514EA3513F5135C
:10025000E93512F512E83511F51180CA3020FD128A
:1002600001005007907FB4E04401F0907FB4E04477
:0602700002F0C22080E64E
:010276002265
:10027700E50CFFE50BF582E50AF58375927E74C000
:08028700F8E208F0A3DFFA22FF
:10028F00907F96858392A8827902900000E0B40057
:10029F00377401F0907F93E054FCF0907F96E05418
:1002AF00FCF0907F9CE04403F0907F94E0547FF04B
:1002BF00907F97E04480F0907F9DE04480F0907FA6
:1002CF0097E0547FF04480F0E50CFF907EC0E0F59E
:1002DF0028E4A24733F269F2E4A24633F269F2E46A
:1002EF00A24533F269F2E4A24433F269F2E4A24385
:1002FF0033F269F2E4A24233F269F2E4A24133F23B
:0D030F0069F2E4A24033F269F2A3DFC222DA
:0C031C00787FE4F6D8FD758129020363A8
:100328000201C0E493A3F8E493A34003F68001F22A
:1003380008DFF48029E493A3F85407240CC8C333D6
:10034800C4540F4420C8834004F456800146F6DFA5
:10035800E4800B0102040810204080900484E47EAD
:10036800019360BCA3FF543F30E509541FFEE4939A
:10037800A360010ECF54C025E060A840B8E493A361
:10038800FAE493A3F8E493A3C8C582C8CAC583CA8C
:10039800F0A3C8C582C8CAC583CADFE9DEE780BE44
:1003A800C0E0C083C082907FC4E4F05391EF907F97
:0B03B800AB7404F0D082D083D0E032A0
:1003C300C0E0C083C082D2205391EF907FAB740111
:0803D300F0D082D083D0E032AB
:1003DB00C0E0C083C0825391EF907FAB7402F0D02A
:0603EB0082D083D0E03255
:0103F10032D9
:0103F20032D8
:0103F30032D7
:0103F40032D6
:0103F50032D5
:0103F60032D4
:0103F70032D3
:0103F80032D2
:0103F90032D1
:0103FA0032D0
:0103FB0032CF
:0103FC0032CE
:0103FD0032CD
:0103FE0032CC
:0103FF0032CB
:100400000203C3000203DB000203A80002046E0023
:10041000020458000203F1000203F2000203F30099
:100420000203F4000203F5000203F6000203F700E2
:100430000203F8000203F9000203FA000203FB00C2
:100440000203FC000203FD000203FE000203FF00A2
:080450000204AB000204AC0041
:10045800C0E0C083C0825391EF907FAB7410F0D09E
:0604680082D083D0E032D7
:10046E00C0E0C083C0825391EF907FAB7408F0D090
:06047E0082D083D0E032C1
:10048400020A000F010C11040D00000000410000DD
:010494000067
:04049500021700004A
:010499000062
:10049A00EB9FF5F0EA9E42F0E99D42F0E89C45F0B8
:0104AA00222F
:0104AB00321E
:0104AC00321D
:1011000012011001000000406A0801010001010203
:10111000000109022000010103A0000904000002EF
:10112000FF0000040705820240000007050202409C
:10113000000004030904260341006E0063006800F8
:101140006F007200200043006800690070007300A7
:101150002C00200049006E0063002E00280346008A
:10116000690072006D007700610072006500200068
:101170004600720061006D00650057006F0072004C
:101180006B0073002A0343006F006E006600690065
:101190006700750072006100740069006F006E00E6
:1011A000200053007400720069006E006700220383
:1011B00049006E0074006500720066006100630003
:1011C0006500200053007400720069006E00670023
:0211D00000001D
:00000001FF
/*
* This firmware is for the Emagic EMI 2|6 Audio Interface
*
* The firmware contained herein is Copyright (c) 1999-2002 Emagic
* as an unpublished work. This notice does not imply unrestricted
* or public access to this firmware which is a trade secret of Emagic,
* and which may not be reproduced, used, sold or transferred to
* any third party without Emagic's written consent. All Rights Reserved.
*
* This firmware may not be modified and may only be used with the
* Emagic EMI 2|6 Audio Interface. Distribution and/or Modification of
* any driver which includes this firmware, in whole or in part,
* requires the inclusion of this statement.
*/
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment