Lines Matching +full:1000 +full:base +full:- +full:t
1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (c) 1998-1999 by Frank van de Pol <fvdpol@coil.demon.nl>
17 #define DEFAULT_FREQUENCY 1000
24 tmr->tempo_base == 1000 ? 1000000 : 10000; in snd_seq_timer_set_tick_resolution()
26 if (tmr->tempo < threshold) in snd_seq_timer_set_tick_resolution()
27 tmr->tick.resolution = (tmr->tempo * tmr->tempo_base) / tmr->ppq; in snd_seq_timer_set_tick_resolution()
31 s = tmr->tempo % tmr->ppq; in snd_seq_timer_set_tick_resolution()
32 s = (s * tmr->tempo_base) / tmr->ppq; in snd_seq_timer_set_tick_resolution()
33 tmr->tick.resolution = (tmr->tempo / tmr->ppq) * tmr->tempo_base; in snd_seq_timer_set_tick_resolution()
34 tmr->tick.resolution += s; in snd_seq_timer_set_tick_resolution()
36 if (tmr->tick.resolution <= 0) in snd_seq_timer_set_tick_resolution()
37 tmr->tick.resolution = 1; in snd_seq_timer_set_tick_resolution()
38 snd_seq_timer_update_tick(&tmr->tick, 0); in snd_seq_timer_set_tick_resolution()
49 spin_lock_init(&tmr->lock); in snd_seq_timer_new()
63 struct snd_seq_timer *t = *tmr; in snd_seq_timer_delete() local
66 if (t == NULL) { in snd_seq_timer_delete()
70 t->running = 0; in snd_seq_timer_delete()
73 snd_seq_timer_stop(t); in snd_seq_timer_delete()
74 snd_seq_timer_reset(t); in snd_seq_timer_delete()
76 kfree(t); in snd_seq_timer_delete()
81 guard(spinlock_irqsave)(&tmr->lock); in snd_seq_timer_defaults()
83 tmr->ppq = 96; /* 96 PPQ */ in snd_seq_timer_defaults()
84 tmr->tempo = 500000; /* 120 BPM */ in snd_seq_timer_defaults()
85 tmr->tempo_base = 1000; /* 1us */ in snd_seq_timer_defaults()
87 tmr->running = 0; in snd_seq_timer_defaults()
89 tmr->type = SNDRV_SEQ_TIMER_ALSA; in snd_seq_timer_defaults()
90 tmr->alsa_id.dev_class = seq_default_timer_class; in snd_seq_timer_defaults()
91 tmr->alsa_id.dev_sclass = seq_default_timer_sclass; in snd_seq_timer_defaults()
92 tmr->alsa_id.card = seq_default_timer_card; in snd_seq_timer_defaults()
93 tmr->alsa_id.device = seq_default_timer_device; in snd_seq_timer_defaults()
94 tmr->alsa_id.subdevice = seq_default_timer_subdevice; in snd_seq_timer_defaults()
95 tmr->preferred_resolution = seq_default_timer_resolution; in snd_seq_timer_defaults()
97 tmr->skew = tmr->skew_base = SKEW_BASE; in snd_seq_timer_defaults()
103 tmr->cur_time.tv_sec = 0; in seq_timer_reset()
104 tmr->cur_time.tv_nsec = 0; in seq_timer_reset()
106 tmr->tick.cur_tick = 0; in seq_timer_reset()
107 tmr->tick.fraction = 0; in seq_timer_reset()
112 guard(spinlock_irqsave)(&tmr->lock); in snd_seq_timer_reset()
122 struct snd_seq_queue *q = timeri->callback_data; in snd_seq_timer_interrupt()
127 tmr = q->timer; in snd_seq_timer_interrupt()
131 scoped_guard(spinlock_irqsave, &tmr->lock) { in snd_seq_timer_interrupt()
132 if (!tmr->running) in snd_seq_timer_interrupt()
136 if (tmr->skew != tmr->skew_base) { in snd_seq_timer_interrupt()
138 resolution = (resolution >> 16) * tmr->skew + in snd_seq_timer_interrupt()
139 (((resolution & 0xffff) * tmr->skew) >> 16); in snd_seq_timer_interrupt()
143 snd_seq_inc_time_nsec(&tmr->cur_time, resolution); in snd_seq_timer_interrupt()
146 snd_seq_timer_update_tick(&tmr->tick, resolution); in snd_seq_timer_interrupt()
149 ktime_get_ts64(&tmr->last_update); in snd_seq_timer_interrupt()
160 return -EINVAL; in snd_seq_timer_set_tempo()
162 return -EINVAL; in snd_seq_timer_set_tempo()
163 guard(spinlock_irqsave)(&tmr->lock); in snd_seq_timer_set_tempo()
164 if ((unsigned int)tempo != tmr->tempo) { in snd_seq_timer_set_tempo()
165 tmr->tempo = tempo; in snd_seq_timer_set_tempo()
171 /* set current tempo, ppq and base in a shot */
178 return -EINVAL; in snd_seq_timer_set_tempo_ppq()
180 return -EINVAL; in snd_seq_timer_set_tempo_ppq()
181 /* allow only 10ns or 1us tempo base for now */ in snd_seq_timer_set_tempo_ppq()
182 if (tempo_base && tempo_base != 10 && tempo_base != 1000) in snd_seq_timer_set_tempo_ppq()
183 return -EINVAL; in snd_seq_timer_set_tempo_ppq()
184 guard(spinlock_irqsave)(&tmr->lock); in snd_seq_timer_set_tempo_ppq()
185 if (tmr->running && (ppq != tmr->ppq)) { in snd_seq_timer_set_tempo_ppq()
189 return -EBUSY; in snd_seq_timer_set_tempo_ppq()
191 changed = (tempo != tmr->tempo) || (ppq != tmr->ppq); in snd_seq_timer_set_tempo_ppq()
192 tmr->tempo = tempo; in snd_seq_timer_set_tempo_ppq()
193 tmr->ppq = ppq; in snd_seq_timer_set_tempo_ppq()
194 tmr->tempo_base = tempo_base ? tempo_base : 1000; in snd_seq_timer_set_tempo_ppq()
205 return -EINVAL; in snd_seq_timer_set_position_tick()
207 guard(spinlock_irqsave)(&tmr->lock); in snd_seq_timer_set_position_tick()
208 tmr->tick.cur_tick = position; in snd_seq_timer_set_position_tick()
209 tmr->tick.fraction = 0; in snd_seq_timer_set_position_tick()
213 /* set current real-time position */
218 return -EINVAL; in snd_seq_timer_set_position_time()
221 guard(spinlock_irqsave)(&tmr->lock); in snd_seq_timer_set_position_time()
222 tmr->cur_time = position; in snd_seq_timer_set_position_time()
228 unsigned int base) in snd_seq_timer_set_skew() argument
231 return -EINVAL; in snd_seq_timer_set_skew()
234 if (base != SKEW_BASE) { in snd_seq_timer_set_skew()
235 pr_debug("ALSA: seq: invalid skew base 0x%x\n", base); in snd_seq_timer_set_skew()
236 return -EINVAL; in snd_seq_timer_set_skew()
238 guard(spinlock_irqsave)(&tmr->lock); in snd_seq_timer_set_skew()
239 tmr->skew = skew; in snd_seq_timer_set_skew()
245 struct snd_timer_instance *t; in snd_seq_timer_open() local
250 tmr = q->timer; in snd_seq_timer_open()
252 return -EINVAL; in snd_seq_timer_open()
253 if (tmr->timeri) in snd_seq_timer_open()
254 return -EBUSY; in snd_seq_timer_open()
255 sprintf(str, "sequencer queue %i", q->queue); in snd_seq_timer_open()
256 if (tmr->type != SNDRV_SEQ_TIMER_ALSA) /* standard ALSA timer */ in snd_seq_timer_open()
257 return -EINVAL; in snd_seq_timer_open()
258 if (tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_SLAVE) in snd_seq_timer_open()
259 tmr->alsa_id.dev_sclass = SNDRV_TIMER_SCLASS_SEQUENCER; in snd_seq_timer_open()
260 t = snd_timer_instance_new(str); in snd_seq_timer_open()
261 if (!t) in snd_seq_timer_open()
262 return -ENOMEM; in snd_seq_timer_open()
263 t->callback = snd_seq_timer_interrupt; in snd_seq_timer_open()
264 t->callback_data = q; in snd_seq_timer_open()
265 t->flags |= SNDRV_TIMER_IFLG_AUTO; in snd_seq_timer_open()
266 err = snd_timer_open(t, &tmr->alsa_id, q->queue); in snd_seq_timer_open()
267 if (err < 0 && tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_SLAVE) { in snd_seq_timer_open()
268 if (tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_GLOBAL || in snd_seq_timer_open()
269 tmr->alsa_id.device != SNDRV_TIMER_GLOBAL_SYSTEM) { in snd_seq_timer_open()
274 tid.card = -1; in snd_seq_timer_open()
276 err = snd_timer_open(t, &tid, q->queue); in snd_seq_timer_open()
281 snd_timer_instance_free(t); in snd_seq_timer_open()
284 scoped_guard(spinlock_irq, &tmr->lock) { in snd_seq_timer_open()
285 if (tmr->timeri) in snd_seq_timer_open()
286 err = -EBUSY; in snd_seq_timer_open()
288 tmr->timeri = t; in snd_seq_timer_open()
291 snd_timer_close(t); in snd_seq_timer_open()
292 snd_timer_instance_free(t); in snd_seq_timer_open()
301 struct snd_timer_instance *t; in snd_seq_timer_close() local
303 tmr = q->timer; in snd_seq_timer_close()
305 return -EINVAL; in snd_seq_timer_close()
306 scoped_guard(spinlock_irq, &tmr->lock) { in snd_seq_timer_close()
307 t = tmr->timeri; in snd_seq_timer_close()
308 tmr->timeri = NULL; in snd_seq_timer_close()
310 if (t) { in snd_seq_timer_close()
311 snd_timer_close(t); in snd_seq_timer_close()
312 snd_timer_instance_free(t); in snd_seq_timer_close()
319 if (! tmr->timeri) in seq_timer_stop()
320 return -EINVAL; in seq_timer_stop()
321 if (!tmr->running) in seq_timer_stop()
323 tmr->running = 0; in seq_timer_stop()
324 snd_timer_pause(tmr->timeri); in seq_timer_stop()
330 guard(spinlock_irqsave)(&tmr->lock); in snd_seq_timer_stop()
336 struct snd_timer *t; in initialize_timer() local
339 t = tmr->timeri->timer; in initialize_timer()
340 if (!t) in initialize_timer()
341 return -EINVAL; in initialize_timer()
343 freq = tmr->preferred_resolution; in initialize_timer()
351 tmr->ticks = 1; in initialize_timer()
352 if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) { in initialize_timer()
353 unsigned long r = snd_timer_resolution(tmr->timeri); in initialize_timer()
355 tmr->ticks = (unsigned int)(1000000000uL / (r * freq)); in initialize_timer()
356 if (! tmr->ticks) in initialize_timer()
357 tmr->ticks = 1; in initialize_timer()
360 tmr->initialized = 1; in initialize_timer()
366 if (! tmr->timeri) in seq_timer_start()
367 return -EINVAL; in seq_timer_start()
368 if (tmr->running) in seq_timer_start()
372 return -EINVAL; in seq_timer_start()
373 snd_timer_start(tmr->timeri, tmr->ticks); in seq_timer_start()
374 tmr->running = 1; in seq_timer_start()
375 ktime_get_ts64(&tmr->last_update); in seq_timer_start()
381 guard(spinlock_irqsave)(&tmr->lock); in snd_seq_timer_start()
387 if (! tmr->timeri) in seq_timer_continue()
388 return -EINVAL; in seq_timer_continue()
389 if (tmr->running) in seq_timer_continue()
390 return -EBUSY; in seq_timer_continue()
391 if (! tmr->initialized) { in seq_timer_continue()
394 return -EINVAL; in seq_timer_continue()
396 snd_timer_start(tmr->timeri, tmr->ticks); in seq_timer_continue()
397 tmr->running = 1; in seq_timer_continue()
398 ktime_get_ts64(&tmr->last_update); in seq_timer_continue()
404 guard(spinlock_irqsave)(&tmr->lock); in snd_seq_timer_continue()
414 guard(spinlock_irqsave)(&tmr->lock); in snd_seq_timer_get_cur_time()
415 cur_time = tmr->cur_time; in snd_seq_timer_get_cur_time()
416 if (adjust_ktime && tmr->running) { in snd_seq_timer_get_cur_time()
420 tm = timespec64_sub(tm, tmr->last_update); in snd_seq_timer_get_cur_time()
432 guard(spinlock_irqsave)(&tmr->lock); in snd_seq_timer_get_cur_tick()
433 return tmr->tick.cur_tick; in snd_seq_timer_get_cur_tick()
452 scoped_guard(mutex, &q->timer_mutex) { in snd_seq_info_timer_read()
453 tmr = q->timer; in snd_seq_info_timer_read()
456 ti = tmr->timeri; in snd_seq_info_timer_read()
459 snd_iprintf(buffer, "Timer for queue %i : %s\n", q->queue, ti->timer->name); in snd_seq_info_timer_read()
460 resolution = snd_timer_resolution(ti) * tmr->ticks; in snd_seq_info_timer_read()
462 snd_iprintf(buffer, " Skew : %u / %u\n", tmr->skew, tmr->skew_base); in snd_seq_info_timer_read()