aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/firewire/amdtp-stream.c80
-rw-r--r--sound/firewire/amdtp-stream.h6
2 files changed, 81 insertions, 5 deletions
diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c
index 646e8e390773..a03b37bdc274 100644
--- a/sound/firewire/amdtp-stream.c
+++ b/sound/firewire/amdtp-stream.c
@@ -27,6 +27,7 @@
27 27
28/* isochronous header parameters */ 28/* isochronous header parameters */
29#define ISO_DATA_LENGTH_SHIFT 16 29#define ISO_DATA_LENGTH_SHIFT 16
30#define TAG_NO_CIP_HEADER 0
30#define TAG_CIP 1 31#define TAG_CIP 1
31 32
32/* common isochronous packet header parameters */ 33/* common isochronous packet header parameters */
@@ -234,11 +235,15 @@ EXPORT_SYMBOL(amdtp_stream_set_parameters);
234unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s) 235unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s)
235{ 236{
236 unsigned int multiplier = 1; 237 unsigned int multiplier = 1;
238 unsigned int header_size = 0;
237 239
238 if (s->flags & CIP_JUMBO_PAYLOAD) 240 if (s->flags & CIP_JUMBO_PAYLOAD)
239 multiplier = 5; 241 multiplier = 5;
242 if (!(s->flags & CIP_NO_HEADER))
243 header_size = 8;
240 244
241 return 8 + s->syt_interval * s->data_block_quadlets * 4 * multiplier; 245 return header_size +
246 s->syt_interval * s->data_block_quadlets * 4 * multiplier;
242} 247}
243EXPORT_SYMBOL(amdtp_stream_get_max_payload); 248EXPORT_SYMBOL(amdtp_stream_get_max_payload);
244 249
@@ -380,7 +385,7 @@ static int queue_packet(struct amdtp_stream *s, unsigned int header_length,
380 goto end; 385 goto end;
381 386
382 p.interrupt = IS_ALIGNED(s->packet_index + 1, INTERRUPT_INTERVAL); 387 p.interrupt = IS_ALIGNED(s->packet_index + 1, INTERRUPT_INTERVAL);
383 p.tag = TAG_CIP; 388 p.tag = s->tag;
384 p.header_length = header_length; 389 p.header_length = header_length;
385 if (payload_length > 0) 390 if (payload_length > 0)
386 p.payload_length = payload_length; 391 p.payload_length = payload_length;
@@ -457,6 +462,34 @@ static int handle_out_packet(struct amdtp_stream *s,
457 return 0; 462 return 0;
458} 463}
459 464
465static int handle_out_packet_without_header(struct amdtp_stream *s,
466 unsigned int payload_length, unsigned int cycle,
467 unsigned int index)
468{
469 __be32 *buffer;
470 unsigned int syt;
471 unsigned int data_blocks;
472 unsigned int pcm_frames;
473 struct snd_pcm_substream *pcm;
474
475 buffer = s->buffer.packets[s->packet_index].buffer;
476 syt = calculate_syt(s, cycle);
477 data_blocks = calculate_data_blocks(s, syt);
478 pcm_frames = s->process_data_blocks(s, buffer, data_blocks, &syt);
479 s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;
480
481 payload_length = data_blocks * 4 * s->data_block_quadlets;
482 if (queue_out_packet(s, payload_length) < 0)
483 return -EIO;
484
485 pcm = ACCESS_ONCE(s->pcm);
486 if (pcm && pcm_frames > 0)
487 update_pcm_pointers(s, pcm, pcm_frames);
488
489 /* No need to return the number of handled data blocks. */
490 return 0;
491}
492
460static int handle_in_packet(struct amdtp_stream *s, 493static int handle_in_packet(struct amdtp_stream *s,
461 unsigned int payload_length, unsigned int cycle, 494 unsigned int payload_length, unsigned int cycle,
462 unsigned int index) 495 unsigned int index)
@@ -573,6 +606,30 @@ end:
573 return 0; 606 return 0;
574} 607}
575 608
609static int handle_in_packet_without_header(struct amdtp_stream *s,
610 unsigned int payload_quadlets, unsigned int cycle,
611 unsigned int index)
612{
613 __be32 *buffer;
614 unsigned int data_blocks;
615 struct snd_pcm_substream *pcm;
616 unsigned int pcm_frames;
617
618 buffer = s->buffer.packets[s->packet_index].buffer;
619 data_blocks = payload_quadlets / s->data_block_quadlets;
620 pcm_frames = s->process_data_blocks(s, buffer, data_blocks, NULL);
621 s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;
622
623 if (queue_in_packet(s) < 0)
624 return -EIO;
625
626 pcm = ACCESS_ONCE(s->pcm);
627 if (pcm && pcm_frames > 0)
628 update_pcm_pointers(s, pcm, pcm_frames);
629
630 return 0;
631}
632
576/* 633/*
577 * In CYCLE_TIMER register of IEEE 1394, 7 bits are used to represent second. On 634 * In CYCLE_TIMER register of IEEE 1394, 7 bits are used to represent second. On
578 * the other hand, in DMA descriptors of 1394 OHCI, 3 bits are used to represent 635 * the other hand, in DMA descriptors of 1394 OHCI, 3 bits are used to represent
@@ -616,7 +673,7 @@ static void out_stream_callback(struct fw_iso_context *context, u32 tstamp,
616 673
617 for (i = 0; i < packets; ++i) { 674 for (i = 0; i < packets; ++i) {
618 cycle = increment_cycle_count(cycle, 1); 675 cycle = increment_cycle_count(cycle, 1);
619 if (handle_out_packet(s, 0, cycle, i) < 0) { 676 if (s->handle_packet(s, 0, cycle, i) < 0) {
620 s->packet_index = -1; 677 s->packet_index = -1;
621 amdtp_stream_pcm_abort(s); 678 amdtp_stream_pcm_abort(s);
622 return; 679 return;
@@ -663,7 +720,7 @@ static void in_stream_callback(struct fw_iso_context *context, u32 tstamp,
663 break; 720 break;
664 } 721 }
665 722
666 if (handle_in_packet(s, payload_length, cycle, i) < 0) 723 if (s->handle_packet(s, payload_length, cycle, i) < 0)
667 break; 724 break;
668 } 725 }
669 726
@@ -699,10 +756,18 @@ static void amdtp_stream_first_callback(struct fw_iso_context *context,
699 packets = header_length / IN_PACKET_HEADER_SIZE; 756 packets = header_length / IN_PACKET_HEADER_SIZE;
700 cycle = decrement_cycle_count(cycle, packets); 757 cycle = decrement_cycle_count(cycle, packets);
701 context->callback.sc = in_stream_callback; 758 context->callback.sc = in_stream_callback;
759 if (s->flags & CIP_NO_HEADER)
760 s->handle_packet = handle_in_packet_without_header;
761 else
762 s->handle_packet = handle_in_packet;
702 } else { 763 } else {
703 packets = header_length / 4; 764 packets = header_length / 4;
704 cycle = increment_cycle_count(cycle, QUEUE_LENGTH - packets); 765 cycle = increment_cycle_count(cycle, QUEUE_LENGTH - packets);
705 context->callback.sc = out_stream_callback; 766 context->callback.sc = out_stream_callback;
767 if (s->flags & CIP_NO_HEADER)
768 s->handle_packet = handle_out_packet_without_header;
769 else
770 s->handle_packet = handle_out_packet;
706 } 771 }
707 772
708 s->start_cycle = cycle; 773 s->start_cycle = cycle;
@@ -782,6 +847,11 @@ int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed)
782 847
783 amdtp_stream_update(s); 848 amdtp_stream_update(s);
784 849
850 if (s->flags & CIP_NO_HEADER)
851 s->tag = TAG_NO_CIP_HEADER;
852 else
853 s->tag = TAG_CIP;
854
785 s->packet_index = 0; 855 s->packet_index = 0;
786 do { 856 do {
787 if (s->direction == AMDTP_IN_STREAM) 857 if (s->direction == AMDTP_IN_STREAM)
@@ -794,7 +864,7 @@ int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed)
794 864
795 /* NOTE: TAG1 matches CIP. This just affects in stream. */ 865 /* NOTE: TAG1 matches CIP. This just affects in stream. */
796 tag = FW_ISO_CONTEXT_MATCH_TAG1; 866 tag = FW_ISO_CONTEXT_MATCH_TAG1;
797 if (s->flags & CIP_EMPTY_WITH_TAG0) 867 if ((s->flags & CIP_EMPTY_WITH_TAG0) || (s->flags & CIP_NO_HEADER))
798 tag |= FW_ISO_CONTEXT_MATCH_TAG0; 868 tag |= FW_ISO_CONTEXT_MATCH_TAG0;
799 869
800 s->callbacked = false; 870 s->callbacked = false;
diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h
index a31dfd849821..2bd4de4c7bb7 100644
--- a/sound/firewire/amdtp-stream.h
+++ b/sound/firewire/amdtp-stream.h
@@ -31,6 +31,7 @@
31 * allows 5 times as large as IEC 61883-6 defines. 31 * allows 5 times as large as IEC 61883-6 defines.
32 * @CIP_HEADER_WITHOUT_EOH: Only for in-stream. CIP Header doesn't include 32 * @CIP_HEADER_WITHOUT_EOH: Only for in-stream. CIP Header doesn't include
33 * valid EOH. 33 * valid EOH.
34 * @CIP_NO_HEADERS: a lack of headers in packets
34 */ 35 */
35enum cip_flags { 36enum cip_flags {
36 CIP_NONBLOCKING = 0x00, 37 CIP_NONBLOCKING = 0x00,
@@ -42,6 +43,7 @@ enum cip_flags {
42 CIP_EMPTY_HAS_WRONG_DBC = 0x20, 43 CIP_EMPTY_HAS_WRONG_DBC = 0x20,
43 CIP_JUMBO_PAYLOAD = 0x40, 44 CIP_JUMBO_PAYLOAD = 0x40,
44 CIP_HEADER_WITHOUT_EOH = 0x80, 45 CIP_HEADER_WITHOUT_EOH = 0x80,
46 CIP_NO_HEADER = 0x100,
45}; 47};
46 48
47/** 49/**
@@ -104,6 +106,10 @@ struct amdtp_stream {
104 struct fw_iso_context *context; 106 struct fw_iso_context *context;
105 struct iso_packets_buffer buffer; 107 struct iso_packets_buffer buffer;
106 int packet_index; 108 int packet_index;
109 int tag;
110 int (*handle_packet)(struct amdtp_stream *s,
111 unsigned int payload_quadlets, unsigned int cycle,
112 unsigned int index);
107 113
108 /* For CIP headers. */ 114 /* For CIP headers. */
109 unsigned int source_node_id_field; 115 unsigned int source_node_id_field;