1 // SPDX-License-Identifier: GPL-2.0 2 // ff-protocol-latter - a part of driver for RME Fireface series 3 // 4 // Copyright (c) 2019 Takashi Sakamoto 5 // 6 // Licensed under the terms of the GNU General Public License, version 2. 7 8 #include <linux/delay.h> 9 10 #include "ff.h" 11 12 #define LATTER_STF 0xffff00000004ULL 13 #define LATTER_ISOC_CHANNELS 0xffff00000008ULL 14 #define LATTER_ISOC_START 0xffff0000000cULL 15 #define LATTER_FETCH_MODE 0xffff00000010ULL 16 #define LATTER_SYNC_STATUS 0x0000801c0000ULL 17 18 static int parse_clock_bits(u32 data, unsigned int *rate, 19 enum snd_ff_clock_src *src, 20 enum snd_ff_unit_version unit_version) 21 { 22 static const struct { 23 unsigned int rate; 24 u32 flag; 25 } *rate_entry, rate_entries[] = { 26 { 32000, 0x00000000, }, 27 { 44100, 0x01000000, }, 28 { 48000, 0x02000000, }, 29 { 64000, 0x04000000, }, 30 { 88200, 0x05000000, }, 31 { 96000, 0x06000000, }, 32 { 128000, 0x08000000, }, 33 { 176400, 0x09000000, }, 34 { 192000, 0x0a000000, }, 35 }; 36 static const struct { 37 enum snd_ff_clock_src src; 38 u32 flag; 39 } *clk_entry, clk_entries[] = { 40 { SND_FF_CLOCK_SRC_SPDIF, 0x00000200, }, 41 { SND_FF_CLOCK_SRC_ADAT1, 0x00000400, }, 42 { SND_FF_CLOCK_SRC_WORD, 0x00000600, }, 43 { SND_FF_CLOCK_SRC_INTERNAL, 0x00000e00, }, 44 }; 45 int i; 46 47 if (unit_version != SND_FF_UNIT_VERSION_UCX) { 48 // e.g. 0x00fe0f20 but expected 0x00eff002. 49 data = ((data & 0xf0f0f0f0) >> 4) | ((data & 0x0f0f0f0f) << 4); 50 } 51 52 for (i = 0; i < ARRAY_SIZE(rate_entries); ++i) { 53 rate_entry = rate_entries + i; 54 if ((data & 0x0f000000) == rate_entry->flag) { 55 *rate = rate_entry->rate; 56 break; 57 } 58 } 59 if (i == ARRAY_SIZE(rate_entries)) 60 return -EIO; 61 62 for (i = 0; i < ARRAY_SIZE(clk_entries); ++i) { 63 clk_entry = clk_entries + i; 64 if ((data & 0x000e00) == clk_entry->flag) { 65 *src = clk_entry->src; 66 break; 67 } 68 } 69 if (i == ARRAY_SIZE(clk_entries)) 70 return -EIO; 71 72 return 0; 73 } 74 75 static int latter_get_clock(struct snd_ff *ff, unsigned int *rate, 76 enum snd_ff_clock_src *src) 77 { 78 __le32 reg; 79 u32 data; 80 int err; 81 82 err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST, 83 LATTER_SYNC_STATUS, ®, sizeof(reg), 0); 84 if (err < 0) 85 return err; 86 data = le32_to_cpu(reg); 87 88 return parse_clock_bits(data, rate, src, ff->unit_version); 89 } 90 91 static int latter_switch_fetching_mode(struct snd_ff *ff, bool enable) 92 { 93 u32 data; 94 __le32 reg; 95 96 if (enable) 97 data = 0x00000000; 98 else 99 data = 0xffffffff; 100 reg = cpu_to_le32(data); 101 102 return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, 103 LATTER_FETCH_MODE, ®, sizeof(reg), 0); 104 } 105 106 static int latter_allocate_resources(struct snd_ff *ff, unsigned int rate) 107 { 108 enum snd_ff_stream_mode mode; 109 unsigned int code; 110 __le32 reg; 111 unsigned int count; 112 int i; 113 int err; 114 115 // Set the number of data blocks transferred in a second. 116 if (rate % 48000 == 0) 117 code = 0x04; 118 else if (rate % 44100 == 0) 119 code = 0x02; 120 else if (rate % 32000 == 0) 121 code = 0x00; 122 else 123 return -EINVAL; 124 125 if (rate >= 64000 && rate < 128000) 126 code |= 0x08; 127 else if (rate >= 128000) 128 code |= 0x10; 129 130 reg = cpu_to_le32(code); 131 err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, 132 LATTER_STF, ®, sizeof(reg), 0); 133 if (err < 0) 134 return err; 135 136 // Confirm to shift transmission clock. 137 count = 0; 138 while (count++ < 10) { 139 unsigned int curr_rate; 140 enum snd_ff_clock_src src; 141 142 err = latter_get_clock(ff, &curr_rate, &src); 143 if (err < 0) 144 return err; 145 146 if (curr_rate == rate) 147 break; 148 } 149 if (count > 10) 150 return -ETIMEDOUT; 151 152 for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); ++i) { 153 if (rate == amdtp_rate_table[i]) 154 break; 155 } 156 if (i == ARRAY_SIZE(amdtp_rate_table)) 157 return -EINVAL; 158 159 err = snd_ff_stream_get_multiplier_mode(i, &mode); 160 if (err < 0) 161 return err; 162 163 // Keep resources for in-stream. 164 ff->tx_resources.channels_mask = 0x00000000000000ffuLL; 165 err = fw_iso_resources_allocate(&ff->tx_resources, 166 amdtp_stream_get_max_payload(&ff->tx_stream), 167 fw_parent_device(ff->unit)->max_speed); 168 if (err < 0) 169 return err; 170 171 // Keep resources for out-stream. 172 ff->rx_resources.channels_mask = 0x00000000000000ffuLL; 173 err = fw_iso_resources_allocate(&ff->rx_resources, 174 amdtp_stream_get_max_payload(&ff->rx_stream), 175 fw_parent_device(ff->unit)->max_speed); 176 if (err < 0) 177 fw_iso_resources_free(&ff->tx_resources); 178 179 return err; 180 } 181 182 static int latter_begin_session(struct snd_ff *ff, unsigned int rate) 183 { 184 unsigned int generation = ff->rx_resources.generation; 185 unsigned int flag; 186 u32 data; 187 __le32 reg; 188 int err; 189 190 if (ff->unit_version == SND_FF_UNIT_VERSION_UCX) { 191 // For Fireface UCX. Always use the maximum number of data 192 // channels in data block of packet. 193 if (rate >= 32000 && rate <= 48000) 194 flag = 0x92; 195 else if (rate >= 64000 && rate <= 96000) 196 flag = 0x8e; 197 else if (rate >= 128000 && rate <= 192000) 198 flag = 0x8c; 199 else 200 return -EINVAL; 201 } else { 202 // For Fireface UFX and 802. Due to bandwidth limitation on 203 // IEEE 1394a (400 Mbps), Analog 1-12 and AES are available 204 // without any ADAT at quadruple speed. 205 if (rate >= 32000 && rate <= 48000) 206 flag = 0x9e; 207 else if (rate >= 64000 && rate <= 96000) 208 flag = 0x96; 209 else if (rate >= 128000 && rate <= 192000) 210 flag = 0x8e; 211 else 212 return -EINVAL; 213 } 214 215 if (generation != fw_parent_device(ff->unit)->card->generation) { 216 err = fw_iso_resources_update(&ff->tx_resources); 217 if (err < 0) 218 return err; 219 220 err = fw_iso_resources_update(&ff->rx_resources); 221 if (err < 0) 222 return err; 223 } 224 225 data = (ff->tx_resources.channel << 8) | ff->rx_resources.channel; 226 reg = cpu_to_le32(data); 227 err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, 228 LATTER_ISOC_CHANNELS, ®, sizeof(reg), 0); 229 if (err < 0) 230 return err; 231 232 reg = cpu_to_le32(flag); 233 return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, 234 LATTER_ISOC_START, ®, sizeof(reg), 0); 235 } 236 237 static void latter_finish_session(struct snd_ff *ff) 238 { 239 __le32 reg; 240 241 reg = cpu_to_le32(0x00000000); 242 snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, 243 LATTER_ISOC_START, ®, sizeof(reg), 0); 244 } 245 246 static void latter_dump_status(struct snd_ff *ff, struct snd_info_buffer *buffer) 247 { 248 static const struct { 249 char *const label; 250 u32 locked_mask; 251 u32 synced_mask; 252 } *clk_entry, clk_entries[] = { 253 { "S/PDIF", 0x00000001, 0x00000010, }, 254 { "ADAT", 0x00000002, 0x00000020, }, 255 { "WDClk", 0x00000004, 0x00000040, }, 256 }; 257 __le32 reg; 258 u32 data; 259 unsigned int rate; 260 enum snd_ff_clock_src src; 261 const char *label; 262 int i; 263 int err; 264 265 err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST, 266 LATTER_SYNC_STATUS, ®, sizeof(reg), 0); 267 if (err < 0) 268 return; 269 data = le32_to_cpu(reg); 270 271 snd_iprintf(buffer, "External source detection:\n"); 272 273 for (i = 0; i < ARRAY_SIZE(clk_entries); ++i) { 274 clk_entry = clk_entries + i; 275 snd_iprintf(buffer, "%s: ", clk_entry->label); 276 if (data & clk_entry->locked_mask) { 277 if (data & clk_entry->synced_mask) 278 snd_iprintf(buffer, "sync\n"); 279 else 280 snd_iprintf(buffer, "lock\n"); 281 } else { 282 snd_iprintf(buffer, "none\n"); 283 } 284 } 285 286 err = parse_clock_bits(data, &rate, &src, ff->unit_version); 287 if (err < 0) 288 return; 289 label = snd_ff_proc_get_clk_label(src); 290 if (!label) 291 return; 292 293 snd_iprintf(buffer, "Referred clock: %s %d\n", label, rate); 294 } 295 296 // NOTE: transactions are transferred within 0x00-0x7f in allocated range of 297 // address. This seems to be for check of discontinuity in receiver side. 298 // 299 // Like Fireface 400, drivers can select one of 4 options for lower 4 bytes of 300 // destination address by bit flags in quadlet register (little endian) at 301 // 0x'ffff'0000'0014: 302 // 303 // bit flags: offset of destination address 304 // - 0x00002000: 0x'....'....'0000'0000 305 // - 0x00004000: 0x'....'....'0000'0080 306 // - 0x00008000: 0x'....'....'0000'0100 307 // - 0x00010000: 0x'....'....'0000'0180 308 // 309 // Drivers can suppress the device to transfer asynchronous transactions by 310 // clear these bit flags. 311 // 312 // Actually, the register is write-only and includes the other settings such as 313 // input attenuation. This driver allocates for the first option 314 // (0x'....'....'0000'0000) and expects userspace application to configure the 315 // register for it. 316 static void latter_handle_midi_msg(struct snd_ff *ff, unsigned int offset, 317 __le32 *buf, size_t length) 318 { 319 u32 data = le32_to_cpu(*buf); 320 unsigned int index = (data & 0x000000f0) >> 4; 321 u8 byte[3]; 322 struct snd_rawmidi_substream *substream; 323 unsigned int len; 324 325 if (index >= ff->spec->midi_in_ports) 326 return; 327 328 switch (data & 0x0000000f) { 329 case 0x00000008: 330 case 0x00000009: 331 case 0x0000000a: 332 case 0x0000000b: 333 case 0x0000000e: 334 len = 3; 335 break; 336 case 0x0000000c: 337 case 0x0000000d: 338 len = 2; 339 break; 340 default: 341 len = data & 0x00000003; 342 if (len == 0) 343 len = 3; 344 break; 345 } 346 347 byte[0] = (data & 0x0000ff00) >> 8; 348 byte[1] = (data & 0x00ff0000) >> 16; 349 byte[2] = (data & 0xff000000) >> 24; 350 351 substream = READ_ONCE(ff->tx_midi_substreams[index]); 352 if (substream) 353 snd_rawmidi_receive(substream, byte, len); 354 } 355 356 /* 357 * When return minus value, given argument is not MIDI status. 358 * When return 0, given argument is a beginning of system exclusive. 359 * When return the others, given argument is MIDI data. 360 */ 361 static inline int calculate_message_bytes(u8 status) 362 { 363 switch (status) { 364 case 0xf6: /* Tune request. */ 365 case 0xf8: /* Timing clock. */ 366 case 0xfa: /* Start. */ 367 case 0xfb: /* Continue. */ 368 case 0xfc: /* Stop. */ 369 case 0xfe: /* Active sensing. */ 370 case 0xff: /* System reset. */ 371 return 1; 372 case 0xf1: /* MIDI time code quarter frame. */ 373 case 0xf3: /* Song select. */ 374 return 2; 375 case 0xf2: /* Song position pointer. */ 376 return 3; 377 case 0xf0: /* Exclusive. */ 378 return 0; 379 case 0xf7: /* End of exclusive. */ 380 break; 381 case 0xf4: /* Undefined. */ 382 case 0xf5: /* Undefined. */ 383 case 0xf9: /* Undefined. */ 384 case 0xfd: /* Undefined. */ 385 break; 386 default: 387 switch (status & 0xf0) { 388 case 0x80: /* Note on. */ 389 case 0x90: /* Note off. */ 390 case 0xa0: /* Polyphonic key pressure. */ 391 case 0xb0: /* Control change and Mode change. */ 392 case 0xe0: /* Pitch bend change. */ 393 return 3; 394 case 0xc0: /* Program change. */ 395 case 0xd0: /* Channel pressure. */ 396 return 2; 397 default: 398 break; 399 } 400 break; 401 } 402 403 return -EINVAL; 404 } 405 406 static int latter_fill_midi_msg(struct snd_ff *ff, 407 struct snd_rawmidi_substream *substream, 408 unsigned int port) 409 { 410 u32 data = {0}; 411 u8 *buf = (u8 *)&data; 412 int consumed; 413 414 buf[0] = port << 4; 415 consumed = snd_rawmidi_transmit_peek(substream, buf + 1, 3); 416 if (consumed <= 0) 417 return consumed; 418 419 if (!ff->on_sysex[port]) { 420 if (buf[1] != 0xf0) { 421 if (consumed < calculate_message_bytes(buf[1])) 422 return 0; 423 } else { 424 // The beginning of exclusives. 425 ff->on_sysex[port] = true; 426 } 427 428 buf[0] |= consumed; 429 } else { 430 if (buf[1] != 0xf7) { 431 if (buf[2] == 0xf7 || buf[3] == 0xf7) { 432 // Transfer end code at next time. 433 consumed -= 1; 434 } 435 436 buf[0] |= consumed; 437 } else { 438 // The end of exclusives. 439 ff->on_sysex[port] = false; 440 consumed = 1; 441 buf[0] |= 0x0f; 442 } 443 } 444 445 ff->msg_buf[port][0] = cpu_to_le32(data); 446 ff->rx_bytes[port] = consumed; 447 448 return 1; 449 } 450 451 const struct snd_ff_protocol snd_ff_protocol_latter = { 452 .handle_midi_msg = latter_handle_midi_msg, 453 .fill_midi_msg = latter_fill_midi_msg, 454 .get_clock = latter_get_clock, 455 .switch_fetching_mode = latter_switch_fetching_mode, 456 .allocate_resources = latter_allocate_resources, 457 .begin_session = latter_begin_session, 458 .finish_session = latter_finish_session, 459 .dump_status = latter_dump_status, 460 }; 461