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