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