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        int err;
 150
 151        reg = kcalloc(18, sizeof(__le32), GFP_KERNEL);
 152        if (reg == NULL)
 153                return -ENOMEM;
 154
 155        if (enable) {
 156                /*
 157                 * Each quadlet is corresponding to data channels in a data
 158                 * blocks in reverse order. Precisely, quadlets for available
 159                 * data channels should be enabled. Here, I take second best
 160                 * to fetch PCM frames from all of data channels regardless of
 161                 * stf.
 162                 */
 163                for (i = 0; i < 18; ++i)
 164                        reg[i] = cpu_to_le32(0x00000001);
 165        }
 166
 167        err = snd_fw_transaction(ff->unit, TCODE_WRITE_BLOCK_REQUEST,
 168                                 FF400_FETCH_PCM_FRAMES, reg,
 169                                 sizeof(__le32) * 18, 0);
 170        kfree(reg);
 171        return err;
 172}
 173
 174static void ff400_dump_sync_status(struct snd_ff *ff,
 175                                   struct snd_info_buffer *buffer)
 176{
 177        __le32 reg;
 178        u32 data;
 179        int err;
 180
 181        err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST,
 182                                 FF400_SYNC_STATUS, &reg, sizeof(reg), 0);
 183        if (err < 0)
 184                return;
 185
 186        data = le32_to_cpu(reg);
 187
 188        snd_iprintf(buffer, "External source detection:\n");
 189
 190        snd_iprintf(buffer, "Word Clock:");
 191        if ((data >> 24) & 0x20) {
 192                if ((data >> 24) & 0x40)
 193                        snd_iprintf(buffer, "sync\n");
 194                else
 195                        snd_iprintf(buffer, "lock\n");
 196        } else {
 197                snd_iprintf(buffer, "none\n");
 198        }
 199
 200        snd_iprintf(buffer, "S/PDIF:");
 201        if ((data >> 16) & 0x10) {
 202                if ((data >> 16) & 0x04)
 203                        snd_iprintf(buffer, "sync\n");
 204                else
 205                        snd_iprintf(buffer, "lock\n");
 206        } else {
 207                snd_iprintf(buffer, "none\n");
 208        }
 209
 210        snd_iprintf(buffer, "ADAT:");
 211        if ((data >> 8) & 0x04) {
 212                if ((data >> 8) & 0x10)
 213                        snd_iprintf(buffer, "sync\n");
 214                else
 215                        snd_iprintf(buffer, "lock\n");
 216        } else {
 217                snd_iprintf(buffer, "none\n");
 218        }
 219
 220        snd_iprintf(buffer, "\nUsed external source:\n");
 221
 222        if (((data >> 22) & 0x07) == 0x07) {
 223                snd_iprintf(buffer, "None\n");
 224        } else {
 225                switch ((data >> 22) & 0x07) {
 226                case 0x00:
 227                        snd_iprintf(buffer, "ADAT:");
 228                        break;
 229                case 0x03:
 230                        snd_iprintf(buffer, "S/PDIF:");
 231                        break;
 232                case 0x04:
 233                        snd_iprintf(buffer, "Word:");
 234                        break;
 235                case 0x07:
 236                        snd_iprintf(buffer, "Nothing:");
 237                        break;
 238                case 0x01:
 239                case 0x02:
 240                case 0x05:
 241                case 0x06:
 242                default:
 243                        snd_iprintf(buffer, "unknown:");
 244                        break;
 245                }
 246
 247                if ((data >> 25) & 0x07) {
 248                        switch ((data >> 25) & 0x07) {
 249                        case 0x01:
 250                                snd_iprintf(buffer, "32000\n");
 251                                break;
 252                        case 0x02:
 253                                snd_iprintf(buffer, "44100\n");
 254                                break;
 255                        case 0x03:
 256                                snd_iprintf(buffer, "48000\n");
 257                                break;
 258                        case 0x04:
 259                                snd_iprintf(buffer, "64000\n");
 260                                break;
 261                        case 0x05:
 262                                snd_iprintf(buffer, "88200\n");
 263                                break;
 264                        case 0x06:
 265                                snd_iprintf(buffer, "96000\n");
 266                                break;
 267                        case 0x07:
 268                                snd_iprintf(buffer, "128000\n");
 269                                break;
 270                        case 0x08:
 271                                snd_iprintf(buffer, "176400\n");
 272                                break;
 273                        case 0x09:
 274                                snd_iprintf(buffer, "192000\n");
 275                                break;
 276                        case 0x00:
 277                                snd_iprintf(buffer, "unknown\n");
 278                                break;
 279                        }
 280                }
 281        }
 282
 283        snd_iprintf(buffer, "Multiplied:");
 284        snd_iprintf(buffer, "%d\n", (data & 0x3ff) * 250);
 285}
 286
 287static void ff400_dump_clock_config(struct snd_ff *ff,
 288                                    struct snd_info_buffer *buffer)
 289{
 290        __le32 reg;
 291        u32 data;
 292        unsigned int rate;
 293        const char *src;
 294        int err;
 295
 296        err = snd_fw_transaction(ff->unit, TCODE_READ_BLOCK_REQUEST,
 297                                 FF400_CLOCK_CONFIG, &reg, sizeof(reg), 0);
 298        if (err < 0)
 299                return;
 300
 301        data = le32_to_cpu(reg);
 302
 303        snd_iprintf(buffer, "Output S/PDIF format: %s (Emphasis: %s)\n",
 304                    (data & 0x20) ? "Professional" : "Consumer",
 305                    (data & 0x40) ? "on" : "off");
 306
 307        snd_iprintf(buffer, "Optical output interface format: %s\n",
 308                    ((data >> 8) & 0x01) ? "S/PDIF" : "ADAT");
 309
 310        snd_iprintf(buffer, "Word output single speed: %s\n",
 311                    ((data >> 8) & 0x20) ? "on" : "off");
 312
 313        snd_iprintf(buffer, "S/PDIF input interface: %s\n",
 314                    ((data >> 8) & 0x02) ? "Optical" : "Coaxial");
 315
 316        switch ((data >> 1) & 0x03) {
 317        case 0x01:
 318                rate = 32000;
 319                break;
 320        case 0x00:
 321                rate = 44100;
 322                break;
 323        case 0x03:
 324                rate = 48000;
 325                break;
 326        case 0x02:
 327        default:
 328                return;
 329        }
 330
 331        if (data & 0x08)
 332                rate *= 2;
 333        else if (data & 0x10)
 334                rate *= 4;
 335
 336        snd_iprintf(buffer, "Sampling rate: %d\n", rate);
 337
 338        if (data & 0x01) {
 339                src = "Internal";
 340        } else {
 341                switch ((data >> 10) & 0x07) {
 342                case 0x00:
 343                        src = "ADAT";
 344                        break;
 345                case 0x03:
 346                        src = "S/PDIF";
 347                        break;
 348                case 0x04:
 349                        src = "Word";
 350                        break;
 351                case 0x05:
 352                        src = "LTC";
 353                        break;
 354                default:
 355                        return;
 356                }
 357        }
 358
 359        snd_iprintf(buffer, "Sync to clock source: %s\n", src);
 360}
 361
 362const struct snd_ff_protocol snd_ff_protocol_ff400 = {
 363        .get_clock              = ff400_get_clock,
 364        .begin_session          = ff400_begin_session,
 365        .finish_session         = ff400_finish_session,
 366        .switch_fetching_mode   = ff400_switch_fetching_mode,
 367
 368        .dump_sync_status       = ff400_dump_sync_status,
 369        .dump_clock_config      = ff400_dump_clock_config,
 370
 371        .midi_high_addr_reg     = FF400_MIDI_HIGH_ADDR,
 372        .midi_rx_port_0_reg     = FF400_MIDI_RX_PORT_0,
 373        .midi_rx_port_1_reg     = FF400_MIDI_RX_PORT_1,
 374};
 375