Commit cb28e45ba2aa42393596a364d4f947027db8a1b5
Committed by
Jaroslav Kysela
1 parent
1d4b822be6
Exists in
master
and in
7 other branches
[ALSA] cs46xx - Fix PM support
Modules: CS46xx driver Fix PM support on CS46xx driver. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Showing 3 changed files with 22 additions and 14 deletions Side-by-side Diff
include/sound/cs46xx.h
... | ... | @@ -1728,6 +1728,8 @@ |
1728 | 1728 | struct pci_dev *pci, |
1729 | 1729 | int external_amp, int thinkpad, |
1730 | 1730 | struct snd_cs46xx **rcodec); |
1731 | +int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state); | |
1732 | +int snd_cs46xx_resume(struct pci_dev *pci); | |
1731 | 1733 | |
1732 | 1734 | int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm); |
1733 | 1735 | int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm); |
sound/pci/cs46xx/cs46xx.c
... | ... | @@ -98,6 +98,7 @@ |
98 | 98 | snd_card_free(card); |
99 | 99 | return err; |
100 | 100 | } |
101 | + card->private_data = chip; | |
101 | 102 | chip->accept_valid = mmap_valid[dev]; |
102 | 103 | if ((err = snd_cs46xx_pcm(chip, 0, NULL)) < 0) { |
103 | 104 | snd_card_free(card); |
... | ... | @@ -166,7 +167,10 @@ |
166 | 167 | .id_table = snd_cs46xx_ids, |
167 | 168 | .probe = snd_card_cs46xx_probe, |
168 | 169 | .remove = __devexit_p(snd_card_cs46xx_remove), |
169 | - SND_PCI_PM_CALLBACKS | |
170 | +#ifdef CONFIG_PM | |
171 | + .suspend = snd_cs46xx_suspend, | |
172 | + .resume = snd_cs46xx_resume, | |
173 | +#endif | |
170 | 174 | }; |
171 | 175 | |
172 | 176 | static int __init alsa_card_cs46xx_init(void) |
sound/pci/cs46xx/cs46xx_lib.c
... | ... | @@ -3654,18 +3654,19 @@ |
3654 | 3654 | * APM support |
3655 | 3655 | */ |
3656 | 3656 | #ifdef CONFIG_PM |
3657 | -static int snd_cs46xx_suspend(struct snd_card *card, pm_message_t state) | |
3657 | +int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) | |
3658 | 3658 | { |
3659 | - struct snd_cs46xx *chip = card->pm_private_data; | |
3659 | + struct snd_card *card = pci_get_drvdata(pci); | |
3660 | + struct snd_cs46xx *chip = card->private_data; | |
3660 | 3661 | int amp_saved; |
3661 | 3662 | |
3663 | + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | |
3662 | 3664 | snd_pcm_suspend_all(chip->pcm); |
3663 | 3665 | // chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL); |
3664 | 3666 | // chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE); |
3665 | 3667 | |
3666 | 3668 | snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); |
3667 | - if (chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]) | |
3668 | - snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); | |
3669 | + snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); | |
3669 | 3670 | |
3670 | 3671 | amp_saved = chip->amplifier; |
3671 | 3672 | /* turn off amp */ |
3672 | 3673 | |
3673 | 3674 | |
3674 | 3675 | |
... | ... | @@ -3674,17 +3675,20 @@ |
3674 | 3675 | /* disable CLKRUN */ |
3675 | 3676 | chip->active_ctrl(chip, -chip->amplifier); |
3676 | 3677 | chip->amplifier = amp_saved; /* restore the status */ |
3677 | - pci_disable_device(chip->pci); | |
3678 | + pci_disable_device(pci); | |
3679 | + pci_save_state(pci); | |
3678 | 3680 | return 0; |
3679 | 3681 | } |
3680 | 3682 | |
3681 | -static int snd_cs46xx_resume(struct snd_card *card) | |
3683 | +int snd_cs46xx_resume(struct pci_dev *pci) | |
3682 | 3684 | { |
3683 | - struct snd_cs46xx *chip = card->pm_private_data; | |
3685 | + struct snd_card *card = pci_get_drvdata(pci); | |
3686 | + struct snd_cs46xx *chip = card->private_data; | |
3684 | 3687 | int amp_saved; |
3685 | 3688 | |
3686 | - pci_enable_device(chip->pci); | |
3687 | - pci_set_master(chip->pci); | |
3689 | + pci_restore_state(pci); | |
3690 | + pci_enable_device(pci); | |
3691 | + pci_set_master(pci); | |
3688 | 3692 | amp_saved = chip->amplifier; |
3689 | 3693 | chip->amplifier = 0; |
3690 | 3694 | chip->active_ctrl(chip, 1); /* force to on */ |
3691 | 3695 | |
... | ... | @@ -3703,14 +3707,14 @@ |
3703 | 3707 | #endif |
3704 | 3708 | |
3705 | 3709 | snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); |
3706 | - if (chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]) | |
3707 | - snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); | |
3710 | + snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); | |
3708 | 3711 | |
3709 | 3712 | if (amp_saved) |
3710 | 3713 | chip->amplifier_ctrl(chip, 1); /* turn amp on */ |
3711 | 3714 | else |
3712 | 3715 | chip->active_ctrl(chip, -1); /* disable CLKRUN */ |
3713 | 3716 | chip->amplifier = amp_saved; |
3717 | + snd_power_change_state(card, SNDRV_CTL_POWER_D0); | |
3714 | 3718 | return 0; |
3715 | 3719 | } |
3716 | 3720 | #endif /* CONFIG_PM */ |
... | ... | @@ -3869,8 +3873,6 @@ |
3869 | 3873 | } |
3870 | 3874 | |
3871 | 3875 | snd_cs46xx_proc_init(card, chip); |
3872 | - | |
3873 | - snd_card_set_pm_callback(card, snd_cs46xx_suspend, snd_cs46xx_resume, chip); | |
3874 | 3876 | |
3875 | 3877 | chip->active_ctrl(chip, -1); /* disable CLKRUN */ |
3876 | 3878 |