Commit 4c0c3686 authored by Oswald Buddenhagen's avatar Oswald Buddenhagen Committed by Takashi Iwai
Browse files

ALSA: emu10k1: move snd_emu1010_load_firmware_entry() to io.c



It is a low-level I/O access function, so io.c is the natural place for
it.

While we're moving the code, reduce the scope of some variables, use
compound assignment operators, and add/adjust some comments.

Signed-off-by: default avatarOswald Buddenhagen <oswald.buddenhagen@gmx.de>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Message-ID: <20240428093717.3198716-4-oswald.buddenhagen@gmx.de>
parent b83587ea
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1843,6 +1843,7 @@ void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 s
u32 snd_emu1010_fpga_link_dst_src_read(struct snd_emu10k1 *emu, u32 dst);
int snd_emu1010_get_raw_rate(struct snd_emu10k1 *emu, u8 src);
void snd_emu1010_update_clock(struct snd_emu10k1 *emu);
void snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, const struct firmware *fw_entry);
unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc);
void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb);
void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb);
+0 −41
Original line number Diff line number Diff line
@@ -652,47 +652,6 @@ static int snd_emu10k1_cardbus_init(struct snd_emu10k1 *emu)
	return 0;
}

static void snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu,
				     const struct firmware *fw_entry)
{
	int n, i;
	u16 reg;
	u8 value;
	__always_unused u16 write_post;

	/* The FPGA is a Xilinx Spartan IIE XC2S50E */
	/* On E-MU 0404b it is a Xilinx Spartan III XC3S50 */
	/* GPIO7 -> FPGA PGMN
	 * GPIO6 -> FPGA CCLK
	 * GPIO5 -> FPGA DIN
	 * FPGA CONFIG OFF -> FPGA PGMN
	 */
	spin_lock_irq(&emu->emu_lock);
	outw(0x00, emu->port + A_GPIO); /* Set PGMN low for 100uS. */
	write_post = inw(emu->port + A_GPIO);
	udelay(100);
	outw(0x80, emu->port + A_GPIO); /* Leave bit 7 set during netlist setup. */
	write_post = inw(emu->port + A_GPIO);
	udelay(100); /* Allow FPGA memory to clean */
	for (n = 0; n < fw_entry->size; n++) {
		value = fw_entry->data[n];
		for (i = 0; i < 8; i++) {
			reg = 0x80;
			if (value & 0x1)
				reg = reg | 0x20;
			value = value >> 1;
			outw(reg, emu->port + A_GPIO);
			write_post = inw(emu->port + A_GPIO);
			outw(reg | 0x40, emu->port + A_GPIO);
			write_post = inw(emu->port + A_GPIO);
		}
	}
	/* After programming, set GPIO bit 4 high again. */
	outw(0x10, emu->port + A_GPIO);
	write_post = inw(emu->port + A_GPIO);
	spin_unlock_irq(&emu->emu_lock);
}

/* firmware file names, per model, init-fw and dock-fw (optional) */
static const char * const firmware_names[5][2] = {
	[EMU_MODEL_EMU1010] = {
+48 −0
Original line number Diff line number Diff line
@@ -422,6 +422,54 @@ void snd_emu1010_update_clock(struct snd_emu10k1 *emu)
	snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, leds);
}

void snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu,
				     const struct firmware *fw_entry)
{
	__always_unused u16 write_post;

	// On E-MU 1010 rev1 the FPGA is a Xilinx Spartan IIE XC2S50E.
	// On E-MU 0404b it is a Xilinx Spartan III XC3S50.
	// The wiring is as follows:
	// GPO7 -> FPGA input & 1K resistor -> FPGA /PGMN <- FPGA output
	//   In normal operation, the active low reset line is held up by
	//   an FPGA output, while the GPO pin performs its duty as control
	//   register access strobe signal. Writing the respective bit to
	//   EMU_HANA_FPGA_CONFIG puts the FPGA output into high-Z mode, at
	//   which point the GPO pin can control the reset line through the
	//   resistor.
	// GPO6 -> FPGA CCLK & FPGA input
	// GPO5 -> FPGA DIN (dual function)

	// Assert reset line for 100uS
	outw(0x00, emu->port + A_GPIO);
	write_post = inw(emu->port + A_GPIO);
	udelay(100);
	outw(0x80, emu->port + A_GPIO);
	write_post = inw(emu->port + A_GPIO);
	udelay(100);  // Allow FPGA memory to clean

	// Upload the netlist. Keep reset line high!
	for (int n = 0; n < fw_entry->size; n++) {
		u8 value = fw_entry->data[n];
		for (int i = 0; i < 8; i++) {
			u16 reg = 0x80;
			if (value & 1)
				reg |= 0x20;
			value >>= 1;
			outw(reg, emu->port + A_GPIO);
			write_post = inw(emu->port + A_GPIO);
			outw(reg | 0x40, emu->port + A_GPIO);
			write_post = inw(emu->port + A_GPIO);
		}
	}

	// After programming, set GPIO bit 4 high again.
	// This appears to be a config word that the rev1 Hana
	// firmware reads; weird things happen without this.
	outw(0x10, emu->port + A_GPIO);
	write_post = inw(emu->port + A_GPIO);
}

void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
{
	unsigned long flags;