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

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
...@@ -1843,6 +1843,7 @@ void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 s ...@@ -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); 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); int snd_emu1010_get_raw_rate(struct snd_emu10k1 *emu, u8 src);
void snd_emu1010_update_clock(struct snd_emu10k1 *emu); 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); 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_enable(struct snd_emu10k1 *emu, unsigned int intrenb);
void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb); void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb);
......
...@@ -652,47 +652,6 @@ static int snd_emu10k1_cardbus_init(struct snd_emu10k1 *emu) ...@@ -652,47 +652,6 @@ static int snd_emu10k1_cardbus_init(struct snd_emu10k1 *emu)
return 0; 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) */ /* firmware file names, per model, init-fw and dock-fw (optional) */
static const char * const firmware_names[5][2] = { static const char * const firmware_names[5][2] = {
[EMU_MODEL_EMU1010] = { [EMU_MODEL_EMU1010] = {
......
...@@ -422,6 +422,54 @@ void snd_emu1010_update_clock(struct snd_emu10k1 *emu) ...@@ -422,6 +422,54 @@ void snd_emu1010_update_clock(struct snd_emu10k1 *emu)
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, leds); 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) void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
{ {
unsigned long flags; unsigned long flags;
......
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