aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/cs46xx/cs46xx_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/cs46xx/cs46xx_lib.c')
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c77
1 files changed, 62 insertions, 15 deletions
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index bef1f6d1859c..71d7aab9d869 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -2897,6 +2897,10 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip)
2897 } 2897 }
2898#endif 2898#endif
2899 2899
2900#ifdef CONFIG_PM
2901 kfree(chip->saved_regs);
2902#endif
2903
2900 pci_disable_device(chip->pci); 2904 pci_disable_device(chip->pci);
2901 kfree(chip); 2905 kfree(chip);
2902 return 0; 2906 return 0;
@@ -3140,6 +3144,23 @@ static int snd_cs46xx_chip_init(struct snd_cs46xx *chip)
3140/* 3144/*
3141 * start and load DSP 3145 * start and load DSP
3142 */ 3146 */
3147
3148static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip)
3149{
3150 unsigned int tmp;
3151
3152 snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM);
3153
3154 tmp = snd_cs46xx_peek(chip, BA1_PFIE);
3155 tmp &= ~0x0000f03f;
3156 snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */
3157
3158 tmp = snd_cs46xx_peek(chip, BA1_CIE);
3159 tmp &= ~0x0000003f;
3160 tmp |= 0x00000001;
3161 snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */
3162}
3163
3143int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip) 3164int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
3144{ 3165{
3145 unsigned int tmp; 3166 unsigned int tmp;
@@ -3214,19 +3235,7 @@ int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
3214 3235
3215 snd_cs46xx_proc_start(chip); 3236 snd_cs46xx_proc_start(chip);
3216 3237
3217 /* 3238 cs46xx_enable_stream_irqs(chip);
3218 * Enable interrupts on the part.
3219 */
3220 snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM);
3221
3222 tmp = snd_cs46xx_peek(chip, BA1_PFIE);
3223 tmp &= ~0x0000f03f;
3224 snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */
3225
3226 tmp = snd_cs46xx_peek(chip, BA1_CIE);
3227 tmp &= ~0x0000003f;
3228 tmp |= 0x00000001;
3229 snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */
3230 3239
3231#ifndef CONFIG_SND_CS46XX_NEW_DSP 3240#ifndef CONFIG_SND_CS46XX_NEW_DSP
3232 /* set the attenuation to 0dB */ 3241 /* set the attenuation to 0dB */
@@ -3665,11 +3674,19 @@ static struct cs_card_type __devinitdata cards[] = {
3665 * APM support 3674 * APM support
3666 */ 3675 */
3667#ifdef CONFIG_PM 3676#ifdef CONFIG_PM
3677static unsigned int saved_regs[] = {
3678 BA0_ACOSV,
3679 BA0_ASER_FADDR,
3680 BA0_ASER_MASTER,
3681 BA1_PVOL,
3682 BA1_CVOL,
3683};
3684
3668int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) 3685int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state)
3669{ 3686{
3670 struct snd_card *card = pci_get_drvdata(pci); 3687 struct snd_card *card = pci_get_drvdata(pci);
3671 struct snd_cs46xx *chip = card->private_data; 3688 struct snd_cs46xx *chip = card->private_data;
3672 int amp_saved; 3689 int i, amp_saved;
3673 3690
3674 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 3691 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
3675 chip->in_suspend = 1; 3692 chip->in_suspend = 1;
@@ -3680,6 +3697,10 @@ int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state)
3680 snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); 3697 snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
3681 snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); 3698 snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
3682 3699
3700 /* save some registers */
3701 for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
3702 chip->saved_regs[i] = snd_cs46xx_peekBA0(chip, saved_regs[i]);
3703
3683 amp_saved = chip->amplifier; 3704 amp_saved = chip->amplifier;
3684 /* turn off amp */ 3705 /* turn off amp */
3685 chip->amplifier_ctrl(chip, -chip->amplifier); 3706 chip->amplifier_ctrl(chip, -chip->amplifier);
@@ -3698,7 +3719,7 @@ int snd_cs46xx_resume(struct pci_dev *pci)
3698{ 3719{
3699 struct snd_card *card = pci_get_drvdata(pci); 3720 struct snd_card *card = pci_get_drvdata(pci);
3700 struct snd_cs46xx *chip = card->private_data; 3721 struct snd_cs46xx *chip = card->private_data;
3701 int amp_saved; 3722 int i, amp_saved;
3702 3723
3703 pci_set_power_state(pci, PCI_D0); 3724 pci_set_power_state(pci, PCI_D0);
3704 pci_restore_state(pci); 3725 pci_restore_state(pci);
@@ -3716,6 +3737,16 @@ int snd_cs46xx_resume(struct pci_dev *pci)
3716 3737
3717 snd_cs46xx_chip_init(chip); 3738 snd_cs46xx_chip_init(chip);
3718 3739
3740 snd_cs46xx_reset(chip);
3741#ifdef CONFIG_SND_CS46XX_NEW_DSP
3742 cs46xx_dsp_resume(chip);
3743 /* restore some registers */
3744 for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
3745 snd_cs46xx_pokeBA0(chip, saved_regs[i], chip->saved_regs[i]);
3746#else
3747 snd_cs46xx_download_image(chip);
3748#endif
3749
3719#if 0 3750#if 0
3720 snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, 3751 snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE,
3721 chip->ac97_general_purpose); 3752 chip->ac97_general_purpose);
@@ -3730,6 +3761,13 @@ int snd_cs46xx_resume(struct pci_dev *pci)
3730 snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); 3761 snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
3731 snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); 3762 snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
3732 3763
3764 /* reset playback/capture */
3765 snd_cs46xx_set_play_sample_rate(chip, 8000);
3766 snd_cs46xx_set_capture_sample_rate(chip, 8000);
3767 snd_cs46xx_proc_start(chip);
3768
3769 cs46xx_enable_stream_irqs(chip);
3770
3733 if (amp_saved) 3771 if (amp_saved)
3734 chip->amplifier_ctrl(chip, 1); /* turn amp on */ 3772 chip->amplifier_ctrl(chip, 1); /* turn amp on */
3735 else 3773 else
@@ -3896,6 +3934,15 @@ int __devinit snd_cs46xx_create(struct snd_card *card,
3896 3934
3897 snd_cs46xx_proc_init(card, chip); 3935 snd_cs46xx_proc_init(card, chip);
3898 3936
3937#ifdef CONFIG_PM
3938 chip->saved_regs = kmalloc(sizeof(*chip->saved_regs) *
3939 ARRAY_SIZE(saved_regs), GFP_KERNEL);
3940 if (!chip->saved_regs) {
3941 snd_cs46xx_free(chip);
3942 return -ENOMEM;
3943 }
3944#endif
3945
3899 chip->active_ctrl(chip, -1); /* disable CLKRUN */ 3946 chip->active_ctrl(chip, -1); /* disable CLKRUN */
3900 3947
3901 snd_card_set_dev(card, &pci->dev); 3948 snd_card_set_dev(card, &pci->dev);