Skip to content

Commit 4c0c368

Browse files
ossilatortiwai
authored andcommitted
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: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Signed-off-by: Takashi Iwai <tiwai@suse.de> Message-ID: <20240428093717.3198716-4-oswald.buddenhagen@gmx.de>
1 parent b83587e commit 4c0c368

3 files changed

Lines changed: 49 additions & 41 deletions

File tree

include/sound/emu10k1.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,6 +1843,7 @@ void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 s
18431843
u32 snd_emu1010_fpga_link_dst_src_read(struct snd_emu10k1 *emu, u32 dst);
18441844
int snd_emu1010_get_raw_rate(struct snd_emu10k1 *emu, u8 src);
18451845
void snd_emu1010_update_clock(struct snd_emu10k1 *emu);
1846+
void snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, const struct firmware *fw_entry);
18461847
unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc);
18471848
void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb);
18481849
void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb);

sound/pci/emu10k1/emu10k1_main.c

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -652,47 +652,6 @@ static int snd_emu10k1_cardbus_init(struct snd_emu10k1 *emu)
652652
return 0;
653653
}
654654

655-
static void snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu,
656-
const struct firmware *fw_entry)
657-
{
658-
int n, i;
659-
u16 reg;
660-
u8 value;
661-
__always_unused u16 write_post;
662-
663-
/* The FPGA is a Xilinx Spartan IIE XC2S50E */
664-
/* On E-MU 0404b it is a Xilinx Spartan III XC3S50 */
665-
/* GPIO7 -> FPGA PGMN
666-
* GPIO6 -> FPGA CCLK
667-
* GPIO5 -> FPGA DIN
668-
* FPGA CONFIG OFF -> FPGA PGMN
669-
*/
670-
spin_lock_irq(&emu->emu_lock);
671-
outw(0x00, emu->port + A_GPIO); /* Set PGMN low for 100uS. */
672-
write_post = inw(emu->port + A_GPIO);
673-
udelay(100);
674-
outw(0x80, emu->port + A_GPIO); /* Leave bit 7 set during netlist setup. */
675-
write_post = inw(emu->port + A_GPIO);
676-
udelay(100); /* Allow FPGA memory to clean */
677-
for (n = 0; n < fw_entry->size; n++) {
678-
value = fw_entry->data[n];
679-
for (i = 0; i < 8; i++) {
680-
reg = 0x80;
681-
if (value & 0x1)
682-
reg = reg | 0x20;
683-
value = value >> 1;
684-
outw(reg, emu->port + A_GPIO);
685-
write_post = inw(emu->port + A_GPIO);
686-
outw(reg | 0x40, emu->port + A_GPIO);
687-
write_post = inw(emu->port + A_GPIO);
688-
}
689-
}
690-
/* After programming, set GPIO bit 4 high again. */
691-
outw(0x10, emu->port + A_GPIO);
692-
write_post = inw(emu->port + A_GPIO);
693-
spin_unlock_irq(&emu->emu_lock);
694-
}
695-
696655
/* firmware file names, per model, init-fw and dock-fw (optional) */
697656
static const char * const firmware_names[5][2] = {
698657
[EMU_MODEL_EMU1010] = {

sound/pci/emu10k1/io.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,54 @@ void snd_emu1010_update_clock(struct snd_emu10k1 *emu)
422422
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, leds);
423423
}
424424

425+
void snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu,
426+
const struct firmware *fw_entry)
427+
{
428+
__always_unused u16 write_post;
429+
430+
// On E-MU 1010 rev1 the FPGA is a Xilinx Spartan IIE XC2S50E.
431+
// On E-MU 0404b it is a Xilinx Spartan III XC3S50.
432+
// The wiring is as follows:
433+
// GPO7 -> FPGA input & 1K resistor -> FPGA /PGMN <- FPGA output
434+
// In normal operation, the active low reset line is held up by
435+
// an FPGA output, while the GPO pin performs its duty as control
436+
// register access strobe signal. Writing the respective bit to
437+
// EMU_HANA_FPGA_CONFIG puts the FPGA output into high-Z mode, at
438+
// which point the GPO pin can control the reset line through the
439+
// resistor.
440+
// GPO6 -> FPGA CCLK & FPGA input
441+
// GPO5 -> FPGA DIN (dual function)
442+
443+
// Assert reset line for 100uS
444+
outw(0x00, emu->port + A_GPIO);
445+
write_post = inw(emu->port + A_GPIO);
446+
udelay(100);
447+
outw(0x80, emu->port + A_GPIO);
448+
write_post = inw(emu->port + A_GPIO);
449+
udelay(100); // Allow FPGA memory to clean
450+
451+
// Upload the netlist. Keep reset line high!
452+
for (int n = 0; n < fw_entry->size; n++) {
453+
u8 value = fw_entry->data[n];
454+
for (int i = 0; i < 8; i++) {
455+
u16 reg = 0x80;
456+
if (value & 1)
457+
reg |= 0x20;
458+
value >>= 1;
459+
outw(reg, emu->port + A_GPIO);
460+
write_post = inw(emu->port + A_GPIO);
461+
outw(reg | 0x40, emu->port + A_GPIO);
462+
write_post = inw(emu->port + A_GPIO);
463+
}
464+
}
465+
466+
// After programming, set GPIO bit 4 high again.
467+
// This appears to be a config word that the rev1 Hana
468+
// firmware reads; weird things happen without this.
469+
outw(0x10, emu->port + A_GPIO);
470+
write_post = inw(emu->port + A_GPIO);
471+
}
472+
425473
void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
426474
{
427475
unsigned long flags;

0 commit comments

Comments
 (0)