"{ATI, SB600},"
"{ATI, RS600},"
"{ATI, RS690},"
+ "{ATI, RS780},"
+ "{ATI, R600},"
"{VIA, VT8251},"
"{VIA, VT8237A},"
"{SiS, SIS966},"
#define RIRB_INT_MASK 0x05
/* STATESTS int mask: SD2,SD1,SD0 */
+#define AZX_MAX_CODECS 3
#define STATESTS_INT_MASK 0x07
/* SD_CTL bits */
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 */
}
/* 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);
}
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);
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 */
*/
/* 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)) {
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 */
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;
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;
}
/*
* 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),
{}
};
{ 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 */
{ 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);