diff options
author | Jaroslav Kysela <perex@perex.cz> | 2009-04-15 04:16:24 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2009-04-15 04:16:24 -0400 |
commit | 2ec775e7053c82bc90858ede011b35aeb416995b (patch) | |
tree | e0bbf9da43c2296eafc7d4c010669eb07c6132cb /sound/pci/intel8x0.c | |
parent | 29dab4fd3176e25dfab6cd763beb02d87973c288 (diff) |
[ALSA] intel8x0: add one retry to the ac97_clock measurement routine
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>
Diffstat (limited to 'sound/pci/intel8x0.c')
-rw-r--r-- | sound/pci/intel8x0.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 10f8609e9c6e..5dced5b79387 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -2676,12 +2676,13 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) | |||
2676 | struct ichdev *ichdev; | 2676 | struct ichdev *ichdev; |
2677 | unsigned long port; | 2677 | unsigned long port; |
2678 | unsigned long pos, pos1, t; | 2678 | unsigned long pos, pos1, t; |
2679 | int civ, timeout = 1000; | 2679 | int civ, timeout = 1000, attempt = 1; |
2680 | struct timespec start_time, stop_time; | 2680 | struct timespec start_time, stop_time; |
2681 | 2681 | ||
2682 | if (chip->ac97_bus->clock != 48000) | 2682 | if (chip->ac97_bus->clock != 48000) |
2683 | return; /* specified in module option */ | 2683 | return; /* specified in module option */ |
2684 | 2684 | ||
2685 | __again: | ||
2685 | subs = chip->pcm[0]->streams[0].substream; | 2686 | subs = chip->pcm[0]->streams[0].substream; |
2686 | if (! subs || subs->dma_buffer.bytes < INTEL8X0_TESTBUF_SIZE) { | 2687 | if (! subs || subs->dma_buffer.bytes < INTEL8X0_TESTBUF_SIZE) { |
2687 | snd_printk(KERN_WARNING "no playback buffer allocated - aborting measure ac97 clock\n"); | 2688 | 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) | |||
2749 | 2750 | ||
2750 | if (pos == 0) { | 2751 | if (pos == 0) { |
2751 | snd_printk(KERN_ERR "intel8x0: measure - unreliable DMA position..\n"); | 2752 | snd_printk(KERN_ERR "intel8x0: measure - unreliable DMA position..\n"); |
2753 | __retry: | ||
2754 | if (attempt < 2) { | ||
2755 | attempt++; | ||
2756 | goto __again; | ||
2757 | } | ||
2752 | return; | 2758 | return; |
2753 | } | 2759 | } |
2754 | 2760 | ||
@@ -2759,14 +2765,15 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) | |||
2759 | printk(KERN_INFO "%s: measured %lu usecs (%lu samples)\n", __func__, t, pos); | 2765 | printk(KERN_INFO "%s: measured %lu usecs (%lu samples)\n", __func__, t, pos); |
2760 | if (t == 0) { | 2766 | if (t == 0) { |
2761 | snd_printk(KERN_ERR "intel8x0: ?? calculation error..\n"); | 2767 | snd_printk(KERN_ERR "intel8x0: ?? calculation error..\n"); |
2762 | return; | 2768 | goto __retry; |
2763 | } | 2769 | } |
2764 | pos *= 1000; | 2770 | pos *= 1000; |
2765 | pos = (pos / t) * 1000 + ((pos % t) * 1000) / t; | 2771 | pos = (pos / t) * 1000 + ((pos % t) * 1000) / t; |
2766 | if (pos < 40000 || pos >= 60000) | 2772 | if (pos < 40000 || pos >= 60000) { |
2767 | /* abnormal value. hw problem? */ | 2773 | /* abnormal value. hw problem? */ |
2768 | printk(KERN_INFO "intel8x0: measured clock %ld rejected\n", pos); | 2774 | printk(KERN_INFO "intel8x0: measured clock %ld rejected\n", pos); |
2769 | else if (pos > 40500 && pos < 41500) | 2775 | goto __retry; |
2776 | } else if (pos > 40500 && pos < 41500) | ||
2770 | /* first exception - 41000Hz reference clock */ | 2777 | /* first exception - 41000Hz reference clock */ |
2771 | chip->ac97_bus->clock = 41000; | 2778 | chip->ac97_bus->clock = 41000; |
2772 | else if (pos > 43600 && pos < 44600) | 2779 | else if (pos > 43600 && pos < 44600) |