[ALSA] HDA-Intel - Add support for Intel SCH
[powerpc.git] / sound / pci / hda / hda_intel.c
index f9c7c2e..56f8a30 100644 (file)
@@ -34,7 +34,6 @@
  * 
  */
 
-#include <sound/driver.h>
 #include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include "hda_codec.h"
 
 
-static int index = SNDRV_DEFAULT_IDX1;
-static char *id = SNDRV_DEFAULT_STR1;
-static char *model;
-static int position_fix;
-static int probe_mask = -1;
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+static char *model[SNDRV_CARDS];
+static int position_fix[SNDRV_CARDS];
+static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
 static int single_cmd;
 static int enable_msi;
 
-module_param(index, int, 0444);
+module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
-module_param(id, charp, 0444);
+module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for Intel HD audio interface.");
-module_param(model, charp, 0444);
+module_param_array(enable, bool, NULL, 0444);
+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(position_fix, int, 0444);
+module_param_array(position_fix, int, NULL, 0444);
 MODULE_PARM_DESC(position_fix, "Fix DMA pointer "
                 "(0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size).");
-module_param(probe_mask, int, 0444);
+module_param_array(probe_mask, int, NULL, 0444);
 MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
 module_param(single_cmd, bool, 0444);
 MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
                 "(for debugging only).");
-module_param(enable_msi, int, 0);
+module_param(enable_msi, int, 0444);
 MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
 
+#ifdef CONFIG_SND_HDA_POWER_SAVE
 /* power_save option is defined in hda_codec.c */
 
-/* just for backward compatibility */
-static int enable;
-module_param(enable, bool, 0444);
+/* reset the HD-audio controller in power save mode.
+ * this may give more power-saving, but will take longer time to
+ * wake up.
+ */
+static int power_save_controller = 1;
+module_param(power_save_controller, bool, 0644);
+MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
+#endif
 
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
@@ -88,12 +96,20 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
                         "{Intel, ESB2},"
                         "{Intel, ICH8},"
                         "{Intel, ICH9},"
+                        "{Intel, ICH10},"
+                        "{Intel, SCH},"
                         "{ATI, SB450},"
                         "{ATI, SB600},"
                         "{ATI, RS600},"
                         "{ATI, RS690},"
                         "{ATI, RS780},"
                         "{ATI, R600},"
+                        "{ATI, RV630},"
+                        "{ATI, RV610},"
+                        "{ATI, RV670},"
+                        "{ATI, RV635},"
+                        "{ATI, RV620},"
+                        "{ATI, RV770},"
                         "{VIA, VT8251},"
                         "{VIA, VT8237A},"
                         "{SiS, SIS966},"
@@ -102,17 +118,6 @@ MODULE_DESCRIPTION("Intel HDA driver");
 
 #define SFX    "hda-intel: "
 
-/*
- * build flags
- */
-
-/*
- * reset the HD-audio controller in power save mode.
- * this may give more power-saving, but will take longer time to
- * wake up.
- */
-#define HDA_POWER_SAVE_RESET_CONTROLLER
-
 
 /*
  * registers
@@ -371,6 +376,7 @@ struct azx {
 /* driver types */
 enum {
        AZX_DRIVER_ICH,
+       AZX_DRIVER_SCH,
        AZX_DRIVER_ATI,
        AZX_DRIVER_ATIHDMI,
        AZX_DRIVER_VIA,
@@ -381,6 +387,7 @@ enum {
 
 static char *driver_short_names[] __devinitdata = {
        [AZX_DRIVER_ICH] = "HDA Intel",
+       [AZX_DRIVER_SCH] = "HDA Intel MID",
        [AZX_DRIVER_ATI] = "HDA ATI SB",
        [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
        [AZX_DRIVER_VIA] = "HDA VIA VT82xx",
@@ -548,7 +555,7 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
 
  again:
        timeout = jiffies + msecs_to_jiffies(1000);
-       do {
+       for (;;) {
                if (chip->polling_mode) {
                        spin_lock_irq(&chip->reg_lock);
                        azx_update_rirb(chip);
@@ -556,8 +563,15 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
                }
                if (!chip->rirb.cmds)
                        return chip->rirb.res; /* the last value */
-               schedule_timeout(1);
-       } while (time_after_eq(timeout, jiffies));
+               if (time_after(jiffies, timeout))
+                       break;
+               if (codec->bus->needs_damn_long_delay)
+                       msleep(2); /* temporary workaround */
+               else {
+                       udelay(10);
+                       cond_resched();
+               }
+       }
 
        if (chip->msi) {
                snd_printk(KERN_WARNING "hda_intel: No response from codec, "
@@ -619,8 +633,9 @@ static int azx_single_send_cmd(struct hda_codec *codec, u32 val)
                }
                udelay(1);
        }
-       snd_printd(SFX "send_cmd timeout: IRS=0x%x, val=0x%x\n",
-                  azx_readw(chip, IRS), val);
+       if (printk_ratelimit())
+               snd_printd(SFX "send_cmd timeout: IRS=0x%x, val=0x%x\n",
+                          azx_readw(chip, IRS), val);
        return -EIO;
 }
 
@@ -636,8 +651,9 @@ static unsigned int azx_single_get_response(struct hda_codec *codec)
                        return azx_readl(chip, IR);
                udelay(1);
        }
-       snd_printd(SFX "get_response timeout: IRS=0x%x\n",
-                  azx_readw(chip, IRS));
+       if (printk_ratelimit())
+               snd_printd(SFX "get_response timeout: IRS=0x%x\n",
+                          azx_readw(chip, IRS));
        return (unsigned int)-1;
 }
 
@@ -688,6 +704,9 @@ static int azx_reset(struct azx *chip)
 {
        int count;
 
+       /* clear STATESTS */
+       azx_writeb(chip, STATESTS, STATESTS_INT_MASK);
+
        /* reset controller */
        azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_RESET);
 
@@ -1029,7 +1048,8 @@ static unsigned int azx_max_codecs[] __devinitdata = {
        [AZX_DRIVER_NVIDIA] = 3,        /* FIXME: correct? */
 };
 
-static int __devinit azx_codec_create(struct azx *chip, const char *model)
+static int __devinit azx_codec_create(struct azx *chip, const char *model,
+                                     unsigned int codec_probe_mask)
 {
        struct hda_bus_template bus_temp;
        int c, codecs, audio_codecs, err;
@@ -1050,7 +1070,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
 
        codecs = audio_codecs = 0;
        for (c = 0; c < AZX_MAX_CODECS; c++) {
-               if ((chip->codec_mask & (1 << c)) & probe_mask) {
+               if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
                        struct hda_codec *codec;
                        err = snd_hda_codec_new(chip->bus, c, &codec);
                        if (err < 0)
@@ -1063,7 +1083,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
        if (!audio_codecs) {
                /* probe additional slots if no codec is found */
                for (; c < azx_max_codecs[chip->driver_type]; c++) {
-                       if ((chip->codec_mask & (1 << c)) & probe_mask) {
+                       if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
                                err = snd_hda_codec_new(chip->bus, c, NULL);
                                if (err < 0)
                                        continue;
@@ -1391,7 +1411,6 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec,
 
 static int __devinit azx_pcm_create(struct azx *chip)
 {
-       struct list_head *p;
        struct hda_codec *codec;
        int c, err;
        int pcm_dev;
@@ -1402,8 +1421,7 @@ static int __devinit azx_pcm_create(struct azx *chip)
 
        /* create audio PCMs */
        pcm_dev = 0;
-       list_for_each(p, &chip->bus->codec_list) {
-               codec = list_entry(p, struct hda_codec, list);
+       list_for_each_entry(codec, &chip->bus->codec_list, list) {
                for (c = 0; c < codec->num_pcms; c++) {
                        if (codec->pcm_info[c].is_modem)
                                continue; /* create later */
@@ -1422,8 +1440,7 @@ static int __devinit azx_pcm_create(struct azx *chip)
 
        /* create modem PCMs */
        pcm_dev = AZX_MAX_AUDIO_PCMS;
-       list_for_each(p, &chip->bus->codec_list) {
-               codec = list_entry(p, struct hda_codec, list);
+       list_for_each_entry(codec, &chip->bus->codec_list, list) {
                for (c = 0; c < codec->num_pcms; c++) {
                        if (!codec->pcm_info[c].is_modem)
                                continue; /* already created */
@@ -1533,10 +1550,8 @@ static void azx_power_notify(struct hda_codec *codec)
        }
        if (power_on)
                azx_init_chip(chip);
-#ifdef HDA_POWER_SAVE_RESET_CONTROLLER
-       else if (chip->running)
+       else if (chip->running && power_save_controller)
                azx_stop_chip(chip);
-#endif
 }
 #endif /* CONFIG_SND_HDA_POWER_SAVE */
 
@@ -1553,7 +1568,8 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
        for (i = 0; i < chip->pcm_devs; i++)
                snd_pcm_suspend_all(chip->pcm[i]);
-       snd_hda_suspend(chip->bus, state);
+       if (chip->initialized)
+               snd_hda_suspend(chip->bus, state);
        azx_stop_chip(chip);
        if (chip->irq >= 0) {
                synchronize_irq(chip->irq);
@@ -1588,11 +1604,11 @@ static int azx_resume(struct pci_dev *pci)
        if (azx_acquire_irq(chip, 1) < 0)
                return -EIO;
        azx_init_pci(chip);
-#ifndef CONFIG_SND_HDA_POWER_SAVE
-       /* the explicit resume is needed only when POWER_SAVE isn't set */
-       azx_init_chip(chip);
+
+       if (snd_hda_codecs_inuse(chip->bus))
+               azx_init_chip(chip);
+
        snd_hda_resume(chip->bus);
-#endif
        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
        return 0;
 }
@@ -1644,6 +1660,7 @@ static int azx_dev_free(struct snd_device *device)
  */
 static struct snd_pci_quirk position_fix_list[] __devinitdata = {
        SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE),
+       SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_NONE),
        {}
 };
 
@@ -1654,7 +1671,7 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
        if (fix == POS_FIX_AUTO) {
                q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
                if (q) {
-                       snd_printdd(KERN_INFO
+                       printk(KERN_INFO
                                    "hda_intel: position_fix set to %d "
                                    "for device %04x:%04x\n",
                                    q->value, q->subvendor, q->subdevice);
@@ -1664,21 +1681,52 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
        return fix;
 }
 
+/*
+ * black-lists for probe_mask
+ */
+static struct snd_pci_quirk probe_mask_list[] __devinitdata = {
+       /* Thinkpad often breaks the controller communication when accessing
+        * to the non-working (or non-existing) modem codec slot.
+        */
+       SND_PCI_QUIRK(0x1014, 0x05b7, "Thinkpad Z60", 0x01),
+       SND_PCI_QUIRK(0x17aa, 0x2010, "Thinkpad X/T/R60", 0x01),
+       SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X/T/R61", 0x01),
+       {}
+};
+
+static void __devinit check_probe_mask(struct azx *chip, int dev)
+{
+       const struct snd_pci_quirk *q;
+
+       if (probe_mask[dev] == -1) {
+               q = snd_pci_quirk_lookup(chip->pci, probe_mask_list);
+               if (q) {
+                       printk(KERN_INFO
+                              "hda_intel: probe_mask set to 0x%x "
+                              "for device %04x:%04x\n",
+                              q->value, q->subvendor, q->subdevice);
+                       probe_mask[dev] = q->value;
+               }
+       }
+}
+
+
 /*
  * constructor
  */
 static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
-                               int driver_type,
+                               int dev, int driver_type,
                                struct azx **rchip)
 {
        struct azx *chip;
        int err;
+       unsigned short gcap;
        static struct snd_device_ops ops = {
                .dev_free = azx_dev_free,
        };
 
        *rchip = NULL;
-       
+
        err = pci_enable_device(pci);
        if (err < 0)
                return err;
@@ -1698,7 +1746,8 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
        chip->driver_type = driver_type;
        chip->msi = enable_msi;
 
-       chip->position_fix = check_position_fix(chip, position_fix);
+       chip->position_fix = check_position_fix(chip, position_fix[dev]);
+       check_probe_mask(chip, dev);
 
        chip->single_cmd = single_cmd;
 
@@ -1739,25 +1788,40 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
        pci_set_master(pci);
        synchronize_irq(chip->irq);
 
-       switch (chip->driver_type) {
-       case AZX_DRIVER_ULI:
-               chip->playback_streams = ULI_NUM_PLAYBACK;
-               chip->capture_streams = ULI_NUM_CAPTURE;
-               chip->playback_index_offset = ULI_PLAYBACK_INDEX;
-               chip->capture_index_offset = ULI_CAPTURE_INDEX;
-               break;
-       case AZX_DRIVER_ATIHDMI:
-               chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
-               chip->capture_streams = ATIHDMI_NUM_CAPTURE;
-               chip->playback_index_offset = ATIHDMI_PLAYBACK_INDEX;
-               chip->capture_index_offset = ATIHDMI_CAPTURE_INDEX;
-               break;
-       default:
-               chip->playback_streams = ICH6_NUM_PLAYBACK;
-               chip->capture_streams = ICH6_NUM_CAPTURE;
-               chip->playback_index_offset = ICH6_PLAYBACK_INDEX;
-               chip->capture_index_offset = ICH6_CAPTURE_INDEX;
-               break;
+       gcap = azx_readw(chip, GCAP);
+       snd_printdd("chipset global capabilities = 0x%x\n", gcap);
+
+       if (gcap) {
+               /* read number of streams from GCAP register instead of using
+                * hardcoded value
+                */
+               chip->playback_streams = (gcap & (0xF << 12)) >> 12;
+               chip->capture_streams = (gcap & (0xF << 8)) >> 8;
+               chip->playback_index_offset = (gcap & (0xF << 12)) >> 12;
+               chip->capture_index_offset = 0;
+       } else {
+               /* gcap didn't give any info, switching to old method */
+
+               switch (chip->driver_type) {
+               case AZX_DRIVER_ULI:
+                       chip->playback_streams = ULI_NUM_PLAYBACK;
+                       chip->capture_streams = ULI_NUM_CAPTURE;
+                       chip->playback_index_offset = ULI_PLAYBACK_INDEX;
+                       chip->capture_index_offset = ULI_CAPTURE_INDEX;
+                       break;
+               case AZX_DRIVER_ATIHDMI:
+                       chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
+                       chip->capture_streams = ATIHDMI_NUM_CAPTURE;
+                       chip->playback_index_offset = ATIHDMI_PLAYBACK_INDEX;
+                       chip->capture_index_offset = ATIHDMI_CAPTURE_INDEX;
+                       break;
+               default:
+                       chip->playback_streams = ICH6_NUM_PLAYBACK;
+                       chip->capture_streams = ICH6_NUM_CAPTURE;
+                       chip->playback_index_offset = ICH6_PLAYBACK_INDEX;
+                       chip->capture_index_offset = ICH6_CAPTURE_INDEX;
+                       break;
+               }
        }
        chip->num_streams = chip->playback_streams + chip->capture_streams;
        chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev),
@@ -1839,17 +1903,25 @@ static void power_down_all_codecs(struct azx *chip)
 static int __devinit azx_probe(struct pci_dev *pci,
                               const struct pci_device_id *pci_id)
 {
+       static int dev;
        struct snd_card *card;
        struct azx *chip;
        int err;
 
-       card = snd_card_new(index, id, THIS_MODULE, 0);
+       if (dev >= SNDRV_CARDS)
+               return -ENODEV;
+       if (!enable[dev]) {
+               dev++;
+               return -ENOENT;
+       }
+
+       card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
        if (!card) {
                snd_printk(KERN_ERR SFX "Error creating card!\n");
                return -ENOMEM;
        }
 
-       err = azx_create(card, pci, pci_id->driver_data, &chip);
+       err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
        if (err < 0) {
                snd_card_free(card);
                return err;
@@ -1857,7 +1929,7 @@ static int __devinit azx_probe(struct pci_dev *pci,
        card->private_data = chip;
 
        /* create codec instances */
-       err = azx_codec_create(chip, model);
+       err = azx_codec_create(chip, model[dev], probe_mask[dev]);
        if (err < 0) {
                snd_card_free(card);
                return err;
@@ -1889,6 +1961,7 @@ static int __devinit azx_probe(struct pci_dev *pci,
        chip->running = 1;
        power_down_all_codecs(chip);
 
+       dev++;
        return err;
 }
 
@@ -1906,12 +1979,21 @@ static struct pci_device_id azx_ids[] = {
        { 0x8086, 0x284b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH8 */
        { 0x8086, 0x293e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH9 */
        { 0x8086, 0x293f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH9 */
+       { 0x8086, 0x3a3e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH10 */
+       { 0x8086, 0x3a6e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH10 */
+       { 0x8086, 0x811b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SCH }, /* SCH*/
        { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */
        { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */
        { 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */
        { 0x1002, 0x7919, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS690 HDMI */
-       { 0x1002, 0x960c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS780 HDMI */
+       { 0x1002, 0x960f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS780 HDMI */
        { 0x1002, 0xaa00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI R600 HDMI */
+       { 0x1002, 0xaa08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RV630 HDMI */
+       { 0x1002, 0xaa10, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RV610 HDMI */
+       { 0x1002, 0xaa18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RV670 HDMI */
+       { 0x1002, 0xaa20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RV635 HDMI */
+       { 0x1002, 0xaa28, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RV620 HDMI */
+       { 0x1002, 0xaa30, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RV770 HDMI */
        { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */
        { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */
        { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */
@@ -1929,6 +2011,10 @@ static struct pci_device_id azx_ids[] = {
        { 0x10de, 0x0775, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */
        { 0x10de, 0x0776, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */
        { 0x10de, 0x0777, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */
+       { 0x10de, 0x0ac0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP79 */
+       { 0x10de, 0x0ac1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP79 */
+       { 0x10de, 0x0ac2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP79 */
+       { 0x10de, 0x0ac3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP79 */
        { 0, }
 };
 MODULE_DEVICE_TABLE(pci, azx_ids);