mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-13 14:24:11 +08:00
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>
This commit is contained in:
parent
b83587eaf2
commit
4c0c36863c
@ -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);
|
||||
|
@ -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] = {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user