tunnels: fix netns vs proto registration ordering
[safe/jmp/linux-2.6] / sound / pci / es1968.c
index 25ccfce..a11f453 100644 (file)
@@ -617,6 +617,18 @@ static int snd_es1968_ac97_wait(struct es1968 *chip)
        return 1; /* timeout */
 }
 
+static int snd_es1968_ac97_wait_poll(struct es1968 *chip)
+{
+       int timeout = 100000;
+
+       while (timeout-- > 0) {
+               if (!(inb(chip->io_port + ESM_AC97_INDEX) & 1))
+                       return 0;
+       }
+       snd_printd("es1968: ac97 timeout\n");
+       return 1; /* timeout */
+}
+
 static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
 {
        struct es1968 *chip = ac97->private_data;
@@ -645,7 +657,7 @@ static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short
        outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX);
        /*msleep(1);*/
 
-       if (! snd_es1968_ac97_wait(chip)) {
+       if (!snd_es1968_ac97_wait_poll(chip)) {
                data = inw(chip->io_port + ESM_AC97_DATA);
                /*msleep(1);*/
        }
@@ -680,7 +692,8 @@ static void apu_data_set(struct es1968 *chip, u16 data)
 /* no spinlock */
 static void __apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data)
 {
-       snd_assert(channel < NR_APUS, return);
+       if (snd_BUG_ON(channel >= NR_APUS))
+               return;
 #ifdef CONFIG_PM
        chip->apu_map[channel][reg] = data;
 #endif
@@ -699,7 +712,8 @@ static void apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data)
 
 static u16 __apu_get_register(struct es1968 *chip, u16 channel, u8 reg)
 {
-       snd_assert(channel < NR_APUS, return 0);
+       if (snd_BUG_ON(channel >= NR_APUS))
+               return 0;
        reg |= (channel << 4);
        apu_index_set(chip, reg);
        return __maestro_read(chip, IDR0_DATA_PORT);
@@ -1815,6 +1829,22 @@ snd_es1968_pcm(struct es1968 *chip, int device)
 
        return 0;
 }
+/*
+ * suppress jitter on some maestros when playing stereo
+ */
+static void snd_es1968_suppress_jitter(struct es1968 *chip, struct esschan *es)
+{
+       unsigned int cp1;
+       unsigned int cp2;
+       unsigned int diff;
+
+       cp1 = __apu_get_register(chip, 0, 5);
+       cp2 = __apu_get_register(chip, 1, 5);
+       diff = (cp1 > cp2 ? cp1 - cp2 : cp2 - cp1);
+
+       if (diff > 1)
+               __maestro_write(chip, IDR0_DATA_PORT, cp1);
+}
 
 /*
  * update pointer
@@ -1923,7 +1953,7 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
        outw(inw(chip->io_port + 4) & 1, chip->io_port + 4);
 
        if (event & ESM_HWVOL_IRQ)
-               tasklet_hi_schedule(&chip->hwvol_tq); /* we'll do this later */
+               tasklet_schedule(&chip->hwvol_tq); /* we'll do this later */
 
        /* else ack 'em all, i imagine */
        outb(0xFF, chip->io_port + 0x1A);
@@ -1936,8 +1966,11 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
                struct esschan *es;
                spin_lock(&chip->substream_lock);
                list_for_each_entry(es, &chip->substream_list, list) {
-                       if (es->running)
+                       if (es->running) {
                                snd_es1968_update_pcm(chip, es);
+                               if (es->fmt & ESS_FMT_STEREO)
+                                       snd_es1968_suppress_jitter(chip, es);
+                       }
                }
                spin_unlock(&chip->substream_lock);
                if (chip->in_measurement) {
@@ -1960,7 +1993,7 @@ snd_es1968_mixer(struct es1968 *chip)
 {
        struct snd_ac97_bus *pbus;
        struct snd_ac97_template ac97;
-       struct snd_ctl_elem_id id;
+       struct snd_ctl_elem_id elem_id;
        int err;
        static struct snd_ac97_bus_ops ops = {
                .write = snd_es1968_ac97_write,
@@ -1977,14 +2010,14 @@ snd_es1968_mixer(struct es1968 *chip)
                return err;
 
        /* attach master switch / volumes for h/w volume control */
-       memset(&id, 0, sizeof(id));
-       id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-       strcpy(id.name, "Master Playback Switch");
-       chip->master_switch = snd_ctl_find_id(chip->card, &id);
-       memset(&id, 0, sizeof(id));
-       id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-       strcpy(id.name, "Master Playback Volume");
-       chip->master_volume = snd_ctl_find_id(chip->card, &id);
+       memset(&elem_id, 0, sizeof(elem_id));
+       elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+       strcpy(elem_id.name, "Master Playback Switch");
+       chip->master_switch = snd_ctl_find_id(chip->card, &elem_id);
+       memset(&elem_id, 0, sizeof(elem_id));
+       elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+       strcpy(elem_id.name, "Master Playback Volume");
+       chip->master_volume = snd_ctl_find_id(chip->card, &elem_id);
 
        return 0;
 }
@@ -2444,7 +2477,8 @@ static inline void snd_es1968_free_gameport(struct es1968 *chip) { }
 static int snd_es1968_free(struct es1968 *chip)
 {
        if (chip->io_port) {
-               synchronize_irq(chip->irq);
+               if (chip->irq >= 0)
+                       synchronize_irq(chip->irq);
                outw(1, chip->io_port + 0x04); /* clear WP interrupts */
                outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */
        }
@@ -2505,8 +2539,8 @@ static int __devinit snd_es1968_create(struct snd_card *card,
        if ((err = pci_enable_device(pci)) < 0)
                return err;
        /* check, if we can restrict PCI DMA transfers to 28 bits */
-       if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
-           pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) {
+       if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
+           pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
                snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
                pci_disable_device(pci);
                return -ENXIO;
@@ -2611,9 +2645,9 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci,
                return -ENOENT;
        }
 
-       card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
-       if (!card)
-               return -ENOMEM;
+       err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+       if (err < 0)
+               return err;
                 
        if (total_bufsize[dev] < 128)
                total_bufsize[dev] = 128;