|
@@ -128,21 +128,33 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
|
|
"{ULI, M5461}}");
|
|
"{ULI, M5461}}");
|
|
MODULE_DESCRIPTION("Intel HDA driver");
|
|
MODULE_DESCRIPTION("Intel HDA driver");
|
|
|
|
|
|
|
|
+#ifdef CONFIG_SND_VERBOSE_PRINTK
|
|
|
|
+#define SFX /* nop */
|
|
|
|
+#else
|
|
#define SFX "hda-intel: "
|
|
#define SFX "hda-intel: "
|
|
-
|
|
|
|
|
|
+#endif
|
|
|
|
|
|
/*
|
|
/*
|
|
* registers
|
|
* registers
|
|
*/
|
|
*/
|
|
#define ICH6_REG_GCAP 0x00
|
|
#define ICH6_REG_GCAP 0x00
|
|
|
|
+#define ICH6_GCAP_64OK (1 << 0) /* 64bit address support */
|
|
|
|
+#define ICH6_GCAP_NSDO (3 << 1) /* # of serial data out signals */
|
|
|
|
+#define ICH6_GCAP_BSS (31 << 3) /* # of bidirectional streams */
|
|
|
|
+#define ICH6_GCAP_ISS (15 << 8) /* # of input streams */
|
|
|
|
+#define ICH6_GCAP_OSS (15 << 12) /* # of output streams */
|
|
#define ICH6_REG_VMIN 0x02
|
|
#define ICH6_REG_VMIN 0x02
|
|
#define ICH6_REG_VMAJ 0x03
|
|
#define ICH6_REG_VMAJ 0x03
|
|
#define ICH6_REG_OUTPAY 0x04
|
|
#define ICH6_REG_OUTPAY 0x04
|
|
#define ICH6_REG_INPAY 0x06
|
|
#define ICH6_REG_INPAY 0x06
|
|
#define ICH6_REG_GCTL 0x08
|
|
#define ICH6_REG_GCTL 0x08
|
|
|
|
+#define ICH6_GCTL_RESET (1 << 0) /* controller reset */
|
|
|
|
+#define ICH6_GCTL_FCNTRL (1 << 1) /* flush control */
|
|
|
|
+#define ICH6_GCTL_UNSOL (1 << 8) /* accept unsol. response enable */
|
|
#define ICH6_REG_WAKEEN 0x0c
|
|
#define ICH6_REG_WAKEEN 0x0c
|
|
#define ICH6_REG_STATESTS 0x0e
|
|
#define ICH6_REG_STATESTS 0x0e
|
|
#define ICH6_REG_GSTS 0x10
|
|
#define ICH6_REG_GSTS 0x10
|
|
|
|
+#define ICH6_GSTS_FSTS (1 << 1) /* flush status */
|
|
#define ICH6_REG_INTCTL 0x20
|
|
#define ICH6_REG_INTCTL 0x20
|
|
#define ICH6_REG_INTSTS 0x24
|
|
#define ICH6_REG_INTSTS 0x24
|
|
#define ICH6_REG_WALCLK 0x30
|
|
#define ICH6_REG_WALCLK 0x30
|
|
@@ -150,17 +162,27 @@ MODULE_DESCRIPTION("Intel HDA driver");
|
|
#define ICH6_REG_CORBLBASE 0x40
|
|
#define ICH6_REG_CORBLBASE 0x40
|
|
#define ICH6_REG_CORBUBASE 0x44
|
|
#define ICH6_REG_CORBUBASE 0x44
|
|
#define ICH6_REG_CORBWP 0x48
|
|
#define ICH6_REG_CORBWP 0x48
|
|
-#define ICH6_REG_CORBRP 0x4A
|
|
|
|
|
|
+#define ICH6_REG_CORBRP 0x4a
|
|
|
|
+#define ICH6_CORBRP_RST (1 << 15) /* read pointer reset */
|
|
#define ICH6_REG_CORBCTL 0x4c
|
|
#define ICH6_REG_CORBCTL 0x4c
|
|
|
|
+#define ICH6_CORBCTL_RUN (1 << 1) /* enable DMA */
|
|
|
|
+#define ICH6_CORBCTL_CMEIE (1 << 0) /* enable memory error irq */
|
|
#define ICH6_REG_CORBSTS 0x4d
|
|
#define ICH6_REG_CORBSTS 0x4d
|
|
|
|
+#define ICH6_CORBSTS_CMEI (1 << 0) /* memory error indication */
|
|
#define ICH6_REG_CORBSIZE 0x4e
|
|
#define ICH6_REG_CORBSIZE 0x4e
|
|
|
|
|
|
#define ICH6_REG_RIRBLBASE 0x50
|
|
#define ICH6_REG_RIRBLBASE 0x50
|
|
#define ICH6_REG_RIRBUBASE 0x54
|
|
#define ICH6_REG_RIRBUBASE 0x54
|
|
#define ICH6_REG_RIRBWP 0x58
|
|
#define ICH6_REG_RIRBWP 0x58
|
|
|
|
+#define ICH6_RIRBWP_RST (1 << 15) /* write pointer reset */
|
|
#define ICH6_REG_RINTCNT 0x5a
|
|
#define ICH6_REG_RINTCNT 0x5a
|
|
#define ICH6_REG_RIRBCTL 0x5c
|
|
#define ICH6_REG_RIRBCTL 0x5c
|
|
|
|
+#define ICH6_RBCTL_IRQ_EN (1 << 0) /* enable IRQ */
|
|
|
|
+#define ICH6_RBCTL_DMA_EN (1 << 1) /* enable DMA */
|
|
|
|
+#define ICH6_RBCTL_OVERRUN_EN (1 << 2) /* enable overrun irq */
|
|
#define ICH6_REG_RIRBSTS 0x5d
|
|
#define ICH6_REG_RIRBSTS 0x5d
|
|
|
|
+#define ICH6_RBSTS_IRQ (1 << 0) /* response irq */
|
|
|
|
+#define ICH6_RBSTS_OVERRUN (1 << 2) /* overrun irq */
|
|
#define ICH6_REG_RIRBSIZE 0x5e
|
|
#define ICH6_REG_RIRBSIZE 0x5e
|
|
|
|
|
|
#define ICH6_REG_IC 0x60
|
|
#define ICH6_REG_IC 0x60
|
|
@@ -257,16 +279,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
|
|
#define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */
|
|
#define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */
|
|
#define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */
|
|
#define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */
|
|
|
|
|
|
-/* GCTL unsolicited response enable bit */
|
|
|
|
-#define ICH6_GCTL_UREN (1<<8)
|
|
|
|
-
|
|
|
|
-/* GCTL reset bit */
|
|
|
|
-#define ICH6_GCTL_RESET (1<<0)
|
|
|
|
-
|
|
|
|
-/* CORB/RIRB control, read/write pointer */
|
|
|
|
-#define ICH6_RBCTL_DMA_EN 0x02 /* enable DMA */
|
|
|
|
-#define ICH6_RBCTL_IRQ_EN 0x01 /* enable IRQ */
|
|
|
|
-#define ICH6_RBRWP_CLR 0x8000 /* read/write pointer clear */
|
|
|
|
/* below are so far hardcoded - should read registers in future */
|
|
/* below are so far hardcoded - should read registers in future */
|
|
#define ICH6_MAX_CORB_ENTRIES 256
|
|
#define ICH6_MAX_CORB_ENTRIES 256
|
|
#define ICH6_MAX_RIRB_ENTRIES 256
|
|
#define ICH6_MAX_RIRB_ENTRIES 256
|
|
@@ -512,25 +524,25 @@ static void azx_init_cmd_io(struct azx *chip)
|
|
/* set the corb write pointer to 0 */
|
|
/* set the corb write pointer to 0 */
|
|
azx_writew(chip, CORBWP, 0);
|
|
azx_writew(chip, CORBWP, 0);
|
|
/* reset the corb hw read pointer */
|
|
/* reset the corb hw read pointer */
|
|
- azx_writew(chip, CORBRP, ICH6_RBRWP_CLR);
|
|
|
|
|
|
+ azx_writew(chip, CORBRP, ICH6_CORBRP_RST);
|
|
/* enable corb dma */
|
|
/* enable corb dma */
|
|
- azx_writeb(chip, CORBCTL, ICH6_RBCTL_DMA_EN);
|
|
|
|
|
|
+ azx_writeb(chip, CORBCTL, ICH6_CORBCTL_RUN);
|
|
|
|
|
|
/* RIRB set up */
|
|
/* RIRB set up */
|
|
chip->rirb.addr = chip->rb.addr + 2048;
|
|
chip->rirb.addr = chip->rb.addr + 2048;
|
|
chip->rirb.buf = (u32 *)(chip->rb.area + 2048);
|
|
chip->rirb.buf = (u32 *)(chip->rb.area + 2048);
|
|
|
|
+ chip->rirb.wp = chip->rirb.rp = chip->rirb.cmds = 0;
|
|
azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr);
|
|
azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr);
|
|
azx_writel(chip, RIRBUBASE, upper_32_bits(chip->rirb.addr));
|
|
azx_writel(chip, RIRBUBASE, upper_32_bits(chip->rirb.addr));
|
|
|
|
|
|
/* set the rirb size to 256 entries (ULI requires explicitly) */
|
|
/* set the rirb size to 256 entries (ULI requires explicitly) */
|
|
azx_writeb(chip, RIRBSIZE, 0x02);
|
|
azx_writeb(chip, RIRBSIZE, 0x02);
|
|
/* reset the rirb hw write pointer */
|
|
/* reset the rirb hw write pointer */
|
|
- azx_writew(chip, RIRBWP, ICH6_RBRWP_CLR);
|
|
|
|
|
|
+ azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST);
|
|
/* set N=1, get RIRB response interrupt for new entry */
|
|
/* set N=1, get RIRB response interrupt for new entry */
|
|
azx_writew(chip, RINTCNT, 1);
|
|
azx_writew(chip, RINTCNT, 1);
|
|
/* enable rirb dma and response irq */
|
|
/* enable rirb dma and response irq */
|
|
azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN);
|
|
azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN);
|
|
- chip->rirb.rp = chip->rirb.cmds = 0;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static void azx_free_cmd_io(struct azx *chip)
|
|
static void azx_free_cmd_io(struct azx *chip)
|
|
@@ -606,6 +618,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
|
|
}
|
|
}
|
|
if (!chip->rirb.cmds) {
|
|
if (!chip->rirb.cmds) {
|
|
smp_rmb();
|
|
smp_rmb();
|
|
|
|
+ bus->rirb_error = 0;
|
|
return chip->rirb.res; /* the last value */
|
|
return chip->rirb.res; /* the last value */
|
|
}
|
|
}
|
|
if (time_after(jiffies, timeout))
|
|
if (time_after(jiffies, timeout))
|
|
@@ -619,19 +632,21 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
|
|
}
|
|
}
|
|
|
|
|
|
if (chip->msi) {
|
|
if (chip->msi) {
|
|
- snd_printk(KERN_WARNING "hda_intel: No response from codec, "
|
|
|
|
|
|
+ snd_printk(KERN_WARNING SFX "No response from codec, "
|
|
"disabling MSI: last cmd=0x%08x\n", chip->last_cmd);
|
|
"disabling MSI: last cmd=0x%08x\n", chip->last_cmd);
|
|
free_irq(chip->irq, chip);
|
|
free_irq(chip->irq, chip);
|
|
chip->irq = -1;
|
|
chip->irq = -1;
|
|
pci_disable_msi(chip->pci);
|
|
pci_disable_msi(chip->pci);
|
|
chip->msi = 0;
|
|
chip->msi = 0;
|
|
- if (azx_acquire_irq(chip, 1) < 0)
|
|
|
|
|
|
+ if (azx_acquire_irq(chip, 1) < 0) {
|
|
|
|
+ bus->rirb_error = 1;
|
|
return -1;
|
|
return -1;
|
|
|
|
+ }
|
|
goto again;
|
|
goto again;
|
|
}
|
|
}
|
|
|
|
|
|
if (!chip->polling_mode) {
|
|
if (!chip->polling_mode) {
|
|
- snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, "
|
|
|
|
|
|
+ snd_printk(KERN_WARNING SFX "azx_get_response timeout, "
|
|
"switching to polling mode: last cmd=0x%08x\n",
|
|
"switching to polling mode: last cmd=0x%08x\n",
|
|
chip->last_cmd);
|
|
chip->last_cmd);
|
|
chip->polling_mode = 1;
|
|
chip->polling_mode = 1;
|
|
@@ -646,14 +661,23 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /* a fatal communication error; need either to reset or to fallback
|
|
|
|
+ * to the single_cmd mode
|
|
|
|
+ */
|
|
|
|
+ bus->rirb_error = 1;
|
|
|
|
+ if (bus->allow_bus_reset && !bus->response_reset && !bus->in_reset) {
|
|
|
|
+ bus->response_reset = 1;
|
|
|
|
+ return -1; /* give a chance to retry */
|
|
|
|
+ }
|
|
|
|
+
|
|
snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, "
|
|
snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, "
|
|
"switching to single_cmd mode: last cmd=0x%08x\n",
|
|
"switching to single_cmd mode: last cmd=0x%08x\n",
|
|
chip->last_cmd);
|
|
chip->last_cmd);
|
|
- chip->rirb.rp = azx_readb(chip, RIRBWP);
|
|
|
|
- chip->rirb.cmds = 0;
|
|
|
|
- /* switch to single_cmd mode */
|
|
|
|
chip->single_cmd = 1;
|
|
chip->single_cmd = 1;
|
|
|
|
+ bus->response_reset = 0;
|
|
|
|
+ /* re-initialize CORB/RIRB */
|
|
azx_free_cmd_io(chip);
|
|
azx_free_cmd_io(chip);
|
|
|
|
+ azx_init_cmd_io(chip);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -667,12 +691,34 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
|
|
* I left the codes, however, for debugging/testing purposes.
|
|
* I left the codes, however, for debugging/testing purposes.
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
+/* receive a response */
|
|
|
|
+static int azx_single_wait_for_response(struct azx *chip)
|
|
|
|
+{
|
|
|
|
+ int timeout = 50;
|
|
|
|
+
|
|
|
|
+ while (timeout--) {
|
|
|
|
+ /* check IRV busy bit */
|
|
|
|
+ if (azx_readw(chip, IRS) & ICH6_IRS_VALID) {
|
|
|
|
+ /* reuse rirb.res as the response return value */
|
|
|
|
+ chip->rirb.res = azx_readl(chip, IR);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ udelay(1);
|
|
|
|
+ }
|
|
|
|
+ if (printk_ratelimit())
|
|
|
|
+ snd_printd(SFX "get_response timeout: IRS=0x%x\n",
|
|
|
|
+ azx_readw(chip, IRS));
|
|
|
|
+ chip->rirb.res = -1;
|
|
|
|
+ return -EIO;
|
|
|
|
+}
|
|
|
|
+
|
|
/* send a command */
|
|
/* send a command */
|
|
static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
|
|
static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
|
|
{
|
|
{
|
|
struct azx *chip = bus->private_data;
|
|
struct azx *chip = bus->private_data;
|
|
int timeout = 50;
|
|
int timeout = 50;
|
|
|
|
|
|
|
|
+ bus->rirb_error = 0;
|
|
while (timeout--) {
|
|
while (timeout--) {
|
|
/* check ICB busy bit */
|
|
/* check ICB busy bit */
|
|
if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) {
|
|
if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) {
|
|
@@ -682,7 +728,7 @@ static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
|
|
azx_writel(chip, IC, val);
|
|
azx_writel(chip, IC, val);
|
|
azx_writew(chip, IRS, azx_readw(chip, IRS) |
|
|
azx_writew(chip, IRS, azx_readw(chip, IRS) |
|
|
ICH6_IRS_BUSY);
|
|
ICH6_IRS_BUSY);
|
|
- return 0;
|
|
|
|
|
|
+ return azx_single_wait_for_response(chip);
|
|
}
|
|
}
|
|
udelay(1);
|
|
udelay(1);
|
|
}
|
|
}
|
|
@@ -696,18 +742,7 @@ static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
|
|
static unsigned int azx_single_get_response(struct hda_bus *bus)
|
|
static unsigned int azx_single_get_response(struct hda_bus *bus)
|
|
{
|
|
{
|
|
struct azx *chip = bus->private_data;
|
|
struct azx *chip = bus->private_data;
|
|
- int timeout = 50;
|
|
|
|
-
|
|
|
|
- while (timeout--) {
|
|
|
|
- /* check IRV busy bit */
|
|
|
|
- if (azx_readw(chip, IRS) & ICH6_IRS_VALID)
|
|
|
|
- return azx_readl(chip, IR);
|
|
|
|
- udelay(1);
|
|
|
|
- }
|
|
|
|
- if (printk_ratelimit())
|
|
|
|
- snd_printd(SFX "get_response timeout: IRS=0x%x\n",
|
|
|
|
- azx_readw(chip, IRS));
|
|
|
|
- return (unsigned int)-1;
|
|
|
|
|
|
+ return chip->rirb.res;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -775,17 +810,17 @@ static int azx_reset(struct azx *chip)
|
|
|
|
|
|
/* check to see if controller is ready */
|
|
/* check to see if controller is ready */
|
|
if (!azx_readb(chip, GCTL)) {
|
|
if (!azx_readb(chip, GCTL)) {
|
|
- snd_printd("azx_reset: controller not ready!\n");
|
|
|
|
|
|
+ snd_printd(SFX "azx_reset: controller not ready!\n");
|
|
return -EBUSY;
|
|
return -EBUSY;
|
|
}
|
|
}
|
|
|
|
|
|
/* Accept unsolicited responses */
|
|
/* Accept unsolicited responses */
|
|
- azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UREN);
|
|
|
|
|
|
+ azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UNSOL);
|
|
|
|
|
|
/* detect codecs */
|
|
/* detect codecs */
|
|
if (!chip->codec_mask) {
|
|
if (!chip->codec_mask) {
|
|
chip->codec_mask = azx_readw(chip, STATESTS);
|
|
chip->codec_mask = azx_readw(chip, STATESTS);
|
|
- snd_printdd("codec_mask = 0x%x\n", chip->codec_mask);
|
|
|
|
|
|
+ snd_printdd(SFX "codec_mask = 0x%x\n", chip->codec_mask);
|
|
}
|
|
}
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -895,8 +930,7 @@ static void azx_init_chip(struct azx *chip)
|
|
azx_int_enable(chip);
|
|
azx_int_enable(chip);
|
|
|
|
|
|
/* initialize the codec command I/O */
|
|
/* initialize the codec command I/O */
|
|
- if (!chip->single_cmd)
|
|
|
|
- azx_init_cmd_io(chip);
|
|
|
|
|
|
+ azx_init_cmd_io(chip);
|
|
|
|
|
|
/* program the position buffer */
|
|
/* program the position buffer */
|
|
azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
|
|
azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
|
|
@@ -953,12 +987,12 @@ static void azx_init_pci(struct azx *chip)
|
|
case AZX_DRIVER_SCH:
|
|
case AZX_DRIVER_SCH:
|
|
pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
|
|
pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
|
|
if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) {
|
|
if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) {
|
|
- pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, \
|
|
|
|
|
|
+ pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC,
|
|
snoop & (~INTEL_SCH_HDA_DEVC_NOSNOOP));
|
|
snoop & (~INTEL_SCH_HDA_DEVC_NOSNOOP));
|
|
pci_read_config_word(chip->pci,
|
|
pci_read_config_word(chip->pci,
|
|
INTEL_SCH_HDA_DEVC, &snoop);
|
|
INTEL_SCH_HDA_DEVC, &snoop);
|
|
- snd_printdd("HDA snoop disabled, enabling ... %s\n",\
|
|
|
|
- (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) \
|
|
|
|
|
|
+ snd_printdd(SFX "HDA snoop disabled, enabling ... %s\n",
|
|
|
|
+ (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)
|
|
? "Failed" : "OK");
|
|
? "Failed" : "OK");
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -1012,7 +1046,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
|
|
/* clear rirb int */
|
|
/* clear rirb int */
|
|
status = azx_readb(chip, RIRBSTS);
|
|
status = azx_readb(chip, RIRBSTS);
|
|
if (status & RIRB_INT_MASK) {
|
|
if (status & RIRB_INT_MASK) {
|
|
- if (!chip->single_cmd && (status & RIRB_INT_RESPONSE))
|
|
|
|
|
|
+ if (status & RIRB_INT_RESPONSE)
|
|
azx_update_rirb(chip);
|
|
azx_update_rirb(chip);
|
|
azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
|
|
azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
|
|
}
|
|
}
|
|
@@ -1098,7 +1132,7 @@ static int azx_setup_periods(struct azx *chip,
|
|
pos_align;
|
|
pos_align;
|
|
pos_adj = frames_to_bytes(runtime, pos_adj);
|
|
pos_adj = frames_to_bytes(runtime, pos_adj);
|
|
if (pos_adj >= period_bytes) {
|
|
if (pos_adj >= period_bytes) {
|
|
- snd_printk(KERN_WARNING "Too big adjustment %d\n",
|
|
|
|
|
|
+ snd_printk(KERN_WARNING SFX "Too big adjustment %d\n",
|
|
bdl_pos_adj[chip->dev_index]);
|
|
bdl_pos_adj[chip->dev_index]);
|
|
pos_adj = 0;
|
|
pos_adj = 0;
|
|
} else {
|
|
} else {
|
|
@@ -1122,7 +1156,7 @@ static int azx_setup_periods(struct azx *chip,
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
error:
|
|
error:
|
|
- snd_printk(KERN_ERR "Too many BDL entries: buffer=%d, period=%d\n",
|
|
|
|
|
|
+ snd_printk(KERN_ERR SFX "Too many BDL entries: buffer=%d, period=%d\n",
|
|
azx_dev->bufsize, period_bytes);
|
|
azx_dev->bufsize, period_bytes);
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
@@ -1215,7 +1249,7 @@ static int probe_codec(struct azx *chip, int addr)
|
|
chip->probing = 0;
|
|
chip->probing = 0;
|
|
if (res == -1)
|
|
if (res == -1)
|
|
return -EIO;
|
|
return -EIO;
|
|
- snd_printdd("hda_intel: codec #%d probed OK\n", addr);
|
|
|
|
|
|
+ snd_printdd(SFX "codec #%d probed OK\n", addr);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1223,6 +1257,26 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
|
|
struct hda_pcm *cpcm);
|
|
struct hda_pcm *cpcm);
|
|
static void azx_stop_chip(struct azx *chip);
|
|
static void azx_stop_chip(struct azx *chip);
|
|
|
|
|
|
|
|
+static void azx_bus_reset(struct hda_bus *bus)
|
|
|
|
+{
|
|
|
|
+ struct azx *chip = bus->private_data;
|
|
|
|
+
|
|
|
|
+ bus->in_reset = 1;
|
|
|
|
+ azx_stop_chip(chip);
|
|
|
|
+ azx_init_chip(chip);
|
|
|
|
+#ifdef CONFIG_PM
|
|
|
|
+ if (chip->initialized) {
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < AZX_MAX_PCMS; i++)
|
|
|
|
+ snd_pcm_suspend_all(chip->pcm[i]);
|
|
|
|
+ snd_hda_suspend(chip->bus);
|
|
|
|
+ snd_hda_resume(chip->bus);
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+ bus->in_reset = 0;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Codec initialization
|
|
* Codec initialization
|
|
*/
|
|
*/
|
|
@@ -1246,6 +1300,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
|
|
bus_temp.ops.command = azx_send_cmd;
|
|
bus_temp.ops.command = azx_send_cmd;
|
|
bus_temp.ops.get_response = azx_get_response;
|
|
bus_temp.ops.get_response = azx_get_response;
|
|
bus_temp.ops.attach_pcm = azx_attach_pcm_stream;
|
|
bus_temp.ops.attach_pcm = azx_attach_pcm_stream;
|
|
|
|
+ bus_temp.ops.bus_reset = azx_bus_reset;
|
|
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
|
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
|
bus_temp.power_save = &power_save;
|
|
bus_temp.power_save = &power_save;
|
|
bus_temp.ops.pm_notify = azx_power_notify;
|
|
bus_temp.ops.pm_notify = azx_power_notify;
|
|
@@ -1270,8 +1325,8 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
|
|
/* Some BIOSen give you wrong codec addresses
|
|
/* Some BIOSen give you wrong codec addresses
|
|
* that don't exist
|
|
* that don't exist
|
|
*/
|
|
*/
|
|
- snd_printk(KERN_WARNING
|
|
|
|
- "hda_intel: Codec #%d probe error; "
|
|
|
|
|
|
+ snd_printk(KERN_WARNING SFX
|
|
|
|
+ "Codec #%d probe error; "
|
|
"disabling it...\n", c);
|
|
"disabling it...\n", c);
|
|
chip->codec_mask &= ~(1 << c);
|
|
chip->codec_mask &= ~(1 << c);
|
|
/* More badly, accessing to a non-existing
|
|
/* More badly, accessing to a non-existing
|
|
@@ -1487,7 +1542,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
|
|
bufsize = snd_pcm_lib_buffer_bytes(substream);
|
|
bufsize = snd_pcm_lib_buffer_bytes(substream);
|
|
period_bytes = snd_pcm_lib_period_bytes(substream);
|
|
period_bytes = snd_pcm_lib_period_bytes(substream);
|
|
|
|
|
|
- snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n",
|
|
|
|
|
|
+ snd_printdd(SFX "azx_pcm_prepare: bufsize=0x%x, format=0x%x\n",
|
|
bufsize, format_val);
|
|
bufsize, format_val);
|
|
|
|
|
|
if (bufsize != azx_dev->bufsize ||
|
|
if (bufsize != azx_dev->bufsize ||
|
|
@@ -1830,7 +1885,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
|
|
&pcm);
|
|
&pcm);
|
|
if (err < 0)
|
|
if (err < 0)
|
|
return err;
|
|
return err;
|
|
- strcpy(pcm->name, cpcm->name);
|
|
|
|
|
|
+ strlcpy(pcm->name, cpcm->name, sizeof(pcm->name));
|
|
apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
|
|
apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
|
|
if (apcm == NULL)
|
|
if (apcm == NULL)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
@@ -1973,7 +2028,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
|
|
for (i = 0; i < AZX_MAX_PCMS; i++)
|
|
for (i = 0; i < AZX_MAX_PCMS; i++)
|
|
snd_pcm_suspend_all(chip->pcm[i]);
|
|
snd_pcm_suspend_all(chip->pcm[i]);
|
|
if (chip->initialized)
|
|
if (chip->initialized)
|
|
- snd_hda_suspend(chip->bus, state);
|
|
|
|
|
|
+ snd_hda_suspend(chip->bus);
|
|
azx_stop_chip(chip);
|
|
azx_stop_chip(chip);
|
|
if (chip->irq >= 0) {
|
|
if (chip->irq >= 0) {
|
|
free_irq(chip->irq, chip);
|
|
free_irq(chip->irq, chip);
|
|
@@ -2265,14 +2320,14 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
|
|
synchronize_irq(chip->irq);
|
|
synchronize_irq(chip->irq);
|
|
|
|
|
|
gcap = azx_readw(chip, GCAP);
|
|
gcap = azx_readw(chip, GCAP);
|
|
- snd_printdd("chipset global capabilities = 0x%x\n", gcap);
|
|
|
|
|
|
+ snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap);
|
|
|
|
|
|
/* ATI chips seems buggy about 64bit DMA addresses */
|
|
/* ATI chips seems buggy about 64bit DMA addresses */
|
|
if (chip->driver_type == AZX_DRIVER_ATI)
|
|
if (chip->driver_type == AZX_DRIVER_ATI)
|
|
- gcap &= ~0x01;
|
|
|
|
|
|
+ gcap &= ~ICH6_GCAP_64OK;
|
|
|
|
|
|
/* allow 64bit DMA address if supported by H/W */
|
|
/* allow 64bit DMA address if supported by H/W */
|
|
- if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
|
|
|
|
|
|
+ if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
|
|
pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
|
|
pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
|
|
else {
|
|
else {
|
|
pci_set_dma_mask(pci, DMA_BIT_MASK(32));
|
|
pci_set_dma_mask(pci, DMA_BIT_MASK(32));
|
|
@@ -2309,7 +2364,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
|
|
chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev),
|
|
chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev),
|
|
GFP_KERNEL);
|
|
GFP_KERNEL);
|
|
if (!chip->azx_dev) {
|
|
if (!chip->azx_dev) {
|
|
- snd_printk(KERN_ERR "cannot malloc azx_dev\n");
|
|
|
|
|
|
+ snd_printk(KERN_ERR SFX "cannot malloc azx_dev\n");
|
|
goto errout;
|
|
goto errout;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2332,11 +2387,9 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
|
|
goto errout;
|
|
goto errout;
|
|
}
|
|
}
|
|
/* allocate CORB/RIRB */
|
|
/* allocate CORB/RIRB */
|
|
- if (!chip->single_cmd) {
|
|
|
|
- err = azx_alloc_cmd_io(chip);
|
|
|
|
- if (err < 0)
|
|
|
|
- goto errout;
|
|
|
|
- }
|
|
|
|
|
|
+ err = azx_alloc_cmd_io(chip);
|
|
|
|
+ if (err < 0)
|
|
|
|
+ goto errout;
|
|
|
|
|
|
/* initialize streams */
|
|
/* initialize streams */
|
|
azx_init_stream(chip);
|
|
azx_init_stream(chip);
|
|
@@ -2359,9 +2412,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
|
|
}
|
|
}
|
|
|
|
|
|
strcpy(card->driver, "HDA-Intel");
|
|
strcpy(card->driver, "HDA-Intel");
|
|
- strcpy(card->shortname, driver_short_names[chip->driver_type]);
|
|
|
|
- sprintf(card->longname, "%s at 0x%lx irq %i",
|
|
|
|
- card->shortname, chip->addr, chip->irq);
|
|
|
|
|
|
+ strlcpy(card->shortname, driver_short_names[chip->driver_type],
|
|
|
|
+ sizeof(card->shortname));
|
|
|
|
+ snprintf(card->longname, sizeof(card->longname),
|
|
|
|
+ "%s at 0x%lx irq %i",
|
|
|
|
+ card->shortname, chip->addr, chip->irq);
|
|
|
|
|
|
*rchip = chip;
|
|
*rchip = chip;
|
|
return 0;
|
|
return 0;
|
|
@@ -2514,6 +2569,20 @@ static struct pci_device_id azx_ids[] = {
|
|
{ PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA },
|
|
{ PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA },
|
|
/* Teradici */
|
|
/* Teradici */
|
|
{ PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
|
|
{ PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
|
|
|
|
+ /* Creative X-Fi (CA0110-IBG) */
|
|
|
|
+#if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE)
|
|
|
|
+ /* the following entry conflicts with snd-ctxfi driver,
|
|
|
|
+ * as ctxfi driver mutates from HD-audio to native mode with
|
|
|
|
+ * a special command sequence.
|
|
|
|
+ */
|
|
|
|
+ { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID),
|
|
|
|
+ .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
|
|
|
|
+ .class_mask = 0xffffff,
|
|
|
|
+ .driver_data = AZX_DRIVER_GENERIC },
|
|
|
|
+#else
|
|
|
|
+ /* this entry seems still valid -- i.e. without emu20kx chip */
|
|
|
|
+ { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_GENERIC },
|
|
|
|
+#endif
|
|
/* AMD Generic, PCI class code and Vendor ID for HD Audio */
|
|
/* AMD Generic, PCI class code and Vendor ID for HD Audio */
|
|
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
|
|
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
|
|
.class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
|
|
.class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
|