]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - sound/pci/hda/hda_intel.c
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
[linux-2.6-omap-h63xx.git] / sound / pci / hda / hda_intel.c
index 9590ece2099dd6e65c3cfbe159c5702ad26b2b55..9d1412a9f2f85f0d93c63913a3cb9eb790b4fd5f 100644 (file)
 #include "hda_codec.h"
 
 
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static char *model[SNDRV_CARDS];
-static int position_fix[SNDRV_CARDS];
+static int index = SNDRV_DEFAULT_IDX1;
+static char *id = SNDRV_DEFAULT_STR1;
+static char *model;
+static int position_fix;
 
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for Intel HD audio interface.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
-module_param_array(model, charp, NULL, 0444);
+module_param(model, charp, 0444);
 MODULE_PARM_DESC(model, "Use the given board model.");
-module_param_array(position_fix, int, NULL, 0444);
+module_param(position_fix, int, 0444);
 MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size).");
 
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
                         "{Intel, ICH6M},"
@@ -223,6 +224,9 @@ enum {
 #define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR   0x42
 #define ATI_SB450_HDAUDIO_ENABLE_SNOOP      0x02
 
+/* Defines for Nvidia HDA support */
+#define NVIDIA_HDA_TRANSREG_ADDR      0x4e
+#define NVIDIA_HDA_ENABLE_COHBITS     0x0f
 
 /*
  * Use CORB/RIRB for communication from/to codecs.
@@ -328,6 +332,7 @@ enum {
        AZX_DRIVER_VIA,
        AZX_DRIVER_SIS,
        AZX_DRIVER_ULI,
+       AZX_DRIVER_NVIDIA,
 };
 
 static char *driver_short_names[] __devinitdata = {
@@ -335,7 +340,8 @@ static char *driver_short_names[] __devinitdata = {
        [AZX_DRIVER_ATI] = "HDA ATI SB",
        [AZX_DRIVER_VIA] = "HDA VIA VT82xx",
        [AZX_DRIVER_SIS] = "HDA SIS966",
-       [AZX_DRIVER_ULI] = "HDA ULI M5461"
+       [AZX_DRIVER_ULI] = "HDA ULI M5461",
+       [AZX_DRIVER_NVIDIA] = "HDA NVidia",
 };
 
 /*
@@ -710,14 +716,14 @@ static void azx_stream_stop(azx_t *chip, azx_dev_t *azx_dev)
  */
 static void azx_init_chip(azx_t *chip)
 {
-       unsigned char tcsel_reg, ati_misc_cntl2;
+       unsigned char reg;
 
        /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
         * TCSEL == Traffic Class Select Register, which sets PCI express QOS
         * Ensuring these bits are 0 clears playback static on some HD Audio codecs
         */
-       pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, &tcsel_reg);
-       pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, tcsel_reg & 0xf8);
+       pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, &reg);
+       pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, reg & 0xf8);
 
        /* reset controller */
        azx_reset(chip);
@@ -733,13 +739,21 @@ static void azx_init_chip(azx_t *chip)
        azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
        azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr));
 
-       /* For ATI SB450 azalia HD audio, we need to enable snoop */
-       if (chip->driver_type == AZX_DRIVER_ATI) {
+       switch (chip->driver_type) {
+       case AZX_DRIVER_ATI:
+               /* For ATI SB450 azalia HD audio, we need to enable snoop */
                pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 
-                                    &ati_misc_cntl2);
+                                    &reg);
                pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 
-                                     (ati_misc_cntl2 & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP);
-       }
+                                     (reg & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP);
+               break;
+       case AZX_DRIVER_NVIDIA:
+               /* For NVIDIA HDA, enable snoop */
+               pci_read_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR, &reg);
+               pci_write_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR,
+                                     (reg & 0xf0) | NVIDIA_HDA_ENABLE_COHBITS);
+               break;
+        }
 }
 
 
@@ -1137,6 +1151,7 @@ static snd_pcm_uframes_t azx_pcm_pointer(snd_pcm_substream_t *substream)
                pos = azx_sd_readl(azx_dev, SD_LPIB);
                if (chip->position_fix == POS_FIX_FIFO)
                        pos += azx_dev->fifo_size;
+#if 0 /* disabled temprarily, auto-correction doesn't work well... */
                else if (chip->position_fix == POS_FIX_AUTO && azx_dev->period_updating) {
                        /* check the validity of DMA position */
                        unsigned int diff = 0;
@@ -1157,6 +1172,10 @@ static snd_pcm_uframes_t azx_pcm_pointer(snd_pcm_substream_t *substream)
                        }
                        azx_dev->period_updating = 0;
                }
+#else
+               else if (chip->position_fix == POS_FIX_AUTO)
+                       pos += azx_dev->fifo_size;
+#endif
        }
        if (pos >= azx_dev->bufsize)
                pos = 0;
@@ -1259,6 +1278,7 @@ static int __devinit azx_pcm_create(azx_t *chip)
                        err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev);
                        if (err < 0)
                                return err;
+                       chip->pcm[pcm_dev]->dev_class = SNDRV_PCM_CLASS_MODEM;
                        pcm_dev++;
                }
        }
@@ -1525,32 +1545,24 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci,
 
 static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
-       static int dev;
        snd_card_t *card;
        azx_t *chip;
        int err = 0;
 
-       if (dev >= SNDRV_CARDS)
-               return -ENODEV;
-       if (! enable[dev]) {
-               dev++;
-               return -ENOENT;
-       }
-
-       card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+       card = snd_card_new(index, id, THIS_MODULE, 0);
        if (NULL == card) {
                snd_printk(KERN_ERR SFX "Error creating card!\n");
                return -ENOMEM;
        }
 
-       if ((err = azx_create(card, pci, position_fix[dev], pci_id->driver_data,
+       if ((err = azx_create(card, pci, position_fix, pci_id->driver_data,
                              &chip)) < 0) {
                snd_card_free(card);
                return err;
        }
 
        /* create codec instances */
-       if ((err = azx_codec_create(chip, model[dev])) < 0) {
+       if ((err = azx_codec_create(chip, model)) < 0) {
                snd_card_free(card);
                return err;
        }
@@ -1576,7 +1588,6 @@ static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *
        }
 
        pci_set_drvdata(pci, card);
-       dev++;
 
        return err;
 }
@@ -1596,6 +1607,8 @@ static struct pci_device_id azx_ids[] = {
        { 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 */
+       { 0x10de, 0x026c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 026c */
+       { 0x10de, 0x0371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 0371 */
        { 0, }
 };
 MODULE_DEVICE_TABLE(pci, azx_ids);