public inbox for linux-sound@vger.kernel.org
 help / color / mirror / Atom feed
From: "Cássio Gabriel" <cassiogabrielcontato@gmail.com>
To: Takashi Iwai <tiwai@suse.com>, Jaroslav Kysela <perex@perex.cz>
Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org,
	"Cássio Gabriel" <cassiogabrielcontato@gmail.com>
Subject: [PATCH v2 2/2] ALSA: sscape: Add suspend and resume support
Date: Sat, 11 Apr 2026 15:14:41 -0300	[thread overview]
Message-ID: <20260411-alsa-sscape-pm-v2-2-aeb5682e14b0@gmail.com> (raw)
In-Reply-To: <20260411-alsa-sscape-pm-v2-0-aeb5682e14b0@gmail.com>

The SoundScape ISA driver has lacked suspend and resume callbacks since
commit 277e926c9b27 ("[ALSA] sscape - Use platform_device").

A plain snd_wss resume is not sufficient for SoundScape. Resume also
needs to restore the board-specific gate-array routing, and non-VIVO
boards need to reinitialize the probe-time MIDI firmware and MIDI
control state when the MPU-401 side was enabled during probe.

That firmware reload can be handled in-kernel because
commit acd47100914b ("ALSA: sscape: convert to firmware loader framework")
moved the driver to request_firmware().

Add ISA and ISA-PnP PM callbacks, reconfigure the board on resume,
reload the non-VIVO MIDI firmware, restore the MIDI state, and then
resume the WSS codec. If MIDI firmware reload fails, keep the WSS resume
path alive and leave MIDI unavailable instead of failing the whole
device resume.

Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
 sound/isa/sscape.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 93 insertions(+)

diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 6e951b3c0080..553ceb92d298 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -144,6 +144,7 @@ struct soundscape {
 
 	unsigned char midi_vol;
 	bool joystick;
+	bool midi_enabled;
 	struct device *dev;
 };
 
@@ -1107,6 +1108,7 @@ static int create_sscape(struct snd_card *card)
 			}
 
 			sscape->midi_vol = 0;
+			sscape->midi_enabled = true;
 			err = sscape_restore_midi_state(sscape);
 			if (err < 0)
 				dev_warn(card->dev,
@@ -1118,6 +1120,77 @@ static int create_sscape(struct snd_card *card)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+/*
+ * Reload the MIDI firmware and restore the saved MIDI state for
+ * boards whose MPU-401 side was enabled during probe.
+ */
+static int sscape_resume_midi(struct snd_card *card)
+{
+	struct soundscape *sscape = get_card_soundscape(card);
+	int err, version;
+
+	if (!sscape->midi_enabled)
+		return 0;
+
+	version = sscape_upload_bootblock(card);
+	if (version < 0)
+		return version;
+
+	err = sscape_upload_microcode(card, version);
+	if (err < 0)
+		return err;
+
+	outb(0, sscape->io_base);
+
+	return sscape_restore_midi_state(sscape);
+}
+
+/*
+ * Save the WSS codec state before the SoundScape is suspended.
+ */
+static int snd_sscape_suspend_card(struct snd_card *card)
+{
+	struct soundscape *sscape = get_card_soundscape(card);
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	sscape->chip->suspend(sscape->chip);
+	return 0;
+}
+
+/*
+ * Restore the board-specific state before resuming the WSS codec.
+ */
+static int snd_sscape_resume_card(struct snd_card *card)
+{
+	struct soundscape *sscape = get_card_soundscape(card);
+	int err;
+
+	err = sscape_configure_board(sscape);
+	if (err < 0)
+		return err;
+
+	err = sscape_resume_midi(card);
+	if (err < 0)
+		dev_warn(card->dev, "sscape: MIDI restore failed: %d\n", err);
+
+	sscape->chip->resume(sscape->chip);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+
+static int snd_sscape_suspend(struct device *dev, unsigned int n,
+			      pm_message_t state)
+{
+	return snd_sscape_suspend_card(dev_get_drvdata(dev));
+}
+
+static int snd_sscape_resume(struct device *dev, unsigned int n)
+{
+	return snd_sscape_resume_card(dev_get_drvdata(dev));
+}
+#endif
+
 
 static int snd_sscape_match(struct device *pdev, unsigned int i)
 {
@@ -1174,6 +1247,10 @@ static int snd_sscape_probe(struct device *pdev, unsigned int dev)
 static struct isa_driver snd_sscape_driver = {
 	.match		= snd_sscape_match,
 	.probe		= snd_sscape_probe,
+#ifdef CONFIG_PM
+	.suspend	= snd_sscape_suspend,
+	.resume		= snd_sscape_resume,
+#endif
 	.driver		= {
 		.name	= DEV_NAME
 	},
@@ -1271,11 +1348,27 @@ static int sscape_pnp_detect(struct pnp_card_link *pcard,
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int sscape_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
+{
+	return snd_sscape_suspend_card(pnp_get_card_drvdata(pcard));
+}
+
+static int sscape_pnp_resume(struct pnp_card_link *pcard)
+{
+	return snd_sscape_resume_card(pnp_get_card_drvdata(pcard));
+}
+#endif
+
 static struct pnp_card_driver sscape_pnpc_driver = {
 	.flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
 	.name = "sscape",
 	.id_table = sscape_pnpids,
 	.probe = sscape_pnp_detect,
+#ifdef CONFIG_PM
+	.suspend = sscape_pnp_suspend,
+	.resume = sscape_pnp_resume,
+#endif
 };
 
 #endif /* CONFIG_PNP */

-- 
2.53.0


      parent reply	other threads:[~2026-04-11 18:14 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-11 18:14 [PATCH v2 0/2] ALSA: sscape: add suspend/resume support Cássio Gabriel
2026-04-11 18:14 ` [PATCH v2 1/2] ALSA: sscape: Cache per-card resources for board reinitialization Cássio Gabriel
2026-04-11 18:14 ` Cássio Gabriel [this message]

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=20260411-alsa-sscape-pm-v2-2-aeb5682e14b0@gmail.com \
    --to=cassiogabrielcontato@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=perex@perex.cz \
    --cc=tiwai@suse.com \
    /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