Merge branch 'fix/hda' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'fix/hda' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: ALSA: hda - Read buffer overflow ALSA: hda: Correct EAPD for Dell Inspiron 1525 ALSA: hda: warn on spurious response ALSA: hda: remember last command for each codec ALSA: hda: read CORBWP inside reg_lock ALSA: hda: take reg_lock in azx_init_cmd_io/azx_free_cmd_io ALSA: hda: take cmd_mutex in probe_codec() ALSA: hda: track CIRB/CORB command/response states for each codec ALSA: hda - Fix quirk for Toshiba Satellite A135-S4527
This commit is contained in:
commit
6ce90c430b
|
@ -174,7 +174,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
|
||||||
mutex_lock(&bus->cmd_mutex);
|
mutex_lock(&bus->cmd_mutex);
|
||||||
err = bus->ops.command(bus, cmd);
|
err = bus->ops.command(bus, cmd);
|
||||||
if (!err && res)
|
if (!err && res)
|
||||||
*res = bus->ops.get_response(bus);
|
*res = bus->ops.get_response(bus, codec->addr);
|
||||||
mutex_unlock(&bus->cmd_mutex);
|
mutex_unlock(&bus->cmd_mutex);
|
||||||
snd_hda_power_down(codec);
|
snd_hda_power_down(codec);
|
||||||
if (res && *res == -1 && bus->rirb_error) {
|
if (res && *res == -1 && bus->rirb_error) {
|
||||||
|
|
|
@ -568,7 +568,7 @@ struct hda_bus_ops {
|
||||||
/* send a single command */
|
/* send a single command */
|
||||||
int (*command)(struct hda_bus *bus, unsigned int cmd);
|
int (*command)(struct hda_bus *bus, unsigned int cmd);
|
||||||
/* get a response from the last command */
|
/* get a response from the last command */
|
||||||
unsigned int (*get_response)(struct hda_bus *bus);
|
unsigned int (*get_response)(struct hda_bus *bus, unsigned int addr);
|
||||||
/* free the private data */
|
/* free the private data */
|
||||||
void (*private_free)(struct hda_bus *);
|
void (*private_free)(struct hda_bus *);
|
||||||
/* attach a PCM stream */
|
/* attach a PCM stream */
|
||||||
|
|
|
@ -253,7 +253,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
|
||||||
|
|
||||||
/* STATESTS int mask: S3,SD2,SD1,SD0 */
|
/* STATESTS int mask: S3,SD2,SD1,SD0 */
|
||||||
#define AZX_MAX_CODECS 4
|
#define AZX_MAX_CODECS 4
|
||||||
#define STATESTS_INT_MASK 0x0f
|
#define STATESTS_INT_MASK ((1 << AZX_MAX_CODECS) - 1)
|
||||||
|
|
||||||
/* SD_CTL bits */
|
/* SD_CTL bits */
|
||||||
#define SD_CTL_STREAM_RESET 0x01 /* stream reset bit */
|
#define SD_CTL_STREAM_RESET 0x01 /* stream reset bit */
|
||||||
|
@ -361,8 +361,8 @@ struct azx_rb {
|
||||||
dma_addr_t addr; /* physical address of CORB/RIRB buffer */
|
dma_addr_t addr; /* physical address of CORB/RIRB buffer */
|
||||||
/* for RIRB */
|
/* for RIRB */
|
||||||
unsigned short rp, wp; /* read/write pointers */
|
unsigned short rp, wp; /* read/write pointers */
|
||||||
int cmds; /* number of pending requests */
|
int cmds[AZX_MAX_CODECS]; /* number of pending requests */
|
||||||
u32 res; /* last read value */
|
u32 res[AZX_MAX_CODECS]; /* last read value */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct azx {
|
struct azx {
|
||||||
|
@ -418,7 +418,7 @@ struct azx {
|
||||||
unsigned int probing :1; /* codec probing phase */
|
unsigned int probing :1; /* codec probing phase */
|
||||||
|
|
||||||
/* for debugging */
|
/* for debugging */
|
||||||
unsigned int last_cmd; /* last issued command (to sync) */
|
unsigned int last_cmd[AZX_MAX_CODECS];
|
||||||
|
|
||||||
/* for pending irqs */
|
/* for pending irqs */
|
||||||
struct work_struct irq_pending_work;
|
struct work_struct irq_pending_work;
|
||||||
|
@ -513,6 +513,7 @@ static int azx_alloc_cmd_io(struct azx *chip)
|
||||||
|
|
||||||
static void azx_init_cmd_io(struct azx *chip)
|
static void azx_init_cmd_io(struct azx *chip)
|
||||||
{
|
{
|
||||||
|
spin_lock_irq(&chip->reg_lock);
|
||||||
/* CORB set up */
|
/* CORB set up */
|
||||||
chip->corb.addr = chip->rb.addr;
|
chip->corb.addr = chip->rb.addr;
|
||||||
chip->corb.buf = (u32 *)chip->rb.area;
|
chip->corb.buf = (u32 *)chip->rb.area;
|
||||||
|
@ -531,7 +532,8 @@ static void azx_init_cmd_io(struct azx *chip)
|
||||||
/* 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;
|
chip->rirb.wp = chip->rirb.rp = 0;
|
||||||
|
memset(chip->rirb.cmds, 0, sizeof(chip->rirb.cmds));
|
||||||
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));
|
||||||
|
|
||||||
|
@ -543,30 +545,60 @@ static void azx_init_cmd_io(struct azx *chip)
|
||||||
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);
|
||||||
|
spin_unlock_irq(&chip->reg_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void azx_free_cmd_io(struct azx *chip)
|
static void azx_free_cmd_io(struct azx *chip)
|
||||||
{
|
{
|
||||||
|
spin_lock_irq(&chip->reg_lock);
|
||||||
/* disable ringbuffer DMAs */
|
/* disable ringbuffer DMAs */
|
||||||
azx_writeb(chip, RIRBCTL, 0);
|
azx_writeb(chip, RIRBCTL, 0);
|
||||||
azx_writeb(chip, CORBCTL, 0);
|
azx_writeb(chip, CORBCTL, 0);
|
||||||
|
spin_unlock_irq(&chip->reg_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int azx_command_addr(u32 cmd)
|
||||||
|
{
|
||||||
|
unsigned int addr = cmd >> 28;
|
||||||
|
|
||||||
|
if (addr >= AZX_MAX_CODECS) {
|
||||||
|
snd_BUG();
|
||||||
|
addr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int azx_response_addr(u32 res)
|
||||||
|
{
|
||||||
|
unsigned int addr = res & 0xf;
|
||||||
|
|
||||||
|
if (addr >= AZX_MAX_CODECS) {
|
||||||
|
snd_BUG();
|
||||||
|
addr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send a command */
|
/* send a command */
|
||||||
static int azx_corb_send_cmd(struct hda_bus *bus, u32 val)
|
static int azx_corb_send_cmd(struct hda_bus *bus, u32 val)
|
||||||
{
|
{
|
||||||
struct azx *chip = bus->private_data;
|
struct azx *chip = bus->private_data;
|
||||||
|
unsigned int addr = azx_command_addr(val);
|
||||||
unsigned int wp;
|
unsigned int wp;
|
||||||
|
|
||||||
|
spin_lock_irq(&chip->reg_lock);
|
||||||
|
|
||||||
/* add command to corb */
|
/* add command to corb */
|
||||||
wp = azx_readb(chip, CORBWP);
|
wp = azx_readb(chip, CORBWP);
|
||||||
wp++;
|
wp++;
|
||||||
wp %= ICH6_MAX_CORB_ENTRIES;
|
wp %= ICH6_MAX_CORB_ENTRIES;
|
||||||
|
|
||||||
spin_lock_irq(&chip->reg_lock);
|
chip->rirb.cmds[addr]++;
|
||||||
chip->rirb.cmds++;
|
|
||||||
chip->corb.buf[wp] = cpu_to_le32(val);
|
chip->corb.buf[wp] = cpu_to_le32(val);
|
||||||
azx_writel(chip, CORBWP, wp);
|
azx_writel(chip, CORBWP, wp);
|
||||||
|
|
||||||
spin_unlock_irq(&chip->reg_lock);
|
spin_unlock_irq(&chip->reg_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -578,13 +610,14 @@ static int azx_corb_send_cmd(struct hda_bus *bus, u32 val)
|
||||||
static void azx_update_rirb(struct azx *chip)
|
static void azx_update_rirb(struct azx *chip)
|
||||||
{
|
{
|
||||||
unsigned int rp, wp;
|
unsigned int rp, wp;
|
||||||
|
unsigned int addr;
|
||||||
u32 res, res_ex;
|
u32 res, res_ex;
|
||||||
|
|
||||||
wp = azx_readb(chip, RIRBWP);
|
wp = azx_readb(chip, RIRBWP);
|
||||||
if (wp == chip->rirb.wp)
|
if (wp == chip->rirb.wp)
|
||||||
return;
|
return;
|
||||||
chip->rirb.wp = wp;
|
chip->rirb.wp = wp;
|
||||||
|
|
||||||
while (chip->rirb.rp != wp) {
|
while (chip->rirb.rp != wp) {
|
||||||
chip->rirb.rp++;
|
chip->rirb.rp++;
|
||||||
chip->rirb.rp %= ICH6_MAX_RIRB_ENTRIES;
|
chip->rirb.rp %= ICH6_MAX_RIRB_ENTRIES;
|
||||||
|
@ -592,18 +625,24 @@ static void azx_update_rirb(struct azx *chip)
|
||||||
rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */
|
rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */
|
||||||
res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]);
|
res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]);
|
||||||
res = le32_to_cpu(chip->rirb.buf[rp]);
|
res = le32_to_cpu(chip->rirb.buf[rp]);
|
||||||
|
addr = azx_response_addr(res_ex);
|
||||||
if (res_ex & ICH6_RIRB_EX_UNSOL_EV)
|
if (res_ex & ICH6_RIRB_EX_UNSOL_EV)
|
||||||
snd_hda_queue_unsol_event(chip->bus, res, res_ex);
|
snd_hda_queue_unsol_event(chip->bus, res, res_ex);
|
||||||
else if (chip->rirb.cmds) {
|
else if (chip->rirb.cmds[addr]) {
|
||||||
chip->rirb.res = res;
|
chip->rirb.res[addr] = res;
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
chip->rirb.cmds--;
|
chip->rirb.cmds[addr]--;
|
||||||
}
|
} else
|
||||||
|
snd_printk(KERN_ERR SFX "spurious response %#x:%#x, "
|
||||||
|
"last cmd=%#08x\n",
|
||||||
|
res, res_ex,
|
||||||
|
chip->last_cmd[addr]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* receive a response */
|
/* receive a response */
|
||||||
static unsigned int azx_rirb_get_response(struct hda_bus *bus)
|
static unsigned int azx_rirb_get_response(struct hda_bus *bus,
|
||||||
|
unsigned int addr)
|
||||||
{
|
{
|
||||||
struct azx *chip = bus->private_data;
|
struct azx *chip = bus->private_data;
|
||||||
unsigned long timeout;
|
unsigned long timeout;
|
||||||
|
@ -616,10 +655,10 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
|
||||||
azx_update_rirb(chip);
|
azx_update_rirb(chip);
|
||||||
spin_unlock_irq(&chip->reg_lock);
|
spin_unlock_irq(&chip->reg_lock);
|
||||||
}
|
}
|
||||||
if (!chip->rirb.cmds) {
|
if (!chip->rirb.cmds[addr]) {
|
||||||
smp_rmb();
|
smp_rmb();
|
||||||
bus->rirb_error = 0;
|
bus->rirb_error = 0;
|
||||||
return chip->rirb.res; /* the last value */
|
return chip->rirb.res[addr]; /* the last value */
|
||||||
}
|
}
|
||||||
if (time_after(jiffies, timeout))
|
if (time_after(jiffies, timeout))
|
||||||
break;
|
break;
|
||||||
|
@ -633,7 +672,8 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
|
||||||
|
|
||||||
if (chip->msi) {
|
if (chip->msi) {
|
||||||
snd_printk(KERN_WARNING SFX "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[addr]);
|
||||||
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);
|
||||||
|
@ -648,7 +688,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
|
||||||
if (!chip->polling_mode) {
|
if (!chip->polling_mode) {
|
||||||
snd_printk(KERN_WARNING SFX "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[addr]);
|
||||||
chip->polling_mode = 1;
|
chip->polling_mode = 1;
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
@ -672,7 +712,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
|
||||||
|
|
||||||
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[addr]);
|
||||||
chip->single_cmd = 1;
|
chip->single_cmd = 1;
|
||||||
bus->response_reset = 0;
|
bus->response_reset = 0;
|
||||||
/* re-initialize CORB/RIRB */
|
/* re-initialize CORB/RIRB */
|
||||||
|
@ -692,7 +732,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* receive a response */
|
/* receive a response */
|
||||||
static int azx_single_wait_for_response(struct azx *chip)
|
static int azx_single_wait_for_response(struct azx *chip, unsigned int addr)
|
||||||
{
|
{
|
||||||
int timeout = 50;
|
int timeout = 50;
|
||||||
|
|
||||||
|
@ -700,7 +740,7 @@ static int azx_single_wait_for_response(struct azx *chip)
|
||||||
/* check IRV busy bit */
|
/* check IRV busy bit */
|
||||||
if (azx_readw(chip, IRS) & ICH6_IRS_VALID) {
|
if (azx_readw(chip, IRS) & ICH6_IRS_VALID) {
|
||||||
/* reuse rirb.res as the response return value */
|
/* reuse rirb.res as the response return value */
|
||||||
chip->rirb.res = azx_readl(chip, IR);
|
chip->rirb.res[addr] = azx_readl(chip, IR);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
udelay(1);
|
udelay(1);
|
||||||
|
@ -708,7 +748,7 @@ static int azx_single_wait_for_response(struct azx *chip)
|
||||||
if (printk_ratelimit())
|
if (printk_ratelimit())
|
||||||
snd_printd(SFX "get_response timeout: IRS=0x%x\n",
|
snd_printd(SFX "get_response timeout: IRS=0x%x\n",
|
||||||
azx_readw(chip, IRS));
|
azx_readw(chip, IRS));
|
||||||
chip->rirb.res = -1;
|
chip->rirb.res[addr] = -1;
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,6 +756,7 @@ static int azx_single_wait_for_response(struct azx *chip)
|
||||||
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;
|
||||||
|
unsigned int addr = azx_command_addr(val);
|
||||||
int timeout = 50;
|
int timeout = 50;
|
||||||
|
|
||||||
bus->rirb_error = 0;
|
bus->rirb_error = 0;
|
||||||
|
@ -728,7 +769,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 azx_single_wait_for_response(chip);
|
return azx_single_wait_for_response(chip, addr);
|
||||||
}
|
}
|
||||||
udelay(1);
|
udelay(1);
|
||||||
}
|
}
|
||||||
|
@ -739,10 +780,11 @@ static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* receive a response */
|
/* receive a response */
|
||||||
static unsigned int azx_single_get_response(struct hda_bus *bus)
|
static unsigned int azx_single_get_response(struct hda_bus *bus,
|
||||||
|
unsigned int addr)
|
||||||
{
|
{
|
||||||
struct azx *chip = bus->private_data;
|
struct azx *chip = bus->private_data;
|
||||||
return chip->rirb.res;
|
return chip->rirb.res[addr];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -757,7 +799,7 @@ static int azx_send_cmd(struct hda_bus *bus, unsigned int val)
|
||||||
{
|
{
|
||||||
struct azx *chip = bus->private_data;
|
struct azx *chip = bus->private_data;
|
||||||
|
|
||||||
chip->last_cmd = val;
|
chip->last_cmd[azx_command_addr(val)] = val;
|
||||||
if (chip->single_cmd)
|
if (chip->single_cmd)
|
||||||
return azx_single_send_cmd(bus, val);
|
return azx_single_send_cmd(bus, val);
|
||||||
else
|
else
|
||||||
|
@ -765,13 +807,14 @@ static int azx_send_cmd(struct hda_bus *bus, unsigned int val)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get a response */
|
/* get a response */
|
||||||
static unsigned int azx_get_response(struct hda_bus *bus)
|
static unsigned int azx_get_response(struct hda_bus *bus,
|
||||||
|
unsigned int addr)
|
||||||
{
|
{
|
||||||
struct azx *chip = bus->private_data;
|
struct azx *chip = bus->private_data;
|
||||||
if (chip->single_cmd)
|
if (chip->single_cmd)
|
||||||
return azx_single_get_response(bus);
|
return azx_single_get_response(bus, addr);
|
||||||
else
|
else
|
||||||
return azx_rirb_get_response(bus);
|
return azx_rirb_get_response(bus, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||||
|
@ -1243,10 +1286,12 @@ static int probe_codec(struct azx *chip, int addr)
|
||||||
(AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
|
(AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
|
||||||
unsigned int res;
|
unsigned int res;
|
||||||
|
|
||||||
|
mutex_lock(&chip->bus->cmd_mutex);
|
||||||
chip->probing = 1;
|
chip->probing = 1;
|
||||||
azx_send_cmd(chip->bus, cmd);
|
azx_send_cmd(chip->bus, cmd);
|
||||||
res = azx_get_response(chip->bus);
|
res = azx_get_response(chip->bus, addr);
|
||||||
chip->probing = 0;
|
chip->probing = 0;
|
||||||
|
mutex_unlock(&chip->bus->cmd_mutex);
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
snd_printdd(SFX "codec #%d probed OK\n", addr);
|
snd_printdd(SFX "codec #%d probed OK\n", addr);
|
||||||
|
|
|
@ -559,7 +559,7 @@ static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
|
||||||
|
|
||||||
/* Find enumerated value for current pinctl setting */
|
/* Find enumerated value for current pinctl setting */
|
||||||
i = alc_pin_mode_min(dir);
|
i = alc_pin_mode_min(dir);
|
||||||
while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
|
while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
|
||||||
i++;
|
i++;
|
||||||
*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
|
*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -15157,7 +15157,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
|
SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
|
||||||
SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
|
SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
|
||||||
/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
|
/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
|
||||||
SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
|
SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
|
||||||
SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
|
SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
|
||||||
SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
|
SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
|
||||||
SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
|
SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
|
||||||
|
|
|
@ -2266,7 +2266,7 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
|
||||||
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
|
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
|
||||||
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
|
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
|
||||||
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS),
|
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS),
|
||||||
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_3ST),
|
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS),
|
||||||
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
|
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
|
||||||
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
|
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
|
||||||
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
|
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
|
||||||
|
@ -5645,6 +5645,13 @@ static int patch_stac927x(struct hda_codec *codec)
|
||||||
/* GPIO2 High = Enable EAPD */
|
/* GPIO2 High = Enable EAPD */
|
||||||
spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x04;
|
spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x04;
|
||||||
spec->gpio_data = 0x04;
|
spec->gpio_data = 0x04;
|
||||||
|
switch (codec->subsystem_id) {
|
||||||
|
case 0x1028022f:
|
||||||
|
/* correct EAPD to be GPIO0 */
|
||||||
|
spec->eapd_mask = spec->gpio_mask = 0x01;
|
||||||
|
spec->gpio_dir = spec->gpio_data = 0x01;
|
||||||
|
break;
|
||||||
|
};
|
||||||
spec->dmic_nids = stac927x_dmic_nids;
|
spec->dmic_nids = stac927x_dmic_nids;
|
||||||
spec->num_dmics = STAC927X_NUM_DMICS;
|
spec->num_dmics = STAC927X_NUM_DMICS;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue