Commit 42f53226 authored by James Courtier-Dutton's avatar James Courtier-Dutton Committed by Jaroslav Kysela

[ALSA] snd-emu10k1:Improves firmware loading for E-Mu cards.

Details:
Fixes http://bugzilla.kernel.org/show_bug.cgi?id=8176Signed-off-by: default avatarJames Courtier-Dutton <James@superbug.co.uk>
Signed-off-by: default avatarJaroslav Kysela <perex@suse.cz>
parent 177a7cdb
...@@ -1456,6 +1456,7 @@ struct snd_emu1010 { ...@@ -1456,6 +1456,7 @@ struct snd_emu1010 {
unsigned int adc_pads; /* bit mask */ unsigned int adc_pads; /* bit mask */
unsigned int dac_pads; /* bit mask */ unsigned int dac_pads; /* bit mask */
unsigned int internal_clock; /* 44100 or 48000 */ unsigned int internal_clock; /* 44100 or 48000 */
struct task_struct *firmware_thread;
}; };
struct snd_emu10k1 { struct snd_emu10k1 {
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
* *
*/ */
#include <linux/sched.h>
#include <linux/kthread.h>
#include <sound/driver.h> #include <sound/driver.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -702,6 +704,59 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file ...@@ -702,6 +704,59 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
return 0; return 0;
} }
int emu1010_firmware_thread(void *data) {
struct snd_emu10k1 * emu = data;
int tmp,tmp2;
int reg;
int err;
for (;;) {
/* Delay to allow Audio Dock to settle */
msleep(1000);
if (kthread_should_stop())
break;
snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */
snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); /* OPTIONS: Which cards are attached to the EMU */
if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) {
/* Audio Dock attached */
/* Return to Audio Dock programming mode */
snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n");
snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK );
if (emu->card_capabilities->emu1010 == 1) {
if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) {
return err;
}
} else if (emu->card_capabilities->emu1010 == 2) {
if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) {
return err;
}
} else if (emu->card_capabilities->emu1010 == 3) {
if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) {
return err;
}
}
snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 );
snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg );
snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg);
/* ID, should read & 0x7f = 0x55 when FPGA programmed. */
snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg );
snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg);
if ((reg & 0x1f) != 0x15) {
/* FPGA failed to be programmed */
snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg);
return 0;
return -ENODEV;
}
snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n");
snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp );
snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2 );
snd_printk("Audio Dock ver:%d.%d\n",tmp ,tmp2);
}
}
return 0;
}
/* /*
* EMU-1010 - details found out from this driver, official MS Win drivers, * EMU-1010 - details found out from this driver, official MS Win drivers,
* testing the card: * testing the card:
...@@ -1004,49 +1059,12 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) ...@@ -1004,49 +1059,12 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp ); snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp );
snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); /* SPDIF Format spdif (or 0x11 for aes/ebu) */ snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); /* SPDIF Format spdif (or 0x11 for aes/ebu) */
/* Delay to allow Audio Dock to settle */ /* Start Micro/Audio Dock firmware loader thread */
msleep(100); emu->emu1010.firmware_thread = kthread_create(&emu1010_firmware_thread,
snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */ emu,
snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); /* OPTIONS: Which cards are attached to the EMU */ "emu1010_firmware");
/* FIXME: The loading of this should be able to happen any time, wake_up_process(emu->emu1010.firmware_thread);
* as the user can plug/unplug it at any time
*/
if (reg & (EMU_HANA_OPTION_DOCK_ONLINE | EMU_HANA_OPTION_DOCK_OFFLINE) ) {
/* Audio Dock attached */
/* Return to Audio Dock programming mode */
snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n");
snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK );
if (emu->card_capabilities->emu1010 == 1) {
if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) {
return err;
}
} else if (emu->card_capabilities->emu1010 == 2) {
if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) {
return err;
}
} else if (emu->card_capabilities->emu1010 == 3) {
if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) {
return err;
}
}
snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 );
snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg );
snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg);
/* ID, should read & 0x7f = 0x55 when FPGA programmed. */
snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg );
snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg);
if ((reg & 0x3f) != 0x15) {
/* FPGA failed to be programmed */
snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg);
return 0;
return -ENODEV;
}
snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n");
snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp );
snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2 );
snd_printk("Audio Dock ver:%d.%d\n",tmp ,tmp2);
}
#if 0 #if 0
snd_emu1010_fpga_link_dst_src_write(emu, snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32B + 2); /* ALICE2 bus 0xa2 */ 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,6 +1191,7 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
if (emu->card_capabilities->emu1010) { if (emu->card_capabilities->emu1010) {
/* Disable 48Volt power to Audio Dock */ /* Disable 48Volt power to Audio Dock */
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 ); snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 );
kthread_stop(emu->emu1010.firmware_thread);
} }
if (emu->memhdr) if (emu->memhdr)
snd_util_memhdr_free(emu->memhdr); snd_util_memhdr_free(emu->memhdr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment