aboutsummaryrefslogtreecommitdiffstats
path: root/sound/firewire/amdtp.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /sound/firewire/amdtp.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'sound/firewire/amdtp.c')
-rw-r--r--sound/firewire/amdtp.c49
1 files changed, 1 insertions, 48 deletions
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c
index ea995af6d04..87657dd7714 100644
--- a/sound/firewire/amdtp.c
+++ b/sound/firewire/amdtp.c
@@ -31,8 +31,6 @@
31#define INTERRUPT_INTERVAL 16 31#define INTERRUPT_INTERVAL 16
32#define QUEUE_LENGTH 48 32#define QUEUE_LENGTH 48
33 33
34static void pcm_period_tasklet(unsigned long data);
35
36/** 34/**
37 * amdtp_out_stream_init - initialize an AMDTP output stream structure 35 * amdtp_out_stream_init - initialize an AMDTP output stream structure
38 * @s: the AMDTP output stream to initialize 36 * @s: the AMDTP output stream to initialize
@@ -49,7 +47,6 @@ int amdtp_out_stream_init(struct amdtp_out_stream *s, struct fw_unit *unit,
49 s->flags = flags; 47 s->flags = flags;
50 s->context = ERR_PTR(-1); 48 s->context = ERR_PTR(-1);
51 mutex_init(&s->mutex); 49 mutex_init(&s->mutex);
52 tasklet_init(&s->period_tasklet, pcm_period_tasklet, (unsigned long)s);
53 s->packet_index = 0; 50 s->packet_index = 0;
54 51
55 return 0; 52 return 0;
@@ -167,21 +164,6 @@ void amdtp_out_stream_set_pcm_format(struct amdtp_out_stream *s,
167} 164}
168EXPORT_SYMBOL(amdtp_out_stream_set_pcm_format); 165EXPORT_SYMBOL(amdtp_out_stream_set_pcm_format);
169 166
170/**
171 * amdtp_out_stream_pcm_prepare - prepare PCM device for running
172 * @s: the AMDTP output stream
173 *
174 * This function should be called from the PCM device's .prepare callback.
175 */
176void amdtp_out_stream_pcm_prepare(struct amdtp_out_stream *s)
177{
178 tasklet_kill(&s->period_tasklet);
179 s->pcm_buffer_pointer = 0;
180 s->pcm_period_pointer = 0;
181 s->pointer_flush = true;
182}
183EXPORT_SYMBOL(amdtp_out_stream_pcm_prepare);
184
185static unsigned int calculate_data_blocks(struct amdtp_out_stream *s) 167static unsigned int calculate_data_blocks(struct amdtp_out_stream *s)
186{ 168{
187 unsigned int phase, data_blocks; 169 unsigned int phase, data_blocks;
@@ -394,21 +376,11 @@ static void queue_out_packet(struct amdtp_out_stream *s, unsigned int cycle)
394 s->pcm_period_pointer += data_blocks; 376 s->pcm_period_pointer += data_blocks;
395 if (s->pcm_period_pointer >= pcm->runtime->period_size) { 377 if (s->pcm_period_pointer >= pcm->runtime->period_size) {
396 s->pcm_period_pointer -= pcm->runtime->period_size; 378 s->pcm_period_pointer -= pcm->runtime->period_size;
397 s->pointer_flush = false; 379 snd_pcm_period_elapsed(pcm);
398 tasklet_hi_schedule(&s->period_tasklet);
399 } 380 }
400 } 381 }
401} 382}
402 383
403static void pcm_period_tasklet(unsigned long data)
404{
405 struct amdtp_out_stream *s = (void *)data;
406 struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm);
407
408 if (pcm)
409 snd_pcm_period_elapsed(pcm);
410}
411
412static void out_packet_callback(struct fw_iso_context *context, u32 cycle, 384static void out_packet_callback(struct fw_iso_context *context, u32 cycle,
413 size_t header_length, void *header, void *data) 385 size_t header_length, void *header, void *data)
414{ 386{
@@ -534,24 +506,6 @@ err_unlock:
534EXPORT_SYMBOL(amdtp_out_stream_start); 506EXPORT_SYMBOL(amdtp_out_stream_start);
535 507
536/** 508/**
537 * amdtp_out_stream_pcm_pointer - get the PCM buffer position
538 * @s: the AMDTP output stream that transports the PCM data
539 *
540 * Returns the current buffer position, in frames.
541 */
542unsigned long amdtp_out_stream_pcm_pointer(struct amdtp_out_stream *s)
543{
544 /* this optimization is allowed to be racy */
545 if (s->pointer_flush)
546 fw_iso_context_flush_completions(s->context);
547 else
548 s->pointer_flush = true;
549
550 return ACCESS_ONCE(s->pcm_buffer_pointer);
551}
552EXPORT_SYMBOL(amdtp_out_stream_pcm_pointer);
553
554/**
555 * amdtp_out_stream_update - update the stream after a bus reset 509 * amdtp_out_stream_update - update the stream after a bus reset
556 * @s: the AMDTP output stream 510 * @s: the AMDTP output stream
557 */ 511 */
@@ -578,7 +532,6 @@ void amdtp_out_stream_stop(struct amdtp_out_stream *s)
578 return; 532 return;
579 } 533 }
580 534
581 tasklet_kill(&s->period_tasklet);
582 fw_iso_context_stop(s->context); 535 fw_iso_context_stop(s->context);
583 fw_iso_context_destroy(s->context); 536 fw_iso_context_destroy(s->context);
584 s->context = ERR_PTR(-1); 537 s->context = ERR_PTR(-1);