diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 236b4caa142fa5bc3dad8ecaf770425732ea52f8..cad9b70c27a06cdc3c380f87ae40371b47e860ae 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -425,7 +425,7 @@ struct azx { struct snd_dma_buffer posbuf; /* flags */ - int position_fix; + int position_fix[2]; /* for both playback/capture streams */ int poll_count; unsigned int running :1; unsigned int initialized :1; @@ -1306,8 +1306,10 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) azx_sd_writel(azx_dev, SD_BDLPU, upper_32_bits(azx_dev->bdl.addr)); /* enable the position buffer */ - if (chip->position_fix == POS_FIX_POSBUF || - chip->position_fix == POS_FIX_AUTO || + if (chip->position_fix[0] == POS_FIX_POSBUF || + chip->position_fix[0] == POS_FIX_AUTO || + chip->position_fix[1] == POS_FIX_POSBUF || + chip->position_fix[1] == POS_FIX_AUTO || chip->via_dmapos_patch) { if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) azx_writel(chip, DPLBASE, @@ -1847,13 +1849,16 @@ static unsigned int azx_get_position(struct azx *chip, if (chip->via_dmapos_patch) pos = azx_via_get_position(chip, azx_dev); - else if (chip->position_fix == POS_FIX_POSBUF || - chip->position_fix == POS_FIX_AUTO) { - /* use the position buffer */ - pos = le32_to_cpu(*azx_dev->posbuf); - } else { - /* read LPIB */ - pos = azx_sd_readl(azx_dev, SD_LPIB); + else { + int stream = azx_dev->substream->stream; + if (chip->position_fix[stream] == POS_FIX_POSBUF || + chip->position_fix[stream] == POS_FIX_AUTO) { + /* use the position buffer */ + pos = le32_to_cpu(*azx_dev->posbuf); + } else { + /* read LPIB */ + pos = azx_sd_readl(azx_dev, SD_LPIB); + } } if (pos >= azx_dev->bufsize) pos = 0; @@ -1881,22 +1886,24 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream) static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) { unsigned int pos; + int stream; if (azx_dev->start_flag && time_before_eq(jiffies, azx_dev->start_jiffies)) return -1; /* bogus (too early) interrupt */ azx_dev->start_flag = 0; + stream = azx_dev->substream->stream; pos = azx_get_position(chip, azx_dev); - if (chip->position_fix == POS_FIX_AUTO) { + if (chip->position_fix[stream] == POS_FIX_AUTO) { if (!pos) { printk(KERN_WARNING "hda-intel: Invalid position buffer, " "using LPIB read method instead.\n"); - chip->position_fix = POS_FIX_LPIB; + chip->position_fix[stream] = POS_FIX_LPIB; pos = azx_get_position(chip, azx_dev); } else - chip->position_fix = POS_FIX_POSBUF; + chip->position_fix[stream] = POS_FIX_POSBUF; } if (!bdl_pos_adj[chip->dev_index]) @@ -2435,7 +2442,8 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, chip->dev_index = dev; INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); - chip->position_fix = check_position_fix(chip, position_fix[dev]); + chip->position_fix[0] = chip->position_fix[1] = + check_position_fix(chip, position_fix[dev]); check_probe_mask(chip, dev); chip->single_cmd = single_cmd;