Changeset 1336

Show
Ignore:
Timestamp:
09/23/08 03:42:04 (12 years ago)
Author:
ppalmers
Message:

Bring trunk up to date with branches/libffado-2.0:

"""
svn merge -r 1254:1299 svn+ssh://ffadosvn@ffado.org/ffado/branches/libffado-2.0
svn merge -r 1301:1320 svn+ssh://ffadosvn@ffado.org/ffado/branches/libffado-2.0
svn merge -r 1322:1323 svn+ssh://ffadosvn@ffado.org/ffado/branches/libffado-2.0
svn merge -r 1329:HEAD svn+ssh://ffadosvn@ffado.org/ffado/branches/libffado-2.0
"""

Add getSupportedSamplingFrequencies() to DICE, RME and Metric Halo AvDevices?

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/config.h.in

    r1254 r1336  
    66#define LIBDIR "$LIBDIR" 
    77#define SHAREDIR "$SHAREDIR" 
     8 
     9/* configuration file locations */ 
     10#define USER_CONFIG_FILE    "$USER_CONFIG_FILE" 
     11#define SYSTEM_CONFIG_FILE  "$SYSTEM_CONFIG_FILE" 
    812 
    913/* Define indicating availability of lrint() */ 
     
    129133// packets early if we want to. (not completely according to spec) 
    130134// (for spec compliance you need to specify a value of 0) 
    131 #define AMDTP_MAX_CYCLES_TO_TRANSMIT_EARLY                  0 
     135#define AMDTP_MAX_CYCLES_TO_TRANSMIT_EARLY                  1 
    132136 
    133137// ensure that the AMDTP SP clips all float values to [-1.0..1.0] 
  • trunk/libffado/external/SConscript

    r1185 r1336  
    2626env = env.Clone() 
    2727 
    28 env.SConscript( dirs="dbus", exports="env" ) 
     28env.SConscript( dirs=["dbus", "libconfig"], exports="env" ) 
    2929 
  • trunk/libffado/README

    r1239 r1336  
    4242* Focusrite Saffire PRO10 
    4343* Focusrite Saffire PRO26 
    44 * ECHO AudioFire2 
    45 * ECHO AudioFire4 
     44* ECHO AudioFire2, AudioFire4, AudioFire8, AudioFire12 
    4645* Mackie Onyx Mixer FireWire expansion 
    4746 
     
    7170* Presonus FireBox 
    7271* Presonus FirePod / FP10 
    73 * Focusrite Saffire LE 
    74 * ECHO AudioFire8 
    75 * ECHO AudioFire12 
     72* Alesis io14 
     73* TC Konnekt 8, Konnekt 24D, Konnekt Live 
    7674 
    7775Usupported devices: 
    7876* Presonus FireStation 
    7977* Presonus FireStudio (all variants) 
    80 * TC Konnekt (all variants) 
    81 * Alesis devices 
     78* Other TC Konnekt devices 
     79* Other Alesis devices 
    8280* Metric Halo devices 
    8381* RME Firewire devices 
     
    105103 
    106104jackd (>= 0.109.12), http://jackaudio.org 
     105[NOTE: at the time of writing, this is the development (SVN) version.] 
    107106 
    108107Optionally, but recommended is that you install qjackctl: 
  • trunk/libffado/SConstruct

    r1258 r1336  
    102102                buildenv[var]='' 
    103103 
    104 env = Environment( tools=['default','scanreplace','pyuic','dbus','doxygen','pkgconfig'], toolpath=['admin'], ENV = buildenv, options=opts ) 
     104env = Environment( tools=['default','scanreplace','pyuic','pyuic4','dbus','doxygen','pkgconfig'], toolpath=['admin'], ENV = buildenv, options=opts ) 
    105105 
    106106if os.environ.has_key('CC'): 
     
    108108if os.environ.has_key('CXX'): 
    109109        env['CXX'] = os.environ['CXX'] 
     110 
     111# grab OS CFLAGS / CCFLAGS 
     112env['OS_CFLAGS']=[] 
     113if os.environ.has_key('CFLAGS'): 
     114        env['OS_CFLAGS'] = os.environ['CFLAGS'] 
     115env['OS_CCFLAGS']=[] 
     116if os.environ.has_key('CCFLAGS'): 
     117        env['OS_CCFLAGS'] = os.environ['CCFLAGS'] 
    110118 
    111119Help( """ 
     
    185193tests.update( env['PKGCONFIG_TESTS'] ) 
    186194tests.update( env['PYUIC_TESTS'] ) 
     195tests.update( env['PYUIC4_TESTS'] ) 
    187196 
    188197conf = Configure( env, 
     
    283292 
    284293        # PyQT checks 
     294        build_mixer = False 
    285295        if conf.CheckForApp( "which pyuic" ) and conf.CheckForPyModule( 'dbus' ) and conf.CheckForPyModule( 'qt' ): 
    286296                env['PYUIC'] = True 
     297                build_mixer = True 
     298         
     299                if conf.CheckForApp( "xdg-desktop-menu --help" ): 
     300                        env['XDG_TOOLS'] = True 
     301                else: 
     302                        print """ 
     303        I couldn't find the program 'xdg-desktop-menu'. Together with xdg-icon-resource 
     304        this is needed to add the fancy entry to your menu. But the mixer will be installed, you can start it by executing "ffadomixer". 
     305        """ 
     306        elif conf.CheckForApp( "which pyuic4" ) and conf.CheckForPyModule( 'dbus' ) and conf.CheckForPyModule( 'PyQt4' ): 
     307                env['PYUIC4'] = True 
     308                build_mixer = True 
    287309         
    288310                if conf.CheckForApp( "xdg-desktop-menu --help" ): 
     
    294316        """ 
    295317         
    296         else
     318        if not build_mixer
    297319                print """ 
    298         I couldn't find all the prerequisites ('pyuic' and the python-modules 'dbus' and 
     320        I couldn't find all the prerequisites ('pyuic' / 'pyuic4' and the python-modules 'dbus' and 
    299321        'qt', the packages could be named like dbus-python and PyQt) to build the mixer. 
    300322        Therefor the mixer won't get installed. 
     
    398420config_os = 3 
    399421config = config_guess.split ("-") 
     422 
     423needs_fPIC = False 
    400424 
    401425# Autodetect 
     
    481505 
    482506    # build for 64-bit userland? 
    483     if env['DIST_TARGET'] == "powerpc64" or env['DIST_TARGET'] == "x86_64"
    484         print "Doing a 64-bit build" 
     507    if env['DIST_TARGET'] == "powerpc64"
     508        print "Doing a 64-bit PowerPC build" 
    485509        env.AppendUnique( CCFLAGS=["-m64"] ) 
    486510        env.AppendUnique( CFLAGS=["-m64"] ) 
     511    elif env['DIST_TARGET'] == "x86_64": 
     512        print "Doing a 64-bit x86 build" 
     513        env.AppendUnique( CCFLAGS=["-m64"] ) 
     514        env.AppendUnique( CFLAGS=["-m64"] ) 
     515        needs_fPIC = True 
    487516    else: 
    488517        print "Doing a 32-bit build" 
    489518        env.AppendUnique( CCFLAGS=["-m32"] ) 
    490519        env.AppendUnique( CFLAGS=["-m32"] ) 
     520 
     521if needs_fPIC or '-fPIC' in env['OS_CFLAGS']: 
     522    env.AppendUnique( CFLAGS=["-fPIC"] ) 
     523if needs_fPIC or '-fPIC' in env['OS_CCFLAGS']: 
     524    env.AppendUnique( CCFLAGS=["-fPIC"] ) 
    491525 
    492526# end of processor-specific section 
     
    502536env['REVISION'] = env['REVISION'].split(':')[-1] 
    503537 
    504 if env['REVISION'] == 'exported': 
     538# try to circumvent localized versions 
     539if len(env['REVISION']) >= 5 and env['REVISION'][0:6] == 'export': 
    505540        env['REVISION'] = '' 
    506541 
     
    513548env['CONFIGDIR'] = "~/.ffado" 
    514549env['CACHEDIR'] = "~/.ffado" 
     550 
     551env['USER_CONFIG_FILE'] = env['CONFIGDIR'] + "/configuration" 
     552env['SYSTEM_CONFIG_FILE'] = env['sharedir'] + "/configuration" 
    515553 
    516554env['REGISTRATION_URL'] = "http://ffado.org/deviceregistration/register.php?action=register" 
     
    540578pkgconfig = env.ScanReplace( "libffado.pc.in" ) 
    541579env.Install( env['libdir'] + '/pkgconfig', pkgconfig ) 
     580 
     581env.Install( env['SYSTEM_CONFIG_FILE'], 'configuration' ) 
    542582 
    543583subdirs=['external','src','libffado','tests','support','doc'] 
     
    600640env.Command( "TAGS", "", findcommand + " |xargs etags" ) 
    601641env.AlwaysBuild( "tags", "TAGS" ) 
    602 env.NoCache( "tags", "TAGS" ) 
    603  
     642if 'NoCache' in dir(env): 
     643    env.NoCache( "tags", "TAGS" ) 
     644 
  • trunk/libffado/src/bebob/bebob_avdevice.cpp

    r1324 r1336  
    2424#include "config.h" 
    2525 
     26#include "devicemanager.h" 
    2627#include "bebob/bebob_avdevice.h" 
    2728#include "bebob/bebob_avdevice_subunit.h" 
     
    3940#include "libieee1394/ieee1394service.h" 
    4041 
    41 #include "genericavc/avc_vendormodel.h" 
    42  
    4342#include "libavc/general/avc_plug_info.h" 
    4443#include "libavc/general/avc_extended_plug_info.h" 
     
    8281 
    8382bool 
    84 AvDevice::probe( ConfigRom& configRom, bool generic ) 
     83AvDevice::probe( Util::Configuration& c, ConfigRom& configRom, bool generic ) 
    8584{ 
    8685    if(generic) { 
     
    118117        unsigned int modelId = configRom.getModelId(); 
    119118 
    120         GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_bebob.txt" ); 
    121         if ( vendorModel.parse() ) { 
    122             return vendorModel.isPresent( vendorId, modelId ); 
    123         } 
    124         return false; 
     119        Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId ); 
     120        return c.isValid(vme) && vme.driver == Util::Configuration::eD_BeBoB; 
    125121    } 
    126122} 
     
    174170} 
    175171 
     172#define BEBOB_CHECK_AND_ADD_SR(v, x) \ 
     173    { if(supportsSamplingFrequency(x)) \ 
     174      v.push_back(x); } 
    176175bool 
    177176AvDevice::discover() 
     
    180179    unsigned int modelId = getConfigRom().getModelId(); 
    181180 
    182     GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_bebob.txt" ); 
    183     if ( vendorModel.parse() ) { 
    184         m_model = vendorModel.find( vendorId, modelId ); 
    185     } 
    186  
    187     if (GenericAVC::VendorModel::isValid(m_model)) { 
     181    Util::Configuration &c = getDeviceManager().getConfiguration(); 
     182    Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId ); 
     183 
     184    if (c.isValid(vme) && vme.driver == Util::Configuration::eD_BeBoB) { 
    188185        debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", 
    189                      m_model.vendor_name.c_str(), 
    190                      m_model.model_name.c_str()); 
     186                     vme.vendor_name.c_str(), 
     187                     vme.model_name.c_str()); 
    191188    } else { 
    192         debugWarning("Using generic BeBoB support for unsupported device '%s %s'\n",  
     189        debugWarning("Using generic BeBoB support for unsupported device '%s %s'\n", 
    193190                     getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str()); 
    194191    } 
     
    452449    return true; 
    453450} 
    454  
    455451 
    456452uint8_t 
  • trunk/libffado/src/bebob/bebob_avdevice.h

    r1324 r1336  
    6464    virtual ~AvDevice(); 
    6565 
    66     static bool probe( ConfigRom& configRom, bool generic = false ); 
     66    static bool probe( Util::Configuration&, ConfigRom& configRom, bool generic = false ); 
    6767    virtual bool loadFromCache(); 
    6868    virtual bool saveCache(); 
     
    113113    virtual uint16_t getConfigurationIdSyncMode(); 
    114114 
     115    std::vector<int> m_supported_frequencies; 
    115116protected: 
    116117    Mixer*             m_Mixer; 
  • trunk/libffado/src/bebob/bebob_dl_mgr.cpp

    r1234 r1336  
    160160        } 
    161161        sleep( 1 ); 
     162        printf("."); 
     163        fflush(stdout); 
    162164    } 
    163165 
     
    387389    // bootloader erases the flash, have to wait until is ready 
    388390    // to answer our next request 
    389     printf( "wait until flash ereasing has terminated\n" ); 
    390     sleep( 30 ); 
     391    printf( "wait until flash erasing has terminated\n" ); 
     392    int cnt = 30; 
     393    while(cnt--) { 
     394        sleep( 1 ); 
     395        printf("."); 
     396        fflush(stdout); 
     397    } 
     398    printf("\n"); 
    391399 
    392400    if ( !readResponse( ccDStart ) ) { 
     
    462470        downloadedBytes += blockSize; 
    463471        if ( ( i % 100 ) == 0 ) { 
    464            printf( "%10d/%d bytes downloaded\n", 
     472           printf( "%10d/%d bytes downloaded\r", 
    465473                   downloadedBytes, totalBytes ); 
     474           fflush(stdout); 
    466475        } 
    467476 
     
    487496 
    488497    printf( "wait for transaction completion\n" ); 
    489     sleep( 10 ); 
     498    cnt = 10; 
     499    while(cnt--) { 
     500        sleep( 1 ); 
     501        printf("."); 
     502        fflush(stdout); 
     503    } 
     504    printf("\n"); 
    490505 
    491506    if ( !readResponse( ccEnd ) ) { 
     
    545560BeBoB::BootloaderManager::waitForBusReset() 
    546561{ 
    547     pthread_cond_wait( &m_cond, &m_mutex ); 
     562    struct timespec timeout; 
     563    int retcode; 
     564    clock_gettime(CLOCK_REALTIME, &timeout); 
     565    do { 
     566        printf("."); 
     567        fflush(stdout); 
     568        timeout.tv_sec = timeout.tv_sec + 1; 
     569        retcode = pthread_cond_timedwait( &m_cond, &m_mutex, &timeout ); 
     570    } while (retcode == ETIMEDOUT); 
    548571} 
    549572 
     
    642665    // there is no way to find out when it has finished 
    643666    sleep( 10 ); 
     667    int cnt = 10; 
     668    while(cnt--) { 
     669        sleep( 1 ); 
     670        printf("."); 
     671        fflush(stdout); 
     672    } 
     673    printf("\n"); 
    644674 
    645675    return true; 
     
    697727 
    698728    sleep( 5 ); 
     729    int cnt = 5; 
     730    while(cnt--) { 
     731        sleep( 1 ); 
     732        printf("."); 
     733        fflush(stdout); 
     734    } 
     735    printf("\n"); 
    699736 
    700737    return true; 
  • trunk/libffado/src/bebob/focusrite/focusrite_generic.cpp

    r1184 r1336  
    5656FocusriteDevice::setSpecificValue(uint32_t id, uint32_t v) 
    5757{ 
    58     bool use_avc=false; 
     58    debugOutput(DEBUG_LEVEL_VERBOSE, "Writing parameter address space id 0x%08lX (%u), data: 0x%08lX\n", 
     59        id, id, v); 
     60    bool use_avc = false; 
    5961    if(!getOption("useAvcForParameters", use_avc)) { 
    6062        debugWarning("Could not retrieve useAvcForParameters parameter, defauling to false\n"); 
     
    7072FocusriteDevice::getSpecificValue(uint32_t id, uint32_t *v) 
    7173{ 
    72     bool use_avc=false; 
     74    bool retval; 
     75    bool use_avc = false; 
    7376    if(!getOption("useAvcForParameters", use_avc)) { 
    7477        debugWarning("Could not retrieve useAvcForParameters parameter, defauling to false\n"); 
    7578    } 
    7679    if (use_avc) { 
    77         return getSpecificValueAvc(id, v); 
    78     } else { 
    79         return getSpecificValueARM(id, v); 
    80     } 
     80        retval = getSpecificValueAvc(id, v); 
     81    } else { 
     82        retval = getSpecificValueARM(id, v); 
     83    } 
     84    debugOutput(DEBUG_LEVEL_VERBOSE,"Read parameter address space id 0x%08lX (%u): %08lX\n", id, id, *v); 
     85    return retval; 
    8186} 
    8287 
     
    308313} 
    309314 
     315MeteringControl::MeteringControl(FocusriteDevice& parent, int id) 
     316: Control::Discrete(&parent) 
     317, m_Parent(parent) 
     318, m_cmd_id ( id ) 
     319{} 
     320MeteringControl::MeteringControl(FocusriteDevice& parent, int id, 
     321                std::string name, std::string label, std::string descr) 
     322: Control::Discrete(&parent) 
     323, m_Parent(parent) 
     324, m_cmd_id ( id ) 
     325{ 
     326    setName(name); 
     327    setLabel(label); 
     328    setDescription(descr); 
     329} 
     330 
     331int 
     332MeteringControl::getValue() 
     333{ 
     334    uint32_t val=0; 
     335 
     336    if ( !m_Parent.getSpecificValue(m_cmd_id, &val) ) { 
     337        debugError( "getSpecificValue failed\n" ); 
     338        return 0; 
     339    } else { 
     340        debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for %d = %d\n",  
     341                                         m_cmd_id, val); 
     342        return val; 
     343    } 
     344} 
     345 
    310346// reg control 
    311347RegisterControl::RegisterControl(FocusriteDevice& parent) 
     
    412448} 
    413449 
     450// hardware dial control 
     451DialPositionControl::DialPositionControl(FocusriteDevice& parent, int id) 
     452: Control::Discrete(&parent) 
     453, m_Parent(parent) 
     454, m_cmd_id ( id ) 
     455{} 
     456DialPositionControl::DialPositionControl(FocusriteDevice& parent, int id, 
     457                std::string name, std::string label, std::string descr) 
     458: Control::Discrete(&parent) 
     459, m_Parent(parent) 
     460, m_cmd_id ( id ) 
     461{ 
     462    setName(name); 
     463    setLabel(label); 
     464    setDescription(descr); 
     465} 
     466 
     467int 
     468DialPositionControl::getValue() 
     469{ 
     470    uint32_t val=0; 
     471 
     472    if ( !m_Parent.getSpecificValue(m_cmd_id, &val) ) { 
     473        debugError( "getSpecificValue failed\n" ); 
     474        return 0; 
     475    } else { 
     476        val = val >> 5; 
     477        debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for %d = %d\n",  
     478                                         m_cmd_id, val); 
     479        return val; 
     480    } 
     481} 
    414482 
    415483// Saffire pro matrix mixer element 
  • trunk/libffado/src/bebob/focusrite/focusrite_generic.h

    r1158 r1336  
    4646    BinaryControl(FocusriteDevice& parent, int id, int bit, 
    4747                  std::string name, std::string label, std::string descr); 
    48      
     48 
    4949    virtual bool setValue(int v); 
    5050    virtual int getValue(); 
     
    8181    virtual int getMaximum() {return 0x07FFF;}; 
    8282 
     83private: 
     84    FocusriteDevice&        m_Parent; 
     85    unsigned int            m_cmd_id; 
     86}; 
     87 
     88class MeteringControl 
     89    : public Control::Discrete 
     90{ 
     91public: 
     92    MeteringControl(FocusriteDevice& parent, int id); 
     93    MeteringControl(FocusriteDevice& parent, int id, 
     94                  std::string name, std::string label, std::string descr); 
     95     
     96    virtual bool setValue(int v) {return false;}; 
     97    virtual int getValue(); 
     98    virtual bool setValue(int idx, int v) 
     99        {return setValue(v);}; 
     100    virtual int getValue(int idx) 
     101        {return getValue();}; 
     102 
     103    virtual int getMinimum() {return 0;}; 
     104    virtual int getMaximum() {return 0x07FFF;}; 
    83105private: 
    84106    FocusriteDevice&        m_Parent; 
     
    122144    unsigned int            m_cmd_id; 
    123145    unsigned int            m_bit_shift; 
     146}; 
     147 
     148class DialPositionControl 
     149    : public Control::Discrete 
     150{ 
     151public: 
     152    DialPositionControl(FocusriteDevice& parent, int id); 
     153    DialPositionControl(FocusriteDevice& parent, int id, 
     154                        std::string name, std::string label, std::string descr); 
     155     
     156    virtual bool setValue(int v) {return false;}; 
     157    virtual int getValue(); 
     158    virtual bool setValue(int idx, int v) 
     159        {return setValue(v);}; 
     160    virtual int getValue(int idx) 
     161        {return getValue();}; 
     162 
     163    virtual int getMinimum() {return 0;}; 
     164    virtual int getMaximum() {return 0x07FFF;}; 
     165private: 
     166    FocusriteDevice&        m_Parent; 
     167    unsigned int            m_cmd_id; 
    124168}; 
    125169 
  • trunk/libffado/src/bebob/focusrite/focusrite_saffire.cpp

    r1181 r1336  
    146146        result &= m_MixerContainer->addElement( 
    147147            new BinaryControl(*this,  
    148                     FR_SAFFIRE_CMD_ID_SPDIF_SWITCH, 0, 
     148                    FR_SAFFIRE_CMD_ID_INPUT_SOURCE, 0, 
    149149                    "SpdifSwitch", "S/PDIF Switch", "S/PDIF Switch")); 
     150        result &= m_MixerContainer->addElement( 
     151            new BinaryControl(*this,  
     152                    FR_SAFFIRE_CMD_ID_MONO_MODE, 0, 
     153                    "MonoMode", "Mono Mode", "Toggle Mono Mode")); 
     154        result &= m_MixerContainer->addElement( 
     155            new BinaryControl(*this,  
     156                    FR_SAFFIRE_CMD_ID_DEVICE_MODE, 0, 
     157                    "DeviceMode", "Device Mode", "Toggle Device Mode")); 
     158        result &= m_MixerContainer->addElement( 
     159            new BinaryControl(*this,  
     160                    FR_SAFFIRE_CMD_ID_EXTERNAL_LOCK, 0, 
     161                    "ExternalLock", "External Lock", "Has external lock?")); 
     162        result &= m_MixerContainer->addElement( 
     163            new BinaryControl(*this,  
     164                    FR_SAFFIRE_CMD_ID_AUDIO_ON_STATUS, 0, 
     165                    "AudioOnStatus", "Audio On Status", "Audio On Status")); 
     166        result &= m_MixerContainer->addElement( 
     167            new BinaryControl(*this,  
     168                    FR_SAFFIRE_CMD_ID_SAVE_SETTINGS, 0, 
     169                    "SaveSettings", "Save Settings", "Save Settings")); 
    150170 
    151171        // output mute controls 
     
    230250                    FR_SAFFIRE_CMD_ID_BITFIELD_OUT78, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DAC, 
    231251                    "Out78Level", "Out7/8 Level", "Output 7/8 Level")); 
     252 
     253        result &= m_MixerContainer->addElement( 
     254            new DialPositionControl(*this,  
     255                    FR_SAFFIRE_CMD_ID_MONITOR_DIAL, 
     256                    "MonitorDial", "Monitor Dial", "Monitor Dial Value")); 
     257 
     258        // metering 
     259        result &= m_MixerContainer->addElement( 
     260            new MeteringControl(*this,  
     261                    FR_SAFFIRE_CMD_ID_METERING_IN1, 
     262                    "MeteringIn1", "Metering Input 1", "Metering on Input 1")); 
     263        result &= m_MixerContainer->addElement( 
     264            new MeteringControl(*this,  
     265                    FR_SAFFIRE_CMD_ID_METERING_IN2, 
     266                    "MeteringIn2", "Metering Input 2", "Metering on Input 2")); 
     267        result &= m_MixerContainer->addElement( 
     268            new MeteringControl(*this,  
     269                    FR_SAFFIRE_CMD_ID_METERING_IN3, 
     270                    "MeteringIn3", "Metering Input 3", "Metering on Input 3")); 
     271        result &= m_MixerContainer->addElement( 
     272            new MeteringControl(*this,  
     273                    FR_SAFFIRE_CMD_ID_METERING_IN4, 
     274                    "MeteringIn4", "Metering Input 4", "Metering on Input 4")); 
     275 
     276        result &= m_MixerContainer->addElement( 
     277            new MeteringControl(*this,  
     278                    FR_SAFFIRE_CMD_ID_METERING_PC1, 
     279                    "MeteringPc1", "Metering PC 1", "Metering on PC Channel 1")); 
     280        result &= m_MixerContainer->addElement( 
     281            new MeteringControl(*this,  
     282                    FR_SAFFIRE_CMD_ID_METERING_PC2, 
     283                    "MeteringPc2", "Metering PC 2", "Metering on PC Channel 2")); 
     284        result &= m_MixerContainer->addElement( 
     285            new MeteringControl(*this,  
     286                    FR_SAFFIRE_CMD_ID_METERING_PC3, 
     287                    "MeteringPc3", "Metering PC 3", "Metering on PC Channel 3")); 
     288        result &= m_MixerContainer->addElement( 
     289            new MeteringControl(*this,  
     290                    FR_SAFFIRE_CMD_ID_METERING_PC4, 
     291                    "MeteringPc4", "Metering PC 4", "Metering on PC Channel 4")); 
     292        result &= m_MixerContainer->addElement( 
     293            new MeteringControl(*this,  
     294                    FR_SAFFIRE_CMD_ID_METERING_PC5, 
     295                    "MeteringPc5", "Metering PC 5", "Metering on PC Channel 5")); 
     296        result &= m_MixerContainer->addElement( 
     297            new MeteringControl(*this,  
     298                    FR_SAFFIRE_CMD_ID_METERING_PC6, 
     299                    "MeteringPc6", "Metering PC 6", "Metering on PC Channel 6")); 
     300        result &= m_MixerContainer->addElement( 
     301            new MeteringControl(*this,  
     302                    FR_SAFFIRE_CMD_ID_METERING_PC7, 
     303                    "MeteringPc7", "Metering PC 7", "Metering on PC Channel 7")); 
     304        result &= m_MixerContainer->addElement( 
     305            new MeteringControl(*this,  
     306                    FR_SAFFIRE_CMD_ID_METERING_PC8, 
     307                    "MeteringPc8", "Metering PC 8", "Metering on PC Channel 8")); 
     308        result &= m_MixerContainer->addElement( 
     309            new MeteringControl(*this,  
     310                    FR_SAFFIRE_CMD_ID_METERING_PC9, 
     311                    "MeteringPc9", "Metering PC 9", "Metering on PC Channel 9")); 
     312        result &= m_MixerContainer->addElement( 
     313            new MeteringControl(*this,  
     314                    FR_SAFFIRE_CMD_ID_METERING_PC10, 
     315                    "MeteringPc10", "Metering PC 10", "Metering on PC Channel 10")); 
     316 
    232317    } 
    233318     
     
    248333                    FR_SAFFIRELE_CMD_ID_SWAP_OUT4_OUT1_96K, 0, 
    249334                    "Swap41_96", "Swap41_96", "Swap41_96")); 
    250  
    251335    } else { 
    252336        result &= m_MixerContainer->addElement( 
    253             new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_InputMix, "InputMix")); 
    254      
    255         result &= m_MixerContainer->addElement( 
    256             new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_PCMix, "PCMix")); 
     337            new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_SaffireStereoMatrixMix, "MatrixMixerStereo")); 
     338        result &= m_MixerContainer->addElement( 
     339            new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_SaffireMonoMatrixMix, "MatrixMixerMono")); 
    257340    } 
    258341 
     
    342425void SaffireMatrixMixer::init() 
    343426{ 
    344     if (m_type==eMMT_PCMix) { 
     427    if (m_type==eMMT_SaffireStereoMatrixMix) { 
     428        m_RowInfo.clear(); 
     429        addSignalInfo(m_RowInfo, "PC910", "PC 9/10", "PC Channel 9/10"); 
    345430        addSignalInfo(m_RowInfo, "PC12", "PC 1/2", "PC Channel 1/2"); 
    346431        addSignalInfo(m_RowInfo, "PC34", "PC 3/4", "PC Channel 3/4"); 
    347432        addSignalInfo(m_RowInfo, "PC56", "PC 5/6", "PC Channel 5/6"); 
    348433        addSignalInfo(m_RowInfo, "PC78", "PC 7/8", "PC Channel 7/8"); 
    349         addSignalInfo(m_RowInfo, "PC910", "PC 9/10", "PC Channel 9/10"); 
    350          
     434        addSignalInfo(m_RowInfo, "IN12", "Input 1/2", "Hardware Inputs 1/2"); 
     435        addSignalInfo(m_RowInfo, "IN34", "Input 3/4", "Hardware Inputs 3/4 (dry / S/PDIF)"); 
     436        addSignalInfo(m_RowInfo, "FX", "Effect return", "Effect return"); 
     437 
     438        m_ColInfo.clear(); 
     439        addSignalInfo(m_ColInfo, "OUT910", "OUT 9/10", "Output 9/10"); 
    351440        addSignalInfo(m_ColInfo, "OUT12", "OUT 1/2", "Output 1/2"); 
    352441        addSignalInfo(m_ColInfo, "OUT34", "OUT 3/4", "Output 3/4"); 
    353         addSignalInfo(m_ColInfo, "OUT56", "OUT 5/6", "Output 5/6"); 
    354         addSignalInfo(m_ColInfo, "OUT78", "OUT 7/8", "Output 7/8"); 
    355         addSignalInfo(m_ColInfo, "OUT910", "OUT 9/10", "Output 9/10"); 
     442        addSignalInfo(m_ColInfo, "OUT56", "OUT 5/6", "Output 5/6 (HP1)"); 
     443        addSignalInfo(m_ColInfo, "OUT78", "OUT 7/8", "Output 7/8 (HP2)"); 
    356444         
    357445        // init the cell matrix 
    358         #define FOCUSRITE_SAFFIRE_PCMIX_NB_COLS 5 
    359         #define FOCUSRITE_SAFFIRE_PCMIX_NB_ROWS 5 
    360          
    361         std::vector<struct sCellInfo> tmp_cols( FOCUSRITE_SAFFIRE_PCMIX_NB_COLS ); 
    362         std::vector< std::vector<struct sCellInfo> > tmp_all(FOCUSRITE_SAFFIRE_PCMIX_NB_ROWS, tmp_cols); 
     446        #define FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_COLS 5 
     447        #define FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_ROWS 8 
     448        #define FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_OFFSET 0 
     449 
     450        std::vector<struct sCellInfo> tmp_cols( FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_COLS ); 
     451        std::vector< std::vector<struct sCellInfo> > tmp_all(FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_ROWS, tmp_cols); 
    363452        m_CellInfo = tmp_all; 
    364453     
     
    369458        c.address=0; 
    370459         
    371         for (int i=0;i<FOCUSRITE_SAFFIRE_PCMIX_NB_ROWS;i++) { 
    372             for (int j=0;j<FOCUSRITE_SAFFIRE_PCMIX_NB_COLS;j++) { 
    373                 m_CellInfo.at(i).at(j) = c; 
     460        // all cells are valid 
     461        for (int i=0; i < FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_ROWS; i++) { 
     462            for (int j=0; j < FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_COLS; j++) { 
     463                c.row = i; 
     464                c.col = j; 
     465                c.valid = true; 
     466                c.address = FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_OFFSET + c.row * FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_COLS + c.col; 
     467                m_CellInfo.at(i).at(j) =  c; 
    374468            } 
    375469        } 
    376      
    377         // now set the cells that are valid 
    378         setCellInfo(0,0,FR_SAFFIRE_CMD_ID_PC12_TO_OUT12, true); 
    379         setCellInfo(0,1,FR_SAFFIRE_CMD_ID_PC12_TO_OUT34, true); 
    380         setCellInfo(0,2,FR_SAFFIRE_CMD_ID_PC12_TO_OUT56, true); 
    381         setCellInfo(0,3,FR_SAFFIRE_CMD_ID_PC12_TO_OUT79, true); 
    382         setCellInfo(0,4,FR_SAFFIRE_CMD_ID_PC12_TO_OUT910, true); 
    383         setCellInfo(1,0,FR_SAFFIRE_CMD_ID_PC34_TO_OUT12, true); 
    384         setCellInfo(1,1,FR_SAFFIRE_CMD_ID_PC34_TO_OUT34, true); 
    385         setCellInfo(1,2,FR_SAFFIRE_CMD_ID_PC34_TO_OUT56, true); 
    386         setCellInfo(1,3,FR_SAFFIRE_CMD_ID_PC34_TO_OUT79, true); 
    387         setCellInfo(1,4,FR_SAFFIRE_CMD_ID_PC34_TO_OUT910, true); 
    388         setCellInfo(2,0,FR_SAFFIRE_CMD_ID_PC56_TO_OUT12, true); 
    389         setCellInfo(2,1,FR_SAFFIRE_CMD_ID_PC56_TO_OUT34, true); 
    390         setCellInfo(2,2,FR_SAFFIRE_CMD_ID_PC56_TO_OUT56, true); 
    391         setCellInfo(2,3,FR_SAFFIRE_CMD_ID_PC56_TO_OUT79, true); 
    392         setCellInfo(2,4,FR_SAFFIRE_CMD_ID_PC56_TO_OUT910, true); 
    393         setCellInfo(3,0,FR_SAFFIRE_CMD_ID_PC78_TO_OUT12, true); 
    394         setCellInfo(3,1,FR_SAFFIRE_CMD_ID_PC78_TO_OUT34, true); 
    395         setCellInfo(3,2,FR_SAFFIRE_CMD_ID_PC78_TO_OUT56, true); 
    396         setCellInfo(3,3,FR_SAFFIRE_CMD_ID_PC78_TO_OUT79, true); 
    397         setCellInfo(3,4,FR_SAFFIRE_CMD_ID_PC78_TO_OUT910, true); 
    398         setCellInfo(4,0,FR_SAFFIRE_CMD_ID_PC910_TO_OUT12, true); 
    399         setCellInfo(4,1,FR_SAFFIRE_CMD_ID_PC910_TO_OUT34, true); 
    400         setCellInfo(4,2,FR_SAFFIRE_CMD_ID_PC910_TO_OUT56, true); 
    401         setCellInfo(4,3,FR_SAFFIRE_CMD_ID_PC910_TO_OUT79, true); 
    402         setCellInfo(4,4,FR_SAFFIRE_CMD_ID_PC910_TO_OUT910, true); 
    403  
    404     } else if (m_type==eMMT_InputMix) { 
    405         addSignalInfo(m_RowInfo, "IN1", "Input 1", "Analog Input 1"); 
    406         addSignalInfo(m_RowInfo, "IN2", "Input 2", "Analog Input 2"); 
    407         addSignalInfo(m_RowInfo, "SPDIFL", "SPDIF L", "S/PDIF Left Input"); 
    408         addSignalInfo(m_RowInfo, "SPDIFR", "SPDIF R", "S/PDIF Right Input"); 
    409         addSignalInfo(m_RowInfo, "REV1", "REVERB 1", "Reverb CH1 return"); 
    410         addSignalInfo(m_RowInfo, "REV1", "REVERB 2", "Reverb CH2 return"); 
    411          
    412         addSignalInfo(m_ColInfo, "OUT1", "OUT 1", "Output 1"); 
    413         addSignalInfo(m_ColInfo, "OUT2", "OUT 2", "Output 2"); 
    414         addSignalInfo(m_ColInfo, "OUT3", "OUT 3", "Output 3"); 
    415         addSignalInfo(m_ColInfo, "OUT4", "OUT 4", "Output 4"); 
    416         addSignalInfo(m_ColInfo, "OUT5", "OUT 5", "Output 5"); 
    417         addSignalInfo(m_ColInfo, "OUT6", "OUT 6", "Output 6"); 
    418         addSignalInfo(m_ColInfo, "OUT7", "OUT 7", "Output 7"); 
    419         addSignalInfo(m_ColInfo, "OUT8", "OUT 8", "Output 8"); 
    420         addSignalInfo(m_ColInfo, "OUT9", "OUT 9", "Output 9"); 
    421         addSignalInfo(m_ColInfo, "OUT10", "OUT 10", "Output 10"); 
     470    } else if (m_type==eMMT_SaffireMonoMatrixMix) { 
     471        m_RowInfo.clear(); 
     472        addSignalInfo(m_RowInfo, "IN1", "Input 1", "Hardware Inputs 1"); 
     473        addSignalInfo(m_RowInfo, "IN3", "Input 3", "Hardware Inputs 3"); 
     474        addSignalInfo(m_RowInfo, "FX1", "Effect return 1", "Effect return 1"); 
     475        addSignalInfo(m_RowInfo, "IN2", "Input 2", "Hardware Inputs 2"); 
     476        addSignalInfo(m_RowInfo, "IN4", "Input 4", "Hardware Inputs 4"); 
     477        addSignalInfo(m_RowInfo, "FX2", "Effect return 2", "Effect return 2"); 
     478        addSignalInfo(m_RowInfo, "PC910", "PC 9/10", "PC Channel 9/10"); 
     479        addSignalInfo(m_RowInfo, "PC12", "PC 1/2", "PC Channel 1/2"); 
     480        addSignalInfo(m_RowInfo, "PC34", "PC 3/4", "PC Channel 3/4"); 
     481        addSignalInfo(m_RowInfo, "PC56", "PC 5/6", "PC Channel 5/6"); 
     482        addSignalInfo(m_RowInfo, "PC78", "PC 7/8", "PC Channel 7/8"); 
     483 
     484        m_ColInfo.clear(); 
     485        addSignalInfo(m_ColInfo, "OUT910", "OUT 9/10", "Output 9/10"); 
     486        addSignalInfo(m_ColInfo, "OUT12", "OUT 1/2", "Output 1/2"); 
     487        addSignalInfo(m_ColInfo, "OUT34", "OUT 3/4", "Output 3/4"); 
     488        addSignalInfo(m_ColInfo, "OUT56", "OUT 5/6", "Output 5/6 (HP1)"); 
     489        addSignalInfo(m_ColInfo, "OUT78", "OUT 7/8", "Output 7/8 (HP2)"); 
    422490         
    423491        // init the cell matrix 
    424         #define FOCUSRITE_SAFFIRE_INPUTMIX_NB_COLS 10 
    425         #define FOCUSRITE_SAFFIRE_INPUTMIX_NB_ROWS 6 
    426          
    427         std::vector<struct sCellInfo> tmp_cols( FOCUSRITE_SAFFIRE_INPUTMIX_NB_COLS ); 
    428         std::vector< std::vector<struct sCellInfo> > tmp_all(FOCUSRITE_SAFFIRE_INPUTMIX_NB_ROWS,tmp_cols); 
     492        #define FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_COLS 5 
     493        #define FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_ROWS 11 
     494        #define FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_OFFSET 0 
     495 
     496        std::vector<struct sCellInfo> tmp_cols( FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_COLS ); 
     497        std::vector< std::vector<struct sCellInfo> > tmp_all(FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_ROWS, tmp_cols); 
    429498        m_CellInfo = tmp_all; 
    430499     
     
    435504        c.address=0; 
    436505         
    437         for (int i=0;i<FOCUSRITE_SAFFIRE_INPUTMIX_NB_ROWS;i++) { 
    438             for (int j=0;j<FOCUSRITE_SAFFIRE_INPUTMIX_NB_COLS;j++) { 
    439                 m_CellInfo.at(i).at(j) = c; 
     506        // all cells are valid 
     507        for (int i=0; i < FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_ROWS; i++) { 
     508            for (int j=0; j < FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_COLS; j++) { 
     509                c.row = i; 
     510                c.col = j; 
     511                c.valid = true; 
     512                c.address = FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_OFFSET + c.row * FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_COLS + c.col; 
     513                m_CellInfo.at(i).at(j) =  c; 
    440514            } 
    441515        } 
    442  
    443         // now set the cells that are valid 
    444         setCellInfo(0,0,FR_SAFFIRE_CMD_ID_IN1_TO_OUT1, true); 
    445         setCellInfo(0,2,FR_SAFFIRE_CMD_ID_IN1_TO_OUT3, true); 
    446         setCellInfo(0,4,FR_SAFFIRE_CMD_ID_IN1_TO_OUT5, true); 
    447         setCellInfo(0,6,FR_SAFFIRE_CMD_ID_IN1_TO_OUT7, true); 
    448         setCellInfo(0,8,FR_SAFFIRE_CMD_ID_IN1_TO_OUT9, true); 
    449         setCellInfo(1,1,FR_SAFFIRE_CMD_ID_IN2_TO_OUT2, true); 
    450         setCellInfo(1,3,FR_SAFFIRE_CMD_ID_IN2_TO_OUT4, true); 
    451         setCellInfo(1,5,FR_SAFFIRE_CMD_ID_IN2_TO_OUT6, true); 
    452         setCellInfo(1,7,FR_SAFFIRE_CMD_ID_IN2_TO_OUT8, true); 
    453         setCellInfo(1,9,FR_SAFFIRE_CMD_ID_IN2_TO_OUT10, true); 
    454         setCellInfo(2,0,FR_SAFFIRE_CMD_ID_IN3_TO_OUT1, true); 
    455         setCellInfo(2,2,FR_SAFFIRE_CMD_ID_IN3_TO_OUT3, true); 
    456         setCellInfo(2,4,FR_SAFFIRE_CMD_ID_IN3_TO_OUT5, true); 
    457         setCellInfo(2,6,FR_SAFFIRE_CMD_ID_IN3_TO_OUT7, true); 
    458         setCellInfo(2,8,FR_SAFFIRE_CMD_ID_IN3_TO_OUT9, true); 
    459         setCellInfo(3,1,FR_SAFFIRE_CMD_ID_IN4_TO_OUT2, true); 
    460         setCellInfo(3,3,FR_SAFFIRE_CMD_ID_IN4_TO_OUT4, true); 
    461         setCellInfo(3,5,FR_SAFFIRE_CMD_ID_IN4_TO_OUT6, true); 
    462         setCellInfo(3,7,FR_SAFFIRE_CMD_ID_IN4_TO_OUT8, true); 
    463         setCellInfo(3,9,FR_SAFFIRE_CMD_ID_IN4_TO_OUT10, true); 
    464  
    465         setCellInfo(4,0,FR_SAFFIRE_CMD_ID_REV1_TO_OUT1, true); 
    466         setCellInfo(5,1,FR_SAFFIRE_CMD_ID_REV2_TO_OUT2, true); 
    467         setCellInfo(4,2,FR_SAFFIRE_CMD_ID_REV1_TO_OUT3, true); 
    468         setCellInfo(5,3,FR_SAFFIRE_CMD_ID_REV2_TO_OUT4, true); 
    469         setCellInfo(4,4,FR_SAFFIRE_CMD_ID_REV1_TO_OUT5, true); 
    470         setCellInfo(5,5,FR_SAFFIRE_CMD_ID_REV2_TO_OUT6, true); 
    471         setCellInfo(4,6,FR_SAFFIRE_CMD_ID_REV1_TO_OUT7, true); 
    472         setCellInfo(5,7,FR_SAFFIRE_CMD_ID_REV2_TO_OUT8, true); 
    473         setCellInfo(4,8,FR_SAFFIRE_CMD_ID_REV1_TO_OUT9, true); 
    474         setCellInfo(5,9,FR_SAFFIRE_CMD_ID_REV2_TO_OUT10, true); 
    475  
    476516    } else if (m_type == eMMT_LEMix48) { 
    477517        addSignalInfo(m_RowInfo, "IN1", "Input 1", "Analog Input 1"); 
  • trunk/libffado/src/bebob/focusrite/focusrite_saffire.h

    r1181 r1336  
    3333// -- Original Saffire -- 
    3434 
    35 // The ID's for the hardware input matrix mixer 
    36 #define FR_SAFFIRE_CMD_ID_IN1_TO_OUT1       1 
    37 #define FR_SAFFIRE_CMD_ID_IN1_TO_OUT3       2 
    38 #define FR_SAFFIRE_CMD_ID_IN1_TO_OUT5       3 
    39 #define FR_SAFFIRE_CMD_ID_IN1_TO_OUT7       4 
    40 #define FR_SAFFIRE_CMD_ID_IN1_TO_OUT9       0 
    41 #define FR_SAFFIRE_CMD_ID_IN2_TO_OUT2       16 
    42 #define FR_SAFFIRE_CMD_ID_IN2_TO_OUT4       17 
    43 #define FR_SAFFIRE_CMD_ID_IN2_TO_OUT6       18 
    44 #define FR_SAFFIRE_CMD_ID_IN2_TO_OUT8       19 
    45 #define FR_SAFFIRE_CMD_ID_IN2_TO_OUT10      15 
    46 #define FR_SAFFIRE_CMD_ID_IN3_TO_OUT1       6 
    47 #define FR_SAFFIRE_CMD_ID_IN3_TO_OUT3       7 
    48 #define FR_SAFFIRE_CMD_ID_IN3_TO_OUT5       8 
    49 #define FR_SAFFIRE_CMD_ID_IN3_TO_OUT7       9 
    50 #define FR_SAFFIRE_CMD_ID_IN3_TO_OUT9       5 
    51 #define FR_SAFFIRE_CMD_ID_IN4_TO_OUT2       21 
    52 #define FR_SAFFIRE_CMD_ID_IN4_TO_OUT4       22 
    53 #define FR_SAFFIRE_CMD_ID_IN4_TO_OUT6       23 
    54 #define FR_SAFFIRE_CMD_ID_IN4_TO_OUT8       24 
    55 #define FR_SAFFIRE_CMD_ID_IN4_TO_OUT10      20 
    56  
    57 // reverb return id's (part of hardware input mixer) 
    58 #define FR_SAFFIRE_CMD_ID_REV1_TO_OUT1       11 
    59 #define FR_SAFFIRE_CMD_ID_REV2_TO_OUT2       26 
    60 #define FR_SAFFIRE_CMD_ID_REV1_TO_OUT3       12 
    61 #define FR_SAFFIRE_CMD_ID_REV2_TO_OUT4       27 
    62 #define FR_SAFFIRE_CMD_ID_REV1_TO_OUT5       13 
    63 #define FR_SAFFIRE_CMD_ID_REV2_TO_OUT6       28 
    64 #define FR_SAFFIRE_CMD_ID_REV1_TO_OUT7       14 
    65 #define FR_SAFFIRE_CMD_ID_REV2_TO_OUT8       29 
    66 #define FR_SAFFIRE_CMD_ID_REV1_TO_OUT9       10 
    67 #define FR_SAFFIRE_CMD_ID_REV2_TO_OUT10      25 
    68  
    69 // The ID's for the playback matrix mixer 
    70 #define FR_SAFFIRE_CMD_ID_PC12_TO_OUT12     36 
    71 #define FR_SAFFIRE_CMD_ID_PC12_TO_OUT34     37 
    72 #define FR_SAFFIRE_CMD_ID_PC12_TO_OUT56     38 
    73 #define FR_SAFFIRE_CMD_ID_PC12_TO_OUT79     39 
    74 #define FR_SAFFIRE_CMD_ID_PC12_TO_OUT910    35 
    75 #define FR_SAFFIRE_CMD_ID_PC34_TO_OUT12     41 
    76 #define FR_SAFFIRE_CMD_ID_PC34_TO_OUT34     42 
    77 #define FR_SAFFIRE_CMD_ID_PC34_TO_OUT56     43 
    78 #define FR_SAFFIRE_CMD_ID_PC34_TO_OUT79     44 
    79 #define FR_SAFFIRE_CMD_ID_PC34_TO_OUT910    40 
    80 #define FR_SAFFIRE_CMD_ID_PC56_TO_OUT12     46 
    81 #define FR_SAFFIRE_CMD_ID_PC56_TO_OUT34     47 
    82 #define FR_SAFFIRE_CMD_ID_PC56_TO_OUT56     48 
    83 #define FR_SAFFIRE_CMD_ID_PC56_TO_OUT79     49 
    84 #define FR_SAFFIRE_CMD_ID_PC56_TO_OUT910    45 
    85 #define FR_SAFFIRE_CMD_ID_PC78_TO_OUT12     51 
    86 #define FR_SAFFIRE_CMD_ID_PC78_TO_OUT34     52 
    87 #define FR_SAFFIRE_CMD_ID_PC78_TO_OUT56     53 
    88 #define FR_SAFFIRE_CMD_ID_PC78_TO_OUT79     54 
    89 #define FR_SAFFIRE_CMD_ID_PC78_TO_OUT910    50 
    90 #define FR_SAFFIRE_CMD_ID_PC910_TO_OUT12    31 
    91 #define FR_SAFFIRE_CMD_ID_PC910_TO_OUT34    32 
    92 #define FR_SAFFIRE_CMD_ID_PC910_TO_OUT56    33 
    93 #define FR_SAFFIRE_CMD_ID_PC910_TO_OUT79    34 
    94 #define FR_SAFFIRE_CMD_ID_PC910_TO_OUT910   30 
     35// no need for control id's, we can directly compute the addresses of the matrix mixer 
     36/* 
     37 
     38MIXER LAYOUT (): 
     39 
     40OFFSET: 30 
     41 
     42   |-- Out9/10--| |-- Out1/2 --| |-- Out3/4 --| |-- Out5/6 --| |-- Out7/8 --| 
     43P5  0:    0/    0  1:  110/  110  2:    0/    0  3:    0/    0  4:    0/    0 
     44P1  5:    0/    0  6:32767/32767  7:    0/    0  8:    0/    0  9:    0/    0 
     45P2 10:    0/    0 11:    0/    0 12:32767/32767 13:    0/    0 14:    0/    0 
     46P3 15:    0/    0 16:    0/    0 17:    0/    0 18:32767/32767 19:    0/    0 
     47P4 20:    0/    0 21:    0/    0 22:    0/    0 23:    0/    0 24:32767/32767 
     48R1 25:    0/    0 26:    0/    0 27:    0/    0 28:    0/    0 29:    0/    0 
     49R2 30:    0/    0 31:    0/    0 32:    0/    0 33:    0/    0 34:    0/    0 
     50Fx 35:    0/    0 36:    0/    0 37:    0/    0 38:    0/    0 39:    0/    0 
     51 
     52P5: DAW ch 9/10 
     53P1: DAW ch 1/2 
     54P2: DAW ch 3/4 
     55P3: DAW ch 5/6 
     56P4: DAW ch 7/8 
     57R1: HW INPUT ch 1/2 / Reverb ch 1 
     58R2: HW INPUT ch 3/4 / Reverb ch 2 
     59Fx: reverb/fx return? / input mix 
     60 
     61*/ 
    9562 
    9663// the control ID's 
     
    10875 
    10976// other stuff 
    110 #define FR_SAFFIRE_CMD_ID_MONITOR_DIAL    61 
    111 #define FR_SAFFIRE_CMD_ID_SPDIF_SWITCH    62 
     77#define FR_SAFFIRE_CMD_ID_MONITOR_DIAL      61 
     78 
     79#define FR_SAFFIRE_CMD_ID_INPUT_SOURCE      62 
     80#define FR_SAFFIRE_CMD_ID_INPUT_SOURCE_SPDIF  1 
     81#define FR_SAFFIRE_CMD_ID_INPUT_SOURCE_ANALOG 0 
     82 
     83#define FR_SAFFIRE_CMD_ID_MONO_MODE         63 
     84#define FR_SAFFIRE_CMD_ID_MONO_MODE_STEREO   0 
     85#define FR_SAFFIRE_CMD_ID_MONO_MODE_MONO     1 
    11286 
    11387#define FR_SAFFIRE_CMD_ID_METERING_IN1      64 
     
    11690#define FR_SAFFIRE_CMD_ID_METERING_IN4      67 
    11791 
    118 #define FR_SAFFIRE_CMD_ID_SPDIF_DETECT    79 
     92#define FR_SAFFIRE_CMD_ID_METERING_PC1      68 
     93#define FR_SAFFIRE_CMD_ID_METERING_PC2      69 
     94#define FR_SAFFIRE_CMD_ID_METERING_PC3      70 
     95#define FR_SAFFIRE_CMD_ID_METERING_PC4      71 
     96#define FR_SAFFIRE_CMD_ID_METERING_PC5      72 
     97#define FR_SAFFIRE_CMD_ID_METERING_PC6      73 
     98#define FR_SAFFIRE_CMD_ID_METERING_PC7      74 
     99#define FR_SAFFIRE_CMD_ID_METERING_PC8      75 
     100#define FR_SAFFIRE_CMD_ID_METERING_PC9      76 
     101#define FR_SAFFIRE_CMD_ID_METERING_PC10     77 
     102 
     103#define FR_SAFFIRE_CMD_ID_DEVICE_MODE       78 
     104#define FR_SAFFIRE_CMD_ID_DEVICE_MODE_NORMAL 0 
     105#define FR_SAFFIRE_CMD_ID_DEVICE_MODE_SCARD  1 
     106 
     107#define FR_SAFFIRE_CMD_ID_EXTERNAL_LOCK     79 
     108#define FR_SAFFIRE_CMD_ID_AUDIO_ON_STATUS   80 
     109#define FR_SAFFIRE_CMD_ID_SAVE_SETTINGS     82 
     110 
     111#define FR_SAFFIRELE_CMD_ID_DSP_REVISION        1022 
     112#define FR_SAFFIRELE_CMD_ID_DSP_VERSION         1023 
    119113 
    120114// -- Saffire LE -- 
     
    257251public: 
    258252    enum eMatrixMixerType { 
    259         eMMT_InputMix, 
    260         eMMT_PCMix, 
     253        eMMT_SaffireStereoMatrixMix, 
     254        eMMT_SaffireMonoMatrixMix, 
    261255        eMMT_LEMix48, 
    262256        eMMT_LEMix96, 
  • trunk/libffado/src/bebob/focusrite/focusrite_saffirepro.cpp

    r1253 r1336  
    2626 
    2727#include "devicemanager.h" 
    28 #include "libutil/Time.h" 
     28#include "libutil/SystemTimeSource.h" 
    2929 
    3030#include "libutil/ByteSwap.h" 
     
    367367void 
    368368SaffireProDevice::updateClockSources() { 
     369    m_active_clocksource = &m_internal_clocksource; 
     370 
    369371    m_internal_clocksource.type = FFADODevice::eCT_Internal; 
     372    m_internal_clocksource.active = false; 
    370373    m_internal_clocksource.valid = true; 
    371374    m_internal_clocksource.locked = true; 
     
    375378 
    376379    m_spdif_clocksource.type = FFADODevice::eCT_SPDIF; 
     380    m_spdif_clocksource.active = false; 
    377381    m_spdif_clocksource.valid = true; 
    378382    m_spdif_clocksource.locked = false; 
     
    382386 
    383387    m_wordclock_clocksource.type = FFADODevice::eCT_WordClock; 
     388    m_wordclock_clocksource.active = false; 
    384389    m_wordclock_clocksource.valid = true; 
    385390    m_wordclock_clocksource.locked = false; 
     
    390395    if(isPro26()) { 
    391396        m_adat1_clocksource.type = FFADODevice::eCT_ADAT; 
     397        m_adat1_clocksource.active = false; 
    392398        m_adat1_clocksource.valid = true; 
    393399        m_adat1_clocksource.locked = false; 
     
    397403 
    398404        m_adat2_clocksource.type = FFADODevice::eCT_ADAT; 
     405        m_adat2_clocksource.active = false; 
    399406        m_adat2_clocksource.valid = true; 
    400407        m_adat2_clocksource.locked = false; 
     
    403410        m_adat2_clocksource.description = "ADAT 2"; 
    404411    } 
    405 
    406  
    407 FFADODevice::ClockSource 
    408 SaffireProDevice::getActiveClockSource() 
    409 
     412 
     413    // figure out the active source 
    410414    uint32_t sync; 
    411415    if ( !getSpecificValue(FR_SAFFIREPRO_CMD_ID_SYNC_CONFIG, &sync ) ){ 
    412416        debugError( "getSpecificValue failed\n" ); 
    413         return ClockSource(); 
    414     } 
    415  
    416     updateClockSources(); // make sure the current state is reflected in the clocksources 
    417  
    418     switch(sync) { 
    419         case FR_SAFFIREPRO_CMD_SYNC_CONFIG_INTERNAL: 
    420             return m_internal_clocksource; 
    421         case FR_SAFFIREPRO_CMD_SYNC_CONFIG_SPDIF: 
    422             return m_spdif_clocksource; 
    423         case FR_SAFFIREPRO_CMD_SYNC_CONFIG_ADAT1: 
    424             return m_adat1_clocksource; 
    425         case FR_SAFFIREPRO_CMD_SYNC_CONFIG_ADAT2: 
    426             return m_adat2_clocksource; 
    427         case FR_SAFFIREPRO_CMD_SYNC_CONFIG_WORDCLOCK: 
    428             return m_wordclock_clocksource; 
     417        m_internal_clocksource.active=true; 
     418        return; 
     419    } 
     420    debugOutput(DEBUG_LEVEL_VERBOSE, "SYNC_CONFIG field value: %08lX\n", sync ); 
     421 
     422    switch(sync & 0xFF) { 
    429423        default: 
    430424            debugWarning( "Unexpected SYNC_CONFIG field value: %08lX\n", sync ); 
    431             return ClockSource(); 
    432     } 
     425        case FR_SAFFIREPRO_CMD_SYNC_CONFIG_INTERNAL: 
     426            m_internal_clocksource.active=true; 
     427            m_active_clocksource = &m_internal_clocksource; 
     428            break; 
     429        case FR_SAFFIREPRO_CMD_SYNC_CONFIG_SPDIF: 
     430            m_spdif_clocksource.active=true; 
     431            m_active_clocksource = &m_spdif_clocksource; 
     432            break; 
     433        case FR_SAFFIREPRO_CMD_SYNC_CONFIG_ADAT1: 
     434            m_wordclock_clocksource.active=true; 
     435            m_active_clocksource = &m_wordclock_clocksource; 
     436            break; 
     437        case FR_SAFFIREPRO_CMD_SYNC_CONFIG_ADAT2: 
     438            m_adat1_clocksource.active=true; 
     439            m_active_clocksource = &m_adat1_clocksource; 
     440            break; 
     441        case FR_SAFFIREPRO_CMD_SYNC_CONFIG_WORDCLOCK: 
     442            m_adat2_clocksource.active=true; 
     443            m_active_clocksource = &m_adat2_clocksource; 
     444            break; 
     445    } 
     446    switch((sync >> 8) & 0xFF) { 
     447        case FR_SAFFIREPRO_CMD_SYNC_CONFIG_INTERNAL: 
     448            // always locked 
     449            break; 
     450        case FR_SAFFIREPRO_CMD_SYNC_CONFIG_SPDIF: 
     451            m_spdif_clocksource.locked=true; 
     452            break; 
     453        case FR_SAFFIREPRO_CMD_SYNC_CONFIG_ADAT1: 
     454            m_wordclock_clocksource.locked=true; 
     455            break; 
     456        case FR_SAFFIREPRO_CMD_SYNC_CONFIG_ADAT2: 
     457            m_adat1_clocksource.locked=true; 
     458            break; 
     459        case FR_SAFFIREPRO_CMD_SYNC_CONFIG_WORDCLOCK: 
     460            m_adat2_clocksource.locked=true; 
     461            break; 
     462        default: 
     463            debugWarning( "Unexpected SYNC_CONFIG_STATE field value: %08lX\n", sync ); 
     464    } 
     465
     466 
     467FFADODevice::ClockSource 
     468SaffireProDevice::getActiveClockSource() 
     469
     470    updateClockSources(); 
     471    return *m_active_clocksource; 
    433472} 
    434473 
     
    436475SaffireProDevice::setActiveClockSource(ClockSource s) 
    437476{ 
     477    // prevent busresets from being handled immediately 
     478    getDeviceManager().lockBusResetHandler(); 
     479    unsigned int gen_before = get1394Service().getGeneration(); 
     480 
     481    debugOutput(DEBUG_LEVEL_VERBOSE, "set active source to %d...\n", s.id); 
    438482    if ( !setSpecificValue(FR_SAFFIREPRO_CMD_ID_SYNC_CONFIG, s.id ) ){ 
    439         debugError( "detSpecificValue failed\n" ); 
    440         return false; 
    441     } 
     483        debugError( "setSpecificValue failed\n" ); 
     484        getDeviceManager().unlockBusResetHandler(); 
     485        return false; 
     486    } 
     487 
     488    // the device can do a bus reset at this moment 
     489    Util::SystemTimeSource::SleepUsecRelative(1000 * 1000); 
     490    if(!get1394Service().waitForBusResetStormToEnd(10, 2000)) { 
     491        debugWarning("Device doesn't stop bus-resetting\n"); 
     492    } 
     493    unsigned int gen_after = get1394Service().getGeneration(); 
     494    debugOutput(DEBUG_LEVEL_VERBOSE, " gen: %d=>%d\n", gen_before, gen_after); 
     495 
     496    getDeviceManager().unlockBusResetHandler(); 
    442497    return true; 
    443498} 
     
    446501SaffireProDevice::getSupportedClockSources() 
    447502{ 
     503    debugOutput(DEBUG_LEVEL_VERBOSE, "listing...\n"); 
    448504    FFADODevice::ClockSourceVector r; 
    449505    r.push_back(m_internal_clocksource); 
     
    571627        const int max_tries = 2; 
    572628        int ntries = max_tries+1; 
    573          
    574         // FIXME: not very clean 
    575         getDeviceManager().ignoreBusResets(true); 
    576          
     629 
     630        // the device behaves like a pig when changing samplerate, 
     631        // generating a bunch of bus-resets. 
     632        // we don't want the busreset handler to run while we are 
     633        // changing the samplerate. however it has to run after the 
     634        // device finished, since the bus resets might have influenced 
     635        // other attached devices. 
     636        getDeviceManager().lockBusResetHandler(); 
    577637        unsigned int gen_before = get1394Service().getGeneration(); 
    578          
     638 
    579639        while(--ntries) { 
    580640            if (rebootOnSamplerateChange) { 
     
    587647 
    588648                // the device needs quite some time to reboot 
    589                 SleepRelativeUsec(2 * 1000 * 1000); 
     649                Util::SystemTimeSource::SleepUsecRelative(2 * 1000 * 1000); 
    590650 
    591651                int timeout = 5; // multiples of 1s 
     
    595655                { 
    596656                    // wait for a while 
    597                     SleepRelativeUsec(1000 * 1000); 
     657                    Util::SystemTimeSource::SleepUsecRelative(1000 * 1000); 
    598658                } 
    599659                if (!timeout) { 
     
    602662 
    603663                    // the device needs quite some time to reboot 
    604                     SleepRelativeUsec(2 * 1000 * 1000); 
     664                    Util::SystemTimeSource::SleepUsecRelative(2 * 1000 * 1000); 
    605665 
    606666                    // wait for the device to finish the reboot 
     
    610670                    { 
    611671                        // wait for a while 
    612                         SleepRelativeUsec(1000 * 1000); 
     672                        Util::SystemTimeSource::SleepUsecRelative(1000 * 1000); 
    613673                    } 
    614674                    if (!timeout) { 
    615675                        debugError( "Device did not reset itself after forced reboot...\n"); 
     676                        getDeviceManager().unlockBusResetHandler(); 
    616677                        return false; 
    617678                    } 
     
    620681                // so we know the device is rebooting 
    621682                // now wait until it stops generating busresets 
    622                 timeout = 10; 
    623                 unsigned int gen_current; 
    624                 do { 
    625                     gen_current=get1394Service().getGeneration(); 
    626                     debugOutput(DEBUG_LEVEL_VERBOSE, "Waiting... (gen: %u)\n", gen_current); 
    627  
    628                     // wait for a while 
    629                     SleepRelativeUsec(4 * 1000 * 1000); 
    630                 } while (gen_current != get1394Service().getGeneration() 
    631                          && --timeout); 
    632  
    633                 if (!timeout) { 
    634                     debugError( "Device did not recover from reboot...\n"); 
     683                if(!get1394Service().waitForBusResetStormToEnd(20, 4000)) { 
     684                    debugError("The device keeps behaving like a pig...\n"); 
     685                    getDeviceManager().unlockBusResetHandler(); 
    635686                    return false; 
    636687                } 
    637  
    638688                debugOutput(DEBUG_LEVEL_VERBOSE, "Device available (gen: %u => %u)...\n",  
    639689                    gen_before, get1394Service().getGeneration()); 
    640690 
    641691                // wait some more 
    642                 SleepRelativeUsec(1 * 1000 * 1000); 
     692                Util::SystemTimeSource::SleepUsecRelative(1 * 1000 * 1000); 
    643693 
    644694                // we have to rediscover the device 
     
    651701            } 
    652702 
    653             int verify=getSamplingFrequency(); 
     703            int verify = getSamplingFrequency(); 
    654704            debugOutput( DEBUG_LEVEL_VERBOSE, 
    655705                        "setSampleRate (try %d): requested samplerate %d, device now has %d\n",  
     
    662712        } 
    663713 
    664         // FIXME: not very clea
    665         getDeviceManager().ignoreBusResets(false); 
     714        // make the busreset handlers ru
     715        getDeviceManager().unlockBusResetHandler(); 
    666716 
    667717        if (ntries==0) { 
  • trunk/libffado/src/bebob/focusrite/focusrite_saffirepro.h

    r1253 r1336  
    421421    ClockSource m_adat1_clocksource; 
    422422    ClockSource m_adat2_clocksource; 
     423    ClockSource *m_active_clocksource; 
    423424 
    424425    Control::Container *m_MixerContainer; 
  • trunk/libffado/src/devicemanager.cpp

    r1254 r1336  
    3232#include "libieee1394/configrom.h" 
    3333#include "libieee1394/ieee1394service.h" 
     34#include "libieee1394/IsoHandlerManager.h" 
    3435 
    3536#include "libstreaming/generic/StreamProcessor.h" 
     
    8586DeviceManager::DeviceManager() 
    8687    : Control::Container(NULL, "devicemanager") // this is the control root node 
    87     , m_avDevicesLock( new Util::PosixMutex() ) 
    88     , m_BusResetLock( new Util::PosixMutex() ) 
    89     , m_processorManager( new Streaming::StreamProcessorManager() ) 
     88    , m_DeviceListLock( new Util::PosixMutex("DEVLST") ) 
     89    , m_BusResetLock( new Util::PosixMutex("DEVBR") ) 
     90    , m_processorManager( new Streaming::StreamProcessorManager( *this ) ) 
    9091    , m_deviceStringParser( new DeviceStringParser() ) 
     92    , m_configuration ( new Util::Configuration() ) 
    9193    , m_used_cache_last_time( false ) 
    92     , m_ignore_busreset( false ) 
    9394    , m_thread_realtime( false ) 
    9495    , m_thread_priority( 0 ) 
     
    100101DeviceManager::~DeviceManager() 
    101102{ 
    102     m_avDevicesLock->Lock(); // make sure nobody is using this 
     103    // save configuration 
     104    if(!m_configuration->save()) { 
     105        debugWarning("could not save configuration\n"); 
     106    } 
     107 
     108    m_BusResetLock->Lock(); // make sure we are not handling a busreset. 
     109    m_DeviceListLock->Lock(); // make sure nobody is using this 
    103110    for ( FFADODeviceVectorIterator it = m_avDevices.begin(); 
    104111          it != m_avDevices.end(); 
     
    110117        delete *it; 
    111118    } 
    112     m_avDevicesLock->Unlock(); 
    113     delete m_avDevicesLock; 
     119    m_DeviceListLock->Unlock(); 
    114120 
    115121    // the SP's are automatically unregistered from the SPM 
    116122    delete m_processorManager; 
    117123 
     124    // the device list is empty, so wake up any waiting 
     125    // reset handlers 
     126    m_BusResetLock->Unlock(); 
     127 
     128    // remove the bus-reset handlers 
    118129    for ( FunctorVectorIterator it = m_busreset_functors.begin(); 
    119130          it != m_busreset_functors.end(); 
     
    122133        delete *it; 
    123134    } 
    124     delete m_BusResetLock; 
    125135 
    126136    for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin(); 
     
    131141    } 
    132142 
     143    delete m_DeviceListLock; 
     144    delete m_BusResetLock; 
    133145    delete m_deviceStringParser; 
    134146} 
     
    159171    assert(m_1394Services.size() == 0); 
    160172    assert(m_busreset_functors.size() == 0); 
     173 
     174    m_configuration->openFile( "temporary", Util::Configuration::eFM_Temporary ); 
     175    m_configuration->openFile( USER_CONFIG_FILE, Util::Configuration::eFM_ReadWrite ); 
     176    m_configuration->openFile( SYSTEM_CONFIG_FILE, Util::Configuration::eFM_ReadOnly ); 
    161177 
    162178    int nb_detected_ports = Ieee1394Service::detectNbPorts(); 
     
    185201        } 
    186202        // add the bus reset handler 
    187         Util::Functor* tmp_busreset_functor = new Util::MemberFunctor0< DeviceManager*, 
    188                     void (DeviceManager::*)()
    189                     ( this, &DeviceManager::busresetHandler, false ); 
     203        Util::Functor* tmp_busreset_functor = new Util::MemberFunctor1< DeviceManager*, 
     204                    void (DeviceManager::*)(Ieee1394Service &), Ieee1394Service &
     205                    ( this, &DeviceManager::busresetHandler, *tmp1394Service, false ); 
    190206        if ( !tmp_busreset_functor ) { 
    191207            debugFatal( "Could not create busreset handler for port %d\n", port ); 
     
    221237 
    222238void 
    223 DeviceManager::busresetHandler(
     239DeviceManager::busresetHandler(Ieee1394Service &service
    224240{ 
    225241    // serialize bus reset handling since it can be that a new one occurs while we're 
    226242    // doing stuff. 
     243    debugOutput( DEBUG_LEVEL_NORMAL, "Bus reset detected on service %p...\n", &service ); 
    227244    Util::MutexLockHelper lock(*m_BusResetLock); 
    228     debugOutput( DEBUG_LEVEL_VERBOSE, "Bus reset...\n" ); 
    229     if(m_ignore_busreset) { 
    230         debugOutput( DEBUG_LEVEL_VERBOSE, " ignoring...\n" ); 
    231         return; 
    232     } 
    233  
    234     // FIXME: what port was the bus reset on? 
    235     // FIXME: what if the devices are gone? 
     245    debugOutput( DEBUG_LEVEL_NORMAL, " handling busreset...\n" ); 
     246 
     247    // FIXME: what if the devices are gone? (device should detect this!) 
    236248    // propagate the bus reset to all avDevices 
    237     m_avDevicesLock->Lock(); // make sure nobody is using this 
     249    m_DeviceListLock->Lock(); // make sure nobody is using this 
    238250    for ( FFADODeviceVectorIterator it = m_avDevices.begin(); 
    239251          it != m_avDevices.end(); 
    240252          ++it ) 
    241253    { 
    242         (*it)->handleBusReset(); 
    243     } 
    244     m_avDevicesLock->Unlock(); 
     254        if(&service == &((*it)->get1394Service())) { 
     255            debugOutput(DEBUG_LEVEL_NORMAL, 
     256                        "issue busreset on device GUID %s\n", 
     257                        (*it)->getConfigRom().getGuidString().c_str()); 
     258            (*it)->handleBusReset(); 
     259        } else { 
     260            debugOutput(DEBUG_LEVEL_NORMAL, 
     261                        "skipping device GUID %s since not on service %p\n", 
     262                        (*it)->getConfigRom().getGuidString().c_str(), &service); 
     263        } 
     264    } 
     265    m_DeviceListLock->Unlock(); 
     266 
     267    // now that the devices have been updates, we can request to update the iso streams 
     268    if(!service.getIsoHandlerManager().handleBusReset()) { 
     269        debugError("IsoHandlerManager failed to handle busreset\n"); 
     270    } 
    245271 
    246272    // notify the streamprocessormanager of the busreset 
    247     if(m_processorManager) { 
    248         m_processorManager->handleBusReset(); 
    249     } else { 
    250         debugWarning("No valid SPM\n"); 
    251     } 
     273//     if(m_processorManager) { 
     274//         m_processorManager->handleBusReset(service); 
     275//     } else { 
     276//         debugWarning("No valid SPM\n"); 
     277//     } 
    252278 
    253279    // rediscover to find new devices 
     
    261287 
    262288    // display the new state 
    263     showDeviceInfo(); 
     289    if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) { 
     290        showDeviceInfo(); 
     291    } 
    264292} 
    265293 
     
    317345DeviceManager::discover( bool useCache, bool rediscover ) 
    318346{ 
     347    debugOutput( DEBUG_LEVEL_NORMAL, "Starting discovery...\n" ); 
    319348    useCache = useCache && ENABLE_DISCOVERY_CACHE; 
    320349    m_used_cache_last_time = useCache; 
     
    370399    // notify that we are going to manipulate the list 
    371400    signalNotifiers(m_preUpdateNotifiers); 
    372     m_avDevicesLock->Lock(); // make sure nobody starts using the list 
     401    m_DeviceListLock->Lock(); // make sure nobody starts using the list 
    373402    if(rediscover) { 
    374403 
     
    635664    } 
    636665 
    637     m_avDevicesLock->Unlock(); 
     666    m_DeviceListLock->Unlock(); 
    638667    // notify any clients 
    639668    signalNotifiers(m_postUpdateNotifiers); 
     
    825854#ifdef ENABLE_BEBOB 
    826855    debugOutput( DEBUG_LEVEL_VERBOSE, "Trying BeBoB...\n" ); 
    827     if ( BeBoB::AvDevice::probe( *configRom, generic ) ) { 
     856    if ( BeBoB::AvDevice::probe( getConfiguration(), *configRom, generic ) ) { 
    828857        return BeBoB::AvDevice::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) ); 
    829858    } 
     
    832861#ifdef ENABLE_FIREWORKS 
    833862    debugOutput( DEBUG_LEVEL_VERBOSE, "Trying ECHO Audio FireWorks...\n" ); 
    834     if ( FireWorks::Device::probe( *configRom, generic ) ) { 
     863    if ( FireWorks::Device::probe( getConfiguration(), *configRom, generic ) ) { 
    835864        return FireWorks::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) ); 
    836865    } 
     
    840869#ifdef ENABLE_GENERICAVC 
    841870    debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Generic AV/C...\n" ); 
    842     if ( GenericAVC::AvDevice::probe( *configRom, generic ) ) { 
     871    if ( GenericAVC::AvDevice::probe( getConfiguration(), *configRom, generic ) ) { 
    843872        return GenericAVC::AvDevice::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) ); 
    844873    } 
     
    847876#ifdef ENABLE_MOTU 
    848877    debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Motu...\n" ); 
    849     if ( Motu::MotuDevice::probe( *configRom, generic ) ) { 
     878    if ( Motu::MotuDevice::probe( getConfiguration(), *configRom, generic ) ) { 
    850879        return Motu::MotuDevice::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) ); 
    851880    } 
     
    10181047} 
    10191048 
    1020  
    10211049void 
    10221050DeviceManager::setVerboseLevel(int l) 
     
    10261054    m_processorManager->setVerboseLevel(l); 
    10271055    m_deviceStringParser->setVerboseLevel(l); 
     1056    m_configuration->setVerboseLevel(l); 
    10281057    for ( FFADODeviceVectorIterator it = m_avDevices.begin(); 
    10291058          it != m_avDevices.end(); 
  • trunk/libffado/src/devicemanager.h

    r1239 r1336  
    3838#include "libutil/Functors.h" 
    3939#include "libutil/Mutex.h" 
     40#include "libutil/Configuration.h" 
    4041 
    4142#include <vector> 
     
    105106    Streaming::StreamProcessor *getSyncSource(); 
    106107 
    107     void ignoreBusResets(bool b) {m_ignore_busreset = b;}; 
     108    /** 
     109     * prevents the busreset handler from running. use with care! 
     110     */ 
     111    void lockBusResetHandler() {m_BusResetLock->Lock();}; 
     112    /** 
     113     * releases the busreset handlers 
     114     */ 
     115    void unlockBusResetHandler() {m_BusResetLock->Unlock();}; 
    108116    bool registerBusresetNotification(Util::Functor *f) 
    109117        {return registerNotification(m_busResetNotifiers, f);}; 
     
    120128    bool unregisterPostUpdateNotification(Util::Functor *f) 
    121129        {return unregisterNotification(m_postUpdateNotifiers, f);}; 
     130 
     131 
     132    Util::Configuration& getConfiguration() {return *m_configuration;}; 
    122133 
    123134    void showDeviceInfo(); 
     
    137148    FFADODevice* getSlaveDriver( std::auto_ptr<ConfigRom>( configRom ) ); 
    138149 
    139     void busresetHandler(); 
     150    void busresetHandler(Ieee1394Service &); 
    140151 
    141152protected: 
     
    147158 
    148159    // the lock protecting the device list 
    149     Util::Mutex*            m_avDevicesLock; 
     160    Util::Mutex*            m_DeviceListLock; 
    150161    // the lock to serialize bus reset handling 
    151162    Util::Mutex*            m_BusResetLock; 
     
    157168    Streaming::StreamProcessorManager*  m_processorManager; 
    158169    DeviceStringParser*                 m_deviceStringParser; 
     170    Util::Configuration*                m_configuration; 
    159171    bool                                m_used_cache_last_time; 
    160     bool                                m_ignore_busreset; 
    161172 
    162173    typedef std::vector< Util::Functor* > notif_vec_t; 
  • trunk/libffado/src/dice/dice_avdevice.cpp

    r1333 r1336  
    190190 
    191191    return samplingFrequency; 
     192} 
     193 
     194#define DICE_CHECK_AND_ADD_SR(v, x, reg) \ 
     195    { if(maskedCheckNotZeroGlobalReg( DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, reg)) \ 
     196       v.push_back(x); } 
     197std::vector<int> 
     198DiceAvDevice::getSupportedSamplingFrequencies() 
     199{ 
     200    std::vector<int> frequencies; 
     201    DICE_CHECK_AND_ADD_SR(frequencies, 32000, DICE_CLOCKCAP_RATE_32K); 
     202    DICE_CHECK_AND_ADD_SR(frequencies, 44100, DICE_CLOCKCAP_RATE_44K1); 
     203    DICE_CHECK_AND_ADD_SR(frequencies, 48000, DICE_CLOCKCAP_RATE_48K); 
     204    DICE_CHECK_AND_ADD_SR(frequencies, 88200, DICE_CLOCKCAP_RATE_88K2); 
     205    DICE_CHECK_AND_ADD_SR(frequencies, 96000, DICE_CLOCKCAP_RATE_96K); 
     206    DICE_CHECK_AND_ADD_SR(frequencies, 176400, DICE_CLOCKCAP_RATE_176K4); 
     207    DICE_CHECK_AND_ADD_SR(frequencies, 192000, DICE_CLOCKCAP_RATE_192K); 
     208    return frequencies; 
    192209} 
    193210 
  • trunk/libffado/src/dice/dice_avdevice.h

    r1239 r1336  
    7070    virtual bool setSamplingFrequency( int samplingFrequency ); 
    7171    virtual int getSamplingFrequency( ); 
     72    virtual std::vector<int> getSupportedSamplingFrequencies(); 
    7273 
    7374    virtual ClockSourceVector getSupportedClockSources(); 
  • trunk/libffado/src/fbtypes.h

    r864 r1336  
    2727#include <libraw1394/raw1394.h> 
    2828 
     29#define INVALID_NODE_ID 0xFF 
     30 
    2931typedef quadlet_t   fb_quadlet_t; 
    3032typedef byte_t      fb_byte_t; 
  • trunk/libffado/src/ffado.cpp

    r1254 r1336  
    9898 
    9999    printMessage("%s built %s %s\n", ffado_get_version(), __DATE__, __TIME__); 
     100 
     101#if DEBUG_USE_MESSAGE_BUFFER 
     102    // ok 
     103#else 
     104    printMessage("FFADO built without realtime-safe message buffer support. This can cause xruns and is not recommended.\n"); 
     105#endif 
    100106 
    101107    if(!dev) { 
  • trunk/libffado/src/ffadodevice.h

    r1129 r1336  
    4242namespace Streaming { 
    4343    class StreamProcessor; 
    44     class StreamProcessorManager; 
    4544} 
    4645 
     
    139138     */ 
    140139    virtual int getSamplingFrequency( ) = 0; 
     140 
     141    /** 
     142     * @brief get the supported sampling frequencies 
     143     * @return a vector containing the supported sampling frequencies 
     144     */ 
     145    virtual std::vector<int> getSupportedSamplingFrequencies( ) = 0; 
    141146 
    142147    /** 
  • trunk/libffado/src/fireworks/efc/efc_cmd.h

    r1234 r1336  
    104104 
    105105// specifiers for the flags field 
    106 #define EFC_CMD_HW_DYNADDR_SUPPORTED                1 
    107 #define EFC_CMD_HW_MIRRORING_SUPPORTED              2 
    108 #define EFC_CMD_HW_SPDIF_COAX_SUPPORTED             3 
    109 #define EFC_CMD_HW_SPDIF_AESEBUXLR_SUPPORTED        4 
    110 #define EFC_CMD_HW_HAS_DSP                          5 
    111 #define EFC_CMD_HW_HAS_FPGA                         6 
    112 #define EFC_CMD_HW_HAS_PHANTOM                      7 
     106#define EFC_CMD_HW_DYNADDR_SUPPORTED                0 
     107#define EFC_CMD_HW_MIRRORING_SUPPORTED              1 
     108#define EFC_CMD_HW_SPDIF_COAX_SUPPORTED             2 
     109#define EFC_CMD_HW_SPDIF_AESEBUXLR_SUPPORTED        3 
     110#define EFC_CMD_HW_HAS_DSP                          4 
     111#define EFC_CMD_HW_HAS_FPGA                         5 
     112#define EFC_CMD_HW_HAS_PHANTOM                      6 
    113113 
    114114#define EFC_CMD_HW_CHECK_FLAG(__val__,__flag__) \ 
  • trunk/libffado/src/fireworks/efc/efc_cmds_hardware.h

    r864 r1336  
    5353    virtual void showEfcCmd(); 
    5454     
    55     bool hasSoftwarePhantom() 
     55    bool hasSoftwarePhantom() const 
    5656        {return EFC_CMD_HW_CHECK_FLAG(m_flags, EFC_CMD_HW_HAS_PHANTOM);}; 
    57     bool hasDSP() 
     57    bool hasDSP() const 
    5858        {return EFC_CMD_HW_CHECK_FLAG(m_flags, EFC_CMD_HW_HAS_DSP);}; 
    59     bool hasFPGA() 
     59    bool hasFPGA() const 
    6060        {return EFC_CMD_HW_CHECK_FLAG(m_flags, EFC_CMD_HW_HAS_FPGA);}; 
    61     bool hasSpdifCoax() 
     61    bool hasSpdifCoax() const 
    6262        {return EFC_CMD_HW_CHECK_FLAG(m_flags, EFC_CMD_HW_SPDIF_COAX_SUPPORTED);}; 
    63     bool hasSpdifAESEBUXLR() 
     63    bool hasSpdifAESEBUXLR() const 
    6464        {return EFC_CMD_HW_CHECK_FLAG(m_flags, EFC_CMD_HW_SPDIF_AESEBUXLR_SUPPORTED);}; 
    65     bool hasMirroring() 
     65    bool hasMirroring() const 
    6666        {return EFC_CMD_HW_CHECK_FLAG(m_flags, EFC_CMD_HW_MIRRORING_SUPPORTED);}; 
    67     bool hasDynAddr() 
     67    bool hasDynAddr() const 
    6868        {return EFC_CMD_HW_CHECK_FLAG(m_flags, EFC_CMD_HW_DYNADDR_SUPPORTED);}; 
    6969 
  • trunk/libffado/src/fireworks/efc/efc_cmds_hardware_ctrl.cpp

    r1136 r1336  
    166166} 
    167167 
     168// -- get flags  
     169EfcGetFlagsCmd::EfcGetFlagsCmd() 
     170    : EfcCmd(EFC_CAT_HARDWARE_CONTROL, EFC_CMD_HWCTRL_GET_FLAGS) 
     171    , m_flags ( 0 ) 
     172{ 
     173} 
     174 
     175bool 
     176EfcGetFlagsCmd::serialize( Util::Cmd::IOSSerialize& se ) 
     177{ 
     178    bool result=true; 
     179 
     180    // the length should be specified before 
     181    // the header is serialized 
     182    m_length=EFC_HEADER_LENGTH_QUADLETS; 
     183 
     184    result &= EfcCmd::serialize ( se ); 
     185 
     186    return result; 
     187} 
     188 
     189bool 
     190EfcGetFlagsCmd::deserialize( Util::Cmd::IISDeserialize& de ) 
     191{ 
     192    bool result=true; 
     193 
     194    result &= EfcCmd::deserialize ( de ); 
     195 
     196    EFC_DESERIALIZE_AND_SWAP(de, &m_flags, result); 
     197 
     198    return result; 
     199} 
     200 
     201void 
     202EfcGetFlagsCmd::showEfcCmd() 
     203{ 
     204    EfcCmd::showEfcCmd(); 
     205    debugOutput(DEBUG_LEVEL_NORMAL, "EFC Get Flags:\n"); 
     206    debugOutput(DEBUG_LEVEL_NORMAL, " Flags       : %08X\n", m_flags); 
     207} 
     208 
     209// ---- 
     210EfcChangeFlagsCmd::EfcChangeFlagsCmd() 
     211    : EfcCmd(EFC_CAT_HARDWARE_CONTROL, EFC_CMD_HWCTRL_CHANGE_FLAGS) 
     212    , m_setmask ( 0 ) 
     213    , m_clearmask ( 0 ) 
     214{ 
     215} 
     216 
     217bool 
     218EfcChangeFlagsCmd::serialize( Util::Cmd::IOSSerialize& se ) 
     219{ 
     220    bool result=true; 
     221 
     222    // the length should be specified before 
     223    // the header is serialized 
     224    m_length=EFC_HEADER_LENGTH_QUADLETS+2; 
     225 
     226    result &= EfcCmd::serialize ( se ); 
     227 
     228    result &= se.write(CondSwapToBus32(m_setmask), "SetMask" ); 
     229    result &= se.write(CondSwapToBus32(m_clearmask), "ClearMask" ); 
     230 
     231    return result; 
     232} 
     233 
     234bool 
     235EfcChangeFlagsCmd::deserialize( Util::Cmd::IISDeserialize& de ) 
     236{ 
     237    bool result=true; 
     238    result &= EfcCmd::deserialize ( de ); 
     239    return result; 
     240} 
     241 
     242void 
     243EfcChangeFlagsCmd::showEfcCmd() 
     244{ 
     245    EfcCmd::showEfcCmd(); 
     246    debugOutput(DEBUG_LEVEL_NORMAL, "EFC Change flags:\n"); 
     247    debugOutput(DEBUG_LEVEL_NORMAL, " Set mask     : %08X\n", m_setmask); 
     248    debugOutput(DEBUG_LEVEL_NORMAL, " Clear mask   : %08X\n", m_clearmask); 
     249} 
     250 
     251 
     252// ---- 
     253EfcIdentifyCmd::EfcIdentifyCmd() 
     254    : EfcCmd(EFC_CAT_HARDWARE_CONTROL, EFC_CMD_HWCTRL_IDENTIFY) 
     255{ 
     256} 
     257 
     258bool 
     259EfcIdentifyCmd::serialize( Util::Cmd::IOSSerialize& se ) 
     260{ 
     261    bool result=true; 
     262 
     263    // the length should be specified before 
     264    // the header is serialized 
     265    m_length=EFC_HEADER_LENGTH_QUADLETS; 
     266 
     267    result &= EfcCmd::serialize ( se ); 
     268 
     269    return result; 
     270} 
     271 
     272bool 
     273EfcIdentifyCmd::deserialize( Util::Cmd::IISDeserialize& de ) 
     274{ 
     275    bool result=true; 
     276 
     277    result &= EfcCmd::deserialize ( de ); 
     278 
     279    return result; 
     280} 
     281 
     282void 
     283EfcIdentifyCmd::showEfcCmd() 
     284{ 
     285    EfcCmd::showEfcCmd(); 
     286    debugOutput(DEBUG_LEVEL_NORMAL, "EFC Identify\n"); 
     287} 
     288 
    168289} // namespace FireWorks 
  • trunk/libffado/src/fireworks/efc/efc_cmds_hardware_ctrl.h

    r864 r1336  
    2828 
    2929namespace FireWorks { 
     30 
     31#define FIREWORKS_EFC_FLAG_MIXER_ENABLED    1 
     32#define FIREWORKS_EFC_FLAG_SPDIF_PRO        2 
     33#define FIREWORKS_EFC_FLAG_SPDIF_RAW        4 
    3034 
    3135class EfcGetClockCmd : public EfcCmd 
     
    8286}; 
    8387 
     88 
     89class EfcGetFlagsCmd : public EfcCmd 
     90{ 
     91public: 
     92    EfcGetFlagsCmd(); 
     93    virtual ~EfcGetFlagsCmd() {}; 
     94 
     95    virtual bool serialize( Util::Cmd::IOSSerialize& se ); 
     96    virtual bool deserialize( Util::Cmd::IISDeserialize& de ); 
     97 
     98    virtual const char* getCmdName() const 
     99    { return "EfcGetFlagsCmd"; } 
     100 
     101    virtual void showEfcCmd(); 
     102 
     103    uint32_t    m_flags; 
     104}; 
     105 
     106class EfcChangeFlagsCmd : public EfcCmd 
     107{ 
     108public: 
     109    EfcChangeFlagsCmd(); 
     110    virtual ~EfcChangeFlagsCmd() {}; 
     111 
     112    virtual bool serialize( Util::Cmd::IOSSerialize& se ); 
     113    virtual bool deserialize( Util::Cmd::IISDeserialize& de ); 
     114 
     115    virtual const char* getCmdName() const 
     116    { return "EfcChangeFlagsCmd"; } 
     117 
     118    virtual void showEfcCmd(); 
     119 
     120    uint32_t    m_setmask; 
     121    uint32_t    m_clearmask; 
     122}; 
     123 
     124class EfcIdentifyCmd : public EfcCmd 
     125{ 
     126public: 
     127    EfcIdentifyCmd(); 
     128    virtual ~EfcIdentifyCmd() {}; 
     129 
     130    virtual bool serialize( Util::Cmd::IOSSerialize& se ); 
     131    virtual bool deserialize( Util::Cmd::IISDeserialize& de ); 
     132 
     133    virtual const char* getCmdName() const 
     134    { return "EfcIdentifyCmd"; } 
     135 
     136    virtual void showEfcCmd(); 
     137 
     138}; 
     139 
    84140} // namespace FireWorks 
    85141 
  • trunk/libffado/src/fireworks/efc/efc_cmds_ioconfig.cpp

    r1136 r1336  
    3737    , m_reg ( r ) 
    3838{ 
     39    m_category_id = EFC_CAT_IO_CONFIG; 
    3940    m_type=eCT_Get; 
    4041    setRegister(r); 
  • trunk/libffado/src/fireworks/efc/efc_cmds_ioconfig.h

    r864 r1336  
    2929namespace FireWorks { 
    3030 
     31#define EFC_MAX_ISOC_MAP_ENTRIES    32 
     32typedef struct tag_efc_isoc_map 
     33{ 
     34    uint32_t    samplerate; 
     35    uint32_t    flags; 
     36 
     37    uint32_t    num_playmap_entries; 
     38    uint32_t    num_phys_out; 
     39    int32_t     playmap[ EFC_MAX_ISOC_MAP_ENTRIES ]; 
     40 
     41    uint32_t    num_recmap_entries; 
     42    uint32_t    num_phys_in; 
     43    int32_t     recmap[ EFC_MAX_ISOC_MAP_ENTRIES ]; 
     44} IsoChannelMap; 
     45 
    3146class EfcGenericIOConfigCmd : public EfcCmd 
    3247{ 
     
    4661     
    4762    virtual const char* getCmdName() const 
    48         { return "EfcGenericIOConfigCmd"; } 
     63        { return "EfcGenericIOConfigCmd"; }; 
    4964 
    50     uint32_t    m_value; 
     65    uint32_t   m_value; 
    5166 
    5267private: 
  • trunk/libffado/src/fireworks/fireworks_control.cpp

    r1158 r1336  
    2828#include "efc/efc_cmds_mixer.h" 
    2929#include "efc/efc_cmds_monitor.h" 
     30#include "efc/efc_cmds_hardware_ctrl.h" 
    3031 
    3132#include <string> 
     
    4041: Control::MatrixMixer(&p, "MonitorControl") 
    4142, m_control(c) 
    42 , m_Parent(p) 
     43, m_ParentDevice(p) 
    4344{ 
    4445} 
     
    4748: Control::MatrixMixer(&p, n) 
    4849, m_control(c) 
    49 , m_Parent(p) 
     50, m_ParentDevice(p) 
    5051{ 
    5152} 
     
    8687    bool did_command=false; 
    8788 
    88     if(row >= (int)m_Parent.getHwInfo().m_nb_phys_audio_in) { 
     89    if(row >= (int)m_ParentDevice.getHwInfo().m_nb_phys_audio_in) { 
    8990        debugError("specified row (%u) larger than number of rows (%d)\n", 
    90             row, m_Parent.getHwInfo().m_nb_phys_audio_in); 
     91            row, m_ParentDevice.getHwInfo().m_nb_phys_audio_in); 
    9192        return 0.0; 
    9293    } 
    93     if(col >= (int)m_Parent.getHwInfo().m_nb_phys_audio_out) { 
     94    if(col >= (int)m_ParentDevice.getHwInfo().m_nb_phys_audio_out) { 
    9495        debugError("specified col (%u) larger than number of cols (%d)\n", 
    95             col, m_Parent.getHwInfo().m_nb_phys_audio_out); 
     96            col, m_ParentDevice.getHwInfo().m_nb_phys_audio_out); 
    9697        return 0.0; 
    9798    } 
    9899 
     100    // not a switch since we create variables 
    99101    if(m_control==eMC_Gain) { 
    100102        EfcSetMonitorGainCmd setCmd; 
    101         setCmd.m_input=row; 
    102         setCmd.m_output=col; 
    103         setCmd.m_value=(uint32_t)val; 
    104         if (!m_Parent.doEfcOverAVC(setCmd))  
    105         { 
    106             debugFatal("Cmd failed\n"); 
    107         } 
    108         retval=setCmd.m_value; 
    109         did_command=true; 
     103        setCmd.m_input = row; 
     104        setCmd.m_output = col; 
     105        setCmd.m_value = (uint32_t)val; 
     106        if (!m_ParentDevice.doEfcOverAVC(setCmd))  
     107        { 
     108            debugError("Cmd failed\n"); 
     109        } 
     110        // update the session block 
     111        m_ParentDevice.m_session.h.monitorgains[row][col] = setCmd.m_value; 
     112        retval = setCmd.m_value; 
     113        did_command = true; 
    110114    } 
    111115    if(m_control==eMC_Pan) { 
    112116        EfcSetMonitorPanCmd setCmd; 
    113         setCmd.m_input=row; 
    114         setCmd.m_output=col; 
    115         setCmd.m_value=(uint32_t)val; 
    116         if (!m_Parent.doEfcOverAVC(setCmd))  
    117         { 
    118             debugFatal("Cmd failed\n"); 
    119         } 
    120         retval=setCmd.m_value; 
    121         did_command=true; 
     117        setCmd.m_input = row; 
     118        setCmd.m_output = col; 
     119        setCmd.m_value = (uint32_t)val; 
     120        if (!m_ParentDevice.doEfcOverAVC(setCmd))  
     121        { 
     122            debugError("Cmd failed\n"); 
     123        } 
     124        // update the session block 
     125        m_ParentDevice.m_session.s.monitorpans[row][col] = setCmd.m_value; 
     126        retval = setCmd.m_value; 
     127        did_command = true; 
    122128    } 
    123129    if(m_control==eMC_Mute) { 
    124130        EfcSetMonitorMuteCmd setCmd; 
    125         setCmd.m_input=row; 
    126         setCmd.m_output=col; 
    127         setCmd.m_value=(uint32_t)val; 
    128         if (!m_Parent.doEfcOverAVC(setCmd))  
    129         { 
    130             debugFatal("Cmd failed\n"); 
    131         } 
    132         retval=setCmd.m_value; 
    133         did_command=true; 
     131        setCmd.m_input = row; 
     132        setCmd.m_output = col; 
     133        setCmd.m_value = (uint32_t)val; 
     134        if (!m_ParentDevice.doEfcOverAVC(setCmd)) 
     135        { 
     136            debugError("Cmd failed\n"); 
     137        } 
     138        // update the session block 
     139        if(setCmd.m_value) { 
     140            m_ParentDevice.m_session.s.monitorflags[row][col] |= ECHO_SESSION_MUTE_BIT; 
     141        } else { 
     142            m_ParentDevice.m_session.s.monitorflags[row][col] &= ~ECHO_SESSION_MUTE_BIT; 
     143        } 
     144        retval = setCmd.m_value; 
     145        did_command = true; 
    134146    } 
    135147    if(m_control==eMC_Solo) { 
    136148        EfcSetMonitorSoloCmd setCmd; 
    137         setCmd.m_input=row; 
    138         setCmd.m_output=col; 
    139         setCmd.m_value=(uint32_t)val; 
    140         if (!m_Parent.doEfcOverAVC(setCmd))  
    141         { 
    142             debugFatal("Cmd failed\n"); 
    143         } 
    144         retval=setCmd.m_value; 
    145         did_command=true; 
     149        setCmd.m_input = row; 
     150        setCmd.m_output = col; 
     151        setCmd.m_value = (uint32_t)val; 
     152        if (!m_ParentDevice.doEfcOverAVC(setCmd))  
     153        { 
     154            debugError("Cmd failed\n"); 
     155        } 
     156        // update the session block 
     157        if(setCmd.m_value) { 
     158            m_ParentDevice.m_session.s.monitorflags[row][col] |= ECHO_SESSION_SOLO_BIT; 
     159        } else { 
     160            m_ParentDevice.m_session.s.monitorflags[row][col] &= ~ECHO_SESSION_SOLO_BIT; 
     161        } 
     162        retval = setCmd.m_value; 
     163        did_command = true; 
    146164    } 
    147165 
     
    160178    bool did_command=false; 
    161179 
    162     if(row >= (int)m_Parent.getHwInfo().m_nb_phys_audio_in) { 
     180    if(row >= (int)m_ParentDevice.getHwInfo().m_nb_phys_audio_in) { 
    163181        debugError("specified row (%u) larger than number of rows (%d)\n", 
    164             row, m_Parent.getHwInfo().m_nb_phys_audio_in); 
     182            row, m_ParentDevice.getHwInfo().m_nb_phys_audio_in); 
    165183        return 0.0; 
    166184    } 
    167     if(col >= (int)m_Parent.getHwInfo().m_nb_phys_audio_out) { 
     185    if(col >= (int)m_ParentDevice.getHwInfo().m_nb_phys_audio_out) { 
    168186        debugError("specified col (%u) larger than number of cols (%d)\n", 
    169             col, m_Parent.getHwInfo().m_nb_phys_audio_out); 
     187            col, m_ParentDevice.getHwInfo().m_nb_phys_audio_out); 
    170188        return 0.0; 
    171189    } 
     
    175193        getCmd.m_input=row; 
    176194        getCmd.m_output=col; 
    177         if (!m_Parent.doEfcOverAVC(getCmd))  
    178         { 
    179             debugFatal("Cmd failed\n"); 
     195        if (!m_ParentDevice.doEfcOverAVC(getCmd))  
     196        { 
     197            debugError("Cmd failed\n"); 
    180198        } 
    181199        retval=getCmd.m_value; 
     
    186204        getCmd.m_input=row; 
    187205        getCmd.m_output=col; 
    188         if (!m_Parent.doEfcOverAVC(getCmd))  
    189         { 
    190             debugFatal("Cmd failed\n"); 
     206        if (!m_ParentDevice.doEfcOverAVC(getCmd))  
     207        { 
     208            debugError("Cmd failed\n"); 
    191209        } 
    192210        retval=getCmd.m_value; 
     
    197215        getCmd.m_input=row; 
    198216        getCmd.m_output=col; 
    199         if (!m_Parent.doEfcOverAVC(getCmd))  
    200         { 
    201             debugFatal("Cmd failed\n"); 
     217        if (!m_ParentDevice.doEfcOverAVC(getCmd))  
     218        { 
     219            debugError("Cmd failed\n"); 
    202220        } 
    203221        retval=getCmd.m_value; 
     
    208226        getCmd.m_input=row; 
    209227        getCmd.m_output=col; 
    210         if (!m_Parent.doEfcOverAVC(getCmd))  
    211         { 
    212             debugFatal("Cmd failed\n"); 
     228        if (!m_ParentDevice.doEfcOverAVC(getCmd))  
     229        { 
     230            debugError("Cmd failed\n"); 
    213231        } 
    214232        retval=getCmd.m_value; 
     
    227245int MonitorControl::getRowCount( ) 
    228246{ 
    229     return m_Parent.getHwInfo().m_nb_phys_audio_in; 
     247    return m_ParentDevice.getHwInfo().m_nb_phys_audio_in; 
    230248} 
    231249 
    232250int MonitorControl::getColCount( ) 
    233251{ 
    234     return m_Parent.getHwInfo().m_nb_phys_audio_out; 
     252    return m_ParentDevice.getHwInfo().m_nb_phys_audio_out; 
    235253} 
    236254 
     
    243261: Control::Continuous(&p, "SimpleControl") 
    244262, m_Slave(new EfcGenericMixerCmd(t, c, channel)) 
    245 , m_Parent(p) 
     263, m_ParentDevice(p) 
    246264{ 
    247265} 
     
    254272: Control::Continuous(&p, n) 
    255273, m_Slave(new EfcGenericMixerCmd(t, c, channel)) 
    256 , m_Parent(p) 
     274, m_ParentDevice(p) 
    257275{ 
    258276} 
     
    273291    if(m_Slave) { 
    274292        m_Slave->setType(eCT_Set); 
    275         m_Slave->m_value=(uint32_t)val; 
    276         if (!m_Parent.doEfcOverAVC(*m_Slave))  
    277         { 
    278             debugFatal("Cmd failed\n"); 
     293        m_Slave->m_value = (uint32_t)val; 
     294        if (!m_ParentDevice.doEfcOverAVC(*m_Slave))  
     295        { 
     296            debugError("Cmd failed\n"); 
    279297            return 0.0; 
     298        } 
     299 
     300        // update the session block 
     301        switch(m_Slave->getTarget()) { 
     302        case eMT_PlaybackMix: 
     303            switch(m_Slave->getCommand()) { 
     304            case eMC_Gain: 
     305                m_ParentDevice.m_session.h.playbackgains[m_Slave->m_channel] = m_Slave->m_value; 
     306                break; 
     307            default: // nothing 
     308                break; 
     309            } 
     310            break; 
     311        case eMT_PhysicalOutputMix: 
     312            switch(m_Slave->getCommand()) { 
     313            case eMC_Gain: 
     314                m_ParentDevice.m_session.h.outputgains[m_Slave->m_channel] = m_Slave->m_value; 
     315                break; 
     316            default: // nothing 
     317                break; 
     318            } 
     319            break; 
     320        default: // nothing 
     321            break; 
    280322        } 
    281323        debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for channel %d to %lf = %lf\n",  
     
    292334    if(m_Slave) { 
    293335        m_Slave->setType(eCT_Get); 
    294         if (!m_Parent.doEfcOverAVC(*m_Slave))  
    295         { 
    296             debugFatal("Cmd failed\n"); 
     336        if (!m_ParentDevice.doEfcOverAVC(*m_Slave))  
     337        { 
     338            debugError("Cmd failed\n"); 
    297339            return 0.0; 
    298340        } 
     
    315357, m_bit(bit) 
    316358, m_Slave(new EfcGenericMixerCmd(t, c, channel)) 
    317 , m_Parent(p) 
     359, m_ParentDevice(p) 
    318360{ 
    319361} 
     
    327369, m_bit(bit) 
    328370, m_Slave(new EfcGenericMixerCmd(t, c, channel)) 
    329 , m_Parent(p) 
     371, m_ParentDevice(p) 
    330372{ 
    331373} 
     
    361403        m_Slave->setType(eCT_Set); 
    362404        m_Slave->m_value=reg; 
    363         if (!m_Parent.doEfcOverAVC(*m_Slave))  
    364         { 
    365             debugFatal("Cmd failed\n"); 
     405        if (!m_ParentDevice.doEfcOverAVC(*m_Slave))  
     406        { 
     407            debugError("Cmd failed\n"); 
    366408            return 0; 
    367409        } 
     410 
     411        // update the session block 
     412        switch(m_Slave->getTarget()) { 
     413        case eMT_PlaybackMix: 
     414            switch(m_Slave->getCommand()) { 
     415            case eMC_Mute: 
     416                m_ParentDevice.m_session.s.playbacks[m_Slave->m_channel].mute = m_Slave->m_value; 
     417                break; 
     418            case eMC_Solo: 
     419                m_ParentDevice.m_session.s.playbacks[m_Slave->m_channel].solo = m_Slave->m_value; 
     420                break; 
     421            default: // nothing 
     422                break; 
     423            } 
     424            break; 
     425        case eMT_PhysicalOutputMix: 
     426            switch(m_Slave->getCommand()) { 
     427            case eMC_Mute: 
     428                m_ParentDevice.m_session.s.outputs[m_Slave->m_channel].mute = m_Slave->m_value; 
     429                break; 
     430            case eMC_Nominal: 
     431                m_ParentDevice.m_session.s.outputs[m_Slave->m_channel].shift = m_Slave->m_value; 
     432                break; 
     433            default: // nothing 
     434                break; 
     435            } 
     436            break; 
     437        case eMT_PhysicalInputMix: 
     438            switch(m_Slave->getCommand()) { 
     439            //case eMC_Pad: 
     440            //    m_ParentDevice.m_session.s.inputs[m_Slave->m_channel].pad = m_Slave->m_value; 
     441            //    break; 
     442            case eMC_Nominal: 
     443                m_ParentDevice.m_session.s.inputs[m_Slave->m_channel].shift = m_Slave->m_value; 
     444                break; 
     445            default: // nothing 
     446                break; 
     447            } 
     448            break; 
     449        default: // nothing 
     450            break; 
     451        } 
     452 
    368453        debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for channel %d to %ld (reg: 0x%08X => 0x%08X)\n",  
    369454                                            m_Slave->m_channel, val, old_reg, reg); 
     
    378463{ 
    379464    if(m_Slave) { 
     465        // workaround for the failing get nominal command for input channels 
     466        // get it from the session block 
     467        if ((m_Slave->getTarget() == eMT_PhysicalInputMix) 
     468            && (m_Slave->getCommand() == eMC_Nominal)) { 
     469            int val = m_ParentDevice.m_session.s.inputs[m_Slave->m_channel].shift; 
     470            debugOutput(DEBUG_LEVEL_VERBOSE, "input pad workaround: %08X\n", val); 
     471            return val; 
     472        } 
    380473        m_Slave->setType(eCT_Get); 
    381         if (!m_Parent.doEfcOverAVC(*m_Slave))  
    382         { 
    383             debugFatal("Cmd failed\n"); 
     474        if (!m_ParentDevice.doEfcOverAVC(*m_Slave))  
     475        { 
     476            debugError("Cmd failed\n"); 
    384477            return 0; 
    385478        } 
     
    394487} 
    395488 
     489// --- control element for flags 
     490 
     491SpdifModeControl::SpdifModeControl(FireWorks::Device& parent) 
     492: Control::Discrete(&parent, "SpdifModeControl") 
     493, m_ParentDevice(parent) 
     494{ 
     495} 
     496 
     497SpdifModeControl::SpdifModeControl(FireWorks::Device& parent, 
     498                                   std::string n) 
     499: Control::Discrete(&parent, n) 
     500, m_ParentDevice(parent) 
     501{ 
     502} 
     503 
     504SpdifModeControl::~SpdifModeControl() 
     505{ 
     506} 
     507 
     508void SpdifModeControl::show() 
     509{ 
     510    debugOutput(DEBUG_LEVEL_NORMAL, "SpdifModeControl\n"); 
     511} 
     512 
     513bool SpdifModeControl::setValue( const int val ) 
     514{ 
     515    EfcChangeFlagsCmd setCmd; 
     516    if(val) { 
     517        setCmd.m_setmask = FIREWORKS_EFC_FLAG_SPDIF_PRO; 
     518    } else { 
     519        setCmd.m_clearmask = FIREWORKS_EFC_FLAG_SPDIF_PRO; 
     520    } 
     521    debugOutput(DEBUG_LEVEL_VERBOSE, "setValue val: %d setmask: %08X, clear: %08X\n",  
     522                                      val, setCmd.m_setmask, setCmd.m_clearmask); 
     523    if (!m_ParentDevice.doEfcOverAVC(setCmd)) 
     524    { 
     525        debugError("Cmd failed\n"); 
     526        return false; 
     527    } 
     528    return true; 
     529} 
     530 
     531int SpdifModeControl::getValue( ) 
     532{ 
     533    EfcGetFlagsCmd getCmd; 
     534    if (!m_ParentDevice.doEfcOverAVC(getCmd)) 
     535    { 
     536        debugError("Cmd failed\n"); 
     537        return 0; 
     538    } 
     539    debugOutput(DEBUG_LEVEL_VERBOSE, "got flags: %08X\n",  
     540                                      getCmd.m_flags); 
     541    if(getCmd.m_flags & FIREWORKS_EFC_FLAG_SPDIF_PRO) return 1; 
     542    else return 0; 
     543} 
     544 
    396545// --- io config controls 
    397546 
     
    400549: Control::Discrete(&parent, "IOConfigControl") 
    401550, m_Slave(new EfcGenericIOConfigCmd(r)) 
    402 , m_Parent(parent) 
     551, m_ParentDevice(parent) 
    403552{ 
    404553} 
     
    409558: Control::Discrete(&parent, n) 
    410559, m_Slave(new EfcGenericIOConfigCmd(r)) 
    411 , m_Parent(parent) 
     560, m_ParentDevice(parent) 
    412561{ 
    413562} 
     
    429578        m_Slave->setType(eCT_Set); 
    430579        m_Slave->m_value=val; 
    431         if (!m_Parent.doEfcOverAVC(*m_Slave))  
    432         { 
    433             debugFatal("Cmd failed\n"); 
     580        if (!m_ParentDevice.doEfcOverAVC(*m_Slave))  
     581        { 
     582            debugError("Cmd failed\n"); 
    434583            return 0; 
    435584        } 
     
    446595    if(m_Slave) { 
    447596        m_Slave->setType(eCT_Get); 
    448         if (!m_Parent.doEfcOverAVC(*m_Slave))  
    449         { 
    450             debugFatal("Cmd failed\n"); 
     597        if (!m_ParentDevice.doEfcOverAVC(*m_Slave))  
     598        { 
     599            debugError("Cmd failed\n"); 
    451600            return 0; 
    452601        } 
     
    460609} 
    461610 
    462  
     611// control to get hardware information 
     612HwInfoControl::HwInfoControl(FireWorks::Device& p, 
     613                             enum eHwInfoField f) 
     614: Control::Discrete(&p, "HwInfoControl") 
     615, m_ParentDevice(p) 
     616, m_Field(f) 
     617
     618
     619 
     620HwInfoControl::HwInfoControl(FireWorks::Device& p, 
     621                             enum eHwInfoField f, 
     622                             std::string n) 
     623: Control::Discrete(&p, n) 
     624, m_ParentDevice(p) 
     625, m_Field(f) 
     626
     627
     628 
     629HwInfoControl::~HwInfoControl() 
     630
     631
     632 
     633int HwInfoControl::getValue() 
     634
     635    switch (m_Field) { 
     636        case eHIF_PhysicalAudioOutCount: 
     637            return m_ParentDevice.getHwInfo().m_nb_phys_audio_out; 
     638        case eHIF_PhysicalAudioInCount: 
     639            return m_ParentDevice.getHwInfo().m_nb_phys_audio_in; 
     640        case eHIF_1394PlaybackCount: 
     641            return m_ParentDevice.getHwInfo().m_nb_1394_playback_channels; 
     642        case eHIF_1394RecordCount: 
     643            return m_ParentDevice.getHwInfo().m_nb_1394_record_channels; 
     644        case eHIF_GroupOutCount: 
     645            return m_ParentDevice.getHwInfo().m_nb_out_groups; 
     646        case eHIF_GroupInCount: 
     647            return m_ParentDevice.getHwInfo().m_nb_in_groups; 
     648        case eHIF_PhantomPower: 
     649            return m_ParentDevice.getHwInfo().hasSoftwarePhantom(); 
     650        default: 
     651            debugError("Bogus field\n"); 
     652            return 0; 
     653    } 
     654
     655 
     656void HwInfoControl::show() 
     657
     658    debugOutput(DEBUG_LEVEL_NORMAL, "HwInfoControl\n"); 
     659
     660 
     661 
     662// control to save settings 
     663MultiControl::MultiControl(FireWorks::Device& p, enum eType t) 
     664: Control::Discrete(&p, "MultiControl") 
     665, m_ParentDevice(p) 
     666, m_Type(t) 
     667
     668
     669 
     670MultiControl::MultiControl(FireWorks::Device& p, 
     671                           enum eType t, std::string n) 
     672: Control::Discrete(&p, n) 
     673, m_ParentDevice(p) 
     674, m_Type(t) 
     675
     676
     677 
     678MultiControl::~MultiControl() 
     679
     680
     681 
     682bool MultiControl::setValue(const int v) 
     683
     684    switch(m_Type) { 
     685    case eT_SaveSession: 
     686        debugOutput(DEBUG_LEVEL_VERBOSE, "saving session\n"); 
     687        return m_ParentDevice.saveSession(); 
     688    case eT_Identify: 
     689        debugOutput(DEBUG_LEVEL_VERBOSE, "indentify device\n"); 
     690        { 
     691            EfcIdentifyCmd cmd; 
     692            if (!m_ParentDevice.doEfcOverAVC(cmd))  
     693            { 
     694                debugError("Cmd failed\n"); 
     695                return false; 
     696            } 
     697        } 
     698        return true; 
     699    default: 
     700        debugError("Bad type\n"); 
     701        return false; 
     702    } 
     703
     704 
     705void MultiControl::show() 
     706
     707    debugOutput(DEBUG_LEVEL_NORMAL, "MultiControl\n"); 
     708    switch(m_Type) { 
     709    case eT_SaveSession: 
     710        debugOutput(DEBUG_LEVEL_NORMAL, "Type: SaveSession\n"); 
     711        break; 
     712    case eT_Identify: 
     713        debugOutput(DEBUG_LEVEL_NORMAL, "Type: Identify\n"); 
     714        break; 
     715    default: 
     716        debugError("Bad type\n"); 
     717    } 
     718
    463719 
    464720} // FireWorks 
  • trunk/libffado/src/fireworks/fireworks_control.h

    r1324 r1336  
    7171protected: 
    7272    enum eMonitorControl        m_control; 
    73     FireWorks::Device&          m_Parent
     73    FireWorks::Device&          m_ParentDevice
    7474}; 
    7575 
     
    101101protected: 
    102102    EfcGenericMixerCmd*         m_Slave; 
    103     FireWorks::Device&          m_Parent
     103    FireWorks::Device&          m_ParentDevice
    104104}; 
    105105 
     
    132132    int                         m_bit; 
    133133    EfcGenericMixerCmd*         m_Slave; 
    134     FireWorks::Device&          m_Parent; 
    135 }; 
     134    FireWorks::Device&          m_ParentDevice; 
     135}; 
     136 
     137class SpdifModeControl : public Control::Discrete 
     138
     139 
     140public: 
     141    SpdifModeControl(FireWorks::Device& parent); 
     142    SpdifModeControl(FireWorks::Device& parent, 
     143                    std::string n); 
     144    virtual ~SpdifModeControl(); 
     145 
     146    virtual void show(); 
     147 
     148    virtual bool setValue( const int ); 
     149    virtual int getValue( ); 
     150    virtual bool setValue(int idx, int v) 
     151        {return setValue(v);}; 
     152    virtual int getValue(int idx) 
     153        {return getValue();}; 
     154 
     155    virtual int getMinimum() {return 0;}; 
     156    virtual int getMaximum() {return 0;}; 
     157 
     158protected: 
     159    FireWorks::Device&          m_ParentDevice; 
     160}; 
     161 
    136162 
    137163// for on-off type of controls 
     
    163189    int                         m_bit; 
    164190    EfcGenericIOConfigCmd*      m_Slave; 
    165     FireWorks::Device&          m_Parent; 
     191    FireWorks::Device&          m_ParentDevice; 
     192}; 
     193 
     194 
     195class HwInfoControl : public Control::Discrete 
     196
     197public: 
     198 
     199    enum eHwInfoField { 
     200        eHIF_PhysicalAudioOutCount, 
     201        eHIF_PhysicalAudioInCount, 
     202        eHIF_1394PlaybackCount, 
     203        eHIF_1394RecordCount, 
     204        eHIF_GroupOutCount, 
     205        eHIF_GroupInCount, 
     206        eHIF_PhantomPower, 
     207    }; 
     208public: 
     209    HwInfoControl(FireWorks::Device& parent, 
     210                  enum eHwInfoField); 
     211    HwInfoControl(FireWorks::Device& parent, 
     212                  enum eHwInfoField, std::string n); 
     213    virtual ~HwInfoControl(); 
     214 
     215    virtual void show(); 
     216 
     217    virtual bool setValue( const int ) {return false;}; 
     218    virtual int getValue( ); 
     219    virtual bool setValue(int idx, int v) 
     220        {return setValue(v);}; 
     221    virtual int getValue(int idx) 
     222        {return getValue();}; 
     223 
     224    virtual int getMinimum() {return 0;}; 
     225    virtual int getMaximum() {return 0;}; 
     226 
     227protected: 
     228    FireWorks::Device&          m_ParentDevice; 
     229    enum eHwInfoField           m_Field; 
     230}; 
     231 
     232class MultiControl : public Control::Discrete 
     233
     234public: 
     235 
     236    enum eType { 
     237        eT_SaveSession, 
     238        eT_Identify, 
     239    }; 
     240public: 
     241    MultiControl(FireWorks::Device& parent, enum eType); 
     242    MultiControl(FireWorks::Device& parent, enum eType, 
     243                        std::string n); 
     244    virtual ~MultiControl(); 
     245 
     246    virtual void show(); 
     247 
     248    virtual bool setValue( const int ); 
     249    virtual int getValue( ) {return 0;}; 
     250    virtual bool setValue(int idx, int v) 
     251        {return setValue(v);}; 
     252    virtual int getValue(int idx) 
     253        {return getValue();}; 
     254 
     255    virtual int getMinimum() {return 0;}; 
     256    virtual int getMaximum() {return 0;}; 
     257 
     258protected: 
     259    FireWorks::Device&  m_ParentDevice; 
     260    enum eType          m_Type; 
    166261}; 
    167262 
  • trunk/libffado/src/fireworks/fireworks_device.cpp

    r1254 r1336  
    2222 */ 
    2323 
    24 #include "config.h" 
    25  
     24// #include "config.h" 
     25#include "devicemanager.h" 
    2626#include "fireworks_device.h" 
    2727#include "efc/efc_avc_cmd.h" 
     
    4040#include "libutil/PosixMutex.h" 
    4141 
     42#include "IntelFlashMap.h" 
     43 
     44#define ECHO_FLASH_ERASE_TIMEOUT_MILLISECS 2000 
     45 
    4246#include <sstream> 
    4347using namespace std; 
     
    4852Device::Device(DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )) 
    4953    : GenericAVC::AvDevice( d, configRom) 
    50     , m_poll_lock( new Util::PosixMutex() ) 
     54    , m_poll_lock( new Util::PosixMutex("DEVPOLL") ) 
    5155    , m_efc_discovery_done ( false ) 
    5256    , m_MixerContainer ( NULL ) 
     57    , m_HwInfoContainer ( NULL ) 
    5358{ 
    5459    debugOutput( DEBUG_LEVEL_VERBOSE, "Created FireWorks::Device (NodeID %d)\n", 
     
    7580 
    7681bool 
    77 Device::probe( ConfigRom& configRom, bool generic ) 
     82Device::probe( Util::Configuration& c, ConfigRom& configRom, bool generic ) 
    7883{ 
    7984    if(generic) { 
     
    106111        unsigned int vendorId = configRom.getNodeVendorId(); 
    107112        unsigned int modelId = configRom.getModelId(); 
    108  
    109         GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_fireworks.txt" ); 
    110         if ( vendorModel.parse() ) { 
    111             return vendorModel.isPresent( vendorId, modelId ); 
    112         } 
    113         return false; 
     113        Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId ); 
     114        return c.isValid(vme) && vme.driver == Util::Configuration::eD_FireWorks; 
    114115    } 
    115116} 
     
    121122    unsigned int modelId = getConfigRom().getModelId(); 
    122123 
    123     GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_fireworks.txt" ); 
    124     if ( vendorModel.parse() ) { 
    125         m_model = vendorModel.find( vendorId, modelId ); 
    126     } 
    127  
    128     if (!GenericAVC::VendorModel::isValid(m_model)) { 
     124    Util::Configuration &c = getDeviceManager().getConfiguration(); 
     125    Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId ); 
     126 
     127    if (c.isValid(vme) && vme.driver == Util::Configuration::eD_FireWorks) { 
     128        debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", 
     129                     vme.vendor_name.c_str(), 
     130                     vme.model_name.c_str()); 
     131    } else { 
    129132        debugWarning("Using generic ECHO Audio FireWorks support for unsupported device '%s %s'\n", 
    130             getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str()); 
    131     } else { 
    132         debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", 
    133                 m_model.vendor_name.c_str(), m_model.model_name.c_str()); 
     133                     getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str()); 
    134134    } 
    135135 
     
    141141 
    142142    // discover AVC-wise 
    143     if ( !GenericAVC::AvDevice::discover() ) { 
     143    if ( !GenericAVC::AvDevice::discoverGeneric() ) { 
    144144        debugError( "Could not discover GenericAVC::AvDevice\n" ); 
    145145        return false; 
     
    259259        result &= m_MixerContainer->addElement( 
    260260            new BinaryControl(*this, eMT_PlaybackMix, eMC_Mute, ch, 0, node_name.str()+"Mute")); 
     261        result &= m_MixerContainer->addElement( 
     262            new BinaryControl(*this, eMT_PlaybackMix, eMC_Solo, ch, 0, node_name.str()+"Solo")); 
    261263        result &= m_MixerContainer->addElement( 
    262264            new SimpleControl(*this, eMT_PlaybackMix, eMC_Gain, ch, node_name.str()+"Gain")); 
     
    276278    } 
    277279     
     280    // Physical input mix controls 
     281    for (unsigned int ch=0;ch<m_HwInfo.m_nb_phys_audio_in;ch++) { 
     282        std::ostringstream node_name; 
     283        node_name << "IN" << ch; 
     284         
     285        // result &= m_MixerContainer->addElement( 
     286        //     new BinaryControl(*this, eMT_PhysicalInputMix, eMC_Pad, ch, 0, node_name.str()+"Pad")); 
     287        result &= m_MixerContainer->addElement( 
     288            new BinaryControl(*this, eMT_PhysicalInputMix, eMC_Nominal, ch, 1, node_name.str()+"Nominal")); 
     289    } 
     290 
     291    // add hardware information controls 
     292    m_HwInfoContainer = new Control::Container(this, "HwInfo"); 
     293    result &= m_HwInfoContainer->addElement( 
     294        new HwInfoControl(*this, HwInfoControl::eHIF_PhysicalAudioOutCount, "PhysicalAudioOutCount")); 
     295    result &= m_HwInfoContainer->addElement( 
     296        new HwInfoControl(*this, HwInfoControl::eHIF_PhysicalAudioInCount, "PhysicalAudioInCount")); 
     297    result &= m_HwInfoContainer->addElement( 
     298        new HwInfoControl(*this, HwInfoControl::eHIF_1394PlaybackCount, "1394PlaybackCount")); 
     299    result &= m_HwInfoContainer->addElement( 
     300        new HwInfoControl(*this, HwInfoControl::eHIF_1394RecordCount, "1394RecordCount")); 
     301    result &= m_HwInfoContainer->addElement( 
     302        new HwInfoControl(*this, HwInfoControl::eHIF_GroupOutCount, "GroupOutCount")); 
     303    result &= m_HwInfoContainer->addElement( 
     304        new HwInfoControl(*this, HwInfoControl::eHIF_GroupInCount, "GroupInCount")); 
     305    result &= m_HwInfoContainer->addElement( 
     306        new HwInfoControl(*this, HwInfoControl::eHIF_PhantomPower, "PhantomPower")); 
     307 
     308    // add a save settings control 
     309    result &= this->addElement( 
     310        new MultiControl(*this, MultiControl::eT_SaveSession, "SaveSettings")); 
     311 
     312    // add an identify control 
     313    result &= this->addElement( 
     314        new MultiControl(*this, MultiControl::eT_Identify, "Identify")); 
     315 
     316    // spdif mode control 
     317    result &= this->addElement( 
     318        new SpdifModeControl(*this, "SpdifMode")); 
     319 
    278320    // check for IO config controls and add them if necessary 
    279321    if(m_HwInfo.hasMirroring()) { 
    280         result &= m_MixerContainer->addElement( 
     322        result &= this->addElement( 
    281323            new IOConfigControl(*this, eCR_Mirror, "ChannelMirror")); 
    282324    } 
    283325    if(m_HwInfo.hasSoftwarePhantom()) { 
    284         result &= m_MixerContainer->addElement( 
     326        result &= this->addElement( 
    285327            new IOConfigControl(*this, eCR_Phantom, "PhantomPower")); 
    286328    } 
     
    300342    } 
    301343 
     344    if (!addElement(m_HwInfoContainer)) { 
     345        debugWarning("Could not register hwinfo to device\n"); 
     346        // clean up 
     347        destroyMixer(); 
     348        return false; 
     349    } 
     350 
     351    // load the session block 
     352    if (!loadSession()) { 
     353        debugWarning("Could not load session\n"); 
     354    } 
     355 
    302356    return true; 
    303357} 
     
    310364    if (m_MixerContainer == NULL) { 
    311365        debugOutput(DEBUG_LEVEL_VERBOSE, "no mixer to destroy...\n"); 
    312         return true; 
    313     } 
    314  
    315     if (!deleteElement(m_MixerContainer)) { 
    316         debugError("Mixer present but not registered to the avdevice\n"); 
    317         return false; 
    318     } 
    319  
    320     // remove and delete (as in free) child control elements 
    321     m_MixerContainer->clearElements(true); 
    322     delete m_MixerContainer; 
    323     return true; 
    324 
    325  
     366    } else { 
     367        if (!deleteElement(m_MixerContainer)) { 
     368            debugError("Mixer present but not registered to the avdevice\n"); 
     369            return false; 
     370        } 
     371 
     372        // remove and delete (as in free) child control elements 
     373        m_MixerContainer->clearElements(true); 
     374        delete m_MixerContainer; 
     375        m_MixerContainer = NULL; 
     376    } 
     377 
     378    if (m_HwInfoContainer == NULL) { 
     379        debugOutput(DEBUG_LEVEL_VERBOSE, "no hwinfo to destroy...\n"); 
     380    } else { 
     381        if (!deleteElement(m_HwInfoContainer)) { 
     382            debugError("HwInfo present but not registered to the avdevice\n"); 
     383            return false; 
     384        } 
     385 
     386        // remove and delete (as in free) child control elements 
     387        m_HwInfoContainer->clearElements(true); 
     388        delete m_HwInfoContainer; 
     389        m_HwInfoContainer = NULL; 
     390    } 
     391    return true; 
     392
     393 
     394bool 
     395Device::saveSession() 
     396
     397    // save the session block 
     398//     if ( !updateSession() ) { 
     399//         debugError( "Could not update session\n" ); 
     400//     } else { 
     401        if ( !m_session.saveToDevice(*this) ) { 
     402            debugError( "Could not save session block\n" ); 
     403        } 
     404//     } 
     405 
     406    return true; 
     407
     408 
     409bool 
     410Device::loadSession() 
     411
     412    if ( !m_session.loadFromDevice(*this) ) { 
     413        debugError( "Could not load session block\n" ); 
     414        return false; 
     415    } 
     416    return true; 
     417
    326418 
    327419bool 
     
    329421    Util::MutexLockHelper lock(*m_poll_lock); 
    330422    return doEfcOverAVC(m_Polled); 
     423} 
     424 
     425#define ECHO_CHECK_AND_ADD_SR(v, x) \ 
     426    { if(x >= m_HwInfo.m_min_sample_rate && x <= m_HwInfo.m_max_sample_rate) \ 
     427      v.push_back(x); } 
     428std::vector<int> 
     429Device::getSupportedSamplingFrequencies() 
     430{ 
     431    std::vector<int> frequencies; 
     432    ECHO_CHECK_AND_ADD_SR(frequencies, 22050); 
     433    ECHO_CHECK_AND_ADD_SR(frequencies, 24000); 
     434    ECHO_CHECK_AND_ADD_SR(frequencies, 32000); 
     435    ECHO_CHECK_AND_ADD_SR(frequencies, 44100); 
     436    ECHO_CHECK_AND_ADD_SR(frequencies, 48000); 
     437    ECHO_CHECK_AND_ADD_SR(frequencies, 88200); 
     438    ECHO_CHECK_AND_ADD_SR(frequencies, 96000); 
     439    ECHO_CHECK_AND_ADD_SR(frequencies, 176400); 
     440    ECHO_CHECK_AND_ADD_SR(frequencies, 192000); 
     441    return frequencies; 
    331442} 
    332443 
     
    528639bool 
    529640Device::lockFlash(bool lock) { 
     641    // some hardware doesn't need/support flash lock 
     642    if (m_HwInfo.hasDSP()) { 
     643        debugOutput(DEBUG_LEVEL_VERBOSE, "flash lock not needed\n"); 
     644        return true; 
     645    } 
     646 
    530647    EfcFlashLockCmd cmd; 
    531648    cmd.m_lock = lock; 
     
    649766 
    650767bool 
     768Device::eraseFlashBlocks(uint32_t start_address, unsigned int nb_quads) 
     769{ 
     770    uint32_t blocksize_bytes; 
     771    uint32_t blocksize_quads; 
     772    unsigned int quads_left = nb_quads; 
     773    bool success = true; 
     774 
     775    const unsigned int max_nb_tries = 10; 
     776    unsigned int nb_tries = 0; 
     777 
     778    do { 
     779        // the erase block size is fixed by the HW, and depends 
     780        // on the flash section we're in 
     781        if (start_address < MAINBLOCKS_BASE_OFFSET_BYTES) 
     782                blocksize_bytes = PROGRAMBLOCK_SIZE_BYTES; 
     783        else 
     784                blocksize_bytes = MAINBLOCK_SIZE_BYTES; 
     785        start_address &= ~(blocksize_bytes - 1); 
     786        blocksize_quads = blocksize_bytes / 4; 
     787 
     788        uint32_t verify[blocksize_quads]; 
     789 
     790        // corner case: requested to erase less than one block 
     791        if (blocksize_quads > quads_left) { 
     792            blocksize_quads = quads_left; 
     793        } 
     794 
     795        // do the actual erase 
     796        if (!eraseFlash(start_address)) { 
     797            debugWarning("Could not erase flash block at 0x%08X\n", start_address); 
     798            success = false; 
     799        } else { 
     800            // wait for the flash to become ready again 
     801            if (!waitForFlash(ECHO_FLASH_ERASE_TIMEOUT_MILLISECS)) { 
     802                debugError("Wait for flash timed out at address 0x%08X\n", start_address); 
     803                return false; 
     804            } 
     805 
     806            // verify that the block is empty as an extra precaution 
     807            if (!readFlash(start_address, blocksize_quads, verify)) { 
     808                debugError("Could not read flash block at 0x%08X\n", start_address); 
     809                return false; 
     810            } 
     811 
     812            // everything should be 0xFFFFFFFF if the erase was successful 
     813            for (unsigned int i = 0; i < blocksize_quads; i++) { 
     814                if (0xFFFFFFFF != verify[i]) { 
     815                    debugWarning("Flash erase verification failed.\n"); 
     816                    success = false; 
     817                    break; 
     818                } 
     819            } 
     820        } 
     821 
     822        if (success) { 
     823            start_address += blocksize_bytes; 
     824            quads_left -= blocksize_quads; 
     825            nb_tries = 0; 
     826        } else { 
     827            nb_tries++; 
     828        } 
     829        if (nb_tries > max_nb_tries) { 
     830            debugError("Needed too many tries to erase flash at 0x%08X\n", start_address); 
     831            return false; 
     832        } 
     833    } while (quads_left > 0); 
     834 
     835    return true; 
     836} 
     837 
     838bool 
    651839Device::waitForFlash(unsigned int msecs) 
    652840{ 
     
    678866} 
    679867 
     868uint32_t 
     869Device::getSessionBase() 
     870{ 
     871    EfcFlashGetSessionBaseCmd cmd; 
     872    if(!doEfcOverAVC(cmd)) { 
     873        debugError("Could not get session base address\n"); 
     874        return 0; // FIXME: arbitrary 
     875    } 
     876    return cmd.m_address; 
     877} 
     878 
    680879} // FireWorks 
  • trunk/libffado/src/fireworks/fireworks_device.h

    r1239 r1336  
    3232#include "efc/efc_cmd.h" 
    3333#include "efc/efc_cmds_hardware.h" 
     34#include "fireworks_session_block.h" 
    3435 
    3536#include <pthread.h> 
     
    4243 
    4344class Device : public GenericAVC::AvDevice { 
     45    friend class MonitorControl; 
     46    friend class SimpleControl; 
     47    friend class BinaryControl; 
     48    friend class IOConfigControl; 
     49     
    4450public: 
    4551    Device( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ) ); 
    4652    virtual ~Device(); 
    4753     
    48     static bool probe( ConfigRom& configRom, bool generic = false ); 
     54    static bool probe( Util::Configuration&, ConfigRom& configRom, bool generic = false ); 
    4955    static FFADODevice * createDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )); 
    5056    virtual bool discover(); 
     
    5460    virtual bool buildMixer(); 
    5561    virtual bool destroyMixer(); 
     62 
     63    virtual std::vector<int> getSupportedSamplingFrequencies(); 
    5664 
    5765    virtual ClockSourceVector getSupportedClockSources(); 
     
    95103     */ 
    96104    bool eraseFlash(uint32_t addr); 
     105    bool eraseFlashBlocks(uint32_t start_address, unsigned int nb_quads); 
    97106 
    98107    /** 
     
    102111     */ 
    103112    bool waitForFlash(unsigned int msecs); 
     113 
     114    /** 
     115     * @brief get the flash address of the session block 
     116     * @return session block base address 
     117     */ 
     118    uint32_t getSessionBase(); 
     119 
     120    /** 
     121     * load the session block from the device 
     122     * @return true if successful 
     123     */ 
     124    bool loadSession(); 
     125    /** 
     126     * save the session block to the device 
     127     * @return true if successful 
     128     */ 
     129    bool saveSession(); 
    104130 
    105131// Echo specific stuff 
     
    123149    bool                m_efc_discovery_done; 
    124150 
     151protected: 
     152    Session             m_session; 
    125153private: 
    126154    Control::Container *m_MixerContainer; 
     155    Control::Container *m_HwInfoContainer; 
    127156 
    128157}; 
  • trunk/libffado/src/fireworks/fireworks_firmware.cpp

    r1234 r1336  
    3737#include <cstring> 
    3838 
    39 #define ECHO_FLASH_ERASE_TIMEOUT_MILLISECS 2000 
    40  
    4139#define DAT_EXTENSION "dat" 
    4240 
    4341// device id's 
    44 #define AUDIOFIRE2                     0x000af2 
    45 #define AUDIOFIRE4                     0x000af4 
    46 #define AUDIOFIRE8                     0x000af8 
    47 #define AUDIOFIRE12                    0x00af12 
    48 #define AUDIOFIRE12HD          0x0af12d 
    49 #define FWHDMI                         0x00afd1 
    50 #define ONYX400F                       0x00400f  
    51 #define ONYX1200F                      0x01200f 
    52 #define FIREWORKS8                     0x0000f8 
     42#define AUDIOFIRE2          0x000af2 
     43#define AUDIOFIRE4          0x000af4 
     44#define AUDIOFIRE8          0x000af8 
     45#define AUDIOFIRE12         0x00af12 
     46#define AUDIOFIRE12HD       0x0af12d 
     47#define FWHDMI              0x00afd1 
     48#define ONYX400F            0x00400f  
     49#define ONYX1200F           0x01200f 
     50#define FIREWORKS8          0x0000f8 
    5351 
    5452using namespace std; 
     
    418416const char *Af2Dats[] =  
    419417{ 
    420        "Fireworks3" 
     418    "Fireworks3" 
    421419}; 
    422420 
    423421const char *Af4Dats[] =  
    424422{ 
    425        "Fireworks3" 
     423    "Fireworks3" 
    426424}; 
    427425 
    428426const char *Af8Dats[] =  
    429427{ 
    430        "bootstrap", 
    431        "audiofire8", 
    432        "audiofire8_E", 
    433        "FireworksARM" 
     428    "bootstrap", 
     429    "audiofire8", 
     430    "audiofire8_E", 
     431    "FireworksARM" 
    434432}; 
    435433 
    436434const char *Af12Dats[] =  
    437435{ 
    438        "bootstrap", 
    439        "audiofire12", 
    440        "audiofire12_E", 
    441        "FireworksARM" 
     436    "bootstrap", 
     437    "audiofire12", 
     438    "audiofire12_E", 
     439    "FireworksARM" 
    442440}; 
    443441 
     
    448446    struct dat_list datlists[4] = 
    449447    { 
    450             { FW_VENDORID_ECHO, AUDIOFIRE2,    0x04010000, 1, Af2Dats }, 
    451             { FW_VENDORID_ECHO, AUDIOFIRE4,    0x04010000, 1, Af4Dats }, 
    452             { FW_VENDORID_ECHO, AUDIOFIRE8,    0x04010000, 4, Af8Dats }, 
    453             { FW_VENDORID_ECHO, AUDIOFIRE12,   0x04010000, 4, Af12Dats } 
     448            { FW_VENDORID_ECHO, AUDIOFIRE2,    0x04010000, 1, Af2Dats }, 
     449            { FW_VENDORID_ECHO, AUDIOFIRE4,    0x04010000, 1, Af4Dats }, 
     450            { FW_VENDORID_ECHO, AUDIOFIRE8,    0x04010000, 4, Af8Dats }, 
     451            { FW_VENDORID_ECHO, AUDIOFIRE12,    0x04010000, 4, Af12Dats } 
    454452    }; 
    455453 
     
    534532FirmwareUtil::eraseBlocks(uint32_t start_address, unsigned int nb_quads) 
    535533{ 
    536     uint32_t blocksize_bytes; 
    537     uint32_t blocksize_quads; 
    538     unsigned int quads_left = nb_quads; 
    539     bool success = true; 
    540  
    541     const unsigned int max_nb_tries = 10; 
    542     unsigned int nb_tries = 0; 
    543  
    544     do { 
    545         // the erase block size is fixed by the HW, and depends 
    546         // on the flash section we're in 
    547         if (start_address < MAINBLOCKS_BASE_OFFSET_BYTES) 
    548                 blocksize_bytes = PROGRAMBLOCK_SIZE_BYTES; 
    549         else 
    550                 blocksize_bytes = MAINBLOCK_SIZE_BYTES; 
    551         start_address &= ~(blocksize_bytes - 1); 
    552         blocksize_quads = blocksize_bytes / 4; 
    553  
    554         uint32_t verify[blocksize_quads]; 
    555  
    556         // corner case: requested to erase less than one block 
    557         if (blocksize_quads > quads_left) { 
    558             blocksize_quads = quads_left; 
    559         } 
    560  
    561         // do the actual erase 
    562         if (!m_Parent.eraseFlash(start_address)) { 
    563             debugWarning("Could not erase flash block at 0x%08X\n", start_address); 
    564             success = false; 
    565         } else { 
    566             // wait for the flash to become ready again 
    567             if (!m_Parent.waitForFlash(ECHO_FLASH_ERASE_TIMEOUT_MILLISECS)) { 
    568                 debugError("Wait for flash timed out at address 0x%08X\n", start_address); 
    569                 return false; 
    570             } 
    571  
    572             // verify that the block is empty as an extra precaution 
    573             if (!m_Parent.readFlash(start_address, blocksize_quads, verify)) { 
    574                 debugError("Could not read flash block at 0x%08X\n", start_address); 
    575                 return false; 
    576             } 
    577  
    578             // everything should be 0xFFFFFFFF if the erase was successful 
    579             for (unsigned int i = 0; i < blocksize_quads; i++) { 
    580                 if (0xFFFFFFFF != verify[i]) { 
    581                     debugWarning("Flash erase verification failed.\n"); 
    582                     success = false; 
    583                     break; 
    584                 } 
    585             } 
    586         } 
    587  
    588         if (success) { 
    589             start_address += blocksize_bytes; 
    590             quads_left -= blocksize_quads; 
    591             nb_tries = 0; 
    592         } else { 
    593             nb_tries++; 
    594         } 
    595         if (nb_tries > max_nb_tries) { 
    596             debugError("Needed too many tries to erase flash at 0x%08X\n", start_address); 
    597             return false; 
    598         } 
    599     } while (quads_left > 0); 
    600      
    601     return true; 
     534    return m_Parent.eraseFlashBlocks(start_address, nb_quads); 
    602535} 
    603536 
  • trunk/libffado/src/genericavc/avc_avdevice.cpp

    r1254 r1336  
    2323 */ 
    2424 
    25 #include "config.h" 
    26  
     25//#include "config.h" 
     26#include "devicemanager.h" 
    2727#include "genericavc/avc_avdevice.h" 
    2828 
     
    7777 
    7878bool 
    79 AvDevice::probe( ConfigRom& configRom, bool generic ) 
     79AvDevice::probe( Util::Configuration& c, ConfigRom& configRom, bool generic ) 
    8080{ 
    8181    if(generic) { 
     
    102102        unsigned int modelId = configRom.getModelId(); 
    103103 
    104         GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_genericavc.txt" ); 
    105         if ( vendorModel.parse() ) { 
    106             return vendorModel.isPresent( vendorId, modelId ); 
    107         } 
     104        Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId ); 
     105        return c.isValid(vme) && vme.driver == Util::Configuration::eD_GenericAVC; 
    108106        return false; 
    109107    } 
     
    120118{ 
    121119    Util::MutexLockHelper lock(m_DeviceMutex); 
    122     // check if we already have a valid VendorModel entry 
    123     // e.g. because a subclass called this function 
    124     if (!GenericAVC::VendorModel::isValid(m_model)) { 
    125         unsigned int vendorId = getConfigRom().getNodeVendorId(); 
    126         unsigned int modelId = getConfigRom().getModelId(); 
    127  
    128         GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_genericavc.txt" ); 
    129         if ( vendorModel.parse() ) { 
    130             m_model = vendorModel.find( vendorId, modelId ); 
    131         } 
    132  
    133         if (!GenericAVC::VendorModel::isValid(m_model)) { 
    134             debugWarning("Using generic AV/C support for unsupported device '%s %s'\n", 
    135                         getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str()); 
    136         } else { 
    137             debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", 
    138                     m_model.vendor_name.c_str(), m_model.model_name.c_str()); 
    139         } 
    140     } 
    141  
     120 
     121    unsigned int vendorId = getConfigRom().getNodeVendorId(); 
     122    unsigned int modelId = getConfigRom().getModelId(); 
     123 
     124    Util::Configuration &c = getDeviceManager().getConfiguration(); 
     125    Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId ); 
     126 
     127    if (c.isValid(vme) && vme.driver == Util::Configuration::eD_GenericAVC) { 
     128        debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", 
     129                     vme.vendor_name.c_str(), 
     130                     vme.model_name.c_str()); 
     131    } else { 
     132        debugWarning("Using generic AV/C support for unsupported device '%s %s'\n", 
     133                     getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str()); 
     134    } 
     135    return discoverGeneric(); 
     136
     137 
     138bool 
     139AvDevice::discoverGeneric() 
     140
    142141    if ( !Unit::discover() ) { 
    143142        debugError( "Could not discover unit\n" ); 
     
    153152        return false; 
    154153    } 
    155  
    156154    return true; 
    157155} 
     
    240238    return false; 
    241239 
     240} 
     241 
     242bool 
     243AvDevice::supportsSamplingFrequency( int s ) 
     244{ 
     245    Util::MutexLockHelper lock(m_DeviceMutex); 
     246 
     247    AVC::Plug* plug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 ); 
     248    if ( !plug ) { 
     249        debugError( "Could not retrieve iso input plug 0\n" ); 
     250        return false; 
     251    } 
     252 
     253    if ( !plug->supportsSampleRate( s ) ) 
     254    { 
     255        debugError( "sample rate not supported by input plug\n" ); 
     256        return false; 
     257    } 
     258 
     259    plug = getPlugById( m_pcrPlugs, Plug::eAPD_Output,  0 ); 
     260    if ( !plug ) { 
     261        debugError( "Could not retrieve iso output plug 0\n" ); 
     262        return false; 
     263    } 
     264 
     265    if ( !plug->supportsSampleRate( s ) ) 
     266    { 
     267        debugError( "sample rate not supported by output plug\n" ); 
     268        return false; 
     269    } 
     270    return true; 
     271} 
     272 
     273#define GENERICAVC_CHECK_AND_ADD_SR(v, x) \ 
     274    { if(supportsSamplingFrequency(x)) \ 
     275      v.push_back(x); } 
     276 
     277std::vector<int> 
     278AvDevice::getSupportedSamplingFrequencies() 
     279{ 
     280    if (m_supported_frequencies_cache.size() == 0) { 
     281        GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 22050); 
     282        GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 24000); 
     283        GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 32000); 
     284        GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 44100); 
     285        GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 48000); 
     286        GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 88200); 
     287        GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 96000); 
     288        GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 176400); 
     289        GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 192000); 
     290    } 
     291    return m_supported_frequencies_cache; 
    242292} 
    243293 
  • trunk/libffado/src/genericavc/avc_avdevice.h

    r1239 r1336  
    2727 
    2828#include "ffadodevice.h" 
    29 #include "genericavc/avc_vendormodel.h" 
     29#include "libutil/Configuration.h" 
    3030 
    3131#include "libavc/avc_definitions.h" 
     
    5050    AvDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )); 
    5151    virtual ~AvDevice(); 
    52      
    53     static bool probe( ConfigRom& configRom, bool generic = false ); 
     52 
     53    static bool probe( Util::Configuration&, ConfigRom& configRom, bool generic = false ); 
    5454    virtual bool discover(); 
     55    bool discoverGeneric(); 
    5556    static FFADODevice * createDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )); 
    5657 
     
    6263 
    6364    virtual bool setSamplingFrequency( int ); 
     65    virtual bool supportsSamplingFrequency( int s ); 
    6466    virtual int getSamplingFrequency( ); 
     67    virtual std::vector<int> getSupportedSamplingFrequencies(); 
    6568 
    6669    virtual ClockSourceVector getSupportedClockSources(); 
     
    9194                                   AVC::ESamplingFrequency samplingFrequency );*/ 
    9295 
    93     struct VendorModelEntry m_model; 
    94  
    9596    // streaming stuff 
    9697    typedef std::vector< Streaming::StreamProcessor * > StreamProcessorVector; 
     
    103104private: 
    104105    ClockSource syncInfoToClockSource(const SyncInfo& si); 
     106    std::vector<int> m_supported_frequencies_cache; 
    105107}; 
    106108 
  • trunk/libffado/src/libavc/general/avc_plug.cpp

    r1239 r1336  
    10151015 
    10161016bool 
     1017Plug::supportsSampleRate( int rate ) 
     1018{ 
     1019    // fallback: BeBoB style 
     1020    ESamplingFrequency samplingFrequency = parseSampleRate(rate); 
     1021 
     1022    ExtendedStreamFormatCmd extStreamFormatCmd( 
     1023        m_unit->get1394Service(), 
     1024        ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommandList ); 
     1025    UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, 
     1026                                     getPlugId() ); 
     1027 
     1028    extStreamFormatCmd.setPlugAddress( 
     1029        PlugAddress( 
     1030            Plug::convertPlugDirection(getPlugDirection() ), 
     1031            PlugAddress::ePAM_Unit, 
     1032            unitPlugAddress ) ); 
     1033 
     1034    extStreamFormatCmd.setNodeId( m_unit->getConfigRom().getNodeId() ); 
     1035    extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status ); 
     1036 
     1037    int i = 0; 
     1038    bool cmdSuccess = false; 
     1039    bool correctFormatFound = false; 
     1040 
     1041    do { 
     1042        extStreamFormatCmd.setIndexInStreamFormat( i ); 
     1043        extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status ); 
     1044        extStreamFormatCmd.setVerbose( getDebugLevel() ); 
     1045 
     1046        cmdSuccess = extStreamFormatCmd.fire(); 
     1047 
     1048        if ( cmdSuccess 
     1049             && ( extStreamFormatCmd.getResponse() == 
     1050                  AVCCommand::eR_Implemented ) ) 
     1051        { 
     1052            ESamplingFrequency foundFreq = eSF_DontCare; 
     1053 
     1054            FormatInformation* formatInfo = 
     1055                extStreamFormatCmd.getFormatInformation(); 
     1056            FormatInformationStreamsCompound* compoundStream 
     1057                = dynamic_cast< FormatInformationStreamsCompound* > ( 
     1058                    formatInfo->m_streams ); 
     1059            if ( compoundStream ) { 
     1060                foundFreq = 
     1061                    static_cast< ESamplingFrequency >( 
     1062                        compoundStream->m_samplingFrequency ); 
     1063            } 
     1064 
     1065            FormatInformationStreamsSync* syncStream 
     1066                = dynamic_cast< FormatInformationStreamsSync* > ( 
     1067                    formatInfo->m_streams ); 
     1068            if ( syncStream ) { 
     1069                foundFreq = 
     1070                    static_cast< ESamplingFrequency >( 
     1071                        syncStream->m_samplingFrequency ); 
     1072            } 
     1073 
     1074            if ( foundFreq == samplingFrequency ) 
     1075            { 
     1076                correctFormatFound = true; 
     1077                break; 
     1078            } 
     1079        } 
     1080 
     1081        ++i; 
     1082    } while ( cmdSuccess 
     1083              && ( extStreamFormatCmd.getResponse() == 
     1084                   ExtendedStreamFormatCmd::eR_Implemented ) ); 
     1085 
     1086    if ( !cmdSuccess ) { 
     1087        debugError( "setSampleRatePlug: Failed to retrieve format info\n" ); 
     1088        return false; 
     1089    } 
     1090 
     1091    if ( !correctFormatFound ) { 
     1092        debugOutput(DEBUG_LEVEL_VERBOSE, 
     1093                    "setSampleRatePlug: %s plug %d does not support sample rate %d\n", 
     1094                    getName(), 
     1095                    getPlugId(), 
     1096                    convertESamplingFrequency( samplingFrequency ) ); 
     1097        return false; 
     1098    } 
     1099    return true; 
     1100} 
     1101 
     1102bool 
    10171103Plug::discoverConnectionsFromSpecificData( 
    10181104    EPlugDirection discoverDirection, 
  • trunk/libffado/src/libavc/general/avc_plug.h

    r1239 r1336  
    129129    int getSampleRate() const; // 22050, 24000, 32000, ... 
    130130    bool setSampleRate( int rate ); 
     131    bool supportsSampleRate( int rate ); 
    131132 
    132133    int getNrOfChannels() const; 
  • trunk/libffado/src/libavc/general/avc_unit.cpp

    r1239 r1336  
    844844Unit::show() 
    845845{ 
    846     m_pPlugManager->showPlugs(); 
     846    if (getDebugLevel() >= DEBUG_LEVEL_VERY_VERBOSE) { 
     847        m_pPlugManager->showPlugs(); 
     848    } 
    847849    //SubunitMusic* s=getMusicSubunit(0); 
    848850    //if(s) s->showMusicPlugs(); 
  • trunk/libffado/src/libcontrol/ClockSelect.cpp

    r1217 r1336  
    4444    if(idx >= (int)v.size()) { 
    4545        debugError("index out of range\n"); 
     46        return false; 
     47    } 
     48    if(idx < 0) { 
     49        debugError("index < 0\n"); 
    4650        return false; 
    4751    } 
     
    8488    if(idx >= (int)v.size()) { 
    8589        debugError("index out of range\n"); 
    86         return false; 
     90        return "Error"; 
     91    } 
     92    if(idx < 0) { 
     93        debugError("index < 0\n"); 
     94        return "Error"; 
    8795    } 
    8896    return v.at(idx).description; 
     
    173181 
    174182SamplerateSelect::SamplerateSelect(FFADODevice &d) 
    175 : Discrete(&d) 
     183: Enum(&d) 
    176184, m_Device( d ) 
    177185{ 
     
    182190 
    183191bool 
    184 SamplerateSelect::setValue(int v) 
    185 
    186     return m_Device.setSamplingFrequency(v); 
    187 
    188  
    189 int 
    190 SamplerateSelect::getValue() 
    191 
    192     return m_Device.getSamplingFrequency(); 
    193 
    194  
    195 bool 
    196 SamplerateSelect::setValue(int idx, int v) 
    197 
    198     return m_Device.setSamplingFrequency(v); 
    199 
    200  
    201 int 
    202 SamplerateSelect::getValue(int idx) 
    203 
    204     return m_Device.getSamplingFrequency(); 
    205 
    206  
    207 int 
    208 SamplerateSelect::getMinimum() 
    209 
    210     return 32000; 
    211 
    212  
    213 int 
    214 SamplerateSelect::getMaximum() 
    215 
    216     return 192000; 
    217 
     192SamplerateSelect::select(int idx) 
     193
     194    std::vector<int> freqs = m_Device.getSupportedSamplingFrequencies(); 
     195    if (idx >= 0 && idx < (int)freqs.size()) { 
     196        if(!m_Device.setSamplingFrequency(freqs.at(idx))) { 
     197            debugWarning("Could not select samplerate\n"); 
     198            return false; 
     199        } 
     200        return true; 
     201    } else { 
     202        debugWarning("bad index specified\n"); 
     203        return false; 
     204    } 
     205
     206 
     207int 
     208SamplerateSelect::selected() 
     209
     210    std::vector<int> freqs = m_Device.getSupportedSamplingFrequencies(); 
     211    int samplerate = m_Device.getSamplingFrequency(); 
     212    for (int i = 0; i < (int)freqs.size(); i++) { 
     213        if (samplerate == freqs.at(i)) { 
     214            return i; 
     215        } 
     216    } 
     217    debugError("could not find the selected samplerate\n"); 
     218    return -1; 
     219
     220 
     221int 
     222SamplerateSelect::count() 
     223
     224    return  m_Device.getSupportedSamplingFrequencies().size(); 
     225
     226 
     227std::string 
     228SamplerateSelect::getEnumLabel(int idx) 
     229
     230    char tmp[16]; 
     231    std::string retval = "Error"; 
     232    std::vector<int> freqs = m_Device.getSupportedSamplingFrequencies(); 
     233    if (idx >= 0 && idx < (int)freqs.size()) { 
     234        snprintf(tmp, 16, "%u", freqs.at(idx)); 
     235        retval = tmp; 
     236    } else { 
     237        debugWarning("bad index specified\n"); 
     238    } 
     239    return retval; 
     240
     241 
     242void 
     243SamplerateSelect::show() 
     244
     245    debugOutput( DEBUG_LEVEL_NORMAL, "SamplerateSelect Element %s, current: %d\n", 
     246        getName().c_str(), m_Device.getSamplingFrequency()); 
     247 
     248
     249 
    218250 
    219251} // namespace Control 
  • trunk/libffado/src/libcontrol/ClockSelect.h

    r1217 r1336  
    6969*/ 
    7070class SamplerateSelect 
    71 : public Discrete 
     71: public Enum 
    7272{ 
    7373public: 
     
    7575    virtual ~SamplerateSelect() {}; 
    7676 
    77     virtual bool setValue(int v); 
    78     virtual int getValue(); 
    79     virtual bool setValue(int idx, int v); 
    80     virtual int getValue(int idx); 
     77    virtual bool select(int idx); 
     78    virtual int selected(); 
     79    virtual int count(); 
     80    virtual std::string getEnumLabel(int idx); 
    8181 
    82     virtual int getMinimum(); 
    83     virtual int getMaximum(); 
     82    virtual void show(); 
     83 
    8484protected: 
    8585    FFADODevice &m_Device; 
  • trunk/libffado/src/libcontrol/Element.cpp

    r1211 r1336  
    5050    // this means we have to create a lock 
    5151    if(parent == NULL) { 
    52         m_element_lock = new Util::PosixMutex(); 
     52        m_element_lock = new Util::PosixMutex("CTLEL"); 
    5353    } 
    5454} 
     
    6565    // this means we have to create a lock 
    6666    if(parent == NULL) { 
    67         m_element_lock = new Util::PosixMutex(); 
     67        m_element_lock = new Util::PosixMutex("CTLEL"); 
    6868    } 
    6969} 
     
    158158} 
    159159 
     160bool 
     161Element::emitSignal(int id) 
     162{ 
     163    for ( std::vector< SignalFunctor* >::iterator it = m_signalHandlers.begin(); 
     164          it != m_signalHandlers.end(); 
     165          ++it ) 
     166    { 
     167        SignalFunctor *f = *it; 
     168        if(f && f->m_id == id) (*f)(); 
     169    } 
     170    return true; 
     171} 
     172 
    160173//// --- Container --- //// 
    161174Container::Container(Element *p) 
     
    166179Container::Container(Element *p, std::string n) 
    167180: Element(p, n) 
     181{ 
     182} 
     183 
     184Container::~Container() 
    168185{ 
    169186} 
  • trunk/libffado/src/libcontrol/Element.h

    r1211 r1336  
    5050    virtual ~SignalFunctor() {} 
    5151 
    52     virtual void operator() (int arg) = 0; 
     52    virtual void operator() () = 0; 
     53    virtual void operator() (int) = 0; 
    5354protected: 
    5455    int m_id; 
     
    103104protected: 
    104105    bool            emitSignal(int id, int value); 
     106    bool            emitSignal(int id); 
    105107    Util::Mutex&    getLock(); 
    106108 
     
    138140    Container(Element *); 
    139141    Container(Element *, std::string n); 
    140     virtual ~Container() {}
    141      
     142    virtual ~Container()
     143 
    142144    virtual bool addElement(Element *e); 
    143145    virtual bool deleteElement(Element *e); 
  • trunk/libffado/src/libieee1394/configrom.cpp

    r1254 r1336  
    548548    } 
    549549 
    550     debugOutput( DEBUG_LEVEL_NORMAL
    551                  "Device with GUID 0x%08x%08x could not be found on " 
     550    debugOutput( DEBUG_LEVEL_VERBOSE
     551                 "Device with GUID 0x%016llX could not be found on " 
    552552                 "the bus anymore (removed?)\n", 
    553                  m_guid >> 32, 
    554                  m_guid & 0xffffffff )
     553                 getGuid() ); 
     554    m_nodeId = INVALID_NODE_ID
    555555    return false; 
    556556} 
  • trunk/libffado/src/libieee1394/configrom.h

    r1154 r1336  
    112112    } 
    113113 
     114    bool isPresentOnBus() { 
     115        return m_nodeId != INVALID_NODE_ID; 
     116    }; 
    114117 protected: 
    115118    void processUnitDirectory( struct csr1212_csr*    csr, 
  • trunk/libffado/src/libieee1394/CycleTimerHelper.cpp

    r1184 r1336  
    7373    , m_realtime ( false ) 
    7474    , m_priority ( 0 ) 
    75     , m_update_lock( new Util::PosixMutex() ) 
     75    , m_update_lock( new Util::PosixMutex("CTRUPD") ) 
    7676    , m_busreset_functor ( NULL) 
    7777    , m_unhandled_busreset ( false ) 
     
    9999    , m_realtime ( rt ) 
    100100    , m_priority ( prio ) 
    101     , m_update_lock( new Util::PosixMutex() ) 
     101    , m_update_lock( new Util::PosixMutex("CTRUPD") ) 
    102102    , m_busreset_functor ( NULL) 
    103103    , m_unhandled_busreset ( false ) 
     
    131131    } 
    132132 
    133     m_Thread = new Util::PosixThread(this, m_realtime, m_priority,  
     133    m_Thread = new Util::PosixThread(this, "CTRHLP", m_realtime, m_priority,  
    134134                                     PTHREAD_CANCEL_DEFERRED); 
    135135    if(!m_Thread) { 
     
    418418        } 
    419419        m_first_run = false; 
     420    } else if (diff_ticks > 20.0*m_ticks_per_update) { 
     421        debugOutput(DEBUG_LEVEL_VERBOSE, 
     422                    "re-init dll due to too large tick diff: %f >> %f\n", 
     423                    diff_ticks, (float)(20.0*m_ticks_per_update)); 
     424        if(!initDLL()) { 
     425            debugError("(%p) Could not init DLL\n", this); 
     426            return false; 
     427        } 
    420428    } else { 
    421429        // calculate next sleep time 
  • trunk/libffado/src/libieee1394/ieee1394service.cpp

    r1254 r1336  
    4747#include <iomanip> 
    4848 
     49using namespace std; 
     50 
    4951IMPL_DEBUG_MODULE( Ieee1394Service, Ieee1394Service, DEBUG_LEVEL_NORMAL ); 
    5052 
    5153Ieee1394Service::Ieee1394Service() 
    5254    : m_handle( 0 ) 
    53     , m_handle_lock( new Util::PosixMutex() ) 
     55    , m_handle_lock( new Util::PosixMutex("SRCVHND") ) 
    5456    , m_resetHandle( 0 ) 
    5557    , m_util_handle( 0 ) 
    5658    , m_port( -1 ) 
    57     , m_RHThread_lock( new Util::PosixMutex() ) 
     59    , m_RHThread_lock( new Util::PosixMutex("SRVCRH") ) 
    5860    , m_threadRunning( false ) 
    5961    , m_realtime ( false ) 
     
    7779Ieee1394Service::Ieee1394Service(bool rt, int prio) 
    7880    : m_handle( 0 ) 
    79     , m_handle_lock( new Util::PosixMutex() ) 
     81    , m_handle_lock( new Util::PosixMutex("SRCVHND") ) 
    8082    , m_resetHandle( 0 ) 
    8183    , m_util_handle( 0 ) 
    8284    , m_port( -1 ) 
    83     , m_RHThread_lock( new Util::PosixMutex() ) 
     85    , m_RHThread_lock( new Util::PosixMutex("SRVCRH") ) 
    8486    , m_threadRunning( false ) 
    8587    , m_realtime ( rt ) 
     
    158160    debugOutput(DEBUG_LEVEL_VERBOSE, "Issue bus reset on service %p (port %d).\n", this, getPort()); 
    159161    raw1394_reset_bus(m_handle); 
     162} 
     163 
     164/** 
     165 * This function waits until there are no bus resets generated in a sleep_time_ms interval 
     166 * @param nb_tries number of tries to take 
     167 * @param sleep_time_ms sleep between tries 
     168 * @return true if the storm passed 
     169 */ 
     170bool 
     171Ieee1394Service::waitForBusResetStormToEnd( int nb_tries, int sleep_time_ms ) { 
     172    unsigned int gen_current; 
     173    do { 
     174        gen_current = getGeneration(); 
     175        debugOutput(DEBUG_LEVEL_VERBOSE, "Waiting... (gen: %u)\n", gen_current); 
     176 
     177        // wait for a while 
     178        Util::SystemTimeSource::SleepUsecRelative( sleep_time_ms * 1000); 
     179    } while (gen_current != getGeneration() && --nb_tries); 
     180 
     181    if (!nb_tries) { 
     182        debugError( "Bus reset storm did not stop on time...\n"); 
     183        return false; 
     184    } 
     185    return true; 
    160186} 
    161187 
     
    415441{ 
    416442    Util::MutexLockHelper lock(*m_handle_lock); 
    417     using namespace std; 
     443    if (nodeId == INVALID_NODE_ID) { 
     444        debugWarning("operation on invalid node\n"); 
     445        return false; 
     446    } 
    418447    if ( raw1394_read( m_handle, nodeId, addr, length*4, buffer ) == 0 ) { 
    419448 
     
    460489{ 
    461490    Util::MutexLockHelper lock(*m_handle_lock); 
    462     using namespace std; 
     491    if (nodeId == INVALID_NODE_ID) { 
     492        debugWarning("operation on invalid node\n"); 
     493        return false; 
     494    } 
    463495 
    464496    #ifdef DEBUG 
     
    489521 
    490522bool 
    491 Ieee1394Service::lockCompareSwap64(  fb_nodeid_t nodeId, 
    492                         fb_nodeaddr_t addr, 
    493                         fb_octlet_t  compare_value, 
    494                         fb_octlet_t  swap_value, 
    495                         fb_octlet_t* result ) 
    496 
     523Ieee1394Service::lockCompareSwap64( fb_nodeid_t nodeId, 
     524                                    fb_nodeaddr_t addr, 
     525                                    fb_octlet_t compare_value, 
     526                                    fb_octlet_t swap_value, 
     527                                    fb_octlet_t* result ) 
     528
     529    if (nodeId == INVALID_NODE_ID) { 
     530        debugWarning("operation on invalid node\n"); 
     531        return false; 
     532    } 
    497533    #ifdef DEBUG 
    498534    debugOutput(DEBUG_LEVEL_VERBOSE,"lockCompareSwap64: node 0x%X, addr = 0x%016llX\n", 
     
    543579                                   unsigned int* resp_len ) 
    544580{ 
     581    if (nodeId == INVALID_NODE_ID) { 
     582        debugWarning("operation on invalid node\n"); 
     583        return false; 
     584    } 
    545585    // FIXME: this requires transactionBlockClose to unlock 
    546586    m_handle_lock->Lock(); 
     
    626666{ 
    627667    quadlet_t buf=0; 
     668 
     669    m_handle_lock->Lock(); 
     670    raw1394_update_generation(m_handle, generation); 
     671    m_handle_lock->Unlock(); 
    628672 
    629673    // do a simple read on ourself in order to update the internal structures 
     
    809853{ 
    810854    if ( m_threadRunning ) { 
     855        // wait for the thread to finish it's work 
    811856        m_RHThread_lock->Lock(); 
    812857        pthread_cancel (m_thread); 
     
    823868 
    824869    while (true) { 
    825         raw1394_loop_iterate (pIeee1394Service->m_resetHandle); 
     870        // protect ourselves from dying 
     871        { 
     872            // use a scoped lock such that it is unlocked 
     873            // even if we are cancelled while running 
     874            // FIXME: check if this is true! 
     875//             Util::MutexLockHelper lock(*(pIeee1394Service->m_RHThread_lock)); 
     876            raw1394_loop_iterate (pIeee1394Service->m_resetHandle); 
     877        } 
    826878        pthread_testcancel (); 
    827879    } 
     
    935987    nodeid_t recv_node, int recv_plug 
    936988    ) { 
     989 
     990    if (xmit_node == INVALID_NODE_ID) { 
     991        debugWarning("operation on invalid node (XMIT)\n"); 
     992        return -1; 
     993    } 
     994    if (recv_node == INVALID_NODE_ID) { 
     995        debugWarning("operation on invalid node (RECV)\n"); 
     996        return -1; 
     997    } 
    937998 
    938999    debugOutput(DEBUG_LEVEL_VERBOSE, "Allocating ISO channel using IEC61883 CMP...\n" ); 
  • trunk/libffado/src/libieee1394/ieee1394service.h

    r1161 r1336  
    227227 
    228228    bool transactionBlockClose(); 
    229 // FIXME: private for thread safety !! 
    230     raw1394handle_t getHandle() {return m_handle;}; 
    231229 
    232230    int getVerboseLevel(); 
     
    236234 
    237235    void doBusReset(); 
     236    bool waitForBusResetStormToEnd( int nb_tries, int sleep_time_ms ); 
    238237 
    239238    /** 
     
    297296    bool registerIsoChannel(unsigned int c, struct ChannelInfo cinfo); 
    298297 
     298public: 
     299// FIXME: should be private, but is used to do the PCR control in GenericAVC::AvDevice 
     300    raw1394handle_t getHandle() {return m_handle;}; 
     301 
    299302private: 
    300  
    301303    bool startRHThread(); 
    302304    void stopRHThread(); 
     
    307309 
    308310    static int resetHandlerLowLevel( raw1394handle_t handle, 
    309                     unsigned int generation ); 
     311                                     unsigned int generation ); 
    310312    bool resetHandler( unsigned int generation ); 
    311313 
  • trunk/libffado/src/libieee1394/IsoHandler.cpp

    r1254 r1336  
    6363                        unsigned int length, unsigned char channel, 
    6464                        unsigned char tag, unsigned char sy, unsigned int cycle, 
    65                         unsigned int dropped1) { 
     65                        unsigned int dropped) { 
    6666 
    6767    IsoHandler *recvHandler = static_cast<IsoHandler *>(raw1394_get_userdata(handle)); 
    6868    assert(recvHandler); 
    6969 
    70     unsigned int skipped = (dropped1 & 0xFFFF0000) >> 16; 
    71     unsigned int dropped = dropped1 & 0xFFFF; 
    72  
    73     return recvHandler->putPacket(data, length, channel, tag, sy, cycle, dropped, skipped); 
    74 
    75  
    76 int IsoHandler::busreset_handler(raw1394handle_t handle, unsigned int generation) 
    77 
    78     debugOutput( DEBUG_LEVEL_VERBOSE, "Busreset happened, generation %d...\n", generation); 
    79  
    80     IsoHandler *handler = static_cast<IsoHandler *>(raw1394_get_userdata(handle)); 
    81     assert(handler); 
    82     return handler->handleBusReset(generation); 
     70    return recvHandler->putPacket(data, length, channel, tag, sy, cycle, dropped); 
    8371} 
    8472 
     
    9280   , m_last_cycle( -1 ) 
    9381   , m_last_now( 0xFFFFFFFF ) 
     82   , m_last_packet_handled_at( 0xFFFFFFFF ) 
    9483   , m_Client( 0 ) 
    9584   , m_speed( RAW1394_ISO_SPEED_400 ) 
     
    10089   , m_packets ( 0 ) 
    10190   , m_dropped( 0 ) 
     91   , m_skipped( 0 ) 
    10292   , m_min_ahead( 7999 ) 
    10393#endif 
     
    115105   , m_last_cycle( -1 ) 
    116106   , m_last_now( 0xFFFFFFFF ) 
     107   , m_last_packet_handled_at( 0xFFFFFFFF ) 
    117108   , m_Client( 0 ) 
    118109   , m_speed( RAW1394_ISO_SPEED_400 ) 
     
    122113   , m_packets ( 0 ) 
    123114   , m_dropped( 0 ) 
     115   , m_skipped( 0 ) 
    124116   , m_min_ahead( 7999 ) 
    125117#endif 
     
    138130   , m_last_cycle( -1 ) 
    139131   , m_last_now( 0xFFFFFFFF ) 
     132   , m_last_packet_handled_at( 0xFFFFFFFF ) 
    140133   , m_Client( 0 ) 
    141134   , m_speed( speed ) 
     
    145138   , m_packets( 0 ) 
    146139   , m_dropped( 0 ) 
     140   , m_skipped( 0 ) 
     141   , m_min_ahead( 7999 ) 
    147142#endif 
    148143{ 
     
    169164    if(m_Client) { 
    170165        bool result; 
     166 
    171167        if (m_type == eHT_Receive) { 
    172168            result = m_Client->canProducePacket(); 
     
    175171        } 
    176172        debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, " returns %d\n", result); 
    177         return result
     173        return result && (m_State != E_Error)
    178174    } else { 
    179175        debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, " no client\n"); 
     
    234230    raw1394_set_userdata(m_handle, static_cast<void *>(this)); 
    235231 
    236     // bus reset handling 
    237     if(raw1394_busreset_notify (m_handle, RAW1394_NOTIFY_ON)) { 
    238         debugWarning("Could not enable busreset notification.\n"); 
    239         debugWarning(" Error message: %s\n",strerror(errno)); 
    240         debugWarning("Continuing without bus reset support.\n"); 
    241     } else { 
    242         // apparently this cannot fail 
    243         raw1394_set_bus_reset_handler(m_handle, busreset_handler); 
    244     } 
    245  
    246232    // update the internal state 
    247233    m_State=E_Initialized; 
     
    261247    } 
    262248 
     249    debugOutput( DEBUG_LEVEL_VERBOSE, "(%p, %s) wake up handle...\n",  
     250                 this, (m_type==eHT_Receive?"Receive":"Transmit")); 
     251 
     252    // wake up any waiting reads/polls 
     253    raw1394_wake_up(m_handle); 
     254 
    263255    // this is put here to try and avoid the 
    264256    // Runaway context problem 
    265257    // don't know if it will help though. 
    266     raw1394_iso_xmit_sync(m_handle); 
     258/*    if(m_State != E_Error) { // if the handler is dead, this might block forever 
     259        raw1394_iso_xmit_sync(m_handle); 
     260    }*/ 
     261    debugOutput( DEBUG_LEVEL_VERBOSE, "(%p, %s) stop...\n",  
     262                 this, (m_type==eHT_Receive?"Receive":"Transmit")); 
    267263    raw1394_iso_stop(m_handle); 
    268264    m_State = E_Prepared; 
     
    276272 */ 
    277273 
    278 int 
    279 IsoHandler::handleBusReset(unsigned int generation) 
    280 
    281     debugOutput( DEBUG_LEVEL_VERBOSE, "bus reset...\n"); 
     274bool 
     275IsoHandler::handleBusReset() 
     276
     277    debugOutput( DEBUG_LEVEL_NORMAL, "bus reset...\n"); 
     278    m_last_packet_handled_at = 0xFFFFFFFF; 
    282279 
    283280    #define CSR_CYCLE_TIME            0x200 
     
    289286                 CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 
    290287 
    291     // notify the client of the fact that we have died 
    292     m_Client->handlerDied(); 
    293  
    294     if(!disable()) { 
    295         debugError("(%p) Could not disable IsoHandler\n", this); 
    296     } 
    297  
    298     // request the manager to update it's shadow map 
    299     m_manager.requestShadowMapUpdate(); 
    300     return 0; 
     288    return m_Client->handleBusReset(); 
    301289} 
    302290 
     
    308296IsoHandler::notifyOfDeath() 
    309297{ 
     298    m_State = E_Error; 
     299 
    310300    // notify the client of the fact that we have died 
    311301    m_Client->handlerDied(); 
     302 
     303    // wake ourselves up 
     304    raw1394_wake_up(m_handle); 
    312305} 
    313306 
     
    331324    } 
    332325    #ifdef DEBUG 
    333     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Last cycle, dropped.........: %4d, %4u\n", 
    334             m_last_cycle, m_dropped); 
     326    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Last cycle, dropped.........: %4d, %4u, %4u\n", 
     327            m_last_cycle, m_dropped, m_skipped); 
    335328    #endif 
    336329 
     
    340333{ 
    341334    setDebugLevel(l); 
     335    debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l ); 
    342336} 
    343337 
     
    381375                    unsigned char *data, unsigned int length, 
    382376                    unsigned char channel, unsigned char tag, unsigned char sy, 
    383                     unsigned int cycle, unsigned int dropped, unsigned int skipped) { 
     377                    unsigned int cycle, unsigned int dropped) { 
    384378 
    385379    // keep track of dropped cycles 
     
    389383        #ifdef DEBUG 
    390384        if (dropped_cycles < 0) { 
    391             debugWarning("(%p) dropped < 1 (%d), cycle: %d, last_cycle: %d, dropped: %d, 'skipped'=%u\n",  
    392                          this, dropped_cycles, cycle, m_last_cycle, dropped, skipped); 
     385            debugWarning("(%p) dropped < 1 (%d), cycle: %d, last_cycle: %d, dropped: %d\n",  
     386                         this, dropped_cycles, cycle, m_last_cycle, dropped); 
    393387        } 
    394388        if (dropped_cycles > 0) { 
    395             debugOutput(DEBUG_LEVEL_NORMAL
    396                         "(%p) dropped %d packets on cycle %u, 'dropped'=%u, 'skipped'=%u, cycle=%d, m_last_cycle=%d\n", 
    397                         this, dropped_cycles, cycle, dropped, skipped, cycle, m_last_cycle); 
     389            debugOutput(DEBUG_LEVEL_VERBOSE
     390                        "(%p) dropped %d packets on cycle %u, 'dropped'=%u, cycle=%d, m_last_cycle=%d\n", 
     391                        this, dropped_cycles, cycle, dropped, cycle, m_last_cycle); 
    398392            m_dropped += dropped_cycles; 
    399393        } 
     
    448442        && dropped_cycles == 0)  
    449443    { 
    450         debugOutput(DEBUG_LEVEL_VERBOSE, "Special non-unwrapping happened\n"); 
     444        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Special non-unwrapping happened\n"); 
    451445    } 
    452446    #endif 
     
    477471    } 
    478472    #endif 
     473    m_last_packet_handled_at = pkt_ctr; 
    479474 
    480475    // leave the offset field (for now?) 
    481476 
    482     debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE, 
    483                        "received packet: length=%d, channel=%d, cycle=%d\n", 
    484                        length, channel, cycle); 
     477    debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 
     478                "received packet: length=%d, channel=%d, cycle=%d, at %08X\n", 
     479                length, channel, cycle, pkt_ctr); 
     480    m_packets++; 
    485481    #ifdef DEBUG 
    486     m_packets++; 
    487482    if (length > m_max_packet_size) { 
    488483        debugWarning("(%p, %s) packet too large: len=%u max=%u\n", 
     
    496491    // iterate the client if required 
    497492    if(m_Client) { 
    498         enum raw1394_iso_disposition retval = m_Client->putPacket(data, length, channel, tag, sy, pkt_ctr, dropped_cycles, skipped); 
     493        enum raw1394_iso_disposition retval = m_Client->putPacket(data, length, channel, tag, sy, pkt_ctr, dropped_cycles); 
    499494        if (retval == RAW1394_ISO_OK) { 
    500495            if (m_dont_exit_iterate_loop) { 
     
    527522        pkt_ctr = cycle << 12; 
    528523 
    529 #if 0 // we don't need this for xmit 
    530524        // if we assume that one iterate() loop doesn't take longer than 0.5 seconds, 
    531525        // the seconds field won't change while the iterate loop runs 
     
    560554        uint32_t pkt_ctr_ref = cycle << 12; 
    561555        pkt_ctr_ref |= (now_secs_ref & 0x7F) << 25; 
    562      
     556 
    563557        if(pkt_ctr != pkt_ctr_ref) { 
    564558            debugWarning("reconstructed CTR counter discrepancy\n"); 
     
    566560        } 
    567561        #endif 
    568 #endif 
    569     } 
    570  
    571     debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE, 
    572                        "sending packet: length=%d, cycle=%d\n", 
    573                        *length, cycle); 
     562    } 
     563    if (m_packets < m_buf_packets) { // these are still prebuffer packets 
     564        m_last_packet_handled_at = 0xFFFFFFFF; 
     565    } else { 
     566        m_last_packet_handled_at = pkt_ctr; 
     567    } 
     568    debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 
     569                "sending packet: length=%d, cycle=%d, at %08X\n", 
     570                *length, cycle, pkt_ctr); 
     571 
     572    m_packets++; 
    574573 
    575574    #ifdef DEBUG 
    576     m_packets++; 
    577575    if(m_last_cycle == -1) { 
    578576        debugOutput(DEBUG_LEVEL_VERBOSE, "Handler for %s SP %p is alive (cycle = %d)\n", getTypeString(), this, cycle); 
     
    590588        #ifdef DEBUG 
    591589        if(skipped) { 
    592             debugOutput(DEBUG_LEVEL_NORMAL
     590            debugOutput(DEBUG_LEVEL_VERBOSE
    593591                        "(%p) skipped %d cycles, cycle: %d, last_cycle: %d, dropped: %d\n",  
    594592                        this, skipped, cycle, m_last_cycle, dropped); 
     593            m_skipped += skipped; 
    595594        } 
    596595        if (dropped_cycles < 0) {  
     
    599598        } 
    600599        if (dropped_cycles > 0) { 
    601             debugOutput(DEBUG_LEVEL_NORMAL
     600            debugOutput(DEBUG_LEVEL_VERBOSE
    602601                        "(%p) dropped %d packets on cycle %u (last_cycle=%u, dropped=%d, skipped: %d)\n", 
    603602                        this, dropped_cycles, cycle, m_last_cycle, dropped, skipped); 
     
    616615    } 
    617616 
     617    #ifdef DEBUG 
     618    if (dropped > 0) { 
     619        debugOutput(DEBUG_LEVEL_VERBOSE, 
     620                    "(%p) OHCI issue on cycle %u (dropped_cycles=%d, last_cycle=%u, dropped=%d, skipped: %d)\n", 
     621                    this, cycle, dropped_cycles, m_last_cycle, dropped, skipped); 
     622    } 
     623    #endif 
     624 
    618625    if(m_Client) { 
    619626        enum raw1394_iso_disposition retval; 
    620         retval = m_Client->getPacket(data, length, tag, sy, pkt_ctr, dropped, skipped, m_max_packet_size); 
     627        retval = m_Client->getPacket(data, length, tag, sy, pkt_ctr, dropped_cycles, skipped, m_max_packet_size); 
    621628        #ifdef DEBUG 
    622629        if (*length > m_max_packet_size) { 
  • trunk/libffado/src/libieee1394/IsoHandler.h

    r1246 r1336  
    6969            putPacket(unsigned char *data, unsigned int length, 
    7070                        unsigned char channel, unsigned char tag, unsigned char sy, 
    71                         unsigned int cycle, unsigned int dropped, unsigned int skipped); 
     71                        unsigned int cycle, unsigned int dropped); 
    7272 
    7373    static enum raw1394_iso_disposition iso_transmit_handler(raw1394handle_t handle, 
     
    162162    uint32_t getLastIterateTime() {return m_last_now;}; 
    163163 
     164    /** 
     165     * @brief returns the CTR value saved at the last iterate handler call 
     166     * @return CTR value saved at last iterate handler call 
     167     */ 
     168    uint32_t getLastPacketTime() {return m_last_packet_handled_at;}; 
     169 
    164170    void notifyOfDeath(); 
     171    bool handleBusReset(); 
     172 
    165173private: 
    166174    IsoHandlerManager& m_manager; 
     
    172180    int             m_last_cycle; 
    173181    uint32_t        m_last_now; 
     182    uint32_t        m_last_packet_handled_at; 
    174183 
    175184    Streaming::StreamProcessor *m_Client; // FIXME: implement with functors 
    176  
    177     int handleBusReset(unsigned int generation); 
    178  
    179     static int busreset_handler(raw1394handle_t handle, unsigned int generation); 
    180185 
    181186    enum raw1394_iso_speed m_speed; 
     
    189194        E_Prepared, 
    190195        E_Running, 
    191         E_Error 
     196        E_Error, 
    192197    }; 
    193198    enum EHandlerStates m_State; 
    194199 
     200public: 
     201    unsigned int    m_packets; 
    195202    #ifdef DEBUG 
    196     unsigned int    m_packets; 
    197203    unsigned int    m_dropped; 
     204    unsigned int    m_skipped; 
    198205    int             m_min_ahead; 
    199206    #endif 
    200207 
     208protected: 
    201209    DECLARE_DEBUG_MODULE; 
    202210}; 
  • trunk/libffado/src/libieee1394/IsoHandlerManager.cpp

    r1254 r1336  
    4848    , m_SyncIsoHandler ( NULL ) 
    4949    , m_handlerType( t ) 
     50    , m_running( false ) 
     51    , m_in_busreset( false ) 
    5052{ 
    5153} 
     
    7476 
    7577    sem_init(&m_activity_semaphore, 0, 0); 
     78    m_running = true; 
    7679    return true; 
    7780} 
     
    8285    debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) enter\n", this); 
    8386    INC_ATOMIC(&request_update); 
     87 
     88    // get the thread going again 
     89    signalActivity(); 
     90 
     91    if (m_running) { 
     92        int timeout = 1000; 
     93        while(request_update && timeout--) { 
     94            Util::SystemTimeSource::SleepUsecRelative(1000); 
     95        } 
     96        if(timeout == 0) { 
     97            debugError("timeout waiting for shadow map update\n"); 
     98        } 
     99    } 
     100    debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) exit\n", this); 
    84101    return true; 
     102} 
     103 
     104bool 
     105IsoTask::handleBusReset() 
     106{ 
     107    bool retval = true; 
     108    m_in_busreset = true; 
     109    requestShadowMapUpdate(); 
     110    if(request_update) { 
     111        debugError("shadow map update request not honored\n"); 
     112        return false; 
     113    } 
     114 
     115    unsigned int i, max; 
     116    max = m_manager.m_IsoHandlers.size(); 
     117    for (i = 0; i < max; i++) { 
     118        IsoHandler *h = m_manager.m_IsoHandlers.at(i); 
     119        assert(h); 
     120 
     121        // skip the handlers not intended for us 
     122        if(h->getType() != m_handlerType) continue; 
     123 
     124        if (!h->handleBusReset()) { 
     125            debugWarning("Failed to handle busreset on %p\n"); 
     126            retval = false; 
     127        } 
     128    } 
     129 
     130    // re-enable processing 
     131    m_in_busreset = false; 
     132    requestShadowMapUpdate(); 
     133    if(request_update) { 
     134        debugError("shadow map update request not honored\n"); 
     135        return false; 
     136    } 
     137    return retval; 
    85138} 
    86139 
     
    92145{ 
    93146    debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) updating shadow vars...\n", this); 
     147    // we are handling a busreset 
     148    if(m_in_busreset) { 
     149        m_poll_nfds_shadow = 0; 
     150        return; 
     151    } 
    94152    unsigned int i, cnt, max; 
    95153    max = m_manager.m_IsoHandlers.size(); 
     
    140198IsoTask::Execute() 
    141199{ 
    142     debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 
    143                        "(%p, %s) Execute\n", 
    144                        this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive")); 
     200    debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 
     201                "(%p, %s) Execute\n", 
     202                this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive")); 
    145203    int err; 
    146204    unsigned int i; 
     
    158216        if(m_successive_short_loops > 10000) { 
    159217            debugError("Shutting down runaway thread\n"); 
     218            m_running = false; 
    160219            return false; 
    161220        } 
     
    210269 
    211270        if(no_one_to_poll) { 
    212             debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 
    213                                "(%p, %s) No one to poll, waiting for something to happen\n", 
    214                                this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive")); 
     271            debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 
     272                        "(%p, %s) No one to poll, waiting for something to happen\n", 
     273                        this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive")); 
    215274            // wait for something to happen 
    216275            switch(waitForActivity()) { 
     
    248307        } 
    249308        debugFatal("poll error: %s\n", strerror (errno)); 
     309        m_running = false; 
    250310        return false; 
    251311    } 
     
    256316    for (i = 0; i < m_poll_nfds_shadow; i++) { 
    257317        // figure out if a handler has died 
    258         // all handlers in the poll() are active, so they should be iterated 
    259         // now and then. If they aren't, the handler has died. 
    260         uint32_t last_call = m_IsoHandler_map_shadow[i]->getLastIterateTime(); 
    261         if (last_call == 0xFFFFFFFF) { 
     318 
     319        // this is the time of the last packet we saw in the iterate() handler 
     320        uint32_t last_packet_seen = m_IsoHandler_map_shadow[i]->getLastPacketTime(); 
     321        if (last_packet_seen == 0xFFFFFFFF) { 
    262322            // this was not iterated yet, so can't be dead 
     323            debugOutput(DEBUG_LEVEL_VERY_VERBOSE, 
     324                        "(%p, %s) handler %d didn't see any packets yet\n", 
     325                        this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"), i); 
    263326            continue; 
    264327        } 
    265328 
    266         uint64_t last_call_ticks = CYCLE_TIMER_TO_TICKS(last_call); 
    267         // we use 4 seconds since that should not cause issues with startup 
    268         int64_t max_diff_ticks = TICKS_PER_SECOND * 4; 
    269         int64_t measured_diff_ticks = diffTicks(ctr_at_poll_return_ticks, last_call_ticks); 
    270  
     329        uint64_t last_packet_seen_ticks = CYCLE_TIMER_TO_TICKS(last_packet_seen); 
     330        // we use a relatively large value to distinguish between "death" and xrun 
     331        int64_t max_diff_ticks = TICKS_PER_SECOND * 2; 
     332        int64_t measured_diff_ticks = diffTicks(ctr_at_poll_return_ticks, last_packet_seen_ticks); 
     333 
     334        debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 
     335                           "(%p, %s) check handler %d: diff = %lld, max = %lld, now: %08lX, last: %08lX\n", 
     336                           this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"),  
     337                           i, measured_diff_ticks, max_diff_ticks, ctr_at_poll_return, last_packet_seen); 
    271338        if(measured_diff_ticks > max_diff_ticks) { 
    272339            debugFatal("(%p, %s) Handler died: now: %08lX, last: %08lX, diff: %lld (max: %lld)\n", 
    273340                       this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"), 
    274                        ctr_at_poll_return, last_call, measured_diff_ticks, max_diff_ticks); 
     341                       ctr_at_poll_return, last_packet_seen, measured_diff_ticks, max_diff_ticks); 
    275342            m_IsoHandler_map_shadow[i]->notifyOfDeath(); 
    276343            handler_died = true; 
     
    278345    } 
    279346    if(handler_died) { 
     347        m_running = false; 
    280348        return false; // one or more handlers have died 
    281349    } 
     
    321389    struct timespec ts; 
    322390    int result; 
     391    long long int timeout_nsec = ISOHANDLERMANAGER_ISO_TASK_WAIT_TIMEOUT_USECS * 1000LL; 
    323392 
    324393    if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { 
     
    326395        return eAR_Error; 
    327396    } 
    328     long long int timeout_nsec=0; 
    329     int timeout_sec = 0; 
    330  
    331     timeout_nsec = ISOHANDLERMANAGER_ISO_TASK_WAIT_TIMEOUT_USECS * 1000LL; 
    332     timeout_sec = 0; 
    333     while(timeout_nsec >= 1000000000LL) { 
    334         timeout_sec += 1; 
    335         timeout_nsec -= 1000000000LL; 
    336     } 
     397 
    337398    ts.tv_nsec += timeout_nsec; 
    338     ts.tv_sec += timeout_sec; 
     399    while(ts.tv_nsec >= 1000000000LL) { 
     400        ts.tv_sec += 1; 
     401        ts.tv_nsec -= 1000000000LL; 
     402    } 
    339403 
    340404    result = sem_timedwait(&m_activity_semaphore, &ts); 
     
    351415                        this, result); 
    352416            return eAR_Interrupted; 
     417        } else if (errno == EINVAL) { 
     418            debugError("(%p) sem_timedwait error (result=%d errno=EINVAL)\n",  
     419                        this, result); 
     420            debugError("(%p) timeout_nsec=%lld ts.sec=%d ts.nsec=%lld\n",  
     421                       this, timeout_nsec, ts.tv_sec, ts.tv_nsec); 
     422            return eAR_Error; 
    353423        } else { 
    354424            debugError("(%p) sem_timedwait error (result=%d errno=%d)\n",  
    355425                        this, result, errno); 
    356             debugError("(%p) timeout_sec=%d timeout_nsec=%lld ts.sec=%d ts.nsec=%lld\n",  
    357                        this, timeout_sec, timeout_nsec, ts.tv_sec, ts.tv_nsec); 
     426            debugError("(%p) timeout_nsec=%lld ts.sec=%d ts.nsec=%lld\n",  
     427                       this, timeout_nsec, ts.tv_sec, ts.tv_nsec); 
    358428            return eAR_Error; 
    359429        } 
    360430    } 
    361431 
    362     debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 
    363                        "(%p, %s) got activity\n", 
    364                        this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive")); 
     432    debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 
     433                "(%p, %s) got activity\n", 
     434                this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive")); 
    365435    return eAR_Activity; 
    366436} 
     
    371441    // signal the activity cond var 
    372442    sem_post(&m_activity_semaphore); 
    373     debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 
    374                        "(%p, %s) activity\n", 
    375                        this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive")); 
     443    debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 
     444                "(%p, %s) activity\n", 
     445                this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive")); 
    376446} 
    377447 
    378448void IsoTask::setVerboseLevel(int i) { 
    379449    setDebugLevel(i); 
     450    debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", i ); 
    380451} 
    381452 
     
    426497} 
    427498 
     499bool 
     500IsoHandlerManager::handleBusReset() 
     501{ 
     502    debugOutput( DEBUG_LEVEL_NORMAL, "bus reset...\n"); 
     503    // A few things can happen on bus reset: 
     504    // 1) no devices added/removed => streams are still valid, but might have to be restarted 
     505    // 2) a device was removed => some streams become invalid 
     506    // 3) a device was added => same as 1, new device is ignored 
     507    if (!m_IsoTaskTransmit) { 
     508        debugError("No xmit task\n"); 
     509        return false; 
     510    } 
     511    if (!m_IsoTaskReceive) { 
     512        debugError("No receive task\n"); 
     513        return false; 
     514    } 
     515    if (!m_IsoTaskTransmit->handleBusReset()) { 
     516        debugWarning("could no handle busreset on xmit\n"); 
     517    } 
     518    if (!m_IsoTaskReceive->handleBusReset()) { 
     519        debugWarning("could no handle busreset on recv\n"); 
     520    } 
     521    return true; 
     522} 
     523 
    428524void 
    429525IsoHandlerManager::requestShadowMapUpdate() 
     
    479575    } 
    480576    m_IsoTaskTransmit->setVerboseLevel(getDebugLevel()); 
    481     m_IsoThreadTransmit = new Util::PosixThread(m_IsoTaskTransmit, m_realtime, 
     577    m_IsoThreadTransmit = new Util::PosixThread(m_IsoTaskTransmit, "ISOXMT", m_realtime, 
    482578                                                m_priority + ISOHANDLERMANAGER_ISO_PRIO_INCREASE 
    483579                                                + ISOHANDLERMANAGER_ISO_PRIO_INCREASE_XMIT, 
     
    497593    } 
    498594    m_IsoTaskReceive->setVerboseLevel(getDebugLevel()); 
    499     m_IsoThreadReceive = new Util::PosixThread(m_IsoTaskReceive, m_realtime, 
     595    m_IsoThreadReceive = new Util::PosixThread(m_IsoTaskReceive, "ISORCV", m_realtime, 
    500596                                               m_priority + ISOHANDLERMANAGER_ISO_PRIO_INCREASE 
    501597                                               + ISOHANDLERMANAGER_ISO_PRIO_INCREASE_RECV, 
     
    642738bool IsoHandlerManager::registerStream(StreamProcessor *stream) 
    643739{ 
    644     debugOutput( DEBUG_LEVEL_VERBOSE, "Registering stream %p\n",stream); 
     740    debugOutput( DEBUG_LEVEL_VERBOSE, "Registering %s stream %p\n", stream->getTypeString(), stream); 
    645741    assert(stream); 
    646742 
     
    767863bool IsoHandlerManager::unregisterStream(StreamProcessor *stream) 
    768864{ 
    769     debugOutput( DEBUG_LEVEL_VERBOSE, "Unregistering stream %p\n",stream); 
     865    debugOutput( DEBUG_LEVEL_VERBOSE, "Unregistering %s stream %p\n", stream->getTypeString(), stream); 
    770866    assert(stream); 
    771867 
     
    895991    { 
    896992        if((*it)->isStreamRegistered(stream)) { 
    897             return (*it)->flush(); 
     993            (*it)->flush(); 
    898994        } 
    899995    } 
    900996    debugError("Stream %p has no attached handler\n", stream); 
    901997    return; 
     998} 
     999 
     1000IsoHandler * 
     1001IsoHandlerManager::getHandlerForStream(Streaming::StreamProcessor *stream) { 
     1002    for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 
     1003      it != m_IsoHandlers.end(); 
     1004      ++it ) 
     1005    { 
     1006        if((*it)->isStreamRegistered(stream)) { 
     1007            return (*it); 
     1008        } 
     1009    } 
     1010    debugError("Stream %p has no attached handler\n", stream); 
     1011    return NULL; 
    9021012} 
    9031013 
     
    10051115    if(m_IsoThreadReceive)  m_IsoThreadReceive->setVerboseLevel(i); 
    10061116    if(m_IsoTaskReceive)    m_IsoTaskReceive->setVerboseLevel(i); 
     1117    setDebugLevel(i); 
     1118    debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", i ); 
    10071119} 
    10081120 
  • trunk/libffado/src/libieee1394/IsoHandlerManager.h

    r1254 r1336  
    4444namespace Streaming { 
    4545    class StreamProcessor; 
    46     class StreamProcessorManager; 
    4746    typedef std::vector<StreamProcessor *> StreamProcessorVector; 
    4847    typedef std::vector<StreamProcessor *>::iterator StreamProcessorVectorIterator; 
     
    8786        enum eActivityResult waitForActivity(); 
    8887 
     88        /** 
     89         * @brief This should be called when a busreset has happened. 
     90         */ 
     91        bool handleBusReset(); 
     92 
    8993        void setVerboseLevel(int i); 
    9094    protected: 
     
    114118 
    115119        enum IsoHandler::EHandlerType m_handlerType; 
     120        bool m_running; 
     121        bool m_in_busreset; 
     122 
    116123        // debug stuff 
    117124        DECLARE_DEBUG_MODULE; 
     
    181188 
    182189        void flushHandlerForStream(Streaming::StreamProcessor *stream); 
     190        IsoHandler * getHandlerForStream(Streaming::StreamProcessor *stream); 
    183191 
    184192        Ieee1394Service& get1394Service() {return m_service;}; 
     
    186194        void requestShadowMapUpdate(); 
    187195 
     196        /** 
     197         * This should be called when a busreset has happened. 
     198         */ 
     199        bool handleBusReset(); 
    188200    // the state machine 
    189201    private: 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp

    r1254 r1336  
    195195        { 
    196196            // we are too late 
    197             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, 
     197            debugOutput(DEBUG_LEVEL_VERBOSE, 
    198198                        "Too late: CY=%04u, TC=%04u, CUT=%04d, TSP=%011llu (%04u)\n", 
    199199                        CYCLE_TIMER_GET_CYCLES(pkt_ctr), 
     
    492492    unsigned int j; 
    493493    quadlet_t *target_event; 
    494     unsigned int i; 
     494    int i; 
    495495 
    496496    for (i = 0; i < m_nb_audio_ports; i++) { 
     
    523523    unsigned int j; 
    524524    quadlet_t *target_event; 
    525     unsigned int i; 
     525    int i; 
    526526 
    527527    float * client_buffers[4]; 
     
    543543    // this assumes that audio ports are sorted by position, 
    544544    // and that there are no gaps 
    545     for (i = 0; i < m_nb_audio_ports-4; i += 4) { 
     545    for (i = 0; i < ((int)m_nb_audio_ports)-4; i += 4) { 
    546546        struct _MBLA_port_cache *p; 
    547547 
     
    615615    // do remaining ports 
    616616    // NOTE: these can be time-SSE'd 
    617     for (; i < m_nb_audio_ports; i++) { 
     617    for (; i < (int)m_nb_audio_ports; i++) { 
    618618        struct _MBLA_port_cache &p = m_audio_ports.at(i); 
    619619        target_event = (quadlet_t *)(data + i); 
     
    715715    unsigned int j; 
    716716    quadlet_t *target_event; 
    717     unsigned int i; 
     717    int i; 
    718718 
    719719    uint32_t *client_buffers[4]; 
     
    729729    // this assumes that audio ports are sorted by position, 
    730730    // and that there are no gaps 
    731     for (i = 0; i < m_nb_audio_ports-4; i += 4) { 
     731    for (i = 0; i < ((int)m_nb_audio_ports)-4; i += 4) { 
    732732        struct _MBLA_port_cache *p; 
    733733 
     
    789789    // do remaining ports 
    790790    // NOTE: these can be time-SSE'd 
    791     for (; i < m_nb_audio_ports; i++) { 
     791    for (; i < ((int)m_nb_audio_ports); i++) { 
    792792        struct _MBLA_port_cache &p = m_audio_ports.at(i); 
    793793        target_event = (quadlet_t *)(data + i); 
     
    872872    unsigned int j; 
    873873    quadlet_t *target_event; 
    874     unsigned int i; 
     874    int i; 
    875875 
    876876    for (i = 0; i < m_nb_audio_ports; i++) { 
     
    913913    unsigned int j; 
    914914    quadlet_t *target_event; 
    915     unsigned int i; 
     915    int i; 
    916916 
    917917    for (i = 0; i < m_nb_audio_ports; i++) { 
     
    962962{ 
    963963    quadlet_t *target_event; 
    964     unsigned int i,j; 
     964    int i; 
     965    unsigned int j; 
    965966 
    966967    for (i = 0; i < m_nb_midi_ports; i++) { 
     
    986987{ 
    987988    quadlet_t *target_event; 
    988     unsigned int i,j; 
     989    int i; 
     990    unsigned int j; 
    989991 
    990992    for (i = 0; i < m_nb_midi_ports; i++) { 
     
    10621064    } 
    10631065 
    1064     unsigned int idx; 
     1066    int idx; 
    10651067    for (idx = 0; idx < m_nb_audio_ports; idx++) { 
    10661068        for(PortVectorIterator it = m_Ports.begin(); 
     
    10721074                        "idx %u: looking at port %s at position %u\n", 
    10731075                        idx, (*it)->getName().c_str(), pinfo->getPosition()); 
    1074             if(pinfo->getPosition() == idx) { 
     1076            if(pinfo->getPosition() == (unsigned int)idx) { 
    10751077                struct _MBLA_port_cache p; 
    10761078                p.port = dynamic_cast<AmdtpAudioPort *>(*it); 
     
    11311133void 
    11321134AmdtpTransmitStreamProcessor::updatePortCache() { 
    1133     unsigned int idx; 
     1135    int idx; 
    11341136    for (idx = 0; idx < m_nb_audio_ports; idx++) { 
    11351137        struct _MBLA_port_cache& p = m_audio_ports.at(idx); 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h

    r1034 r1336  
    150150    }; 
    151151    std::vector<struct _MBLA_port_cache> m_audio_ports; 
    152     unsigned int m_nb_audio_ports; 
     152    int m_nb_audio_ports; 
    153153 
    154154    struct _MIDI_port_cache { 
     
    163163    }; 
    164164    std::vector<struct _MIDI_port_cache> m_midi_ports; 
    165     unsigned int m_nb_midi_ports; 
     165    int m_nb_midi_ports; 
    166166 
    167167    bool initPortCache(); 
  • trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp

    r1254 r1336  
    9393} 
    9494 
    95 void 
     95bool 
     96StreamProcessor::handleBusResetDo() 
     97
     98    debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) handling busreset\n", this); 
     99    m_state = ePS_Error; 
     100    // this will result in the SPM dying 
     101    m_in_xrun = true; 
     102    SIGNAL_ACTIVITY_ALL; 
     103    return true; 
     104
     105 
     106bool 
    96107StreamProcessor::handleBusReset() 
    97108{ 
    98109    debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) handling busreset\n", this); 
    99     // for now, we try and make sure everything is cleanly shutdown 
    100     if(!stopRunning(-1)) { 
    101         debugError("Failed to stop SP\n"); 
    102     } 
    103     SIGNAL_ACTIVITY_ALL; 
     110 
     111    // we are sure that we're not iterated since this is called from within the ISO manager thread 
     112 
     113    // lock the wait loop of the SPM, such that the client leaves us alone 
     114    m_StreamProcessorManager.lockWaitLoop(); 
     115 
     116    // pass on to the implementing classes 
     117    bool retval = handleBusResetDo(); 
     118 
     119    // resume wait loop 
     120    m_StreamProcessorManager.unlockWaitLoop(); 
     121 
     122    return retval; 
    104123} 
    105124 
     
    109128    m_state = ePS_Stopped; 
    110129    m_in_xrun = true; 
     130    SIGNAL_ACTIVITY_ALL; 
    111131} 
    112132 
     
    287307                           unsigned char channel, unsigned char tag, unsigned char sy, 
    288308                           uint32_t pkt_ctr, 
    289                            unsigned int dropped_cycles, unsigned int skipped) { 
     309                           unsigned int dropped_cycles) { 
    290310    // bypass based upon state 
    291311#ifdef DEBUG 
     
    298318    if (m_state == ePS_Created) { 
    299319        return RAW1394_ISO_DEFER; 
     320    } 
     321 
     322    if (m_state == ePS_Error) { 
     323        debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "skip due to error state\n"); 
     324        return RAW1394_ISO_OK; 
    300325    } 
    301326 
     
    365390 
    366391    if (result == eCRV_OK) { 
    367         #ifdef DEBUG 
     392//         #ifdef DEBUG 
    368393        int ticks_per_packet = (int)(getTicksPerFrame() * getNominalFramesPerPacket()); 
    369394        int diff = diffTicks(m_last_timestamp, m_last_timestamp2); 
     
    376401                        CYCLE_TIMER_GET_CYCLES(pkt_ctr), m_last_timestamp2, 
    377402                        m_last_timestamp, diff, ticks_per_packet); 
     403            // !!!HACK!!! FIXME: this is the result of a failure in wrapping/unwrapping somewhere 
     404            // it's definitely a bug. 
     405            // try to fix up the timestamp 
     406            int64_t last_timestamp_fixed; 
     407            // first try to add one second 
     408            last_timestamp_fixed = m_last_timestamp + TICKS_PER_SECOND; 
     409            diff = diffTicks(last_timestamp_fixed, m_last_timestamp2); 
     410            if(diff-ticks_per_packet < 50 && diff-ticks_per_packet > -50) { 
     411                debugWarning("cy %04u rather large TSP difference TS=%011llu => TS=%011llu (%d, nom %d)\n", 
     412                             CYCLE_TIMER_GET_CYCLES(pkt_ctr), m_last_timestamp2, 
     413                             m_last_timestamp, diff, ticks_per_packet); 
     414                debugWarning("HACK: fixed by adding one second of ticks. This is a bug being run-time fixed.\n"); 
     415                m_last_timestamp = last_timestamp_fixed; 
     416            } 
     417            // then try to subtract one second 
     418            last_timestamp_fixed = m_last_timestamp - TICKS_PER_SECOND; 
     419            if(last_timestamp_fixed >= 0) { 
     420                diff = diffTicks(last_timestamp_fixed, m_last_timestamp2); 
     421                if(diff-ticks_per_packet < 50 && diff-ticks_per_packet > -50) { 
     422                    debugWarning("cy %04u rather large TSP difference TS=%011llu => TS=%011llu (%d, nom %d)\n", 
     423                                CYCLE_TIMER_GET_CYCLES(pkt_ctr), m_last_timestamp2, 
     424                                m_last_timestamp, diff, ticks_per_packet); 
     425                    debugWarning("HACK: fixed by subtracing one second of ticks. This is a bug being run-time fixed.\n"); 
     426                    m_last_timestamp = last_timestamp_fixed; 
     427                } 
     428            } 
    378429        } 
    379430        debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 
     
    382433                           m_last_timestamp2, m_last_timestamp,  
    383434                           diff, ticks_per_packet); 
    384         #endif 
     435//         #endif 
    385436 
    386437        debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 
     
    488539        return RAW1394_ISO_OK; 
    489540    } 
     541 
     542    if (m_state == ePS_Error) { 
     543        debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "skip due to error state\n"); 
     544        return RAW1394_ISO_OK; 
     545    } 
     546 
    490547    uint64_t prev_timestamp; 
    491  
    492548    // note that we can ignore skipped cycles since 
    493549    // the protocol will take care of that 
     
    498554        if(m_state == ePS_Running) { 
    499555            debugShowBackLogLines(200); 
    500             debugOutput(DEBUG_LEVEL_NORMAL, "dropped packets xrun\n"); 
     556            debugOutput(DEBUG_LEVEL_NORMAL, "dropped packets xrun (%u)\n", dropped_cycles); 
    501557            debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to dropped packets xrun\n"); 
    502558            m_cycle_to_switch_state = CYCLE_TIMER_GET_CYCLES(pkt_ctr) + 1; 
     
    554610            debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 
    555611                               "XMIT SILENT: CY=%04u TS=%011llu\n", 
    556                                cycle, m_last_timestamp); 
     612                               CYCLE_TIMER_GET_CYCLES(pkt_ctr), m_last_timestamp); 
    557613 
    558614            // assumed not to xrun 
     
    605661            debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 
    606662                               "XMIT: CY=%04u TS=%011llu\n", 
    607                                cycle, m_last_timestamp); 
     663                               CYCLE_TIMER_GET_CYCLES(pkt_ctr), m_last_timestamp); 
    608664 
    609665            // valid packet timestamp 
     
    876932StreamProcessor::shiftStream(int nbframes) 
    877933{ 
     934    // FIXME: this is not a good idea since the ISO thread is also writing the buffer 
     935    // resulting in multiple writers (not supported) 
    878936    bool result; 
    879937    if(nbframes == 0) return true; 
    880938    if(nbframes > 0) { 
     939        debugOutput(DEBUG_LEVEL_VERBOSE, 
     940                    "(%p) dropping %d frames\n", 
     941                    this, nbframes); 
    881942        result = m_data_buffer->dropFrames(nbframes); 
    882         SIGNAL_ACTIVITY_ALL; 
     943    } else { 
     944        result = false; 
    883945        return result; 
    884     } else { 
    885         result = true; 
     946        debugOutput(DEBUG_LEVEL_VERBOSE, 
     947                    "(%p) adding %d frames\n", 
     948                    this, nbframes); 
    886949        while(nbframes++) { 
    887950            result &= m_data_buffer->writeDummyFrame(); 
    888951        } 
    889         SIGNAL_ACTIVITY_ALL; 
    890         return result
    891     } 
     952    } 
     953    SIGNAL_ACTIVITY_ALL
     954    return result; 
    892955} 
    893956 
     
    17671830        case ePS_Running: return "ePS_Running"; 
    17681831        case ePS_WaitingForStreamDisable: return "ePS_WaitingForStreamDisable"; 
     1832        case ePS_Error: return "ePS_Error"; 
    17691833        default: return "error: unknown state"; 
    17701834    } 
     
    17931857    #ifdef DEBUG 
    17941858    debugOutputShort( DEBUG_LEVEL_NORMAL, " StreamProcessor %p, %s:\n", this, ePTToString(m_processor_type)); 
    1795     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Port, Channel  : %d, %d\n", m_1394service.getPort(), m_channel); 
     1859    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Port, Channel    : %d, %d\n", m_1394service.getPort(), m_channel); 
     1860    IsoHandler *h = m_IsoHandlerManager.getHandlerForStream(this); 
     1861    if (h) { 
     1862        debugOutputShort( DEBUG_LEVEL_NORMAL, "  Packets, Dropped, Skipped : %d, %d, %d\n", 
     1863                                              h->m_packets, h->m_dropped, h->m_skipped); 
     1864    } else { 
     1865        debugError("No handler for stream??\n"); 
     1866    } 
    17961867    uint64_t now = m_1394service.getCycleTimerTicks(); 
    17971868    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Now                   : %011llu (%03us %04uc %04ut)\n", 
     
    18351906    PortManager::setVerboseLevel(l); 
    18361907    m_data_buffer->setVerboseLevel(l); 
     1908    debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l ); 
    18371909} 
    18381910 
  • trunk/libffado/src/libstreaming/generic/StreamProcessor.h

    r1036 r1336  
    7979        ePS_Running, 
    8080        ePS_WaitingForStreamDisable, 
     81        ePS_Error, 
    8182    }; 
    8283 
     
    113114    bool isWaitingForStream() 
    114115            {return m_state == ePS_WaitingForStream;}; 
     116    bool inError() 
     117            {return m_state == ePS_Error;}; 
    115118 
    116119    // these schedule and wait for the state transition 
     
    131134    bool prepare(); 
    132135 
    133     void handleBusReset(); 
     136    bool handleBusReset(); 
     137 
     138    // the one to be implemented by the child class 
     139    virtual bool handleBusResetDo(); 
     140 
     141    FFADODevice& getParent() {return m_Parent;}; 
    134142 
    135143public: // constructor/destructor 
     
    153161        putPacket(unsigned char *data, unsigned int length, 
    154162                  unsigned char channel, unsigned char tag, unsigned char sy, 
    155                   uint32_t pkt_ctr, unsigned int dropped, unsigned int skipped); 
     163                  uint32_t pkt_ctr, unsigned int dropped); 
    156164 
    157165    enum raw1394_iso_disposition 
  • trunk/libffado/src/libstreaming/StreamProcessorManager.cpp

    r1254 r1336  
    2929#include "libieee1394/cycletimer.h" 
    3030 
     31#include "devicemanager.h" 
     32 
    3133#include "libutil/Time.h" 
    3234 
     
    3941IMPL_DEBUG_MODULE( StreamProcessorManager, StreamProcessorManager, DEBUG_LEVEL_VERBOSE ); 
    4042 
    41 StreamProcessorManager::StreamProcessorManager(
     43StreamProcessorManager::StreamProcessorManager(DeviceManager &p
    4244    : m_is_slave( false ) 
    4345    , m_SyncSource(NULL) 
     46    , m_parent( p ) 
    4447    , m_xrun_happened( false ) 
    4548    , m_activity_wait_timeout_usec( 1000*1000 ) 
     
    5154    , m_shutdown_needed(false) 
    5255    , m_nbperiods(0) 
    53     , m_WaitLock( new Util::PosixMutex
     56    , m_WaitLock( new Util::PosixMutex("SPMWAIT")
    5457{ 
    5558    addOption(Util::OptionContainer::Option("slaveMode",false)); 
     
    5760} 
    5861 
    59 StreamProcessorManager::StreamProcessorManager(unsigned int period, unsigned int framerate, unsigned int nb_buffers) 
     62StreamProcessorManager::StreamProcessorManager(DeviceManager &p, unsigned int period, 
     63                                               unsigned int framerate, unsigned int nb_buffers) 
    6064    : m_is_slave( false ) 
    6165    , m_SyncSource(NULL) 
     66    , m_parent( p ) 
    6267    , m_xrun_happened( false ) 
    6368    , m_activity_wait_timeout_usec( 1000*1000 ) 
     
    6974    , m_shutdown_needed(false) 
    7075    , m_nbperiods(0) 
    71     , m_WaitLock( new Util::PosixMutex
     76    , m_WaitLock( new Util::PosixMutex("SPMWAIT")
    7277{ 
    7378    addOption(Util::OptionContainer::Option("slaveMode",false)); 
     
    8186} 
    8287 
    83 void 
    84 StreamProcessorManager::handleBusReset() 
    85 
    86     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) Handle bus reset...\n", this); 
    87  
    88     // FIXME: we request shutdown for now. 
    89     m_shutdown_needed=true; 
    90  
    91     // note that all receive streams are gone once a device is unplugged 
    92  
    93     // synchronize with the wait lock 
    94     Util::MutexLockHelper lock(*m_WaitLock); 
    95  
    96     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) got wait lock...\n", this); 
    97     // cause all SP's to bail out 
    98     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    99           it != m_ReceiveProcessors.end(); 
    100           ++it ) 
    101     { 
    102         (*it)->handleBusReset(); 
    103     } 
    104     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    105           it != m_TransmitProcessors.end(); 
    106           ++it ) 
    107     { 
    108         (*it)->handleBusReset(); 
    109     } 
    110 
     88// void 
     89// StreamProcessorManager::handleBusReset(Ieee1394Service &s) 
     90// { 
     91// //     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) Handle bus reset on service %p...\n", this, &s); 
     92// //  
     93// //     bool handled_at_least_one = false; 
     94// //     // note that all receive streams are gone once a device is unplugged 
     95// //  
     96// //     // synchronize with the wait lock 
     97// //     Util::MutexLockHelper lock(*m_WaitLock); 
     98// //  
     99// //     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) got wait lock...\n", this); 
     100// //     // cause all SP's to bail out 
     101// //     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     102// //           it != m_ReceiveProcessors.end(); 
     103// //           ++it ) 
     104// //     { 
     105// //         if(&s == &((*it)->getParent().get1394Service())) { 
     106// //             debugOutput(DEBUG_LEVEL_NORMAL, 
     107// //                         "issue busreset on receive SPM on channel %d\n", 
     108// //                         (*it)->getChannel()); 
     109// //             (*it)->handleBusReset(); 
     110// //             handled_at_least_one = true; 
     111// //         } else { 
     112// //             debugOutput(DEBUG_LEVEL_NORMAL, 
     113// //                         "skipping receive SPM on channel %d since not on service %p\n", 
     114// //                         (*it)->getChannel(), &s); 
     115// //         } 
     116// //     } 
     117// //     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     118// //           it != m_TransmitProcessors.end(); 
     119// //           ++it ) 
     120// //     { 
     121// //         if(&s == &((*it)->getParent().get1394Service())) { 
     122// //             debugOutput(DEBUG_LEVEL_NORMAL, 
     123// //                         "issue busreset on transmit SPM on channel %d\n", 
     124// //                         (*it)->getChannel()); 
     125// //             (*it)->handleBusReset(); 
     126// //             handled_at_least_one = true; 
     127// //         } else { 
     128// //             debugOutput(DEBUG_LEVEL_NORMAL, 
     129// //                         "skipping transmit SPM on channel %d since not on service %p\n", 
     130// //                         (*it)->getChannel(), &s); 
     131// //         } 
     132// //     } 
     133// //  
     134// //     // FIXME: we request shutdown for now. 
     135// //     m_shutdown_needed = handled_at_least_one; 
     136// } 
    111137 
    112138void 
     
    124150    int result; 
    125151 
    126     if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { 
    127         debugError("clock_gettime failed\n"); 
    128         return eAR_Error; 
    129     } 
    130152    long long int timeout_nsec=0; 
    131     int timeout_sec = 0; 
    132153    if (m_activity_wait_timeout_usec >= 0) { 
    133154        timeout_nsec = m_activity_wait_timeout_usec * 1000LL; 
    134         timeout_sec = 0; 
    135         while(timeout_nsec >= 1000000000LL) { 
    136             timeout_sec += 1
    137             timeout_nsec -= 1000000000LL
     155 
     156        if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { 
     157            debugError("clock_gettime failed\n")
     158            return eAR_Error
    138159        } 
    139160        ts.tv_nsec += timeout_nsec; 
    140         ts.tv_sec += timeout_sec; 
     161        while(ts.tv_nsec >= 1000000000LL) { 
     162            ts.tv_sec += 1; 
     163            ts.tv_nsec -= 1000000000LL; 
     164        } 
    141165    } 
    142166 
     
    158182                        this, result); 
    159183            return eAR_Interrupted; 
     184        } else if (errno == EINVAL) { 
     185            debugError("(%p) sem_[timed]wait error (result=%d errno=EINVAL)\n",  
     186                        this, result); 
     187            debugError("(%p) timeout_nsec=%lld ts.sec=%d ts.nsec=%lld\n",  
     188                       this, timeout_nsec, ts.tv_sec, ts.tv_nsec); 
     189            return eAR_Error; 
    160190        } else { 
    161191            debugError("(%p) sem_[timed]wait error (result=%d errno=%d)\n",  
    162192                        this, result, errno); 
    163             debugError("(%p) timeout_sec=%d timeout_nsec=%lld ts.sec=%d ts.nsec=%lld\n",  
    164                        this, timeout_sec, timeout_nsec, ts.tv_sec, ts.tv_nsec); 
     193            debugError("(%p) timeout_nsec=%lld ts.sec=%d ts.nsec=%lld\n",  
     194                       this, timeout_nsec, ts.tv_sec, ts.tv_nsec); 
    165195            return eAR_Error; 
    166196        } 
     
    319349        return false; 
    320350    } 
     351 
     352    // set the activity timeout value to two periods worth of usecs. 
     353    // since we can expect activity once every period, but we might have some 
     354    // offset, the safe value is two periods. 
     355    int timeout_usec = 2*1000LL * 1000LL * m_period / m_nominal_framerate; 
     356    debugOutput(DEBUG_LEVEL_VERBOSE, "setting activity timeout to %d\n", timeout_usec); 
     357    setActivityWaitTimeoutUsec(timeout_usec); 
     358 
    321359    return true; 
    322360} 
     
    330368            it != m_TransmitProcessors.end(); 
    331369            ++it ) { 
     370        if ((*it)->inError()) { 
     371            debugOutput(DEBUG_LEVEL_VERBOSE, "SP %p in error state\n", *it); 
     372            return false; 
     373        } 
    332374        if (!(*it)->isDryRunning()) { 
    333375            if(!(*it)->scheduleStartDryRunning(-1)) { 
     
    342384            it != m_ReceiveProcessors.end(); 
    343385            ++it ) { 
     386        if ((*it)->inError()) { 
     387            debugOutput(DEBUG_LEVEL_VERBOSE, "SP %p in error state\n", *it); 
     388            return false; 
     389        } 
    344390        if (!(*it)->isDryRunning()) { 
    345391            if(!(*it)->scheduleStartDryRunning(-1)) { 
     
    687733        } else { 
    688734            debugOutput(DEBUG_LEVEL_VERBOSE, "Sync start try %d failed...\n", ntries); 
     735            if(m_shutdown_needed) { 
     736                debugOutput(DEBUG_LEVEL_VERBOSE, "Some fatal error occurred, stop trying.\n"); 
     737                return false; 
     738            } 
    689739        } 
    690740    } 
     
    693743        return false; 
    694744    } 
    695  
     745    debugOutput( DEBUG_LEVEL_VERBOSE, " Started...\n"); 
    696746    return true; 
    697747} 
     
    730780            it != m_ReceiveProcessors.end(); 
    731781            ++it ) { 
    732             ready &= ((*it)->isDryRunning() || (*it)->isStopped() || (*it)->isWaitingForStream()); 
     782            ready &= ((*it)->isDryRunning() || (*it)->isStopped() || (*it)->isWaitingForStream() || (*it)->inError()); 
    733783        } 
    734784        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    735785            it != m_TransmitProcessors.end(); 
    736786            ++it ) { 
    737             ready &= ((*it)->isDryRunning() || (*it)->isStopped() || (*it)->isWaitingForStream()); 
     787            ready &= ((*it)->isDryRunning() || (*it)->isStopped() || (*it)->isWaitingForStream() || (*it)->inError()); 
    738788        } 
    739789        SleepRelativeUsec(125); 
     
    759809          it != m_ReceiveProcessors.end(); 
    760810          ++it ) { 
    761         if(!(*it)->scheduleStopDryRunning(-1)) { 
     811        if ((*it)->inError()) { 
     812            debugOutput(DEBUG_LEVEL_VERBOSE, "SP %p in error state\n", *it); 
     813        } else if(!(*it)->scheduleStopDryRunning(-1)) { 
    762814            debugError("%p->scheduleStopDryRunning(-1) failed\n", *it); 
    763815            return false; 
     
    767819          it != m_TransmitProcessors.end(); 
    768820          ++it ) { 
    769         if(!(*it)->scheduleStopDryRunning(-1)) { 
     821        if ((*it)->inError()) { 
     822            debugOutput(DEBUG_LEVEL_VERBOSE, "SP %p in error state\n", *it); 
     823        } else if(!(*it)->scheduleStopDryRunning(-1)) { 
    770824            debugError("%p->scheduleStopDryRunning(-1) failed\n", *it); 
    771825            return false; 
     
    780834            it != m_ReceiveProcessors.end(); 
    781835            ++it ) { 
    782             ready &= (*it)->isStopped(); 
     836            ready &= ((*it)->isStopped() || (*it)->inError()); 
    783837        } 
    784838        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    785839            it != m_TransmitProcessors.end(); 
    786840            ++it ) { 
    787             ready &= (*it)->isStopped(); 
     841            ready &= ((*it)->isStopped() || (*it)->inError()); 
    788842        } 
    789843        SleepRelativeUsec(125); 
     
    804858        return false; 
    805859    } 
     860    debugOutput( DEBUG_LEVEL_VERBOSE, " Stopped...\n"); 
    806861    return true; 
    807862} 
     
    874929    if(m_shutdown_needed) return false; 
    875930    bool xrun_occurred = false; 
     931    bool in_error = false; 
    876932    bool period_not_ready = true; 
    877933 
     
    889945            case eAR_Error: 
    890946                debugError("Error while waiting for activity\n"); 
     947                m_shutdown_needed = true; 
    891948                return false; 
    892949            case eAR_Interrupted: 
     
    895952                break; 
    896953            case eAR_Timeout: 
    897                 // FIXME: what to do here? 
    898954                debugWarning("Timeout while waiting for activity\n"); 
    899                 break; 
     955                // ignore this since it can also be due to some other hardware 
     956                // or high-prio software that preempts us. hence only an xrun should 
     957                // be generated (if necessary) 
    900958            case eAR_Activity: 
    901959                // do nothing 
     
    924982        debugOutputExtreme(DEBUG_LEVEL_VERBOSE, " period not ready? %d...\n", period_not_ready); 
    925983 
    926         // check for underruns on the ISO side, 
     984        // check for underruns/errors on the ISO side, 
    927985        // those should make us bail out of the wait loop 
    928986        for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     
    931989            // a xrun has occurred on the Iso side 
    932990            xrun_occurred |= (*it)->xrunOccurred(); 
     991            in_error |= (*it)->inError(); 
    933992        } 
    934993        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     
    937996            // a xrun has occurred on the Iso side 
    938997            xrun_occurred |= (*it)->xrunOccurred(); 
    939         } 
    940         if(xrun_occurred) break; 
    941         // FIXME: make sure we also exit this loop when something else happens (e.g. signal, iso error) 
    942  
    943         // if we have to shutdown due to some async event (busreset), do so 
    944         if(m_shutdown_needed) break; 
     998            in_error |= (*it)->inError(); 
     999        } 
     1000        if(xrun_occurred | in_error | m_shutdown_needed) break; 
    9451001    } 
    9461002 
    9471003    if(xrun_occurred) { 
    9481004        debugOutput( DEBUG_LEVEL_VERBOSE, "exit due to xrun...\n"); 
     1005    } 
     1006    if(in_error) { 
     1007        debugOutput( DEBUG_LEVEL_VERBOSE, "exit due to error...\n"); 
     1008        m_shutdown_needed = true; 
    9491009    } 
    9501010 
     
    12041264 
    12051265void StreamProcessorManager::setVerboseLevel(int l) { 
    1206     setDebugLevel(l); 
    12071266    if(m_WaitLock) m_WaitLock->setVerboseLevel(l); 
    12081267 
    1209     debugOutput( DEBUG_LEVEL_VERBOSE, " Receive processors...\n"); 
    12101268    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    12111269        it != m_ReceiveProcessors.end(); 
     
    12131271        (*it)->setVerboseLevel(l); 
    12141272    } 
    1215  
    1216     debugOutput( DEBUG_LEVEL_VERBOSE, " Transmit processors...\n"); 
    12171273    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    12181274        it != m_TransmitProcessors.end(); 
     
    12201276        (*it)->setVerboseLevel(l); 
    12211277    } 
    1222 
    1223  
     1278    setDebugLevel(l); 
     1279    debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l ); 
     1280
    12241281 
    12251282int StreamProcessorManager::getPortCount(enum Port::E_PortType type, enum Port::E_Direction direction) { 
     
    12621319 
    12631320// TODO: implement a port map here, instead of the loop 
    1264  
    12651321Port* StreamProcessorManager::getPortByIndex(int idx, enum Port::E_Direction direction) { 
    12661322    int count=0; 
  • trunk/libffado/src/libstreaming/StreamProcessorManager.h

    r1045 r1336  
    3636#include <semaphore.h> 
    3737 
     38class DeviceManager; 
     39 
    3840namespace Streaming { 
    3941 
     
    5658    }; 
    5759 
    58     StreamProcessorManager(); 
    59     StreamProcessorManager(unsigned int period, unsigned int rate, unsigned int nb_buffers); 
     60    StreamProcessorManager(DeviceManager &parent); 
     61    StreamProcessorManager(DeviceManager &parent, unsigned int period, 
     62                           unsigned int rate, unsigned int nb_buffers); 
    6063    virtual ~StreamProcessorManager(); 
    61  
    62     void handleBusReset(); 
    6364 
    6465    bool prepare(); ///< to be called after the processors are registered 
     
    9596    void setNbBuffers(unsigned int nb_buffers) 
    9697            {m_nb_buffers = nb_buffers;}; 
    97     int getNbBuffers()  
     98    unsigned int getNbBuffers()  
    9899            {return m_nb_buffers;}; 
     100 
     101    // this is the amount of usecs we wait before an activity 
     102    // timeout occurs. 
     103    void setActivityWaitTimeoutUsec(int usec) 
     104            {m_activity_wait_timeout_usec = usec;}; 
     105    int getActivityWaitTimeoutUsec()  
     106            {return m_activity_wait_timeout_usec;}; 
    99107 
    100108    int getPortCount(enum Port::E_PortType, enum Port::E_Direction); 
     
    106114    bool transfer(); 
    107115    bool transfer(enum StreamProcessor::eProcessorType); 
     116 
     117    // for bus reset handling 
     118    void lockWaitLoop() {m_WaitLock->Lock();}; 
     119    void unlockWaitLoop() {m_WaitLock->Unlock();}; 
     120 
    108121private: 
    109122    bool transferSilence(); 
     
    150163protected: // FIXME: private? 
    151164 
     165    // parent device manager 
     166    DeviceManager &m_parent; 
     167 
    152168    // thread related vars 
    153169    bool m_xrun_happened; 
  • trunk/libffado/src/libutil/PosixMutex.cpp

    r1211 r1336  
    4949PosixMutex::PosixMutex() 
    5050{ 
     51    m_id = "?"; 
    5152    pthread_mutexattr_t attr; 
    5253    pthread_mutexattr_init(&attr); 
     
    6465} 
    6566 
     67PosixMutex::PosixMutex(std::string id) 
     68{ 
     69    m_id = id; 
     70    pthread_mutexattr_t attr; 
     71    pthread_mutexattr_init(&attr); 
     72    #ifdef DEBUG 
     73        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); 
     74    #else 
     75        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT); 
     76    #endif 
     77    pthread_mutex_init(&m_mutex, &attr); 
     78    pthread_mutexattr_destroy(&attr); 
     79 
     80    #if DEBUG_LOCK_COLLISION_TRACING 
     81    m_locked_by = NULL; 
     82    #endif 
     83} 
     84 
    6685PosixMutex::~PosixMutex() 
    6786{ 
     
    7392{ 
    7493    int err; 
    75     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(%p) lock\n", this); 
     94    debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(%s, %p) lock\n", m_id.c_str(), this); 
    7695    #if DEBUG_LOCK_COLLISION_TRACING 
    7796    if(TryLock()) { 
     
    84103 
    85104        debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 
    86                     "(%p) %s obtained lock\n", 
    87                     this, name); 
     105                    "(%s, %p) %s obtained lock\n", 
     106                    m_id.c_str(), this, name); 
    88107        return; 
    89108    } else { 
     
    97116        debugGetFunctionNameFromAddr(m_locked_by, name2, DEBUG_LOCK_COLLISION_TRACING_NAME_MAXLEN); 
    98117 
    99         debugWarning("(%p) lock collision: %s wants lock, %s has lock\n", 
    100                     this, name1, name2); 
     118        debugWarning("(%s, %p) lock collision: %s wants lock, %s has lock\n", 
     119                    m_id.c_str(), this, name1, name2); 
    101120        if((err = pthread_mutex_lock(&m_mutex))) { 
    102121            if (err == EDEADLK) { 
    103                 debugError("Resource deadlock detected\n"); 
     122                debugError("(%s, %p) Resource deadlock detected\n", m_id.c_str(), this); 
    104123                debugPrintBacktrace(10); 
    105124            } else { 
    106                 debugError("Error locking the mutex: %d\n", err); 
     125                debugError("(%s, %p) Error locking the mutex: %d\n", m_id.c_str(), this, err); 
    107126            } 
    108127        } else { 
    109             debugWarning("(%p) lock collision: %s got lock (from %s?)\n", 
    110                         this, name1, name2); 
     128            debugWarning("(%s, %p) lock collision: %s got lock (from %s?)\n", 
     129                        m_id.c_str(), this, name1, name2); 
    111130        } 
    112131    } 
     
    115134    if((err = pthread_mutex_lock(&m_mutex))) { 
    116135        if (err == EDEADLK) { 
    117             debugError("Resource deadlock detected\n"); 
     136            debugError("(%s, %p) Resource deadlock detected\n", m_id.c_str(), this); 
    118137            debugPrintBacktrace(10); 
    119138        } else { 
    120             debugError("Error locking the mutex: %d\n", err); 
     139            debugError("(%s, %p) Error locking the mutex: %d\n", m_id.c_str(), this, err); 
    121140        } 
    122141    } 
     
    130149PosixMutex::TryLock() 
    131150{ 
    132     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(%p) trying to lock\n", this); 
     151    debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(%s, %p) trying to lock\n", m_id.c_str(), this); 
    133152    return pthread_mutex_trylock(&m_mutex) == 0; 
    134153} 
     
    137156PosixMutex::isLocked() 
    138157{ 
    139     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(%p) checking lock\n", this); 
    140     int res=pthread_mutex_trylock(&m_mutex); 
     158    debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(%s, %p) checking lock\n", m_id.c_str(), this); 
     159    int res = pthread_mutex_trylock(&m_mutex); 
    141160    if(res == 0) { 
    142161        pthread_mutex_unlock(&m_mutex); 
    143162        return false; 
    144163    } else { 
    145         if(res != EBUSY) { 
    146             debugError("Bogus error code: %d\n", res); 
     164        if (res == EDEADLK) { 
     165            // this means that the current thread already has the lock, 
     166            // iow it's locked. 
     167            debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(%s, %p) lock taken by current thread\n", m_id.c_str(), this); 
     168        } else if(res == EBUSY) { 
     169            debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(%s, %p) lock taken\n", m_id.c_str(), this); 
     170        } else { 
     171            debugError("(%s, %p) Bogus error code: %d\n", m_id.c_str(), this, res); 
    147172        } 
    148173        return true; 
     
    153178PosixMutex::Unlock() 
    154179{ 
    155     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(%p) unlock\n", this); 
     180    debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(%s, %p) unlock\n", m_id.c_str(), this); 
    156181    #if DEBUG_LOCK_COLLISION_TRACING 
    157182    // unlocking 
     
    162187    debugGetFunctionNameFromAddr(unlocker, name, DEBUG_LOCK_COLLISION_TRACING_NAME_MAXLEN); 
    163188    debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 
    164                 "(%p) %s releases lock\n", 
    165                 this, name); 
     189                "(%s, %p) %s releases lock\n", 
     190                m_id.c_str(), this, name); 
    166191    #endif 
    167192 
     
    169194    int err; 
    170195    if((err = pthread_mutex_unlock(&m_mutex))) { 
    171         debugError("Error unlocking the mutex: %d\n", err); 
     196        debugError("(%s, %p) Error unlocking the mutex: %d\n", m_id.c_str(), this, err); 
    172197    } 
    173198    #else 
     
    179204PosixMutex::show() 
    180205{ 
    181     debugOutput(DEBUG_LEVEL_NORMAL, "(%p) mutex (%s)\n", this, (isLocked() ? "Locked" : "Unlocked")); 
     206    debugOutput(DEBUG_LEVEL_NORMAL, "(%s, %p) mutex (%s)\n", m_id.c_str(), this, (isLocked() ? "Locked" : "Unlocked")); 
    182207} 
    183208 
  • trunk/libffado/src/libutil/PosixMutex.h

    r1254 r1336  
    2929#include "Mutex.h" 
    3030#include <pthread.h> 
     31#include <string> 
    3132 
    3233#include "debugmodule/debugmodule.h" 
     
    4344public: 
    4445    PosixMutex(); 
     46    PosixMutex(std::string id); 
    4547    virtual ~PosixMutex(); 
    4648 
     
    6062    pthread_mutex_t m_mutex; 
    6163 
     64    std::string m_id; 
     65 
    6266    #if DEBUG_LOCK_COLLISION_TRACING 
    6367    void *m_locked_by; 
  • trunk/libffado/src/libutil/PosixThread.cpp

    r1096 r1336  
    7474    } 
    7575 
    76     debugOutput( DEBUG_LEVEL_VERBOSE, "ThreadHandler: start %p\n", obj); 
     76    debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) ThreadHandler: start %p\n", obj->m_id.c_str(), obj); 
    7777 
    7878    // If Init succeed start the thread loop 
    7979    bool res = true; 
    8080    while (obj->fRunning && res) { 
    81         debugOutputExtreme( DEBUG_LEVEL_VERY_VERBOSE, "ThreadHandler: run %p\n", obj); 
     81        debugOutputExtreme( DEBUG_LEVEL_VERY_VERBOSE, "(%s) ThreadHandler: run %p\n", obj->m_id.c_str(), obj); 
    8282        res = runnable->Execute(); 
    8383        pthread_testcancel(); 
    8484    } 
    8585 
    86     debugOutput( DEBUG_LEVEL_VERBOSE, "ThreadHandler: exit %p\n", obj); 
     86    debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) ThreadHandler: exit %p\n", obj->m_id.c_str(), obj); 
    8787    return 0; 
    8888} 
     
    9595    if (fRealTime) { 
    9696 
    97         debugOutput( DEBUG_LEVEL_VERBOSE, "Create RT thread %p with priority %d\n", this, fPriority); 
     97        debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Create RT thread %p with priority %d\n", m_id.c_str(), this, fPriority); 
    9898 
    9999        /* Get the client thread to run as an RT-FIFO 
     
    139139        return 0; 
    140140    } else { 
    141         debugOutput( DEBUG_LEVEL_VERBOSE, "Create non RT thread %p\n", this); 
     141        debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Create non RT thread %p\n", m_id.c_str(), this); 
    142142 
    143143        if ((res = pthread_create(&fThread, 0, ThreadHandler, this))) { 
     
    153153{ 
    154154    if (fThread) { // If thread has been started 
    155         debugOutput( DEBUG_LEVEL_VERBOSE, "PosixThread::Kill %p (thread: %p)\n", this, fThread); 
     155        debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Kill %p (thread: %p)\n", m_id.c_str(), this, fThread); 
    156156        void* status; 
    157157        pthread_cancel(fThread); 
    158158        pthread_join(fThread, &status); 
    159         debugOutput( DEBUG_LEVEL_VERBOSE, "PosixThread::Killed %p (thread: %p)\n", this, fThread); 
     159        debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Killed %p (thread: %p)\n", m_id.c_str(), this, fThread); 
    160160        return 0; 
    161161    } else { 
     
    167167{ 
    168168    if (fThread) { // If thread has been started 
    169         debugOutput( DEBUG_LEVEL_VERBOSE, "PosixThread::Stop %p (thread: %p)\n", this, fThread); 
     169        debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Stop %p (thread: %p)\n", m_id.c_str(), this, fThread); 
    170170        void* status; 
    171171        fRunning = false; // Request for the thread to stop 
    172172        pthread_join(fThread, &status); 
    173         debugOutput( DEBUG_LEVEL_VERBOSE, "PosixThread::Stopped %p (thread: %p)\n", this, fThread); 
     173        debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Stopped %p (thread: %p)\n", m_id.c_str(), this, fThread); 
    174174        return 0; 
    175175    } else { 
     
    182182    struct sched_param rtparam; 
    183183    int res; 
    184     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) Aquire realtime, prio %d\n", this, fPriority); 
     184    debugOutput( DEBUG_LEVEL_VERBOSE, "(%s, %p) Aquire realtime, prio %d\n", m_id.c_str(), this, fPriority); 
    185185 
    186186    if (!fThread) 
     
    211211    struct sched_param rtparam; 
    212212    int res; 
    213     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) Drop realtime\n", this); 
     213    debugOutput( DEBUG_LEVEL_VERBOSE, "(%s, %p) Drop realtime\n", m_id.c_str(), this); 
    214214 
    215215    if (!fThread) 
  • trunk/libffado/src/libutil/PosixThread.h

    r864 r1336  
    8787        {} 
    8888 
     89        PosixThread(RunnableInterface* runnable, std::string id, bool real_time, int priority, int cancellation) 
     90                : Thread(runnable, id), fThread((pthread_t)NULL), fPriority(priority), fRealTime(real_time), fRunning(false), fCancellation(cancellation) 
     91        {} 
     92        PosixThread(RunnableInterface* runnable, std::string id) 
     93                : Thread(runnable, id), fThread((pthread_t)NULL), fPriority(0), fRealTime(false), fRunning(false), fCancellation(PTHREAD_CANCEL_DEFERRED) 
     94        {} 
     95        PosixThread(RunnableInterface* runnable, std::string id, int cancellation) 
     96                : Thread(runnable, id), fThread((pthread_t)NULL), fPriority(0), fRealTime(false), fRunning(false), fCancellation(cancellation) 
     97        {} 
     98 
    8999        virtual ~PosixThread() 
    90100        {} 
  • trunk/libffado/src/libutil/Thread.h

    r1144 r1336  
    5656#include "Atomic.h" 
    5757#include <pthread.h> 
     58#include <string> 
    5859 
    5960namespace Util 
     
    9495    public: 
    9596 
    96         Thread(RunnableInterface* runnable): fRunnable(runnable) 
     97        Thread(RunnableInterface* runnable) 
     98        : fRunnable(runnable) 
     99        , m_id( "UNKNOWN" ) 
     100        {} 
     101        Thread(RunnableInterface* runnable, std::string id) 
     102        : fRunnable(runnable) 
     103        , m_id( id ) 
    97104        {} 
    98105        virtual ~Thread() 
     
    113120 
    114121        virtual void setVerboseLevel(int l) 
    115             {setDebugLevel(l);}; 
     122            { 
     123                setDebugLevel(l); 
     124                debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Setting verbose level to %d...\n", m_id.c_str(), l ); 
     125            }; 
    116126    protected: 
    117             DECLARE_DEBUG_MODULE; 
     127        std::string m_id; 
     128        DECLARE_DEBUG_MODULE; 
    118129 
    119130}; 
  • trunk/libffado/src/libutil/TimestampedBuffer.cpp

    r1234 r1336  
    166166 
    167167    debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 
    168                        "for (%p) to "TIMESTAMP_FORMAT_SPEC" => "TIMESTAMP_FORMAT_SPEC",
     168                       "for (%p)
    169169                       "NTS="TIMESTAMP_FORMAT_SPEC", DLL2=%f, RATE=%f\n", 
    170                        this, new_timestamp, ts, m_buffer_next_tail_timestamp, m_dll_e2, getRate()); 
     170                       this, m_buffer_next_tail_timestamp, m_dll_e2, getRate()); 
    171171} 
    172172 
     
    289289 * 
    290290 * Resets the TimestampedBuffer, clearing the buffers and counters. 
    291  * (not true yet: Also resets the DLL to the nominal values.) 
     291 * Also resets the DLL to the nominal values. 
    292292 * 
    293293 * \note when this is called, you should make sure that the buffer 
     
    300300    ffado_ringbuffer_reset(m_event_buffer); 
    301301    resetFrameCounter(); 
     302 
     303    m_current_rate = m_nominal_rate; 
     304    m_dll_e2=m_nominal_rate * (float)m_update_period; 
     305    // this will init the internal timestamps to a sensible value 
     306    setBufferTailTimestamp(m_buffer_tail_timestamp); 
     307 
    302308    return true; 
    303309} 
  • trunk/libffado/src/libutil/TimestampedBuffer.h

    r1001 r1336  
    2525#define __FFADO_TIMESTAMPEDBUFFER__ 
    2626 
    27 #include "../debugmodule/debugmodule.h" 
     27#include "debugmodule/debugmodule.h" 
    2828#include "libutil/ringbuffer.h" 
    2929#include <pthread.h> 
  • trunk/libffado/src/libutil/Watchdog.cpp

    r1165 r1336  
    205205        return false; 
    206206    } 
    207     m_HartbeatThread = new Util::PosixThread(m_HartbeatTask, false, 
     207    m_HartbeatThread = new Util::PosixThread(m_HartbeatTask, "WDGHBT", false, 
    208208                                             0, PTHREAD_CANCEL_ASYNCHRONOUS); 
    209209    if(!m_HartbeatThread) { 
     
    221221        return false; 
    222222    } 
    223     m_CheckThread = new Util::PosixThread(m_CheckTask, false, 
     223    m_CheckThread = new Util::PosixThread(m_CheckTask,"WDGCHK", false, 
    224224                                          0, PTHREAD_CANCEL_ASYNCHRONOUS); 
    225225    if(!m_CheckThread) { 
  • trunk/libffado/src/metrichalo/mh_avdevice.cpp

    r1239 r1336  
    126126} 
    127127 
     128std::vector<int> 
     129MHAvDevice::getSupportedSamplingFrequencies() 
     130{ 
     131    std::vector<int> frequencies; 
     132    return frequencies; 
     133} 
     134 
    128135FFADODevice::ClockSourceVector 
    129136MHAvDevice::getSupportedClockSources() { 
  • trunk/libffado/src/metrichalo/mh_avdevice.h

    r1239 r1336  
    6161    virtual bool setSamplingFrequency( int ); 
    6262    virtual int getSamplingFrequency( ); 
     63    virtual std::vector<int> getSupportedSamplingFrequencies(); 
    6364 
    6465    virtual ClockSourceVector getSupportedClockSources(); 
  • trunk/libffado/src/motu/motu_avdevice.cpp

    r1274 r1336  
    3838#include "libutil/DelayLockedLoop.h" 
    3939#include "libutil/Time.h" 
     40#include "libutil/Configuration.h" 
    4041 
    4142#include "libcontrol/BasicElements.h" 
     
    302303}; 
    303304 
    304 const MixerCtrl MixerCtrls_828Mk2[] = { 
     305const MatrixMixBus MixerBuses_Ultralite[] = { 
     306    {"Mix 1", 0x4000, }, 
     307    {"Mix 2", 0x4100, }, 
     308    {"Mix 3", 0x4200, }, 
     309    {"Mix 4", 0x4300, }, 
     310}; 
     311 
     312const MatrixMixChannel MixerChannels_Ultralite[] = { 
     313    {"Analog 1", MOTU_CTRL_STD_CHANNEL, 0x0000, }, 
     314    {"Analog 2", MOTU_CTRL_STD_CHANNEL, 0x0004, }, 
     315    {"Analog 3", MOTU_CTRL_STD_CHANNEL, 0x0008, }, 
     316    {"Analog 4", MOTU_CTRL_STD_CHANNEL, 0x000c, }, 
     317    {"Analog 5", MOTU_CTRL_STD_CHANNEL, 0x0010, }, 
     318    {"Analog 6", MOTU_CTRL_STD_CHANNEL, 0x0014, }, 
     319    {"Analog 7", MOTU_CTRL_STD_CHANNEL, 0x0018, }, 
     320    {"Analog 8", MOTU_CTRL_STD_CHANNEL, 0x001c, }, 
     321    {"SPDIF 1", MOTU_CTRL_STD_CHANNEL, 0x0020, }, 
     322    {"SPDIF 2", MOTU_CTRL_STD_CHANNEL, 0x0024, }, 
     323}; 
     324 
     325const MixerCtrl MixerCtrls_Ultralite[] = { 
    305326    {"Mix1/Mix_", "Mix 1 ", "", MOTU_CTRL_STD_MIX, 0x0c20, }, 
    306327    {"Mix2/Mix_", "Mix 2 ", "", MOTU_CTRL_STD_MIX, 0x0c24, }, 
     
    326347}; 
    327348 
     349const MixerCtrl MixerCtrls_896HD[] = { 
     350    {"Mix1/Mix_", "Mix 1 ", "", MOTU_CTRL_STD_MIX, 0x0c20, }, 
     351    {"Mix2/Mix_", "Mix 2 ", "", MOTU_CTRL_STD_MIX, 0x0c24, }, 
     352    {"Mix3/Mix_", "Mix 3 ", "", MOTU_CTRL_STD_MIX, 0x0c28, }, 
     353    {"Mix4/Mix_", "Mix 4 ", "", MOTU_CTRL_STD_MIX, 0x0c2c, }, 
     354 
     355    /* For phones source control, "register" is currently unused */ 
     356    {"Control/Phones_", "Phones source", "", MOTU_CTRL_PHONES_SRC, 0}, 
     357 
     358    /* For optical mode controls, the "register" is used to indicate direction */ 
     359    {"Control/OpticalIn_mode", "Optical input mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_IN}, 
     360    {"Control/OpticalOut_mode", "Optical output mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_OUT}, 
     361 
     362    /* For meter controls the "register" indicates which meter controls are available */ 
     363    {"Control/Meter_", "Meter ", "", MOTU_CTRL_METER, 
     364      MOTU_CTRL_METER_PEAKHOLD | MOTU_CTRL_METER_CLIPHOLD | MOTU_CTRL_METER_AESEBU_SRC |  
     365      MOTU_CTRL_METER_PROG_SRC}, 
     366}; 
     367 
     368const MixerCtrl MixerCtrls_828Mk2[] = { 
     369    {"Mix1/Mix_", "Mix 1 ", "", MOTU_CTRL_STD_MIX, 0x0c20, }, 
     370    {"Mix2/Mix_", "Mix 2 ", "", MOTU_CTRL_STD_MIX, 0x0c24, }, 
     371    {"Mix3/Mix_", "Mix 3 ", "", MOTU_CTRL_STD_MIX, 0x0c28, }, 
     372    {"Mix4/Mix_", "Mix 4 ", "", MOTU_CTRL_STD_MIX, 0x0c2c, }, 
     373 
     374    /* For mic/line input controls, the "register" is the zero-based channel number */ 
     375    {"Control/Ana1_", "Analog 1 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 0}, 
     376    {"Control/Ana2_", "Analog 2 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 1}, 
     377    {"Control/Ana3_", "Analog 3 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 2}, 
     378    {"Control/Ana4_", "Analog 4 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 3}, 
     379    {"Control/Ana5_", "Analog 5 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 4}, 
     380    {"Control/Ana6_", "Analog 6 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 5}, 
     381    {"Control/Ana7_", "Analog 7 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 6}, 
     382    {"Control/Ana8_", "Analog 8 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 7}, 
     383 
     384    /* For phones source control, "register" is currently unused */ 
     385    {"Control/Phones_", "Phones source", "", MOTU_CTRL_PHONES_SRC, 0}, 
     386 
     387    /* For optical mode controls, the "register" is used to indicate direction */ 
     388    {"Control/OpticalIn_mode", "Optical input mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_IN}, 
     389    {"Control/OpticalOut_mode", "Optical output mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_OUT}, 
     390}; 
     391 
    328392const MotuMixer Mixer_Traveler = MOTUMIXER( 
    329393    MixerCtrls_Traveler, MixerBuses_Traveler, MixerChannels_Traveler); 
    330394 
     395const MotuMixer Mixer_Ultralite = MOTUMIXER( 
     396    MixerCtrls_Ultralite, MixerBuses_Ultralite, MixerChannels_Ultralite); 
     397 
    331398const MotuMixer Mixer_828Mk2 = MOTUMIXER( 
    332399    MixerCtrls_828Mk2, MixerBuses_Traveler, MixerChannels_Traveler); 
    333400 
    334 // For convenience during initial testing, just make the 896HD use the 
    335 // Traveler's mixer definition.  Separate definitions for these models will 
    336 // come once the final mixer structure is in place.  For now it's in a state 
    337 // of flux and subject to significant change. 
    338 #define Mixer_896HD   Mixer_Traveler 
     401const MotuMixer Mixer_896HD = MOTUMIXER( 
     402    MixerCtrls_896HD, MixerBuses_Traveler, MixerChannels_Traveler); 
    339403 
    340404/* The order of DevicesProperty entries must match the numeric order of the 
     
    345409    { Ports_828MKII,   N_ELEMENTS( Ports_828MKII ),    96000, &Mixer_828Mk2, }, 
    346410    { Ports_TRAVELER,  N_ELEMENTS( Ports_TRAVELER ),  192000, &Mixer_Traveler, }, 
    347     { Ports_ULTRALITE, N_ELEMENTS( Ports_ULTRALITE ),  96000 }, 
     411    { Ports_ULTRALITE, N_ELEMENTS( Ports_ULTRALITE ),  96000, &Mixer_Ultralite, }, 
    348412    { Ports_8PRE,      N_ELEMENTS( Ports_8PRE ),       96000 }, 
    349413    { Ports_828MKI,    N_ELEMENTS( Ports_828MKI ),     48000 }, 
     
    549613            type &= ~MOTU_CTRL_OPTICAL_MODE; 
    550614        } 
     615        if (type & MOTU_CTRL_METER) { 
     616            if (ctrl->dev_register & MOTU_CTRL_METER_PEAKHOLD) { 
     617                snprintf(name, 100, "%s%s", ctrl->name, "peakhold_time"); 
     618                snprintf(label,100, "%s%s", ctrl->label,"peakhold time"); 
     619                result &= m_MixerContainer->addElement( 
     620                    new MeterControl(*this, MOTU_METER_PEAKHOLD_MASK, 
     621                        MOTU_METER_PEAKHOLD_SHIFT, name, label, ctrl->desc)); 
     622            } 
     623            if (ctrl->dev_register & MOTU_CTRL_METER_CLIPHOLD) { 
     624                snprintf(name, 100, "%s%s", ctrl->name, "cliphold_time"); 
     625                snprintf(label,100, "%s%s", ctrl->label,"cliphold time"); 
     626                result &= m_MixerContainer->addElement( 
     627                    new MeterControl(*this, MOTU_METER_CLIPHOLD_MASK, 
     628                        MOTU_METER_CLIPHOLD_SHIFT, name, label, ctrl->desc)); 
     629            } 
     630            if (ctrl->dev_register & MOTU_CTRL_METER_AESEBU_SRC) { 
     631                snprintf(name, 100, "%s%s", ctrl->name, "aesebu_src"); 
     632                snprintf(label,100, "%s%s", ctrl->label,"AESEBU source"); 
     633                result &= m_MixerContainer->addElement( 
     634                    new MeterControl(*this, MOTU_METER_AESEBU_SRC_MASK, 
     635                        MOTU_METER_AESEBU_SRC_SHIFT, name, label, ctrl->desc)); 
     636            } 
     637            if (ctrl->dev_register & MOTU_CTRL_METER_PROG_SRC) { 
     638                snprintf(name, 100, "%s%s", ctrl->name, "src"); 
     639                snprintf(label,100, "%s%s", ctrl->label,"source"); 
     640                result &= m_MixerContainer->addElement( 
     641                    new MeterControl(*this, MOTU_METER_PROG_SRC_MASK, 
     642                        MOTU_METER_PROG_SRC_SHIFT, name, label, ctrl->desc)); 
     643            } 
     644            type &= ~MOTU_CTRL_METER; 
     645        } 
    551646 
    552647        if (type) { 
     
    645740 
    646741bool 
    647 MotuDevice::probe( ConfigRom& configRom, bool generic) 
     742MotuDevice::probe( Util::Configuration& c, ConfigRom& configRom, bool generic) 
    648743{ 
    649744    if(generic) return false; 
     
    883978} 
    884979 
     980std::vector<int> 
     981MotuDevice::getSupportedSamplingFrequencies() 
     982{ 
     983    std::vector<int> frequencies; 
     984    signed int max_freq = DevicesProperty[m_motu_model-1].MaxSampleRate; 
     985 
     986    /* All MOTUs support 1x rates.  All others must be conditional. */ 
     987    frequencies.push_back(44100); 
     988    frequencies.push_back(48000); 
     989 
     990    if (88200 <= max_freq) 
     991        frequencies.push_back(88200); 
     992    if (96000 <= max_freq) 
     993        frequencies.push_back(96000); 
     994    if (176400 <= max_freq) 
     995        frequencies.push_back(176400); 
     996    if (192000 <= max_freq) 
     997        frequencies.push_back(192000); 
     998    return frequencies; 
     999} 
     1000 
    8851001FFADODevice::ClockSource 
    8861002MotuDevice::clockIdToClockSource(unsigned int id) { 
     
    10071123 
    10081124    debugOutput(DEBUG_LEVEL_NORMAL, "Preparing MotuDevice...\n" ); 
     1125 
     1126    // Explicitly set the optical mode, primarily to ensure that the 
     1127    // MOTU_REG_OPTICAL_CTRL register is initialised.  We need to do this to 
     1128    // because some interfaces (the Ultralite for example) appear to power 
     1129    // up without this set to anything sensible.  In this case, writes to 
     1130    // MOTU_REG_ISOCTRL fail more often than not, which is bad. 
     1131    setOpticalMode(MOTU_DIR_IN, optical_in_mode); 
     1132    setOpticalMode(MOTU_DIR_OUT, optical_out_mode); 
    10091133 
    10101134    // Allocate bandwidth if not previously done. 
     
    10751199    std::string id=std::string("dev?"); 
    10761200    if(!getOption("id", id)) { 
    1077         debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n"); 
     1201        debugWarning("Could not retrieve id parameter, defaulting to 'dev?'\n"); 
    10781202    } 
    10791203 
     
    13101434        opt_ctrl |= 0x00000040; 
    13111435 
    1312     if (mode & MOTU_DIR_IN) { 
     1436    if (dir & MOTU_DIR_IN) { 
    13131437        reg &= ~MOTU_OPTICAL_IN_MODE_MASK; 
    13141438        reg |= (mode << 8) & MOTU_OPTICAL_IN_MODE_MASK; 
     
    13181442            opt_ctrl &= ~0x00000080; 
    13191443    } 
    1320     if (mode & MOTU_DIR_OUT) { 
     1444    if (dir & MOTU_DIR_OUT) { 
    13211445        reg &= ~MOTU_OPTICAL_OUT_MODE_MASK; 
    13221446        reg |= (mode <<10) & MOTU_OPTICAL_OUT_MODE_MASK; 
  • trunk/libffado/src/motu/motu_avdevice.h

    r1265 r1336  
    6868#define MOTU_DIR_INOUT       (MOTU_DIR_IN | MOTU_DIR_OUT) 
    6969 
     70#define MOTU_METER_PEAKHOLD_MASK     0x3800 
     71#define MOTU_METER_PEAKHOLD_SHIFT    11 
     72#define MOTU_METER_CLIPHOLD_MASK     0x0700 
     73#define MOTU_METER_CLIPHOLD_SHIFT    8 
     74#define MOTU_METER_AESEBU_SRC_MASK   0x0004 
     75#define MOTU_METER_AESEBU_SRC_SHIFT  2 
     76#define MOTU_METER_PROG_SRC_MASK     0x0003 
     77#define MOTU_METER_PROG_SRC_SHIFT    0 
     78 
    7079/* Device registers */ 
    7180#define MOTU_REG_ISOCTRL           0x0b00 
    7281#define MOTU_REG_OPTICAL_CTRL      0x0b10 
    7382#define MOTU_REG_CLK_CTRL          0x0b14 
     83#define MOTU_REG_896HD_METER_REG   0x0b1c 
     84#define MOTU_REG_896HD_METER_CONF  0x0b24 
    7485#define MOTU_REG_ROUTE_PORT_CONF   0x0c04 
    7586#define MOTU_REG_INPUT_LEVEL       0x0c08 
     
    95106class Ieee1394Service; 
    96107 
     108namespace Util { 
     109    class Configuration; 
     110} 
     111 
    97112namespace Motu { 
    98113 
     
    174189    virtual bool destroyMixer(); 
    175190 
    176     static bool probe( ConfigRom& configRom, bool generic = false ); 
     191    static bool probe( Util::Configuration&, ConfigRom& configRom, bool generic = false ); 
    177192    static FFADODevice * createDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )); 
    178193    static int getConfigurationId( ); 
     
    184199    virtual bool setSamplingFrequency( int samplingFrequency ); 
    185200    virtual int getSamplingFrequency( ); 
     201    virtual std::vector<int> getSupportedSamplingFrequencies(); 
    186202 
    187203    FFADODevice::ClockSource clockIdToClockSource(unsigned int id); 
  • trunk/libffado/src/motu/motu_controls.cpp

    r1274 r1336  
    727727} 
    728728 
     729MeterControl::MeterControl(MotuDevice &parent, unsigned int ctrl_mask, unsigned int ctrl_shift) 
     730: MotuDiscreteCtrl(parent, ctrl_mask) 
     731{ 
     732    m_shift = ctrl_shift; 
     733    validate(); 
     734} 
     735 
     736MeterControl::MeterControl(MotuDevice &parent, unsigned int ctrl_mask, unsigned int ctrl_shift, 
     737             std::string name, std::string label, std::string descr) 
     738: MotuDiscreteCtrl(parent, ctrl_mask, name, label, descr) 
     739{ 
     740    m_shift = ctrl_shift; 
     741    validate(); 
     742} 
     743 
     744void MeterControl::validate(void) { 
     745    if (m_register & (1<< m_shift) == 0) { 
     746        debugOutput(DEBUG_LEVEL_VERBOSE, "Inconsistent mask/shift: 0x%08x/%d\n", m_register, m_shift); 
     747    } 
     748} 
     749 
     750bool 
     751MeterControl::setValue(int v) 
     752{ 
     753    unsigned int val; 
     754    debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for meter control 0x%08x/%d: %d\n",  
     755        m_register, m_shift, v); 
     756 
     757    // Need to get current register setting so we can preserve the parts not 
     758    // being controlled by this object.  m_register holds the mask for the  
     759    // parts we're changing. 
     760    val = m_parent.ReadRegister(MOTU_REG_896HD_METER_CONF) & ~m_register; 
     761    val |= (v << m_shift) & m_register; 
     762 
     763    m_parent.WriteRegister(MOTU_REG_896HD_METER_CONF, val); 
     764 
     765    // Drivers under other OSes set MOTU_REG_896HD_METER_REG (0x0b1c) to 
     766    // 0x0400 whenever MOTU_REG_896HD_METER_CONF (0x0b24) is changed.  
     767    // There's no obvious reason why they do this, but since it's no hassle 
     768    // we might as well do the same. 
     769    m_parent.WriteRegister(MOTU_REG_896HD_METER_REG, 0x0400); 
     770 
     771    return true; 
     772} 
     773 
     774int 
     775MeterControl::getValue() 
     776{ 
     777    unsigned int val; 
     778    debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for meter control 0x%08x/%d\n",  
     779        m_register, m_shift); 
     780 
     781    // m_register holds the mask of the part of interest 
     782    val = (m_parent.ReadRegister(MOTU_REG_896HD_METER_CONF) & m_register) >> m_shift; 
     783 
     784    return val; 
     785} 
     786 
    729787InfoElement::InfoElement(MotuDevice &parent, unsigned infotype) 
    730788: MotuDiscreteCtrl(parent, infotype) 
  • trunk/libffado/src/motu/motu_controls.h

    r1274 r1336  
    4141#define MOTU_CTRL_MIX_DEST        0x00000400 
    4242 
     43#define MOTU_CTRL_METER           0x00001000 
     44 
    4345#define MOTU_CTRL_INPUT_TRIMGAIN  0x01000000 
    4446#define MOTU_CTRL_INPUT_PAD       0x02000000 
     
    7375#define MOTU_CTRL_MODE_PAD                 0x00000000 
    7476#define MOTU_CTRL_MODE_TRIMGAIN            0x00000001 
     77 
     78#define MOTU_CTRL_METER_PEAKHOLD           0x00000000 
     79#define MOTU_CTRL_METER_CLIPHOLD           0x00000001 
     80#define MOTU_CTRL_METER_AESEBU_SRC         0x00000002 
     81#define MOTU_CTRL_METER_PROG_SRC           0x00000004 
    7582 
    7683#define MOTU_INFO_MODEL                    0x00000001 
     
    293300}; 
    294301 
     302class MeterControl 
     303    : public MotuDiscreteCtrl 
     304{ 
     305public: 
     306    MeterControl(MotuDevice &parent, unsigned int ctrl_mask, unsigned int ctrl_shift); 
     307    MeterControl(MotuDevice &parent, unsigned int ctrl_mask, unsigned int ctrl_shift,  
     308          std::string name, std::string label, std::string descr); 
     309 
     310    virtual bool setValue(int v); 
     311    virtual int getValue(); 
     312protected: 
     313    void validate(); 
     314    unsigned int m_shift; 
     315}; 
     316 
    295317class InfoElement 
    296318    : public MotuDiscreteCtrl 
  • trunk/libffado/src/rme/rme_avdevice.cpp

    r1239 r1336  
    177177} 
    178178 
     179#define RME_CHECK_AND_ADD_SR(v, x) \ 
     180    { \ 
     181    if (((x >= 32000*0.96 && x <= 32000*1.04) || \ 
     182        (x >= 44100*0.96 && x <= 44100*1.04) || \ 
     183        (x >= 48000*0.96 && x <= 48000*1.04) || \ 
     184        (x >= 64000*0.96 && x <= 64000*1.04) || \ 
     185        (x >= 88200*0.96 && x <= 88200*1.04) || \ 
     186        (x >= 96000*0.96 && x <= 96000*1.04) || \ 
     187        (x >= 128000*0.96 && x <= 128000*1.04) || \ 
     188        (x >= 176000*0.96 && x <= 176000*1.04) || \ 
     189        (x >= 192000*0.96 && x <= 192000*1.04))) { \ 
     190        v.push_back(x); \ 
     191    };}; 
     192 
     193std::vector<int> 
     194RmeDevice::getSupportedSamplingFrequencies() 
     195{ 
     196    std::vector<int> frequencies; 
     197    RME_CHECK_AND_ADD_SR(frequencies, 32000); 
     198    RME_CHECK_AND_ADD_SR(frequencies, 44100); 
     199    RME_CHECK_AND_ADD_SR(frequencies, 48000); 
     200    RME_CHECK_AND_ADD_SR(frequencies, 64000); 
     201    RME_CHECK_AND_ADD_SR(frequencies, 88200); 
     202    RME_CHECK_AND_ADD_SR(frequencies, 96000); 
     203    RME_CHECK_AND_ADD_SR(frequencies, 128000); 
     204    RME_CHECK_AND_ADD_SR(frequencies, 176400); 
     205    RME_CHECK_AND_ADD_SR(frequencies, 192000); 
     206    return frequencies; 
     207} 
     208 
    179209FFADODevice::ClockSourceVector 
    180210RmeDevice::getSupportedClockSources() { 
  • trunk/libffado/src/rme/rme_avdevice.h

    r1239 r1336  
    7676    virtual bool setSamplingFrequency( int samplingFrequency ); 
    7777    virtual int getSamplingFrequency( ); 
     78    virtual std::vector<int> getSupportedSamplingFrequencies(); 
    7879 
    7980    virtual ClockSourceVector getSupportedClockSources(); 
  • trunk/libffado/src/SConscript

    r1210 r1336  
    7575        libutil/IpcRingBuffer.cpp \ 
    7676        libutil/PacketBuffer.cpp \ 
     77        libutil/Configuration.cpp \ 
    7778        libutil/OptionContainer.cpp \ 
    7879        libutil/PosixMessageQueue.cpp \ 
     
    124125        maudio/fw410.xml \ 
    125126        maudio/fwap.xml \ 
    126         bebob/ffado_driver_bebob.txt \ 
    127127' ) 
    128128 
    129129genericavc_source =  env.Split( '\ 
    130130        genericavc/avc_avdevice.cpp \ 
    131         genericavc/avc_vendormodel.cpp \ 
    132131' ) 
    133132 
    134133genericavc_pkgdata = env.Split( '\ 
    135         genericavc/ffado_driver_genericavc.txt \ 
    136134' )      
    137135 
     
    148146        fireworks/efc/efc_cmds_monitor.cpp \ 
    149147        fireworks/efc/efc_cmds_ioconfig.cpp \ 
     148        fireworks/fireworks_session_block.cpp \ 
    150149        fireworks/audiofire/audiofire_device.cpp \ 
    151150' ) 
    152151 
    153152fireworks_pkgdata =  env.Split( '\ 
    154         fireworks/ffado_driver_fireworks.txt \ 
    155153' ) 
    156154 
     
    233231                libenv.PrependUnique( LIBS=["expat"] ) 
    234232 
     233# add the libconfig 
     234libenv.AppendUnique( CPPPATH=["#/external/libconfig"] ) 
     235libenv.PrependUnique( LIBPATH=[env['build_base']+"external/libconfig"] ) 
     236libenv.PrependUnique( LIBS=["libconfigpp"] ) 
     237 
    235238#env1.AppendUnique( LINKFLAGS = env.Split("-Wl,-rpath $libdir -Wl,-soname -Wl,libffado.so.1 --version-info=1:0:0") ) 
    236239ffadolib = libenv.SharedLibrary( "ffado", source ) 
  • trunk/libffado/support/alsa/alsa_plugin.cpp

    r1255 r1336  
    181181//     } 
    182182// } 
    183  
    184 //     if (io->state != SND_PCM_STATE_RUNNING) { 
    185 //         if (io->stream == SND_PCM_STREAM_PLAYBACK) { 
    186 //             for (channel = 0; channel < io->channels; channel++) 
    187 //                 snd_pcm_area_silence(&jack->areas[channel], 0, nframes, io->format); 
    188 //             return 0; 
    189 //         } 
    190 //     } 
    191 //      
    192 //     areas = snd_pcm_ioplug_mmap_areas(io); 
    193 //  
    194 //     while (xfer < nframes) { 
    195 //         snd_pcm_uframes_t frames = nframes - xfer; 
    196 //         snd_pcm_uframes_t offset = jack->hw_ptr; 
    197 //         snd_pcm_uframes_t cont = io->buffer_size - offset; 
    198 //  
    199 //         if (cont < frames) 
    200 //             frames = cont; 
    201 //  
    202 //         for (channel = 0; channel < io->channels; channel++) { 
    203 //             if (io->stream == SND_PCM_STREAM_PLAYBACK) 
    204 //                 snd_pcm_area_copy(&jack->areas[channel], xfer, &areas[channel], offset, frames, io->format); 
    205 //             else 
    206 //                 snd_pcm_area_copy(&areas[channel], offset, &jack->areas[channel], xfer, frames, io->format); 
    207 //         } 
    208 //          
    209 //         jack->hw_ptr += frames; 
    210 //         jack->hw_ptr %= io->buffer_size; 
    211 //         xfer += frames; 
    212 //     } 
    213 //  
    214 //     write(jack->fd, buf, 1); /* for polling */ 
    215183 
    216184static int 
     
    473441    unsigned int access_list[] = { 
    474442        SND_PCM_ACCESS_MMAP_NONINTERLEAVED, 
    475         SND_PCM_ACCESS_RW_NONINTERLEAVED, 
     443//         SND_PCM_ACCESS_RW_NONINTERLEAVED, 
    476444    }; 
    477445 
  • trunk/libffado/support/dbus/control-interface.xml

    r1173 r1336  
    3131          <arg type="s" name="name" direction="out"/> 
    3232      </method> 
     33      <signal name="Destroyed"></signal> 
    3334      <signal name="Updated"></signal> 
     35      <signal name="PreUpdate"></signal> 
     36      <signal name="PostUpdate"></signal> 
    3437  </interface> 
    3538 
  • trunk/libffado/support/dbus/controlserver.cpp

    r1324 r1336  
    4444    // allocate a lock 
    4545    if(parent == NULL) { 
    46         m_UpdateLock = new Util::PosixMutex(); 
     46        m_UpdateLock = new Util::PosixMutex("CTLSVEL"); 
    4747    } else { 
    4848        m_UpdateLock = NULL; 
     
    129129 
    130130    // register an update signal handler 
    131     m_updateFunctor = new MemberSignalFunctor< Container*, 
     131    m_updateFunctor = new MemberSignalFunctor1< Container*, 
    132132                      void (Container::*)(int) > 
    133133                      ( this, &Container::updated, (int)Control::Container::eS_Updated ); 
     
    148148    debugOutput( DEBUG_LEVEL_VERBOSE, "Deleting Container on '%s'\n", 
    149149                 path().c_str() ); 
     150 
     151    Destroyed(); //send dbus signal 
     152 
    150153    if(m_updateFunctor) { 
    151154        if(!m_Slave.remSignalHandler(m_updateFunctor)) { 
     
    201204    bool something_changed = false; 
    202205    debugOutput( DEBUG_LEVEL_VERBOSE, "Updating tree...\n"); 
     206    // send a pre update signal 
     207    PreUpdate(); 
    203208    debugOutput( DEBUG_LEVEL_VERBOSE, "Add handlers for elements...\n"); 
    204209    // add handlers for the slaves that don't have one yet 
     
    272277        Updated(); 
    273278    } 
     279    // send a post update signal 
     280    PostUpdate(); 
    274281} 
    275282 
  • trunk/libffado/support/dbus/controlserver.h

    r1173 r1336  
    4545 
    4646template< typename CalleePtr, typename MemFunPtr > 
    47 class MemberSignalFunctor 
     47class MemberSignalFunctor0 
    4848    : public Control::SignalFunctor 
    4949{ 
    5050public: 
    51     MemberSignalFunctor( const CalleePtr& pCallee, 
     51    MemberSignalFunctor0( const CalleePtr& pCallee, 
    5252            MemFunPtr pMemFun, 
    5353            int pSignalId) 
     
    5757        {} 
    5858 
    59     virtual ~MemberSignalFunctor() 
     59    virtual ~MemberSignalFunctor0() 
    6060        {} 
     61 
     62    virtual void operator() () 
     63        { 
     64            ( ( *m_pCallee ).*m_pMemFun )(); 
     65        } 
     66    virtual void operator() (int) {} 
     67private: 
     68    CalleePtr  m_pCallee; 
     69    MemFunPtr  m_pMemFun; 
     70}; 
     71 
     72template< typename CalleePtr, typename MemFunPtr > 
     73class MemberSignalFunctor1 
     74    : public Control::SignalFunctor 
     75{ 
     76public: 
     77    MemberSignalFunctor1( const CalleePtr& pCallee, 
     78            MemFunPtr pMemFun, 
     79            int pSignalId) 
     80        : Control::SignalFunctor( pSignalId ) 
     81        , m_pCallee( pCallee ) 
     82        , m_pMemFun( pMemFun ) 
     83        {} 
     84 
     85    virtual ~MemberSignalFunctor1() 
     86        {} 
     87 
     88    virtual void operator() () {} 
    6189 
    6290    virtual void operator() (int value) 
     
    119147 
    120148    void updated(int new_nb_elements); 
     149    void destroyed(); 
     150 
    121151    void setVerboseLevel( const DBus::Int32 &); 
    122152private: 
  • trunk/libffado/support/dbus/ffado-dbus-server.cpp

    r1254 r1336  
    252252    debugOutput( DEBUG_LEVEL_NORMAL, "Using ffado library version: %s\n\n", ffado_get_version() ); 
    253253 
    254         m_deviceManager = new DeviceManager(); 
    255         if ( !m_deviceManager ) { 
    256             debugError("Could not allocate device manager\n" ); 
    257             return exitfunction(-1); 
    258         } 
    259         if ( !m_deviceManager->initialize() ) { 
    260             debugError("Could not initialize device manager\n" ); 
    261             delete m_deviceManager; 
    262             return exitfunction(-1); 
    263         } 
    264         if ( arguments.verbose ) { 
    265             m_deviceManager->setVerboseLevel(arguments.verbose); 
    266         } 
    267         if ( !m_deviceManager->discover(arguments.use_cache) ) { 
    268             debugError("Could not discover devices\n" ); 
    269             delete m_deviceManager; 
    270             return exitfunction(-1); 
    271         } 
    272  
    273         // add pre-update handler 
    274         Util::Functor* preupdate_functor = new Util::CallbackFunctor0< void (*)() > 
    275                     ( &preUpdateHandler, false ); 
    276         if ( !preupdate_functor ) { 
    277             debugFatal( "Could not create pre-update handler\n" ); 
    278             return false; 
    279         } 
    280         if(!m_deviceManager->registerPreUpdateNotification(preupdate_functor)) { 
    281             debugError("could not register pre-update notifier"); 
    282         } 
    283         // add post-update handler 
    284         Util::Functor* postupdate_functor = new Util::CallbackFunctor0< void (*)() > 
    285                     ( &postUpdateHandler, false ); 
    286         if ( !postupdate_functor ) { 
    287             debugFatal( "Could not create post-update handler\n" ); 
    288             return false; 
    289         } 
    290         if(!m_deviceManager->registerPostUpdateNotification(postupdate_functor)) { 
    291             debugError("could not register post-update notifier"); 
    292         } 
    293  
    294         signal (SIGINT, sighandler); 
    295          
    296         DBus::_init_threading(); 
     254    m_deviceManager = new DeviceManager(); 
     255    if ( !m_deviceManager ) { 
     256        debugError("Could not allocate device manager\n" ); 
     257        return exitfunction(-1); 
     258    } 
     259    if ( !m_deviceManager->initialize() ) { 
     260        debugError("Could not initialize device manager\n" ); 
     261        delete m_deviceManager; 
     262        return exitfunction(-1); 
     263    } 
     264    if ( arguments.verbose ) { 
     265        m_deviceManager->setVerboseLevel(arguments.verbose); 
     266    } 
     267    if ( !m_deviceManager->discover(arguments.use_cache) ) { 
     268        debugError("Could not discover devices\n" ); 
     269        delete m_deviceManager; 
     270        return exitfunction(-1); 
     271    } 
     272 
     273    // add pre-update handler 
     274    Util::Functor* preupdate_functor = new Util::CallbackFunctor0< void (*)() > 
     275                ( &preUpdateHandler, false ); 
     276    if ( !preupdate_functor ) { 
     277        debugFatal( "Could not create pre-update handler\n" ); 
     278        return false; 
     279    } 
     280    if(!m_deviceManager->registerPreUpdateNotification(preupdate_functor)) { 
     281        debugError("could not register pre-update notifier"); 
     282    } 
     283    // add post-update handler 
     284    Util::Functor* postupdate_functor = new Util::CallbackFunctor0< void (*)() > 
     285                ( &postUpdateHandler, false ); 
     286    if ( !postupdate_functor ) { 
     287        debugFatal( "Could not create post-update handler\n" ); 
     288        return false; 
     289    } 
     290    if(!m_deviceManager->registerPostUpdateNotification(postupdate_functor)) { 
     291        debugError("could not register post-update notifier"); 
     292    } 
     293 
     294    signal (SIGINT, sighandler); 
    297295     
    298         // test DBUS stuff 
    299         DBus::default_dispatcher = &dispatcher; 
    300         DBus::Connection conn = DBus::Connection::SessionBus(); 
    301         global_conn = &conn; 
    302         conn.request_name("org.ffado.Control"); 
    303  
    304         // lock the control tree such that it does not get modified while we build our view 
    305         m_deviceManager->lockControl(); 
    306         container = new DBusControl::Container(conn, "/org/ffado/Control/DeviceManager",  
    307                                                NULL, *m_deviceManager); 
    308         // unlock the control tree since the tree is built 
    309         m_deviceManager->unlockControl(); 
    310  
    311         printMessage("DBUS test service running\n"); 
    312         printMessage("press ctrl-c to stop it & exit\n"); 
    313          
    314         while(run) { 
    315             debugOutput( DEBUG_LEVEL_NORMAL, "dispatching...\n"); 
    316             dispatcher.enter(); 
    317  
    318             debugOutput( DEBUG_LEVEL_NORMAL, " dispatcher exited...\n"); 
    319             sem_wait(&run_sem); 
    320             debugOutput( DEBUG_LEVEL_NORMAL, " activity handled...\n"); 
    321         } 
    322          
    323         if(!m_deviceManager->unregisterPreUpdateNotification(preupdate_functor)) { 
    324             debugError("could not unregister pre update notifier"); 
    325         } 
    326         delete preupdate_functor; 
    327         if(!m_deviceManager->unregisterPostUpdateNotification(postupdate_functor)) { 
    328             debugError("could not unregister post update notifier"); 
    329         } 
    330         delete postupdate_functor; 
    331         delete container; 
    332  
    333         signal (SIGINT, SIG_DFL); 
    334  
    335         printMessage("server stopped\n"); 
    336         delete m_deviceManager; 
    337         return exitfunction(0); 
    338 
     296    DBus::_init_threading(); 
     297 
     298    // test DBUS stuff 
     299    DBus::default_dispatcher = &dispatcher; 
     300    DBus::Connection conn = DBus::Connection::SessionBus(); 
     301    global_conn = &conn; 
     302    conn.request_name("org.ffado.Control"); 
     303 
     304    // lock the control tree such that it does not get modified while we build our view 
     305    m_deviceManager->lockControl(); 
     306    container = new DBusControl::Container(conn, "/org/ffado/Control/DeviceManager",  
     307                                            NULL, *m_deviceManager); 
     308    // unlock the control tree since the tree is built 
     309    m_deviceManager->unlockControl(); 
     310 
     311    printMessage("DBUS test service running\n"); 
     312    printMessage("press ctrl-c to stop it & exit\n"); 
     313     
     314    while(run) { 
     315        debugOutput( DEBUG_LEVEL_NORMAL, "dispatching...\n"); 
     316        dispatcher.enter(); 
     317        debugOutput( DEBUG_LEVEL_NORMAL, " dispatcher exited...\n"); 
     318        sem_wait(&run_sem); 
     319        debugOutput( DEBUG_LEVEL_NORMAL, " activity handled...\n"); 
     320    } 
     321     
     322    if(!m_deviceManager->unregisterPreUpdateNotification(preupdate_functor)) { 
     323        debugError("could not unregister pre update notifier"); 
     324    } 
     325    delete preupdate_functor; 
     326    if(!m_deviceManager->unregisterPostUpdateNotification(postupdate_functor)) { 
     327        debugError("could not unregister post update notifier"); 
     328    } 
     329    delete postupdate_functor; 
     330    delete container; 
     331 
     332    signal (SIGINT, SIG_DFL); 
     333 
     334    printMessage("server stopped\n"); 
     335    delete m_deviceManager; 
     336    return exitfunction(0); 
     337
  • trunk/libffado/support/firmware/bridgeco-downloader.cpp

    r1234 r1336  
    4242const char *argp_program_bug_address = "<ffado-devel@lists.sf.net>"; 
    4343const char *doc = "bridgeco-downloader -- firmware downloader application for BridgeCo devices\n\n" 
    44                     "OPERATION: display\n" 
    45                     "           setguid GUID\n" 
    46                     "           firmware FILE\n" 
    47                     "           cne FILE\n" 
    48                     "           bcd FILE\n"; 
     44                    "OPERATION: GUID display\n" 
     45                    "           GUID setguid NEW_GUID\n" 
     46                    "           GUID firmware FILE\n" 
     47                    "           GUID cne FILE\n" 
     48                    "           GUID bcd FILE\n"; 
    4949static struct argp_option _options[] = { 
    5050    {"verbose",   'v', "level",     0,  "Produce verbose output" }, 
     
    8888        ConfigRom configRom(service, i); 
    8989        configRom.initialize(); 
    90          
     90 
    9191        if (configRom.getGuid() == guid) 
    9292            node_id = configRom.getNodeId(); 
     
    135135        } else { 
    136136            cout << "Firmware download was successful" << endl; 
     137            cout << "Please reboot the device by removing the power and firewire connections." << endl; 
    137138        } 
    138139    } else if ( strcmp( args->args[1], "cne" ) == 0 ) { 
     
    148149        } else { 
    149150            cout << "CnE download was successful" << endl; 
     151            cout << "Please reboot the device by removing the power and firewire connections." << endl; 
    150152        } 
    151153    } else if ( strcmp( args->args[1], "display" ) == 0 ) { 
  • trunk/libffado/support/firmware/fireworks-downloader.cpp

    r1234 r1336  
    2525#include "downloader.h" 
    2626 
     27#include "config.h" 
     28 
    2729#include "src/fireworks/fireworks_device.h" 
    2830#include "src/fireworks/fireworks_firmware.h" 
     31#include "src/fireworks/fireworks_session_block.h" 
    2932 
    3033#include "libieee1394/configrom.h" 
    3134#include "libieee1394/ieee1394service.h" 
     35#include "libutil/Configuration.h" 
    3236 
    3337#include "debugmodule/debugmodule.h" 
     
    4953// arg parsing 
    5054//////////////////////////////////////////////// 
    51 const char *argp_program_version = "fireworks-downloader 0.2"; 
     55const char *argp_program_version = "fireworks-downloader 0.3"; 
    5256const char *argp_program_bug_address = "<ffado-devel@lists.sf.net>"; 
    5357const char *doc = "fireworks-downloader -- firmware downloader application for ECHO Fireworks devices\n\n" 
     
    6771                    "              Verify that the firmware contained in the device corresponds\n" 
    6872                    "              to the one contained in FILE\n" 
     73                    "           session_display\n" 
     74                    "              show information about the session on the device\n" 
     75                    "           session_info FILE\n" 
     76                    "              show information about the session in FILE\n" 
     77                    "           session_download FILE\n" 
     78                    "              Download the session content from the device to FILE\n" 
     79                    "           session_upload FILE\n" 
     80                    "              Upload the session from FILE to the device\n" 
    6981                    ; 
    7082 
     
    148160        f.dumpData(); 
    149161        return 0; 
     162    } else if ( strcmp( args->args[0], "session_info" ) == 0 ) { 
     163        if (!args->args[1] ) { 
     164            printMessage("FILE argument is missing\n"); 
     165            return -1; 
     166        } 
     167        std::string str( args->args[1] ); 
     168 
     169        // load the file 
     170        Session s = Session(); 
     171        s.setVerboseLevel( args->verbose ); 
     172 
     173        if (!s.loadFromFile(str)) { 
     174            printMessage("Could not load session\n"); 
     175            return -1; 
     176        } 
     177        s.show(); 
     178        return 0; 
    150179    } else if ( strcmp( args->args[0], "list" ) == 0 ) { 
    151180        printDeviceList(); 
     
    169198        ConfigRom configRom(service, i); 
    170199        configRom.initialize(); 
    171          
    172200        if (configRom.getGuid() == guid) { 
    173201            node_id = configRom.getNodeId(); 
     
    195223    } 
    196224 
    197     if ( !FireWorks::Device::probe(*configRom) ) { 
     225    Util::Configuration c; 
     226    c.openFile( USER_CONFIG_FILE, Util::Configuration::eFM_ReadOnly ); 
     227    c.openFile( SYSTEM_CONFIG_FILE, Util::Configuration::eFM_ReadOnly ); 
     228 
     229    if ( !FireWorks::Device::probe(c, *configRom) ) { 
    198230        printMessage( "Device with node id %d is not an ECHO FireWorks device.\n", 
    199231                    node_id ); 
     
    201233        return -1; 
    202234    } 
    203      
     235 
    204236    DeviceManager d = DeviceManager(); 
    205237    Device *dev = new Device(d, std::auto_ptr<ConfigRom>(configRom) ); 
     
    382414            printMessage(" => Verify successful. Firmware upload successful.\n"); 
    383415        } 
     416    } else if ( strcmp( args->args[0], "session_display" ) == 0 ) { 
     417        // load the session 
     418        Session s = Session(); 
     419        s.setVerboseLevel( args->verbose ); 
     420 
     421        if (!s.loadFromDevice(*dev)) { 
     422            printMessage("Could not load session\n"); 
     423            return -1; 
     424        } 
     425        s.show(); 
     426    } else if ( strcmp( args->args[0], "session_download" ) == 0 ) { 
     427        if (!args->args[1] ) { 
     428            printMessage("FILE argument is missing\n"); 
     429            delete dev; 
     430            return -1; 
     431        } 
     432        std::string str( args->args[1] ); 
     433 
     434        printMessage("Downloading session to file: %s\n", str.c_str()); 
     435 
     436        printMessage(" loading session...\n"); 
     437        // load the session 
     438        Session s = Session(); 
     439        s.setVerboseLevel( args->verbose ); 
     440 
     441        if (!s.loadFromDevice(*dev)) { 
     442            printMessage("Could not load session from device\n"); 
     443            return -1; 
     444        } 
     445 
     446        printMessage(" saving session...\n"); 
     447        if (!s.saveToFile(str)) { 
     448            printMessage("Could not save session to file\n"); 
     449            return -1; 
     450        } 
     451    } else if ( strcmp( args->args[0], "session_upload" ) == 0 ) { 
     452        if (!args->args[1] ) { 
     453            printMessage("FILE argument is missing\n"); 
     454            delete dev; 
     455            return -1; 
     456        } 
     457        std::string str( args->args[1] ); 
     458 
     459        printMessage("Uploading session from file: %s\n", str.c_str()); 
     460 
     461        printMessage(" loading session...\n"); 
     462        // load the session 
     463        Session s = Session(); 
     464        s.setVerboseLevel( args->verbose ); 
     465        if (!s.loadFromFile(str)) { 
     466            printMessage("Could not load session from file\n"); 
     467            return -1; 
     468        } 
     469 
     470        printMessage(" saving session...\n"); 
     471        if (!s.saveToDevice(*dev)) { 
     472            printMessage("Could not save session to device\n"); 
     473            return -1; 
     474        } 
     475 
    384476    }  else { 
    385477        printMessage("Unknown operation\n"); 
  • trunk/libffado/support/mixer/ffadomixer.in

    r1326 r1336  
    4343from mixer_saffirele import * 
    4444from mixer_saffirepro import * 
    45 from mixer_af2 import * 
     45from mixer_audiofire import * 
    4646from mixer_bcoaudio5 import * 
    4747from mixer_edirolfa66 import * 
     
    6969    [(0x00130e, 0x00000006),'SaffireProMixer'], 
    7070    [(0x00130e, 0x00000000),'SaffireMixer'], 
    71     [(0x001486, 0x00000af2),'AudioFire2Mixer'], 
     71    [(0x001486, 0x00000af2),'AudioFireMixer'], 
     72    [(0x001486, 0x00000af4),'AudioFireMixer'], 
     73    [(0x001486, 0x00000af8),'AudioFireMixer'], 
     74    [(0x001486, 0x0000af12),'AudioFireMixer'], 
    7275    [(0x0007f5, 0x00010049),'BCoAudio5Control'], 
    7376    [(0x0040AB, 0x00010049),'EdirolFa66Control'], 
     
    7780    [(0x0001f2, 0x00000000),'MotuMixer'], 
    7881    ] 
     82 
     83POLL_SLEEP_TIME_MSEC = 100 # 100ms 
    7984 
    8085class ControlInterface: 
     
    271276        return self.iface.getAttributeName(idx) 
    272277 
     278class SamplerateSelectInterface: 
     279    def __init__(self, servername, devicepath): 
     280        self.basepath=devicepath + '/Generic/SamplerateSelect' 
     281        self.servername=servername 
     282        self.bus=dbus.SessionBus() 
     283        self.dev = self.bus.get_object(self.servername, self.basepath) 
     284        self.iface = dbus.Interface(self.dev, dbus_interface='org.ffado.Control.Element.Enum') 
     285    def count(self): 
     286        return self.iface.count() 
     287    def select(self, idx): 
     288        return self.iface.select(idx) 
     289    def selected(self): 
     290        return self.iface.selected() 
     291    def getEnumLabel(self, idx): 
     292        return self.iface.getEnumLabel(idx) 
     293 
    273294class TextInterface: 
    274295    def __init__(self, servername, basepath): 
     
    291312        self.setLineWidth( 2 ) 
    292313        self.setMinimumHeight( 10 ) 
     314 
     315class PollUpdateWidgets(QObject): 
     316    def __init__(self, widgets): 
     317        QObject.__init__(self) 
     318        self.widgets = widgets 
     319 
     320    def updateWidgets(self): 
     321        for w in self.widgets: 
     322            if 'polledUpdate' in dir(w): 
     323                try: 
     324                    w.polledUpdate() 
     325                except: 
     326                    print "error in polled update" 
    293327 
    294328if __name__ == "__main__": 
     
    336370    mw = QTabWidget() 
    337371 
     372    mixerwidgets = [] 
     373 
    338374    for idx in range(nbDevices): 
    339375        path=devmgr.getDeviceName(idx) 
     
    372408        # create a control object 
    373409        hw = ControlInterface(server, basepath+'/DeviceManager/'+path) 
     410        clockselect = ClockSelectInterface( server, basepath+"/DeviceManager/"+path ) 
     411        samplerateselect = SamplerateSelectInterface( server, basepath+"/DeviceManager/"+path ) 
     412        nickname = TextInterface( server, basepath+"/DeviceManager/"+path+"/Generic/Nickname" ) 
    374413 
    375414        # 
     
    377416        # 
    378417        tmp = GlobalMixer( w ) 
    379         tmp.clockselect = ClockSelectInterface( server, basepath+"/DeviceManager/"+path ) 
    380         tmp.nickname = TextInterface( server, basepath+"/DeviceManager/"+path+"/Generic/Nickname" ) 
     418        tmp.configrom = cfgrom 
     419        tmp.clockselect = clockselect 
     420        tmp.samplerateselect = samplerateselect 
     421        tmp.nickname = nickname 
    381422        tmp.hw = hw 
    382423        tmp.initValues() 
     
    409450 
    410451                # different panel for different clock frequency 
    411                 samplerate = hw.getDiscrete('/Generic/SamplerateSelect') 
     452                selected = samplerateselect.selected() 
     453                samplerate = int(samplerateselect.getEnumLabel( selected )) 
    412454 
    413455                # adat on PRO26 makes a difference 
     
    455497        # 
    456498        l.addWidget( mixerwidget, 10 ) 
     499        mixerwidget.configrom = cfgrom 
     500        mixerwidget.clockselect = clockselect 
     501        mixerwidget.samplerateselect = samplerateselect 
     502        mixerwidget.nickname = nickname 
    457503        mixerwidget.hw = hw 
    458         mixerwidget.configrom = cfgrom 
    459         mixerwidget.clockselect = ClockSelectInterface(server, basepath+'/DeviceManager/'+path) 
    460         mixerwidget.initValues() 
     504        if 'buildMixer' in dir(mixerwidget): 
     505            mixerwidget.buildMixer() 
     506        if 'initValues' in dir(mixerwidget): 
     507            mixerwidget.initValues() 
     508        mixerwidgets.append(mixerwidget) 
    461509        mw.addTab( w, mixerapp ) 
    462510 
     
    471519    # 
    472520    if mw.count() > 0: 
     521        puw = PollUpdateWidgets(mixerwidgets) 
     522        timer = QTimer(puw) 
     523        QObject.connect( timer, SIGNAL('timeout()'), puw.updateWidgets ); 
     524        timer.start( POLL_SLEEP_TIME_MSEC ); 
     525 
     526        # Adjust size of mixer window to the requirements of the selected device mixer(s)  
     527        mw.adjustSize() 
     528 
    473529        mw.show() 
    474530 
     
    476532 
    477533        app.exec_loop() 
    478  
  • trunk/libffado/support/mixer/ffadomixer_config.py.in

    r1077 r1336  
     1#!/usr/bin/python 
     2#coding: utf-8 
     3 
    14REGISTER_URL = '$REGISTRATION_URL' 
    25INI_FILE_PATH = "$CONFIGDIR/registration.ini" 
  • trunk/libffado/support/mixer/mixer_global.py

    r1108 r1336  
    4141                        self.clocksource.setCurrentItem( selected ) 
    4242 
     43        def samplerateChanged( self, sr ): 
     44                print "samplerateChanged( " + str(sr) + " )" 
     45                self.samplerateselect.select( sr ) 
     46                selected = self.samplerateselect.selected() 
     47 
     48                if selected != sr: 
     49                        srname = self.samplerateselect.getEnumLabel( sr ) 
     50                        msg = QMessageBox() 
     51                        msg.question( msg, "Failed to select sample rate", \ 
     52                                "<qt>Could not select %s as samplerate.</qt>" % srname, \ 
     53                                QMessageBox.Ok ) 
     54                        self.samplerate.setCurrentItem( selected ) 
     55 
    4356        def nicknameChanged( self, name ): 
    4457                #print "nicknameChanged( %s )" % name 
     
    5063                        self.clocksource.insertItem( self.clockselect.getEnumLabel( i ) ) 
    5164                self.clocksource.setCurrentItem( self.clockselect.selected() ) 
     65 
     66                for i in range( self.samplerateselect.count() ): 
     67                        self.samplerate.insertItem( self.samplerateselect.getEnumLabel( i ) ) 
     68                self.samplerate.setCurrentItem( self.samplerateselect.selected() ) 
     69 
    5270                self.txtNickname.setText( self.nickname.text() ) 
    5371 
  • trunk/libffado/support/mixer/mixer_global.ui

    r1105 r1336  
    2626            <x>0</x> 
    2727            <y>0</y> 
    28             <width>600</width> 
     28            <width>721</width> 
    2929            <height>191</height> 
    3030        </rect> 
     
    4141        <string>Global Mixer Options</string> 
    4242    </property> 
    43     <grid
     43    <hbox
    4444        <property name="name"> 
    4545            <cstring>unnamed</cstring> 
    4646        </property> 
    47         <widget class="QLabel" row="0" column="0"> 
     47        <widget class="QLayoutWidget"> 
    4848            <property name="name"> 
    49                 <cstring>textLabel1</cstring> 
     49                <cstring>layout5</cstring> 
    5050            </property> 
    51             <property name="text"> 
    52                 <string>Device Nickname:</string> 
    53             </property> 
    54             <property name="buddy" stdset="0"> 
    55                 <cstring>nickname</cstring> 
    56             </property> 
     51            <vbox> 
     52                <property name="name"> 
     53                    <cstring>unnamed</cstring> 
     54                </property> 
     55                <widget class="QLayoutWidget"> 
     56                    <property name="name"> 
     57                        <cstring>layout2</cstring> 
     58                    </property> 
     59                    <hbox> 
     60                        <property name="name"> 
     61                            <cstring>unnamed</cstring> 
     62                        </property> 
     63                        <widget class="QLabel"> 
     64                            <property name="name"> 
     65                                <cstring>textLabel1</cstring> 
     66                            </property> 
     67                            <property name="text"> 
     68                                <string>Device Nickname:</string> 
     69                            </property> 
     70                            <property name="buddy" stdset="0"> 
     71                                <cstring>nickname</cstring> 
     72                            </property> 
     73                        </widget> 
     74                        <widget class="QLineEdit"> 
     75                            <property name="name"> 
     76                                <cstring>txtNickname</cstring> 
     77                            </property> 
     78                            <property name="minimumSize"> 
     79                                <size> 
     80                                    <width>100</width> 
     81                                    <height>0</height> 
     82                                </size> 
     83                            </property> 
     84                        </widget> 
     85                    </hbox> 
     86                </widget> 
     87                <widget class="QLayoutWidget"> 
     88                    <property name="name"> 
     89                        <cstring>layout4</cstring> 
     90                    </property> 
     91                    <hbox> 
     92                        <property name="name"> 
     93                            <cstring>unnamed</cstring> 
     94                        </property> 
     95                        <widget class="QLabel"> 
     96                            <property name="name"> 
     97                                <cstring>textLabel2</cstring> 
     98                            </property> 
     99                            <property name="text"> 
     100                                <string>Clock Source:</string> 
     101                            </property> 
     102                            <property name="buddy" stdset="0"> 
     103                                <cstring>clocksource</cstring> 
     104                            </property> 
     105                        </widget> 
     106                        <widget class="QComboBox"> 
     107                            <property name="name"> 
     108                                <cstring>clocksource</cstring> 
     109                            </property> 
     110                        </widget> 
     111                        <spacer> 
     112                            <property name="name"> 
     113                                <cstring>spacer2</cstring> 
     114                            </property> 
     115                            <property name="orientation"> 
     116                                <enum>Horizontal</enum> 
     117                            </property> 
     118                            <property name="sizeType"> 
     119                                <enum>Expanding</enum> 
     120                            </property> 
     121                            <property name="sizeHint"> 
     122                                <size> 
     123                                    <width>31</width> 
     124                                    <height>21</height> 
     125                                </size> 
     126                            </property> 
     127                        </spacer> 
     128                        <widget class="QLabel"> 
     129                            <property name="name"> 
     130                                <cstring>textLabel2_2</cstring> 
     131                            </property> 
     132                            <property name="text"> 
     133                                <string>Sample Rate:</string> 
     134                            </property> 
     135                            <property name="buddy" stdset="0"> 
     136                                <cstring>clocksource</cstring> 
     137                            </property> 
     138                        </widget> 
     139                        <widget class="QComboBox"> 
     140                            <property name="name"> 
     141                                <cstring>samplerate</cstring> 
     142                            </property> 
     143                            <property name="enabled"> 
     144                                <bool>false</bool> 
     145                            </property> 
     146                        </widget> 
     147                    </hbox> 
     148                </widget> 
     149            </vbox> 
    57150        </widget> 
    58         <widget class="QLineEdit" row="0" column="1"> 
    59             <property name="name"> 
    60                 <cstring>txtNickname</cstring> 
    61             </property> 
    62             <property name="minimumSize"> 
    63                 <size> 
    64                     <width>100</width> 
    65                     <height>0</height> 
    66                 </size> 
    67             </property> 
    68         </widget> 
    69         <widget class="QLabel" row="1" column="0"> 
    70             <property name="name"> 
    71                 <cstring>textLabel2</cstring> 
    72             </property> 
    73             <property name="text"> 
    74                 <string>Clock Source:</string> 
    75             </property> 
    76             <property name="buddy" stdset="0"> 
    77                 <cstring>clocksource</cstring> 
    78             </property> 
    79         </widget> 
    80         <widget class="QComboBox" row="1" column="1"> 
    81             <property name="name"> 
    82                 <cstring>clocksource</cstring> 
    83             </property> 
    84         </widget> 
    85         <spacer row="0" column="2" rowspan="2" colspan="1"> 
     151        <spacer> 
    86152            <property name="name"> 
    87153                <cstring>spacer1</cstring> 
     
    95161            <property name="sizeHint"> 
    96162                <size> 
    97                     <width>111</width> 
     163                    <width>330</width> 
    98164                    <height>71</height> 
    99165                </size> 
    100166            </property> 
    101167        </spacer> 
    102     </grid
     168    </hbox
    103169</widget> 
    104170<connections> 
     
    115181        <slot>nicknameChanged(const QString&amp;)</slot> 
    116182    </connection> 
     183    <connection> 
     184        <sender>samplerate</sender> 
     185        <signal>activated(int)</signal> 
     186        <receiver>GlobalMixerUi</receiver> 
     187        <slot>samplerateChanged(int)</slot> 
     188    </connection> 
    117189</connections> 
    118190<slots> 
    119191    <slot>clockChanged( int )</slot> 
    120192    <slot>nicknameChanged( const QString&amp; )</slot> 
     193    <slot>samplerateChanged(int)</slot> 
    121194</slots> 
    122195<layoutdefaults spacing="6" margin="11"/> 
  • trunk/libffado/support/mixer/mixer_motu.py

    r1274 r1336  
    505505        # may end up using a matrix mixer. 
    506506        self.PairSwitches={ 
    507             self.mix1ana1_2_pair:   ['Mixer/Mix1/Ana1_2_pair'], 
    508             self.mix1ana3_4_pair:   ['Mixer/Mix1/Ana3_4_pair'], 
    509             self.mix1ana5_6_pair:   ['Mixer/Mix1/Ana5_6_pair'], 
    510             self.mix1ana7_8_pair:   ['Mixer/Mix1/Ana7_8_pair'], 
    511             self.mix1aes1_2_pair:   ['Mixer/Mix1/Aes1_2_pair'], 
    512             self.mix1adat1_2_pair:  ['Mixer/Mix1/Adat1_2_pair'], 
    513             self.mix1adat3_4_pair:  ['Mixer/Mix1/Adat3_4_pair'], 
    514             self.mix1adat5_6_pair:  ['Mixer/Mix1/Adat5_6_pair'], 
    515             self.mix1adat7_8_pair:  ['Mixer/Mix1/Adat7_8_pair'], 
    516             self.mix1spdif1_2_pair: ['Mixer/Mix1/Spdif1_2_pair'], 
    517  
    518             self.mix2ana1_2_pair:   ['Mixer/Mix2/Ana1_2_pair'], 
    519             self.mix2ana3_4_pair:   ['Mixer/Mix2/Ana3_4_pair'], 
    520             self.mix2ana5_6_pair:   ['Mixer/Mix2/Ana5_6_pair'], 
    521             self.mix2ana7_8_pair:   ['Mixer/Mix2/Ana7_8_pair'], 
    522             self.mix2aes1_2_pair:   ['Mixer/Mix2/Aes1_2_pair'], 
    523             self.mix2adat1_2_pair:  ['Mixer/Mix2/Adat1_2_pair'], 
    524             self.mix2adat3_4_pair:  ['Mixer/Mix2/Adat3_4_pair'], 
    525             self.mix2adat5_6_pair:  ['Mixer/Mix2/Adat5_6_pair'], 
    526             self.mix2adat7_8_pair:  ['Mixer/Mix2/Adat7_8_pair'], 
    527             self.mix2spdif1_2_pair: ['Mixer/Mix2/Spdif1_2_pair'], 
    528  
    529             self.mix3ana1_2_pair:   ['Mixer/Mix3/Ana1_2_pair'], 
    530             self.mix3ana3_4_pair:   ['Mixer/Mix3/Ana3_4_pair'], 
    531             self.mix3ana5_6_pair:   ['Mixer/Mix3/Ana5_6_pair'], 
    532             self.mix3ana7_8_pair:   ['Mixer/Mix3/Ana7_8_pair'], 
    533             self.mix3aes1_2_pair:   ['Mixer/Mix3/Aes1_2_pair'], 
    534             self.mix3adat1_2_pair:  ['Mixer/Mix3/Adat1_2_pair'], 
    535             self.mix3adat3_4_pair:  ['Mixer/Mix3/Adat3_4_pair'], 
    536             self.mix3adat5_6_pair:  ['Mixer/Mix3/Adat5_6_pair'], 
    537             self.mix3adat7_8_pair:  ['Mixer/Mix3/Adat7_8_pair'], 
    538             self.mix3spdif1_2_pair: ['Mixer/Mix3/Spdif1_2_pair'], 
    539  
    540             self.mix4ana1_2_pair:   ['Mixer/Mix4/Ana1_2_pair'], 
    541             self.mix4ana3_4_pair:   ['Mixer/Mix4/Ana3_4_pair'], 
    542             self.mix4ana5_6_pair:   ['Mixer/Mix4/Ana5_6_pair'], 
    543             self.mix4ana7_8_pair:   ['Mixer/Mix4/Ana7_8_pair'], 
    544             self.mix4aes1_2_pair:   ['Mixer/Mix4/Aes1_2_pair'], 
    545             self.mix4adat1_2_pair:  ['Mixer/Mix4/Adat1_2_pair'], 
    546             self.mix4adat3_4_pair:  ['Mixer/Mix4/Adat3_4_pair'], 
    547             self.mix4adat5_6_pair:  ['Mixer/Mix4/Adat5_6_pair'], 
    548             self.mix4adat7_8_pair:  ['Mixer/Mix4/Adat7_8_pair'], 
    549             self.mix4spdif1_2_pair: ['Mixer/Mix4/Spdif1_2_pair'], 
     507#            self.mix1ana1_2_pair:   ['Mixer/Mix1/Ana1_2_pair'], 
     508#            self.mix1ana3_4_pair:   ['Mixer/Mix1/Ana3_4_pair'], 
     509#            self.mix1ana5_6_pair:   ['Mixer/Mix1/Ana5_6_pair'], 
     510#            self.mix1ana7_8_pair:   ['Mixer/Mix1/Ana7_8_pair'], 
     511#            self.mix1aes1_2_pair:   ['Mixer/Mix1/Aes1_2_pair'], 
     512#            self.mix1adat1_2_pair:  ['Mixer/Mix1/Adat1_2_pair'], 
     513#            self.mix1adat3_4_pair:  ['Mixer/Mix1/Adat3_4_pair'], 
     514#            self.mix1adat5_6_pair:  ['Mixer/Mix1/Adat5_6_pair'], 
     515#            self.mix1adat7_8_pair:  ['Mixer/Mix1/Adat7_8_pair'], 
     516#            self.mix1spdif1_2_pair: ['Mixer/Mix1/Spdif1_2_pair'], 
     517 
     518#            self.mix2ana1_2_pair:   ['Mixer/Mix2/Ana1_2_pair'], 
     519#            self.mix2ana3_4_pair:   ['Mixer/Mix2/Ana3_4_pair'], 
     520#            self.mix2ana5_6_pair:   ['Mixer/Mix2/Ana5_6_pair'], 
     521#            self.mix2ana7_8_pair:   ['Mixer/Mix2/Ana7_8_pair'], 
     522#            self.mix2aes1_2_pair:   ['Mixer/Mix2/Aes1_2_pair'], 
     523#            self.mix2adat1_2_pair:  ['Mixer/Mix2/Adat1_2_pair'], 
     524#            self.mix2adat3_4_pair:  ['Mixer/Mix2/Adat3_4_pair'], 
     525#            self.mix2adat5_6_pair:  ['Mixer/Mix2/Adat5_6_pair'], 
     526#            self.mix2adat7_8_pair:  ['Mixer/Mix2/Adat7_8_pair'], 
     527#            self.mix2spdif1_2_pair: ['Mixer/Mix2/Spdif1_2_pair'], 
     528 
     529#            self.mix3ana1_2_pair:   ['Mixer/Mix3/Ana1_2_pair'], 
     530#            self.mix3ana3_4_pair:   ['Mixer/Mix3/Ana3_4_pair'], 
     531#            self.mix3ana5_6_pair:   ['Mixer/Mix3/Ana5_6_pair'], 
     532#            self.mix3ana7_8_pair:   ['Mixer/Mix3/Ana7_8_pair'], 
     533#            self.mix3aes1_2_pair:   ['Mixer/Mix3/Aes1_2_pair'], 
     534#            self.mix3adat1_2_pair:  ['Mixer/Mix3/Adat1_2_pair'], 
     535#            self.mix3adat3_4_pair:  ['Mixer/Mix3/Adat3_4_pair'], 
     536#            self.mix3adat5_6_pair:  ['Mixer/Mix3/Adat5_6_pair'], 
     537#            self.mix3adat7_8_pair:  ['Mixer/Mix3/Adat7_8_pair'], 
     538#            self.mix3spdif1_2_pair: ['Mixer/Mix3/Spdif1_2_pair'], 
     539 
     540#            self.mix4ana1_2_pair:   ['Mixer/Mix4/Ana1_2_pair'], 
     541#            self.mix4ana3_4_pair:   ['Mixer/Mix4/Ana3_4_pair'], 
     542#            self.mix4ana5_6_pair:   ['Mixer/Mix4/Ana5_6_pair'], 
     543#            self.mix4ana7_8_pair:   ['Mixer/Mix4/Ana7_8_pair'], 
     544#            self.mix4aes1_2_pair:   ['Mixer/Mix4/Aes1_2_pair'], 
     545#            self.mix4adat1_2_pair:  ['Mixer/Mix4/Adat1_2_pair'], 
     546#            self.mix4adat3_4_pair:  ['Mixer/Mix4/Adat3_4_pair'], 
     547#            self.mix4adat5_6_pair:  ['Mixer/Mix4/Adat5_6_pair'], 
     548#            self.mix4adat7_8_pair:  ['Mixer/Mix4/Adat7_8_pair'], 
     549#            self.mix4spdif1_2_pair: ['Mixer/Mix4/Spdif1_2_pair'], 
    550550        } 
    551551 
     
    560560            self.optical_in_mode:   ['/Mixer/Control/OpticalIn_mode'], 
    561561            self.optical_out_mode:  ['/Mixer/Control/OpticalOut_mode'], 
     562 
     563            self.meter_src_ctrl:    ['/Mixer/Control/Meter_src'], 
     564            self.aesebu_meter_ctrl: ['/Mixer/Control/Meter_aesebu_src'], 
     565            self.peakhold_time_ctrl:['/Mixer/Control/Meter_peakhold_time'], 
     566            self.cliphold_time_ctrl:['/Mixer/Control/Meter_cliphold_time'], 
    562567        } 
    563568 
     
    594599            # Mic input controls displace AES/EBU since no current device 
    595600            # has both. 
    596             self.mix1_aes_group.setTitle("Mic inputs") 
    597             self.mix2_aes_group.setTitle("Mic inputs") 
    598             self.mix3_aes_group.setTitle("Mic inputs") 
    599             self.mix4_aes_group.setTitle("Mic inputs") 
     601            self.mix1_tab.setTabLabel(self.mix1_tab.page(1), "Mic inputs"); 
     602            self.mix2_tab.setTabLabel(self.mix1_tab.page(1), "Mic inputs"); 
     603            self.mix3_tab.setTabLabel(self.mix1_tab.page(1), "Mic inputs"); 
     604            self.mix4_tab.setTabLabel(self.mix1_tab.page(1), "Mic inputs"); 
    600605            # FIXME: when implmented, will mic channels just reuse the AES/EBU 
    601606            # dbus path?  If not we'll have to reset the respective values in 
     
    603608        else: 
    604609            if (not(self.has_aesebu_inputs)): 
    605                 self.mix1_aes_group.setEnabled(False) 
    606                 self.mix2_aes_group.setEnabled(False) 
    607                 self.mix3_aes_group.setEnabled(False) 
    608                 self.mix4_aes_group.setEnabled(False) 
     610                self.mix1_tab.page(1).setEnabled(False) 
     611                self.mix2_tab.page(1).setEnabled(False) 
     612                self.mix3_tab.page(1).setEnabled(False) 
     613                self.mix4_tab.page(1).setEnabled(False) 
    609614        if (not(self.has_spdif_inputs)): 
    610             self.mix1_spdif_group.setEnabled(False) 
    611             self.mix2_spdif_group.setEnabled(False) 
    612             self.mix3_spdif_group.setEnabled(False) 
    613             self.mix4_spdif_group.setEnabled(False) 
    614  
    615         # Devices without AES/EBU inputs/outputs have dedicated "MainOut" 
    616         # outputs instead. 
    617         if (not(self.has_aesebu_inputs)): 
     615            self.mix1_tab.page(2).setEnabled(False); 
     616            self.mix2_tab.page(2).setEnabled(False); 
     617            self.mix3_tab.page(2).setEnabled(False); 
     618            self.mix4_tab.page(2).setEnabled(False); 
     619 
     620        # Devices without AES/EBU inputs/outputs (normally ID 6 in the 
     621        # destination lists) have dedicated "MainOut" outputs instead.  The 
     622        # 896HD is an exception: it uses ID 6 for MainOut and ID 7 
     623        # (nominally SPDIF) for AES/EBU. 
     624        if (not(self.has_aesebu_inputs) or self.model==MOTU_MODEL_896HD): 
    618625            self.mix1_dest.changeItem("MainOut", 6) 
    619626            self.mix2_dest.changeItem("MainOut", 6) 
    620627            self.mix3_dest.changeItem("MainOut", 6) 
    621628            self.mix4_dest.changeItem("MainOut", 6) 
     629            self.phones_src.changeItem("MainOut", 6) 
     630        # Change the SPDIF destination to AES/EBU for the 896HD. 
     631        if (self.model == MOTU_MODEL_896HD): 
     632            self.mix1_dest.changeItem("AES/EBU", 7) 
     633            self.mix2_dest.changeItem("AES/EBU", 7) 
     634            self.mix3_dest.changeItem("AES/EBU", 7) 
     635            self.mix4_dest.changeItem("AES/EBU", 7) 
     636            self.phones_src.changeItem("AES/EBU", 7) 
    622637 
    623638        # Some devices don't have the option of selecting an optical SPDIF 
     
    627642            self.optical_out_mode.removeItem(2) 
    628643 
     644        # Only the 896HD has meter controls 
     645        if (self.model != MOTU_MODEL_896HD): 
     646            self.disable_hide(self.meter_src) 
     647            self.disable_hide(self.aesebu_meter) 
     648            self.disable_hide(self.peakhold_time) 
     649            self.disable_hide(self.cliphold_time) 
     650 
    629651        # Some controls must be disabled if the device is streaming 
    630652        if (self.is_streaming): 
     
    636658        if (self.sample_rate > 96000): 
    637659            print "Disabling controls not present above 96 kHz" 
    638             self.mix1_adat_group.setEnabled(False) 
    639             self.mix1_aes_group.setEnabled(False) 
    640             self.mix1_spdif_group.setEnabled(False) 
    641             self.mix2_adat_group.setEnabled(False) 
    642             self.mix2_aes_group.setEnabled(False) 
    643             self.mix2_spdif_group.setEnabled(False) 
    644             self.mix3_adat_group.setEnabled(False) 
    645             self.mix3_aes_group.setEnabled(False) 
    646             self.mix3_spdif_group.setEnabled(False) 
    647             self.mix4_adat_group.setEnabled(False) 
    648             self.mix4_aes_group.setEnabled(False) 
    649             self.mix4_spdif_group.setEnabled(False) 
     660            self.mix1_tab.page(3).setEnabled(False)  # ADAT 
     661            self.mix1_tab.page(2).setEnabled(False)  # SPDIF 
     662            self.mix1_tab.page(1).setEnabled(False)  # AES/EBU 
     663            self.mix2_tab.page(3).setEnabled(False)  # ADAT 
     664            self.mix2_tab.page(2).setEnabled(False)  # SPDIF 
     665            self.mix2_tab.page(1).setEnabled(False)  # AES/EBU 
     666            self.mix3_tab.page(3).setEnabled(False)  # ADAT 
     667            self.mix3_tab.page(2).setEnabled(False)  # SPDIF 
     668            self.mix3_tab.page(1).setEnabled(False)  # AES/EBU 
     669            self.mix4_tab.page(3).setEnabled(False)  # ADAT 
     670            self.mix4_tab.page(2).setEnabled(False)  # SPDIF 
     671            self.mix4_tab.page(1).setEnabled(False)  # AES/EBU 
    650672        if (self.sample_rate > 48000): 
    651673            print "Disabling controls not present above 48 kHz" 
    652             self.mix1_adat58_group.setEnabled(False) 
    653             self.mix2_adat58_group.setEnabled(False) 
    654             self.mix3_adat58_group.setEnabled(False) 
    655             self.mix4_adat58_group.setEnabled(False) 
     674            self.mix1_adat5.setEnabled(False) 
     675            self.mix1_adat6.setEnabled(False) 
     676            self.mix1_adat7.setEnabled(False) 
     677            self.mix1_adat8.setEnabled(False) 
     678            self.mix2_adat5.setEnabled(False) 
     679            self.mix2_adat6.setEnabled(False) 
     680            self.mix2_adat7.setEnabled(False) 
     681            self.mix2_adat8.setEnabled(False) 
     682            self.mix3_adat5.setEnabled(False) 
     683            self.mix3_adat6.setEnabled(False) 
     684            self.mix3_adat7.setEnabled(False) 
     685            self.mix3_adat8.setEnabled(False) 
     686            self.mix4_adat5.setEnabled(False) 
     687            self.mix4_adat6.setEnabled(False) 
     688            self.mix4_adat7.setEnabled(False) 
     689            self.mix4_adat8.setEnabled(False) 
    656690 
    657691        # Ensure the correct input controls are active for a given interface 
    658692        if (self.model == MOTU_MODEL_TRAVELER): 
    659693            self.disable_hide(self.ana1_level) 
    660             self.disable_hide(self.ana1_level_label) 
    661694            self.disable_hide(self.ana2_level) 
    662             self.disable_hide(self.ana2_level_label) 
    663695            self.disable_hide(self.ana3_level) 
    664             self.disable_hide(self.ana3_level_label) 
    665696            self.disable_hide(self.ana4_level) 
    666             self.disable_hide(self.ana4_level_label) 
    667697            self.disable_hide(self.ana1_boost) 
    668             self.disable_hide(self.ana1_boost_label) 
    669698            self.disable_hide(self.ana2_boost) 
    670             self.disable_hide(self.ana2_boost_label) 
    671699            self.disable_hide(self.ana3_boost) 
    672             self.disable_hide(self.ana3_boost_label) 
    673700            self.disable_hide(self.ana4_boost) 
    674             self.disable_hide(self.ana4_boost_label) 
     701            self.disable_hide(self.ana5_trimgain) 
     702            self.disable_hide(self.ana5_trimgain_label) 
     703            self.disable_hide(self.ana6_trimgain) 
     704            self.disable_hide(self.ana6_trimgain_label) 
     705            self.disable_hide(self.ana7_trimgain) 
     706            self.disable_hide(self.ana7_trimgain_label) 
     707            self.disable_hide(self.ana8_trimgain) 
     708            self.disable_hide(self.ana8_trimgain_label) 
     709            self.disable_hide(self.ana5_pad) 
     710            self.disable_hide(self.ana6_pad) 
     711            self.disable_hide(self.ana7_pad) 
     712            self.disable_hide(self.ana8_pad) 
    675713        else: 
    676714            self.disable_hide(self.ana1_trimgain) 
     
    683721            self.disable_hide(self.ana4_trimgain_label) 
    684722            self.disable_hide(self.ana1_pad) 
    685             self.disable_hide(self.ana1_pad_label) 
    686723            self.disable_hide(self.ana2_pad) 
    687             self.disable_hide(self.ana2_pad_label) 
    688724            self.disable_hide(self.ana3_pad) 
    689             self.disable_hide(self.ana3_pad_label) 
    690725            self.disable_hide(self.ana4_pad) 
    691             self.disable_hide(self.ana4_pad_label) 
     726            self.disable_hide(self.ana5_trimgain) 
     727            self.disable_hide(self.ana5_trimgain_label) 
     728            self.disable_hide(self.ana6_trimgain) 
     729            self.disable_hide(self.ana6_trimgain_label) 
     730            self.disable_hide(self.ana7_trimgain) 
     731            self.disable_hide(self.ana7_trimgain_label) 
     732            self.disable_hide(self.ana8_trimgain) 
     733            self.disable_hide(self.ana8_trimgain_label) 
     734            self.disable_hide(self.ana5_pad) 
     735            self.disable_hide(self.ana6_pad) 
     736            self.disable_hide(self.ana7_pad) 
     737            self.disable_hide(self.ana8_pad) 
    692738 
    693739        # Now fetch the current values into the respective controls.  Don't 
     
    735781            val = self.hw.getMatrixMixerValue(info[0], info[1], info[2]) 
    736782            print "%s for mix %d channel %d is %d" % (info[0] , info[1], info[2], val) 
    737             ctrl.setChecked(val) 
     783            ctrl.setOn(val) 
    738784            QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateChannelBinarySwitch) 
    739785 
     
    743789            val = self.hw.getDiscrete(info[0]) 
    744790            print "%s switch is %d" % (info[0] , val) 
    745             ctrl.setChecked(val) 
     791            ctrl.setOn(val) 
    746792            QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateBinarySwitch) 
    747793 
  • trunk/libffado/support/mixer/mixer_motu.ui

    r1274 r1336  
    11<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> 
    22<class>MotuMixerUI</class> 
    3 <comment>Copyright (C) 2005-2008 by Pieter Palmers 
    4         Copyright (C) 2008 by Jonathan Woithe 
    5          
    6        This file is part of FFADO 
    7        FFADO = Free Firewire (pro-)audio drivers for linux 
    8          
    9        FFADO is based upon FreeBoB. 
    10          
    11        This program is free software: you can redistribute it and/or modify 
    12        it under the terms of the GNU General Public License as published by 
    13        the Free Software Foundation, either version 2 of the License, or 
    14        (at your option) version 3 of the License. 
    15          
    16        This program is distributed in the hope that it will be useful, 
    17        but WITHOUT ANY WARRANTY; without even the implied warranty of 
    18        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    19        GNU General Public License for more details. 
     3<comment>Copyright (C) 2008 by Jonathan Woithe 
     4Copyright (C) 2005-2008 by Pieter Palmers 
     5 
     6This file is part of FFADO 
     7FFADO = Free Firewire (pro-)audio drivers for linux 
     8 
     9FFADO is based upon FreeBoB. 
     10         
     11This program is free software: you can redistribute it and/or modify 
     12it under the terms of the GNU General Public License as published by 
     13the Free Software Foundation, either version 2 of the License, or 
     14(at your option) version 3 of the License. 
     15         
     16This program is distributed in the hope that it will be useful, 
     17but WITHOUT ANY WARRANTY; without even the implied warranty of 
     18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     19GNU General Public License for more details. 
    2020</comment> 
    2121<widget class="QWidget"> 
     
    2727            <x>0</x> 
    2828            <y>0</y> 
    29             <width>800</width> 
    30             <height>750</height> 
     29            <width>1004</width> 
     30            <height>693</height> 
    3131        </rect> 
    3232    </property> 
    33     <property name="sizePolicy"> 
    34         <sizepolicy> 
    35             <hsizetype>0</hsizetype> 
    36             <vsizetype>0</vsizetype> 
    37             <horstretch>0</horstretch> 
    38             <verstretch>0</verstretch> 
    39         </sizepolicy> 
    40     </property> 
    4133    <property name="minimumSize"> 
    42         <size> 
    43             <width>800</width> 
    44             <height>750</height> 
    45         </size> 
    46     </property> 
    47     <property name="sizeIncrement"> 
    48         <size> 
    49             <width>0</width> 
    50             <height>0</height> 
    51         </size> 
    52     </property> 
    53     <property name="baseSize"> 
    5434        <size> 
    5535            <width>0</width> 
     
    5838    </property> 
    5939    <property name="caption"> 
    60         <string>MOTU </string> 
     40        <string>Form1</string> 
    6141    </property> 
    62     <widget class="QGroupBox"
     42    <hbox
    6343        <property name="name"> 
    64             <cstring>groupBox7</cstring> 
     44            <cstring>unnamed</cstring> 
    6545        </property> 
    66         <property name="geometry"> 
    67             <rect> 
    68                 <x>10</x> 
    69                 <y>470</y> 
    70                 <width>170</width> 
    71                 <height>140</height> 
    72             </rect> 
    73         </property> 
    74         <property name="title"> 
    75             <string>Output settings</string> 
    76         </property> 
    77         <widget class="QLabel"> 
     46        <widget class="QGroupBox"> 
    7847            <property name="name"> 
    79                 <cstring>textLabel1_2_11_3_2</cstring> 
     48                <cstring>settings_pane</cstring> 
    8049            </property> 
    81             <property name="geometry"> 
    82                 <rect> 
    83                     <x>10</x> 
    84                     <y>50</y> 
    85                     <width>90</width> 
    86                     <height>22</height> 
    87                 </rect> 
     50            <property name="title"> 
     51                <string>Device settings</string> 
    8852            </property> 
    89             <property name="font"> 
    90                 <font> 
    91                 </font> 
    92             </property> 
    93             <property name="text"> 
    94                 <string>&lt;qt&gt;&lt;small&gt;Phones assign&lt;/small&gt;&lt;/qt&gt;</string> 
    95             </property> 
    96             <property name="alignment"> 
    97                 <set>WordBreak|AlignCenter</set> 
    98             </property> 
    99         </widget> 
    100         <widget class="QLabel"> 
    101             <property name="name"> 
    102                 <cstring>textLabel1_2_11_3_2_2_2</cstring> 
    103             </property> 
    104             <property name="geometry"> 
    105                 <rect> 
    106                     <x>10</x> 
    107                     <y>110</y> 
    108                     <width>100</width> 
    109                     <height>22</height> 
    110                 </rect> 
    111             </property> 
    112             <property name="font"> 
    113                 <font> 
    114                 </font> 
    115             </property> 
    116             <property name="text"> 
    117                 <string>&lt;qt&gt;&lt;small&gt;Optical out mode&lt;/small&gt;&lt;qt&gt;</string> 
    118             </property> 
    119             <property name="alignment"> 
    120                 <set>WordBreak|AlignCenter</set> 
    121             </property> 
    122         </widget> 
    123         <widget class="QComboBox"> 
    124             <item> 
    125                 <property name="text"> 
    126                     <string>Disabled</string> 
     53            <vbox> 
     54                <property name="name"> 
     55                    <cstring>unnamed</cstring> 
    12756                </property> 
    128             </item> 
    129             <item> 
    130                 <property name="text"> 
    131                     <string>Phones</string> 
    132                 </property> 
    133             </item> 
    134             <item> 
    135                 <property name="text"> 
    136                     <string>Analog 1-2</string> 
    137                 </property> 
    138             </item> 
    139             <item> 
    140                 <property name="text"> 
    141                     <string>Analog 3-4</string> 
    142                 </property> 
    143             </item> 
    144             <item> 
    145                 <property name="text"> 
    146                     <string>Analog 5-6</string> 
    147                 </property> 
    148             </item> 
    149             <item> 
    150                 <property name="text"> 
    151                     <string>Analog 7-8</string> 
    152                 </property> 
    153             </item> 
    154             <item> 
    155                 <property name="text"> 
    156                     <string>AES/EBU</string> 
    157                 </property> 
    158             </item> 
    159             <item> 
    160                 <property name="text"> 
    161                     <string>SPDIF</string> 
    162                 </property> 
    163             </item> 
    164             <item> 
    165                 <property name="text"> 
    166                     <string>ADAT 1-2</string> 
    167                 </property> 
    168             </item> 
    169             <item> 
    170                 <property name="text"> 
    171                     <string>ADAT 3-4</string> 
    172                 </property> 
    173             </item> 
    174             <item> 
    175                 <property name="text"> 
    176                     <string>ADAT 5-6</string> 
    177                 </property> 
    178             </item> 
    179             <item> 
    180                 <property name="text"> 
    181                     <string>ADAT 7-8</string> 
    182                 </property> 
    183             </item> 
    184             <property name="name"> 
    185                 <cstring>phones_src</cstring> 
    186             </property> 
    187             <property name="geometry"> 
    188                 <rect> 
    189                     <x>10</x> 
    190                     <y>30</y> 
    191                     <width>90</width> 
    192                     <height>21</height> 
    193                 </rect> 
    194             </property> 
    195             <property name="font"> 
    196                 <font> 
    197                     <pointsize>9</pointsize> 
    198                 </font> 
    199             </property> 
    200         </widget> 
    201         <widget class="QComboBox"> 
    202             <item> 
    203                 <property name="text"> 
    204                     <string>Disabled</string> 
    205                 </property> 
    206             </item> 
    207             <item> 
    208                 <property name="text"> 
    209                     <string>ADAT</string> 
    210                 </property> 
    211             </item> 
    212             <item> 
    213                 <property name="text"> 
    214                     <string>Toslink</string> 
    215                 </property> 
    216             </item> 
    217             <property name="name"> 
    218                 <cstring>optical_out_mode</cstring> 
    219             </property> 
    220             <property name="geometry"> 
    221                 <rect> 
    222                     <x>10</x> 
    223                     <y>90</y> 
    224                     <width>90</width> 
    225                     <height>21</height> 
    226                 </rect> 
    227             </property> 
    228             <property name="font"> 
    229                 <font> 
    230                     <pointsize>9</pointsize> 
    231                 </font> 
    232             </property> 
    233         </widget> 
    234     </widget> 
    235     <widget class="QTabWidget"> 
    236         <property name="name"> 
    237             <cstring>tabWidget2</cstring> 
    238         </property> 
    239         <property name="geometry"> 
    240             <rect> 
    241                 <x>190</x> 
    242                 <y>10</y> 
    243                 <width>600</width> 
    244                 <height>740</height> 
    245             </rect> 
    246         </property> 
    247         <widget class="QWidget"> 
    248             <property name="name"> 
    249                 <cstring>tab</cstring> 
    250