···165165 u32 value2;166166167167 if (emu->card_capabilities->emu_model) {168168+ snd_emu1010_fpga_lock(emu);169169+168170 // This represents the S/PDIF lock status on 0404b, which is169171 // kinda weird and unhelpful, because monitoring it via IRQ is170172 // impractical (one gets an IRQ flood as long as it is desynced).···199197 snd_iprintf(buffer, "\nS/PDIF mode: %s%s\n",200198 value & EMU_HANA_SPDIF_MODE_RX_PRO ? "professional" : "consumer",201199 value & EMU_HANA_SPDIF_MODE_RX_NOCOPY ? ", no copy" : "");200200+201201+ snd_emu1010_fpga_unlock(emu);202202 } else {203203 snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF In", CDCS, CDSRCS);204204 snd_emu10k1_proc_spdif_status(emu, buffer, "Optical or Coax S/PDIF In", GPSCS, GPSRCS);···462458 struct snd_emu10k1 *emu = entry->private_data;463459 u32 value;464460 int i;461461+462462+ snd_emu1010_fpga_lock(emu);463463+465464 snd_iprintf(buffer, "EMU1010 Registers:\n\n");466465467466 for(i = 0; i < 0x40; i+=1) {···503496 snd_emu_proc_emu1010_link_read(emu, buffer, 0x701);504497 }505498 }499499+500500+ snd_emu1010_fpga_unlock(emu);506501}507502508503static void snd_emu_proc_io_reg_read(struct snd_info_entry *entry,
+75-29
sound/pci/emu10k1/io.c
···285285 outw(value, emu->port + A_GPIO);286286 udelay(10);287287 outw(value | 0x80 , emu->port + A_GPIO); /* High bit clocks the value into the fpga. */288288+ udelay(10);288289}289290290291void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value)291292{292292- unsigned long flags;293293-294294- spin_lock_irqsave(&emu->emu_lock, flags);293293+ if (snd_BUG_ON(!mutex_is_locked(&emu->emu1010.lock)))294294+ return;295295 snd_emu1010_fpga_write_locked(emu, reg, value);296296- spin_unlock_irqrestore(&emu->emu_lock, flags);297296}298297299299-static void snd_emu1010_fpga_read_locked(struct snd_emu10k1 *emu, u32 reg, u32 *value)298298+void snd_emu1010_fpga_write_lock(struct snd_emu10k1 *emu, u32 reg, u32 value)299299+{300300+ snd_emu1010_fpga_lock(emu);301301+ snd_emu1010_fpga_write_locked(emu, reg, value);302302+ snd_emu1010_fpga_unlock(emu);303303+}304304+305305+void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value)300306{301307 // The higest input pin is used as the designated interrupt trigger,302308 // so it needs to be masked out.303309 // But note that any other input pin change will also cause an IRQ,304310 // so using this function often causes an IRQ as a side effect.305311 u32 mask = emu->card_capabilities->ca0108_chip ? 0x1f : 0x7f;312312+313313+ if (snd_BUG_ON(!mutex_is_locked(&emu->emu1010.lock)))314314+ return;306315 if (snd_BUG_ON(reg > 0x3f))307316 return;308317 reg += 0x40; /* 0x40 upwards are registers. */···322313 *value = ((inw(emu->port + A_GPIO) >> 8) & mask);323314}324315325325-void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value)326326-{327327- unsigned long flags;328328-329329- spin_lock_irqsave(&emu->emu_lock, flags);330330- snd_emu1010_fpga_read_locked(emu, reg, value);331331- spin_unlock_irqrestore(&emu->emu_lock, flags);332332-}333333-334316/* Each Destination has one and only one Source,335317 * but one Source can feed any number of Destinations simultaneously.336318 */337319void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 src)338320{339339- unsigned long flags;340340-341321 if (snd_BUG_ON(dst & ~0x71f))342322 return;343323 if (snd_BUG_ON(src & ~0x71f))344324 return;345345- spin_lock_irqsave(&emu->emu_lock, flags);346346- snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTHI, dst >> 8);347347- snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTLO, dst & 0x1f);348348- snd_emu1010_fpga_write_locked(emu, EMU_HANA_SRCHI, src >> 8);349349- snd_emu1010_fpga_write_locked(emu, EMU_HANA_SRCLO, src & 0x1f);350350- spin_unlock_irqrestore(&emu->emu_lock, flags);325325+ snd_emu1010_fpga_write(emu, EMU_HANA_DESTHI, dst >> 8);326326+ snd_emu1010_fpga_write(emu, EMU_HANA_DESTLO, dst & 0x1f);327327+ snd_emu1010_fpga_write(emu, EMU_HANA_SRCHI, src >> 8);328328+ snd_emu1010_fpga_write(emu, EMU_HANA_SRCLO, src & 0x1f);351329}352330353331u32 snd_emu1010_fpga_link_dst_src_read(struct snd_emu10k1 *emu, u32 dst)354332{355355- unsigned long flags;356333 u32 hi, lo;357334358335 if (snd_BUG_ON(dst & ~0x71f))359336 return 0;360360- spin_lock_irqsave(&emu->emu_lock, flags);361361- snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTHI, dst >> 8);362362- snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTLO, dst & 0x1f);363363- snd_emu1010_fpga_read_locked(emu, EMU_HANA_SRCHI, &hi);364364- snd_emu1010_fpga_read_locked(emu, EMU_HANA_SRCLO, &lo);365365- spin_unlock_irqrestore(&emu->emu_lock, flags);337337+ snd_emu1010_fpga_write(emu, EMU_HANA_DESTHI, dst >> 8);338338+ snd_emu1010_fpga_write(emu, EMU_HANA_DESTLO, dst & 0x1f);339339+ snd_emu1010_fpga_read(emu, EMU_HANA_SRCHI, &hi);340340+ snd_emu1010_fpga_read(emu, EMU_HANA_SRCLO, &lo);366341 return (hi << 8) | lo;367342}368343···420427 leds |= EMU_HANA_DOCK_LEDS_2_LOCK;421428422429 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, leds);430430+}431431+432432+void snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, int dock,433433+ const struct firmware *fw_entry)434434+{435435+ __always_unused u16 write_post;436436+437437+ // On E-MU 1010 rev1 the FPGA is a Xilinx Spartan IIE XC2S50E.438438+ // On E-MU 0404b it is a Xilinx Spartan III XC3S50.439439+ // The wiring is as follows:440440+ // GPO7 -> FPGA input & 1K resistor -> FPGA /PGMN <- FPGA output441441+ // In normal operation, the active low reset line is held up by442442+ // an FPGA output, while the GPO pin performs its duty as control443443+ // register access strobe signal. Writing the respective bit to444444+ // EMU_HANA_FPGA_CONFIG puts the FPGA output into high-Z mode, at445445+ // which point the GPO pin can control the reset line through the446446+ // resistor.447447+ // GPO6 -> FPGA CCLK & FPGA input448448+ // GPO5 -> FPGA DIN (dual function)449449+450450+ // If the FPGA is already programmed, return it to programming mode451451+ snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG,452452+ dock ? EMU_HANA_FPGA_CONFIG_AUDIODOCK :453453+ EMU_HANA_FPGA_CONFIG_HANA);454454+455455+ // Assert reset line for 100uS456456+ outw(0x00, emu->port + A_GPIO);457457+ write_post = inw(emu->port + A_GPIO);458458+ udelay(100);459459+ outw(0x80, emu->port + A_GPIO);460460+ write_post = inw(emu->port + A_GPIO);461461+ udelay(100); // Allow FPGA memory to clean462462+463463+ // Upload the netlist. Keep reset line high!464464+ for (int n = 0; n < fw_entry->size; n++) {465465+ u8 value = fw_entry->data[n];466466+ for (int i = 0; i < 8; i++) {467467+ u16 reg = 0x80;468468+ if (value & 1)469469+ reg |= 0x20;470470+ value >>= 1;471471+ outw(reg, emu->port + A_GPIO);472472+ write_post = inw(emu->port + A_GPIO);473473+ outw(reg | 0x40, emu->port + A_GPIO);474474+ write_post = inw(emu->port + A_GPIO);475475+ }476476+ }477477+478478+ // After programming, set GPIO bit 4 high again.479479+ // This appears to be a config word that the rev1 Hana480480+ // firmware reads; weird things happen without this.481481+ outw(0x10, emu->port + A_GPIO);482482+ write_post = inw(emu->port + A_GPIO);423483}424484425485void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)