aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2005-11-17 10:16:36 -0500
committerJaroslav Kysela <perex@suse.cz>2006-01-03 06:28:04 -0500
commit703529140cfb774366b839f38f027f283cb948b4 (patch)
treea138810f5748f34aea4d3617010e8ede9fc1075c
parent5bdb6a1629408f657f5f2c42b3c07c689c411499 (diff)
[ALSA] als4000 - Add PM support
Modules: ALS4000 driver Add PM support to PCI ALS4000 driver. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/als4000.c76
1 files changed, 69 insertions, 7 deletions
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 8d0d9c0222c1..7b2ff5f4672e 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -109,6 +109,7 @@ struct snd_card_als4000 {
109 /* most frequent access first */ 109 /* most frequent access first */
110 unsigned long gcr; 110 unsigned long gcr;
111 struct pci_dev *pci; 111 struct pci_dev *pci;
112 struct snd_sb *chip;
112#ifdef SUPPORT_JOYSTICK 113#ifdef SUPPORT_JOYSTICK
113 struct gameport *gameport; 114 struct gameport *gameport;
114#endif 115#endif
@@ -305,14 +306,20 @@ static int snd_als4000_capture_trigger(struct snd_pcm_substream *substream, int
305 int result = 0; 306 int result = 0;
306 307
307 spin_lock(&chip->mixer_lock); 308 spin_lock(&chip->mixer_lock);
308 if (cmd == SNDRV_PCM_TRIGGER_START) { 309 switch (cmd) {
310 case SNDRV_PCM_TRIGGER_START:
311 case SNDRV_PCM_TRIGGER_RESUME:
309 chip->mode |= SB_RATE_LOCK_CAPTURE; 312 chip->mode |= SB_RATE_LOCK_CAPTURE;
310 snd_sbmixer_write(chip, 0xde, capture_cmd(chip)); 313 snd_sbmixer_write(chip, 0xde, capture_cmd(chip));
311 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { 314 break;
315 case SNDRV_PCM_TRIGGER_STOP:
316 case SNDRV_PCM_TRIGGER_SUSPEND:
312 chip->mode &= ~SB_RATE_LOCK_CAPTURE; 317 chip->mode &= ~SB_RATE_LOCK_CAPTURE;
313 snd_sbmixer_write(chip, 0xde, 0); 318 snd_sbmixer_write(chip, 0xde, 0);
314 } else { 319 break;
320 default:
315 result = -EINVAL; 321 result = -EINVAL;
322 break;
316 } 323 }
317 spin_unlock(&chip->mixer_lock); 324 spin_unlock(&chip->mixer_lock);
318 return result; 325 return result;
@@ -324,14 +331,20 @@ static int snd_als4000_playback_trigger(struct snd_pcm_substream *substream, int
324 int result = 0; 331 int result = 0;
325 332
326 spin_lock(&chip->reg_lock); 333 spin_lock(&chip->reg_lock);
327 if (cmd == SNDRV_PCM_TRIGGER_START) { 334 switch (cmd) {
335 case SNDRV_PCM_TRIGGER_START:
336 case SNDRV_PCM_TRIGGER_RESUME:
328 chip->mode |= SB_RATE_LOCK_PLAYBACK; 337 chip->mode |= SB_RATE_LOCK_PLAYBACK;
329 snd_sbdsp_command(chip, playback_cmd(chip).dma_on); 338 snd_sbdsp_command(chip, playback_cmd(chip).dma_on);
330 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { 339 break;
340 case SNDRV_PCM_TRIGGER_STOP:
341 case SNDRV_PCM_TRIGGER_SUSPEND:
331 snd_sbdsp_command(chip, playback_cmd(chip).dma_off); 342 snd_sbdsp_command(chip, playback_cmd(chip).dma_off);
332 chip->mode &= ~SB_RATE_LOCK_PLAYBACK; 343 chip->mode &= ~SB_RATE_LOCK_PLAYBACK;
333 } else { 344 break;
345 default:
334 result = -EINVAL; 346 result = -EINVAL;
347 break;
335 } 348 }
336 spin_unlock(&chip->reg_lock); 349 spin_unlock(&chip->reg_lock);
337 return result; 350 return result;
@@ -551,7 +564,7 @@ static void snd_als4000_set_addr(unsigned long gcr,
551 snd_als4000_gcr_write_addr(gcr, 0xa9, confB); 564 snd_als4000_gcr_write_addr(gcr, 0xa9, confB);
552} 565}
553 566
554static void __devinit snd_als4000_configure(struct snd_sb *chip) 567static void snd_als4000_configure(struct snd_sb *chip)
555{ 568{
556 unsigned tmp; 569 unsigned tmp;
557 int i; 570 int i;
@@ -718,6 +731,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
718 &chip)) < 0) { 731 &chip)) < 0) {
719 goto out_err; 732 goto out_err;
720 } 733 }
734 acard->chip = chip;
721 735
722 chip->pci = pci; 736 chip->pci = pci;
723 chip->alt_port = gcr; 737 chip->alt_port = gcr;
@@ -777,11 +791,59 @@ static void __devexit snd_card_als4000_remove(struct pci_dev *pci)
777 pci_set_drvdata(pci, NULL); 791 pci_set_drvdata(pci, NULL);
778} 792}
779 793
794#ifdef CONFIG_PM
795static int snd_als4000_suspend(struct pci_dev *pci, pm_message_t state)
796{
797 struct snd_card *card = pci_get_drvdata(pci);
798 struct snd_card_als4000 *acard = card->private_data;
799 struct snd_sb *chip = acard->chip;
800
801 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
802
803 snd_pcm_suspend_all(chip->pcm);
804 snd_sbmixer_suspend(chip);
805
806 pci_set_power_state(pci, PCI_D3hot);
807 pci_disable_device(pci);
808 pci_save_state(pci);
809 return 0;
810}
811
812static int snd_als4000_resume(struct pci_dev *pci)
813{
814 struct snd_card *card = pci_get_drvdata(pci);
815 struct snd_card_als4000 *acard = card->private_data;
816 struct snd_sb *chip = acard->chip;
817
818 pci_restore_state(pci);
819 pci_enable_device(pci);
820 pci_set_power_state(pci, PCI_D0);
821 pci_set_master(pci);
822
823 snd_als4000_configure(chip);
824 snd_sbdsp_reset(chip);
825 snd_sbmixer_resume(chip);
826
827#ifdef SUPPORT_JOYSTICK
828 if (acard->gameport)
829 snd_als4000_set_addr(acard->gcr, 0, 0, 0, 1);
830#endif
831
832 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
833 return 0;
834}
835#endif
836
837
780static struct pci_driver driver = { 838static struct pci_driver driver = {
781 .name = "ALS4000", 839 .name = "ALS4000",
782 .id_table = snd_als4000_ids, 840 .id_table = snd_als4000_ids,
783 .probe = snd_card_als4000_probe, 841 .probe = snd_card_als4000_probe,
784 .remove = __devexit_p(snd_card_als4000_remove), 842 .remove = __devexit_p(snd_card_als4000_remove),
843#ifdef CONFIG_PM
844 .suspend = snd_als4000_suspend,
845 .resume = snd_als4000_resume,
846#endif
785}; 847};
786 848
787static int __init alsa_card_als4000_init(void) 849static int __init alsa_card_als4000_init(void)