aboutsummaryrefslogtreecommitdiff
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2010-05-11 12:10:47 +0200
committerJaroslav Kysela <perex@perex.cz>2010-05-11 12:17:55 +0200
commitf48f606d9f85a8b25c716082c73c36e9ff6f0cde (patch)
tree3c3cf4754a49d9bdc5f3bd648b53860dbc696ab5 /sound/pci/hda
parente54637205b00837bf00de916b0ae361c6aa0b139 (diff)
[ALSA] snd-hda-intel: Improve azx_position_ok()
Add back the zero return value (activate workqueue) when bdl_pos_adj is nonzero for position check. Do the position related check only for first next period using wallclk counter. Return -1 value (ignore interrupt) when period_bytes variable is zero. Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/hda_intel.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 0a6c55bb7d6..170610e1d7d 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1890,9 +1890,8 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
unsigned int pos;
int stream;
- wallclk = azx_readl(chip, WALLCLK);
- if ((wallclk - azx_dev->start_wallclk) <
- (azx_dev->period_wallclk * 2) / 3)
+ wallclk = azx_readl(chip, WALLCLK) - azx_dev->start_wallclk;
+ if (wallclk < (azx_dev->period_wallclk * 2) / 3)
return -1; /* bogus (too early) interrupt */
stream = azx_dev->substream->stream;
@@ -1910,9 +1909,11 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
if (WARN_ONCE(!azx_dev->period_bytes,
"hda-intel: zero azx_dev->period_bytes"))
- return 0; /* this shouldn't happen! */
- if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2)
- return 0; /* NG - it's below the period boundary */
+ return -1; /* this shouldn't happen! */
+ if (wallclk <= azx_dev->period_wallclk &&
+ pos % azx_dev->period_bytes > azx_dev->period_bytes / 2)
+ /* NG - it's below the first next period boundary */
+ return bdl_pos_adj[chip->dev_index] ? 0 : -1;
azx_dev->start_wallclk = wallclk;
return 1; /* OK, it's fine */
}