aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2014-04-25 09:44:50 -0400
committerTakashi Iwai <tiwai@suse.de>2014-05-26 08:14:41 -0400
commit77d2a8a4f61c158ca34db167e5a9d57ceec0f0df (patch)
tree6fc94490618aba36989424ab3fc294db6eff2307 /sound
parent7b3b0d8583c926547fed8e493344cd8b30aa847d (diff)
ALSA: firewire-lib: Add support for channel mapping
Some devices arrange the position of PCM/MIDI data channel in AMDTP packet. This commit allows drivers to set channel mapping. To be simple, the mapping table is an array with fixed length. Then the number of channels for PCM is restricted by 64 channels. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/firewire/amdtp.c118
-rw-r--r--sound/firewire/amdtp.h8
2 files changed, 79 insertions, 47 deletions
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c
index 8498155c15a6..9cf81b2b4298 100644
--- a/sound/firewire/amdtp.c
+++ b/sound/firewire/amdtp.c
@@ -129,11 +129,12 @@ void amdtp_stream_set_parameters(struct amdtp_stream *s,
129 [CIP_SFC_176400] = 176400, 129 [CIP_SFC_176400] = 176400,
130 [CIP_SFC_192000] = 192000, 130 [CIP_SFC_192000] = 192000,
131 }; 131 };
132 unsigned int sfc, midi_channels; 132 unsigned int i, sfc, midi_channels;
133 133
134 midi_channels = DIV_ROUND_UP(midi_ports, 8); 134 midi_channels = DIV_ROUND_UP(midi_ports, 8);
135 135
136 if (WARN_ON(amdtp_stream_running(s)) || 136 if (WARN_ON(amdtp_stream_running(s)) |
137 WARN_ON(pcm_channels > AMDTP_MAX_CHANNELS_FOR_PCM) |
137 WARN_ON(midi_channels > AMDTP_MAX_CHANNELS_FOR_MIDI)) 138 WARN_ON(midi_channels > AMDTP_MAX_CHANNELS_FOR_MIDI))
138 return; 139 return;
139 140
@@ -148,11 +149,12 @@ sfc_found:
148 if (s->dual_wire) { 149 if (s->dual_wire) {
149 sfc -= 2; 150 sfc -= 2;
150 rate /= 2; 151 rate /= 2;
151 pcm_channels *= 2; 152 s->pcm_channels = pcm_channels * 2;
153 } else {
154 s->pcm_channels = pcm_channels;
152 } 155 }
153 s->sfc = sfc; 156 s->sfc = sfc;
154 s->data_block_quadlets = pcm_channels + midi_channels; 157 s->data_block_quadlets = s->pcm_channels + midi_channels;
155 s->pcm_channels = pcm_channels;
156 s->midi_ports = midi_ports; 158 s->midi_ports = midi_ports;
157 159
158 s->syt_interval = amdtp_syt_intervals[sfc]; 160 s->syt_interval = amdtp_syt_intervals[sfc];
@@ -162,6 +164,11 @@ sfc_found:
162 if (s->flags & CIP_BLOCKING) 164 if (s->flags & CIP_BLOCKING)
163 /* additional buffering needed to adjust for no-data packets */ 165 /* additional buffering needed to adjust for no-data packets */
164 s->transfer_delay += TICKS_PER_SECOND * s->syt_interval / rate; 166 s->transfer_delay += TICKS_PER_SECOND * s->syt_interval / rate;
167
168 /* init the position map for PCM and MIDI channels */
169 for (i = 0; i < pcm_channels; i++)
170 s->pcm_positions[i] = i;
171 s->midi_position = s->pcm_channels;
165} 172}
166EXPORT_SYMBOL(amdtp_stream_set_parameters); 173EXPORT_SYMBOL(amdtp_stream_set_parameters);
167 174
@@ -341,22 +348,21 @@ static void amdtp_write_s32(struct amdtp_stream *s,
341 __be32 *buffer, unsigned int frames) 348 __be32 *buffer, unsigned int frames)
342{ 349{
343 struct snd_pcm_runtime *runtime = pcm->runtime; 350 struct snd_pcm_runtime *runtime = pcm->runtime;
344 unsigned int channels, remaining_frames, frame_step, i, c; 351 unsigned int channels, remaining_frames, i, c;
345 const u32 *src; 352 const u32 *src;
346 353
347 channels = s->pcm_channels; 354 channels = s->pcm_channels;
348 src = (void *)runtime->dma_area + 355 src = (void *)runtime->dma_area +
349 frames_to_bytes(runtime, s->pcm_buffer_pointer); 356 frames_to_bytes(runtime, s->pcm_buffer_pointer);
350 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; 357 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
351 frame_step = s->data_block_quadlets - channels;
352 358
353 for (i = 0; i < frames; ++i) { 359 for (i = 0; i < frames; ++i) {
354 for (c = 0; c < channels; ++c) { 360 for (c = 0; c < channels; ++c) {
355 *buffer = cpu_to_be32((*src >> 8) | 0x40000000); 361 buffer[s->pcm_positions[c]] =
362 cpu_to_be32((*src >> 8) | 0x40000000);
356 src++; 363 src++;
357 buffer++;
358 } 364 }
359 buffer += frame_step; 365 buffer += s->data_block_quadlets;
360 if (--remaining_frames == 0) 366 if (--remaining_frames == 0)
361 src = (void *)runtime->dma_area; 367 src = (void *)runtime->dma_area;
362 } 368 }
@@ -367,22 +373,21 @@ static void amdtp_write_s16(struct amdtp_stream *s,
367 __be32 *buffer, unsigned int frames) 373 __be32 *buffer, unsigned int frames)
368{ 374{
369 struct snd_pcm_runtime *runtime = pcm->runtime; 375 struct snd_pcm_runtime *runtime = pcm->runtime;
370 unsigned int channels, remaining_frames, frame_step, i, c; 376 unsigned int channels, remaining_frames, i, c;
371 const u16 *src; 377 const u16 *src;
372 378
373 channels = s->pcm_channels; 379 channels = s->pcm_channels;
374 src = (void *)runtime->dma_area + 380 src = (void *)runtime->dma_area +
375 frames_to_bytes(runtime, s->pcm_buffer_pointer); 381 frames_to_bytes(runtime, s->pcm_buffer_pointer);
376 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; 382 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
377 frame_step = s->data_block_quadlets - channels;
378 383
379 for (i = 0; i < frames; ++i) { 384 for (i = 0; i < frames; ++i) {
380 for (c = 0; c < channels; ++c) { 385 for (c = 0; c < channels; ++c) {
381 *buffer = cpu_to_be32((*src << 8) | 0x40000000); 386 buffer[s->pcm_positions[c]] =
387 cpu_to_be32((*src << 8) | 0x40000000);
382 src++; 388 src++;
383 buffer++;
384 } 389 }
385 buffer += frame_step; 390 buffer += s->data_block_quadlets;
386 if (--remaining_frames == 0) 391 if (--remaining_frames == 0)
387 src = (void *)runtime->dma_area; 392 src = (void *)runtime->dma_area;
388 } 393 }
@@ -393,29 +398,29 @@ static void amdtp_write_s32_dualwire(struct amdtp_stream *s,
393 __be32 *buffer, unsigned int frames) 398 __be32 *buffer, unsigned int frames)
394{ 399{
395 struct snd_pcm_runtime *runtime = pcm->runtime; 400 struct snd_pcm_runtime *runtime = pcm->runtime;
396 unsigned int channels, frame_adjust_1, frame_adjust_2, i, c; 401 unsigned int channels, remaining_frames, i, c;
397 const u32 *src; 402 const u32 *src;
398 403
399 channels = s->pcm_channels;
400 src = (void *)runtime->dma_area + 404 src = (void *)runtime->dma_area +
401 s->pcm_buffer_pointer * (runtime->frame_bits / 8); 405 frames_to_bytes(runtime, s->pcm_buffer_pointer);
402 frame_adjust_1 = channels - 1; 406 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
403 frame_adjust_2 = 1 - (s->data_block_quadlets - channels); 407 channels = s->pcm_channels / 2;
404 408
405 channels /= 2;
406 for (i = 0; i < frames; ++i) { 409 for (i = 0; i < frames; ++i) {
407 for (c = 0; c < channels; ++c) { 410 for (c = 0; c < channels; ++c) {
408 *buffer = cpu_to_be32((*src >> 8) | 0x40000000); 411 buffer[s->pcm_positions[c] * 2] =
412 cpu_to_be32((*src >> 8) | 0x40000000);
409 src++; 413 src++;
410 buffer += 2;
411 } 414 }
412 buffer -= frame_adjust_1; 415 buffer += 1;
413 for (c = 0; c < channels; ++c) { 416 for (c = 0; c < channels; ++c) {
414 *buffer = cpu_to_be32((*src >> 8) | 0x40000000); 417 buffer[s->pcm_positions[c] * 2] =
418 cpu_to_be32((*src >> 8) | 0x40000000);
415 src++; 419 src++;
416 buffer += 2;
417 } 420 }
418 buffer -= frame_adjust_2; 421 buffer += s->data_block_quadlets - 1;
422 if (--remaining_frames == 0)
423 src = (void *)runtime->dma_area;
419 } 424 }
420} 425}
421 426
@@ -424,29 +429,29 @@ static void amdtp_write_s16_dualwire(struct amdtp_stream *s,
424 __be32 *buffer, unsigned int frames) 429 __be32 *buffer, unsigned int frames)
425{ 430{
426 struct snd_pcm_runtime *runtime = pcm->runtime; 431 struct snd_pcm_runtime *runtime = pcm->runtime;
427 unsigned int channels, frame_adjust_1, frame_adjust_2, i, c; 432 unsigned int channels, remaining_frames, i, c;
428 const u16 *src; 433 const u16 *src;
429 434
430 channels = s->pcm_channels;
431 src = (void *)runtime->dma_area + 435 src = (void *)runtime->dma_area +
432 s->pcm_buffer_pointer * (runtime->frame_bits / 8); 436 frames_to_bytes(runtime, s->pcm_buffer_pointer);
433 frame_adjust_1 = channels - 1; 437 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
434 frame_adjust_2 = 1 - (s->data_block_quadlets - channels); 438 channels = s->pcm_channels / 2;
435 439
436 channels /= 2;
437 for (i = 0; i < frames; ++i) { 440 for (i = 0; i < frames; ++i) {
438 for (c = 0; c < channels; ++c) { 441 for (c = 0; c < channels; ++c) {
439 *buffer = cpu_to_be32((*src << 8) | 0x40000000); 442 buffer[s->pcm_positions[c] * 2] =
443 cpu_to_be32((*src << 8) | 0x40000000);
440 src++; 444 src++;
441 buffer += 2;
442 } 445 }
443 buffer -= frame_adjust_1; 446 buffer += 1;
444 for (c = 0; c < channels; ++c) { 447 for (c = 0; c < channels; ++c) {
445 *buffer = cpu_to_be32((*src << 8) | 0x40000000); 448 buffer[s->pcm_positions[c] * 2] =
449 cpu_to_be32((*src << 8) | 0x40000000);
446 src++; 450 src++;
447 buffer += 2;
448 } 451 }
449 buffer -= frame_adjust_2; 452 buffer += s->data_block_quadlets - 1;
453 if (--remaining_frames == 0)
454 src = (void *)runtime->dma_area;
450 } 455 }
451} 456}
452 457
@@ -465,7 +470,7 @@ static void amdtp_read_s32(struct amdtp_stream *s,
465 470
466 for (i = 0; i < frames; ++i) { 471 for (i = 0; i < frames; ++i) {
467 for (c = 0; c < channels; ++c) { 472 for (c = 0; c < channels; ++c) {
468 *dst = be32_to_cpu(buffer[c]) << 8; 473 *dst = be32_to_cpu(buffer[s->pcm_positions[c]]) << 8;
469 dst++; 474 dst++;
470 } 475 }
471 buffer += s->data_block_quadlets; 476 buffer += s->data_block_quadlets;
@@ -489,12 +494,14 @@ static void amdtp_read_s32_dualwire(struct amdtp_stream *s,
489 494
490 for (i = 0; i < frames; ++i) { 495 for (i = 0; i < frames; ++i) {
491 for (c = 0; c < channels; ++c) { 496 for (c = 0; c < channels; ++c) {
492 *dst = be32_to_cpu(buffer[c * 2]) << 8; 497 *dst =
498 be32_to_cpu(buffer[s->pcm_positions[c] * 2]) << 8;
493 dst++; 499 dst++;
494 } 500 }
495 buffer += 1; 501 buffer += 1;
496 for (c = 0; c < channels; ++c) { 502 for (c = 0; c < channels; ++c) {
497 *dst = be32_to_cpu(buffer[c * 2]) << 8; 503 *dst =
504 be32_to_cpu(buffer[s->pcm_positions[c] * 2]) << 8;
498 dst++; 505 dst++;
499 } 506 }
500 buffer += s->data_block_quadlets - 1; 507 buffer += s->data_block_quadlets - 1;
@@ -510,11 +517,26 @@ static void amdtp_fill_pcm_silence(struct amdtp_stream *s,
510 517
511 for (i = 0; i < frames; ++i) { 518 for (i = 0; i < frames; ++i) {
512 for (c = 0; c < s->pcm_channels; ++c) 519 for (c = 0; c < s->pcm_channels; ++c)
513 buffer[c] = cpu_to_be32(0x40000000); 520 buffer[s->pcm_positions[c]] = cpu_to_be32(0x40000000);
514 buffer += s->data_block_quadlets; 521 buffer += s->data_block_quadlets;
515 } 522 }
516} 523}
517 524
525static void amdtp_fill_pcm_silence_dualwire(struct amdtp_stream *s,
526 __be32 *buffer, unsigned int frames)
527{
528 unsigned int i, c, channels;
529
530 channels = s->pcm_channels / 2;
531 for (i = 0; i < frames; ++i) {
532 for (c = 0; c < channels; ++c) {
533 buffer[s->pcm_positions[c] * 2] =
534 buffer[s->pcm_positions[c] * 2 + 1] =
535 cpu_to_be32(0x40000000);
536 }
537 buffer += s->data_block_quadlets;
538 }
539}
518static void amdtp_fill_midi(struct amdtp_stream *s, 540static void amdtp_fill_midi(struct amdtp_stream *s,
519 __be32 *buffer, unsigned int frames) 541 __be32 *buffer, unsigned int frames)
520{ 542{
@@ -522,8 +544,8 @@ static void amdtp_fill_midi(struct amdtp_stream *s,
522 u8 *b; 544 u8 *b;
523 545
524 for (f = 0; f < frames; f++) { 546 for (f = 0; f < frames; f++) {
525 buffer[s->pcm_channels + 1] = 0; 547 buffer[s->midi_position] = 0;
526 b = (u8 *)&buffer[s->pcm_channels + 1]; 548 b = (u8 *)&buffer[s->midi_position];
527 549
528 port = (s->data_block_counter + f) % 8; 550 port = (s->data_block_counter + f) % 8;
529 if ((s->midi[port] == NULL) || 551 if ((s->midi[port] == NULL) ||
@@ -545,7 +567,7 @@ static void amdtp_pull_midi(struct amdtp_stream *s,
545 567
546 for (f = 0; f < frames; f++) { 568 for (f = 0; f < frames; f++) {
547 port = (s->data_block_counter + f) % 8; 569 port = (s->data_block_counter + f) % 8;
548 b = (u8 *)&buffer[s->pcm_channels + 1]; 570 b = (u8 *)&buffer[s->midi_position];
549 571
550 len = b[0] - 0x80; 572 len = b[0] - 0x80;
551 if ((1 <= len) && (len <= 3) && (s->midi[port])) 573 if ((1 <= len) && (len <= 3) && (s->midi[port]))
@@ -652,6 +674,8 @@ static void handle_out_packet(struct amdtp_stream *s, unsigned int syt)
652 pcm = ACCESS_ONCE(s->pcm); 674 pcm = ACCESS_ONCE(s->pcm);
653 if (pcm) 675 if (pcm)
654 s->transfer_samples(s, pcm, buffer, data_blocks); 676 s->transfer_samples(s, pcm, buffer, data_blocks);
677 else if (s->dual_wire)
678 amdtp_fill_pcm_silence_dualwire(s, buffer, data_blocks);
655 else 679 else
656 amdtp_fill_pcm_silence(s, buffer, data_blocks); 680 amdtp_fill_pcm_silence(s, buffer, data_blocks);
657 if (s->midi_ports) 681 if (s->midi_ports)
@@ -683,7 +707,7 @@ static void handle_in_packet(struct amdtp_stream *s,
683 707
684 /* 708 /*
685 * This module supports 'Two-quadlet CIP header with SYT field'. 709 * This module supports 'Two-quadlet CIP header with SYT field'.
686 * For convinience, also check FMT field is AM824 or not. 710 * For convenience, also check FMT field is AM824 or not.
687 */ 711 */
688 if (((cip_header[0] & CIP_EOH_MASK) == CIP_EOH) || 712 if (((cip_header[0] & CIP_EOH_MASK) == CIP_EOH) ||
689 ((cip_header[1] & CIP_EOH_MASK) != CIP_EOH) || 713 ((cip_header[1] & CIP_EOH_MASK) != CIP_EOH) ||
diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h
index 2bd3b27ac938..e8d62ace6fff 100644
--- a/sound/firewire/amdtp.h
+++ b/sound/firewire/amdtp.h
@@ -51,6 +51,12 @@ enum cip_sfc {
51 51
52 52
53/* 53/*
54 * This module supports maximum 64 PCM channels for one PCM stream
55 * This is for our convenience.
56 */
57#define AMDTP_MAX_CHANNELS_FOR_PCM 64
58
59/*
54 * AMDTP packet can include channels for MIDI conformant data. 60 * AMDTP packet can include channels for MIDI conformant data.
55 * Each MIDI conformant data channel includes 8 MPX-MIDI data stream. 61 * Each MIDI conformant data channel includes 8 MPX-MIDI data stream.
56 * Each MPX-MIDI data stream includes one data stream from/to MIDI ports. 62 * Each MPX-MIDI data stream includes one data stream from/to MIDI ports.
@@ -85,6 +91,8 @@ struct amdtp_stream {
85 void (*transfer_samples)(struct amdtp_stream *s, 91 void (*transfer_samples)(struct amdtp_stream *s,
86 struct snd_pcm_substream *pcm, 92 struct snd_pcm_substream *pcm,
87 __be32 *buffer, unsigned int frames); 93 __be32 *buffer, unsigned int frames);
94 u8 pcm_positions[AMDTP_MAX_CHANNELS_FOR_PCM];
95 u8 midi_position;
88 96
89 unsigned int syt_interval; 97 unsigned int syt_interval;
90 unsigned int transfer_delay; 98 unsigned int transfer_delay;