Commit 14d34f16 authored by Takashi Iwai's avatar Takashi Iwai

ALSA: hda - Add some workarounds for Creative IBG

Creative HD-audio controller chips require some workarounds:
 - Additional delay before RIRB response
 - Set the initial RIRB counter to 0xc0

The latter seems to be done in general in Windows driver, so we may
use this value later for all types if it's confirmed to work better.
Reported-by: default avatarWai Yew CHAY <wychay@ctl.creative.com>
Cc: <stable@kernel.org>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 24b55c69
...@@ -458,6 +458,7 @@ enum { ...@@ -458,6 +458,7 @@ enum {
AZX_DRIVER_ULI, AZX_DRIVER_ULI,
AZX_DRIVER_NVIDIA, AZX_DRIVER_NVIDIA,
AZX_DRIVER_TERA, AZX_DRIVER_TERA,
AZX_DRIVER_CTX,
AZX_DRIVER_GENERIC, AZX_DRIVER_GENERIC,
AZX_NUM_DRIVERS, /* keep this as last entry */ AZX_NUM_DRIVERS, /* keep this as last entry */
}; };
...@@ -473,6 +474,7 @@ static char *driver_short_names[] __devinitdata = { ...@@ -473,6 +474,7 @@ static char *driver_short_names[] __devinitdata = {
[AZX_DRIVER_ULI] = "HDA ULI M5461", [AZX_DRIVER_ULI] = "HDA ULI M5461",
[AZX_DRIVER_NVIDIA] = "HDA NVidia", [AZX_DRIVER_NVIDIA] = "HDA NVidia",
[AZX_DRIVER_TERA] = "HDA Teradici", [AZX_DRIVER_TERA] = "HDA Teradici",
[AZX_DRIVER_CTX] = "HDA Creative",
[AZX_DRIVER_GENERIC] = "HD-Audio Generic", [AZX_DRIVER_GENERIC] = "HD-Audio Generic",
}; };
...@@ -563,6 +565,9 @@ static void azx_init_cmd_io(struct azx *chip) ...@@ -563,6 +565,9 @@ static void azx_init_cmd_io(struct azx *chip)
/* reset the rirb hw write pointer */ /* reset the rirb hw write pointer */
azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST); 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 */
if (chip->driver_type == AZX_DRIVER_CTX)
azx_writew(chip, RINTCNT, 0xc0);
else
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);
...@@ -1136,8 +1141,11 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) ...@@ -1136,8 +1141,11 @@ 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 (status & RIRB_INT_RESPONSE) if (status & RIRB_INT_RESPONSE) {
if (chip->driver_type == AZX_DRIVER_CTX)
udelay(80);
azx_update_rirb(chip); azx_update_rirb(chip);
}
azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
} }
...@@ -2784,10 +2792,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { ...@@ -2784,10 +2792,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID), { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID),
.class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
.class_mask = 0xffffff, .class_mask = 0xffffff,
.driver_data = AZX_DRIVER_GENERIC }, .driver_data = AZX_DRIVER_CTX },
#else #else
/* this entry seems still valid -- i.e. without emu20kx chip */ /* this entry seems still valid -- i.e. without emu20kx chip */
{ PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_GENERIC }, { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_CTX },
#endif #endif
/* Vortex86MX */ /* Vortex86MX */
{ PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment