]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - sound/pci/hda/hda_intel.c
Pull dock-bay into release branch
[linux-2.6-omap-h63xx.git] / sound / pci / hda / hda_intel.c
index 1672cace1ae7d55592a1088a97511efe9761d4c0..92bc8b3fa2a0b7b198f03b8d4c3d53f73b0cd469 100644 (file)
@@ -88,6 +88,8 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
                         "{ATI, SB600},"
                         "{ATI, RS600},"
                         "{ATI, RS690},"
+                        "{ATI, RS780},"
+                        "{ATI, R600},"
                         "{VIA, VT8251},"
                         "{VIA, VT8237A},"
                         "{SiS, SIS966},"
@@ -198,6 +200,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
 #define RIRB_INT_MASK          0x05
 
 /* STATESTS int mask: SD2,SD1,SD0 */
+#define AZX_MAX_CODECS         3
 #define STATESTS_INT_MASK      0x07
 
 /* SD_CTL bits */
@@ -338,6 +341,9 @@ struct azx {
        unsigned int single_cmd :1;
        unsigned int polling_mode :1;
        unsigned int msi :1;
+
+       /* for debugging */
+       unsigned int last_cmd;  /* last issued command (to sync) */
 };
 
 /* driver types */
@@ -463,18 +469,10 @@ static void azx_free_cmd_io(struct azx *chip)
 }
 
 /* send a command */
-static int azx_corb_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
-                            unsigned int verb, unsigned int para)
+static int azx_corb_send_cmd(struct hda_codec *codec, u32 val)
 {
        struct azx *chip = codec->bus->private_data;
        unsigned int wp;
-       u32 val;
-
-       val = (u32)(codec->addr & 0x0f) << 28;
-       val |= (u32)direct << 27;
-       val |= (u32)nid << 20;
-       val |= verb << 8;
-       val |= para;
 
        /* add command to corb */
        wp = azx_readb(chip, CORBWP);
@@ -535,12 +533,12 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
                }
                if (! chip->rirb.cmds)
                        return chip->rirb.res; /* the last value */
-               schedule_timeout_interruptible(1);
+               schedule_timeout(1);
        } while (time_after_eq(timeout, jiffies));
 
        if (chip->msi) {
                snd_printk(KERN_WARNING "hda_intel: No response from codec, "
-                          "disabling MSI...\n");
+                          "disabling MSI: last cmd=0x%08x\n", chip->last_cmd);
                free_irq(chip->irq, chip);
                chip->irq = -1;
                pci_disable_msi(chip->pci);
@@ -552,13 +550,15 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
 
        if (!chip->polling_mode) {
                snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, "
-                          "switching to polling mode...\n");
+                          "switching to polling mode: last cmd=0x%08x\n",
+                          chip->last_cmd);
                chip->polling_mode = 1;
                goto again;
        }
 
        snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, "
-                  "switching to single_cmd mode...\n");
+                  "switching to single_cmd mode: last cmd=0x%08x\n",
+                  chip->last_cmd);
        chip->rirb.rp = azx_readb(chip, RIRBWP);
        chip->rirb.cmds = 0;
        /* switch to single_cmd mode */
@@ -578,20 +578,11 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
  */
 
 /* send a command */
-static int azx_single_send_cmd(struct hda_codec *codec, hda_nid_t nid,
-                              int direct, unsigned int verb,
-                              unsigned int para)
+static int azx_single_send_cmd(struct hda_codec *codec, u32 val)
 {
        struct azx *chip = codec->bus->private_data;
-       u32 val;
        int timeout = 50;
 
-       val = (u32)(codec->addr & 0x0f) << 28;
-       val |= (u32)direct << 27;
-       val |= (u32)nid << 20;
-       val |= verb << 8;
-       val |= para;
-
        while (timeout--) {
                /* check ICB busy bit */
                if (! (azx_readw(chip, IRS) & ICH6_IRS_BUSY)) {
@@ -636,10 +627,19 @@ static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid,
                        unsigned int para)
 {
        struct azx *chip = codec->bus->private_data;
+       u32 val;
+
+       val = (u32)(codec->addr & 0x0f) << 28;
+       val |= (u32)direct << 27;
+       val |= (u32)nid << 20;
+       val |= verb << 8;
+       val |= para;
+       chip->last_cmd = val;
+
        if (chip->single_cmd)
-               return azx_single_send_cmd(codec, nid, direct, verb, para);
+               return azx_single_send_cmd(codec, val);
        else
-               return azx_corb_send_cmd(codec, nid, direct, verb, para);
+               return azx_corb_send_cmd(codec, val);
 }
 
 /* get a response */
@@ -978,7 +978,7 @@ static unsigned int azx_max_codecs[] __devinitdata = {
 static int __devinit azx_codec_create(struct azx *chip, const char *model)
 {
        struct hda_bus_template bus_temp;
-       int c, codecs, err;
+       int c, codecs, audio_codecs, err;
 
        memset(&bus_temp, 0, sizeof(bus_temp));
        bus_temp.private_data = chip;
@@ -990,16 +990,30 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
        if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0)
                return err;
 
-       codecs = 0;
-       for (c = 0; c < azx_max_codecs[chip->driver_type]; c++) {
+       codecs = audio_codecs = 0;
+       for (c = 0; c < AZX_MAX_CODECS; c++) {
                if ((chip->codec_mask & (1 << c)) & probe_mask) {
-                       err = snd_hda_codec_new(chip->bus, c, NULL);
+                       struct hda_codec *codec;
+                       err = snd_hda_codec_new(chip->bus, c, &codec);
                        if (err < 0)
                                continue;
                        codecs++;
+                       if (codec->afg)
+                               audio_codecs++;
+               }
+       }
+       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) {
+                               err = snd_hda_codec_new(chip->bus, c, NULL);
+                               if (err < 0)
+                                       continue;
+                               codecs++;
+                       }
                }
        }
-       if (! codecs) {
+       if (!codecs) {
                snd_printk(KERN_ERR SFX "no codecs initialized\n");
                return -ENXIO;
        }
@@ -1518,7 +1532,7 @@ static int azx_dev_free(struct snd_device *device)
 /*
  * white/black-listing for position_fix
  */
-static const struct snd_pci_quirk position_fix_list[] __devinitdata = {
+static struct snd_pci_quirk position_fix_list[] __devinitdata = {
        SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE),
        {}
 };
@@ -1758,6 +1772,8 @@ static struct pci_device_id azx_ids[] = {
        { 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, 0xaa00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI R600 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 */
@@ -1769,6 +1785,12 @@ static struct pci_device_id azx_ids[] = {
        { 0x10de, 0x044b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP65 */
        { 0x10de, 0x055c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP67 */
        { 0x10de, 0x055d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP67 */
+       { 0x10de, 0x07fc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP73 */
+       { 0x10de, 0x07fd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP73 */
+       { 0x10de, 0x0774, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */
+       { 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 */
        { 0, }
 };
 MODULE_DEVICE_TABLE(pci, azx_ids);