[ALSA] intel8x0: add one retry to the ac97_clock measurement routine
authorJaroslav Kysela <perex@perex.cz>
Wed, 15 Apr 2009 08:16:24 +0000 (10:16 +0200)
committerJaroslav Kysela <perex@perex.cz>
Wed, 15 Apr 2009 08:16:24 +0000 (10:16 +0200)
It seems that on some hardware platforms, the first measurement is wrong.
This patch adds second measurement to this case.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
sound/pci/intel8x0.c

index 10f8609e9c6ecc2eb49ea1910efac94befa56a93..5dced5b793873409f32bd20f3e06588de8dfb662 100644 (file)
@@ -2676,12 +2676,13 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip)
        struct ichdev *ichdev;
        unsigned long port;
        unsigned long pos, pos1, t;
-       int civ, timeout = 1000;
+       int civ, timeout = 1000, attempt = 1;
        struct timespec start_time, stop_time;
 
        if (chip->ac97_bus->clock != 48000)
                return; /* specified in module option */
 
+      __again:
        subs = chip->pcm[0]->streams[0].substream;
        if (! subs || subs->dma_buffer.bytes < INTEL8X0_TESTBUF_SIZE) {
                snd_printk(KERN_WARNING "no playback buffer allocated - aborting measure ac97 clock\n");
@@ -2749,6 +2750,11 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip)
 
        if (pos == 0) {
                snd_printk(KERN_ERR "intel8x0: measure - unreliable DMA position..\n");
+             __retry:
+               if (attempt < 2) {
+                       attempt++;
+                       goto __again;
+               }
                return;
        }
 
@@ -2759,14 +2765,15 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip)
        printk(KERN_INFO "%s: measured %lu usecs (%lu samples)\n", __func__, t, pos);
        if (t == 0) {
                snd_printk(KERN_ERR "intel8x0: ?? calculation error..\n");
-               return;
+               goto __retry;
        }
        pos *= 1000;
        pos = (pos / t) * 1000 + ((pos % t) * 1000) / t;
-       if (pos < 40000 || pos >= 60000) 
+       if (pos < 40000 || pos >= 60000) {
                /* abnormal value. hw problem? */
                printk(KERN_INFO "intel8x0: measured clock %ld rejected\n", pos);
-       else if (pos > 40500 && pos < 41500)
+               goto __retry;
+       } else if (pos > 40500 && pos < 41500)
                /* first exception - 41000Hz reference clock */
                chip->ac97_bus->clock = 41000;
        else if (pos > 43600 && pos < 44600)