1
0
Fork 0

ALSA: 6fire - Improve firmware loader

Firmware loader: magical device bytes check updated (accepts all device
versions now and accepts possibly loaded firmware, if it is knowing to
be working)

Signed-off-by: Torsten Schenk <torsten.schenk@zoho.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
hifive-unleashed-5.1
Torsten Schenk 2011-04-04 11:49:57 +02:00 committed by Takashi Iwai
parent 58c54fa47f
commit b84610b95f
1 changed files with 31 additions and 13 deletions

View File

@ -3,12 +3,6 @@
*
* Firmware loader
*
* Currently not working for all devices. To be able to use the device
* in linux, it is also possible to let the windows driver upload the firmware.
* For that, start the computer in windows and reboot.
* As long as the device is connected to the power supply, no firmware reload
* needs to be performed.
*
* Author: Torsten Schenk <torsten.schenk@zoho.com>
* Created: Jan 01, 2011
* Version: 0.3.0
@ -72,6 +66,10 @@ static const u8 ep_w_max_packet_size[] = {
0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */
};
static const u8 known_fw_versions[][4] = {
{ 0x03, 0x01, 0x0b, 0x00 }
};
struct ihex_record {
u16 address;
u8 len;
@ -363,6 +361,25 @@ static int usb6fire_fw_fpga_upload(
return 0;
}
/* check, if the firmware version the devices has currently loaded
* is known by this driver. 'version' needs to have 4 bytes version
* info data. */
static int usb6fire_fw_check(u8 *version)
{
int i;
for (i = 0; i < ARRAY_SIZE(known_fw_versions); i++)
if (!memcmp(version, known_fw_versions + i, 4))
return 0;
snd_printk(KERN_ERR PREFIX "invalid fimware version in device: "
"%02x %02x %02x %02x. "
"please reconnect to power. if this failure "
"still happens, check your firmware installation.",
version[0], version[1], version[2], version[3]);
return -EINVAL;
}
int usb6fire_fw_init(struct usb_interface *intf)
{
int i;
@ -378,9 +395,7 @@ int usb6fire_fw_init(struct usb_interface *intf)
"firmware state.\n");
return ret;
}
if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55
|| buffer[4] != 0x03 || buffer[5] != 0x01 || buffer[7]
!= 0x00) {
if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55) {
snd_printk(KERN_ERR PREFIX "unknown device firmware state "
"received from device: ");
for (i = 0; i < 8; i++)
@ -389,7 +404,7 @@ int usb6fire_fw_init(struct usb_interface *intf)
return -EIO;
}
/* do we need fpga loader ezusb firmware? */
if (buffer[3] == 0x01 && buffer[6] == 0x19) {
if (buffer[3] == 0x01) {
ret = usb6fire_fw_ezusb_upload(intf,
"6fire/dmx6firel2.ihx", 0, NULL, 0);
if (ret < 0)
@ -397,7 +412,10 @@ int usb6fire_fw_init(struct usb_interface *intf)
return FW_NOT_READY;
}
/* do we need fpga firmware and application ezusb firmware? */
else if (buffer[3] == 0x02 && buffer[6] == 0x0b) {
else if (buffer[3] == 0x02) {
ret = usb6fire_fw_check(buffer + 4);
if (ret < 0)
return ret;
ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin");
if (ret < 0)
return ret;
@ -410,8 +428,8 @@ int usb6fire_fw_init(struct usb_interface *intf)
return FW_NOT_READY;
}
/* all fw loaded? */
else if (buffer[3] == 0x03 && buffer[6] == 0x0b)
return 0;
else if (buffer[3] == 0x03)
return usb6fire_fw_check(buffer + 4);
/* unknown data? */
else {
snd_printk(KERN_ERR PREFIX "unknown device firmware state "