Changeset 1832

Show
Ignore:
Timestamp:
05/16/10 05:07:57 (2 years ago)
Author:
jwoithe
Message:

MOTU: decouple clock source identifiers from the values sent to devices. This will make it much easier to add support for new sources added in the "mark 3" devices.
MOTU: the active clock source should be correctly retrieved from original 828 interfaces now.
MOTU: update "mark 3" protocol details, correcting errors and adding SMTPE clock source information.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/doc/motu_firewire_protocol-mk3.txt

    r1828 r1832  
    22using an 828 Mk 3. 
    33 
    4 Version: 20100510-1 
     4Version: 20100516-1 
    55Author: Jonathan Woithe 
    66 
     
    9696-------------- 
    9797 
    98 ADAT modes 
    99  
    100 The modes of the two ADAT ports can be controlled independently.  The 
     98Optical port modes 
     99 
     100The modes of the two optical ports can be controlled independently.  The 
    101101primary mechanism for this is via a quadlet write to register 
    1021020xfffff0000c94. 
    103103 
    104   Bit 17: ADAT port B mode (0=ADAT, 1=Toslink) 
    105   Bit 16: ADAT port A mode (0=ADAT, 1=Toslink) 
    106   Bit  1: ADAT port B enabled (0=disabled, 1=enabled) 
    107   Bit  0: ADAT port A enabled (0=disabled, 1=enabled) 
    108  
    109 Other systems also appear to refresh the device status with writes to 
    110 other registers at the time the optical mode is updated: 
     104  Bit 17: optical port B mode (0=ADAT, 1=Toslink) 
     105  Bit 16: optical port A mode (0=ADAT, 1=Toslink) 
     106  Bit  1: optical port B enabled (0=disabled, 1=enabled) 
     107  Bit  0: optical port A enabled (0=disabled, 1=enabled) 
     108 
     109Other areas of the driver also appear to refresh the device status with 
     110writes to other registers at the time the optical mode is updated: 
    111111  0xfffff0000c04 
    112112  0xfffff0000c60 - 0xfffff0000c6c (ASCII name of clock source) 
     
    125125Clock source control and sample rate 
    126126 
    127 The clock source is set with a quadlet write to bits 0, 3 and 4 of register  
    128 0xfffff0000b14.  Values for bits 4-3-0: 
    129   0-0-0 = internal / SMTPE 
    130   0-0-1 = Word clock 
    131   1-0-0 = SPDIF 
    132   1-1-0 = ADAT port A 
    133   1-1-1 = ADAT port B 
     127The clock source is set with a quadlet write to bits 0, 1, 3 and 4 of 
     128register 0xfffff0000b14.  Values for bits 4-3-1-0: 
     129  0-0-0-0 = internal 
     130  0-0-1-0 = SMTPE 
     131  0-0-0-1 = Word clock 
     132  1-0-0-0 = SPDIF 
     133  1-1-0-0 = ADAT port A / Toslink-A (depending on current optical port mode) 
     134  1-1-0-1 = ADAT port B / Toslink-B (depending on current optical port mode) 
    134135 
    135136The sample rate is selected using bits 10-8 of register 0xfffff0000b14: 
  • trunk/libffado/src/motu/motu_avdevice.cpp

    r1831 r1832  
    554554} 
    555555 
     556unsigned int 
     557MotuDevice::getHwClockSource() 
     558{ 
     559    unsigned int reg; 
     560 
     561    if (m_motu_model == MOTU_MODEL_828MkI) { 
     562        reg = ReadRegister(MOTU_G1_REG_CONFIG); 
     563        switch (reg & MOTU_G1_CLKSRC_MASK) { 
     564            case MOTU_G1_CLKSRC_INTERNAL: return MOTU_CLKSRC_INTERNAL; 
     565            case MOTU_G1_CLKSRC_ADAT_9PIN: return MOTU_CLKSRC_ADAT_9PIN; 
     566            case MOTU_G1_CLKSRC_SPDIF: return MOTU_CLKSRC_SPDIF_TOSLINK; 
     567        } 
     568        return MOTU_CLKSRC_NONE; 
     569    } 
     570 
     571    reg = ReadRegister(MOTU_REG_CLK_CTRL); 
     572    switch (reg & MOTU_G2_CLKSRC_MASK) { 
     573        case MOTU_G2_CLKSRC_INTERNAL: return MOTU_CLKSRC_INTERNAL; 
     574        case MOTU_G2_CLKSRC_ADAT_OPTICAL: return MOTU_CLKSRC_ADAT_OPTICAL; 
     575        case MOTU_G2_CLKSRC_SPDIF_TOSLINK: return MOTU_CLKSRC_SPDIF_TOSLINK; 
     576        case MOTU_G2_CLKSRC_SMPTE: return MOTU_CLKSRC_SMPTE; 
     577        case MOTU_G2_CLKSRC_WORDCLOCK: return MOTU_CLKSRC_WORDCLOCK; 
     578        case MOTU_G2_CLKSRC_ADAT_9PIN: return MOTU_CLKSRC_ADAT_9PIN; 
     579        case MOTU_G2_CLKSRC_AES_EBU: return MOTU_CLKSRC_AES_EBU; 
     580    } 
     581    return MOTU_CLKSRC_NONE; 
     582} 
     583 
    556584bool 
    557585MotuDevice::setClockCtrlRegister(signed int samplingFrequency, unsigned int clock_source) 
     
    566594    int i, supported=true, cancel_adat=false; 
    567595    quadlet_t reg; 
     596    unsigned int old_clock_src = getHwClockSource(); 
    568597 
    569598    /* Don't touch anything if there's nothing to do */ 
     
    644673 
    645674    // Sanity check the clock source 
    646     if ((clock_source>7 || clock_source==6) && clock_source!=MOTU_CLKSRC_UNCHANGED) 
     675    if (clock_source>MOTU_CLKSRC_LAST && clock_source!=MOTU_CLKSRC_UNCHANGED) 
    647676        supported = false; 
    648677 
     
    668697        // Set up new clock source if required 
    669698        if (clock_source != MOTU_CLKSRC_UNCHANGED) { 
    670             reg &= ~MOTU_CLKSRC_MASK; 
    671             reg |= (clock_source & MOTU_CLKSRC_MASK); 
     699            reg &= ~MOTU_G2_CLKSRC_MASK; 
     700            switch (clock_source) { 
     701              case MOTU_CLKSRC_INTERNAL: reg |= MOTU_G2_CLKSRC_INTERNAL; break; 
     702              case MOTU_CLKSRC_ADAT_OPTICAL: reg |= MOTU_G2_CLKSRC_ADAT_OPTICAL; break; 
     703              case MOTU_CLKSRC_SPDIF_TOSLINK: reg |= MOTU_G2_CLKSRC_SPDIF_TOSLINK; break; 
     704              case MOTU_CLKSRC_SMPTE: reg |= MOTU_G2_CLKSRC_SMPTE; break; 
     705              case MOTU_CLKSRC_WORDCLOCK: reg |= MOTU_G2_CLKSRC_WORDCLOCK; break; 
     706              case MOTU_CLKSRC_ADAT_9PIN: reg |= MOTU_G2_CLKSRC_ADAT_9PIN; break; 
     707              case MOTU_CLKSRC_AES_EBU: reg |= MOTU_G2_CLKSRC_AES_EBU; break; 
     708            } 
     709        } else { 
     710            /* Use the device's current clock source to set the clock 
     711             * source name registers, which must be done even if we aren't 
     712             * changing the clock source. 
     713             */ 
     714            clock_source = old_clock_src; 
    672715        } 
    673716 
     
    706749        // textual name of the current clock source be sent to the 
    707750        // clock source name registers. 
    708         switch (reg & MOTU_CLKSRC_MASK) { 
     751        switch (clock_source) { 
    709752            case MOTU_CLKSRC_INTERNAL: 
    710753                src_name = "Internal        "; 
     
    779822MotuDevice::clockIdToClockSource(unsigned int id) { 
    780823    ClockSource s; 
    781     bool g1_model = (m_motu_model == MOTU_MODEL_828MkI); 
     824    signed int device_gen = getDeviceGeneration(); 
    782825    s.id = id; 
    783826 
     
    795838            s.type = eCT_ADAT; 
    796839            s.description = "ADAT optical"; 
    797             s.valid = s.active = s.locked = !g1_model
     840            s.valid = s.active = s.locked = (device_gen!=MOTU_DEVICE_G1)
    798841            break; 
    799842        case MOTU_CLKSRC_SPDIF_TOSLINK: 
     
    804847            s.type = eCT_SMPTE; 
    805848            s.description = "SMPTE"; 
    806             // Since we don't currently know how to deal with SMPTE on these devices 
    807             // make sure the SMPTE clock source is disabled. 
     849            // Since we don't currently know how to deal with SMPTE on these 
     850            // devices make sure the SMPTE clock source is disabled. 
    808851            s.valid = false; 
    809852            s.active = false; 
     
    813856            s.type = eCT_WordClock; 
    814857            s.description = "Wordclock"; 
    815             s.valid = s.active = s.locked = !g1_model
     858            s.valid = s.active = s.locked = (device_gen!=MOTU_DEVICE_G1)
    816859            break; 
    817860        case MOTU_CLKSRC_ADAT_9PIN: 
     
    822865            s.type = eCT_AES; 
    823866            s.description = "AES/EBU"; 
    824             s.valid = s.active = s.locked = !g1_model
     867            s.valid = s.active = s.locked = (device_gen!=MOTU_DEVICE_G1)
    825868            break; 
    826869        default: 
     
    867910MotuDevice::getActiveClockSource() { 
    868911    ClockSource s; 
    869     quadlet_t clock_id = ReadRegister(MOTU_REG_CLK_CTRL) & MOTU_CLKSRC_MASK
     912    quadlet_t clock_id = getHwClockSource()
    870913    s = clockIdToClockSource(clock_id); 
    871914    s.active = true; 
     
    12461289 
    12471290    if (port_b_mode != NULL) 
    1248         *port_b_mode = MOTU_OPTICAL_MODE_OFF
     1291        *port_b_mode = MOTU_OPTICAL_MODE_NONE
    12491292    if (getDeviceGeneration()!=MOTU_DEVICE_G3 && port_a_mode==NULL) 
    12501293        return 0; 
  • trunk/libffado/src/motu/motu_avdevice.h

    r1831 r1832  
    6262#define MOTU_G2_OPTICAL_MODE_MASK      (MOTU_G2_OPTICAL_IN_MODE_MASK|MOTU_G2_OPTICAL_MODE_MASK) 
    6363 
    64 #define MOTU_CLKSRC_MASK             0x00000007 
    65 #define MOTU_CLKSRC_INTERNAL         0 
    66 #define MOTU_CLKSRC_ADAT_OPTICAL     1 
    67 #define MOTU_CLKSRC_SPDIF_TOSLINK    2 
    68 #define MOTU_CLKSRC_SMPTE            3 
    69 #define MOTU_CLKSRC_WORDCLOCK        4 
    70 #define MOTU_CLKSRC_ADAT_9PIN        5 
    71 #define MOTU_CLKSRC_AES_EBU          7 
    72 #define MOTU_CLKSRC_NONE             0xffff 
    73 #define MOTU_CLKSRC_UNCHANGED        MOTU_CLKSRC_NONE 
     64#define MOTU_G2_CLKSRC_MASK             0x00000007 
     65#define MOTU_G2_CLKSRC_INTERNAL         0 
     66#define MOTU_G2_CLKSRC_ADAT_OPTICAL     1 
     67#define MOTU_G2_CLKSRC_SPDIF_TOSLINK    2 
     68#define MOTU_G2_CLKSRC_SMPTE            3 
     69#define MOTU_G2_CLKSRC_WORDCLOCK        4 
     70#define MOTU_G2_CLKSRC_ADAT_9PIN        5 
     71#define MOTU_G2_CLKSRC_AES_EBU          7 
    7472 
    7573#define MOTU_METER_PEAKHOLD_MASK     0x3800 
     
    155153 * from the G2s. 
    156154 */ 
    157 #define MOTU_G3_CLKSRC_MASK      0x00000019 
     155#define MOTU_G3_CLKSRC_MASK      0x0000001b 
    158156#define MOTU_G3_CLKSRC_INTERNAL  0x00000000 
    159157#define MOTU_G3_CLKSRC_WORDCLOCK 0x00000001 
    160 #define MOTU_G3_CLKSRC_SPDIR     0x00000010 
    161 #define MOTU_G3_CLKSRC_ADAT_A    0x00000018 
    162 #define MOTU_G3_CLKSRC_ADAT_B    0x00000019 
     158#define MOTU_G3_CLKSRC_SMTPE     0x00000002 
     159#define MOTU_G3_CLKSRC_SPDIF     0x00000010 
     160#define MOTU_G3_CLKSRC_OPTICAL_A 0x00000018 
     161#define MOTU_G3_CLKSRC_OPTICAL_B 0x00000019 
     162#define MOTU_G3_CLKSRC_ADAT_A    MOTU_G3_CLKSRC_OPTICAL_A 
     163#define MOTU_G3_CLKSRC_ADAT_B    MOTU_G3_CLKSRC_OPTICAL_B 
     164#define MOTU_G3_CLKSRC_TOSLINK_A MOTU_G3_CLKSRC_OPTICAL_A 
     165#define MOTU_G3_CLKSRC_TOSLINK_B MOTU_G3_CLKSRC_OPTICAL_A 
    163166 
    164167/* The following values are used when defining configuration structures and 
     
    209212#define MOTU_OPTICAL_MODE_TOSLINK 0x0002 
    210213#define MOTU_OPTICAL_MODE_KEEP    0xffff 
     214#define MOTU_OPTICAL_MODE_NONE    0xffffffff 
     215 
     216/* Clock source settings/flags */ 
     217#define MOTU_CLKSRC_INTERNAL         0 
     218#define MOTU_CLKSRC_ADAT_OPTICAL     1 
     219#define MOTU_CLKSRC_SPDIF_TOSLINK    2 
     220#define MOTU_CLKSRC_SMPTE            3 
     221#define MOTU_CLKSRC_WORDCLOCK        4 
     222#define MOTU_CLKSRC_ADAT_9PIN        5 
     223#define MOTU_CLKSRC_AES_EBU          7 
     224#define MOTU_CLKSRC_LAST             7 
     225#define MOTU_CLKSRC_NONE             0xffff 
     226#define MOTU_CLKSRC_UNCHANGED        MOTU_CLKSRC_NONE 
     227 
    211228/* Device generation identifiers */ 
    212229#define MOTU_DEVICE_G1            0x0001 
     
    314331    virtual void showDevice(); 
    315332 
     333    unsigned int getHwClockSource(); 
    316334    bool setClockCtrlRegister(signed int samplingFrequency, unsigned int clock_source); 
    317335    virtual bool setSamplingFrequency( int samplingFrequency );