Changeset 2692

05/14/17 03:54:21 (3 years ago)

rme: adjustments to maintain compatibility with the kernel snd-fireface
driver for FF400 devices.

This is a modified version of a patch submitted by Takashi Sakamoto. His
original commit message follows. Changes from the original patch were:

1. Abbreviate comments added to fireface_def.h. This file was never

intended to contain verbose protocol-level descriptions, so a briefer
version is fine.

2. In fireface_def.h, omit the added "Not used in user land." comment

attached to RME_FF400_MIDI_HIGH_ADDR. While FFADO does not utilise this
at present, it doesn't mean that it couldn't in future (at least in
principle). Since this file describes the programming interface
implemented by the device, the proposed annotation could be confusing in
the future.

3. Do not remove the "provide_midi" device field. This infrastructure

field helps document the device's programming interface and could be used
in future to allow FFADO to support MIDI on the FF400 device. In the
meantime, its current setting (0) continues to allow FFADO and the kernel
snd-fireface module (kernel >= 4.12) to co-exist. To this end, the
changes to CR2 requested in the patch are carried out if provide_midi
is 0.

[Takashi Sakamoto's commit message]

As of May 2017, FFADO library has no support for MIDI functionality
as a driver for RME fireface series.

ALSA fireface driver, a.k.a. snd-fireface were added to Linux kernel
v4.12. This driver is designed to just support functionalities to handle
PCM frames and MIDI messages for ALSA userspace applications. The other
features should be implemented in user space to avoid complexity in
kernel land.

Additionally, due to design of target hardware, the driver request
userspace applications to handle some registers. In RME Fireface series,
some registers are write-only. Fortunately, none of the registers is
relevant to packet streaming feature; i.e. isochronous communication on
IEEE 1394 bus, while asynchronous communication is controlled by such
registers. MIDI functionality in ALSA fireface driver gets influences
from this specification. The driver need a care of userspace applications
to set the registers correctly.

For the above reason, this commit changes this library to configure
the registers so that ALSA fireface driver can handle MIDI messages
properly. The issue is an address to which the unit transfers asynchronous
transactions for MIDI messages. 4 byte in MSB of the address is
represented in 0x'0000'8010'03f4 with node ID. This is readable/writable
by ALSA fireface driver. Rest of the address is decided by write
transaction to 0x'0000'8010'051c with bit flags. This register is
write-only, it includes effects for the other features than MIDI
functionality. ALSA fireface driver doesn't touch it but expects userspace
applications to configure the register to transfer MIDI messagess to
a certain address.

Signed-off-by: Takashi Sakamoto <>



  • trunk/libffado/src/rme/fireface_def.h

    r2637 r2692  
    250250#define CR2_TOGGLE_TCO          0x00004000  // Normally set to 0 
    251251#define CR2_P12DB_AN0           0x00010000  // Disable soft-limiter.  Normally set to 0 
    252 #define CR2_FF400_BIT           0x04000000  // Set on FF400, clear on FF800 
     252#define CR2_FF400_DISABLE_MIDI_TX_MASK  0x03000000  // Either or all bits will disable 
     253#define CR2_FF400_SELECT_MIDI_TX_ADDR_1 0x04000000  // FF400 tx to 0x'....'....'0000'0000'0000'0000 
     254#define CR2_FF400_SELECT_MIDI_TX_ADDR_2 0x08000000  // FF400 tx to 0x'....'....'0000'0000'0000'0080 
     255#define CR2_FF400_SELECT_MIDI_TX_ADDR_3 0x10000000  // FF400 tx to 0x'....'....'0000'0000'0000'0100 
     256#define CR2_FF400_SELECT_MIDI_TX_ADDR_4 0x20000000  // FF400 tx to 0x'....'....'0000'0000'0000'0180 
     257                                                    // '....'....' = content of RME_FF400_MIDI_HIGH_ADDR 
    253258#define CR2_TMS                 0x40000000  // Unit option, normally 0 
    254259#define CR2_DROP_AND_STOP       0x80000000  // Normally set to 1 
  • trunk/libffado/src/rme/fireface_hw.cpp

    r2651 r2692  
    193193    if (ret==0 && m_rme_model==RME_MODEL_FIREFACE400 && provide_midi) { 
    194         // Precisely mirror the method used under other operating systems 
    195         // to set the high quadlet of the MIDI ARM address, even though it 
    196         // is a little inflexible.  We can refine this later if need be. 
     194        // Precisely mirror the method used under other operating systems to 
     195        // set the high quadlet of the MIDI ARM address, even though it is a 
     196        // little inflexible.  We can refine this later if need be.  This is 
     197        // only done if FFADO is providing MIDI functionality.  If not, the 
     198        // RME_FF400_MIDI_HIGH_ADDR is left alone for other drivers (such as 
     199        // snd-fireface in Linux kernel >= 4.12) to configure if desired. 
    197200        unsigned int node_id = getConfigRom().getNodeId(); 
    198201        unsigned int midi_hi_addr; 
    543546    data[2] |= CR2_DROP_AND_STOP; 
    545     if (m_rme_model == RME_MODEL_FIREFACE400) { 
    546         data[2] |= CR2_FF400_BIT; 
     548    if (m_rme_model==RME_MODEL_FIREFACE400 && !provide_midi) { 
     549        // If libffado is not providing MIDI, configure the register to 
     550        // allow snd-fireface (linux kernel >= 4.12) - or any other driver 
     551        // for the FF400 which might appear in future - to do so if desired.  
     552        // The choice of tx address 1 matches that which is coded in 
     553        // snd-fireface as of kernel 4.12. 
     554        data[2] &= ~CR2_FF400_DISABLE_MIDI_TX_MASK; 
     555        data[2] |= CR2_FF400_SELECT_MIDI_TX_ADDR_1; 
    547556    }