1 /* 2 * Emagic EMI 2|6 usb audio interface firmware loader. 3 * Copyright (C) 2002 4 * Tapio Laxström (tapio.laxstrom@iptime.fi) 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License, as published by 8 * the Free Software Foundation, version 2. 9 */ 10 #include <linux/kernel.h> 11 #include <linux/errno.h> 12 #include <linux/slab.h> 13 #include <linux/module.h> 14 #include <linux/usb.h> 15 #include <linux/delay.h> 16 #include <linux/firmware.h> 17 #include <linux/ihex.h> 18 19 /* include firmware (variables)*/ 20 21 /* FIXME: This is quick and dirty solution! */ 22 #define SPDIF /* if you want SPDIF comment next line */ 23 //#undef SPDIF /* if you want MIDI uncomment this line */ 24 25 #ifdef SPDIF 26 #define FIRMWARE_FW "emi62/spdif.fw" 27 #else 28 #define FIRMWARE_FW "emi62/midi.fw" 29 #endif 30 31 #define EMI62_VENDOR_ID 0x086a /* Emagic Soft-und Hardware GmBH */ 32 #define EMI62_PRODUCT_ID 0x0110 /* EMI 6|2m without firmware */ 33 34 #define ANCHOR_LOAD_INTERNAL 0xA0 /* Vendor specific request code for Anchor Upload/Download (This one is implemented in the core) */ 35 #define ANCHOR_LOAD_EXTERNAL 0xA3 /* This command is not implemented in the core. Requires firmware */ 36 #define ANCHOR_LOAD_FPGA 0xA5 /* This command is not implemented in the core. Requires firmware. Emagic extension */ 37 #define MAX_INTERNAL_ADDRESS 0x1B3F /* This is the highest internal RAM address for the AN2131Q */ 38 #define CPUCS_REG 0x7F92 /* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */ 39 #define INTERNAL_RAM(address) (address <= MAX_INTERNAL_ADDRESS) 40 41 static int emi62_writememory(struct usb_device *dev, int address, 42 const unsigned char *data, int length, 43 __u8 bRequest); 44 static int emi62_set_reset(struct usb_device *dev, unsigned char reset_bit); 45 static int emi62_load_firmware (struct usb_device *dev); 46 static int emi62_probe(struct usb_interface *intf, const struct usb_device_id *id); 47 static void emi62_disconnect(struct usb_interface *intf); 48 49 /* thanks to drivers/usb/serial/keyspan_pda.c code */ 50 static int emi62_writememory(struct usb_device *dev, int address, 51 const unsigned char *data, int length, 52 __u8 request) 53 { 54 int result; 55 unsigned char *buffer = kmemdup(data, length, GFP_KERNEL); 56 57 if (!buffer) { 58 dev_err(&dev->dev, "kmalloc(%d) failed.\n", length); 59 return -ENOMEM; 60 } 61 /* Note: usb_control_msg returns negative value on error or length of the 62 * data that was written! */ 63 result = usb_control_msg (dev, usb_sndctrlpipe(dev, 0), request, 0x40, address, 0, buffer, length, 300); 64 kfree (buffer); 65 return result; 66 } 67 68 /* thanks to drivers/usb/serial/keyspan_pda.c code */ 69 static int emi62_set_reset (struct usb_device *dev, unsigned char reset_bit) 70 { 71 int response; 72 dev_info(&dev->dev, "%s - %d\n", __func__, reset_bit); 73 74 response = emi62_writememory (dev, CPUCS_REG, &reset_bit, 1, 0xa0); 75 if (response < 0) 76 dev_err(&dev->dev, "set_reset (%d) failed\n", reset_bit); 77 return response; 78 } 79 80 #define FW_LOAD_SIZE 1023 81 82 static int emi62_load_firmware (struct usb_device *dev) 83 { 84 const struct firmware *loader_fw = NULL; 85 const struct firmware *bitstream_fw = NULL; 86 const struct firmware *firmware_fw = NULL; 87 const struct ihex_binrec *rec; 88 int err = -ENOMEM; 89 int i; 90 __u32 addr; /* Address to write */ 91 __u8 *buf; 92 93 dev_dbg(&dev->dev, "load_firmware\n"); 94 buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL); 95 if (!buf) 96 goto wraperr; 97 98 err = request_ihex_firmware(&loader_fw, "emi62/loader.fw", &dev->dev); 99 if (err) 100 goto nofw; 101 102 err = request_ihex_firmware(&bitstream_fw, "emi62/bitstream.fw", 103 &dev->dev); 104 if (err) 105 goto nofw; 106 107 err = request_ihex_firmware(&firmware_fw, FIRMWARE_FW, &dev->dev); 108 if (err) { 109 nofw: 110 goto wraperr; 111 } 112 113 /* Assert reset (stop the CPU in the EMI) */ 114 err = emi62_set_reset(dev,1); 115 if (err < 0) 116 goto wraperr; 117 118 rec = (const struct ihex_binrec *)loader_fw->data; 119 120 /* 1. We need to put the loader for the FPGA into the EZ-USB */ 121 while (rec) { 122 err = emi62_writememory(dev, be32_to_cpu(rec->addr), 123 rec->data, be16_to_cpu(rec->len), 124 ANCHOR_LOAD_INTERNAL); 125 if (err < 0) 126 goto wraperr; 127 rec = ihex_next_binrec(rec); 128 } 129 130 /* De-assert reset (let the CPU run) */ 131 err = emi62_set_reset(dev,0); 132 if (err < 0) 133 goto wraperr; 134 msleep(250); /* let device settle */ 135 136 /* 2. We upload the FPGA firmware into the EMI 137 * Note: collect up to 1023 (yes!) bytes and send them with 138 * a single request. This is _much_ faster! */ 139 rec = (const struct ihex_binrec *)bitstream_fw->data; 140 do { 141 i = 0; 142 addr = be32_to_cpu(rec->addr); 143 144 /* intel hex records are terminated with type 0 element */ 145 while (rec && (i + be16_to_cpu(rec->len) < FW_LOAD_SIZE)) { 146 memcpy(buf + i, rec->data, be16_to_cpu(rec->len)); 147 i += be16_to_cpu(rec->len); 148 rec = ihex_next_binrec(rec); 149 } 150 err = emi62_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA); 151 if (err < 0) 152 goto wraperr; 153 } while (rec); 154 155 /* Assert reset (stop the CPU in the EMI) */ 156 err = emi62_set_reset(dev,1); 157 if (err < 0) 158 goto wraperr; 159 160 /* 3. We need to put the loader for the firmware into the EZ-USB (again...) */ 161 for (rec = (const struct ihex_binrec *)loader_fw->data; 162 rec; rec = ihex_next_binrec(rec)) { 163 err = emi62_writememory(dev, be32_to_cpu(rec->addr), 164 rec->data, be16_to_cpu(rec->len), 165 ANCHOR_LOAD_INTERNAL); 166 if (err < 0) 167 goto wraperr; 168 } 169 170 /* De-assert reset (let the CPU run) */ 171 err = emi62_set_reset(dev,0); 172 if (err < 0) 173 goto wraperr; 174 msleep(250); /* let device settle */ 175 176 /* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */ 177 178 for (rec = (const struct ihex_binrec *)firmware_fw->data; 179 rec; rec = ihex_next_binrec(rec)) { 180 if (!INTERNAL_RAM(be32_to_cpu(rec->addr))) { 181 err = emi62_writememory(dev, be32_to_cpu(rec->addr), 182 rec->data, be16_to_cpu(rec->len), 183 ANCHOR_LOAD_EXTERNAL); 184 if (err < 0) 185 goto wraperr; 186 } 187 } 188 189 /* Assert reset (stop the CPU in the EMI) */ 190 err = emi62_set_reset(dev,1); 191 if (err < 0) 192 goto wraperr; 193 194 for (rec = (const struct ihex_binrec *)firmware_fw->data; 195 rec; rec = ihex_next_binrec(rec)) { 196 if (INTERNAL_RAM(be32_to_cpu(rec->addr))) { 197 err = emi62_writememory(dev, be32_to_cpu(rec->addr), 198 rec->data, be16_to_cpu(rec->len), 199 ANCHOR_LOAD_EXTERNAL); 200 if (err < 0) 201 goto wraperr; 202 } 203 } 204 205 /* De-assert reset (let the CPU run) */ 206 err = emi62_set_reset(dev,0); 207 if (err < 0) 208 goto wraperr; 209 msleep(250); /* let device settle */ 210 211 release_firmware(loader_fw); 212 release_firmware(bitstream_fw); 213 release_firmware(firmware_fw); 214 215 kfree(buf); 216 217 /* return 1 to fail the driver inialization 218 * and give real driver change to load */ 219 return 1; 220 221 wraperr: 222 if (err < 0) 223 dev_err(&dev->dev,"%s - error loading firmware: error = %d\n", 224 __func__, err); 225 release_firmware(loader_fw); 226 release_firmware(bitstream_fw); 227 release_firmware(firmware_fw); 228 229 kfree(buf); 230 dev_err(&dev->dev, "Error\n"); 231 return err; 232 } 233 234 static const struct usb_device_id id_table[] = { 235 { USB_DEVICE(EMI62_VENDOR_ID, EMI62_PRODUCT_ID) }, 236 { } /* Terminating entry */ 237 }; 238 239 MODULE_DEVICE_TABLE (usb, id_table); 240 241 static int emi62_probe(struct usb_interface *intf, const struct usb_device_id *id) 242 { 243 struct usb_device *dev = interface_to_usbdev(intf); 244 dev_dbg(&intf->dev, "emi62_probe\n"); 245 246 dev_info(&intf->dev, "%s start\n", __func__); 247 248 emi62_load_firmware(dev); 249 250 /* do not return the driver context, let real audio driver do that */ 251 return -EIO; 252 } 253 254 static void emi62_disconnect(struct usb_interface *intf) 255 { 256 } 257 258 static struct usb_driver emi62_driver = { 259 .name = "emi62 - firmware loader", 260 .probe = emi62_probe, 261 .disconnect = emi62_disconnect, 262 .id_table = id_table, 263 }; 264 265 module_usb_driver(emi62_driver); 266 267 MODULE_AUTHOR("Tapio Laxström"); 268 MODULE_DESCRIPTION("Emagic EMI 6|2m firmware loader."); 269 MODULE_LICENSE("GPL"); 270 271 MODULE_FIRMWARE("emi62/loader.fw"); 272 MODULE_FIRMWARE("emi62/bitstream.fw"); 273 MODULE_FIRMWARE(FIRMWARE_FW); 274 /* vi:ai:syntax=c:sw=8:ts=8:tw=80 275 */ 276