[ALSA] Clean up with common snd_ctl_boolean_*_info callbacks
[deliverable/linux.git] / sound / pci / cs46xx / cs46xx_lib.c
index 2807b9756ef09d96e2f48646084d201aa7daefd0..0dc69d071406c209700a9deed64abce0db573beb 100644 (file)
@@ -1818,15 +1818,7 @@ static int snd_cs46xx_vol_iec958_put(struct snd_kcontrol *kcontrol, struct snd_c
 }
 #endif
 
-static int snd_mixer_boolean_info(struct snd_kcontrol *kcontrol, 
-                                 struct snd_ctl_elem_info *uinfo)
-{
-       uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-       uinfo->count = 1;
-       uinfo->value.integer.min = 0;
-       uinfo->value.integer.max = 1;
-       return 0;
-}
+#define snd_mixer_boolean_info         snd_ctl_boolean_mono_info
 
 static int snd_cs46xx_iec958_get(struct snd_kcontrol *kcontrol, 
                                  struct snd_ctl_elem_value *ucontrol)
@@ -2897,6 +2889,10 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip)
        }
 #endif
        
+#ifdef CONFIG_PM
+       kfree(chip->saved_regs);
+#endif
+
        pci_disable_device(chip->pci);
        kfree(chip);
        return 0;
@@ -3107,7 +3103,7 @@ static int snd_cs46xx_chip_init(struct snd_cs46xx *chip)
        snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n");
        snd_printk(KERN_ERR "       Try reloading the ALSA driver, if you find something\n");
         snd_printk(KERN_ERR "       broken or not working on your soundcard upon\n");
-       snd_printk(KERN_ERR "       this message please report to alsa-devel@lists.sourceforge.net\n");
+       snd_printk(KERN_ERR "       this message please report to alsa-devel@alsa-project.org\n");
 
        return -EIO;
 #endif
@@ -3140,6 +3136,23 @@ static int snd_cs46xx_chip_init(struct snd_cs46xx *chip)
 /*
  *  start and load DSP 
  */
+
+static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip)
+{
+       unsigned int tmp;
+
+       snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM);
+        
+       tmp = snd_cs46xx_peek(chip, BA1_PFIE);
+       tmp &= ~0x0000f03f;
+       snd_cs46xx_poke(chip, BA1_PFIE, tmp);   /* playback interrupt enable */
+
+       tmp = snd_cs46xx_peek(chip, BA1_CIE);
+       tmp &= ~0x0000003f;
+       tmp |=  0x00000001;
+       snd_cs46xx_poke(chip, BA1_CIE, tmp);    /* capture interrupt enable */
+}
+
 int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
 {      
        unsigned int tmp;
@@ -3214,19 +3227,7 @@ int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
 
        snd_cs46xx_proc_start(chip);
 
-       /*
-        *  Enable interrupts on the part.
-        */
-       snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM);
-        
-       tmp = snd_cs46xx_peek(chip, BA1_PFIE);
-       tmp &= ~0x0000f03f;
-       snd_cs46xx_poke(chip, BA1_PFIE, tmp);   /* playback interrupt enable */
-
-       tmp = snd_cs46xx_peek(chip, BA1_CIE);
-       tmp &= ~0x0000003f;
-       tmp |=  0x00000001;
-       snd_cs46xx_poke(chip, BA1_CIE, tmp);    /* capture interrupt enable */
+       cs46xx_enable_stream_irqs(chip);
        
 #ifndef CONFIG_SND_CS46XX_NEW_DSP
        /* set the attenuation to 0dB */ 
@@ -3665,11 +3666,19 @@ static struct cs_card_type __devinitdata cards[] = {
  * APM support
  */
 #ifdef CONFIG_PM
+static unsigned int saved_regs[] = {
+       BA0_ACOSV,
+       BA0_ASER_FADDR,
+       BA0_ASER_MASTER,
+       BA1_PVOL,
+       BA1_CVOL,
+};
+
 int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state)
 {
        struct snd_card *card = pci_get_drvdata(pci);
        struct snd_cs46xx *chip = card->private_data;
-       int amp_saved;
+       int i, amp_saved;
 
        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
        chip->in_suspend = 1;
@@ -3680,6 +3689,10 @@ int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state)
        snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
        snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
 
+       /* save some registers */
+       for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
+               chip->saved_regs[i] = snd_cs46xx_peekBA0(chip, saved_regs[i]);
+
        amp_saved = chip->amplifier;
        /* turn off amp */
        chip->amplifier_ctrl(chip, -chip->amplifier);
@@ -3698,7 +3711,7 @@ int snd_cs46xx_resume(struct pci_dev *pci)
 {
        struct snd_card *card = pci_get_drvdata(pci);
        struct snd_cs46xx *chip = card->private_data;
-       int amp_saved;
+       int i, amp_saved;
 
        pci_set_power_state(pci, PCI_D0);
        pci_restore_state(pci);
@@ -3716,6 +3729,16 @@ int snd_cs46xx_resume(struct pci_dev *pci)
 
        snd_cs46xx_chip_init(chip);
 
+       snd_cs46xx_reset(chip);
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
+       cs46xx_dsp_resume(chip);
+       /* restore some registers */
+       for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
+               snd_cs46xx_pokeBA0(chip, saved_regs[i], chip->saved_regs[i]);
+#else
+       snd_cs46xx_download_image(chip);
+#endif
+
 #if 0
        snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, 
                               chip->ac97_general_purpose);
@@ -3730,6 +3753,13 @@ int snd_cs46xx_resume(struct pci_dev *pci)
        snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
        snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
 
+       /* reset playback/capture */
+       snd_cs46xx_set_play_sample_rate(chip, 8000);
+       snd_cs46xx_set_capture_sample_rate(chip, 8000);
+       snd_cs46xx_proc_start(chip);
+
+       cs46xx_enable_stream_irqs(chip);
+
        if (amp_saved)
                chip->amplifier_ctrl(chip, 1); /* turn amp on */
        else
@@ -3867,7 +3897,7 @@ int __devinit snd_cs46xx_create(struct snd_card *card,
                }
        }
 
-       if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_DISABLED|IRQF_SHARED,
+       if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED,
                        "CS46XX", chip)) {
                snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
                snd_cs46xx_free(chip);
@@ -3896,6 +3926,15 @@ int __devinit snd_cs46xx_create(struct snd_card *card,
        
        snd_cs46xx_proc_init(card, chip);
 
+#ifdef CONFIG_PM
+       chip->saved_regs = kmalloc(sizeof(*chip->saved_regs) *
+                                  ARRAY_SIZE(saved_regs), GFP_KERNEL);
+       if (!chip->saved_regs) {
+               snd_cs46xx_free(chip);
+               return -ENOMEM;
+       }
+#endif
+
        chip->active_ctrl(chip, -1); /* disable CLKRUN */
 
        snd_card_set_dev(card, &pci->dev);
This page took 0.027348 seconds and 5 git commands to generate.