2 * PCM timer handling on ctxfi
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
9 #include <linux/slab.h>
10 #include <linux/math64.h>
11 #include <linux/moduleparam.h>
12 #include <sound/core.h>
13 #include <sound/pcm.h>
15 #include "cthardware.h"
18 static bool use_system_timer
;
19 MODULE_PARM_DESC(use_system_timer
, "Force to use system-timer");
20 module_param(use_system_timer
, bool, 0444);
23 void (*init
)(struct ct_timer_instance
*);
24 void (*prepare
)(struct ct_timer_instance
*);
25 void (*start
)(struct ct_timer_instance
*);
26 void (*stop
)(struct ct_timer_instance
*);
27 void (*free_instance
)(struct ct_timer_instance
*);
28 void (*interrupt
)(struct ct_timer
*);
29 void (*free_global
)(struct ct_timer
*);
32 /* timer instance -- assigned to each PCM stream */
33 struct ct_timer_instance
{
35 struct ct_timer
*timer_base
;
36 struct ct_atc_pcm
*apcm
;
37 struct snd_pcm_substream
*substream
;
38 struct timer_list timer
;
39 struct list_head instance_list
;
40 struct list_head running_list
;
41 unsigned int position
;
42 unsigned int frag_count
;
43 unsigned int running
:1;
44 unsigned int need_update
:1;
47 /* timer instance manager */
49 spinlock_t lock
; /* global timer lock (for xfitimer) */
50 spinlock_t list_lock
; /* lock for instance list */
52 const struct ct_timer_ops
*ops
;
53 struct list_head instance_head
;
54 struct list_head running_head
;
55 unsigned int wc
; /* current wallclock */
56 unsigned int irq_handling
:1; /* in IRQ handling */
57 unsigned int reprogram
:1; /* need to reprogram the internval */
58 unsigned int running
:1; /* global timer running */
63 * system-timer-based updates
66 static void ct_systimer_callback(struct timer_list
*t
)
68 struct ct_timer_instance
*ti
= from_timer(ti
, t
, timer
);
69 struct snd_pcm_substream
*substream
= ti
->substream
;
70 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
71 struct ct_atc_pcm
*apcm
= ti
->apcm
;
72 unsigned int period_size
= runtime
->period_size
;
73 unsigned int buffer_size
= runtime
->buffer_size
;
75 unsigned int position
, dist
, interval
;
77 position
= substream
->ops
->pointer(substream
);
78 dist
= (position
+ buffer_size
- ti
->position
) % buffer_size
;
79 if (dist
>= period_size
||
80 position
/ period_size
!= ti
->position
/ period_size
) {
81 apcm
->interrupt(apcm
);
82 ti
->position
= position
;
84 /* Add extra HZ*5/1000 to avoid overrun issue when recording
85 * at 8kHz in 8-bit format or at 88kHz in 24-bit format. */
86 interval
= ((period_size
- (position
% period_size
))
87 * HZ
+ (runtime
->rate
- 1)) / runtime
->rate
+ HZ
* 5 / 1000;
88 spin_lock_irqsave(&ti
->lock
, flags
);
90 mod_timer(&ti
->timer
, jiffies
+ interval
);
91 spin_unlock_irqrestore(&ti
->lock
, flags
);
94 static void ct_systimer_init(struct ct_timer_instance
*ti
)
96 timer_setup(&ti
->timer
, ct_systimer_callback
, 0);
99 static void ct_systimer_start(struct ct_timer_instance
*ti
)
101 struct snd_pcm_runtime
*runtime
= ti
->substream
->runtime
;
104 spin_lock_irqsave(&ti
->lock
, flags
);
106 mod_timer(&ti
->timer
,
107 jiffies
+ (runtime
->period_size
* HZ
+
108 (runtime
->rate
- 1)) / runtime
->rate
);
109 spin_unlock_irqrestore(&ti
->lock
, flags
);
112 static void ct_systimer_stop(struct ct_timer_instance
*ti
)
116 spin_lock_irqsave(&ti
->lock
, flags
);
118 del_timer(&ti
->timer
);
119 spin_unlock_irqrestore(&ti
->lock
, flags
);
122 static void ct_systimer_prepare(struct ct_timer_instance
*ti
)
124 ct_systimer_stop(ti
);
125 try_to_del_timer_sync(&ti
->timer
);
128 #define ct_systimer_free ct_systimer_prepare
130 static const struct ct_timer_ops ct_systimer_ops
= {
131 .init
= ct_systimer_init
,
132 .free_instance
= ct_systimer_free
,
133 .prepare
= ct_systimer_prepare
,
134 .start
= ct_systimer_start
,
135 .stop
= ct_systimer_stop
,
140 * Handling multiple streams using a global emu20k1 timer irq
143 #define CT_TIMER_FREQ 48000
145 #define MAX_TICKS ((1 << 13) - 1)
147 static void ct_xfitimer_irq_rearm(struct ct_timer
*atimer
, int ticks
)
149 struct hw
*hw
= atimer
->atc
->hw
;
150 if (ticks
> MAX_TICKS
)
152 hw
->set_timer_tick(hw
, ticks
);
153 if (!atimer
->running
)
154 hw
->set_timer_irq(hw
, 1);
158 static void ct_xfitimer_irq_stop(struct ct_timer
*atimer
)
160 if (atimer
->running
) {
161 struct hw
*hw
= atimer
->atc
->hw
;
162 hw
->set_timer_irq(hw
, 0);
163 hw
->set_timer_tick(hw
, 0);
168 static inline unsigned int ct_xfitimer_get_wc(struct ct_timer
*atimer
)
170 struct hw
*hw
= atimer
->atc
->hw
;
171 return hw
->get_wc(hw
);
175 * reprogram the timer interval;
176 * checks the running instance list and determines the next timer interval.
177 * also updates the each stream position, returns the number of streams
178 * to call snd_pcm_period_elapsed() appropriately
180 * call this inside the lock and irq disabled
182 static int ct_xfitimer_reprogram(struct ct_timer
*atimer
, int can_update
)
184 struct ct_timer_instance
*ti
;
185 unsigned int min_intr
= (unsigned int)-1;
187 unsigned int wc
, diff
;
189 if (list_empty(&atimer
->running_head
)) {
190 ct_xfitimer_irq_stop(atimer
);
191 atimer
->reprogram
= 0; /* clear flag */
195 wc
= ct_xfitimer_get_wc(atimer
);
196 diff
= wc
- atimer
->wc
;
198 list_for_each_entry(ti
, &atimer
->running_head
, running_list
) {
199 if (ti
->frag_count
> diff
)
200 ti
->frag_count
-= diff
;
203 unsigned int period_size
, rate
;
205 period_size
= ti
->substream
->runtime
->period_size
;
206 rate
= ti
->substream
->runtime
->rate
;
207 pos
= ti
->substream
->ops
->pointer(ti
->substream
);
208 if (pos
/ period_size
!= ti
->position
/ period_size
) {
214 pos
= period_size
- pos
;
215 ti
->frag_count
= div_u64((u64
)pos
* CT_TIMER_FREQ
+
218 if (ti
->need_update
&& !can_update
)
219 min_intr
= 0; /* pending to the next irq */
220 if (ti
->frag_count
< min_intr
)
221 min_intr
= ti
->frag_count
;
224 if (min_intr
< MIN_TICKS
)
225 min_intr
= MIN_TICKS
;
226 ct_xfitimer_irq_rearm(atimer
, min_intr
);
227 atimer
->reprogram
= 0; /* clear flag */
231 /* look through the instance list and call period_elapsed if needed */
232 static void ct_xfitimer_check_period(struct ct_timer
*atimer
)
234 struct ct_timer_instance
*ti
;
237 spin_lock_irqsave(&atimer
->list_lock
, flags
);
238 list_for_each_entry(ti
, &atimer
->instance_head
, instance_list
) {
239 if (ti
->running
&& ti
->need_update
) {
241 ti
->apcm
->interrupt(ti
->apcm
);
244 spin_unlock_irqrestore(&atimer
->list_lock
, flags
);
247 /* Handle timer-interrupt */
248 static void ct_xfitimer_callback(struct ct_timer
*atimer
)
253 spin_lock_irqsave(&atimer
->lock
, flags
);
254 atimer
->irq_handling
= 1;
256 update
= ct_xfitimer_reprogram(atimer
, 1);
257 spin_unlock(&atimer
->lock
);
259 ct_xfitimer_check_period(atimer
);
260 spin_lock(&atimer
->lock
);
261 } while (atimer
->reprogram
);
262 atimer
->irq_handling
= 0;
263 spin_unlock_irqrestore(&atimer
->lock
, flags
);
266 static void ct_xfitimer_prepare(struct ct_timer_instance
*ti
)
268 ti
->frag_count
= ti
->substream
->runtime
->period_size
;
274 /* start/stop the timer */
275 static void ct_xfitimer_update(struct ct_timer
*atimer
)
279 spin_lock_irqsave(&atimer
->lock
, flags
);
280 if (atimer
->irq_handling
) {
281 /* reached from IRQ handler; let it handle later */
282 atimer
->reprogram
= 1;
283 spin_unlock_irqrestore(&atimer
->lock
, flags
);
287 ct_xfitimer_irq_stop(atimer
);
288 ct_xfitimer_reprogram(atimer
, 0);
289 spin_unlock_irqrestore(&atimer
->lock
, flags
);
292 static void ct_xfitimer_start(struct ct_timer_instance
*ti
)
294 struct ct_timer
*atimer
= ti
->timer_base
;
297 spin_lock_irqsave(&atimer
->lock
, flags
);
298 if (list_empty(&ti
->running_list
))
299 atimer
->wc
= ct_xfitimer_get_wc(atimer
);
302 list_add(&ti
->running_list
, &atimer
->running_head
);
303 spin_unlock_irqrestore(&atimer
->lock
, flags
);
304 ct_xfitimer_update(atimer
);
307 static void ct_xfitimer_stop(struct ct_timer_instance
*ti
)
309 struct ct_timer
*atimer
= ti
->timer_base
;
312 spin_lock_irqsave(&atimer
->lock
, flags
);
313 list_del_init(&ti
->running_list
);
315 spin_unlock_irqrestore(&atimer
->lock
, flags
);
316 ct_xfitimer_update(atimer
);
319 static void ct_xfitimer_free_global(struct ct_timer
*atimer
)
321 ct_xfitimer_irq_stop(atimer
);
324 static const struct ct_timer_ops ct_xfitimer_ops
= {
325 .prepare
= ct_xfitimer_prepare
,
326 .start
= ct_xfitimer_start
,
327 .stop
= ct_xfitimer_stop
,
328 .interrupt
= ct_xfitimer_callback
,
329 .free_global
= ct_xfitimer_free_global
,
336 struct ct_timer_instance
*
337 ct_timer_instance_new(struct ct_timer
*atimer
, struct ct_atc_pcm
*apcm
)
339 struct ct_timer_instance
*ti
;
341 ti
= kzalloc(sizeof(*ti
), GFP_KERNEL
);
344 spin_lock_init(&ti
->lock
);
345 INIT_LIST_HEAD(&ti
->instance_list
);
346 INIT_LIST_HEAD(&ti
->running_list
);
347 ti
->timer_base
= atimer
;
349 ti
->substream
= apcm
->substream
;
350 if (atimer
->ops
->init
)
351 atimer
->ops
->init(ti
);
353 spin_lock_irq(&atimer
->list_lock
);
354 list_add(&ti
->instance_list
, &atimer
->instance_head
);
355 spin_unlock_irq(&atimer
->list_lock
);
360 void ct_timer_prepare(struct ct_timer_instance
*ti
)
362 if (ti
->timer_base
->ops
->prepare
)
363 ti
->timer_base
->ops
->prepare(ti
);
368 void ct_timer_start(struct ct_timer_instance
*ti
)
370 struct ct_timer
*atimer
= ti
->timer_base
;
371 atimer
->ops
->start(ti
);
374 void ct_timer_stop(struct ct_timer_instance
*ti
)
376 struct ct_timer
*atimer
= ti
->timer_base
;
377 atimer
->ops
->stop(ti
);
380 void ct_timer_instance_free(struct ct_timer_instance
*ti
)
382 struct ct_timer
*atimer
= ti
->timer_base
;
384 atimer
->ops
->stop(ti
); /* to be sure */
385 if (atimer
->ops
->free_instance
)
386 atimer
->ops
->free_instance(ti
);
388 spin_lock_irq(&atimer
->list_lock
);
389 list_del(&ti
->instance_list
);
390 spin_unlock_irq(&atimer
->list_lock
);
399 static void ct_timer_interrupt(void *data
, unsigned int status
)
401 struct ct_timer
*timer
= data
;
403 /* Interval timer interrupt */
404 if ((status
& IT_INT
) && timer
->ops
->interrupt
)
405 timer
->ops
->interrupt(timer
);
408 struct ct_timer
*ct_timer_new(struct ct_atc
*atc
)
410 struct ct_timer
*atimer
;
413 atimer
= kzalloc(sizeof(*atimer
), GFP_KERNEL
);
416 spin_lock_init(&atimer
->lock
);
417 spin_lock_init(&atimer
->list_lock
);
418 INIT_LIST_HEAD(&atimer
->instance_head
);
419 INIT_LIST_HEAD(&atimer
->running_head
);
422 if (!use_system_timer
&& hw
->set_timer_irq
) {
423 dev_info(atc
->card
->dev
, "Use xfi-native timer\n");
424 atimer
->ops
= &ct_xfitimer_ops
;
425 hw
->irq_callback_data
= atimer
;
426 hw
->irq_callback
= ct_timer_interrupt
;
428 dev_info(atc
->card
->dev
, "Use system timer\n");
429 atimer
->ops
= &ct_systimer_ops
;
434 void ct_timer_free(struct ct_timer
*atimer
)
436 struct hw
*hw
= atimer
->atc
->hw
;
437 hw
->irq_callback
= NULL
;
438 if (atimer
->ops
->free_global
)
439 atimer
->ops
->free_global(atimer
);