浏览代码

[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>
Jaroslav Kysela 15 年之前
父节点
当前提交
f48f606d9f
共有 1 个文件被更改,包括 7 次插入6 次删除
  1. 7 6
      sound/pci/hda/hda_intel.c

+ 7 - 6
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 */
 }