| .. | .. |
|---|
| 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 |
|---|