ALSA: hda - Enable snoop bit for AMD controllers
[linux-flexiantxendom0-natty.git] / sound / pci / hda / hda_intel.c
index cad9b70..5fd012b 100644 (file)
@@ -78,8 +78,8 @@ MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
 module_param_array(model, charp, NULL, 0444);
 MODULE_PARM_DESC(model, "Use the given board model.");
 module_param_array(position_fix, int, NULL, 0444);
-MODULE_PARM_DESC(position_fix, "Fix DMA pointer "
-                "(0 = auto, 1 = none, 2 = POSBUF).");
+MODULE_PARM_DESC(position_fix, "DMA pointer read method."
+                "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO).");
 module_param_array(bdl_pos_adj, int, NULL, 0644);
 MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
 module_param_array(probe_mask, int, NULL, 0444);
@@ -126,6 +126,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
                         "{Intel, ICH10},"
                         "{Intel, PCH},"
                         "{Intel, CPT},"
+                        "{Intel, PBG},"
                         "{Intel, SCH},"
                         "{ATI, SB450},"
                         "{ATI, SB600},"
@@ -174,7 +175,7 @@ MODULE_DESCRIPTION("Intel HDA driver");
 #define   ICH6_GSTS_FSTS       (1 << 1)   /* flush status */
 #define ICH6_REG_INTCTL                        0x20
 #define ICH6_REG_INTSTS                        0x24
-#define ICH6_REG_WALCLK                        0x30
+#define ICH6_REG_WALLCLK               0x30    /* 24Mhz source */
 #define ICH6_REG_SYNC                  0x34    
 #define ICH6_REG_CORBLBASE             0x40
 #define ICH6_REG_CORBUBASE             0x44
@@ -304,6 +305,7 @@ enum {
        POS_FIX_AUTO,
        POS_FIX_LPIB,
        POS_FIX_POSBUF,
+       POS_FIX_VIACOMBO,
 };
 
 /* Defines for ATI HD Audio support in SB450 south bridge */
@@ -340,8 +342,8 @@ struct azx_dev {
        unsigned int period_bytes; /* size of the period in bytes */
        unsigned int frags;     /* number for period in the play buffer */
        unsigned int fifo_size; /* FIFO size */
-       unsigned long start_jiffies;    /* start + minimum jiffies */
-       unsigned long min_jiffies;      /* minimum jiffies before position is valid */
+       unsigned long start_wallclk;    /* start + minimum wallclk */
+       unsigned long period_wallclk;   /* wallclk for period */
 
        void __iomem *sd_addr;  /* stream descriptor pointer */
 
@@ -361,7 +363,6 @@ struct azx_dev {
        unsigned int opened :1;
        unsigned int running :1;
        unsigned int irq_pending :1;
-       unsigned int start_flag: 1;     /* stream full start flag */
        /*
         * For VIA:
         *  A flag to ensure DMA position is 0
@@ -433,7 +434,6 @@ struct azx {
        unsigned int polling_mode :1;
        unsigned int msi :1;
        unsigned int irq_pending_warned :1;
-       unsigned int via_dmapos_patch :1; /* enable DMA-position fix for VIA */
        unsigned int probing :1; /* codec probing phase */
 
        /* for debugging */
@@ -458,6 +458,7 @@ enum {
        AZX_DRIVER_ULI,
        AZX_DRIVER_NVIDIA,
        AZX_DRIVER_TERA,
+       AZX_DRIVER_CTX,
        AZX_DRIVER_GENERIC,
        AZX_NUM_DRIVERS, /* keep this as last entry */
 };
@@ -473,6 +474,7 @@ static char *driver_short_names[] __devinitdata = {
        [AZX_DRIVER_ULI] = "HDA ULI M5461",
        [AZX_DRIVER_NVIDIA] = "HDA NVidia",
        [AZX_DRIVER_TERA] = "HDA Teradici", 
+       [AZX_DRIVER_CTX] = "HDA Creative", 
        [AZX_DRIVER_GENERIC] = "HD-Audio Generic",
 };
 
@@ -563,7 +565,10 @@ static void azx_init_cmd_io(struct azx *chip)
        /* reset the rirb hw write pointer */
        azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST);
        /* set N=1, get RIRB response interrupt for new entry */
-       azx_writew(chip, RINTCNT, 1);
+       if (chip->driver_type == AZX_DRIVER_CTX)
+               azx_writew(chip, RINTCNT, 0xc0);
+       else
+               azx_writew(chip, RINTCNT, 1);
        /* enable rirb dma and response irq */
        azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN);
        spin_unlock_irq(&chip->reg_lock);
@@ -1083,7 +1088,13 @@ static void azx_init_pci(struct azx *chip)
                                ? "Failed" : "OK");
                }
                break;
-
+       default:
+               /* AMD Hudson needs the similar snoop, as it seems... */
+               if (chip->pci->vendor == PCI_VENDOR_ID_AMD)
+                       update_pci_byte(chip->pci,
+                               ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR,
+                               0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP);
+               break;
         }
 }
 
@@ -1098,6 +1109,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
        struct azx *chip = dev_id;
        struct azx_dev *azx_dev;
        u32 status;
+       u8 sd_status;
        int i, ok;
 
        spin_lock(&chip->reg_lock);
@@ -1111,8 +1123,10 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
        for (i = 0; i < chip->num_streams; i++) {
                azx_dev = &chip->azx_dev[i];
                if (status & azx_dev->sd_int_sta_mask) {
+                       sd_status = azx_sd_readb(azx_dev, SD_STS);
                        azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK);
-                       if (!azx_dev->substream || !azx_dev->running)
+                       if (!azx_dev->substream || !azx_dev->running ||
+                           !(sd_status & SD_INT_COMPLETE))
                                continue;
                        /* check whether this IRQ is really acceptable */
                        ok = azx_position_ok(chip, azx_dev);
@@ -1133,8 +1147,11 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
        /* clear rirb int */
        status = azx_readb(chip, RIRBSTS);
        if (status & RIRB_INT_MASK) {
-               if (status & RIRB_INT_RESPONSE)
+               if (status & RIRB_INT_RESPONSE) {
+                       if (chip->driver_type == AZX_DRIVER_CTX)
+                               udelay(80);
                        azx_update_rirb(chip);
+               }
                azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
        }
 
@@ -1224,7 +1241,8 @@ static int azx_setup_periods(struct azx *chip,
                        pos_adj = 0;
                } else {
                        ofs = setup_bdle(substream, azx_dev,
-                                        &bdl, ofs, pos_adj, 1);
+                                        &bdl, ofs, pos_adj,
+                                        !substream->runtime->no_period_wakeup);
                        if (ofs < 0)
                                goto error;
                }
@@ -1236,7 +1254,8 @@ static int azx_setup_periods(struct azx *chip,
                                         period_bytes - pos_adj, 0);
                else
                        ofs = setup_bdle(substream, azx_dev, &bdl, ofs,
-                                        period_bytes, 1);
+                                        period_bytes,
+                                        !substream->runtime->no_period_wakeup);
                if (ofs < 0)
                        goto error;
        }
@@ -1306,11 +1325,8 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
        azx_sd_writel(azx_dev, SD_BDLPU, upper_32_bits(azx_dev->bdl.addr));
 
        /* enable the position buffer */
-       if (chip->position_fix[0] == POS_FIX_POSBUF ||
-           chip->position_fix[0] == POS_FIX_AUTO ||
-           chip->position_fix[1] == POS_FIX_POSBUF ||
-           chip->position_fix[1] == POS_FIX_AUTO ||
-           chip->via_dmapos_patch) {
+       if (chip->position_fix[0] != POS_FIX_LPIB ||
+           chip->position_fix[1] != POS_FIX_LPIB) {
                if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
                        azx_writel(chip, DPLBASE,
                                (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
@@ -1507,7 +1523,8 @@ static struct snd_pcm_hardware azx_pcm_hw = {
                                 /* No full-resume yet implemented */
                                 /* SNDRV_PCM_INFO_RESUME |*/
                                 SNDRV_PCM_INFO_PAUSE |
-                                SNDRV_PCM_INFO_SYNC_START),
+                                SNDRV_PCM_INFO_SYNC_START |
+                                SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
        .formats =              SNDRV_PCM_FMTBIT_S16_LE,
        .rates =                SNDRV_PCM_RATE_48000,
        .rate_min =             48000,
@@ -1632,7 +1649,7 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
        azx_dev->period_bytes = 0;
        azx_dev->format_val = 0;
 
-       hinfo->ops.cleanup(hinfo, apcm->codec, substream);
+       snd_hda_codec_cleanup(apcm->codec, hinfo, substream);
 
        return snd_pcm_lib_free_pages(substream);
 }
@@ -1644,14 +1661,15 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
        struct azx_dev *azx_dev = get_azx_dev(substream);
        struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
        struct snd_pcm_runtime *runtime = substream->runtime;
-       unsigned int bufsize, period_bytes, format_val;
+       unsigned int bufsize, period_bytes, format_val, stream_tag;
        int err;
 
        azx_stream_reset(chip, azx_dev);
        format_val = snd_hda_calc_stream_format(runtime->rate,
                                                runtime->channels,
                                                runtime->format,
-                                               hinfo->maxbps);
+                                               hinfo->maxbps,
+                                               apcm->codec->spdif_ctls);
        if (!format_val) {
                snd_printk(KERN_ERR SFX
                           "invalid format_val, rate=%d, ch=%d, format=%d\n",
@@ -1676,16 +1694,22 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
                        return err;
        }
 
-       azx_dev->min_jiffies = (runtime->period_size * HZ) /
-                                               (runtime->rate * 2);
+       /* wallclk has 24Mhz clock source */
+       azx_dev->period_wallclk = (((runtime->period_size * 24000) /
+                                               runtime->rate) * 1000);
        azx_setup_controller(chip, azx_dev);
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1;
        else
                azx_dev->fifo_size = 0;
 
-       return hinfo->ops.prepare(hinfo, apcm->codec, azx_dev->stream_tag,
-                                 azx_dev->format_val, substream);
+       stream_tag = azx_dev->stream_tag;
+       /* CA-IBG chips need the playback stream starting from 1 */
+       if (chip->driver_type == AZX_DRIVER_CTX &&
+           stream_tag > chip->capture_streams)
+               stream_tag -= chip->capture_streams;
+       return snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag,
+                                    azx_dev->format_val, substream);
 }
 
 static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
@@ -1731,14 +1755,15 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
                if (s->pcm->card != substream->pcm->card)
                        continue;
                azx_dev = get_azx_dev(s);
-               if (rstart) {
-                       azx_dev->start_flag = 1;
-                       azx_dev->start_jiffies = jiffies + azx_dev->min_jiffies;
-               }
-               if (start)
+               if (start) {
+                       azx_dev->start_wallclk = azx_readl(chip, WALLCLK);
+                       if (!rstart)
+                               azx_dev->start_wallclk -=
+                                               azx_dev->period_wallclk;
                        azx_stream_start(chip, azx_dev);
-               else
+               } else {
                        azx_stream_stop(chip, azx_dev);
+               }
                azx_dev->running = start;
        }
        spin_unlock(&chip->reg_lock);
@@ -1846,20 +1871,21 @@ static unsigned int azx_get_position(struct azx *chip,
                                     struct azx_dev *azx_dev)
 {
        unsigned int pos;
+       int stream = azx_dev->substream->stream;
 
-       if (chip->via_dmapos_patch)
+       switch (chip->position_fix[stream]) {
+       case POS_FIX_LPIB:
+               /* read LPIB */
+               pos = azx_sd_readl(azx_dev, SD_LPIB);
+               break;
+       case POS_FIX_VIACOMBO:
                pos = azx_via_get_position(chip, azx_dev);
-       else {
-               int stream = azx_dev->substream->stream;
-               if (chip->position_fix[stream] == POS_FIX_POSBUF ||
-                   chip->position_fix[stream] == POS_FIX_AUTO) {
-                       /* use the position buffer */
-                       pos = le32_to_cpu(*azx_dev->posbuf);
-               } else {
-                       /* read LPIB */
-                       pos = azx_sd_readl(azx_dev, SD_LPIB);
-               }
+               break;
+       default:
+               /* use the position buffer */
+               pos = le32_to_cpu(*azx_dev->posbuf);
        }
+
        if (pos >= azx_dev->bufsize)
                pos = 0;
        return pos;
@@ -1885,13 +1911,13 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
  */
 static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
 {
+       u32 wallclk;
        unsigned int pos;
        int stream;
 
-       if (azx_dev->start_flag &&
-           time_before_eq(jiffies, azx_dev->start_jiffies))
+       wallclk = azx_readl(chip, WALLCLK) - azx_dev->start_wallclk;
+       if (wallclk < (azx_dev->period_wallclk * 2) / 3)
                return -1;      /* bogus (too early) interrupt */
-       azx_dev->start_flag = 0;
 
        stream = azx_dev->substream->stream;
        pos = azx_get_position(chip, azx_dev);
@@ -1906,13 +1932,14 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
                        chip->position_fix[stream] = POS_FIX_POSBUF;
        }
 
-       if (!bdl_pos_adj[chip->dev_index])
-               return 1; /* no delayed ack */
        if (WARN_ONCE(!azx_dev->period_bytes,
                      "hda-intel: zero azx_dev->period_bytes"))
-               return 0; /* this shouldn't happen! */
-       if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2)
-               return 0; /* NG - it's below the period boundary */
+               return -1; /* this shouldn't happen! */
+       if (wallclk < (azx_dev->period_wallclk * 5) / 4 &&
+           pos % azx_dev->period_bytes > azx_dev->period_bytes / 2)
+               /* NG - it's below the first next period boundary */
+               return bdl_pos_adj[chip->dev_index] ? 0 : -1;
+       azx_dev->start_wallclk += wallclk;
        return 1; /* OK, it's fine */
 }
 
@@ -1922,7 +1949,7 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
 static void azx_irq_pending_work(struct work_struct *work)
 {
        struct azx *chip = container_of(work, struct azx, irq_pending_work);
-       int i, pending;
+       int i, pending, ok;
 
        if (!chip->irq_pending_warned) {
                printk(KERN_WARNING
@@ -1941,18 +1968,21 @@ static void azx_irq_pending_work(struct work_struct *work)
                            !azx_dev->substream ||
                            !azx_dev->running)
                                continue;
-                       if (azx_position_ok(chip, azx_dev)) {
+                       ok = azx_position_ok(chip, azx_dev);
+                       if (ok > 0) {
                                azx_dev->irq_pending = 0;
                                spin_unlock(&chip->reg_lock);
                                snd_pcm_period_elapsed(azx_dev->substream);
                                spin_lock(&chip->reg_lock);
+                       } else if (ok < 0) {
+                               pending = 0;    /* too early */
                        } else
                                pending++;
                }
                spin_unlock_irq(&chip->reg_lock);
                if (!pending)
                        return;
-               cond_resched();
+               msleep(1);
        }
 }
 
@@ -1997,6 +2027,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
        struct azx_pcm *apcm;
        int pcm_dev = cpcm->device;
        int s, err;
+       size_t prealloc_min = 64*1024;  /* 64KB */
 
        if (pcm_dev >= HDA_MAX_PCMS) {
                snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n",
@@ -2030,10 +2061,21 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
                if (cpcm->stream[s].substreams)
                        snd_pcm_set_ops(pcm, s, &azx_pcm_ops);
        }
+
        /* buffer pre-allocation */
+
+       /* subtle, don't allocate a big buffer for modems...
+        * also, don't just test 32BIT_MASK, since azx supports
+        * 64-bit DMA in some cases.
+        */
+       /* lennart wants a 2.2MB buffer for 2sec of 48khz */
+       if (pcm->dev_class == SNDRV_PCM_CLASS_GENERIC &&
+           chip->pci->dma_mask >= DMA_32BIT_MASK)
+               prealloc_min = 4 * 1024 * 1024; /* 4MB */
+
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
                                              snd_dma_pci_data(chip->pci),
-                                             1024 * 64, 32 * 1024 * 1024);
+                                             prealloc_min, 32 * 1024 * 1024);
        return 0;
 }
 
@@ -2274,16 +2316,26 @@ static int azx_dev_free(struct snd_device *device)
  * white/black-listing for position_fix
  */
 static struct snd_pci_quirk position_fix_list[] __devinitdata = {
+       SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1025, 0x026f, "Acer Aspire 5538", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1028, 0x0470, "Dell Inspiron 1120", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
-       SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1043, 0x8410, "ASUS", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1849, 0x0888, "775Dual-VSTA", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB),
        {}
@@ -2296,19 +2348,10 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
        switch (fix) {
        case POS_FIX_LPIB:
        case POS_FIX_POSBUF:
+       case POS_FIX_VIACOMBO:
                return fix;
        }
 
-       /* Check VIA/ATI HD Audio Controller exist */
-       switch (chip->driver_type) {
-       case AZX_DRIVER_VIA:
-       case AZX_DRIVER_ATI:
-               chip->via_dmapos_patch = 1;
-               /* Use link position directly, avoid any transfer problem. */
-               return POS_FIX_LPIB;
-       }
-       chip->via_dmapos_patch = 0;
-
        q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
        if (q) {
                printk(KERN_INFO
@@ -2317,6 +2360,22 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
                       q->value, q->subvendor, q->subdevice);
                return q->value;
        }
+
+       /* Check VIA/ATI HD Audio Controller exist */
+       switch (chip->driver_type) {
+       case AZX_DRIVER_VIA:
+               /* Use link position directly, avoid any transfer problem. */
+               return POS_FIX_VIACOMBO;
+       case AZX_DRIVER_ATI:
+               /* ATI chipsets don't work well with position-buffer */
+               return POS_FIX_LPIB;
+       case AZX_DRIVER_GENERIC:
+               /* AMD chipsets also don't work with position-buffer */
+               if (chip->pci->vendor == PCI_VENDOR_ID_AMD)
+                       return POS_FIX_LPIB;
+               break;
+       }
+
        return POS_FIX_AUTO;
 }
 
@@ -2512,6 +2571,13 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
                                gcap &= ~ICH6_GCAP_64OK;
                        pci_dev_put(p_smbus);
                }
+       } else {
+               /* FIXME: not sure whether this is really needed, but
+                * Hudson isn't stable enough for allowing everything...
+                * let's check later again.
+                */
+               if (chip->pci->vendor == PCI_VENDOR_ID_AMD)
+                       gcap &= ~ICH6_GCAP_64OK;
        }
 
        /* disable 64bit DMA address for Teradici */
@@ -2670,7 +2736,7 @@ static int __devinit azx_probe(struct pci_dev *pci,
        if (err < 0)
                goto out_free;
 #ifdef CONFIG_SND_HDA_PATCH_LOADER
-       if (patch[dev]) {
+       if (patch[dev] && *patch[dev]) {
                snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n",
                           patch[dev]);
                err = snd_hda_load_patch(chip->bus, patch[dev]);
@@ -2718,23 +2784,17 @@ static void __devexit azx_remove(struct pci_dev *pci)
 
 /* PCI IDs */
 static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
-       /* ICH 6..10 */
-       { PCI_DEVICE(0x8086, 0x2668), .driver_data = AZX_DRIVER_ICH },
-       { PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH },
-       { PCI_DEVICE(0x8086, 0x269a), .driver_data = AZX_DRIVER_ICH },
-       { PCI_DEVICE(0x8086, 0x284b), .driver_data = AZX_DRIVER_ICH },
-       { PCI_DEVICE(0x8086, 0x2911), .driver_data = AZX_DRIVER_ICH },
-       { PCI_DEVICE(0x8086, 0x293e), .driver_data = AZX_DRIVER_ICH },
-       { PCI_DEVICE(0x8086, 0x293f), .driver_data = AZX_DRIVER_ICH },
-       { PCI_DEVICE(0x8086, 0x3a3e), .driver_data = AZX_DRIVER_ICH },
-       { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH },
-       /* PCH */
-       { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH },
-       { PCI_DEVICE(0x8086, 0x3b57), .driver_data = AZX_DRIVER_ICH },
        /* CPT */
        { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH },
+       /* PBG */
+       { PCI_DEVICE(0x8086, 0x1d20), .driver_data = AZX_DRIVER_PCH },
        /* SCH */
        { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH },
+       /* Generic Intel */
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
+         .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
+         .class_mask = 0xffffff,
+         .driver_data = AZX_DRIVER_ICH },
        /* ATI SB 450/600 */
        { PCI_DEVICE(0x1002, 0x437b), .driver_data = AZX_DRIVER_ATI },
        { PCI_DEVICE(0x1002, 0x4383), .driver_data = AZX_DRIVER_ATI },
@@ -2775,11 +2835,15 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
        { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID),
          .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
          .class_mask = 0xffffff,
-         .driver_data = AZX_DRIVER_GENERIC },
+         .driver_data = AZX_DRIVER_CTX },
 #else
        /* this entry seems still valid -- i.e. without emu20kx chip */
-       { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_GENERIC },
+       { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_CTX },
 #endif
+       /* Vortex86MX */
+       { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
+       /* VMware HDAudio */
+       { PCI_DEVICE(0x15ad, 0x1977), .driver_data = AZX_DRIVER_GENERIC },
        /* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */
        { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
          .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,