[PATCH 1/7] ALSA: emu10k1: properly assert E-MU FPGA access constaints
Assert the validity of the registers and values, as them being out of range would indicate an error in the driver. Consequently, don't bother returning error codes; they were ignored everywhere anyway.
Signed-off-by: Oswald Buddenhagen oswald.buddenhagen@gmx.de --- include/sound/emu10k1.h | 6 +++--- sound/pci/emu10k1/io.c | 36 +++++++++++++++++------------------- 2 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 39787fecc8d9..01e2e22689bd 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h @@ -1824,9 +1824,9 @@ unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, unsigned int reg, void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data); int snd_emu10k1_spi_write(struct snd_emu10k1 * emu, unsigned int data); int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu, u32 reg, u32 value); -int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, u32 reg, u32 value); -int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, u32 reg, u32 *value); -int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, u32 dst, u32 src); +void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value); +void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value); +void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 src); 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); diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c index e15092ce9848..35bc73d99d04 100644 --- a/sound/pci/emu10k1/io.c +++ b/sound/pci/emu10k1/io.c @@ -233,56 +233,54 @@ int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu, return err; }
-int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, u32 reg, u32 value) +void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value) { unsigned long flags;
- if (reg > 0x3f) - return 1; + if (snd_BUG_ON(reg > 0x3f)) + return; reg += 0x40; /* 0x40 upwards are registers. */ - if (value > 0x3f) /* 0 to 0x3f are values */ - return 1; + if (snd_BUG_ON(value > 0x3f)) /* 0 to 0x3f are values */ + return; spin_lock_irqsave(&emu->emu_lock, flags); outl(reg, emu->port + A_IOCFG); udelay(10); outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ udelay(10); outl(value, emu->port + A_IOCFG); udelay(10); outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ spin_unlock_irqrestore(&emu->emu_lock, flags); - - return 0; }
-int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, u32 reg, u32 *value) +void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value) { unsigned long flags; - if (reg > 0x3f) - return 1; + if (snd_BUG_ON(reg > 0x3f)) + return; reg += 0x40; /* 0x40 upwards are registers. */ spin_lock_irqsave(&emu->emu_lock, flags); outl(reg, emu->port + A_IOCFG); udelay(10); outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ udelay(10); *value = ((inl(emu->port + A_IOCFG) >> 8) & 0x7f); spin_unlock_irqrestore(&emu->emu_lock, flags); - - return 0; }
/* Each Destination has one and only one Source, * but one Source can feed any number of Destinations simultaneously. */ -int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, u32 dst, u32 src) +void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 src) { - snd_emu1010_fpga_write(emu, 0x00, ((dst >> 8) & 0x3f) ); - snd_emu1010_fpga_write(emu, 0x01, (dst & 0x3f) ); - snd_emu1010_fpga_write(emu, 0x02, ((src >> 8) & 0x3f) ); - snd_emu1010_fpga_write(emu, 0x03, (src & 0x3f) ); - - return 0; + if (snd_BUG_ON(dst & ~0x71f)) + return; + if (snd_BUG_ON(src & ~0x71f)) + return; + snd_emu1010_fpga_write(emu, 0x00, dst >> 8); + snd_emu1010_fpga_write(emu, 0x01, dst & 0x1f); + snd_emu1010_fpga_write(emu, 0x02, src >> 8); + snd_emu1010_fpga_write(emu, 0x03, src & 0x1f); }
void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
As the register definition clearly states, this is a 16-bit register, yet we did all accesses as 32-bit. The writes in particular would have the potential to clear the TIMER register (depending on how the bus/card actually handles the too long writes).
This commit also introduces a separate define A_GPIO which aliases A_IOCFG, which better reflects the distinct usage on E-MU cards. This is done in the same commit to keep the churn down, as we're touching all involved lines anyway.
Signed-off-by: Oswald Buddenhagen oswald.buddenhagen@gmx.de --- include/sound/emu10k1.h | 7 +++- sound/pci/emu10k1/emu10k1_main.c | 62 ++++++++++++++++---------------- sound/pci/emu10k1/emumixer.c | 14 ++++---- sound/pci/emu10k1/io.c | 14 ++++---- 4 files changed, 51 insertions(+), 46 deletions(-)
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 01e2e22689bd..d6c4c290ad1d 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h @@ -251,11 +251,16 @@ #define MUSTAT_IRDYN 0x80 /* 0 = MIDI data or command ACK */ #define MUSTAT_ORDYN 0x40 /* 0 = MUDATA can accept a command or data */
-#define A_IOCFG 0x18 /* GPIO on Audigy card (16bits) */ +#define A_GPIO 0x18 /* GPIO on Audigy card (16bits) */ #define A_GPINPUT_MASK 0xff00 #define A_GPOUTPUT_MASK 0x00ff
+// The GPIO port is used for I/O config on Sound Blasters; +// card-specific info can be found in the emu_chip_details table. +// On E-MU cards the port is used as the interface to the FPGA. + // Audigy output/GPIO stuff taken from the kX drivers +#define A_IOCFG A_GPIO #define A_IOCFG_GPOUT0 0x0044 /* analog/digital */ #define A_IOCFG_DISABLE_ANALOG 0x0040 /* = 'enable' for Audigy2 (chiprev=4) */ #define A_IOCFG_ENABLE_DIGITAL 0x0004 diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 3880f359e688..bf1a261547d4 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -223,8 +223,8 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) */ outl(0x7a0000, emu->port + 0x20); outl(0xFF000000, emu->port + 0x24); - tmp = inl(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */ - outl(tmp, emu->port + A_IOCFG); + tmp = inw(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */ + outw(tmp, emu->port + A_IOCFG); } if (emu->card_capabilities->spi_dac) { /* Audigy 2 ZS Notebook with DAC Wolfson WM8768/WM8568 */ int size, n; @@ -244,15 +244,15 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) * GPIO6: Unknown * GPIO7: Unknown */ - outl(0x76, emu->port + A_IOCFG); /* Windows uses 0x3f76 */ + outw(0x76, emu->port + A_IOCFG); /* Windows uses 0x3f76 */ } if (emu->card_capabilities->i2c_adc) { /* Audigy 2 ZS Notebook with ADC Wolfson WM8775 */ int size, n;
snd_emu10k1_ptr20_write(emu, P17V_I2S_SRC_SEL, 0, 0x2020205f); - tmp = inl(emu->port + A_IOCFG); - outl(tmp | 0x4, emu->port + A_IOCFG); /* Set bit 2 for mic input */ - tmp = inl(emu->port + A_IOCFG); + tmp = inw(emu->port + A_IOCFG); + outw(tmp | 0x4, emu->port + A_IOCFG); /* Set bit 2 for mic input */ + tmp = inw(emu->port + A_IOCFG); size = ARRAY_SIZE(i2c_adc_init); for (n = 0; n < size; n++) snd_emu10k1_i2c_write(emu, i2c_adc_init[n][0], i2c_adc_init[n][1]); @@ -308,12 +308,12 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) } else if (emu->card_capabilities->i2c_adc) { ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */ } else if (emu->audigy) { - unsigned int reg = inl(emu->port + A_IOCFG); - outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG); + u16 reg = inw(emu->port + A_IOCFG); + outw(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG); udelay(500); - outl(reg | A_IOCFG_GPOUT1 | A_IOCFG_GPOUT2, emu->port + A_IOCFG); + outw(reg | A_IOCFG_GPOUT1 | A_IOCFG_GPOUT2, emu->port + A_IOCFG); udelay(100); - outl(reg, emu->port + A_IOCFG); + outw(reg, emu->port + A_IOCFG); } else { unsigned int reg = inl(emu->port + HCFG); outl(reg | HCFG_GPOUT2, emu->port + HCFG); @@ -329,8 +329,8 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) } else if (emu->card_capabilities->i2c_adc) { ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */ } else if (emu->audigy) { /* enable analog output */ - unsigned int reg = inl(emu->port + A_IOCFG); - outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG); + u16 reg = inw(emu->port + A_IOCFG); + outw(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG); }
if (emu->address_mode == 0) { @@ -354,19 +354,19 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu) } else if (emu->card_capabilities->i2c_adc) { ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */ } else if (emu->audigy) { - outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG); + outw(inw(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ /* Unmute Analog now. Set GPO6 to 1 for Apollo. * This has to be done after init ALice3 I2SOut beyond 48KHz. * So, sequence is important. */ - outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG); + outw(inw(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG); } else if (emu->card_capabilities->ca0108_chip) { /* audigy2 value */ /* Unmute Analog now. */ - outl(inl(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG); + outw(inw(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG); } else { /* Disable routing from AC97 line out to Front speakers */ - outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG); + outw(inw(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG); } }
@@ -651,9 +651,9 @@ static int snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, const struct firmware *fw_entry) { int n, i; - int reg; - int value; - __always_unused unsigned int write_post; + u16 reg; + u8 value; + __always_unused u16 write_post; unsigned long flags;
if (!fw_entry) @@ -666,28 +666,28 @@ static int snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, * FPGA CONFIG OFF -> FPGA PGMN */ spin_lock_irqsave(&emu->emu_lock, flags); - outl(0x00, emu->port + A_IOCFG); /* Set PGMN low for 1uS. */ - write_post = inl(emu->port + A_IOCFG); + outw(0x00, emu->port + A_GPIO); /* Set PGMN low for 1uS. */ + write_post = inw(emu->port + A_GPIO); udelay(100); - outl(0x80, emu->port + A_IOCFG); /* Leave bit 7 set during netlist setup. */ - write_post = inl(emu->port + A_IOCFG); + 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; - outl(reg, emu->port + A_IOCFG); - write_post = inl(emu->port + A_IOCFG); - outl(reg | 0x40, emu->port + A_IOCFG); - write_post = inl(emu->port + A_IOCFG); + 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. */ - outl(0x10, emu->port + A_IOCFG); - write_post = inl(emu->port + A_IOCFG); + outw(0x10, emu->port + A_GPIO); + write_post = inw(emu->port + A_GPIO); spin_unlock_irqrestore(&emu->emu_lock, flags);
return 0; @@ -2054,7 +2054,7 @@ void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu) *val = snd_emu10k1_ptr_read(emu, *reg, i); } if (emu->audigy) - emu->saved_a_iocfg = inl(emu->port + A_IOCFG); + emu->saved_a_iocfg = inw(emu->port + A_IOCFG); emu->saved_hcfg = inl(emu->port + HCFG); }
@@ -2081,7 +2081,7 @@ void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu)
/* resore for spdif */ if (emu->audigy) - outl(emu->saved_a_iocfg, emu->port + A_IOCFG); + outw(emu->saved_a_iocfg, emu->port + A_IOCFG); outl(emu->saved_hcfg, emu->port + HCFG);
val = emu->saved_ptr; diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 3c115f8ab96c..754d91050af2 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c @@ -924,7 +924,7 @@ static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol, struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); unsigned int source_id; unsigned int ngain, ogain; - u32 gpio; + u16 gpio; int change = 0; unsigned long flags; u32 source; @@ -941,11 +941,11 @@ static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol, if (change) { snd_emu10k1_i2c_write(emu, ADC_MUX, 0); /* Mute input */ spin_lock_irqsave(&emu->emu_lock, flags); - gpio = inl(emu->port + A_IOCFG); + gpio = inw(emu->port + A_IOCFG); if (source_id==0) - outl(gpio | 0x4, emu->port + A_IOCFG); + outw(gpio | 0x4, emu->port + A_IOCFG); else - outl(gpio & ~0x4, emu->port + A_IOCFG); + outw(gpio & ~0x4, emu->port + A_IOCFG); spin_unlock_irqrestore(&emu->emu_lock, flags);
ngain = emu->i2c_capture_volume[source_id][0]; /* Left */ @@ -1632,7 +1632,7 @@ static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol, struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
if (emu->audigy) - ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0; + ucontrol->value.integer.value[0] = inw(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0; else ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0; if (emu->card_capabilities->invert_shared_spdif) @@ -1657,13 +1657,13 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol, if ( emu->card_capabilities->i2c_adc) { /* Do nothing for Audigy 2 ZS Notebook */ } else if (emu->audigy) { - reg = inl(emu->port + A_IOCFG); + reg = inw(emu->port + A_IOCFG); val = sw ? A_IOCFG_GPOUT0 : 0; change = (reg & A_IOCFG_GPOUT0) != val; if (change) { reg &= ~A_IOCFG_GPOUT0; reg |= val; - outl(reg | val, emu->port + A_IOCFG); + outw(reg | val, emu->port + A_IOCFG); } } reg = inl(emu->port + HCFG); diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c index 35bc73d99d04..f0134689c320 100644 --- a/sound/pci/emu10k1/io.c +++ b/sound/pci/emu10k1/io.c @@ -243,28 +243,28 @@ void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value) if (snd_BUG_ON(value > 0x3f)) /* 0 to 0x3f are values */ return; spin_lock_irqsave(&emu->emu_lock, flags); - outl(reg, emu->port + A_IOCFG); + outw(reg, emu->port + A_GPIO); udelay(10); - outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ + outw(reg | 0x80, emu->port + A_GPIO); /* High bit clocks the value into the fpga. */ udelay(10); - outl(value, emu->port + A_IOCFG); + outw(value, emu->port + A_GPIO); udelay(10); - outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ + outw(value | 0x80 , emu->port + A_GPIO); /* High bit clocks the value into the fpga. */ spin_unlock_irqrestore(&emu->emu_lock, flags); }
void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value) { unsigned long flags; if (snd_BUG_ON(reg > 0x3f)) return; reg += 0x40; /* 0x40 upwards are registers. */ spin_lock_irqsave(&emu->emu_lock, flags); - outl(reg, emu->port + A_IOCFG); + outw(reg, emu->port + A_GPIO); udelay(10); - outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ + outw(reg | 0x80, emu->port + A_GPIO); /* High bit clocks the value into the fpga. */ udelay(10); - *value = ((inl(emu->port + A_IOCFG) >> 8) & 0x7f); + *value = ((inw(emu->port + A_GPIO) >> 8) & 0x7f); spin_unlock_irqrestore(&emu->emu_lock, flags); }
Signed-off-by: Oswald Buddenhagen oswald.buddenhagen@gmx.de --- include/sound/emu10k1.h | 3 ++- sound/pci/emu10k1/io.c | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index d6c4c290ad1d..6867a042ebe2 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h @@ -252,7 +252,8 @@ #define MUSTAT_ORDYN 0x40 /* 0 = MUDATA can accept a command or data */
#define A_GPIO 0x18 /* GPIO on Audigy card (16bits) */ -#define A_GPINPUT_MASK 0xff00 +#define A_GPINPUT_MASK 0xff00 /* Alice/2 has 8 input pins */ +#define A3_GPINPUT_MASK 0x3f00 /* ... while Tina/2 has only 6 */ #define A_GPOUTPUT_MASK 0x00ff
// The GPIO port is used for I/O config on Sound Blasters; diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c index f0134689c320..42b06f2e5552 100644 --- a/sound/pci/emu10k1/io.c +++ b/sound/pci/emu10k1/io.c @@ -255,16 +255,19 @@ void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value)
void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value) { + // The higest input pin is used as the designated interrupt trigger, + // so it needs to be masked out. + u32 mask = emu->card_capabilities->ca0108_chip ? 0x1f : 0x7f; unsigned long flags; if (snd_BUG_ON(reg > 0x3f)) return; reg += 0x40; /* 0x40 upwards are registers. */ spin_lock_irqsave(&emu->emu_lock, flags); outw(reg, emu->port + A_GPIO); udelay(10); outw(reg | 0x80, emu->port + A_GPIO); /* High bit clocks the value into the fpga. */ udelay(10); - *value = ((inw(emu->port + A_GPIO) >> 8) & 0x7f); + *value = ((inw(emu->port + A_GPIO) >> 8) & mask); spin_unlock_irqrestore(&emu->emu_lock, flags); }
On Fri, 21 Apr 2023 16:10:02 +0200, Oswald Buddenhagen wrote:
Signed-off-by: Oswald Buddenhagen oswald.buddenhagen@gmx.de
No changelog is no good news. Please give more information.
thanks,
Takashi
On Fri, Apr 21, 2023 at 05:14:10PM +0200, Takashi Iwai wrote:
On Fri, 21 Apr 2023 16:10:02 +0200, Oswald Buddenhagen wrote:
Signed-off-by: Oswald Buddenhagen oswald.buddenhagen@gmx.de
No changelog is no good news. Please give more information.
i suppose this is a difference in philosophy. i generally refrain from covering in the commit message what comments in the patch already explain. otherwise it would be just redundant, and i don't like that very much.
anyway, i can add some speculation what problems this could have theoretically caused.
regards
On Fri, 21 Apr 2023 17:25:46 +0200, Oswald Buddenhagen wrote:
On Fri, Apr 21, 2023 at 05:14:10PM +0200, Takashi Iwai wrote:
On Fri, 21 Apr 2023 16:10:02 +0200, Oswald Buddenhagen wrote:
Signed-off-by: Oswald Buddenhagen oswald.buddenhagen@gmx.de
No changelog is no good news. Please give more information.
i suppose this is a difference in philosophy. i generally refrain from covering in the commit message what comments in the patch already explain. otherwise it would be just redundant, and i don't like that very much.
anyway, i can add some speculation what problems this could have theoretically caused.
You didn't explain exactly *WHAT* you fixed, and that's the readers may be interested more. The summary says merely "fix snd_emu1010_fpga_read() input masking for rev2 cards". What was broken beforehand and what was corrected by your patch? The summary isn't enough for explaining it, but you have more space here.
thanks,
Takashi
This doesn't do anything snd_emu10k1_init() wouldn't do later, and none of the things it does seem relevant for the function itself (which is pretty much about setting up the FPGA). It was probably a Windows driver behavior cargo-culting artifact.
Signed-off-by: Oswald Buddenhagen oswald.buddenhagen@gmx.de --- sound/pci/emu10k1/emu10k1_main.c | 33 ++++---------------------------- 1 file changed, 4 insertions(+), 29 deletions(-)
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index bf1a261547d4..f7908e5a6e0d 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -831,24 +831,10 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) int err;
dev_info(emu->card->dev, "emu1010: Special config.\n"); - /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, - * Lock Sound Memory Cache, Lock Tank Memory Cache, - * Mute all codecs. - */ - outl(0x0005a00c, emu->port + HCFG); - /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, - * Lock Tank Memory Cache, - * Mute all codecs. - */ - outl(0x0005a004, emu->port + HCFG); - /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, - * Mute all codecs. - */ - outl(0x0005a000, emu->port + HCFG); - /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, - * Mute all codecs. - */ - outl(0x0005a000, emu->port + HCFG); + + /* Mute, and disable audio and lock cache, just in case. + * Proper init follows in snd_emu10k1_init(). */ + outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
/* Disable 48Volt power to Audio Dock */ snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0); @@ -1075,17 +1061,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp);
- /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave, - * Lock Sound Memory Cache, Lock Tank Memory Cache, - * Mute all codecs. - */ - outl(0x0000a000, emu->port + HCFG); - /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave, - * Lock Sound Memory Cache, Lock Tank Memory Cache, - * Un-Mute all codecs. - */ - outl(0x0000a001, emu->port + HCFG); - /* Initial boot complete. Now patches */
snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp);
These seem to be simply cargo-culted from the Windows driver's behavior. However, the original reason were presumably read-modify-write cycles, which we don't do.
Signed-off-by: Oswald Buddenhagen oswald.buddenhagen@gmx.de --- sound/pci/emu10k1/emu10k1_main.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index f7908e5a6e0d..ac0c8865c76b 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -885,32 +885,26 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) dev_info(emu->card->dev, "emu1010: Card options = 0x%x\n", reg); snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ®); dev_info(emu->card->dev, "emu1010: Card options = 0x%x\n", reg); - snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp); /* Optical -> ADAT I/O */ /* 0 : SPDIF * 1 : ADAT */ emu->emu1010.optical_in = 1; /* IN_ADAT */ emu->emu1010.optical_out = 1; /* IN_ADAT */ tmp = 0; tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) | (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0); snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp); - snd_emu1010_fpga_read(emu, EMU_HANA_ADC_PADS, &tmp); /* Set no attenuation on Audio Dock pads. */ snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00); emu->emu1010.adc_pads = 0x00; - snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp); /* Unmute Audio dock DACs, Headphone source DAC-4. */ snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30); snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12); - snd_emu1010_fpga_read(emu, EMU_HANA_DAC_PADS, &tmp); /* DAC PADs. */ snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, 0x0f); emu->emu1010.dac_pads = 0x0f; - snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp); snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30); - snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp); /* SPDIF Format. Set Consumer mode, 24bit, copy enable */ snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10); /* MIDI routing */ @@ -1068,7 +1062,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* Unknown */ snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* MIDI Route */ snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* Unknown */ - 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) */
#if 0
These seem to be another instance of cargo-culting from the Windows driver. It presumably queries the register to decide about the followup actions, but we don't do that.
Signed-off-by: Oswald Buddenhagen oswald.buddenhagen@gmx.de --- sound/pci/emu10k1/emu10k1_main.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index ac0c8865c76b..9d6a00bf6f2f 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -881,8 +881,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) /* Enable 48Volt power to Audio Dock */ snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, EMU_HANA_DOCK_PWR_ON);
- snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ®); - dev_info(emu->card->dev, "emu1010: Card options = 0x%x\n", reg); snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ®); dev_info(emu->card->dev, "emu1010: Card options = 0x%x\n", reg); /* Optical -> ADAT I/O */ @@ -916,8 +914,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) /* IRQ Enable: All off */ snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00);
- snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ®); - dev_info(emu->card->dev, "emu1010: Card options3 = 0x%x\n", reg); /* Default WCLK set to 48kHz. */ snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00); /* Word Clock source, Internal 48kHz x1 */ @@ -1053,11 +1049,8 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1); snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01); /* Unmute all */
- snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp); - /* Initial boot complete. Now patches */
- snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp); snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* MIDI Route */ snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* Unknown */ snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* MIDI Route */
Various redundant FPGA writes which were presumably also cargo-culted from the Windows driver.
Signed-off-by: Oswald Buddenhagen oswald.buddenhagen@gmx.de --- sound/pci/emu10k1/emu10k1_main.c | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-)
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 9d6a00bf6f2f..2f3e679e85a7 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -889,31 +889,29 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) */ emu->emu1010.optical_in = 1; /* IN_ADAT */ emu->emu1010.optical_out = 1; /* IN_ADAT */ - tmp = 0; tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) | (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0); snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp); /* Set no attenuation on Audio Dock pads. */ snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00); emu->emu1010.adc_pads = 0x00; /* Unmute Audio dock DACs, Headphone source DAC-4. */ snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30); - snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12); /* DAC PADs. */ snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, 0x0f); emu->emu1010.dac_pads = 0x0f; - snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30); /* SPDIF Format. Set Consumer mode, 24bit, copy enable */ snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10); /* MIDI routing */ snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* Unknown. */ snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* IRQ Enable: All on */ /* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); */ /* IRQ Enable: All off */ snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00);
+ emu->emu1010.internal_clock = 1; /* 48000 */ /* Default WCLK set to 48kHz. */ snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00); /* Word Clock source, Internal 48kHz x1 */ @@ -1049,14 +1047,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1); snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01); /* Unmute all */
- /* Initial boot complete. Now patches */ - - snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* MIDI Route */ - snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* Unknown */ - snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* MIDI Route */ - snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* Unknown */ - snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10); /* SPDIF Format spdif (or 0x11 for aes/ebu) */ - #if 0 snd_emu1010_fpga_link_dst_src_write(emu, EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32B + 2); /* ALICE2 bus 0xa2 */ @@ -1176,21 +1166,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) EMU_DST_HANA_ADAT + 7, EMU_SRC_ALICE_EMU32A + 7); emu->emu1010.output_source[23] = 28; } - /* TEMP: Select SPDIF in/out */ - /* snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); */ /* Output spdif */ - - /* TEMP: Select 48kHz SPDIF out */ - snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x0); /* Mute all */ - snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x0); /* Default fallback clock 48kHz */ - /* Word Clock source, Internal 48kHz x1 */ - snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K); - /* snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X); */ - emu->emu1010.internal_clock = 1; /* 48000 */ - snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12); /* Set LEDs on Audio Dock */ - snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x1); /* Unmute all */ - /* snd_emu1010_fpga_write(emu, 0x7, 0x0); */ /* Mute all */ - /* snd_emu1010_fpga_write(emu, 0x7, 0x1); */ /* Unmute all */ - /* snd_emu1010_fpga_write(emu, 0xe, 0x12); */ /* Set LEDs on Audio Dock */
return 0; }
On Fri, 21 Apr 2023 16:10:00 +0200, Oswald Buddenhagen wrote:
Assert the validity of the registers and values, as them being out of range would indicate an error in the driver. Consequently, don't bother returning error codes; they were ignored everywhere anyway.
Signed-off-by: Oswald Buddenhagen oswald.buddenhagen@gmx.de
I applied a part of the series (patches 1, 2, 4, 5, 6, 7) now. Please resubmit the patch 3.
thanks,
Takashi
participants (2)
-
Oswald Buddenhagen
-
Takashi Iwai