linux-sound.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
To: linux-sound@vger.kernel.org
Cc: Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@perex.cz>,
	Pietro Caruso <pietrocaruso50@gmail.com>
Subject: [PATCH v2 3/4] ALSA: emu10k1: move snd_emu1010_load_firmware_entry() to io.c
Date: Sun, 28 Apr 2024 11:37:16 +0200	[thread overview]
Message-ID: <20240428093717.3198716-4-oswald.buddenhagen@gmx.de> (raw)
In-Reply-To: <20240428093717.3198716-1-oswald.buddenhagen@gmx.de>

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>
---
 include/sound/emu10k1.h          |  1 +
 sound/pci/emu10k1/emu10k1_main.c | 41 ---------------------------
 sound/pci/emu10k1/io.c           | 48 ++++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 41 deletions(-)

diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 234b5baea69c..2856f4717c93 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -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);
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index ec010971a220..c8aa4143ac4f 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -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] = {
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index f4a1c2d4b078..fafa299efa5c 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -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;
-- 
2.44.0.701.g2cf7baacf3.dirty


  parent reply	other threads:[~2024-04-28  9:37 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-28  9:37 [PATCH v2 0/4] ALSA: emu10k1: more improvements related to uploading firmware to the E-MU dock Oswald Buddenhagen
2024-04-28  9:37 ` [PATCH v2 1/4] ALSA: emu10k1: simplify E-MU card FPGA reset sequence Oswald Buddenhagen
2024-04-28  9:37 ` [PATCH v2 2/4] ALSA: emu10k1: make snd_emu1010_load_firmware_entry() void Oswald Buddenhagen
2024-04-28  9:37 ` Oswald Buddenhagen [this message]
2024-04-28  9:37 ` [PATCH v2 4/4] ALSA: emu10k1: move code for entering E-MU card FPGA programming mode Oswald Buddenhagen
2024-04-28 18:16 ` [PATCH v2 0/4] ALSA: emu10k1: more improvements related to uploading firmware to the E-MU dock Takashi Iwai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240428093717.3198716-4-oswald.buddenhagen@gmx.de \
    --to=oswald.buddenhagen@gmx.de \
    --cc=linux-sound@vger.kernel.org \
    --cc=perex@perex.cz \
    --cc=pietrocaruso50@gmail.com \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).