Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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

parent 177a7cdb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1456,6 +1456,7 @@ struct snd_emu1010 {
	unsigned int adc_pads; /* bit mask */
	unsigned int dac_pads; /* bit mask */
	unsigned int internal_clock; /* 44100 or 48000 */
	struct task_struct *firmware_thread;
};

struct snd_emu10k1 {
+61 −42
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@
 *
 */

#include <linux/sched.h>
#include <linux/kthread.h>
#include <sound/driver.h>
#include <linux/delay.h>
#include <linux/init.h>
@@ -702,6 +704,59 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
	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,
 * testing the card:
@@ -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_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); /* SPDIF Format spdif  (or 0x11 for aes/ebu) */

	/* Delay to allow Audio Dock to settle */
	msleep(100);
	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 */
	/* FIXME: The loading of this should be able to happen any time,
	 * 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;
			}
		}
	/* Start Micro/Audio Dock firmware loader thread */
	emu->emu1010.firmware_thread = kthread_create(&emu1010_firmware_thread,
                                   emu,
                                   "emu1010_firmware");
	wake_up_process(emu->emu1010.firmware_thread);

		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
	snd_emu1010_fpga_link_dst_src_write(emu,
		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)
	if (emu->card_capabilities->emu1010) {
		/* Disable 48Volt power to Audio Dock */
		snd_emu1010_fpga_write(emu,  EMU_HANA_DOCK_PWR,  0 );
		kthread_stop(emu->emu1010.firmware_thread);
	}
	if (emu->memhdr)
		snd_util_memhdr_free(emu->memhdr);