diff options
| author | Cássio Gabriel <cassiogabrielcontato@gmail.com> | 2026-04-10 06:54:33 +0300 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2026-04-10 15:59:47 +0300 |
| commit | 47f72d57ddb11222479c80bd07f5bc036d84c94d (patch) | |
| tree | c7b9870d6d40647de89ceece0b4bc6368def4ddd | |
| parent | fb79bf127ac2577b4876132da6dba768018aad4c (diff) | |
| download | linux-47f72d57ddb11222479c80bd07f5bc036d84c94d.tar.xz | |
ALSA: sc6000: Restore board setup across suspend
snd_wss_resume() restores only the codec register image. The SC-6000
driver also programs card-specific DSP routing and enters MSS mode
during probe, and that setup is not replayed after suspend.
Cache the WSS chip pointer in the SC-6000 card state and wire ISA
suspend and resume callbacks to the shared board-programming helper,
so the board is reinitialized before the codec state is restored.
This keeps the old/new DSP split in one place and restores the
board-level MSS setup that the codec resume path does not cover.
Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260410-alsa-sc6000-pm-v1-2-4d9e95493d26@gmail.com
| -rw-r--r-- | sound/isa/sc6000.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c index 9949e06403f6..cd3a63c7c2a7 100644 --- a/sound/isa/sc6000.c +++ b/sound/isa/sc6000.c @@ -103,6 +103,7 @@ MODULE_PARM_DESC(joystick, "Enable gameport."); struct snd_sc6000 { char __iomem *vport; char __iomem *vmss_port; + struct snd_wss *chip; u8 mss_config; u8 config; u8 hw_cfg[2]; @@ -646,6 +647,7 @@ static int __snd_sc6000_probe(struct device *devptr, unsigned int dev) WSS_HW_DETECT, 0, &chip); if (err < 0) return err; + sc6000->chip = chip; err = snd_wss_pcm(chip, 0); if (err < 0) { @@ -702,10 +704,47 @@ static int snd_sc6000_probe(struct device *devptr, unsigned int dev) return snd_card_free_on_error(devptr, __snd_sc6000_probe(devptr, dev)); } +#ifdef CONFIG_PM +static int snd_sc6000_suspend(struct device *devptr, unsigned int dev, + pm_message_t state) +{ + struct snd_card *card = dev_get_drvdata(devptr); + struct snd_sc6000 *sc6000 = card->private_data; + + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + sc6000->chip->suspend(sc6000->chip); + return 0; +} + +static int snd_sc6000_resume(struct device *devptr, unsigned int dev) +{ + struct snd_card *card = dev_get_drvdata(devptr); + struct snd_sc6000 *sc6000 = card->private_data; + int err; + + err = sc6000_dsp_reset(sc6000->vport); + if (err < 0) { + dev_err(devptr, "sc6000_dsp_reset: failed!\n"); + return err; + } + + err = sc6000_program_board(devptr, sc6000); + if (err < 0) + return err; + + sc6000->chip->resume(sc6000->chip); + snd_power_change_state(card, SNDRV_CTL_POWER_D0); + return 0; +} +#endif + static struct isa_driver snd_sc6000_driver = { .match = snd_sc6000_match, .probe = snd_sc6000_probe, - /* FIXME: suspend/resume */ +#ifdef CONFIG_PM + .suspend = snd_sc6000_suspend, + .resume = snd_sc6000_resume, +#endif .driver = { .name = DRV_NAME, }, |
