Commit | Line | Data |
---|---|---|
5955815e TS |
1 | /* |
2 | * AM824 format in Audio and Music Data Transmission Protocol (IEC 61883-6) | |
3 | * | |
4 | * Copyright (c) 2015 Takashi Sakamoto <o-takashi@sakamocchi.jp> | |
5 | * | |
6 | * Licensed under the terms of the GNU General Public License, version 2. | |
7 | */ | |
8 | ||
9 | #include "amdtp-am824.h" | |
10 | ||
11 | #define CIP_FMT_AM 0x10 | |
12 | ||
51c29fd2 TS |
13 | /* "Clock-based rate control mode" is just supported. */ |
14 | #define AMDTP_FDF_AM824 0x00 | |
15 | ||
16 | /** | |
17 | * amdtp_am824_set_parameters - set stream parameters | |
18 | * @s: the AMDTP stream to configure | |
19 | * @rate: the sample rate | |
20 | * @pcm_channels: the number of PCM samples in each data block, to be encoded | |
21 | * as AM824 multi-bit linear audio | |
22 | * @midi_ports: the number of MIDI ports (i.e., MPX-MIDI Data Channels) | |
23 | * @double_pcm_frames: one data block transfers two PCM frames | |
24 | * | |
25 | * The parameters must be set before the stream is started, and must not be | |
26 | * changed while the stream is running. | |
27 | */ | |
28 | int amdtp_am824_set_parameters(struct amdtp_stream *s, unsigned int rate, | |
29 | unsigned int pcm_channels, | |
30 | unsigned int midi_ports, | |
31 | bool double_pcm_frames) | |
32 | { | |
33 | int err; | |
34 | ||
35 | err = amdtp_stream_set_parameters(s, rate, pcm_channels, midi_ports); | |
36 | if (err < 0) | |
37 | return err; | |
38 | ||
39 | s->fdf = AMDTP_FDF_AM824 | s->sfc; | |
40 | ||
41 | /* | |
42 | * In IEC 61883-6, one data block represents one event. In ALSA, one | |
43 | * event equals to one PCM frame. But Dice has a quirk at higher | |
44 | * sampling rate to transfer two PCM frames in one data block. | |
45 | */ | |
46 | if (double_pcm_frames) | |
47 | s->frame_multiplier = 2; | |
48 | else | |
49 | s->frame_multiplier = 1; | |
50 | ||
51 | return 0; | |
52 | } | |
53 | EXPORT_SYMBOL_GPL(amdtp_am824_set_parameters); | |
54 | ||
f65be911 TS |
55 | /** |
56 | * amdtp_am824_set_pcm_position - set an index of data channel for a channel | |
57 | * of PCM frame | |
58 | * @s: the AMDTP stream | |
59 | * @index: the index of data channel in an data block | |
60 | * @position: the channel of PCM frame | |
61 | */ | |
62 | void amdtp_am824_set_pcm_position(struct amdtp_stream *s, unsigned int index, | |
63 | unsigned int position) | |
64 | { | |
65 | if (index < s->pcm_channels) | |
66 | s->pcm_positions[index] = position; | |
67 | } | |
68 | EXPORT_SYMBOL_GPL(amdtp_am824_set_pcm_position); | |
69 | ||
70 | /** | |
71 | * amdtp_am824_set_midi_position - set a index of data channel for MIDI | |
72 | * conformant data channel | |
73 | * @s: the AMDTP stream | |
74 | * @position: the index of data channel in an data block | |
75 | */ | |
76 | void amdtp_am824_set_midi_position(struct amdtp_stream *s, | |
77 | unsigned int position) | |
78 | { | |
79 | s->midi_position = position; | |
80 | } | |
81 | EXPORT_SYMBOL_GPL(amdtp_am824_set_midi_position); | |
82 | ||
bc8500da TS |
83 | /** |
84 | * amdtp_am824_add_pcm_hw_constraints - add hw constraints for PCM substream | |
85 | * @s: the AMDTP stream for AM824 data block, must be initialized. | |
86 | * @runtime: the PCM substream runtime | |
87 | * | |
88 | */ | |
89 | int amdtp_am824_add_pcm_hw_constraints(struct amdtp_stream *s, | |
90 | struct snd_pcm_runtime *runtime) | |
91 | { | |
92 | int err; | |
93 | ||
94 | err = amdtp_stream_add_pcm_hw_constraints(s, runtime); | |
95 | if (err < 0) | |
96 | return err; | |
97 | ||
98 | /* AM824 in IEC 61883-6 can deliver 24bit data. */ | |
99 | return snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); | |
100 | } | |
101 | EXPORT_SYMBOL_GPL(amdtp_am824_add_pcm_hw_constraints); | |
102 | ||
5955815e TS |
103 | /** |
104 | * amdtp_am824_init - initialize an AMDTP stream structure to handle AM824 | |
105 | * data block | |
106 | * @s: the AMDTP stream to initialize | |
107 | * @unit: the target of the stream | |
108 | * @dir: the direction of stream | |
109 | * @flags: the packet transmission method to use | |
110 | */ | |
111 | int amdtp_am824_init(struct amdtp_stream *s, struct fw_unit *unit, | |
112 | enum amdtp_stream_direction dir, enum cip_flags flags) | |
113 | { | |
114 | return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM); | |
115 | } | |
116 | EXPORT_SYMBOL_GPL(amdtp_am824_init); |