From 87ef7779be825c187747b6b39a24d5326d610c53 Mon Sep 17 00:00:00 2001
From: Clemens Ladisch <clemens@ladisch.de>
Date: Wed, 19 Oct 2005 14:38:30 +0200
Subject: [ALSA] seq-timer: restrict timer frequencies

Modules: ALSA sequencer

When no default timer frequency has been set, initialize_timer() just
uses the maximum frequency supported by the timer, which is ridiculously
high on 96 kHz timers.

This patch introduces a default frequency of 1000 Hz for this case, and
makes sure that a frequency set by the user isn't too high.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
---
 sound/core/seq/seq_timer.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

(limited to 'sound/core')

diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index 9c87d9f8ba9..65b64a7c456 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -34,6 +34,11 @@ extern int seq_default_timer_device;
 extern int seq_default_timer_subdevice;
 extern int seq_default_timer_resolution;
 
+/* allowed sequencer timer frequencies, in Hz */
+#define MIN_FREQUENCY		10
+#define MAX_FREQUENCY		6250
+#define DEFAULT_FREQUENCY	1000
+
 #define SKEW_BASE	0x10000	/* 16bit shift */
 
 static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick,
@@ -325,17 +330,26 @@ int snd_seq_timer_stop(seq_timer_t * tmr)
 static int initialize_timer(seq_timer_t *tmr)
 {
 	snd_timer_t *t;
+	unsigned long freq;
+
 	t = tmr->timeri->timer;
 	snd_assert(t, return -EINVAL);
 
+	freq = tmr->preferred_resolution;
+	if (!freq)
+		freq = DEFAULT_FREQUENCY;
+	else if (freq < MIN_FREQUENCY)
+		freq = MIN_FREQUENCY;
+	else if (freq > MAX_FREQUENCY)
+		freq = MAX_FREQUENCY;
+
 	tmr->ticks = 1;
-	if (tmr->preferred_resolution &&
-	    ! (t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
+	if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
 		unsigned long r = t->hw.resolution;
 		if (! r && t->hw.c_resolution)
 			r = t->hw.c_resolution(t);
 		if (r) {
-			tmr->ticks = (unsigned int)(1000000000uL / (r * tmr->preferred_resolution));
+			tmr->ticks = (unsigned int)(1000000000uL / (r * freq));
 			if (! tmr->ticks)
 				tmr->ticks = 1;
 		}
-- 
cgit v1.2.3