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