]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - sound/pci/oxygen/oxygen_lib.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm
[linux-2.6-omap-h63xx.git] / sound / pci / oxygen / oxygen_lib.c
index d98867c1f2d4ab76d2f2bbe18fea4ac6e192d793..6eb36dd11476f7c9e5b8715dfba93273faa3b650 100644 (file)
@@ -53,7 +53,8 @@ static irqreturn_t oxygen_interrupt(int dummy, void *dev_id)
                          OXYGEN_CHANNEL_MULTICH |
                          OXYGEN_CHANNEL_AC97 |
                          OXYGEN_INT_SPDIF_IN_DETECT |
-                         OXYGEN_INT_GPIO);
+                         OXYGEN_INT_GPIO |
+                         OXYGEN_INT_AC97);
        if (clear) {
                if (clear & OXYGEN_INT_SPDIF_IN_DETECT)
                        chip->interrupt_mask &= ~OXYGEN_INT_SPDIF_IN_DETECT;
@@ -84,11 +85,14 @@ static irqreturn_t oxygen_interrupt(int dummy, void *dev_id)
        }
 
        if (status & OXYGEN_INT_GPIO)
-               ;
+               schedule_work(&chip->gpio_work);
 
        if ((status & OXYGEN_INT_MIDI) && chip->midi)
                snd_mpu401_uart_interrupt(0, chip->midi->private_data);
 
+       if (status & OXYGEN_INT_AC97)
+               wake_up(&chip->ac97_waitqueue);
+
        return IRQ_HANDLED;
 }
 
@@ -153,6 +157,14 @@ static void oxygen_spdif_input_bits_changed(struct work_struct *work)
        }
 }
 
+static void oxygen_gpio_changed(struct work_struct *work)
+{
+       struct oxygen *chip = container_of(work, struct oxygen, gpio_work);
+
+       if (chip->model->gpio_changed)
+               chip->model->gpio_changed(chip);
+}
+
 #ifdef CONFIG_PROC_FS
 static void oxygen_proc_read(struct snd_info_entry *entry,
                             struct snd_info_buffer *buffer)
@@ -306,7 +318,9 @@ static void __devinit oxygen_init(struct oxygen *chip)
                      (2 << OXYGEN_A_MONITOR_ROUTE_2_SHIFT) |
                      (3 << OXYGEN_A_MONITOR_ROUTE_3_SHIFT));
 
-       oxygen_write8(chip, OXYGEN_AC97_INTERRUPT_MASK, 0);
+       oxygen_write8(chip, OXYGEN_AC97_INTERRUPT_MASK,
+                     OXYGEN_AC97_INT_READ_DONE |
+                     OXYGEN_AC97_INT_WRITE_DONE);
        oxygen_write32(chip, OXYGEN_AC97_OUT_CONFIG, 0);
        oxygen_write32(chip, OXYGEN_AC97_IN_CONFIG, 0);
        if (!(chip->has_ac97_0 | chip->has_ac97_1))
@@ -359,8 +373,7 @@ static void __devinit oxygen_init(struct oxygen *chip)
                oxygen_write_ac97(chip, 1, AC97_AUX, 0x8808);
                oxygen_write_ac97(chip, 1, AC97_PCM, 0x0808);
                oxygen_write_ac97(chip, 1, AC97_REC_SEL, 0x0000);
-               oxygen_write_ac97(chip, 1, AC97_REC_GAIN, 0x8000);
-               oxygen_ac97_clear_bits(chip, 1, AC97_REC_GAIN, 0x1c00);
+               oxygen_write_ac97(chip, 1, AC97_REC_GAIN, 0x0000);
                oxygen_ac97_set_bits(chip, 1, 0x6a, 0x0040);
        }
 }
@@ -408,6 +421,8 @@ int __devinit oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
        mutex_init(&chip->mutex);
        INIT_WORK(&chip->spdif_input_bits_work,
                  oxygen_spdif_input_bits_changed);
+       INIT_WORK(&chip->gpio_work, oxygen_gpio_changed);
+       init_waitqueue_head(&chip->ac97_waitqueue);
 
        err = pci_enable_device(pci);
        if (err < 0)
@@ -471,7 +486,7 @@ int __devinit oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
        oxygen_proc_init(chip);
 
        spin_lock_irq(&chip->reg_lock);
-       chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_DETECT;
+       chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_DETECT | OXYGEN_INT_AC97;
        oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
        spin_unlock_irq(&chip->reg_lock);