diff options
-rw-r--r-- | sound/usb/6fire/firmware.c | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c index 9081a54a9c6c..e720035fbd1e 100644 --- a/sound/usb/6fire/firmware.c +++ b/sound/usb/6fire/firmware.c | |||
@@ -3,12 +3,6 @@ | |||
3 | * | 3 | * |
4 | * Firmware loader | 4 | * Firmware loader |
5 | * | 5 | * |
6 | * Currently not working for all devices. To be able to use the device | ||
7 | * in linux, it is also possible to let the windows driver upload the firmware. | ||
8 | * For that, start the computer in windows and reboot. | ||
9 | * As long as the device is connected to the power supply, no firmware reload | ||
10 | * needs to be performed. | ||
11 | * | ||
12 | * Author: Torsten Schenk <torsten.schenk@zoho.com> | 6 | * Author: Torsten Schenk <torsten.schenk@zoho.com> |
13 | * Created: Jan 01, 2011 | 7 | * Created: Jan 01, 2011 |
14 | * Version: 0.3.0 | 8 | * Version: 0.3.0 |
@@ -72,6 +66,10 @@ static const u8 ep_w_max_packet_size[] = { | |||
72 | 0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */ | 66 | 0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */ |
73 | }; | 67 | }; |
74 | 68 | ||
69 | static const u8 known_fw_versions[][4] = { | ||
70 | { 0x03, 0x01, 0x0b, 0x00 } | ||
71 | }; | ||
72 | |||
75 | struct ihex_record { | 73 | struct ihex_record { |
76 | u16 address; | 74 | u16 address; |
77 | u8 len; | 75 | u8 len; |
@@ -363,6 +361,25 @@ static int usb6fire_fw_fpga_upload( | |||
363 | return 0; | 361 | return 0; |
364 | } | 362 | } |
365 | 363 | ||
364 | /* check, if the firmware version the devices has currently loaded | ||
365 | * is known by this driver. 'version' needs to have 4 bytes version | ||
366 | * info data. */ | ||
367 | static int usb6fire_fw_check(u8 *version) | ||
368 | { | ||
369 | int i; | ||
370 | |||
371 | for (i = 0; i < ARRAY_SIZE(known_fw_versions); i++) | ||
372 | if (!memcmp(version, known_fw_versions + i, 4)) | ||
373 | return 0; | ||
374 | |||
375 | snd_printk(KERN_ERR PREFIX "invalid fimware version in device: " | ||
376 | "%02x %02x %02x %02x. " | ||
377 | "please reconnect to power. if this failure " | ||
378 | "still happens, check your firmware installation.", | ||
379 | version[0], version[1], version[2], version[3]); | ||
380 | return -EINVAL; | ||
381 | } | ||
382 | |||
366 | int usb6fire_fw_init(struct usb_interface *intf) | 383 | int usb6fire_fw_init(struct usb_interface *intf) |
367 | { | 384 | { |
368 | int i; | 385 | int i; |
@@ -378,9 +395,7 @@ int usb6fire_fw_init(struct usb_interface *intf) | |||
378 | "firmware state.\n"); | 395 | "firmware state.\n"); |
379 | return ret; | 396 | return ret; |
380 | } | 397 | } |
381 | if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55 | 398 | if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55) { |
382 | || buffer[4] != 0x03 || buffer[5] != 0x01 || buffer[7] | ||
383 | != 0x00) { | ||
384 | snd_printk(KERN_ERR PREFIX "unknown device firmware state " | 399 | snd_printk(KERN_ERR PREFIX "unknown device firmware state " |
385 | "received from device: "); | 400 | "received from device: "); |
386 | for (i = 0; i < 8; i++) | 401 | for (i = 0; i < 8; i++) |
@@ -389,7 +404,7 @@ int usb6fire_fw_init(struct usb_interface *intf) | |||
389 | return -EIO; | 404 | return -EIO; |
390 | } | 405 | } |
391 | /* do we need fpga loader ezusb firmware? */ | 406 | /* do we need fpga loader ezusb firmware? */ |
392 | if (buffer[3] == 0x01 && buffer[6] == 0x19) { | 407 | if (buffer[3] == 0x01) { |
393 | ret = usb6fire_fw_ezusb_upload(intf, | 408 | ret = usb6fire_fw_ezusb_upload(intf, |
394 | "6fire/dmx6firel2.ihx", 0, NULL, 0); | 409 | "6fire/dmx6firel2.ihx", 0, NULL, 0); |
395 | if (ret < 0) | 410 | if (ret < 0) |
@@ -397,7 +412,10 @@ int usb6fire_fw_init(struct usb_interface *intf) | |||
397 | return FW_NOT_READY; | 412 | return FW_NOT_READY; |
398 | } | 413 | } |
399 | /* do we need fpga firmware and application ezusb firmware? */ | 414 | /* do we need fpga firmware and application ezusb firmware? */ |
400 | else if (buffer[3] == 0x02 && buffer[6] == 0x0b) { | 415 | else if (buffer[3] == 0x02) { |
416 | ret = usb6fire_fw_check(buffer + 4); | ||
417 | if (ret < 0) | ||
418 | return ret; | ||
401 | ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin"); | 419 | ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin"); |
402 | if (ret < 0) | 420 | if (ret < 0) |
403 | return ret; | 421 | return ret; |
@@ -410,8 +428,8 @@ int usb6fire_fw_init(struct usb_interface *intf) | |||
410 | return FW_NOT_READY; | 428 | return FW_NOT_READY; |
411 | } | 429 | } |
412 | /* all fw loaded? */ | 430 | /* all fw loaded? */ |
413 | else if (buffer[3] == 0x03 && buffer[6] == 0x0b) | 431 | else if (buffer[3] == 0x03) |
414 | return 0; | 432 | return usb6fire_fw_check(buffer + 4); |
415 | /* unknown data? */ | 433 | /* unknown data? */ |
416 | else { | 434 | else { |
417 | snd_printk(KERN_ERR PREFIX "unknown device firmware state " | 435 | snd_printk(KERN_ERR PREFIX "unknown device firmware state " |