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 2/2] ALSA: msnd: add ISA and PnP system sleep callbacks
Date: Thu, 09 Apr 2026 02:07:46 -0300	[thread overview]
Message-ID: <20260409-msnd-pm-support-v1-2-2abef720d0e7@gmail.com> (raw)
In-Reply-To: <20260409-msnd-pm-support-v1-0-2abef720d0e7@gmail.com>

The msnd drivers do not implement system sleep callbacks today, so
they have no defined way to recover DSP state after suspend.

Add common card suspend/resume helpers, rerun the DSP
initialization path on resume, restore the cached capture-source
state, and rearm the shared IRQ for already-open users.

Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
 sound/isa/msnd/msnd.h          |  2 +
 sound/isa/msnd/msnd_pinnacle.c | 95 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/sound/isa/msnd/msnd.h b/sound/isa/msnd/msnd.h
index b25beca25c0d..56a700e6a5cb 100644
--- a/sound/isa/msnd/msnd.h
+++ b/sound/isa/msnd/msnd.h
@@ -253,6 +253,8 @@ struct snd_msnd {
 	spinlock_t mixer_lock;
 	int nresets;
 	unsigned recsrc;
+	u8 pm_recsrc;
+	bool pm_mpu_input;
 #define LEVEL_ENTRIES 32
 	int left_levels[LEVEL_ENTRIES];
 	int right_levels[LEVEL_ENTRIES];
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c
index c4eec391cd29..5b729bb02ef6 100644
--- a/sound/isa/msnd/msnd_pinnacle.c
+++ b/sound/isa/msnd/msnd_pinnacle.c
@@ -513,6 +513,19 @@ static void snd_msnd_mpu401_close(struct snd_mpu401 *mpu)
 	snd_msnd_disable_irq(mpu->private_data);
 }
 
+#ifdef CONFIG_PM
+static u8 snd_msnd_pm_recsrc(struct snd_msnd *chip)
+{
+	/* Convert recsrc to the Capture Source selector: 0=Analog, 1=MASS, 2=SPDIF. */
+	if (chip->recsrc & BIT(4))
+		return 1;
+	if ((chip->recsrc & BIT(17)) &&
+	    test_bit(F_HAVEDIGITAL, &chip->flags))
+		return 2;
+	return 0;
+}
+#endif
+
 static long mpu_io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
 
@@ -1001,10 +1014,73 @@ static int snd_msnd_isa_probe(struct device *pdev, unsigned int idx)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int snd_msnd_card_suspend(struct snd_card *card)
+{
+	struct snd_msnd *chip = card->private_data;
+	struct snd_mpu401 *mpu;
+	int err;
+
+	mpu = chip->rmidi ? chip->rmidi->private_data : NULL;
+	chip->pm_recsrc = snd_msnd_pm_recsrc(chip);
+	chip->pm_mpu_input = mpu && test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode);
+	if (chip->pm_mpu_input)
+		snd_msnd_send_dsp_cmd(chip, HDEX_MIDI_IN_STOP);
+
+	err = snd_msnd_force_irq(chip, false);
+	if (err < 0) {
+		if (chip->pm_mpu_input)
+			snd_msnd_send_dsp_cmd(chip, HDEX_MIDI_IN_START);
+		return err;
+	}
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	return 0;
+}
+
+static int snd_msnd_card_resume(struct snd_card *card)
+{
+	struct snd_msnd *chip = card->private_data;
+	int err;
+
+	err = snd_msnd_initialize(card);
+	if (err < 0)
+		return err;
+
+	snd_msnd_calibrate_adc(chip, chip->play_sample_rate);
+	snd_msndmix_force_recsrc(chip, chip->pm_recsrc);
+
+	err = snd_msnd_force_irq(chip, true);
+	if (err < 0)
+		return err;
+
+	if (chip->pm_mpu_input)
+		snd_msnd_send_dsp_cmd(chip, HDEX_MIDI_IN_START);
+
+	chip->nresets = 0;
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+
+static int snd_msnd_isa_suspend(struct device *dev, unsigned int idx,
+				pm_message_t state)
+{
+	return snd_msnd_card_suspend(dev_get_drvdata(dev));
+}
+
+static int snd_msnd_isa_resume(struct device *dev, unsigned int idx)
+{
+	return snd_msnd_card_resume(dev_get_drvdata(dev));
+}
+#endif
+
 static struct isa_driver snd_msnd_driver = {
 	.match		= snd_msnd_isa_match,
 	.probe		= snd_msnd_isa_probe,
-	/* FIXME: suspend, resume */
+#ifdef CONFIG_PM
+	.suspend	= snd_msnd_isa_suspend,
+	.resume		= snd_msnd_isa_resume,
+#endif
 	.driver		= {
 		.name	= DEV_NAME
 	},
@@ -1111,6 +1187,18 @@ static int snd_msnd_pnp_detect(struct pnp_card_link *pcard,
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int snd_msnd_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
+{
+	return snd_msnd_card_suspend(pnp_get_card_drvdata(pcard));
+}
+
+static int snd_msnd_pnp_resume(struct pnp_card_link *pcard)
+{
+	return snd_msnd_card_resume(pnp_get_card_drvdata(pcard));
+}
+#endif
+
 static int isa_registered;
 static int pnp_registered;
 
@@ -1127,6 +1215,10 @@ static struct pnp_card_driver msnd_pnpc_driver = {
 	.name = "msnd_pinnacle",
 	.id_table = msnd_pnpids,
 	.probe = snd_msnd_pnp_detect,
+#ifdef CONFIG_PM
+	.suspend = snd_msnd_pnp_suspend,
+	.resume = snd_msnd_pnp_resume,
+#endif
 };
 #endif /* CONFIG_PNP */
 
@@ -1161,4 +1253,3 @@ static void __exit snd_msnd_exit(void)
 
 module_init(snd_msnd_init);
 module_exit(snd_msnd_exit);
-

-- 
2.53.0


  parent reply	other threads:[~2026-04-09  5:07 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-09  5:07 [PATCH 0/2] ALSA: msnd: add suspend/resume support Cássio Gabriel
2026-04-09  5:07 ` [PATCH 1/2] ALSA: msnd: prepare system sleep support Cássio Gabriel
2026-04-09  5:07 ` Cássio Gabriel [this message]
2026-04-09 10:02 ` [PATCH 0/2] ALSA: msnd: add suspend/resume support 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=20260409-msnd-pm-support-v1-2-2abef720d0e7@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