diff options
Diffstat (limited to 'sound/pci/rme9652')
-rw-r--r-- | sound/pci/rme9652/hdsp.c | 62 |
1 files changed, 34 insertions, 28 deletions
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 0d6930c4f4b7..b8ddbb18f141 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
@@ -59,13 +59,11 @@ MODULE_LICENSE("GPL"); | |||
59 | MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," | 59 | MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," |
60 | "{RME HDSP-9652}," | 60 | "{RME HDSP-9652}," |
61 | "{RME HDSP-9632}}"); | 61 | "{RME HDSP-9632}}"); |
62 | #ifdef HDSP_FW_LOADER | ||
63 | MODULE_FIRMWARE("rpm_firmware.bin"); | 62 | MODULE_FIRMWARE("rpm_firmware.bin"); |
64 | MODULE_FIRMWARE("multiface_firmware.bin"); | 63 | MODULE_FIRMWARE("multiface_firmware.bin"); |
65 | MODULE_FIRMWARE("multiface_firmware_rev11.bin"); | 64 | MODULE_FIRMWARE("multiface_firmware_rev11.bin"); |
66 | MODULE_FIRMWARE("digiface_firmware.bin"); | 65 | MODULE_FIRMWARE("digiface_firmware.bin"); |
67 | MODULE_FIRMWARE("digiface_firmware_rev11.bin"); | 66 | MODULE_FIRMWARE("digiface_firmware_rev11.bin"); |
68 | #endif | ||
69 | 67 | ||
70 | #define HDSP_MAX_CHANNELS 26 | 68 | #define HDSP_MAX_CHANNELS 26 |
71 | #define HDSP_MAX_DS_CHANNELS 14 | 69 | #define HDSP_MAX_DS_CHANNELS 14 |
@@ -423,12 +421,7 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin"); | |||
423 | #define HDSP_DMA_AREA_BYTES ((HDSP_MAX_CHANNELS+1) * HDSP_CHANNEL_BUFFER_BYTES) | 421 | #define HDSP_DMA_AREA_BYTES ((HDSP_MAX_CHANNELS+1) * HDSP_CHANNEL_BUFFER_BYTES) |
424 | #define HDSP_DMA_AREA_KILOBYTES (HDSP_DMA_AREA_BYTES/1024) | 422 | #define HDSP_DMA_AREA_KILOBYTES (HDSP_DMA_AREA_BYTES/1024) |
425 | 423 | ||
426 | /* use hotplug firmware loader? */ | 424 | #define HDSP_FIRMWARE_SIZE (24413 * 4) |
427 | #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) | ||
428 | #if !defined(HDSP_USE_HWDEP_LOADER) | ||
429 | #define HDSP_FW_LOADER | ||
430 | #endif | ||
431 | #endif | ||
432 | 425 | ||
433 | struct hdsp_9632_meters { | 426 | struct hdsp_9632_meters { |
434 | u32 input_peak[16]; | 427 | u32 input_peak[16]; |
@@ -475,7 +468,8 @@ struct hdsp { | |||
475 | enum HDSP_IO_Type io_type; /* ditto, but for code use */ | 468 | enum HDSP_IO_Type io_type; /* ditto, but for code use */ |
476 | unsigned short firmware_rev; | 469 | unsigned short firmware_rev; |
477 | unsigned short state; /* stores state bits */ | 470 | unsigned short state; /* stores state bits */ |
478 | u32 firmware_cache[24413]; /* this helps recover from accidental iobox power failure */ | 471 | const struct firmware *firmware; |
472 | u32 *fw_uploaded; | ||
479 | size_t period_bytes; /* guess what this is */ | 473 | size_t period_bytes; /* guess what this is */ |
480 | unsigned char max_channels; | 474 | unsigned char max_channels; |
481 | unsigned char qs_in_channels; /* quad speed mode for H9632 */ | 475 | unsigned char qs_in_channels; /* quad speed mode for H9632 */ |
@@ -712,6 +706,17 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) { | |||
712 | 706 | ||
713 | int i; | 707 | int i; |
714 | unsigned long flags; | 708 | unsigned long flags; |
709 | const u32 *cache; | ||
710 | |||
711 | if (hdsp->fw_uploaded) | ||
712 | cache = hdsp->fw_uploaded; | ||
713 | else { | ||
714 | if (!hdsp->firmware) | ||
715 | return -ENODEV; | ||
716 | cache = (u32 *)hdsp->firmware->data; | ||
717 | if (!cache) | ||
718 | return -ENODEV; | ||
719 | } | ||
715 | 720 | ||
716 | if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { | 721 | if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { |
717 | 722 | ||
@@ -727,8 +732,8 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) { | |||
727 | 732 | ||
728 | hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); | 733 | hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); |
729 | 734 | ||
730 | for (i = 0; i < 24413; ++i) { | 735 | for (i = 0; i < HDSP_FIRMWARE_SIZE / 4; ++i) { |
731 | hdsp_write(hdsp, HDSP_fifoData, hdsp->firmware_cache[i]); | 736 | hdsp_write(hdsp, HDSP_fifoData, cache[i]); |
732 | if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) { | 737 | if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) { |
733 | snd_printk ("Hammerfall-DSP: timeout during firmware loading\n"); | 738 | snd_printk ("Hammerfall-DSP: timeout during firmware loading\n"); |
734 | return -EIO; | 739 | return -EIO; |
@@ -798,9 +803,7 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp) | |||
798 | } | 803 | } |
799 | 804 | ||
800 | 805 | ||
801 | #ifdef HDSP_FW_LOADER | ||
802 | static int hdsp_request_fw_loader(struct hdsp *hdsp); | 806 | static int hdsp_request_fw_loader(struct hdsp *hdsp); |
803 | #endif | ||
804 | 807 | ||
805 | static int hdsp_check_for_firmware (struct hdsp *hdsp, int load_on_demand) | 808 | static int hdsp_check_for_firmware (struct hdsp *hdsp, int load_on_demand) |
806 | { | 809 | { |
@@ -813,10 +816,8 @@ static int hdsp_check_for_firmware (struct hdsp *hdsp, int load_on_demand) | |||
813 | snd_printk(KERN_ERR "Hammerfall-DSP: firmware not present.\n"); | 816 | snd_printk(KERN_ERR "Hammerfall-DSP: firmware not present.\n"); |
814 | /* try to load firmware */ | 817 | /* try to load firmware */ |
815 | if (! (hdsp->state & HDSP_FirmwareCached)) { | 818 | if (! (hdsp->state & HDSP_FirmwareCached)) { |
816 | #ifdef HDSP_FW_LOADER | ||
817 | if (! hdsp_request_fw_loader(hdsp)) | 819 | if (! hdsp_request_fw_loader(hdsp)) |
818 | return 0; | 820 | return 0; |
819 | #endif | ||
820 | snd_printk(KERN_ERR | 821 | snd_printk(KERN_ERR |
821 | "Hammerfall-DSP: No firmware loaded nor " | 822 | "Hammerfall-DSP: No firmware loaded nor " |
822 | "cached, please upload firmware.\n"); | 823 | "cached, please upload firmware.\n"); |
@@ -3673,9 +3674,7 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) | |||
3673 | } | 3674 | } |
3674 | } else { | 3675 | } else { |
3675 | int err = -EINVAL; | 3676 | int err = -EINVAL; |
3676 | #ifdef HDSP_FW_LOADER | ||
3677 | err = hdsp_request_fw_loader(hdsp); | 3677 | err = hdsp_request_fw_loader(hdsp); |
3678 | #endif | ||
3679 | if (err < 0) { | 3678 | if (err < 0) { |
3680 | snd_iprintf(buffer, | 3679 | snd_iprintf(buffer, |
3681 | "No firmware loaded nor cached, " | 3680 | "No firmware loaded nor cached, " |
@@ -5100,8 +5099,18 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne | |||
5100 | if (hdsp_check_for_iobox (hdsp)) | 5099 | if (hdsp_check_for_iobox (hdsp)) |
5101 | return -EIO; | 5100 | return -EIO; |
5102 | 5101 | ||
5103 | if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(hdsp->firmware_cache)) != 0) | 5102 | if (!hdsp->fw_uploaded) { |
5103 | hdsp->fw_uploaded = vmalloc(HDSP_FIRMWARE_SIZE); | ||
5104 | if (!hdsp->fw_uploaded) | ||
5105 | return -ENOMEM; | ||
5106 | } | ||
5107 | |||
5108 | if (copy_from_user(hdsp->fw_uploaded, firmware_data, | ||
5109 | HDSP_FIRMWARE_SIZE)) { | ||
5110 | vfree(hdsp->fw_uploaded); | ||
5111 | hdsp->fw_uploaded = NULL; | ||
5104 | return -EFAULT; | 5112 | return -EFAULT; |
5113 | } | ||
5105 | 5114 | ||
5106 | hdsp->state |= HDSP_FirmwareCached; | 5115 | hdsp->state |= HDSP_FirmwareCached; |
5107 | 5116 | ||
@@ -5330,7 +5339,6 @@ static int snd_hdsp_create_alsa_devices(struct snd_card *card, struct hdsp *hdsp | |||
5330 | return 0; | 5339 | return 0; |
5331 | } | 5340 | } |
5332 | 5341 | ||
5333 | #ifdef HDSP_FW_LOADER | ||
5334 | /* load firmware via hotplug fw loader */ | 5342 | /* load firmware via hotplug fw loader */ |
5335 | static int hdsp_request_fw_loader(struct hdsp *hdsp) | 5343 | static int hdsp_request_fw_loader(struct hdsp *hdsp) |
5336 | { | 5344 | { |
@@ -5373,16 +5381,13 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp) | |||
5373 | snd_printk(KERN_ERR "Hammerfall-DSP: cannot load firmware %s\n", fwfile); | 5381 | snd_printk(KERN_ERR "Hammerfall-DSP: cannot load firmware %s\n", fwfile); |
5374 | return -ENOENT; | 5382 | return -ENOENT; |
5375 | } | 5383 | } |
5376 | if (fw->size < sizeof(hdsp->firmware_cache)) { | 5384 | if (fw->size < HDSP_FIRMWARE_SIZE) { |
5377 | snd_printk(KERN_ERR "Hammerfall-DSP: too short firmware size %d (expected %d)\n", | 5385 | snd_printk(KERN_ERR "Hammerfall-DSP: too short firmware size %d (expected %d)\n", |
5378 | (int)fw->size, (int)sizeof(hdsp->firmware_cache)); | 5386 | (int)fw->size, HDSP_FIRMWARE_SIZE); |
5379 | release_firmware(fw); | ||
5380 | return -EINVAL; | 5387 | return -EINVAL; |
5381 | } | 5388 | } |
5382 | 5389 | ||
5383 | memcpy(hdsp->firmware_cache, fw->data, sizeof(hdsp->firmware_cache)); | 5390 | hdsp->firmware = fw; |
5384 | |||
5385 | release_firmware(fw); | ||
5386 | 5391 | ||
5387 | hdsp->state |= HDSP_FirmwareCached; | 5392 | hdsp->state |= HDSP_FirmwareCached; |
5388 | 5393 | ||
@@ -5406,7 +5411,6 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp) | |||
5406 | } | 5411 | } |
5407 | return 0; | 5412 | return 0; |
5408 | } | 5413 | } |
5409 | #endif | ||
5410 | 5414 | ||
5411 | static int __devinit snd_hdsp_create(struct snd_card *card, | 5415 | static int __devinit snd_hdsp_create(struct snd_card *card, |
5412 | struct hdsp *hdsp) | 5416 | struct hdsp *hdsp) |
@@ -5504,7 +5508,6 @@ static int __devinit snd_hdsp_create(struct snd_card *card, | |||
5504 | return err; | 5508 | return err; |
5505 | 5509 | ||
5506 | if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { | 5510 | if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { |
5507 | #ifdef HDSP_FW_LOADER | ||
5508 | if ((err = hdsp_request_fw_loader(hdsp)) < 0) | 5511 | if ((err = hdsp_request_fw_loader(hdsp)) < 0) |
5509 | /* we don't fail as this can happen | 5512 | /* we don't fail as this can happen |
5510 | if userspace is not ready for | 5513 | if userspace is not ready for |
@@ -5514,7 +5517,6 @@ static int __devinit snd_hdsp_create(struct snd_card *card, | |||
5514 | else | 5517 | else |
5515 | /* init is complete, we return */ | 5518 | /* init is complete, we return */ |
5516 | return 0; | 5519 | return 0; |
5517 | #endif | ||
5518 | /* we defer initialization */ | 5520 | /* we defer initialization */ |
5519 | snd_printk(KERN_INFO "Hammerfall-DSP: card initialization pending : waiting for firmware\n"); | 5521 | snd_printk(KERN_INFO "Hammerfall-DSP: card initialization pending : waiting for firmware\n"); |
5520 | if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) | 5522 | if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) |
@@ -5568,6 +5570,10 @@ static int snd_hdsp_free(struct hdsp *hdsp) | |||
5568 | 5570 | ||
5569 | snd_hdsp_free_buffers(hdsp); | 5571 | snd_hdsp_free_buffers(hdsp); |
5570 | 5572 | ||
5573 | if (hdsp->firmware) | ||
5574 | release_firmware(hdsp->firmware); | ||
5575 | vfree(hdsp->fw_uploaded); | ||
5576 | |||
5571 | if (hdsp->iobase) | 5577 | if (hdsp->iobase) |
5572 | iounmap(hdsp->iobase); | 5578 | iounmap(hdsp->iobase); |
5573 | 5579 | ||