Lines Matching +full:channel +full:- +full:fifo +full:- +full:len
1 // SPDX-License-Identifier: GPL-2.0-only
3 * AM824 format in Audio and Music Data Transmission Protocol (IEC 61883-6)
6 * Copyright (c) 2015 Takashi Sakamoto <o-takashi@sakamocchi.jp>
11 #include "amdtp-am824.h"
15 /* "Clock-based rate control mode" is just supported. */
42 * amdtp_am824_set_parameters - set stream parameters
46 * as AM824 multi-bit linear audio
47 * @midi_ports: the number of MIDI ports (i.e., MPX-MIDI Data Channels)
58 struct amdtp_am824 *p = s->protocol; in amdtp_am824_set_parameters()
64 return -EINVAL; in amdtp_am824_set_parameters()
67 return -EINVAL; in amdtp_am824_set_parameters()
71 return -EINVAL; in amdtp_am824_set_parameters()
76 return -EINVAL; in amdtp_am824_set_parameters()
79 * In IEC 61883-6, one data block represents one event. In ALSA, one in amdtp_am824_set_parameters()
93 if (s->direction == AMDTP_OUT_STREAM) in amdtp_am824_set_parameters()
94 s->ctx_data.rx.fdf = AMDTP_FDF_AM824 | s->sfc; in amdtp_am824_set_parameters()
96 p->pcm_channels = pcm_channels; in amdtp_am824_set_parameters()
97 p->midi_ports = midi_ports; in amdtp_am824_set_parameters()
101 p->pcm_positions[i] = i; in amdtp_am824_set_parameters()
102 p->midi_position = p->pcm_channels; in amdtp_am824_set_parameters()
105 * We do not know the actual MIDI FIFO size of most devices. Just in amdtp_am824_set_parameters()
110 p->midi_fifo_limit = rate - MIDI_BYTES_PER_SECOND * s->syt_interval + 1; in amdtp_am824_set_parameters()
117 * amdtp_am824_set_pcm_position - set an index of data channel for a channel
120 * @index: the index of data channel in an data block
121 * @position: the channel of PCM frame
126 struct amdtp_am824 *p = s->protocol; in amdtp_am824_set_pcm_position()
128 if (index < p->pcm_channels) in amdtp_am824_set_pcm_position()
129 p->pcm_positions[index] = position; in amdtp_am824_set_pcm_position()
134 * amdtp_am824_set_midi_position - set a index of data channel for MIDI
135 * conformant data channel
137 * @position: the index of data channel in an data block
142 struct amdtp_am824 *p = s->protocol; in amdtp_am824_set_midi_position()
144 p->midi_position = position; in amdtp_am824_set_midi_position()
152 struct amdtp_am824 *p = s->protocol; in write_pcm_s32()
153 unsigned int channels = p->pcm_channels; in write_pcm_s32()
154 struct snd_pcm_runtime *runtime = pcm->runtime; in write_pcm_s32()
160 pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames; in write_pcm_s32()
161 pcm_buffer_pointer %= runtime->buffer_size; in write_pcm_s32()
163 src = (void *)runtime->dma_area + in write_pcm_s32()
165 remaining_frames = runtime->buffer_size - pcm_buffer_pointer; in write_pcm_s32()
169 buffer[p->pcm_positions[c]] = in write_pcm_s32()
173 buffer += s->data_block_quadlets; in write_pcm_s32()
174 if (--remaining_frames == 0) in write_pcm_s32()
175 src = (void *)runtime->dma_area; in write_pcm_s32()
183 struct amdtp_am824 *p = s->protocol; in read_pcm_s32()
184 unsigned int channels = p->pcm_channels; in read_pcm_s32()
185 struct snd_pcm_runtime *runtime = pcm->runtime; in read_pcm_s32()
191 pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames; in read_pcm_s32()
192 pcm_buffer_pointer %= runtime->buffer_size; in read_pcm_s32()
194 dst = (void *)runtime->dma_area + in read_pcm_s32()
196 remaining_frames = runtime->buffer_size - pcm_buffer_pointer; in read_pcm_s32()
200 *dst = be32_to_cpu(buffer[p->pcm_positions[c]]) << 8; in read_pcm_s32()
203 buffer += s->data_block_quadlets; in read_pcm_s32()
204 if (--remaining_frames == 0) in read_pcm_s32()
205 dst = (void *)runtime->dma_area; in read_pcm_s32()
212 struct amdtp_am824 *p = s->protocol; in write_pcm_silence()
213 unsigned int i, c, channels = p->pcm_channels; in write_pcm_silence()
217 buffer[p->pcm_positions[c]] = cpu_to_be32(0x40000000); in write_pcm_silence()
218 buffer += s->data_block_quadlets; in write_pcm_silence()
223 * amdtp_am824_add_pcm_hw_constraints - add hw constraints for PCM substream
237 /* AM824 in IEC 61883-6 can deliver 24bit data. */ in amdtp_am824_add_pcm_hw_constraints()
243 * amdtp_am824_midi_trigger - start/stop playback/capture with a MIDI device
255 struct amdtp_am824 *p = s->protocol; in amdtp_am824_midi_trigger()
257 if (port < p->midi_ports) in amdtp_am824_midi_trigger()
258 WRITE_ONCE(p->midi[port], midi); in amdtp_am824_midi_trigger()
264 * device has a FIFO, and track how much it is filled. This values increases
265 * by one whenever we send one byte in a packet, but the FIFO empties at
267 * samples, so the number of bytes that empty out of the FIFO, per packet(!),
274 struct amdtp_am824 *p = s->protocol; in midi_ratelimit_per_packet()
277 used = p->midi_fifo_used[port]; in midi_ratelimit_per_packet()
281 used -= MIDI_BYTES_PER_SECOND * s->syt_interval; in midi_ratelimit_per_packet()
283 p->midi_fifo_used[port] = used; in midi_ratelimit_per_packet()
285 return used < p->midi_fifo_limit; in midi_ratelimit_per_packet()
290 struct amdtp_am824 *p = s->protocol; in midi_rate_use_one_byte()
292 p->midi_fifo_used[port] += amdtp_rate_table[s->sfc]; in midi_rate_use_one_byte()
298 struct amdtp_am824 *p = s->protocol; in write_midi_messages()
303 b = (u8 *)&buffer[p->midi_position]; in write_midi_messages()
308 p->midi[port] != NULL && in write_midi_messages()
309 snd_rawmidi_transmit(p->midi[port], &b[1], 1) == 1) { in write_midi_messages()
319 buffer += s->data_block_quadlets; in write_midi_messages()
326 struct amdtp_am824 *p = s->protocol; in read_midi_messages()
327 int len; in read_midi_messages() local
334 if (!(s->flags & CIP_UNALIGHED_DBC)) in read_midi_messages()
337 b = (u8 *)&buffer[p->midi_position]; in read_midi_messages()
339 len = b[0] - 0x80; in read_midi_messages()
340 if ((1 <= len) && (len <= 3) && (p->midi[port])) in read_midi_messages()
341 snd_rawmidi_receive(p->midi[port], b + 1, len); in read_midi_messages()
343 buffer += s->data_block_quadlets; in read_midi_messages()
350 struct amdtp_am824 *p = s->protocol; in process_it_ctx_payloads()
355 __be32 *buf = desc->ctx_payload; in process_it_ctx_payloads()
356 unsigned int data_blocks = desc->data_blocks; in process_it_ctx_payloads()
360 pcm_frames += data_blocks * s->pcm_frame_multiplier; in process_it_ctx_payloads()
365 if (p->midi_ports) { in process_it_ctx_payloads()
367 desc->data_block_counter); in process_it_ctx_payloads()
377 struct amdtp_am824 *p = s->protocol; in process_ir_ctx_payloads()
382 __be32 *buf = desc->ctx_payload; in process_ir_ctx_payloads()
383 unsigned int data_blocks = desc->data_blocks; in process_ir_ctx_payloads()
387 pcm_frames += data_blocks * s->pcm_frame_multiplier; in process_ir_ctx_payloads()
390 if (p->midi_ports) { in process_ir_ctx_payloads()
392 desc->data_block_counter); in process_ir_ctx_payloads()
400 * amdtp_am824_init - initialize an AMDTP stream structure to handle AM824
405 * @flags: the details of the streaming protocol consist of cip_flags enumeration-constants.