aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/misc/emi62.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/misc/emi62.c')
-rw-r--r--drivers/usb/misc/emi62.c130
1 files changed, 73 insertions, 57 deletions
diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c
index 1a2b79ac5e10..20886c21e739 100644
--- a/drivers/usb/misc/emi62.c
+++ b/drivers/usb/misc/emi62.c
@@ -16,15 +16,8 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/usb.h> 17#include <linux/usb.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19 19#include <linux/firmware.h>
20#define MAX_INTEL_HEX_RECORD_LENGTH 16 20#include <linux/ihex.h>
21typedef struct _INTEL_HEX_RECORD
22{
23 __u32 length;
24 __u32 address;
25 __u32 type;
26 __u8 data[MAX_INTEL_HEX_RECORD_LENGTH];
27} INTEL_HEX_RECORD, *PINTEL_HEX_RECORD;
28 21
29/* include firmware (variables)*/ 22/* include firmware (variables)*/
30 23
@@ -33,9 +26,9 @@ typedef struct _INTEL_HEX_RECORD
33//#undef SPDIF /* if you want MIDI uncomment this line */ 26//#undef SPDIF /* if you want MIDI uncomment this line */
34 27
35#ifdef SPDIF 28#ifdef SPDIF
36# include "emi62_fw_s.h" /* spdif fw */ 29#define FIRMWARE_FW "emi62/spdif.fw"
37#else 30#else
38# include "emi62_fw_m.h" /* midi fw */ 31#define FIRMWARE_FW "emi62/midi.fw"
39#endif 32#endif
40 33
41#define EMI62_VENDOR_ID 0x086a /* Emagic Soft-und Hardware GmBH */ 34#define EMI62_VENDOR_ID 0x086a /* Emagic Soft-und Hardware GmBH */
@@ -48,7 +41,9 @@ typedef struct _INTEL_HEX_RECORD
48#define CPUCS_REG 0x7F92 /* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */ 41#define CPUCS_REG 0x7F92 /* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */
49#define INTERNAL_RAM(address) (address <= MAX_INTERNAL_ADDRESS) 42#define INTERNAL_RAM(address) (address <= MAX_INTERNAL_ADDRESS)
50 43
51static int emi62_writememory( struct usb_device *dev, int address, unsigned char *data, int length, __u8 bRequest); 44static int emi62_writememory(struct usb_device *dev, int address,
45 const unsigned char *data, int length,
46 __u8 bRequest);
52static int emi62_set_reset(struct usb_device *dev, unsigned char reset_bit); 47static int emi62_set_reset(struct usb_device *dev, unsigned char reset_bit);
53static int emi62_load_firmware (struct usb_device *dev); 48static int emi62_load_firmware (struct usb_device *dev);
54static int emi62_probe(struct usb_interface *intf, const struct usb_device_id *id); 49static int emi62_probe(struct usb_interface *intf, const struct usb_device_id *id);
@@ -58,7 +53,9 @@ static void __exit emi62_exit (void);
58 53
59 54
60/* thanks to drivers/usb/serial/keyspan_pda.c code */ 55/* thanks to drivers/usb/serial/keyspan_pda.c code */
61static int emi62_writememory (struct usb_device *dev, int address, unsigned char *data, int length, __u8 request) 56static int emi62_writememory(struct usb_device *dev, int address,
57 const unsigned char *data, int length,
58 __u8 request)
62{ 59{
63 int result; 60 int result;
64 unsigned char *buffer = kmemdup(data, length, GFP_KERNEL); 61 unsigned char *buffer = kmemdup(data, length, GFP_KERNEL);
@@ -91,9 +88,12 @@ static int emi62_set_reset (struct usb_device *dev, unsigned char reset_bit)
91 88
92static int emi62_load_firmware (struct usb_device *dev) 89static int emi62_load_firmware (struct usb_device *dev)
93{ 90{
91 const struct firmware *loader_fw = NULL;
92 const struct firmware *bitstream_fw = NULL;
93 const struct firmware *firmware_fw = NULL;
94 const struct ihex_binrec *rec;
94 int err; 95 int err;
95 int i; 96 int i;
96 int pos = 0; /* Position in hex record */
97 __u32 addr; /* Address to write */ 97 __u32 addr; /* Address to write */
98 __u8 *buf; 98 __u8 *buf;
99 99
@@ -105,6 +105,22 @@ static int emi62_load_firmware (struct usb_device *dev)
105 goto wraperr; 105 goto wraperr;
106 } 106 }
107 107
108 err = request_ihex_firmware(&loader_fw, "emi62/loader.fw", &dev->dev);
109 if (err)
110 goto nofw;
111
112 err = request_ihex_firmware(&bitstream_fw, "emi62/bitstream.fw",
113 &dev->dev);
114 if (err)
115 goto nofw;
116
117 err = request_ihex_firmware(&firmware_fw, FIRMWARE_FW, &dev->dev);
118 if (err) {
119 nofw:
120 err( "%s - request_firmware() failed", __func__);
121 goto wraperr;
122 }
123
108 /* Assert reset (stop the CPU in the EMI) */ 124 /* Assert reset (stop the CPU in the EMI) */
109 err = emi62_set_reset(dev,1); 125 err = emi62_set_reset(dev,1);
110 if (err < 0) { 126 if (err < 0) {
@@ -112,13 +128,18 @@ static int emi62_load_firmware (struct usb_device *dev)
112 goto wraperr; 128 goto wraperr;
113 } 129 }
114 130
131 rec = (const struct ihex_binrec *)loader_fw->data;
132
115 /* 1. We need to put the loader for the FPGA into the EZ-USB */ 133 /* 1. We need to put the loader for the FPGA into the EZ-USB */
116 for (i=0; g_emi62_loader[i].type == 0; i++) { 134 while (rec) {
117 err = emi62_writememory(dev, g_emi62_loader[i].address, g_emi62_loader[i].data, g_emi62_loader[i].length, ANCHOR_LOAD_INTERNAL); 135 err = emi62_writememory(dev, be32_to_cpu(rec->addr),
136 rec->data, be16_to_cpu(rec->len),
137 ANCHOR_LOAD_INTERNAL);
118 if (err < 0) { 138 if (err < 0) {
119 err("%s - error loading firmware: error = %d", __func__, err); 139 err("%s - error loading firmware: error = %d", __func__, err);
120 goto wraperr; 140 goto wraperr;
121 } 141 }
142 rec = ihex_next_binrec(rec);
122 } 143 }
123 144
124 /* De-assert reset (let the CPU run) */ 145 /* De-assert reset (let the CPU run) */
@@ -132,15 +153,16 @@ static int emi62_load_firmware (struct usb_device *dev)
132 /* 2. We upload the FPGA firmware into the EMI 153 /* 2. We upload the FPGA firmware into the EMI
133 * Note: collect up to 1023 (yes!) bytes and send them with 154 * Note: collect up to 1023 (yes!) bytes and send them with
134 * a single request. This is _much_ faster! */ 155 * a single request. This is _much_ faster! */
156 rec = (const struct ihex_binrec *)bitstream_fw->data;
135 do { 157 do {
136 i = 0; 158 i = 0;
137 addr = g_emi62bs[pos].address; 159 addr = be32_to_cpu(rec->addr);
138 160
139 /* intel hex records are terminated with type 0 element */ 161 /* intel hex records are terminated with type 0 element */
140 while ((g_emi62bs[pos].type == 0) && (i + g_emi62bs[pos].length < FW_LOAD_SIZE)) { 162 while (rec && (i + be16_to_cpu(rec->len) < FW_LOAD_SIZE)) {
141 memcpy(buf + i, g_emi62bs[pos].data, g_emi62bs[pos].length); 163 memcpy(buf + i, rec->data, be16_to_cpu(rec->len));
142 i += g_emi62bs[pos].length; 164 i += be16_to_cpu(rec->len);
143 pos++; 165 rec = ihex_next_binrec(rec);
144 } 166 }
145 err = emi62_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA); 167 err = emi62_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA);
146 if (err < 0) { 168 if (err < 0) {
@@ -157,8 +179,11 @@ static int emi62_load_firmware (struct usb_device *dev)
157 } 179 }
158 180
159 /* 3. We need to put the loader for the firmware into the EZ-USB (again...) */ 181 /* 3. We need to put the loader for the firmware into the EZ-USB (again...) */
160 for (i=0; g_emi62_loader[i].type == 0; i++) { 182 for (rec = (const struct ihex_binrec *)loader_fw->data;
161 err = emi62_writememory(dev, g_emi62_loader[i].address, g_emi62_loader[i].data, g_emi62_loader[i].length, ANCHOR_LOAD_INTERNAL); 183 rec; rec = ihex_next_binrec(rec)) {
184 err = emi62_writememory(dev, be32_to_cpu(rec->addr),
185 rec->data, be16_to_cpu(rec->len),
186 ANCHOR_LOAD_INTERNAL);
162 if (err < 0) { 187 if (err < 0) {
163 err("%s - error loading firmware: error = %d", __func__, err); 188 err("%s - error loading firmware: error = %d", __func__, err);
164 goto wraperr; 189 goto wraperr;
@@ -175,29 +200,19 @@ static int emi62_load_firmware (struct usb_device *dev)
175 200
176 /* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */ 201 /* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */
177 202
178/* FIXME: quick and dirty ifdefs */ 203 for (rec = (const struct ihex_binrec *)firmware_fw->data;
179#ifdef SPDIF 204 rec; rec = ihex_next_binrec(rec)) {
180 for (i=0; g_HexSpdifFw62[i].type == 0; i++) { 205 if (!INTERNAL_RAM(be32_to_cpu(rec->addr))) {
181 if (!INTERNAL_RAM(g_HexSpdifFw62[i].address)) { 206 err = emi62_writememory(dev, be32_to_cpu(rec->addr),
182 err = emi62_writememory(dev, g_HexSpdifFw62[i].address, g_HexSpdifFw62[i].data, g_HexSpdifFw62[i].length, ANCHOR_LOAD_EXTERNAL); 207 rec->data, be16_to_cpu(rec->len),
208 ANCHOR_LOAD_EXTERNAL);
183 if (err < 0) { 209 if (err < 0) {
184 err("%s - error loading firmware: error = %d", __func__, err); 210 err("%s - error loading firmware: error = %d", __func__, err);
185 goto wraperr; 211 goto wraperr;
186 } 212 }
187 } 213 }
188 } 214 }
189#else /* MIDI */ 215
190 for (i=0; g_HexMidiFw62[i].type == 0; i++) {
191 if (!INTERNAL_RAM(g_HexMidiFw62[i].address)) {
192 err = emi62_writememory(dev, g_HexMidiFw62[i].address, g_HexMidiFw62[i].data, g_HexMidiFw62[i].length, ANCHOR_LOAD_EXTERNAL);
193 if (err < 0) {
194 err("%s - error loading firmware: error = %d\n", __func__, err);
195 goto wraperr;
196 return err;
197 }
198 }
199 }
200#endif
201 /* Assert reset (stop the CPU in the EMI) */ 216 /* Assert reset (stop the CPU in the EMI) */
202 err = emi62_set_reset(dev,1); 217 err = emi62_set_reset(dev,1);
203 if (err < 0) { 218 if (err < 0) {
@@ -205,29 +220,19 @@ static int emi62_load_firmware (struct usb_device *dev)
205 goto wraperr; 220 goto wraperr;
206 } 221 }
207 222
208/* FIXME: quick and dirty ifdefs */ 223 for (rec = (const struct ihex_binrec *)firmware_fw->data;
209#ifdef SPDIF 224 rec; rec = ihex_next_binrec(rec)) {
210 for (i=0; g_HexSpdifFw62[i].type == 0; i++) { 225 if (INTERNAL_RAM(be32_to_cpu(rec->addr))) {
211 if (INTERNAL_RAM(g_HexSpdifFw62[i].address)) { 226 err = emi62_writememory(dev, be32_to_cpu(rec->addr),
212 err = emi62_writememory(dev, g_HexSpdifFw62[i].address, g_HexSpdifFw62[i].data, g_HexSpdifFw62[i].length, ANCHOR_LOAD_INTERNAL); 227 rec->data, be16_to_cpu(rec->len),
228 ANCHOR_LOAD_EXTERNAL);
213 if (err < 0) { 229 if (err < 0) {
214 err("%s - error loading firmware: error = %d", __func__, err); 230 err("%s - error loading firmware: error = %d", __func__, err);
215 goto wraperr; 231 goto wraperr;
216 } 232 }
217 } 233 }
218 } 234 }
219#else /* MIDI */ 235
220 for (i=0; g_HexMidiFw62[i].type == 0; i++) {
221 if (INTERNAL_RAM(g_HexMidiFw62[i].address)) {
222 err = emi62_writememory(dev, g_HexMidiFw62[i].address, g_HexMidiFw62[i].data, g_HexMidiFw62[i].length, ANCHOR_LOAD_INTERNAL);
223 if (err < 0) {
224 err("%s - error loading firmware: error = %d\n", __func__, err);
225 goto wraperr;
226 }
227 }
228 }
229#endif
230
231 /* De-assert reset (let the CPU run) */ 236 /* De-assert reset (let the CPU run) */
232 err = emi62_set_reset(dev,0); 237 err = emi62_set_reset(dev,0);
233 if (err < 0) { 238 if (err < 0) {
@@ -236,6 +241,10 @@ static int emi62_load_firmware (struct usb_device *dev)
236 } 241 }
237 msleep(250); /* let device settle */ 242 msleep(250); /* let device settle */
238 243
244 release_firmware(loader_fw);
245 release_firmware(bitstream_fw);
246 release_firmware(firmware_fw);
247
239 kfree(buf); 248 kfree(buf);
240 249
241 /* return 1 to fail the driver inialization 250 /* return 1 to fail the driver inialization
@@ -243,6 +252,10 @@ static int emi62_load_firmware (struct usb_device *dev)
243 return 1; 252 return 1;
244 253
245wraperr: 254wraperr:
255 release_firmware(loader_fw);
256 release_firmware(bitstream_fw);
257 release_firmware(firmware_fw);
258
246 kfree(buf); 259 kfree(buf);
247 dev_err(&dev->dev, "Error\n"); 260 dev_err(&dev->dev, "Error\n");
248 return err; 261 return err;
@@ -300,5 +313,8 @@ MODULE_AUTHOR("Tapio Laxström");
300MODULE_DESCRIPTION("Emagic EMI 6|2m firmware loader."); 313MODULE_DESCRIPTION("Emagic EMI 6|2m firmware loader.");
301MODULE_LICENSE("GPL"); 314MODULE_LICENSE("GPL");
302 315
316MODULE_FIRMWARE("emi62/loader.fw");
317MODULE_FIRMWARE("emi62/bitstream.fw");
318MODULE_FIRMWARE(FIRMWARE_FW);
303/* vi:ai:syntax=c:sw=8:ts=8:tw=80 319/* vi:ai:syntax=c:sw=8:ts=8:tw=80
304 */ 320 */