Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[ALSA] cs46xx - Fix PM support

Modules: CS46xx driver

Fix PM support on CS46xx driver.

Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Takashi Iwai and committed by
Jaroslav Kysela
cb28e45b 1d4b822b

+22 -14
+2
include/sound/cs46xx.h
··· 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);
+5 -1
sound/pci/cs46xx/cs46xx.c
··· 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); ··· 167 166 .id_table = snd_cs46xx_ids, 168 167 .probe = snd_card_cs46xx_probe, 169 168 .remove = __devexit_p(snd_card_cs46xx_remove), 170 - SND_PCI_PM_CALLBACKS 169 + #ifdef CONFIG_PM 170 + .suspend = snd_cs46xx_suspend, 171 + .resume = snd_cs46xx_resume, 172 + #endif 171 173 }; 172 174 173 175 static int __init alsa_card_cs46xx_init(void)
+15 -13
sound/pci/cs46xx/cs46xx_lib.c
··· 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 */ ··· 3675 3674 /* disable CLKRUN */ 3676 3675 chip->active_ctrl(chip, -chip->amplifier); 3677 3676 chip->amplifier = amp_saved; /* restore the status */ 3678 - pci_disable_device(chip->pci); 3677 + pci_disable_device(pci); 3678 + pci_save_state(pci); 3679 3679 return 0; 3680 3680 } 3681 3681 3682 - static int snd_cs46xx_resume(struct snd_card *card) 3682 + int snd_cs46xx_resume(struct pci_dev *pci) 3683 3683 { 3684 - struct snd_cs46xx *chip = card->pm_private_data; 3684 + struct snd_card *card = pci_get_drvdata(pci); 3685 + struct snd_cs46xx *chip = card->private_data; 3685 3686 int amp_saved; 3686 3687 3687 - pci_enable_device(chip->pci); 3688 - pci_set_master(chip->pci); 3688 + pci_restore_state(pci); 3689 + pci_enable_device(pci); 3690 + pci_set_master(pci); 3689 3691 amp_saved = chip->amplifier; 3690 3692 chip->amplifier = 0; 3691 3693 chip->active_ctrl(chip, 1); /* force to on */ ··· 3707 3703 #endif 3708 3704 3709 3705 snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); 3710 - if (chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]) 3711 - snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); 3706 + snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); 3712 3707 3713 3708 if (amp_saved) 3714 3709 chip->amplifier_ctrl(chip, 1); /* turn amp on */ 3715 3710 else 3716 3711 chip->active_ctrl(chip, -1); /* disable CLKRUN */ 3717 3712 chip->amplifier = amp_saved; 3713 + snd_power_change_state(card, SNDRV_CTL_POWER_D0); 3718 3714 return 0; 3719 3715 } 3720 3716 #endif /* CONFIG_PM */ ··· 3873 3869 } 3874 3870 3875 3871 snd_cs46xx_proc_init(card, chip); 3876 - 3877 - snd_card_set_pm_callback(card, snd_cs46xx_suspend, snd_cs46xx_resume, chip); 3878 3872 3879 3873 chip->active_ctrl(chip, -1); /* disable CLKRUN */ 3880 3874