.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
---|
1 | 2 | /* |
---|
2 | 3 | * motu.h - a part of driver for MOTU FireWire series |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp> |
---|
5 | | - * |
---|
6 | | - * Licensed under the terms of the GNU General Public License, version 2. |
---|
7 | 6 | */ |
---|
8 | 7 | |
---|
9 | 8 | #ifndef SOUND_FIREWIRE_MOTU_H_INCLUDED |
---|
.. | .. |
---|
37 | 36 | unsigned char pcm_byte_offset; |
---|
38 | 37 | |
---|
39 | 38 | unsigned char msg_chunks; |
---|
40 | | - unsigned char fixed_part_pcm_chunks[3]; |
---|
41 | | - unsigned char differed_part_pcm_chunks[3]; |
---|
| 39 | + unsigned char pcm_chunks[3]; |
---|
42 | 40 | }; |
---|
43 | 41 | |
---|
44 | 42 | struct snd_motu { |
---|
.. | .. |
---|
60 | 58 | struct amdtp_stream rx_stream; |
---|
61 | 59 | struct fw_iso_resources tx_resources; |
---|
62 | 60 | struct fw_iso_resources rx_resources; |
---|
63 | | - unsigned int capture_substreams; |
---|
64 | | - unsigned int playback_substreams; |
---|
| 61 | + unsigned int substreams_counter; |
---|
65 | 62 | |
---|
66 | 63 | /* For notification. */ |
---|
67 | 64 | struct fw_address_handler async_handler; |
---|
.. | .. |
---|
71 | 68 | int dev_lock_count; |
---|
72 | 69 | bool dev_lock_changed; |
---|
73 | 70 | wait_queue_head_t hwdep_wait; |
---|
| 71 | + |
---|
| 72 | + struct amdtp_domain domain; |
---|
74 | 73 | }; |
---|
75 | 74 | |
---|
76 | 75 | enum snd_motu_spec_flags { |
---|
77 | | - SND_MOTU_SPEC_SUPPORT_CLOCK_X2 = 0x0001, |
---|
78 | | - SND_MOTU_SPEC_SUPPORT_CLOCK_X4 = 0x0002, |
---|
79 | | - SND_MOTU_SPEC_TX_MICINST_CHUNK = 0x0004, |
---|
80 | | - SND_MOTU_SPEC_TX_RETURN_CHUNK = 0x0008, |
---|
81 | | - SND_MOTU_SPEC_TX_REVERB_CHUNK = 0x0010, |
---|
82 | | - SND_MOTU_SPEC_HAS_AESEBU_IFACE = 0x0020, |
---|
83 | | - SND_MOTU_SPEC_HAS_OPT_IFACE_A = 0x0040, |
---|
84 | | - SND_MOTU_SPEC_HAS_OPT_IFACE_B = 0x0080, |
---|
85 | | - SND_MOTU_SPEC_RX_MIDI_2ND_Q = 0x0100, |
---|
86 | | - SND_MOTU_SPEC_RX_MIDI_3RD_Q = 0x0200, |
---|
87 | | - SND_MOTU_SPEC_TX_MIDI_2ND_Q = 0x0400, |
---|
88 | | - SND_MOTU_SPEC_TX_MIDI_3RD_Q = 0x0800, |
---|
89 | | - SND_MOTU_SPEC_RX_SEPARETED_MAIN = 0x1000, |
---|
| 76 | + SND_MOTU_SPEC_RX_MIDI_2ND_Q = 0x0001, |
---|
| 77 | + SND_MOTU_SPEC_RX_MIDI_3RD_Q = 0x0002, |
---|
| 78 | + SND_MOTU_SPEC_TX_MIDI_2ND_Q = 0x0004, |
---|
| 79 | + SND_MOTU_SPEC_TX_MIDI_3RD_Q = 0x0008, |
---|
90 | 80 | }; |
---|
91 | 81 | |
---|
92 | 82 | #define SND_MOTU_CLOCK_RATE_COUNT 6 |
---|
.. | .. |
---|
104 | 94 | SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX, |
---|
105 | 95 | SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR, |
---|
106 | 96 | SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC, |
---|
| 97 | + SND_MOTU_CLOCK_SOURCE_SPH, |
---|
107 | 98 | SND_MOTU_CLOCK_SOURCE_UNKNOWN, |
---|
108 | 99 | }; |
---|
109 | 100 | |
---|
110 | | -struct snd_motu_protocol { |
---|
111 | | - int (*get_clock_rate)(struct snd_motu *motu, unsigned int *rate); |
---|
112 | | - int (*set_clock_rate)(struct snd_motu *motu, unsigned int rate); |
---|
113 | | - int (*get_clock_source)(struct snd_motu *motu, |
---|
114 | | - enum snd_motu_clock_source *source); |
---|
115 | | - int (*switch_fetching_mode)(struct snd_motu *motu, bool enable); |
---|
116 | | - int (*cache_packet_formats)(struct snd_motu *motu); |
---|
| 101 | +enum snd_motu_protocol_version { |
---|
| 102 | + SND_MOTU_PROTOCOL_V2, |
---|
| 103 | + SND_MOTU_PROTOCOL_V3, |
---|
117 | 104 | }; |
---|
118 | 105 | |
---|
119 | 106 | struct snd_motu_spec { |
---|
120 | 107 | const char *const name; |
---|
| 108 | + enum snd_motu_protocol_version protocol_version; |
---|
121 | 109 | enum snd_motu_spec_flags flags; |
---|
122 | 110 | |
---|
123 | | - unsigned char analog_in_ports; |
---|
124 | | - unsigned char analog_out_ports; |
---|
125 | | - |
---|
126 | | - const struct snd_motu_protocol *const protocol; |
---|
| 111 | + unsigned char tx_fixed_pcm_chunks[3]; |
---|
| 112 | + unsigned char rx_fixed_pcm_chunks[3]; |
---|
127 | 113 | }; |
---|
128 | 114 | |
---|
129 | | -extern const struct snd_motu_protocol snd_motu_protocol_v2; |
---|
130 | | -extern const struct snd_motu_protocol snd_motu_protocol_v3; |
---|
131 | | - |
---|
| 115 | +extern const struct snd_motu_spec snd_motu_spec_828mk2; |
---|
132 | 116 | extern const struct snd_motu_spec snd_motu_spec_traveler; |
---|
| 117 | +extern const struct snd_motu_spec snd_motu_spec_ultralite; |
---|
| 118 | +extern const struct snd_motu_spec snd_motu_spec_8pre; |
---|
| 119 | + |
---|
| 120 | +extern const struct snd_motu_spec snd_motu_spec_828mk3; |
---|
| 121 | +extern const struct snd_motu_spec snd_motu_spec_ultralite_mk3; |
---|
| 122 | +extern const struct snd_motu_spec snd_motu_spec_audio_express; |
---|
| 123 | +extern const struct snd_motu_spec snd_motu_spec_4pre; |
---|
133 | 124 | |
---|
134 | 125 | int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit, |
---|
135 | 126 | enum amdtp_stream_direction dir, |
---|
136 | | - const struct snd_motu_protocol *const protocol); |
---|
| 127 | + const struct snd_motu_spec *spec); |
---|
137 | 128 | int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate, |
---|
138 | 129 | unsigned int midi_ports, |
---|
139 | 130 | struct snd_motu_packet_format *formats); |
---|
.. | .. |
---|
153 | 144 | int snd_motu_stream_init_duplex(struct snd_motu *motu); |
---|
154 | 145 | void snd_motu_stream_destroy_duplex(struct snd_motu *motu); |
---|
155 | 146 | int snd_motu_stream_cache_packet_formats(struct snd_motu *motu); |
---|
156 | | -int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate); |
---|
| 147 | +int snd_motu_stream_reserve_duplex(struct snd_motu *motu, unsigned int rate, |
---|
| 148 | + unsigned int frames_per_period, |
---|
| 149 | + unsigned int frames_per_buffer); |
---|
| 150 | +int snd_motu_stream_start_duplex(struct snd_motu *motu); |
---|
157 | 151 | void snd_motu_stream_stop_duplex(struct snd_motu *motu); |
---|
158 | 152 | int snd_motu_stream_lock_try(struct snd_motu *motu); |
---|
159 | 153 | void snd_motu_stream_lock_release(struct snd_motu *motu); |
---|
.. | .. |
---|
165 | 159 | int snd_motu_create_midi_devices(struct snd_motu *motu); |
---|
166 | 160 | |
---|
167 | 161 | int snd_motu_create_hwdep_device(struct snd_motu *motu); |
---|
| 162 | + |
---|
| 163 | +int snd_motu_protocol_v2_get_clock_rate(struct snd_motu *motu, |
---|
| 164 | + unsigned int *rate); |
---|
| 165 | +int snd_motu_protocol_v2_set_clock_rate(struct snd_motu *motu, |
---|
| 166 | + unsigned int rate); |
---|
| 167 | +int snd_motu_protocol_v2_get_clock_source(struct snd_motu *motu, |
---|
| 168 | + enum snd_motu_clock_source *src); |
---|
| 169 | +int snd_motu_protocol_v2_switch_fetching_mode(struct snd_motu *motu, |
---|
| 170 | + bool enable); |
---|
| 171 | +int snd_motu_protocol_v2_cache_packet_formats(struct snd_motu *motu); |
---|
| 172 | + |
---|
| 173 | +int snd_motu_protocol_v3_get_clock_rate(struct snd_motu *motu, |
---|
| 174 | + unsigned int *rate); |
---|
| 175 | +int snd_motu_protocol_v3_set_clock_rate(struct snd_motu *motu, |
---|
| 176 | + unsigned int rate); |
---|
| 177 | +int snd_motu_protocol_v3_get_clock_source(struct snd_motu *motu, |
---|
| 178 | + enum snd_motu_clock_source *src); |
---|
| 179 | +int snd_motu_protocol_v3_switch_fetching_mode(struct snd_motu *motu, |
---|
| 180 | + bool enable); |
---|
| 181 | +int snd_motu_protocol_v3_cache_packet_formats(struct snd_motu *motu); |
---|
| 182 | + |
---|
| 183 | +static inline int snd_motu_protocol_get_clock_rate(struct snd_motu *motu, |
---|
| 184 | + unsigned int *rate) |
---|
| 185 | +{ |
---|
| 186 | + if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2) |
---|
| 187 | + return snd_motu_protocol_v2_get_clock_rate(motu, rate); |
---|
| 188 | + else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3) |
---|
| 189 | + return snd_motu_protocol_v3_get_clock_rate(motu, rate); |
---|
| 190 | + else |
---|
| 191 | + return -ENXIO; |
---|
| 192 | +} |
---|
| 193 | + |
---|
| 194 | +static inline int snd_motu_protocol_set_clock_rate(struct snd_motu *motu, |
---|
| 195 | + unsigned int rate) |
---|
| 196 | +{ |
---|
| 197 | + if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2) |
---|
| 198 | + return snd_motu_protocol_v2_set_clock_rate(motu, rate); |
---|
| 199 | + else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3) |
---|
| 200 | + return snd_motu_protocol_v3_set_clock_rate(motu, rate); |
---|
| 201 | + else |
---|
| 202 | + return -ENXIO; |
---|
| 203 | +} |
---|
| 204 | + |
---|
| 205 | +static inline int snd_motu_protocol_get_clock_source(struct snd_motu *motu, |
---|
| 206 | + enum snd_motu_clock_source *source) |
---|
| 207 | +{ |
---|
| 208 | + if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2) |
---|
| 209 | + return snd_motu_protocol_v2_get_clock_source(motu, source); |
---|
| 210 | + else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3) |
---|
| 211 | + return snd_motu_protocol_v3_get_clock_source(motu, source); |
---|
| 212 | + else |
---|
| 213 | + return -ENXIO; |
---|
| 214 | +} |
---|
| 215 | + |
---|
| 216 | +static inline int snd_motu_protocol_switch_fetching_mode(struct snd_motu *motu, |
---|
| 217 | + bool enable) |
---|
| 218 | +{ |
---|
| 219 | + if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2) |
---|
| 220 | + return snd_motu_protocol_v2_switch_fetching_mode(motu, enable); |
---|
| 221 | + else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3) |
---|
| 222 | + return snd_motu_protocol_v3_switch_fetching_mode(motu, enable); |
---|
| 223 | + else |
---|
| 224 | + return -ENXIO; |
---|
| 225 | +} |
---|
| 226 | + |
---|
| 227 | +static inline int snd_motu_protocol_cache_packet_formats(struct snd_motu *motu) |
---|
| 228 | +{ |
---|
| 229 | + if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2) |
---|
| 230 | + return snd_motu_protocol_v2_cache_packet_formats(motu); |
---|
| 231 | + else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3) |
---|
| 232 | + return snd_motu_protocol_v3_cache_packet_formats(motu); |
---|
| 233 | + else |
---|
| 234 | + return -ENXIO; |
---|
| 235 | +} |
---|
| 236 | + |
---|
168 | 237 | #endif |
---|