diff options
author | James Courtier-Dutton <James@superbug.co.uk> | 2007-07-23 12:52:27 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2007-10-16 09:57:51 -0400 |
commit | 42f53226953b0f2ad16bf55d0c11e08fe86c3666 (patch) | |
tree | 0af9ae1b05ef0510e902e840c00c200814b361ab /sound/pci/emu10k1/emu10k1_main.c | |
parent | 177a7cdbd1d88be5cbf957a2793a59ffa50cbef9 (diff) |
[ALSA] snd-emu10k1:Improves firmware loading for E-Mu cards.
Details:
Fixes http://bugzilla.kernel.org/show_bug.cgi?id=8176
Signed-off-by: James Courtier-Dutton <James@superbug.co.uk>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/emu10k1/emu10k1_main.c')
-rw-r--r-- | sound/pci/emu10k1/emu10k1_main.c | 103 |
1 files changed, 61 insertions, 42 deletions
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 404ae1be0a4b..800d6348de71 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c | |||
@@ -31,6 +31,8 @@ | |||
31 | * | 31 | * |
32 | */ | 32 | */ |
33 | 33 | ||
34 | #include <linux/sched.h> | ||
35 | #include <linux/kthread.h> | ||
34 | #include <sound/driver.h> | 36 | #include <sound/driver.h> |
35 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
36 | #include <linux/init.h> | 38 | #include <linux/init.h> |
@@ -702,6 +704,59 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file | |||
702 | return 0; | 704 | return 0; |
703 | } | 705 | } |
704 | 706 | ||
707 | int emu1010_firmware_thread(void *data) { | ||
708 | struct snd_emu10k1 * emu = data; | ||
709 | int tmp,tmp2; | ||
710 | int reg; | ||
711 | int err; | ||
712 | |||
713 | for (;;) { | ||
714 | /* Delay to allow Audio Dock to settle */ | ||
715 | msleep(1000); | ||
716 | if (kthread_should_stop()) | ||
717 | break; | ||
718 | snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */ | ||
719 | snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® ); /* OPTIONS: Which cards are attached to the EMU */ | ||
720 | if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) { | ||
721 | /* Audio Dock attached */ | ||
722 | /* Return to Audio Dock programming mode */ | ||
723 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); | ||
724 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); | ||
725 | if (emu->card_capabilities->emu1010 == 1) { | ||
726 | if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { | ||
727 | return err; | ||
728 | } | ||
729 | } else if (emu->card_capabilities->emu1010 == 2) { | ||
730 | if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { | ||
731 | return err; | ||
732 | } | ||
733 | } else if (emu->card_capabilities->emu1010 == 3) { | ||
734 | if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { | ||
735 | return err; | ||
736 | } | ||
737 | } | ||
738 | |||
739 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); | ||
740 | snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, ® ); | ||
741 | snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg); | ||
742 | /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ | ||
743 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); | ||
744 | snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg); | ||
745 | if ((reg & 0x1f) != 0x15) { | ||
746 | /* FPGA failed to be programmed */ | ||
747 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg); | ||
748 | return 0; | ||
749 | return -ENODEV; | ||
750 | } | ||
751 | snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n"); | ||
752 | snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp ); | ||
753 | snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2 ); | ||
754 | snd_printk("Audio Dock ver:%d.%d\n",tmp ,tmp2); | ||
755 | } | ||
756 | } | ||
757 | return 0; | ||
758 | } | ||
759 | |||
705 | /* | 760 | /* |
706 | * EMU-1010 - details found out from this driver, official MS Win drivers, | 761 | * EMU-1010 - details found out from this driver, official MS Win drivers, |
707 | * testing the card: | 762 | * testing the card: |
@@ -1004,49 +1059,12 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) | |||
1004 | snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp ); | 1059 | snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp ); |
1005 | snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); /* SPDIF Format spdif (or 0x11 for aes/ebu) */ | 1060 | snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); /* SPDIF Format spdif (or 0x11 for aes/ebu) */ |
1006 | 1061 | ||
1007 | /* Delay to allow Audio Dock to settle */ | 1062 | /* Start Micro/Audio Dock firmware loader thread */ |
1008 | msleep(100); | 1063 | emu->emu1010.firmware_thread = kthread_create(&emu1010_firmware_thread, |
1009 | snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */ | 1064 | emu, |
1010 | snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® ); /* OPTIONS: Which cards are attached to the EMU */ | 1065 | "emu1010_firmware"); |
1011 | /* FIXME: The loading of this should be able to happen any time, | 1066 | wake_up_process(emu->emu1010.firmware_thread); |
1012 | * as the user can plug/unplug it at any time | ||
1013 | */ | ||
1014 | if (reg & (EMU_HANA_OPTION_DOCK_ONLINE | EMU_HANA_OPTION_DOCK_OFFLINE) ) { | ||
1015 | /* Audio Dock attached */ | ||
1016 | /* Return to Audio Dock programming mode */ | ||
1017 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); | ||
1018 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); | ||
1019 | if (emu->card_capabilities->emu1010 == 1) { | ||
1020 | if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { | ||
1021 | return err; | ||
1022 | } | ||
1023 | } else if (emu->card_capabilities->emu1010 == 2) { | ||
1024 | if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { | ||
1025 | return err; | ||
1026 | } | ||
1027 | } else if (emu->card_capabilities->emu1010 == 3) { | ||
1028 | if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { | ||
1029 | return err; | ||
1030 | } | ||
1031 | } | ||
1032 | 1067 | ||
1033 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); | ||
1034 | snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, ® ); | ||
1035 | snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg); | ||
1036 | /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ | ||
1037 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); | ||
1038 | snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg); | ||
1039 | if ((reg & 0x3f) != 0x15) { | ||
1040 | /* FPGA failed to be programmed */ | ||
1041 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg); | ||
1042 | return 0; | ||
1043 | return -ENODEV; | ||
1044 | } | ||
1045 | snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n"); | ||
1046 | snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp ); | ||
1047 | snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2 ); | ||
1048 | snd_printk("Audio Dock ver:%d.%d\n",tmp ,tmp2); | ||
1049 | } | ||
1050 | #if 0 | 1068 | #if 0 |
1051 | snd_emu1010_fpga_link_dst_src_write(emu, | 1069 | snd_emu1010_fpga_link_dst_src_write(emu, |
1052 | EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32B + 2); /* ALICE2 bus 0xa2 */ | 1070 | EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32B + 2); /* ALICE2 bus 0xa2 */ |
@@ -1173,6 +1191,7 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu) | |||
1173 | if (emu->card_capabilities->emu1010) { | 1191 | if (emu->card_capabilities->emu1010) { |
1174 | /* Disable 48Volt power to Audio Dock */ | 1192 | /* Disable 48Volt power to Audio Dock */ |
1175 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 ); | 1193 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 ); |
1194 | kthread_stop(emu->emu1010.firmware_thread); | ||
1176 | } | 1195 | } |
1177 | if (emu->memhdr) | 1196 | if (emu->memhdr) |
1178 | snd_util_memhdr_free(emu->memhdr); | 1197 | snd_util_memhdr_free(emu->memhdr); |