aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorJames Courtier-Dutton <James@superbug.co.uk>2007-07-23 12:52:27 -0400
committerJaroslav Kysela <perex@perex.cz>2007-10-16 09:57:51 -0400
commit42f53226953b0f2ad16bf55d0c11e08fe86c3666 (patch)
tree0af9ae1b05ef0510e902e840c00c200814b361ab /sound
parent177a7cdbd1d88be5cbf957a2793a59ffa50cbef9 (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')
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c103
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
707int 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, &reg ); /* 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, &reg );
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, &reg );
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, &reg ); /* 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, &reg );
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, &reg );
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);