diff options
author | Takashi Iwai <tiwai@suse.de> | 2005-11-17 10:16:36 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-01-03 06:28:04 -0500 |
commit | 703529140cfb774366b839f38f027f283cb948b4 (patch) | |
tree | a138810f5748f34aea4d3617010e8ede9fc1075c /sound | |
parent | 5bdb6a1629408f657f5f2c42b3c07c689c411499 (diff) |
[ALSA] als4000 - Add PM support
Modules: ALS4000 driver
Add PM support to PCI ALS4000 driver.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/als4000.c | 76 |
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 | ||
554 | static void __devinit snd_als4000_configure(struct snd_sb *chip) | 567 | static 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 | ||
795 | static 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 | |||
812 | static 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 | |||
780 | static struct pci_driver driver = { | 838 | static 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 | ||
787 | static int __init alsa_card_als4000_init(void) | 849 | static int __init alsa_card_als4000_init(void) |