Changeset 1828

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

MOTU: begin expansion of optical mode functions needed to support the 828Mk3:

  • expand optical port mode control function interface to allow for the two ports on some of the G3 devices (eg: the 828Mk3). Actual G3 support code is yet to be written.
  • consolidate optical port mode code to device methods and have control objects call these.
  • optical port mode identifiers passed to optical mode functions are now decoupled from the values sent to (G2) device registers making them truly device independent.
  • improved readability of the G2 optical mode code.

MOTU: fix retrieval of optical port mode for "generation 1" devices (ie: the original 828).
MOTU: added clock source defines for the G3 devices.
MOTU: added function to return device generation.
MOTU: minor Mark3 documentation fixes.

Files:

Legend:

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

    r1818 r1828  
    22using an 828 Mk 3. 
    33 
    4 Version: 20100426-1 
     4Version: 20100510-1 
    55Author: Jonathan Woithe 
    66 
     
    126126 
    127127The clock source is set with a quadlet write to bits 0, 3 and 4 of register  
    128 0xfffff0000b14.  Values for bits 4-3-1
     1280xfffff0000b14.  Values for bits 4-3-0
    129129  0-0-0 = internal / SMTPE 
    130130  0-0-1 = Word clock 
  • trunk/libffado/src/motu/motu_avdevice.cpp

    r1818 r1828  
    657657        // port if the sample rate is set to a 1x or 2x rate later. 
    658658        if (cancel_adat) { 
    659             setOpticalMode(MOTU_CTRL_DIR_INOUT, MOTU_OPTICAL_MODE_OFF); 
     659            setOpticalMode(0, MOTU_CTRL_DIR_INOUT, MOTU_OPTICAL_MODE_OFF); 
    660660        } 
    661661 
     
    714714                break; 
    715715            case MOTU_CLKSRC_SPDIF_TOSLINK: 
    716                 if (getOpticalMode(MOTU_DIR_IN) == MOTU_OPTICAL_MODE_TOSLINK) 
     716                if (getOpticalMode(0, MOTU_DIR_IN) == MOTU_OPTICAL_MODE_TOSLINK) 
    717717                    src_name = "TOSLink         "; 
    718718                else 
     
    895895 
    896896    int samp_freq = getSamplingFrequency(); 
    897     unsigned int optical_in_mode = getOpticalMode(MOTU_DIR_IN); 
    898     unsigned int optical_out_mode = getOpticalMode(MOTU_DIR_OUT); 
     897    unsigned int optical_in_mode = getOpticalMode(0, MOTU_DIR_IN); 
     898    unsigned int optical_out_mode = getOpticalMode(0, MOTU_DIR_OUT); 
    899899    unsigned int event_size_in = getEventSize(MOTU_DIR_IN); 
    900900    unsigned int event_size_out= getEventSize(MOTU_DIR_OUT); 
     
    907907    // up without this set to anything sensible.  In this case, writes to 
    908908    // MOTU_REG_ISOCTRL fail more often than not, which is bad. 
    909     setOpticalMode(MOTU_DIR_IN, optical_in_mode); 
    910     setOpticalMode(MOTU_DIR_OUT, optical_out_mode); 
     909    setOpticalMode(0, MOTU_DIR_IN, optical_in_mode); 
     910    setOpticalMode(0, MOTU_DIR_OUT, optical_out_mode); 
    911911 
    912912    // Allocate bandwidth if not previously done. 
     
    12211221} 
    12221222 
    1223 unsigned int MotuDevice::getOpticalMode(unsigned int dir) { 
     1223signed int MotuDevice::getDeviceGeneration(void) { 
     1224    if (m_motu_model == MOTU_MODEL_828MkI) 
     1225        return MOTU_DEVICE_G1; 
     1226    if (m_motu_model==MOTU_MODEL_828mk3 || 
     1227        m_motu_model==MOTU_MODEL_ULTRALITEmk3) 
     1228        return MOTU_DEVICE_G3; 
     1229    return MOTU_DEVICE_G2; 
     1230
     1231 
     1232unsigned int MotuDevice::getOpticalMode(unsigned int port, unsigned int dir) { 
     1233    // Only the "Mark 3" (aka G3) MOTU devices had more than one optical port. 
     1234    // Therefore the "port" parameter is ignored for all devices other than 
     1235    // the Mark 3 devices. 
    12241236    unsigned int reg; 
     1237    unsigned int mask, shift; 
    12251238 
    12261239    if (m_motu_model == MOTU_MODEL_828MkI) { 
    12271240        // The early devices used a different register layout.   
    1228         unsigned int mask, shift; 
    12291241        reg = ReadRegister(MOTU_G1_REG_CONFIG); 
    12301242        mask = (dir==MOTU_DIR_IN)?MOTU_G1_OPT_IN_MODE_MASK:MOTU_G1_OPT_OUT_MODE_MASK; 
    12311243        shift = (dir==MOTU_DIR_IN)?MOTU_G1_OPT_IN_MODE_BIT0:MOTU_G1_OPT_OUT_MODE_BIT0; 
    1232         switch (reg & mask) { 
     1244        switch ((reg & mask) >> shift) { 
    12331245            case MOTU_G1_OPTICAL_OFF: return MOTU_OPTICAL_MODE_OFF; 
    12341246            case MOTU_G1_OPTICAL_TOSLINK: return MOTU_OPTICAL_MODE_TOSLINK; 
     
    12411253    } 
    12421254 
     1255    if (getDeviceGeneration() == MOTU_DEVICE_G3) { 
     1256        debugOutput(DEBUG_LEVEL_INFO, "Optical mode control not implemented for Mark3/G3 devices yet"); 
     1257        return 0; 
     1258    } 
     1259 
    12431260    reg = ReadRegister(MOTU_REG_ROUTE_PORT_CONF); 
    1244  
    1245     if (dir == MOTU_DIR_IN) 
    1246         return (reg & MOTU_OPTICAL_IN_MODE_MASK) >> 8; 
    1247     else 
    1248         return (reg & MOTU_OPTICAL_OUT_MODE_MASK) >> 10; 
    1249 
    1250  
    1251 signed int MotuDevice::setOpticalMode(unsigned int dir, unsigned int mode) { 
    1252     unsigned int reg; 
     1261    mask = (dir==MOTU_DIR_IN)?MOTU_G2_OPTICAL_IN_MODE_MASK:MOTU_G2_OPTICAL_OUT_MODE_MASK; 
     1262    shift = (dir==MOTU_DIR_IN)?MOTU_G2_OPTICAL_IN_MODE_BIT0:MOTU_G2_OPTICAL_OUT_MODE_BIT0; 
     1263 
     1264    switch ((reg & mask) >> shift) { 
     1265        case MOTU_G2_OPTICAL_MODE_OFF: return MOTU_OPTICAL_MODE_OFF; 
     1266        case MOTU_G2_OPTICAL_MODE_ADAT: return MOTU_OPTICAL_MODE_ADAT; 
     1267        case MOTU_G2_OPTICAL_MODE_TOSLINK: return MOTU_OPTICAL_MODE_TOSLINK; 
     1268    } 
     1269 
     1270    return 0; 
     1271
     1272 
     1273signed int MotuDevice::setOpticalMode(unsigned int port, unsigned int dir,  
     1274  unsigned int mode) { 
     1275    // Only the "Mark 3" (aka G3) MOTU devices had more than one optical port. 
     1276    // Therefore the "port" parameter is ignored for all devices other than 
     1277    // the Mark 3 devices. 
     1278    unsigned int reg, g2mode; 
    12531279    unsigned int opt_ctrl = 0x0000002; 
    12541280 
     
    12751301    } 
    12761302 
     1303    if (getDeviceGeneration() == MOTU_DEVICE_G3) { 
     1304        debugOutput(DEBUG_LEVEL_INFO, "Optical mode control not implemented for Mark3/G3 devices yet"); 
     1305        return 0; 
     1306    } 
     1307 
    12771308    reg = ReadRegister(MOTU_REG_ROUTE_PORT_CONF); 
     1309 
     1310    // Map from user mode to values sent to the device registers. 
     1311    g2mode = 0; 
     1312    switch (mode) { 
     1313        case MOTU_OPTICAL_MODE_OFF: g2mode = MOTU_G2_OPTICAL_MODE_OFF; break; 
     1314        case MOTU_OPTICAL_MODE_ADAT: g2mode = MOTU_G2_OPTICAL_MODE_ADAT; break; 
     1315        case MOTU_OPTICAL_MODE_TOSLINK: g2mode = MOTU_G2_OPTICAL_MODE_TOSLINK; break; 
     1316    } 
    12781317 
    12791318    // Set up the optical control register value according to the current 
     
    12811320    // what the "Optical control" register does, so the values it's set to 
    12821321    // are more or less "magic" numbers. 
    1283     if ((reg & MOTU_OPTICAL_IN_MODE_MASK) != (MOTU_OPTICAL_MODE_ADAT<<8)) 
     1322    if ((reg & MOTU_G2_OPTICAL_IN_MODE_MASK) != (MOTU_G2_OPTICAL_MODE_ADAT<<MOTU_G2_OPTICAL_IN_MODE_BIT0)) 
    12841323        opt_ctrl |= 0x00000080; 
    1285     if ((reg & MOTU_OPTICAL_OUT_MODE_MASK) != (MOTU_OPTICAL_MODE_ADAT<<10)) 
     1324    if ((reg & MOTU_G2_OPTICAL_OUT_MODE_MASK) != (MOTU_G2_OPTICAL_MODE_ADAT<<MOTU_G2_OPTICAL_OUT_MODE_BIT0)) 
    12861325        opt_ctrl |= 0x00000040; 
    12871326 
    12881327    if (dir & MOTU_DIR_IN) { 
    1289         reg &= ~MOTU_OPTICAL_IN_MODE_MASK; 
    1290         reg |= (mode << 8) & MOTU_OPTICAL_IN_MODE_MASK; 
    1291         if (mode != MOTU_OPTICAL_MODE_ADAT) 
     1328        reg &= ~MOTU_G2_OPTICAL_IN_MODE_MASK; 
     1329        reg |= (g2mode << MOTU_G2_OPTICAL_IN_MODE_BIT0) & MOTU_G2_OPTICAL_IN_MODE_MASK; 
     1330        if (g2mode != MOTU_G2_OPTICAL_MODE_ADAT) 
    12921331            opt_ctrl |= 0x00000080; 
    12931332        else 
     
    12951334    } 
    12961335    if (dir & MOTU_DIR_OUT) { 
    1297         reg &= ~MOTU_OPTICAL_OUT_MODE_MASK; 
    1298         reg |= (mode <<10) & MOTU_OPTICAL_OUT_MODE_MASK; 
    1299         if (mode != MOTU_OPTICAL_MODE_ADAT) 
     1336        reg &= ~MOTU_G2_OPTICAL_OUT_MODE_MASK; 
     1337        reg |= (mode << MOTU_G2_OPTICAL_OUT_MODE_BIT0) & MOTU_G2_OPTICAL_OUT_MODE_MASK; 
     1338        if (g2mode != MOTU_G2_OPTICAL_MODE_ADAT) 
    13001339            opt_ctrl |= 0x00000040; 
    13011340        else 
    13021341            opt_ctrl &= ~0x00000040; 
    13031342    } 
     1343 
     1344    /* Setting bit 25 in the route/port configuration register enables the 
     1345     * setting of the optical mode.  Bit 24 allows the phones assign to be 
     1346     * set using the lower 8 bits of the register.  This function has no 
     1347     * business setting that, so make sure bit 24 is masked off. 
     1348     */ 
     1349    reg |= 0x02000000; 
     1350    reg &= ~0x01000000; 
    13041351 
    13051352    // FIXME: there seems to be more to it than this, but for 
     
    13231370// Note that all audio channels are sent using 3 bytes. 
    13241371signed int sample_rate = getSamplingFrequency(); 
    1325 signed int optical_mode = getOpticalMode(direction); 
     1372signed int optical_mode = getOpticalMode(0, direction); 
    13261373signed int size = 4+6; 
    13271374 
  • trunk/libffado/src/motu/motu_avdevice.h

    r1812 r1828  
    3939#define MOTU_BASE_ADDR               0xfffff0000000ULL 
    4040 
    41 /* Bitmasks and values used when setting MOTU device registers */ 
     41/* Bitmasks and values used when setting MOTU device registers.  Note that 
     42 * the only "generation 1" device presently supported is the original 828. 
     43 * "Generation 2" devices include the original Traveler, the 828Mk2, the 
     44 * original Ultralite, the 896/896HD and so forth.  "Generation 3" devices 
     45 * are all those which carry the "Mark 3" moniker. 
     46 */ 
    4247#define MOTU_RATE_BASE_44100         (0<<3) 
    4348#define MOTU_RATE_BASE_48000         (1<<3) 
     
    4853#define MOTU_RATE_MULTIPLIER_MASK    (0x00000030) 
    4954 
    50 #define MOTU_OPTICAL_MODE_OFF        0x00 
    51 #define MOTU_OPTICAL_MODE_ADAT       0x01 
    52 #define MOTU_OPTICAL_MODE_TOSLINK    0x02 
    53 #define MOTU_OPTICAL_IN_MODE_MASK    (0x00000300) 
    54 #define MOTU_OPTICAL_OUT_MODE_MASK   (0x00000c00) 
    55 #define MOTU_OPTICAL_MODE_MASK       (MOTU_OPTICAL_IN_MODE_MASK|MOTU_OPTICAL_MODE_MASK) 
     55#define MOTU_G2_OPTICAL_MODE_OFF       0x00 
     56#define MOTU_G2_OPTICAL_MODE_ADAT      0x01 
     57#define MOTU_G2_OPTICAL_MODE_TOSLINK   0x02 
     58#define MOTU_G2_OPTICAL_IN_MODE_MASK   (0x00000300) 
     59#define MOTU_G2_OPTICAL_IN_MODE_BIT0   8 
     60#define MOTU_G2_OPTICAL_OUT_MODE_MASK  (0x00000c00) 
     61#define MOTU_G2_OPTICAL_OUT_MODE_BIT0  10 
     62#define MOTU_G2_OPTICAL_MODE_MASK      (MOTU_G2_OPTICAL_IN_MODE_MASK|MOTU_G2_OPTICAL_MODE_MASK) 
    5663 
    5764#define MOTU_CLKSRC_MASK             0x00000007 
     
    138145 
    139146/* Mark3 device registers - these don't have MOTU_BASE_ADDR as the base 
    140  * address so for now we'll define them as absolute addresses. 
     147 * address so for now we'll define them as absolute addresses.  The "Mark 3" 
     148 * (aka G3) devices share a number of control registers with the G2 devices.  
     149 * Where this occurs we just use the G2 definitions since there's little to 
     150 * be gained by adding duplicate defines. 
    141151 */ 
    142152#define MOTU_MARK3_REG_MIXER     0xffff00010000LL 
     153 
     154/* Mark3 (aka G3) register constants for cases where the G3 devices differ 
     155 * from the G2s. 
     156 */ 
     157#define MOTU_G3_CLKSRC_MASK      0x00000019 
     158#define MOTU_G3_CLKSRC_INTERNAL  0x00000000 
     159#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 
     163 
     164/* The following values are used when defining configuration structures and 
     165 * calling driver functions.  They are generally not raw values written to 
     166 * registers. 
     167 */ 
    143168 
    144169/* Port Active Flags (ports declaration) */ 
     
    179204#define MOTU_DIR_INOUT       (MOTU_DIR_IN | MOTU_DIR_OUT) 
    180205 
     206/* Optical port mode settings/flags */ 
     207#define MOTU_OPTICAL_MODE_OFF     0x0000 
     208#define MOTU_OPTICAL_MODE_ADAT    0x0001 
     209#define MOTU_OPTICAL_MODE_TOSLINK 0x0002 
     210#define MOTU_OPTICAL_PORT_A       0x0001 
     211#define MOTU_OPTICAL_PORT_B       0x0002 
     212#define MOTU_OPTICAL_PORT_ALL     (MOTU_OPTICAL_PORT_A|MOTU_OPTICAL_PORT_B) 
     213 
     214/* Device generation identifiers */ 
     215#define MOTU_DEVICE_G1            0x0001 
     216#define MOTU_DEVICE_G2            0x0002 
     217#define MOTU_DEVICE_G3            0x0003 
     218 
    181219class ConfigRom; 
    182220class Ieee1394Service; 
     
    300338    virtual bool stopStreamByIndex(int i); 
    301339 
     340    signed int getDeviceGeneration(void); 
     341 
    302342    signed int getIsoRecvChannel(void); 
    303343    signed int getIsoSendChannel(void); 
    304     unsigned int getOpticalMode(unsigned int dir); 
    305     signed int setOpticalMode(unsigned int dir, unsigned int mode); 
     344    unsigned int getOpticalMode(unsigned int port, unsigned int dir); 
     345    signed int setOpticalMode(unsigned int port, unsigned int dir, unsigned int mode); 
    306346 
    307347    signed int getEventSize(unsigned int dir); 
  • trunk/libffado/src/motu/motu_controls.cpp

    r1763 r1828  
    685685OpticalMode::setValue(int v) 
    686686{ 
    687     unsigned int val
     687    unsigned int val, dir
    688688    debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for optical mode %d to %d\n", m_register, v); 
    689689 
    690     // Need to get current optical modes so we can preserve the one we're 
    691     // not setting.  Input mode is in bits 9-8, output is in bits 11-10. 
    692     val = m_parent.ReadRegister(MOTU_REG_ROUTE_PORT_CONF) & 0x00000f00; 
    693  
    694     // Set mode as requested.  An invalid setting is effectively ignored. 
    695     if (v>=0 && v<=3) { 
    696       if (m_register == MOTU_CTRL_DIR_IN) { 
    697         val = (val & ~0x0300) | ((v & 0x03) << 8); 
    698       } else { 
    699         val = (val & ~0x0c00) | ((v & 0x03) << 10); 
    700       } 
    701     } 
    702     // Bit 25 indicates that optical modes are being set 
    703     val |= 0x02000000; 
    704     m_parent.WriteRegister(MOTU_REG_ROUTE_PORT_CONF, val); 
    705  
     690    /* Assume v is 0 for "off", 1 for "ADAT" and 2 for "Toslink" */ 
     691    switch (v) { 
     692        case 0: val = MOTU_OPTICAL_MODE_OFF; break; 
     693        case 1: val = MOTU_OPTICAL_MODE_ADAT; break; 
     694        case 2: val = MOTU_OPTICAL_MODE_TOSLINK; break; 
     695        default: return true; 
     696    } 
     697    dir = (m_register==MOTU_CTRL_DIR_IN)?MOTU_DIR_IN:MOTU_DIR_OUT; 
     698    m_parent.setOpticalMode(0, dir, val); 
    706699    return true; 
    707700} 
     
    710703OpticalMode::getValue() 
    711704{ 
    712     unsigned int val
     705    unsigned int dir
    713706    debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for optical mode %d\n", m_register); 
    714707 
    715708    // FIXME: we could just read the appropriate mixer status field from the 
    716709    // receive stream processor once we work out an efficient way to do this. 
    717     val = m_parent.ReadRegister(MOTU_REG_ROUTE_PORT_CONF); 
    718     if (m_register == MOTU_CTRL_DIR_IN) 
    719       val = (val >> 8) & 0x03; 
    720     else 
    721       val = (val >> 10) & 0x03; 
    722     return val; 
     710    dir = (m_register==MOTU_CTRL_DIR_IN)?MOTU_DIR_IN:MOTU_DIR_OUT; 
     711    switch (m_parent.getOpticalMode(0, dir)) { 
     712        case MOTU_OPTICAL_MODE_OFF: return 0; 
     713        case MOTU_OPTICAL_MODE_ADAT: return 1; 
     714        case MOTU_OPTICAL_MODE_TOSLINK: return 2; 
     715        default: return 0; 
     716    } 
     717    return 0; 
    723718} 
    724719