Pull asus into release branch
[pandora-kernel.git] / sound / pci / hda / hda_intel.c
index 1a7e821..1672cac 100644 (file)
@@ -199,7 +199,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
 
 /* STATESTS int mask: SD2,SD1,SD0 */
 #define STATESTS_INT_MASK      0x07
-#define AZX_MAX_CODECS         4
 
 /* SD_CTL bits */
 #define SD_CTL_STREAM_RESET    0x01    /* stream reset bit */
@@ -966,6 +965,16 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
  * Codec initialization
  */
 
+static unsigned int azx_max_codecs[] __devinitdata = {
+       [AZX_DRIVER_ICH] = 3,
+       [AZX_DRIVER_ATI] = 4,
+       [AZX_DRIVER_ATIHDMI] = 4,
+       [AZX_DRIVER_VIA] = 3,           /* FIXME: correct? */
+       [AZX_DRIVER_SIS] = 3,           /* FIXME: correct? */
+       [AZX_DRIVER_ULI] = 3,           /* FIXME: correct? */
+       [AZX_DRIVER_NVIDIA] = 3,        /* FIXME: correct? */
+};
+
 static int __devinit azx_codec_create(struct azx *chip, const char *model)
 {
        struct hda_bus_template bus_temp;
@@ -982,7 +991,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
                return err;
 
        codecs = 0;
-       for (c = 0; c < AZX_MAX_CODECS; c++) {
+       for (c = 0; c < azx_max_codecs[chip->driver_type]; c++) {
                if ((chip->codec_mask & (1 << c)) & probe_mask) {
                        err = snd_hda_codec_new(chip->bus, c, NULL);
                        if (err < 0)
@@ -1078,6 +1087,10 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
        runtime->hw.rates = hinfo->rates;
        snd_pcm_limit_hw_rates(runtime);
        snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+       snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
+                                  128);
+       snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
+                                  128);
        if ((err = hinfo->ops.open(hinfo, apcm->codec, substream)) < 0) {
                azx_release_device(azx_dev);
                mutex_unlock(&chip->open_mutex);
@@ -1285,7 +1298,7 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec,
                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &azx_pcm_ops);
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                              snd_dma_pci_data(chip->pci),
-                                             1024 * 64, 1024 * 128);
+                                             1024 * 64, 1024 * 1024);
        chip->pcm[pcm_dev] = pcm;
        if (chip->pcm_devs < pcm_dev + 1)
                chip->pcm_devs = pcm_dev + 1;
@@ -1391,6 +1404,7 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect)
                return -1;
        }
        chip->irq = chip->pci->irq;
+       pci_intx(chip->pci, !chip->msi);
        return 0;
 }
 
@@ -1501,6 +1515,31 @@ static int azx_dev_free(struct snd_device *device)
        return azx_free(device->device_data);
 }
 
+/*
+ * white/black-listing for position_fix
+ */
+static const struct snd_pci_quirk position_fix_list[] __devinitdata = {
+       SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE),
+       {}
+};
+
+static int __devinit check_position_fix(struct azx *chip, int fix)
+{
+       const struct snd_pci_quirk *q;
+
+       if (fix == POS_FIX_AUTO) {
+               q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
+               if (q) {
+                       snd_printdd(KERN_INFO
+                                   "hda_intel: position_fix set to %d "
+                                   "for device %04x:%04x\n",
+                                   q->value, q->subvendor, q->subdevice);
+                       return q->value;
+               }
+       }
+       return fix;
+}
+
 /*
  * constructor
  */
@@ -1535,7 +1574,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 = position_fix;
+       chip->position_fix = check_position_fix(chip, position_fix);
+
        chip->single_cmd = single_cmd;
 
 #if BITS_PER_LONG != 64