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
next prev 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