fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / sound / pci / cs4281.c
index 9631456..8e5519d 100644 (file)
@@ -33,6 +33,7 @@
 #include <sound/pcm.h>
 #include <sound/rawmidi.h>
 #include <sound/ac97_codec.h>
+#include <sound/tlv.h>
 #include <sound/opl3.h>
 #include <sound/initval.h>
 
@@ -492,7 +493,7 @@ struct cs4281 {
 
 };
 
-static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id);
 
 static struct pci_device_id snd_cs4281_ids[] = {
        { 0x1013, 0x6005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },   /* CS4281 */
@@ -1054,6 +1055,8 @@ static int snd_cs4281_put_volume(struct snd_kcontrol *kcontrol,
        return change;
 }
 
+static DECLARE_TLV_DB_SCALE(db_scale_dsp, -4650, 150, 0);
+
 static struct snd_kcontrol_new snd_cs4281_fm_vol = 
 {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1062,6 +1065,7 @@ static struct snd_kcontrol_new snd_cs4281_fm_vol =
        .get = snd_cs4281_get_volume,
        .put = snd_cs4281_put_volume, 
        .private_value = ((BA0_FMLVC << 16) | BA0_FMRVC),
+       .tlv = { .p = db_scale_dsp },
 };
 
 static struct snd_kcontrol_new snd_cs4281_pcm_vol = 
@@ -1072,6 +1076,7 @@ static struct snd_kcontrol_new snd_cs4281_pcm_vol =
        .get = snd_cs4281_get_volume,
        .put = snd_cs4281_put_volume, 
        .private_value = ((BA0_PPLVC << 16) | BA0_PPRVC),
+       .tlv = { .p = db_scale_dsp },
 };
 
 static void snd_cs4281_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
@@ -1386,7 +1391,7 @@ static int __devinit snd_cs4281_create(struct snd_card *card,
                return -ENOMEM;
        }
        
-       if (request_irq(pci->irq, snd_cs4281_interrupt, IRQF_DISABLED|IRQF_SHARED,
+       if (request_irq(pci->irq, snd_cs4281_interrupt, IRQF_SHARED,
                        "CS4281", chip)) {
                snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
                snd_cs4281_free(chip);
@@ -1809,7 +1814,7 @@ static int __devinit snd_cs4281_midi(struct cs4281 * chip, int device,
  *  Interrupt handler
  */
 
-static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id)
 {
        struct cs4281 *chip = dev_id;
        unsigned int status, dma, val;
@@ -2045,6 +2050,7 @@ static int cs4281_suspend(struct pci_dev *pci, pm_message_t state)
 
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -2055,8 +2061,14 @@ static int cs4281_resume(struct pci_dev *pci)
        unsigned int i;
        u32 ulCLK;
 
+       pci_set_power_state(pci, PCI_D0);
        pci_restore_state(pci);
-       pci_enable_device(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "cs4281: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
 
        ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);