linux/sound/firewire/fireface/ff-protocol-ff400.c
<<
>>
Prefs
   1/*
   2 * ff-protocol-ff400.c - a part of driver for RME Fireface series
   3 *
   4 * Copyright (c) 2015-2017 Takashi Sakamoto
   5 *
   6 * Licensed under the terms of the GNU General Public License, version 2.
   7 */
   8
   9#include <linux/delay.h>
  10#include "ff.h"
  11
  12#define FF400_STF               0x000080100500ull
  13#define FF400_RX_PACKET_FORMAT  0x000080100504ull
  14#define FF400_ISOC_COMM_START   0x000080100508ull
  15#define FF400_TX_PACKET_FORMAT  0x00008010050cull
  16#define FF400_ISOC_COMM_STOP    0x000080100510ull
  17#define FF400_SYNC_STATUS       0x0000801c0000ull
  18#define FF400_FETCH_PCM_FRAMES  0x0000801c0000ull       /* For block request. */
  19#define FF400_CLOCK_CONFIG      0x0000801c0004ull
  20
  21#define FF400_MIDI_HIGH_ADDR    0x0000801003f4ull
  22#define FF400_MIDI_RX_PORT_0    0x000080180000ull
  23#define FF400_MIDI_RX_PORT_1    0x000080190000ull
  24
  25static int ff400_get_clock(struct snd_ff *ff, unsigned int *rate,
  26                           enum snd_ff_clock_src *src)
  27{
  28        __le32 reg;
  29        u32 data;
  30        int err;
  31
  32        err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST,
  33                                 FF400_SYNC_STATUS, &reg, sizeof(reg), 0);
  34        if (err < 0)
  35                return err;
  36        data = le32_to_cpu(reg);
  37
  38        /* Calculate sampling rate. */
  39        switch ((data >> 1) & 0x03) {
  40        case 0x01:
  41                *rate = 32000;
  42                break;
  43        case 0x00:
  44                *rate = 44100;
  45                break;
  46        case 0x03:
  47                *rate = 48000;
  48                break;
  49        case 0x02:
  50        default:
  51                return -EIO;
  52        }
  53
  54        if (data & 0x08)
  55                *rate *= 2;
  56        else if (data & 0x10)
  57                *rate *= 4;
  58
  59        /* Calculate source of clock. */
  60        if (data & 0x01) {
  61                *src = SND_FF_CLOCK_SRC_INTERNAL;
  62        } else {
  63                /* TODO: 0x00, 0x01, 0x02, 0x06, 0x07? */
  64                switch ((data >> 10) & 0x07) {
  65                case 0x03:
  66                        *src = SND_FF_CLOCK_SRC_SPDIF;
  67                        break;
  68                case 0x04:
  69                        *src = SND_FF_CLOCK_SRC_WORD;
  70                        break;
  71                case 0x05:
  72                        *src = SND_FF_CLOCK_SRC_LTC;
  73                        break;
  74                case 0x00:
  75                default:
  76                        *src = SND_FF_CLOCK_SRC_ADAT;
  77                        break;
  78                }
  79        }
  80
  81        return 0;
  82}
  83
  84static int ff400_begin_session(struct snd_ff *ff, unsigned int rate)
  85{
  86        __le32 reg;
  87        int i, err;
  88
  89        /* Check whether the given value is supported or not. */
  90        for (i = 0; i < CIP_SFC_COUNT; i++) {
  91                if (amdtp_rate_table[i] == rate)
  92                        break;
  93        }
  94        if (i == CIP_SFC_COUNT)
  95                return -EINVAL;
  96
  97        /* Set the number of data blocks transferred in a second. */
  98        reg = cpu_to_le32(rate);
  99        err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
 100                                 FF400_STF, &reg, sizeof(reg), 0);
 101        if (err < 0)
 102                return err;
 103
 104        msleep(100);
 105
 106        /*
 107         * Set isochronous channel and the number of quadlets of received
 108         * packets.
 109         */
 110        reg = cpu_to_le32(((ff->rx_stream.data_block_quadlets << 3) << 8) |
 111                          ff->rx_resources.channel);
 112        err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
 113                                 FF400_RX_PACKET_FORMAT, &reg, sizeof(reg), 0);
 114        if (err < 0)
 115                return err;
 116
 117        /*
 118         * Set isochronous channel and the number of quadlets of transmitted
 119         * packet.
 120         */
 121        /* TODO: investigate the purpose of this 0x80. */
 122        reg = cpu_to_le32((0x80 << 24) |
 123                          (ff->tx_resources.channel << 5) |
 124                          (ff->tx_stream.data_block_quadlets));
 125        err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
 126                                 FF400_TX_PACKET_FORMAT, &reg, sizeof(reg), 0);
 127        if (err < 0)
 128                return err;
 129
 130        /* Allow to transmit packets. */
 131        reg = cpu_to_le32(0x00000001);
 132        return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
 133                                 FF400_ISOC_COMM_START, &reg, sizeof(reg), 0);
 134}
 135
 136static void ff400_finish_session(struct snd_ff *ff)
 137{
 138        __le32 reg;
 139
 140        reg = cpu_to_le32(0x80000000);
 141        snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
 142                           FF400_ISOC_COMM_STOP, &reg, sizeof(reg), 0);
 143}
 144
 145static int ff400_switch_fetching_mode(struct snd_ff *ff, bool enable)
 146{
 147        __le32 *reg;
 148        int i;
 149
 150        reg = kzalloc(sizeof(__le32) * 18, GFP_KERNEL);
 151        if (reg == NULL)
 152                return -ENOMEM;
 153
 154        if (enable) {
 155                /*
 156                 * Each quadlet is corresponding to data channels in a data
 157                 * blocks in reverse order. Precisely, quadlets for available
 158                 * data channels should be enabled. Here, I take second best
 159                 * to fetch PCM frames from all of data channels regardless of
 160                 * stf.
 161                 */
 162                for (i = 0; i < 18; ++i)
 163                        reg[i] = cpu_to_le32(0x00000001);
 164        }
 165
 166        return snd_fw_transaction(ff->unit, TCODE_WRITE_BLOCK_REQUEST,
 167                                  FF400_FETCH_PCM_FRAMES, reg,
 168                                  sizeof(__le32) * 18, 0);
 169}
 170
 171static void ff400_dump_sync_status(struct snd_ff *ff,
 172                                   struct snd_info_buffer *buffer)
 173{
 174        __le32 reg;
 175        u32 data;
 176        int err;
 177
 178        err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST,
 179                                 FF400_SYNC_STATUS, &reg, sizeof(reg), 0);
 180        if (err < 0)
 181                return;
 182
 183        data = le32_to_cpu(reg);
 184
 185        snd_iprintf(buffer, "External source detection:\n");
 186
 187        snd_iprintf(buffer, "Word Clock:");
 188        if ((data >> 24) & 0x20) {
 189                if ((data >> 24) & 0x40)
 190                        snd_iprintf(buffer, "sync\n");
 191                else
 192                        snd_iprintf(buffer, "lock\n");
 193        } else {
 194                snd_iprintf(buffer, "none\n");
 195        }
 196
 197        snd_iprintf(buffer, "S/PDIF:");
 198        if ((data >> 16) & 0x10) {
 199                if ((data >> 16) & 0x04)
 200                        snd_iprintf(buffer, "sync\n");
 201                else
 202                        snd_iprintf(buffer, "lock\n");
 203        } else {
 204                snd_iprintf(buffer, "none\n");
 205        }
 206
 207        snd_iprintf(buffer, "ADAT:");
 208        if ((data >> 8) & 0x04) {
 209                if ((data >> 8) & 0x10)
 210                        snd_iprintf(buffer, "sync\n");
 211                else
 212                        snd_iprintf(buffer, "lock\n");
 213        } else {
 214                snd_iprintf(buffer, "none\n");
 215        }
 216
 217        snd_iprintf(buffer, "\nUsed external source:\n");
 218
 219        if (((data >> 22) & 0x07) == 0x07) {
 220                snd_iprintf(buffer, "None\n");
 221        } else {
 222                switch ((data >> 22) & 0x07) {
 223                case 0x00:
 224                        snd_iprintf(buffer, "ADAT:");
 225                        break;
 226                case 0x03:
 227                        snd_iprintf(buffer, "S/PDIF:");
 228                        break;
 229                case 0x04:
 230                        snd_iprintf(buffer, "Word:");
 231                        break;
 232                case 0x07:
 233                        snd_iprintf(buffer, "Nothing:");
 234                        break;
 235                case 0x01:
 236                case 0x02:
 237                case 0x05:
 238                case 0x06:
 239                default:
 240                        snd_iprintf(buffer, "unknown:");
 241                        break;
 242                }
 243
 244                if ((data >> 25) & 0x07) {
 245                        switch ((data >> 25) & 0x07) {
 246                        case 0x01:
 247                                snd_iprintf(buffer, "32000\n");
 248                                break;
 249                        case 0x02:
 250                                snd_iprintf(buffer, "44100\n");
 251                                break;
 252                        case 0x03:
 253                                snd_iprintf(buffer, "48000\n");
 254                                break;
 255                        case 0x04:
 256                                snd_iprintf(buffer, "64000\n");
 257                                break;
 258                        case 0x05:
 259                                snd_iprintf(buffer, "88200\n");
 260                                break;
 261                        case 0x06:
 262                                snd_iprintf(buffer, "96000\n");
 263                                break;
 264                        case 0x07:
 265                                snd_iprintf(buffer, "128000\n");
 266                                break;
 267                        case 0x08:
 268                                snd_iprintf(buffer, "176400\n");
 269                                break;
 270                        case 0x09:
 271                                snd_iprintf(buffer, "192000\n");
 272                                break;
 273                        case 0x00:
 274                                snd_iprintf(buffer, "unknown\n");
 275                                break;
 276                        }
 277                }
 278        }
 279
 280        snd_iprintf(buffer, "Multiplied:");
 281        snd_iprintf(buffer, "%d\n", (data & 0x3ff) * 250);
 282}
 283
 284static void ff400_dump_clock_config(struct snd_ff *ff,
 285                                    struct snd_info_buffer *buffer)
 286{
 287        __le32 reg;
 288        u32 data;
 289        unsigned int rate;
 290        const char *src;
 291        int err;
 292
 293        err = snd_fw_transaction(ff->unit, TCODE_READ_BLOCK_REQUEST,
 294                                 FF400_CLOCK_CONFIG, &reg, sizeof(reg), 0);
 295        if (err < 0)
 296                return;
 297
 298        data = le32_to_cpu(reg);
 299
 300        snd_iprintf(buffer, "Output S/PDIF format: %s (Emphasis: %s)\n",
 301                    (data & 0x20) ? "Professional" : "Consumer",
 302                    (data & 0x40) ? "on" : "off");
 303
 304        snd_iprintf(buffer, "Optical output interface format: %s\n",
 305                    ((data >> 8) & 0x01) ? "S/PDIF" : "ADAT");
 306
 307        snd_iprintf(buffer, "Word output single speed: %s\n",
 308                    ((data >> 8) & 0x20) ? "on" : "off");
 309
 310        snd_iprintf(buffer, "S/PDIF input interface: %s\n",
 311                    ((data >> 8) & 0x02) ? "Optical" : "Coaxial");
 312
 313        switch ((data >> 1) & 0x03) {
 314        case 0x01:
 315                rate = 32000;
 316                break;
 317        case 0x00:
 318                rate = 44100;
 319                break;
 320        case 0x03:
 321                rate = 48000;
 322                break;
 323        case 0x02:
 324        default:
 325                return;
 326        }
 327
 328        if (data & 0x08)
 329                rate *= 2;
 330        else if (data & 0x10)
 331                rate *= 4;
 332
 333        snd_iprintf(buffer, "Sampling rate: %d\n", rate);
 334
 335        if (data & 0x01) {
 336                src = "Internal";
 337        } else {
 338                switch ((data >> 10) & 0x07) {
 339                case 0x00:
 340                        src = "ADAT";
 341                        break;
 342                case 0x03:
 343                        src = "S/PDIF";
 344                        break;
 345                case 0x04:
 346                        src = "Word";
 347                        break;
 348                case 0x05:
 349                        src = "LTC";
 350                        break;
 351                default:
 352                        return;
 353                }
 354        }
 355
 356        snd_iprintf(buffer, "Sync to clock source: %s\n", src);
 357}
 358
 359struct snd_ff_protocol snd_ff_protocol_ff400 = {
 360        .get_clock              = ff400_get_clock,
 361        .begin_session          = ff400_begin_session,
 362        .finish_session         = ff400_finish_session,
 363        .switch_fetching_mode   = ff400_switch_fetching_mode,
 364
 365        .dump_sync_status       = ff400_dump_sync_status,
 366        .dump_clock_config      = ff400_dump_clock_config,
 367
 368        .midi_high_addr_reg     = FF400_MIDI_HIGH_ADDR,
 369        .midi_rx_port_0_reg     = FF400_MIDI_RX_PORT_0,
 370        .midi_rx_port_1_reg     = FF400_MIDI_RX_PORT_1,
 371};
 372