Merge branch 'topic/hda' into for-linus
authorTakashi Iwai <tiwai@suse.de>
Mon, 23 Mar 2009 23:36:09 +0000 (00:36 +0100)
committerTakashi Iwai <tiwai@suse.de>
Mon, 23 Mar 2009 23:36:09 +0000 (00:36 +0100)
1  2 
Documentation/sound/alsa/ALSA-Configuration.txt
include/linux/pci_ids.h
sound/pci/hda/hda_intel.c

index 57fe4f3ca2c046a616cb0cce392fa77faa406bee,012afd7afb13df0657c2e113b1757972a11842aa..ab163b701f9dc136034354a95678e1966d7d1345
@@@ -346,9 -346,6 +346,9 @@@ Prior to version 0.9.0rc4 options had 
      sbirq     - IRQ # for CMI8330 chip (SB16)
      sbdma8    - 8bit DMA # for CMI8330 chip (SB16)
      sbdma16   - 16bit DMA # for CMI8330 chip (SB16)
 +    fmport    - (optional) OPL3 I/O port
 +    mpuport   - (optional) MPU401 I/O port
 +    mpuirq    - (optional) MPU401 irq #
  
      This module supports multiple cards and autoprobe.
  
  
      The power-management is supported.
      
 -  Module snd-cs4232
 -  -----------------
 -
 -    Module for sound cards based on CS4232/CS4232A ISA chips.
 -
 -    isapnp    - ISA PnP detection - 0 = disable, 1 = enable (default)
 -
 -    with isapnp=0, the following options are available:
 -
 -    port      - port # for CS4232 chip (PnP setup - 0x534)
 -    cport     - control port # for CS4232 chip (PnP setup - 0x120,0x210,0xf00)
 -    mpu_port  - port # for MPU-401 UART (PnP setup - 0x300), -1 = disable
 -    fm_port   - FM port # for CS4232 chip (PnP setup - 0x388), -1 = disable
 -    irq               - IRQ # for CS4232 chip (5,7,9,11,12,15)
 -    mpu_irq   - IRQ # for MPU-401 UART (9,11,12,15)
 -    dma1      - first DMA # for CS4232 chip (0,1,3)
 -    dma2      - second DMA # for Yamaha CS4232 chip (0,1,3), -1 = disable
 -    
 -    This module supports multiple cards. This module does not support autoprobe
 -    (if ISA PnP is not used) thus main port must be specified!!! Other ports are
 -    optional.
 -
 -    The power-management is supported.
 -    
    Module snd-cs4236
    -----------------
  
 -    Module for sound cards based on CS4235/CS4236/CS4236B/CS4237B/
 +    Module for sound cards based on CS4232/CS4232A,
 +                                 CS4235/CS4236/CS4236B/CS4237B/
                                     CS4238B/CS4239 ISA chips.
  
      isapnp    - ISA PnP detection - 0 = disable, 1 = enable (default)
  
      The power-management is supported.
  
 +    This module is aliased as snd-cs4232 since it provides the old
 +    snd-cs4232 functionality, too.
 +
    Module snd-cs4281
    -----------------
  
      Module for ESS AudioDrive ES-1688 and ES-688 sound cards.
  
      port      - port # for ES-1688 chip (0x220,0x240,0x260)
 +    fm_port   - port # for OPL3 (option; share the same port as default)
      mpu_port  - port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable (default)
      irq               - IRQ # for ES-1688 chip (5,7,9,10)
      mpu_irq   - IRQ # for MPU-401 port (5,7,9,10)
      model     - force the model name
      position_fix - Fix DMA pointer (0 = auto, 1 = use LPIB, 2 = POSBUF)
      probe_mask  - Bitmask to probe codecs (default = -1, meaning all slots)
+                 When the bit 8 (0x100) is set, the lower 8 bits are used
+                 as the "fixed" codec slots; i.e. the driver probes the
+                 slots regardless what hardware reports back
      probe_only        - Only probing and no codec initialization (default=off);
                  Useful to check the initial codec status for debugging
      bdl_pos_adj       - Specifies the DMA IRQ timing delay in samples.
diff --combined include/linux/pci_ids.h
index aca8c458aa8a7a23e87198ce8a9cb9eba8f3d87b,88152e50d063588ebbda9d33595011629acfe7e4..02c18b903986b3e3168fba80098425deaf046c78
  #define PCI_DEVICE_ID_VIA_VT3351      0x0351
  #define PCI_DEVICE_ID_VIA_VT3364      0x0364
  #define PCI_DEVICE_ID_VIA_8371_0      0x0391
 +#define PCI_DEVICE_ID_VIA_6415                0x0415
  #define PCI_DEVICE_ID_VIA_8501_0      0x0501
  #define PCI_DEVICE_ID_VIA_82C561      0x0561
  #define PCI_DEVICE_ID_VIA_82C586_1    0x0571
  #define PCI_DEVICE_ID_DIGI_DF_M_E     0x0071
  #define PCI_DEVICE_ID_DIGI_DF_M_IOM2_A        0x0072
  #define PCI_DEVICE_ID_DIGI_DF_M_A     0x0073
 +#define PCI_DEVICE_ID_DIGI_NEO_8      0x00B1
  #define PCI_DEVICE_ID_NEO_2DB9          0x00C8
  #define PCI_DEVICE_ID_NEO_2DB9PRI       0x00C9
  #define PCI_DEVICE_ID_NEO_2RJ45         0x00CA
  #define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c
  #define PCI_DEVICE_ID_MELLANOX_SINAI  0x6274
  
+ #define PCI_VENDOR_ID_DFI             0x15bd
  #define PCI_VENDOR_ID_QUICKNET                0x15e2
  #define PCI_DEVICE_ID_QUICKNET_XJ     0x0500
  
  #define PCI_DEVICE_ID_INTEL_82378     0x0484
  #define PCI_DEVICE_ID_INTEL_I960      0x0960
  #define PCI_DEVICE_ID_INTEL_I960RM    0x0962
 +#define PCI_DEVICE_ID_INTEL_8257X_SOL 0x1062
 +#define PCI_DEVICE_ID_INTEL_82573E_SOL        0x1085
 +#define PCI_DEVICE_ID_INTEL_82573L_SOL        0x108F
  #define PCI_DEVICE_ID_INTEL_82815_MC  0x1130
  #define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132
  #define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221
  #define PCI_DEVICE_ID_INTEL_ICH7_0    0x27b8
  #define PCI_DEVICE_ID_INTEL_ICH7_1    0x27b9
  #define PCI_DEVICE_ID_INTEL_ICH7_30   0x27b0
 +#define PCI_DEVICE_ID_INTEL_TGP_LPC   0x27bc
  #define PCI_DEVICE_ID_INTEL_ICH7_31   0x27bd
  #define PCI_DEVICE_ID_INTEL_ICH7_17   0x27da
  #define PCI_DEVICE_ID_INTEL_ICH7_19   0x27dd
index 3683978324e82b2df93f2923bc89d931702ee353,8b2e4160de8d94294c590f43721217e4de9796f3..30829ee920c3a8366ea841dbdb985787719b521e
@@@ -381,6 -381,7 +381,7 @@@ struct azx 
  
        /* HD codec */
        unsigned short codec_mask;
+       int  codec_probe_mask; /* copied from probe_mask option */
        struct hda_bus *bus;
  
        /* CORB/RIRB */
@@@ -858,13 -859,18 +859,18 @@@ static void azx_stream_start(struct az
                      SD_CTL_DMA_START | SD_INT_MASK);
  }
  
- /* stop a stream */
- static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
+ /* stop DMA */
+ static void azx_stream_clear(struct azx *chip, struct azx_dev *azx_dev)
  {
-       /* stop DMA */
        azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) &
                      ~(SD_CTL_DMA_START | SD_INT_MASK));
        azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */
+ }
+ /* stop a stream */
+ static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
+ {
+       azx_stream_clear(chip, azx_dev);
        /* disable SIE */
        azx_writeb(chip, INTCTL,
                   azx_readb(chip, INTCTL) & ~(1 << azx_dev->index));
@@@ -1075,8 -1081,7 +1081,7 @@@ static int azx_setup_periods(struct az
        azx_sd_writel(azx_dev, SD_BDLPL, 0);
        azx_sd_writel(azx_dev, SD_BDLPU, 0);
  
-       period_bytes = snd_pcm_lib_period_bytes(substream);
-       azx_dev->period_bytes = period_bytes;
+       period_bytes = azx_dev->period_bytes;
        periods = azx_dev->bufsize / period_bytes;
  
        /* program the initial BDL entries */
   error:
        snd_printk(KERN_ERR "Too many BDL entries: buffer=%d, period=%d\n",
                   azx_dev->bufsize, period_bytes);
-       /* reset */
-       azx_sd_writel(azx_dev, SD_BDLPL, 0);
-       azx_sd_writel(azx_dev, SD_BDLPU, 0);
        return -EINVAL;
  }
  
- /*
-  * set up the SD for streaming
-  */
- static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
+ /* reset stream */
+ static void azx_stream_reset(struct azx *chip, struct azx_dev *azx_dev)
  {
        unsigned char val;
        int timeout;
  
-       /* make sure the run bit is zero for SD */
-       azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) &
-                     ~SD_CTL_DMA_START);
-       /* reset stream */
+       azx_stream_clear(chip, azx_dev);
        azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) |
                      SD_CTL_STREAM_RESET);
        udelay(3);
        while (((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) &&
               --timeout)
                ;
+ }
  
+ /*
+  * set up the SD for streaming
+  */
+ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
+ {
+       /* make sure the run bit is zero for SD */
+       azx_stream_clear(chip, azx_dev);
        /* program the stream_tag */
        azx_sd_writel(azx_dev, SD_CTL,
                      (azx_sd_readl(azx_dev, SD_CTL) & ~SD_CTL_STREAM_TAG_MASK)|
@@@ -1228,7 -1234,6 +1234,6 @@@ static unsigned int azx_max_codecs[AZX_
  };
  
  static int __devinit azx_codec_create(struct azx *chip, const char *model,
-                                     unsigned int codec_probe_mask,
                                      int no_init)
  {
        struct hda_bus_template bus_temp;
  
        /* First try to probe all given codec slots */
        for (c = 0; c < max_slots; c++) {
-               if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
+               if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
                        if (probe_codec(chip, c) < 0) {
                                /* Some BIOSen give you wrong codec addresses
                                 * that don't exist
  
        /* Then create codec instances */
        for (c = 0; c < max_slots; c++) {
-               if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
+               if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
                        struct hda_codec *codec;
                        err = snd_hda_codec_new(chip->bus, c, !no_init, &codec);
                        if (err < 0)
@@@ -1403,6 -1408,8 +1408,8 @@@ static int azx_pcm_open(struct snd_pcm_
        runtime->private_data = azx_dev;
        snd_pcm_set_sync(substream);
        mutex_unlock(&chip->open_mutex);
+       azx_stream_reset(chip, azx_dev);
        return 0;
  }
  
@@@ -1429,6 -1436,11 +1436,11 @@@ static int azx_pcm_close(struct snd_pcm
  static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *hw_params)
  {
+       struct azx_dev *azx_dev = get_azx_dev(substream);
+       azx_dev->bufsize = 0;
+       azx_dev->period_bytes = 0;
+       azx_dev->format_val = 0;
        return snd_pcm_lib_malloc_pages(substream,
                                        params_buffer_bytes(hw_params));
  }
@@@ -1443,6 -1455,9 +1455,9 @@@ static int azx_pcm_hw_free(struct snd_p
        azx_sd_writel(azx_dev, SD_BDLPL, 0);
        azx_sd_writel(azx_dev, SD_BDLPU, 0);
        azx_sd_writel(azx_dev, SD_CTL, 0);
+       azx_dev->bufsize = 0;
+       azx_dev->period_bytes = 0;
+       azx_dev->format_val = 0;
  
        hinfo->ops.cleanup(hinfo, apcm->codec, substream);
  
@@@ -1456,23 -1471,37 +1471,37 @@@ static int azx_pcm_prepare(struct snd_p
        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;
+       int err;
  
-       azx_dev->bufsize = snd_pcm_lib_buffer_bytes(substream);
-       azx_dev->format_val = snd_hda_calc_stream_format(runtime->rate,
-                                                        runtime->channels,
-                                                        runtime->format,
-                                                        hinfo->maxbps);
-       if (!azx_dev->format_val) {
+       format_val = snd_hda_calc_stream_format(runtime->rate,
+                                               runtime->channels,
+                                               runtime->format,
+                                               hinfo->maxbps);
+       if (!format_val) {
                snd_printk(KERN_ERR SFX
                           "invalid format_val, rate=%d, ch=%d, format=%d\n",
                           runtime->rate, runtime->channels, runtime->format);
                return -EINVAL;
        }
  
+       bufsize = snd_pcm_lib_buffer_bytes(substream);
+       period_bytes = snd_pcm_lib_period_bytes(substream);
        snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n",
-                   azx_dev->bufsize, azx_dev->format_val);
-       if (azx_setup_periods(chip, substream, azx_dev) < 0)
-               return -EINVAL;
+                   bufsize, format_val);
+       if (bufsize != azx_dev->bufsize ||
+           period_bytes != azx_dev->period_bytes ||
+           format_val != azx_dev->format_val) {
+               azx_dev->bufsize = bufsize;
+               azx_dev->period_bytes = period_bytes;
+               azx_dev->format_val = format_val;
+               err = azx_setup_periods(chip, substream, azx_dev);
+               if (err < 0)
+                       return err;
+       }
        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;
@@@ -2100,25 -2129,36 +2129,36 @@@ static struct snd_pci_quirk probe_mask_
        SND_PCI_QUIRK(0x1028, 0x20ac, "Dell Studio Desktop", 0x01),
        /* including bogus ALC268 in slot#2 that conflicts with ALC888 */
        SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01),
-       /* conflict of ALC268 in slot#3 (digital I/O); a temporary fix */
-       SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba laptop", 0x03),
+       /* forced codec slots */
+       SND_PCI_QUIRK(0x1046, 0x1262, "ASUS W5F", 0x103),
        {}
  };
  
+ #define AZX_FORCE_CODEC_MASK  0x100
  static void __devinit check_probe_mask(struct azx *chip, int dev)
  {
        const struct snd_pci_quirk *q;
  
-       if (probe_mask[dev] == -1) {
+       chip->codec_probe_mask = probe_mask[dev];
+       if (chip->codec_probe_mask == -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;
+                       chip->codec_probe_mask = q->value;
                }
        }
+       /* check forced option */
+       if (chip->codec_probe_mask != -1 &&
+           (chip->codec_probe_mask & AZX_FORCE_CODEC_MASK)) {
+               chip->codec_mask = chip->codec_probe_mask & 0xff;
+               printk(KERN_INFO "hda_intel: codec_mask forced to 0x%x\n",
+                      chip->codec_mask);
+       }
  }
  
  
@@@ -2347,10 -2387,10 +2387,10 @@@ static int __devinit azx_probe(struct p
                return -ENOENT;
        }
  
 -      card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
 -      if (!card) {
 +      err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
 +      if (err < 0) {
                snd_printk(KERN_ERR SFX "Error creating card!\n");
 -              return -ENOMEM;
 +              return err;
        }
  
        err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
        card->private_data = chip;
  
        /* create codec instances */
-       err = azx_codec_create(chip, model[dev], probe_mask[dev],
-                              probe_only[dev]);
+       err = azx_codec_create(chip, model[dev], probe_only[dev]);
        if (err < 0)
                goto out_free;
  
@@@ -2457,10 -2496,10 +2496,10 @@@ static struct pci_device_id azx_ids[] 
        { PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA },
        { PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA },
        { PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA },
-       { PCI_DEVICE(0x10de, 0x0bd4), .driver_data = AZX_DRIVER_NVIDIA },
-       { PCI_DEVICE(0x10de, 0x0bd5), .driver_data = AZX_DRIVER_NVIDIA },
-       { PCI_DEVICE(0x10de, 0x0bd6), .driver_data = AZX_DRIVER_NVIDIA },
-       { PCI_DEVICE(0x10de, 0x0bd7), .driver_data = AZX_DRIVER_NVIDIA },
+       { PCI_DEVICE(0x10de, 0x0d94), .driver_data = AZX_DRIVER_NVIDIA },
+       { PCI_DEVICE(0x10de, 0x0d95), .driver_data = AZX_DRIVER_NVIDIA },
+       { PCI_DEVICE(0x10de, 0x0d96), .driver_data = AZX_DRIVER_NVIDIA },
+       { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA },
        /* Teradici */
        { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
        /* AMD Generic, PCI class code and Vendor ID for HD Audio */