[ALSA] snd-hda-intel: Improve azx_position_ok()
authorJaroslav Kysela <perex@perex.cz>
Tue, 11 May 2010 10:10:47 +0000 (12:10 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 11 May 2010 10:17:55 +0000 (12:17 +0200)
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>
sound/pci/hda/hda_intel.c

index 0a6c55bb7d6b88ac3c9b1c39d40f715d55f3c3a1..170610e1d7da4d8a2a89bf46ae01085743dee840 100644 (file)
@@ -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 */
 }