Show
Ignore:
Timestamp:
11/29/07 12:24:38 (16 years ago)
Author:
ppalmers
Message:

implement clock source selection for DICE EVM

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/src/devicemanager.cpp

    r742 r745  
    162162        { 
    163163            FFADODevice::ClockSource c=*it; 
    164             debugOutput(DEBUG_LEVEL_NORMAL, " Type: %s, Id: %d, Valid: %d, Active: %d, Description: %s\n", 
    165                 FFADODevice::ClockSourceTypeToString(c.type), c.id, c.valid, c.active, c.description.c_str()); 
     164            debugOutput(DEBUG_LEVEL_NORMAL, " Type: %s, Id: %2d, Valid: %1d, Active: %1d, Locked %1d, Slipping: %1d, Description: %s\n", 
     165                FFADODevice::ClockSourceTypeToString(c.type), c.id, c.valid, c.active, c.locked, c.slipping, c.description.c_str()); 
    166166        } 
    167167    } 
  • trunk/libffado/src/dice/dice_avdevice.cpp

    r742 r745  
    282282DiceAvDevice::getSupportedClockSources() { 
    283283    FFADODevice::ClockSourceVector r; 
     284 
     285    quadlet_t clock_caps; 
     286    readGlobalReg(DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, &clock_caps); 
     287    uint16_t clocks_supported = (clock_caps >> 16) & 0xFFFF; 
     288    debugOutput(DEBUG_LEVEL_VERBOSE," Clock caps: 0x%08X, supported=0x%04X\n", 
     289                                    clock_caps, clocks_supported); 
     290 
     291    quadlet_t clock_select; 
     292    readGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, &clock_select); 
     293    byte_t clock_selected = (clock_select) & 0xFF; 
     294    debugOutput(DEBUG_LEVEL_VERBOSE," Clock select: 0x%08X, selected=0x%04X\n", 
     295                                    clock_select, clock_selected); 
     296    quadlet_t extended_status; 
     297    readGlobalReg(DICE_REGISTER_GLOBAL_EXTENDED_STATUS, &extended_status); 
     298    uint16_t clock_status = (extended_status) & 0xFFFF; 
     299    uint16_t clock_slipping = (extended_status >> 16) & 0xFFFF; 
     300    debugOutput(DEBUG_LEVEL_VERBOSE," Clock status: 0x%08X, status=0x%04X, slip=0x%04X\n", 
     301                                    extended_status, clock_status, clock_slipping); 
     302 
     303    diceNameVector names = getClockSourceNameString(); 
     304    if( names.size() < DICE_CLOCKSOURCE_COUNT) { 
     305        debugError("Not enough clock source names on device\n"); 
     306        return r; 
     307    } 
     308    for (unsigned int i=0; i < DICE_CLOCKSOURCE_COUNT; i++) { 
     309        bool supported = (((clocks_supported >> i) & 0x01) == 1); 
     310        if (supported) { 
     311            ClockSource s; 
     312            s.type = clockIdToType(i); 
     313            s.id = i; 
     314            s.valid = true; 
     315            s.locked = isClockSourceIdLocked(i, extended_status); 
     316            s.slipping = isClockSourceIdSlipping(i, extended_status); 
     317            s.active = (clock_selected == i); 
     318            s.description = names.at(i); 
     319            r.push_back(s); 
     320        } else { 
     321            debugOutput(DEBUG_LEVEL_VERBOSE, "Clock source id %d not supported by device\n", i); 
     322        } 
     323    } 
    284324    return r; 
    285325} 
    286326 
    287327bool 
     328DiceAvDevice::isClockSourceIdLocked(unsigned int id, quadlet_t ext_status_reg) { 
     329    switch (id) { 
     330        default: return true; 
     331        case  DICE_CLOCKSOURCE_AES1: 
     332                return ext_status_reg & DICE_EXT_STATUS_AES0_LOCKED; 
     333        case  DICE_CLOCKSOURCE_AES2: 
     334                return ext_status_reg & DICE_EXT_STATUS_AES1_LOCKED; 
     335        case  DICE_CLOCKSOURCE_AES3: 
     336                return ext_status_reg & DICE_EXT_STATUS_AES2_LOCKED; 
     337        case  DICE_CLOCKSOURCE_AES4: 
     338                return ext_status_reg & DICE_EXT_STATUS_AES3_LOCKED; 
     339        case  DICE_CLOCKSOURCE_AES_ANY: 
     340                return ext_status_reg & DICE_EXT_STATUS_AES_ANY_LOCKED; 
     341        case  DICE_CLOCKSOURCE_ADAT: 
     342                return ext_status_reg & DICE_EXT_STATUS_ADAT_LOCKED; 
     343        case  DICE_CLOCKSOURCE_TDIF: 
     344                return ext_status_reg & DICE_EXT_STATUS_TDIF_LOCKED; 
     345        case  DICE_CLOCKSOURCE_ARX1: 
     346                return ext_status_reg & DICE_EXT_STATUS_ARX1_LOCKED; 
     347        case  DICE_CLOCKSOURCE_ARX2: 
     348                return ext_status_reg & DICE_EXT_STATUS_ARX2_LOCKED; 
     349        case  DICE_CLOCKSOURCE_ARX3: 
     350                return ext_status_reg & DICE_EXT_STATUS_ARX3_LOCKED; 
     351        case  DICE_CLOCKSOURCE_ARX4: 
     352                return ext_status_reg & DICE_EXT_STATUS_ARX4_LOCKED; 
     353        case  DICE_CLOCKSOURCE_WC: 
     354                return ext_status_reg & DICE_EXT_STATUS_WC_LOCKED; 
     355    } 
     356} 
     357bool 
     358DiceAvDevice::isClockSourceIdSlipping(unsigned int id, quadlet_t ext_status_reg) { 
     359    switch (id) { 
     360        default: return false; 
     361        case  DICE_CLOCKSOURCE_AES1: 
     362                return ext_status_reg & DICE_EXT_STATUS_AES0_SLIP; 
     363        case  DICE_CLOCKSOURCE_AES2: 
     364                return ext_status_reg & DICE_EXT_STATUS_AES1_SLIP; 
     365        case  DICE_CLOCKSOURCE_AES3: 
     366                return ext_status_reg & DICE_EXT_STATUS_AES2_SLIP; 
     367        case  DICE_CLOCKSOURCE_AES4: 
     368                return ext_status_reg & DICE_EXT_STATUS_AES3_SLIP; 
     369        case  DICE_CLOCKSOURCE_AES_ANY: 
     370                return false; 
     371        case  DICE_CLOCKSOURCE_ADAT: 
     372                return ext_status_reg & DICE_EXT_STATUS_ADAT_SLIP; 
     373        case  DICE_CLOCKSOURCE_TDIF: 
     374                return ext_status_reg & DICE_EXT_STATUS_TDIF_SLIP; 
     375        case  DICE_CLOCKSOURCE_ARX1: 
     376                return ext_status_reg & DICE_EXT_STATUS_ARX1_SLIP; 
     377        case  DICE_CLOCKSOURCE_ARX2: 
     378                return ext_status_reg & DICE_EXT_STATUS_ARX2_SLIP; 
     379        case  DICE_CLOCKSOURCE_ARX3: 
     380                return ext_status_reg & DICE_EXT_STATUS_ARX3_SLIP; 
     381        case  DICE_CLOCKSOURCE_ARX4: 
     382                return ext_status_reg & DICE_EXT_STATUS_ARX4_SLIP; 
     383        case  DICE_CLOCKSOURCE_WC: // FIXME: not in driver spec, so non-existant 
     384                return ext_status_reg & DICE_EXT_STATUS_WC_SLIP; 
     385    } 
     386} 
     387 
     388enum FFADODevice::eClockSourceType 
     389DiceAvDevice::clockIdToType(unsigned int id) { 
     390    switch (id) { 
     391        default: return eCT_Invalid; 
     392        case  DICE_CLOCKSOURCE_AES1: 
     393        case  DICE_CLOCKSOURCE_AES2: 
     394        case  DICE_CLOCKSOURCE_AES3: 
     395        case  DICE_CLOCKSOURCE_AES4: 
     396        case  DICE_CLOCKSOURCE_AES_ANY: 
     397                return eCT_AES; 
     398        case  DICE_CLOCKSOURCE_ADAT: 
     399                return eCT_ADAT; 
     400        case  DICE_CLOCKSOURCE_TDIF: 
     401                return eCT_TDIF; 
     402        case  DICE_CLOCKSOURCE_ARX1: 
     403        case  DICE_CLOCKSOURCE_ARX2: 
     404        case  DICE_CLOCKSOURCE_ARX3: 
     405        case  DICE_CLOCKSOURCE_ARX4: 
     406                return eCT_SytMatch; 
     407        case  DICE_CLOCKSOURCE_WC: 
     408                return eCT_WordClock; 
     409        case DICE_CLOCKSOURCE_INTERNAL: 
     410                return eCT_Internal; 
     411    } 
     412} 
     413 
     414bool 
    288415DiceAvDevice::setActiveClockSource(ClockSource s) { 
    289     return false; 
     416    fb_quadlet_t clockreg; 
     417    if (!readGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, &clockreg)) { 
     418        debugError("Could not read CLOCK_SELECT register\n"); 
     419        return false; 
     420    } 
     421 
     422    clockreg = DICE_SET_CLOCKSOURCE(clockreg, s.id); 
     423 
     424    if (!writeGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, clockreg)) { 
     425        debugError("Could not write CLOCK_SELECT register\n"); 
     426        return false; 
     427    } 
     428 
     429    // check if the write succeeded 
     430    fb_quadlet_t clockreg_verify; 
     431    if (!readGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, &clockreg_verify)) { 
     432        debugError("Could not read CLOCK_SELECT register\n"); 
     433        return false; 
     434    } 
     435 
     436    if(clockreg != clockreg_verify) { 
     437        debugError("CLOCK_SELECT register write failed\n"); 
     438        return false; 
     439    } 
     440 
     441    return DICE_GET_CLOCKSOURCE(clockreg_verify) == s.id; 
    290442} 
    291443 
     
    293445DiceAvDevice::getActiveClockSource() { 
    294446    ClockSource s; 
     447    quadlet_t clock_caps; 
     448    readGlobalReg(DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, &clock_caps); 
     449    uint16_t clocks_supported = (clock_caps >> 16) & 0xFFFF; 
     450    debugOutput(DEBUG_LEVEL_VERBOSE," Clock caps: 0x%08X, supported=0x%04X\n", 
     451                                    clock_caps, clocks_supported); 
     452 
     453    quadlet_t clock_select; 
     454    readGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, &clock_select); 
     455    byte_t id = (clock_select) & 0xFF; 
     456    debugOutput(DEBUG_LEVEL_VERBOSE," Clock select: 0x%08X, selected=0x%04X\n", 
     457                                    clock_select, id); 
     458    quadlet_t extended_status; 
     459    readGlobalReg(DICE_REGISTER_GLOBAL_EXTENDED_STATUS, &extended_status); 
     460    uint16_t clock_status = (extended_status) & 0xFFFF; 
     461    uint16_t clock_slipping = (extended_status >> 16) & 0xFFFF; 
     462    debugOutput(DEBUG_LEVEL_VERBOSE," Clock status: 0x%08X, status=0x%04X, slip=0x%04X\n", 
     463                                    extended_status, clock_status, clock_slipping); 
     464 
     465    diceNameVector names = getClockSourceNameString(); 
     466    if( names.size() < DICE_CLOCKSOURCE_COUNT) { 
     467        debugError("Not enough clock source names on device\n"); 
     468        return s; 
     469    } 
     470    bool supported = (((clocks_supported >> id) & 0x01) == 1); 
     471    if (supported) { 
     472        s.type = clockIdToType(id); 
     473        s.id = id; 
     474        s.valid = true; 
     475        s.locked = isClockSourceIdLocked(id, extended_status); 
     476        s.slipping = isClockSourceIdSlipping(id, extended_status); 
     477        s.active = true; 
     478        s.description = names.at(id); 
     479    } else { 
     480        debugOutput(DEBUG_LEVEL_VERBOSE, "Clock source id %2d not supported by device\n", id); 
     481    } 
    295482    return s; 
    296483} 
     
    302489    fb_octlet_t tmp_octlet; 
    303490 
    304     debugOutput(DEBUG_LEVEL_VERBOSE, 
    305         "%s %s at node %d\n", m_model->vendor_name, m_model->model_name, 
    306         getNodeId()); 
     491    debugOutput(DEBUG_LEVEL_NORMAL, "Device is a DICE device\n"); 
     492    FFADODevice::showDevice(); 
    307493 
    308494    debugOutput(DEBUG_LEVEL_VERBOSE," DICE Parameter Space info:\n"); 
     
    324510 
    325511    readGlobalReg(DICE_REGISTER_GLOBAL_NOTIFICATION, &tmp_quadlet); 
    326     debugOutput(DEBUG_LEVEL_VERBOSE,"  Nick name        : %s\n",getDeviceNickName().c_str()); 
     512    debugOutput(DEBUG_LEVEL_NORMAL,"  Nick name        : %s\n",getDeviceNickName().c_str()); 
    327513 
    328514    readGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, &tmp_quadlet); 
    329     debugOutput(DEBUG_LEVEL_VERBOSE,"  Clock Select     : 0x%02X 0x%02X\n", 
     515    debugOutput(DEBUG_LEVEL_NORMAL,"  Clock Select     : 0x%02X 0x%02X\n", 
    330516        (tmp_quadlet>>8) & 0xFF, tmp_quadlet & 0xFF); 
    331517 
    332518    readGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, &tmp_quadlet); 
    333     debugOutput(DEBUG_LEVEL_VERBOSE,"  Enable           : %s\n", 
     519    debugOutput(DEBUG_LEVEL_NORMAL,"  Enable           : %s\n", 
    334520        (tmp_quadlet&0x1?"true":"false")); 
    335521 
    336522    readGlobalReg(DICE_REGISTER_GLOBAL_STATUS, &tmp_quadlet); 
    337     debugOutput(DEBUG_LEVEL_VERBOSE,"  Clock Status     : %s 0x%02X\n", 
     523    debugOutput(DEBUG_LEVEL_NORMAL,"  Clock Status     : %s 0x%02X\n", 
    338524        (tmp_quadlet&0x1?"locked":"not locked"), (tmp_quadlet>>8) & 0xFF); 
    339525 
     
    342528 
    343529    readGlobalReg(DICE_REGISTER_GLOBAL_SAMPLE_RATE, &tmp_quadlet); 
    344     debugOutput(DEBUG_LEVEL_VERBOSE,"  Samplerate       : 0x%08X (%lu)\n",tmp_quadlet,tmp_quadlet); 
     530    debugOutput(DEBUG_LEVEL_NORMAL,"  Samplerate       : 0x%08X (%lu)\n",tmp_quadlet,tmp_quadlet); 
    345531 
    346532    readGlobalReg(DICE_REGISTER_GLOBAL_VERSION, &tmp_quadlet); 
    347     debugOutput(DEBUG_LEVEL_VERBOSE,"  Version          : 0x%08X (%u.%u.%u.%u)\n", 
     533    debugOutput(DEBUG_LEVEL_NORMAL,"  Version          : 0x%08X (%u.%u.%u.%u)\n", 
    348534        tmp_quadlet, 
    349535        DICE_DRIVER_SPEC_VERSION_NUMBER_GET_A(tmp_quadlet), 
     
    354540 
    355541    readGlobalReg(DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, &tmp_quadlet); 
    356     debugOutput(DEBUG_LEVEL_VERBOSE,"  Clock caps       : 0x%08X\n",tmp_quadlet & 0x1FFF007F); 
     542    debugOutput(DEBUG_LEVEL_VERBOSE,"  Clock caps       : 0x%08X\n",tmp_quadlet); 
    357543 
    358544    diceNameVector names=getClockSourceNameString(); 
     
    425611        } 
    426612    } 
     613    flushDebugOutput(); 
    427614} 
    428615 
  • trunk/libffado/src/dice/dice_avdevice.h

    r742 r745  
    132132    diceNameVector getClockSourceNameString(); 
    133133    std::string getDeviceNickName(); 
     134 
     135    enum eClockSourceType  clockIdToType(unsigned int id); 
     136    bool isClockSourceIdLocked(unsigned int id, quadlet_t ext_status_reg); 
     137    bool isClockSourceIdSlipping(unsigned int id, quadlet_t ext_status_reg); 
    134138 
    135139private: // register I/O routines 
  • trunk/libffado/src/dice/dice_defines.h

    r742 r745  
    185185#define DICE_CLOCKSOURCE_ARX4           0x0B 
    186186#define DICE_CLOCKSOURCE_INTERNAL       0x0C 
     187#define DICE_CLOCKSOURCE_COUNT (DICE_CLOCKSOURCE_INTERNAL+1) 
    187188 
    188189#define DICE_CLOCKSOURCE_MASK           0x0000FFFFLU 
     
    223224#define DICE_EXT_STATUS_AES2_LOCKED         (1UL << 2) 
    224225#define DICE_EXT_STATUS_AES3_LOCKED         (1UL << 3) 
     226#define DICE_EXT_STATUS_AES_ANY_LOCKED      (    0x0F) 
    225227#define DICE_EXT_STATUS_ADAT_LOCKED         (1UL << 4) 
    226228#define DICE_EXT_STATUS_TDIF_LOCKED         (1UL << 5) 
     
    231233 
    232234// FIXME: this one is missing in dicedriverExtStatus.h 
    233 #define DICE_EXT_STATUS_WORDCLOCK_LOCKED    (1UL << 10) 
     235#define DICE_EXT_STATUS_WC_LOCKED          (1UL << 10) 
    234236 
    235237#define DICE_EXT_STATUS_AES0_SLIP           (1UL << 16) 
     
    243245#define DICE_EXT_STATUS_ARX3_SLIP           (1UL << 24) 
    244246#define DICE_EXT_STATUS_ARX4_SLIP           (1UL << 25) 
     247 
     248// FIXME: does this even exist? 
     249#define DICE_EXT_STATUS_WC_SLIP             (1UL << 26) 
    245250 
    246251//   SAMPLE_RATE register 
  • trunk/libffado/src/ffadodevice.cpp

    r742 r745  
    151151                                    s.getPort(), s.getPortName().c_str()); 
    152152    debugOutput(DEBUG_LEVEL_NORMAL, "Node...................: %d\n", getNodeId()); 
     153    debugOutput(DEBUG_LEVEL_NORMAL, "Vendor name............: %s\n", 
     154                                    getConfigRom().getVendorName().c_str()); 
     155    debugOutput(DEBUG_LEVEL_NORMAL, "Model name.............: %s\n", 
     156                                    getConfigRom().getModelName().c_str()); 
    153157    debugOutput(DEBUG_LEVEL_NORMAL, "GUID...................: %s\n", 
    154158                                    getConfigRom().getGuidString().c_str()); 
  • trunk/libffado/src/ffadodevice.h

    r742 r745  
    178178            , valid( false ) 
    179179            , active( false ) 
     180            , locked( true ) 
     181            , slipping( false ) 
    180182            , description( "" ) 
    181183        {} 
     
    184186        /// indicated the id of the clock source (e.g. id=1 => clocksource is ADAT_1) 
    185187        unsigned int id; 
    186         /// is the clock source valid at this moment? 
     188        /// is the clock source valid (i.e. can be selected) at this moment? 
    187189        bool valid; 
    188190        /// is the clock source active at this moment? 
    189191        bool active; 
     192        /// is the clock source locked? 
     193        bool locked; 
     194        /// is the clock source slipping? 
     195        bool slipping; 
    190196        /// description of the clock struct (optional) 
    191197        std::string description; 
  • trunk/libffado/src/fireworks/fireworks_device.cpp

    r742 r745  
    6868    } 
    6969    m_HwInfo.showEfcCmd(); 
    70      
    7170    GenericAVC::AvDevice::showDevice(); 
    7271} 
     
    8382        return vendorModel.isPresent( vendorId, modelId ); 
    8483    } 
    85  
    8684    return false; 
    8785} 
     
    353351        if (s.type != eCT_Invalid) r.push_back(s); 
    354352    } 
    355  
    356353    return r; 
    357354} 
  • trunk/libffado/src/genericavc/avc_avdevice.cpp

    r742 r745  
    385385    FFADODevice::showDevice(); 
    386386 
    387     debugOutput(DEBUG_LEVEL_NORMAL, 
    388         "%s %s\n", m_model.vendor_name.c_str(), m_model.model_name.c_str()); 
    389  
    390387    AVC::Unit::show(); 
    391388    flushDebugOutput();