1
2
3
4
5
6
7
8
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
20
21
22#define SPDIF
23
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
32#define EMI62_PRODUCT_ID 0x0110
33
34#define ANCHOR_LOAD_INTERNAL 0xA0
35#define ANCHOR_LOAD_EXTERNAL 0xA3
36#define ANCHOR_LOAD_FPGA 0xA5
37#define MAX_INTERNAL_ADDRESS 0x1B3F
38#define CPUCS_REG 0x7F92
39#define INTERNAL_RAM(address) (address <= MAX_INTERNAL_ADDRESS)
40
41static int emi62_writememory(struct usb_device *dev, int address,
42 const unsigned char *data, int length,
43 __u8 bRequest);
44static int emi62_set_reset(struct usb_device *dev, unsigned char reset_bit);
45static int emi62_load_firmware (struct usb_device *dev);
46static int emi62_probe(struct usb_interface *intf, const struct usb_device_id *id);
47static void emi62_disconnect(struct usb_interface *intf);
48
49
50static 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
62
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
69static 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
82static 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;
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
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
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
131 err = emi62_set_reset(dev,0);
132 if (err < 0)
133 goto wraperr;
134 msleep(250);
135
136
137
138
139 rec = (const struct ihex_binrec *)bitstream_fw->data;
140 do {
141 i = 0;
142 addr = be32_to_cpu(rec->addr);
143
144
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
156 err = emi62_set_reset(dev,1);
157 if (err < 0)
158 goto wraperr;
159
160
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
171 err = emi62_set_reset(dev,0);
172 if (err < 0)
173 goto wraperr;
174 msleep(250);
175
176
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
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
206 err = emi62_set_reset(dev,0);
207 if (err < 0)
208 goto wraperr;
209 msleep(250);
210
211 release_firmware(loader_fw);
212 release_firmware(bitstream_fw);
213 release_firmware(firmware_fw);
214
215 kfree(buf);
216
217
218
219 return 1;
220
221wraperr:
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
234static const struct usb_device_id id_table[] = {
235 { USB_DEVICE(EMI62_VENDOR_ID, EMI62_PRODUCT_ID) },
236 { }
237};
238
239MODULE_DEVICE_TABLE (usb, id_table);
240
241static 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
251 return -EIO;
252}
253
254static void emi62_disconnect(struct usb_interface *intf)
255{
256}
257
258static 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
265module_usb_driver(emi62_driver);
266
267MODULE_AUTHOR("Tapio Laxström");
268MODULE_DESCRIPTION("Emagic EMI 6|2m firmware loader.");
269MODULE_LICENSE("GPL");
270
271MODULE_FIRMWARE("emi62/loader.fw");
272MODULE_FIRMWARE("emi62/bitstream.fw");
273MODULE_FIRMWARE(FIRMWARE_FW);
274
275
276