Changeset 639

Show
Ignore:
Timestamp:
09/09/07 12:04:35 (16 years ago)
Author:
ppalmers
Message:

- Introduce a generic infrastructure for FFADODevices to present the clock sources they support and their state
- Implement this infrastructure for BeBoB devices
- Implement this infrastructure for ECHO Fireworks devices

Files:

Legend:

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

    r618 r639  
    145145} 
    146146 
     147FFADODevice::ClockSourceVector 
     148BounceDevice::getSupportedClockSources() { 
     149    FFADODevice::ClockSourceVector r; 
     150    return r; 
     151} 
     152 
     153bool 
     154BounceDevice::setActiveClockSource(ClockSource s) { 
     155    return false; 
     156} 
     157 
     158FFADODevice::ClockSource 
     159BounceDevice::getActiveClockSource() { 
     160    ClockSource s; 
     161    return s; 
     162} 
     163 
    147164int BounceDevice::getConfigurationId( ) { 
    148165    return 0; 
  • trunk/libffado/src/bounce/bounce_avdevice.h

    r583 r639  
    8181    virtual bool setSamplingFrequency( int samplingFrequency ); 
    8282    virtual int getSamplingFrequency( ); 
     83     
     84    virtual ClockSourceVector getSupportedClockSources(); 
     85    virtual bool setActiveClockSource(ClockSource); 
     86    virtual ClockSource getActiveClockSource(); 
    8387 
    8488    virtual bool prepare(); 
  • trunk/libffado/src/devicemanager.cpp

    r587 r639  
    130130        debugOutput(DEBUG_LEVEL_NORMAL, "--- Device %2d ---\n", i++); 
    131131        avDevice->showDevice(); 
     132 
     133        debugOutput(DEBUG_LEVEL_NORMAL, "Clock sync sources:\n"); 
     134        FFADODevice::ClockSourceVector sources=avDevice->getSupportedClockSources(); 
     135        for ( FFADODevice::ClockSourceVector::const_iterator it 
     136                = sources.begin(); 
     137            it != sources.end(); 
     138            ++it ) 
     139        { 
     140            FFADODevice::ClockSource c=*it; 
     141            debugOutput(DEBUG_LEVEL_NORMAL, " Type: %s, Id: %d, Valid: %d, Active: %d, Description: %s\n", 
     142                FFADODevice::ClockSourceTypeToString(c.type), c.id, c.valid, c.active, c.description.c_str()); 
     143        } 
     144 
    132145    } 
    133146} 
  • trunk/libffado/src/dice/dice_avdevice.cpp

    r587 r639  
    280280} 
    281281 
     282FFADODevice::ClockSourceVector 
     283DiceAvDevice::getSupportedClockSources() { 
     284    FFADODevice::ClockSourceVector r; 
     285    return r; 
     286} 
     287 
     288bool 
     289DiceAvDevice::setActiveClockSource(ClockSource s) { 
     290    return false; 
     291} 
     292 
     293FFADODevice::ClockSource 
     294DiceAvDevice::getActiveClockSource() { 
     295    ClockSource s; 
     296    return s; 
     297} 
     298 
    282299void 
    283300DiceAvDevice::showDevice() 
  • trunk/libffado/src/dice/dice_avdevice.h

    r583 r639  
    7171    virtual bool setSamplingFrequency( int samplingFrequency ); 
    7272    virtual int getSamplingFrequency( ); 
     73 
     74    virtual ClockSourceVector getSupportedClockSources(); 
     75    virtual bool setActiveClockSource(ClockSource); 
     76    virtual ClockSource getActiveClockSource(); 
    7377 
    7478    virtual int getStreamCount(); 
  • trunk/libffado/src/ffadodevice.cpp

    r623 r639  
    148148    return true; 
    149149} 
     150 
     151const char * 
     152FFADODevice::ClockSourceTypeToString(enum eClockSourceType t) 
     153{ 
     154    switch(t) { 
     155        default:            return "Erratic type      "; 
     156        case eCT_Invalid:   return "Invalid           "; 
     157        case eCT_Internal:  return "Internal          "; 
     158        case eCT_1394Bus:   return "1394 Bus          "; 
     159        case eCT_SytMatch:  return "Compound Syt Match"; 
     160        case eCT_SytStream: return "Sync Syt Match    "; 
     161        case eCT_WordClock: return "WordClock         "; 
     162        case eCT_SPDIF:     return "SPDIF             "; 
     163        case eCT_ADAT:      return "ADAT              "; 
     164        case eCT_TDIF:      return "TDIF              "; 
     165        case eCT_AES:       return "AES               "; 
     166    } 
     167} 
  • trunk/libffado/src/ffadodevice.h

    r623 r639  
    3131#include "libieee1394/vendor_model_ids.h" 
    3232 
     33#include <vector> 
     34#include <string> 
     35 
    3336class ConfigRom; 
    3437class Ieee1394Service; 
     
    149152 
    150153    /** 
     154     * @brief clock source types 
     155     */ 
     156    enum eClockSourceType { 
     157        eCT_Invalid,   ///> invalid entry (e.g. on error) 
     158        eCT_Internal,  ///> internal sync (unspecified) 
     159        eCT_1394Bus,   ///> Sync on the 1394 bus clock (e.g. CSP) 
     160        eCT_SytMatch,  ///> SYT match on incoming audio stream 
     161        eCT_SytStream, ///> SYT match on incoming sync stream 
     162        eCT_WordClock, ///> SYT on WordClock input 
     163        eCT_SPDIF,     ///> SYT on SPDIF input 
     164        eCT_ADAT,      ///> SYT on ADAT input 
     165        eCT_TDIF,      ///> SYT on TDIF input 
     166        eCT_AES,       ///> SYT on AES input 
     167    }; 
     168 
     169    /** 
     170     * @brief convert the clock source type to a C string 
     171     * @return a C string describing the clock source type 
     172     */ 
     173    static const char *ClockSourceTypeToString(enum eClockSourceType); 
     174 
     175    /** 
     176     * @brief Clock source identification struct 
     177     */ 
     178    struct sClockSource { 
     179        sClockSource() 
     180            : type( eCT_Invalid ) 
     181            , id( 0 ) 
     182            , valid( false ) 
     183            , active( false ) 
     184            , description( "" ) 
     185        {} 
     186        /// indicates the type of the clock source (e.g. eCT_ADAT) 
     187        enum eClockSourceType type; 
     188        /// indicated the id of the clock source (e.g. id=1 => clocksource is ADAT_1) 
     189        unsigned int id; 
     190        /// is the clock source valid at this moment? 
     191        bool valid; 
     192        /// is the clock source active at this moment? 
     193        bool active; 
     194        /// description of the clock struct (optional) 
     195        std::string description; 
     196    }; 
     197    typedef struct sClockSource ClockSource; 
     198 
     199    typedef std::vector< ClockSource > ClockSourceVector; 
     200    typedef std::vector< ClockSource >::iterator ClockSourceVectorIterator; 
     201 
     202    /** 
     203     * @brief Get the clocksources supported by this device 
     204     * 
     205     * This function returns a vector of ClockSource structures that contains 
     206     * one entry for every clock source supported by the device. 
     207     * 
     208     * @returns a vector of ClockSource structures 
     209     */ 
     210    virtual ClockSourceVector getSupportedClockSources() = 0; 
     211 
     212 
     213    /** 
     214     * @brief Sets the active clock source of this device 
     215     * 
     216     * This function sets the clock source of the device. 
     217     * 
     218     * @returns true upon success. false upon failure. 
     219     */ 
     220    virtual bool setActiveClockSource(ClockSource) = 0; 
     221 
     222    /** 
     223     * @brief Returns the active clock source of this device 
     224     * 
     225     * This function returns the active clock source of the device. 
     226     * 
     227     * @returns the active ClockSource 
     228     */ 
     229    virtual ClockSource getActiveClockSource() = 0; 
     230 
     231    /** 
    151232     * @brief This is called by the device manager to give the device a unique ID. 
    152233     * 
  • trunk/libffado/src/fireworks/audiofire/audiofire_device.h

    r587 r639  
    3333 
    3434class AudioFire : public FireWorks::Device { 
     35 
    3536public: 
    3637    AudioFire( Ieee1394Service& ieee1394Service, 
  • trunk/libffado/src/fireworks/efc/efc_cmd.h

    r629 r639  
    4545#define EFC_CAT_COUNT                   10 
    4646 
     47// Commands for the EFC_CAT_HARDWARE_INFO category 
     48#define EFC_CMD_HW_HWINFO_GET_CAPS      0 
     49#define EFC_CMD_HW_GET_POLLED           1 
     50#define EFC_CMD_HW_SET_EFR_ADDRESS      2 
     51#define EFC_CMD_HW_READ_SESSION_BLOCK   3 
     52#define EFC_CMD_HW_GET_DEBUG_INFO       4 
     53#define EFC_CMD_HW_SET_DEBUG_TRACKING   5 
     54#define EFC_CMD_HW_COUNT                6 
     55 
     56// Commands for the EFC_CAT_HARDWARE_CONTROL category 
     57#define EFC_CMD_HWCTRL_SET_CLOCK        0 
     58#define EFC_CMD_HWCTRL_GET_CLOCK        1 
     59#define EFC_CMD_HWCTRL_BSX_HANDSHAKE    2 
     60#define EFC_CMD_HWCTRL_CHANGE_FLAGS     3 
     61#define EFC_CMD_HWCTRL_GET_FLAGS        4 
     62#define EFC_CMD_HWCTRL_IDENTIFY         5 
     63#define EFC_CMD_HWCTRL_RECONNECT_PHY    6 
     64 
    4765// size of the header 
    4866#define EFC_HEADER_LENGTH_QUADLETS      ((sizeof(uint32_t) + sizeof(struct EfcCmd::efc_header))/4) 
     
    5371      *(__value__)=ntohl(*(__value__)); } \ 
    5472 
     73 
     74// specifiers for the flags field 
     75#define EFC_CMD_HW_DYNADDR_SUPPORTED                1 
     76#define EFC_CMD_HW_MIRRORING_SUPPORTED              2 
     77#define EFC_CMD_HW_SPDIF_COAX_SUPPORTED             3 
     78#define EFC_CMD_HW_SPDIF_AESEBUXLR_SUPPORTED        4 
     79#define EFC_CMD_HW_HAS_DSP                          5 
     80#define EFC_CMD_HW_HAS_FPGA                         6 
     81#define EFC_CMD_HW_HAS_PHANTOM                      7 
     82 
     83#define EFC_CMD_HW_CHECK_FLAG(__val__,__flag__) \ 
     84    (((__val__) & (1<<(__flag__))) != 0) 
     85#define EFC_CMD_HW_TO_FLAG(__val__) \ 
     86    (1<<(__val__)) 
     87 
     88// Clock sources 
     89#define EFC_CMD_HW_CLOCK_INTERNAL                   0 
     90#define EFC_CMD_HW_CLOCK_SYTMATCH                   1 
     91#define EFC_CMD_HW_CLOCK_WORDCLOCK                  2 
     92#define EFC_CMD_HW_CLOCK_SPDIF                      3 
     93#define EFC_CMD_HW_CLOCK_ADAT_1                     4 
     94#define EFC_CMD_HW_CLOCK_ADAT_2                     5 
     95#define EFC_CMD_HW_CLOCK_COUNT                      6 
     96 
     97#define EFC_CMD_HW_CLOCK_UNSPECIFIED       0xFFFFFFFF 
     98 
     99// MIDI flags 
     100#define EFC_CMD_HW_MIDI_IN_1                        8 
     101#define EFC_CMD_HW_MIDI_OUT_1                       9 
     102#define EFC_CMD_HW_MIDI_IN_2                       10 
     103#define EFC_CMD_HW_MIDI_OUT_2                      11 
     104 
     105// Channel types 
     106#define EFC_CMD_HW_CHANNEL_TYPE_ANALOG              0 
     107#define EFC_CMD_HW_CHANNEL_TYPE_SPDIF               1 
     108#define EFC_CMD_HW_CHANNEL_TYPE_ADAT                2 
     109#define EFC_CMD_HW_CHANNEL_TYPE_SPDIF_OR_ADAT       3 
     110#define EFC_CMD_HW_CHANNEL_TYPE_ANALOG_MIRRORING    4 
     111#define EFC_CMD_HW_CHANNEL_TYPE_HEADPHONES          5 
     112#define EFC_CMD_HW_CHANNEL_TYPE_I2S                 6 
    55113 
    56114namespace FireWorks { 
  • trunk/libffado/src/fireworks/efc/efc_cmds_hardware.cpp

    r629 r639  
    3333EfcHardwareInfoCmd::EfcHardwareInfoCmd() 
    3434: EfcCmd(EFC_CAT_HARDWARE_INFO, EFC_CMD_HW_HWINFO_GET_CAPS) 
     35, m_nb_out_groups( 0 ) 
     36, m_nb_in_groups( 0 ) 
    3537{} 
    3638 
     
    169171EfcPolledValuesCmd::EfcPolledValuesCmd() 
    170172: EfcCmd(EFC_CAT_HARDWARE_INFO, EFC_CMD_HW_GET_POLLED) 
     173, m_nb_output_meters ( 0 ) 
     174, m_nb_input_meters ( 0 ) 
    171175{} 
    172176 
     
    195199     
    196200    EFC_DESERIALIZE_AND_SWAP(de, &m_detect_spdif, result); 
    197     EFC_DESERIALIZE_AND_SWAP(de, &m_detect_spdif, result);     
     201    EFC_DESERIALIZE_AND_SWAP(de, &m_detect_adat, result); 
    198202    EFC_DESERIALIZE_AND_SWAP(de, &m_reserved3, result); 
    199203    EFC_DESERIALIZE_AND_SWAP(de, &m_reserved4, result); 
    200204 
    201205    EFC_DESERIALIZE_AND_SWAP(de, &m_nb_output_meters, result); 
    202     EFC_DESERIALIZE_AND_SWAP(de, &m_nb_input_meters, result);     
     206    EFC_DESERIALIZE_AND_SWAP(de, &m_nb_input_meters, result); 
    203207    EFC_DESERIALIZE_AND_SWAP(de, &m_reserved5, result); 
    204208    EFC_DESERIALIZE_AND_SWAP(de, &m_reserved6, result); 
  • trunk/libffado/src/fireworks/efc/efc_cmds_hardware.h

    r629 r639  
    3232#define HWINFO_MAX_CAPS_GROUPS      8 
    3333#define POLLED_MAX_NB_METERS        100 
    34  
    35 // Commands for the EFC_CAT_HARDWARE_INFO category 
    36 #define EFC_CMD_HW_HWINFO_GET_CAPS      0 
    37 #define EFC_CMD_HW_GET_POLLED           1 
    38 #define EFC_CMD_HW_SET_EFR_ADDRESS      2 
    39 #define EFC_CMD_HW_READ_SESSION_BLOCK   3 
    40 #define EFC_CMD_HW_GET_DEBUG_INFO       4 
    41 #define EFC_CMD_HW_SET_DEBUG_TRACKING   5 
    42 #define EFC_CMD_HW_COUNT                6 
    43  
    44  
    4534 
    4635class EfcHardwareInfoCmd : public EfcCmd 
  • trunk/libffado/src/fireworks/fireworks_device.cpp

    r629 r639  
    2626#include "efc/efc_cmd.h" 
    2727#include "efc/efc_cmds_hardware.h" 
     28#include "efc/efc_cmds_hardware_ctrl.h" 
    2829 
    2930#include "audiofire/audiofire_device.h" 
     
    4041                            std::auto_ptr<ConfigRom>( configRom )) 
    4142    : GenericAVC::AvDevice( ieee1394Service, configRom) 
     43    , m_efc_discovery_done ( false ) 
    4244{ 
    4345    debugOutput( DEBUG_LEVEL_VERBOSE, "Created FireWorks::Device (NodeID %d)\n", 
    4446                 getConfigRom().getNodeId() ); 
     47    pthread_mutex_init( &m_polled_mutex, 0 ); 
    4548} 
    4649 
     
    5356{ 
    5457    debugOutput(DEBUG_LEVEL_VERBOSE, "This is a FireWorks::Device\n"); 
    55 //     GenericAVC::AvDevice::showDevice(); 
    56  
     58    GenericAVC::AvDevice::showDevice(); 
     59
     60 
     61 
     62bool 
     63Device::probe( ConfigRom& configRom ) 
     64
     65    unsigned int vendorId = configRom.getNodeVendorId(); 
     66    unsigned int modelId = configRom.getModelId(); 
     67 
     68    GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_fireworks.txt" ); 
     69    if ( vendorModel.parse() ) { 
     70        vendorModel.printTable(); 
     71        return vendorModel.isPresent( vendorId, modelId ); 
     72    } 
     73 
     74    return false; 
     75
     76 
     77bool 
     78Device::discover() 
     79
     80    unsigned int vendorId = m_pConfigRom->getNodeVendorId(); 
     81    unsigned int modelId = m_pConfigRom->getModelId(); 
     82 
     83    GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_fireworks.txt" ); 
     84    if ( vendorModel.parse() ) { 
     85        m_model = vendorModel.find( vendorId, modelId ); 
     86    } 
     87 
     88    if (!GenericAVC::VendorModel::isValid(m_model)) { 
     89        return false; 
     90    } 
     91    debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", 
     92            m_model.vendor_name.c_str(), m_model.model_name.c_str()); 
     93 
     94    // get the info from the EFC 
     95    if ( !discoverUsingEFC() ) { 
     96        debugError( "Could not discover using EFC\n" ); 
     97        return false; 
     98    } 
     99 
     100    // discover AVC-wise 
     101    if ( !GenericAVC::AvDevice::discover() ) { 
     102        debugError( "Could not discover GenericAVC::AvDevice\n" ); 
     103        return false; 
     104    } 
     105 
     106    return true; 
     107
     108 
     109bool 
     110Device::discoverUsingEFC() 
     111
     112    m_efc_discovery_done = false; 
     113 
     114    if (!doEfcOverAVC(m_HwInfo)) { 
     115        debugError("Could not read hardware capabilities\n"); 
     116        return false; 
     117    } 
     118 
     119    // save the EFC version, since some stuff 
     120    // depends on this 
     121    m_efc_version = m_HwInfo.m_header.version; 
     122 
     123    if (!updatePolledValues()) { 
     124        debugError("Could not update polled values\n"); 
     125        return false; 
     126    } 
     127 
     128    m_efc_discovery_done = true; 
     129    return true; 
     130
     131 
     132FFADODevice * 
     133Device::createDevice( Ieee1394Service& ieee1394Service, 
     134                      std::auto_ptr<ConfigRom>( configRom )) 
     135
     136    unsigned int vendorId = configRom->getNodeVendorId(); 
     137    unsigned int modelId = configRom->getModelId(); 
     138 
     139    switch(vendorId) { 
     140        case FW_VENDORID_ECHO: return new ECHO::AudioFire(ieee1394Service, configRom ); 
     141        default: return new Device(ieee1394Service, configRom ); 
     142    } 
     143
     144 
     145bool  
     146Device::doEfcOverAVC(EfcCmd &c) { 
    57147    EfcOverAVCCmd cmd( get1394Service() ); 
    58148    cmd.setCommandType( AVC::AVCCommand::eCT_Control ); 
     
    60150    cmd.setSubunitType( AVC::eST_Unit  ); 
    61151    cmd.setSubunitId( 0xff ); 
    62      
     152 
    63153    cmd.setVerbose( getDebugLevel() ); 
    64     cmd.setVerbose( DEBUG_LEVEL_VERY_VERBOSE ); 
    65  
    66     EfcHardwareInfoCmd *efccmd=new EfcHardwareInfoCmd(); 
    67     if (!efccmd) { 
    68         debugError("could not allocate efc cmd\n"); 
    69         return; 
    70     } 
    71     cmd.m_cmd = efccmd; 
    72  
    73     if ( !cmd.fire() ) { 
     154//     cmd.setVerbose( DEBUG_LEVEL_VERY_VERBOSE ); 
     155 
     156    cmd.m_cmd = &c; 
     157 
     158//     c.showEfcCmd(); 
     159 
     160    if ( !cmd.fire()) { 
    74161        debugError( "EfcOverAVCCmd command failed\n" ); 
    75     } 
    76  
    77     efccmd->showEfcCmd(); 
    78     delete efccmd; 
    79      
    80     // test the next command 
    81     cmd.setCommandType( AVC::AVCCommand::eCT_Control ); 
    82      
    83     EfcPolledValuesCmd *efccmd2=new EfcPolledValuesCmd(); 
    84     if (!efccmd2) { 
    85         debugError("could not allocate efc cmd 2\n"); 
    86         return; 
    87     } 
    88     cmd.m_cmd = efccmd2; 
    89  
    90     if ( !cmd.fire() ) { 
    91         debugError( "EfcOverAVCCmd command failed\n" ); 
    92     } 
    93  
    94     efccmd2->showEfcCmd(); 
    95     delete efccmd2; 
    96      
    97 
    98  
    99  
    100 bool 
    101 Device::probe( ConfigRom& configRom ) 
    102 
    103     unsigned int vendorId = configRom.getNodeVendorId(); 
    104     unsigned int modelId = configRom.getModelId(); 
    105  
    106     GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_fireworks.txt" ); 
    107     if ( vendorModel.parse() ) { 
    108         vendorModel.printTable(); 
    109         return vendorModel.isPresent( vendorId, modelId ); 
    110     } 
    111  
    112     return false; 
    113 
    114  
    115 bool 
    116 Device::discover() 
    117 
    118     unsigned int vendorId = m_pConfigRom->getNodeVendorId(); 
    119     unsigned int modelId = m_pConfigRom->getModelId(); 
    120  
    121     GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_fireworks.txt" ); 
    122     if ( vendorModel.parse() ) { 
    123         m_model = vendorModel.find( vendorId, modelId ); 
    124     } 
    125  
    126     if (!GenericAVC::VendorModel::isValid(m_model)) { 
    127         return false; 
    128     } 
    129     debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", 
    130             m_model.vendor_name.c_str(), m_model.model_name.c_str()); 
    131  
    132     if ( !GenericAVC::AvDevice::discover() ) { 
    133         debugError( "Could not discover GenericAVC::AvDevice\n" ); 
     162        c.showEfcCmd(); 
     163        return false; 
     164    } 
     165//     c.showEfcCmd(); 
     166 
     167    if (   c.m_header.retval != EfcCmd::eERV_Ok 
     168        && c.m_header.retval != EfcCmd::eERV_FlashBusy) { 
     169        debugError( "EFC command failed\n" ); 
     170        c.showEfcCmd(); 
    134171        return false; 
    135172    } 
     
    138175} 
    139176 
    140 FFADODevice * 
    141 Device::createDevice( Ieee1394Service& ieee1394Service, 
    142                       std::auto_ptr<ConfigRom>( configRom )) 
    143 
    144     unsigned int vendorId = configRom->getNodeVendorId(); 
    145  
    146 //     return NULL; 
    147  
    148     unsigned int modelId = configRom->getModelId(); 
    149  
    150     switch(vendorId) { 
    151         case FW_VENDORID_ECHO: return new ECHO::AudioFire(ieee1394Service, configRom ); 
    152         default: return new Device(ieee1394Service, configRom ); 
    153     } 
    154 
    155  
     177bool 
     178Device::updatePolledValues() { 
     179    bool retval; 
     180 
     181    pthread_mutex_lock( &m_polled_mutex ); 
     182    retval = doEfcOverAVC(m_Polled); 
     183    pthread_mutex_unlock( &m_polled_mutex ); 
     184 
     185    return retval; 
     186
     187 
     188FFADODevice::ClockSourceVector 
     189Device::getSupportedClockSources() { 
     190    FFADODevice::ClockSourceVector r; 
     191 
     192    if (!m_efc_discovery_done) { 
     193        debugError("EFC discovery not done yet!\n"); 
     194        return r; 
     195    } 
     196 
     197    uint32_t active_clock=getClock(); 
     198 
     199    if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_INTERNAL)) { 
     200        debugOutput(DEBUG_LEVEL_VERBOSE, "Internal clock supported\n"); 
     201        ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_INTERNAL); 
     202        s.active=(active_clock == EFC_CMD_HW_CLOCK_INTERNAL); 
     203        if (s.type != eCT_Invalid) r.push_back(s); 
     204    } 
     205    if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_SYTMATCH)) { 
     206        debugOutput(DEBUG_LEVEL_VERBOSE, "Syt Match clock supported\n"); 
     207        ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_SYTMATCH); 
     208        s.active=(active_clock == EFC_CMD_HW_CLOCK_SYTMATCH); 
     209        if (s.type != eCT_Invalid) r.push_back(s); 
     210    } 
     211    if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_WORDCLOCK)) { 
     212        debugOutput(DEBUG_LEVEL_VERBOSE, "WordClock supported\n"); 
     213        ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_WORDCLOCK); 
     214        s.active=(active_clock == EFC_CMD_HW_CLOCK_WORDCLOCK); 
     215        if (s.type != eCT_Invalid) r.push_back(s); 
     216    } 
     217    if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_SPDIF)) { 
     218        debugOutput(DEBUG_LEVEL_VERBOSE, "SPDIF clock supported\n"); 
     219        ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_SPDIF); 
     220        s.active=(active_clock == EFC_CMD_HW_CLOCK_SPDIF); 
     221        if (s.type != eCT_Invalid) r.push_back(s); 
     222    } 
     223    if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_ADAT_1)) { 
     224        debugOutput(DEBUG_LEVEL_VERBOSE, "ADAT 1 clock supported\n"); 
     225        ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_ADAT_1); 
     226        s.active=(active_clock == EFC_CMD_HW_CLOCK_ADAT_1); 
     227        if (s.type != eCT_Invalid) r.push_back(s); 
     228    } 
     229    if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_ADAT_2)) { 
     230        debugOutput(DEBUG_LEVEL_VERBOSE, "ADAT 2 clock supported\n"); 
     231        ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_ADAT_2); 
     232        s.active=(active_clock == EFC_CMD_HW_CLOCK_ADAT_2); 
     233        if (s.type != eCT_Invalid) r.push_back(s); 
     234    } 
     235 
     236    return r; 
     237
     238 
     239bool 
     240Device::isClockValid(uint32_t id) { 
     241    // always valid 
     242    if (id==EFC_CMD_HW_CLOCK_INTERNAL) return true; 
     243 
     244    // the polled values are used to detect 
     245    // whether clocks are valid 
     246    if (!updatePolledValues()) { 
     247        debugError("Could not update polled values\n"); 
     248        return false; 
     249    } 
     250    return EFC_CMD_HW_CHECK_FLAG(m_Polled.m_status,id); 
     251
     252 
     253bool 
     254Device::setActiveClockSource(ClockSource s) { 
     255    bool result; 
     256 
     257    debugOutput(DEBUG_LEVEL_VERBOSE, "setting clock source to id: %d\n",s.id); 
     258 
     259    if(!isClockValid(s.id)) { 
     260        debugError("Clock not valid\n"); 
     261        return false; 
     262    } 
     263 
     264    result=setClock(s.id); 
     265 
     266    // From the ECHO sources: 
     267    // "If this is a 1200F and the sample rate is being set via EFC, then 
     268    // send the "phy reconnect command" so the device will vanish and reappear  
     269    // with a new descriptor." 
     270 
     271//     EfcPhyReconnectCmd rccmd; 
     272//     if(!doEfcOverAVC(rccmd)) { 
     273//         debugError("Phy reconnect failed"); 
     274//     } else { 
     275//         // sleep for one second such that the phy can get reconnected 
     276//         sleep(1); 
     277//     } 
     278 
     279    return result; 
     280
     281 
     282FFADODevice::ClockSource 
     283Device::getActiveClockSource() { 
     284    ClockSource s; 
     285    uint32_t active_clock=getClock(); 
     286    s=clockIdToClockSource(active_clock); 
     287    s.active=true; 
     288    return s; 
     289
     290 
     291FFADODevice::ClockSource 
     292Device::clockIdToClockSource(uint32_t clockid) { 
     293    ClockSource s; 
     294    debugOutput(DEBUG_LEVEL_VERBOSE, "clock id: %lu\n", clockid); 
     295 
     296    // the polled values are used to detect 
     297    // whether clocks are valid 
     298    if (!updatePolledValues()) { 
     299        debugError("Could not update polled values\n"); 
     300        return s; 
     301    } 
     302 
     303    switch (clockid) { 
     304        case EFC_CMD_HW_CLOCK_INTERNAL: 
     305            debugOutput(DEBUG_LEVEL_VERBOSE, "Internal clock\n"); 
     306            s.type=eCT_Internal; 
     307            s.description="Internal sync"; 
     308            break; 
     309 
     310        case EFC_CMD_HW_CLOCK_SYTMATCH: 
     311            debugOutput(DEBUG_LEVEL_VERBOSE, "Syt Match\n"); 
     312            s.type=eCT_SytMatch; 
     313            s.description="SYT Match"; 
     314            break; 
     315 
     316        case EFC_CMD_HW_CLOCK_WORDCLOCK: 
     317            debugOutput(DEBUG_LEVEL_VERBOSE, "WordClock\n"); 
     318            s.type=eCT_WordClock; 
     319            s.description="Word Clock"; 
     320            break; 
     321 
     322        case EFC_CMD_HW_CLOCK_SPDIF: 
     323            debugOutput(DEBUG_LEVEL_VERBOSE, "SPDIF clock\n"); 
     324            s.type=eCT_SPDIF; 
     325            s.description="SPDIF"; 
     326            break; 
     327 
     328        case EFC_CMD_HW_CLOCK_ADAT_1: 
     329            debugOutput(DEBUG_LEVEL_VERBOSE, "ADAT 1 clock\n"); 
     330            s.type=eCT_ADAT; 
     331            s.description="ADAT 1"; 
     332            break; 
     333 
     334        case EFC_CMD_HW_CLOCK_ADAT_2: 
     335            debugOutput(DEBUG_LEVEL_VERBOSE, "ADAT 2 clock\n"); 
     336            s.type=eCT_ADAT; 
     337            s.description="ADAT 2"; 
     338            break; 
     339 
     340        default: 
     341            debugError("Invalid clock id: %d\n",clockid); 
     342            return s; // return an invalid ClockSource 
     343    } 
     344 
     345    s.id=clockid; 
     346    s.valid=isClockValid(clockid); 
     347 
     348    return s; 
     349
     350 
     351uint32_t 
     352Device::getClock() { 
     353    EfcGetClockCmd gccmd; 
     354    if (!doEfcOverAVC(gccmd)) { 
     355        debugError("Could not get clock info\n"); 
     356        return EFC_CMD_HW_CLOCK_UNSPECIFIED; 
     357    } 
     358    debugOutput(DEBUG_LEVEL_VERBOSE, "Active clock: 0x%08lX\n",gccmd.m_clock); 
     359    gccmd.showEfcCmd(); 
     360 
     361    return gccmd.m_clock; 
     362
     363 
     364bool 
     365Device::setClock(uint32_t id) { 
     366    EfcGetClockCmd gccmd; 
     367    if (!doEfcOverAVC(gccmd)) { 
     368        debugError("Could not get clock info\n"); 
     369        return false; 
     370    } 
     371    debugOutput(DEBUG_LEVEL_VERBOSE, "Set clock: 0x%08lX\n", id); 
     372 
     373    EfcSetClockCmd sccmd; 
     374    sccmd.m_clock=id; 
     375    sccmd.m_samplerate=gccmd.m_samplerate; 
     376    sccmd.m_index=0; 
     377    if (!doEfcOverAVC(sccmd)) { 
     378        debugError("Could not set clock info\n"); 
     379        return false; 
     380    } 
     381    return true; 
     382
    156383 
    157384} // FireWorks 
  • trunk/libffado/src/fireworks/fireworks_device.h

    r589 r639  
    3030#include "genericavc/avc_avdevice.h" 
    3131 
     32#include "efc/efc_cmd.h" 
     33#include "efc/efc_cmds_hardware.h" 
     34 
     35#include <pthread.h> 
     36 
    3237class ConfigRom; 
    3338class Ieee1394Service; 
     
    4752 
    4853    virtual void showDevice(); 
     54     
     55    virtual ClockSourceVector getSupportedClockSources(); 
     56    virtual bool setActiveClockSource(ClockSource); 
     57    virtual ClockSource getActiveClockSource(); 
     58 
     59// Echo specific stuff 
     60private: 
     61    bool doEfcOverAVC(EfcCmd& c); 
     62     
     63    bool discoverUsingEFC(); 
     64 
     65    FFADODevice::ClockSource clockIdToClockSource(uint32_t clockflag); 
     66    bool isClockValid(uint32_t id); 
     67    uint32_t getClock(); 
     68    bool setClock(uint32_t); 
     69 
     70    uint32_t            m_efc_version; 
     71 
     72    EfcHardwareInfoCmd  m_HwInfo; 
     73 
     74    bool updatePolledValues(); 
     75    pthread_mutex_t     m_polled_mutex; 
     76    EfcPolledValuesCmd  m_Polled; 
     77 
     78    bool                m_efc_discovery_done; 
    4979 
    5080}; 
  • trunk/libffado/src/genericavc/avc_avdevice.cpp

    r630 r639  
    210210} 
    211211 
     212FFADODevice::ClockSourceVector 
     213AvDevice::getSupportedClockSources() { 
     214    FFADODevice::ClockSourceVector r; 
     215 
     216    PlugVector syncMSUInputPlugs = m_pPlugManager->getPlugsByType( 
     217        eST_Music, 
     218        0, 
     219        0xff, 
     220        0xff, 
     221        Plug::eAPA_SubunitPlug, 
     222        Plug::eAPD_Input, 
     223        Plug::eAPT_Sync ); 
     224    if ( !syncMSUInputPlugs.size() ) { 
     225        debugWarning( "No sync input plug for MSU subunit found\n" ); 
     226        return r; 
     227    } 
     228 
     229    for ( SyncInfoVector::const_iterator it 
     230              = getSyncInfos().begin(); 
     231          it != getSyncInfos().end(); 
     232          ++it ) 
     233    { 
     234        const SyncInfo si=*it; 
     235 
     236        // check if the destination is a MSU input plug 
     237        bool found=false; 
     238        for ( PlugVector::const_iterator it2 = syncMSUInputPlugs.begin(); 
     239            it2 != syncMSUInputPlugs.end(); 
     240            ++it2 ) 
     241        { 
     242            AVC::Plug* msuPlug = *it2; 
     243            found |= (msuPlug == si.m_destination); 
     244        } 
     245 
     246        if (found) { 
     247            ClockSource s=syncInfoToClockSource(*it); 
     248            r.push_back(s); 
     249        } 
     250    } 
     251 
     252    return r; 
     253} 
     254 
     255bool 
     256AvDevice::setActiveClockSource(ClockSource s) { 
     257    Plug *src=m_pPlugManager->getPlug( s.id ); 
     258    if (!src) { 
     259        debugError("Could not find plug with id %d\n", s.id); 
     260        return false; 
     261    } 
     262 
     263    for ( SyncInfoVector::const_iterator it 
     264              = getSyncInfos().begin(); 
     265          it != getSyncInfos().end(); 
     266          ++it ) 
     267    { 
     268        const SyncInfo si=*it; 
     269 
     270        if (si.m_source==src) { 
     271            return setActiveSync(si); 
     272        } 
     273    } 
     274 
     275    return false; 
     276} 
     277 
     278FFADODevice::ClockSource 
     279AvDevice::getActiveClockSource() { 
     280    const SyncInfo* si=getActiveSyncInfo(); 
     281    if ( !si ) { 
     282        debugError( "Could not retrieve active sync information\n" ); 
     283        ClockSource s; 
     284        s.type=eCT_Invalid; 
     285        return s; 
     286    } 
     287    debugOutput(DEBUG_LEVEL_VERBOSE, "Active Sync mode:  %s\n", si->m_description.c_str() ); 
     288 
     289    return syncInfoToClockSource(*si); 
     290} 
     291 
     292FFADODevice::ClockSource 
     293AvDevice::syncInfoToClockSource(const SyncInfo& si) { 
     294    ClockSource s; 
     295 
     296    // the description is easy 
     297    // it can be that we overwrite it later 
     298    s.description=si.m_description; 
     299 
     300    // FIXME: always valid at the moment 
     301    s.valid=true; 
     302 
     303    assert(si.m_source); 
     304    s.id=si.m_source->getGlobalId(); 
     305 
     306    // now figure out what type this is 
     307    switch(si.m_source->getPlugType()) { 
     308        case Plug::eAPT_IsoStream: 
     309            s.type=eCT_SytMatch; 
     310            break; 
     311        case Plug::eAPT_Sync: 
     312            if(si.m_source->getPlugAddressType() == Plug::eAPA_PCR) { 
     313                s.type=eCT_SytStream; // this is logical 
     314            } else if(si.m_source->getPlugAddressType() == Plug::eAPA_SubunitPlug) { 
     315                s.type=eCT_Internal; // this assumes some stuff 
     316            } else if(si.m_source->getPlugAddressType() == Plug::eAPA_ExternalPlug) { 
     317                std::string plugname=si.m_source->getName(); 
     318                s.description=plugname; 
     319                // this is basically due to Focusrites interpretation 
     320                if(plugname.find( "SPDIF", 0 ) != string::npos) { 
     321                    s.type=eCT_SPDIF; // this assumes the name will tell us 
     322                } else { 
     323                    s.type=eCT_WordClock; // this assumes a whole lot more 
     324                } 
     325            } else { 
     326                s.type=eCT_Invalid; 
     327            } 
     328            break; 
     329        case Plug::eAPT_Digital: 
     330            if(si.m_source->getPlugAddressType() == Plug::eAPA_ExternalPlug) { 
     331                std::string plugname=si.m_source->getName(); 
     332                s.description=plugname; 
     333                // this is basically due to Focusrites interpretation 
     334                if(plugname.find( "ADAT", 0 ) != string::npos) { 
     335                    s.type=eCT_ADAT; // this assumes the name will tell us 
     336                } else if(plugname.find( "SPDIF", 0 ) != string::npos) { 
     337                    s.type=eCT_SPDIF; // this assumes the name will tell us 
     338                } else { 
     339                    s.type=eCT_WordClock; // this assumes a whole lot more 
     340                } 
     341            } else { 
     342                s.type=eCT_Invalid; 
     343            } 
     344            break; 
     345        default: 
     346            s.type=eCT_Invalid; break; 
     347    } 
     348 
     349    // is it active? 
     350    const SyncInfo* active=getActiveSyncInfo(); 
     351    if (active) { 
     352        if ((active->m_source == si.m_source) 
     353           && (active->m_destination == si.m_destination)) 
     354           s.active=true; 
     355        else s.active=false; 
     356    } else s.active=false; 
     357 
     358    return s; 
     359} 
     360 
    212361bool 
    213362AvDevice::lock() { 
  • trunk/libffado/src/genericavc/avc_avdevice.h

    r630 r639  
    6565    virtual int getSamplingFrequency( ); 
    6666 
     67    virtual ClockSourceVector getSupportedClockSources(); 
     68    virtual bool setActiveClockSource(ClockSource); 
     69    virtual ClockSource getActiveClockSource(); 
     70 
    6771    virtual int getStreamCount(); 
    6872    virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i); 
     
    96100 
    97101    DECLARE_DEBUG_MODULE; 
     102 
     103private: 
     104    ClockSource syncInfoToClockSource(const SyncInfo& si); 
    98105}; 
    99106 
  • trunk/libffado/src/metrichalo/mh_avdevice.cpp

    r584 r639  
    125125} 
    126126 
     127FFADODevice::ClockSourceVector 
     128MHAvDevice::getSupportedClockSources() { 
     129    FFADODevice::ClockSourceVector r; 
     130    return r; 
     131} 
     132 
     133bool 
     134MHAvDevice::setActiveClockSource(ClockSource s) { 
     135    return false; 
     136} 
     137 
     138FFADODevice::ClockSource 
     139MHAvDevice::getActiveClockSource() { 
     140    ClockSource s; 
     141    return s; 
     142} 
     143 
     144 
    127145int 
    128146MHAvDevice::getConfigurationId( ) { 
  • trunk/libffado/src/metrichalo/mh_avdevice.h

    r583 r639  
    6262    virtual int getSamplingFrequency( ); 
    6363 
     64    virtual ClockSourceVector getSupportedClockSources(); 
     65    virtual bool setActiveClockSource(ClockSource); 
     66    virtual ClockSource getActiveClockSource(); 
     67 
    6468    virtual int getStreamCount(); 
    6569    virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i); 
  • trunk/libffado/src/motu/motu_avdevice.cpp

    r587 r639  
    304304} 
    305305 
     306FFADODevice::ClockSourceVector 
     307MotuDevice::getSupportedClockSources() { 
     308    FFADODevice::ClockSourceVector r; 
     309    return r; 
     310} 
     311 
     312bool 
     313MotuDevice::setActiveClockSource(ClockSource s) { 
     314    return false; 
     315} 
     316 
     317FFADODevice::ClockSource 
     318MotuDevice::getActiveClockSource() { 
     319    ClockSource s; 
     320    return s; 
     321} 
     322 
    306323bool 
    307324MotuDevice::lock() { 
  • trunk/libffado/src/motu/motu_avdevice.h

    r583 r639  
    109109    virtual int getSamplingFrequency( ); 
    110110 
     111    virtual ClockSourceVector getSupportedClockSources(); 
     112    virtual bool setActiveClockSource(ClockSource); 
     113    virtual ClockSource getActiveClockSource(); 
     114 
    111115    virtual int getStreamCount(); 
    112116    virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i); 
  • trunk/libffado/src/rme/rme_avdevice.cpp

    r587 r639  
    144144} 
    145145 
     146FFADODevice::ClockSourceVector 
     147RmeDevice::getSupportedClockSources() { 
     148    FFADODevice::ClockSourceVector r; 
     149    return r; 
     150} 
     151 
     152bool 
     153RmeDevice::setActiveClockSource(ClockSource s) { 
     154    return false; 
     155} 
     156 
     157FFADODevice::ClockSource 
     158RmeDevice::getActiveClockSource() { 
     159    ClockSource s; 
     160    return s; 
     161} 
     162 
    146163bool 
    147164RmeDevice::lock() { 
  • trunk/libffado/src/rme/rme_avdevice.h

    r583 r639  
    6464    virtual int getSamplingFrequency( ); 
    6565 
     66    virtual ClockSourceVector getSupportedClockSources(); 
     67    virtual bool setActiveClockSource(ClockSource); 
     68    virtual ClockSource getActiveClockSource(); 
     69 
    6670    virtual int getStreamCount(); 
    6771    virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i); 
  • trunk/libffado/src/SConscript

    r629 r639  
    108108        fireworks/efc/efc_cmd.cpp \ 
    109109        fireworks/efc/efc_cmds_hardware.cpp \ 
     110        fireworks/efc/efc_cmds_hardware_ctrl.cpp \ 
    110111        fireworks/audiofire/audiofire_device.cpp \ 
    111112' ) 
  • trunk/libffado/tests/test-ffado.cpp

    r585 r639  
    9797                    "OPERATION: Discover\n" 
    9898                    "           SetSamplerate samplerate\n" 
     99                    "           SetClockSource [id]\n" 
    99100                    "           ListOscSpace\n" 
    100101                    "           OscServer\n" 
     
    316317                } 
    317318            } 
     319        } 
     320        delete m_deviceManager; 
     321        return exitfunction(0); 
     322    } else if ( strcmp( arguments.args[0], "SetClockSource" ) == 0 ) { 
     323        char* tail; 
     324        unsigned int targetid = (unsigned int)strtol( arguments.args[1], &tail, 0 ); 
     325        if ( errno ) { 
     326            fprintf( stderr,  "Could not parse clock source argument\n" ); 
     327            targetid=0xFFFF; 
     328        } 
     329        DeviceManager *m_deviceManager = new DeviceManager(); 
     330        if ( !m_deviceManager ) { 
     331            fprintf( stderr, "Could not allocate device manager\n" ); 
     332            return exitfunction(-1); 
     333        } 
     334        if ( arguments.verbose ) { 
     335            m_deviceManager->setVerboseLevel(arguments.verbose); 
     336        } 
     337        if ( !m_deviceManager->initialize( arguments.port ) ) { 
     338            fprintf( stderr, "Could not initialize device manager\n" ); 
     339            delete m_deviceManager; 
     340            return exitfunction(-1); 
     341        } 
     342        if ( arguments.verbose ) { 
     343            m_deviceManager->setVerboseLevel(arguments.verbose); 
     344        } 
     345        if ( !m_deviceManager->discover() ) { 
     346            fprintf( stderr, "Could not discover devices\n" ); 
     347            delete m_deviceManager; 
     348            return exitfunction(-1); 
     349        } 
     350 
     351        if(arguments.node_id_set) { 
     352            FFADODevice* avDevice = m_deviceManager->getAvDevice( arguments.node_id ); 
     353            if ( avDevice ) { 
     354                FFADODevice::ClockSource s; 
     355             
     356                avDevice->setVerboseLevel(arguments.verbose); 
     357                FFADODevice::ClockSourceVector sources=avDevice->getSupportedClockSources(); 
     358                for ( FFADODevice::ClockSourceVector::const_iterator it 
     359                        = sources.begin(); 
     360                    it != sources.end(); 
     361                    ++it ) 
     362                { 
     363                    FFADODevice::ClockSource c=*it; 
     364                    printf( " Type: %s, Id: %d, Valid: %d, Active: %d, Description: %s\n", 
     365                        FFADODevice::ClockSourceTypeToString(c.type), c.id, c.valid, c.active, c.description.c_str()); 
     366                     
     367                    if (c.id==targetid) { 
     368                        s=*it; 
     369                    } 
     370                } 
     371                 
     372                if (s.type != FFADODevice::eCT_Invalid) { 
     373                    printf("  set clock source to %d\n", s.id); 
     374                    if ( ! avDevice->setActiveClockSource( s ) ) { 
     375                        fprintf( stderr, "Could not set clock source\n" ); 
     376                    } 
     377                } else { 
     378                    printf("  no clock source with id %d found\n", targetid); 
     379                } 
     380            } 
     381        } else { 
     382            fprintf( stderr, "please specify a node\n" ); 
    318383        } 
    319384        delete m_deviceManager;