Changeset 1630 for trunk/libffado

Show
Ignore:
Timestamp:
08/27/09 12:25:28 (15 years ago)
Author:
ppalmers
Message:

add base level support for the DICE EAP based mixers (incomplete)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/src/bebob/focusrite/focusrite_generic.h

    r1543 r1630  
    187187    virtual int getRowCount( ); 
    188188    virtual int getColCount( ); 
     189 
     190    // full map updates are unsupported 
     191    virtual bool getCoefficientMap(int &) {return false;}; 
     192    virtual bool storeCoefficientMap(int &) {return false;}; 
    189193 
    190194protected: 
  • trunk/libffado/src/dice/dice_avdevice.cpp

    r1550 r1630  
    4646#include "devicemanager.h" 
    4747 
     48#include "focusrite/saffire_pro40.h" 
     49 
    4850using namespace std; 
    4951 
     
    5254Device::Device( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )) 
    5355    : FFADODevice( d, configRom ) 
     56    , m_eap( NULL ) 
    5457    , m_global_reg_offset (0xFFFFFFFFLU) 
    5558    , m_global_reg_size (0xFFFFFFFFLU) 
     
    9194        unlock(); 
    9295    } 
     96 
     97    if(m_eap) { 
     98        delete m_eap; 
     99    } 
     100 
    93101} 
    94102 
     
    111119Device::createDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )) 
    112120{ 
    113     return new Device( d, configRom ); 
     121    unsigned int vendorId = configRom->getNodeVendorId(); 
     122    unsigned int modelId = configRom->getModelId(); 
     123 
     124    switch (vendorId) { 
     125        case FW_VENDORID_FOCUSRITE: 
     126            switch(modelId) { 
     127                case 0x00000005: 
     128                    return new Focusrite::SaffirePro40(d, configRom); 
     129                default: // return a plain Dice device 
     130                    return new Device(d, configRom); 
     131           } 
     132        default: 
     133            return new Device(d, configRom); 
     134    } 
     135    return NULL; 
    114136} 
    115137 
     
    137159    } 
    138160 
     161    bool supports_eap = Device::EAP::supportsEAP(*this); 
     162    if (supports_eap) { // FIXME: move to buildMixer() ?? 
     163        m_eap = new Device::EAP(*this); 
     164        if(m_eap == NULL) { 
     165            debugError("Failed to allocate EAP.\n"); 
     166            return false; 
     167        } 
     168        if(!m_eap->init()) { 
     169            debugError("Could not init EAP\n"); 
     170            delete m_eap; 
     171            m_eap = NULL; 
     172            return false; 
     173        } 
     174        // register the EAP controls to the control structure 
     175        if(!addElement(m_eap)) { 
     176            debugError("Failed to add the EAP controls to the control tree\n"); 
     177            return false; 
     178        } 
     179    } 
    139180    return true; 
    140181} 
    141182 
     183enum Device::eDiceConfig 
     184Device::getCurrentConfig() 
     185{ 
     186    int samplerate = getSamplingFrequency(); 
     187    if(samplerate > 31999 && samplerate <= 48000) { 
     188        return eDC_Low; 
     189    } 
     190    if(samplerate > 48000 && samplerate <= 96000) { 
     191        return eDC_Mid; 
     192    } 
     193    if(samplerate > 96000 && samplerate <= 192000) { 
     194        return eDC_High; 
     195    } 
     196    return eDC_Unknown; 
     197} 
     198 
    142199int 
    143 Device::getSamplingFrequency( ) { 
     200Device::getSamplingFrequency() { 
    144201    int samplingFrequency; 
    145202 
     
    17441801 
    17451802        if(!get1394Service().read( nodeId, curr_addr, quads_todo, curr_data ) ) { 
    1746             debugError("Could not read %d quadlets from node 0x%04X addr 0x%012llX\n", nodeId, quads_todo, curr_addr); 
     1803            debugError("Could not read %d quadlets from node 0x%04X addr 0x%012llX\n", quads_todo, nodeId, curr_addr); 
    17471804            return false; 
    17481805        } 
     
    17881845 
    17891846        if(!get1394Service().write( nodeId, addr, quads_todo, curr_data ) ) { 
    1790             debugError("Could not write %d quadlets to node 0x%04X addr 0x%012llX\n", nodeId, quads_todo, curr_addr); 
     1847            debugError("Could not write %d quadlets to node 0x%04X addr 0x%012llX\n", quads_todo, nodeId, curr_addr); 
    17911848            return false; 
    17921849        } 
  • trunk/libffado/src/dice/dice_avdevice.h

    r1550 r1630  
    3636#include "libieee1394/ieee1394service.h" 
    3737 
     38#include "libcontrol/Element.h" 
     39#include "libcontrol/MatrixMixer.h" 
     40#include "libcontrol/CrossbarRouter.h" 
     41 
     42#include "dice_eap.h" 
     43 
    3844#include <string> 
    3945#include <vector> 
     
    5258class Device : public FFADODevice { 
    5359// private: 
     60    typedef std::vector< std::string > diceNameVector; 
     61    typedef std::vector< std::string >::iterator diceNameVectorIterator; 
     62 
    5463public: 
    5564    class Notifier; 
    5665    class EAP; 
    57  
    58 public: 
    59     Device( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )); 
    60     ~Device(); 
    61  
    62     static bool probe( Util::Configuration& c, ConfigRom& configRom, bool generic = false ); 
    63     static FFADODevice * createDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )); 
    64     virtual bool discover(); 
    65  
    66     static int getConfigurationId( ); 
    67  
    68     virtual void showDevice(); 
    69  
    70     virtual bool setSamplingFrequency( int samplingFrequency ); 
    71     virtual int getSamplingFrequency( ); 
    72     virtual std::vector<int> getSupportedSamplingFrequencies(); 
    73  
    74     virtual ClockSourceVector getSupportedClockSources(); 
    75     virtual bool setActiveClockSource(ClockSource); 
    76     virtual ClockSource getActiveClockSource(); 
    77  
    78     virtual int getStreamCount(); 
    79     virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i); 
    80  
    81     virtual bool prepare(); 
    82  
    83     virtual bool lock(); 
    84     virtual bool unlock(); 
    85  
    86     virtual bool startStreamByIndex(int i); 
    87     virtual bool stopStreamByIndex(int i); 
    88  
    89     virtual bool enableStreaming(); 
    90     virtual bool disableStreaming(); 
    91  
    92     virtual std::string getNickname(); 
    93     virtual bool setNickname(std::string name); 
    94  
    95 protected: 
    96  
    97     // streaming stuff 
    98     typedef std::vector< Streaming::StreamProcessor * > StreamProcessorVector; 
    99     typedef std::vector< Streaming::StreamProcessor * >::iterator StreamProcessorVectorIterator; 
    100     StreamProcessorVector m_receiveProcessors; 
    101     StreamProcessorVector m_transmitProcessors; 
    102  
    103 private: // streaming & port helpers 
    104     enum EPortTypes { 
    105         ePT_Analog, 
    106         ePT_MIDI, 
    107     }; 
    108  
    109     typedef struct { 
    110         std::string name; 
    111         enum EPortTypes portType; 
    112         unsigned int streamPosition; 
    113         unsigned int streamLocation; 
    114     } diceChannelInfo; 
    115  
    116     bool addChannelToProcessor( diceChannelInfo *, 
    117                               Streaming::StreamProcessor *, 
    118                               Streaming::Port::E_Direction direction); 
    119  
    120     int allocateIsoChannel(unsigned int packet_size); 
    121     bool deallocateIsoChannel(int channel); 
    122  
    123 private: // helper functions 
    124     bool enableIsoStreaming(); 
    125     bool disableIsoStreaming(); 
    126     bool isIsoStreamingEnabled(); 
    127  
    128     bool maskedCheckZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask); 
    129     bool maskedCheckNotZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask); 
    130  
    131     typedef std::vector< std::string > diceNameVector; 
    132     typedef std::vector< std::string >::iterator diceNameVectorIterator; 
    133     diceNameVector splitNameString(std::string in); 
    134     diceNameVector getTxNameString(unsigned int i); 
    135     diceNameVector getRxNameString(unsigned int i); 
    136     diceNameVector getClockSourceNameString(); 
    137     std::string getDeviceNickName(); 
    138     bool setDeviceNickName(std::string name); 
    139  
    140     enum eClockSourceType  clockIdToType(unsigned int id); 
    141     bool isClockSourceIdLocked(unsigned int id, quadlet_t ext_status_reg); 
    142     bool isClockSourceIdSlipping(unsigned int id, quadlet_t ext_status_reg); 
    143  
    144 private: // register I/O routines 
    145     bool initIoFunctions(); 
    146     // quadlet read/write routines 
    147     bool readReg(fb_nodeaddr_t, fb_quadlet_t *); 
    148     bool writeReg(fb_nodeaddr_t, fb_quadlet_t); 
    149     bool readRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t); 
    150     bool writeRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t); 
    151  
    152     bool readGlobalReg(fb_nodeaddr_t, fb_quadlet_t *); 
    153     bool writeGlobalReg(fb_nodeaddr_t, fb_quadlet_t); 
    154     bool readGlobalRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t); 
    155     bool writeGlobalRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t); 
    156     fb_nodeaddr_t globalOffsetGen(fb_nodeaddr_t, size_t); 
    157  
    158     bool readTxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t *); 
    159     bool writeTxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t); 
    160     bool readTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length); 
    161     bool writeTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length); 
    162     fb_nodeaddr_t txOffsetGen(unsigned int, fb_nodeaddr_t, size_t); 
    163  
    164     bool readRxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t *); 
    165     bool writeRxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t); 
    166     bool readRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length); 
    167     bool writeRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length); 
    168     fb_nodeaddr_t rxOffsetGen(unsigned int, fb_nodeaddr_t, size_t); 
    169  
    170     fb_quadlet_t m_global_reg_offset; 
    171     fb_quadlet_t m_global_reg_size; 
    172     fb_quadlet_t m_tx_reg_offset; 
    173     fb_quadlet_t m_tx_reg_size; 
    174     fb_quadlet_t m_rx_reg_offset; 
    175     fb_quadlet_t m_rx_reg_size; 
    176     fb_quadlet_t m_unused1_reg_offset; 
    177     fb_quadlet_t m_unused1_reg_size; 
    178     fb_quadlet_t m_unused2_reg_offset; 
    179     fb_quadlet_t m_unused2_reg_size; 
    180  
    181     fb_quadlet_t m_nb_tx; 
    182     fb_quadlet_t m_tx_size; 
    183     fb_quadlet_t m_nb_rx; 
    184     fb_quadlet_t m_rx_size; 
    185  
    186 // private: 
    187 public: 
    188     // notification 
    189     Notifier *m_notifier; 
    190  
    191     /** 
    192      * this class reacts on the DICE device writing to the 
    193      * hosts notify address 
    194      */ 
    195     #define DICE_NOTIFIER_BASE_ADDRESS 0x0000FFFFE0000000ULL 
    196     #define DICE_NOTIFIER_BLOCK_LENGTH 4 
    197     class Notifier : public Ieee1394Service::ARMHandler 
    198     { 
    199     public: 
    200         Notifier(Device &, nodeaddr_t start); 
    201         virtual ~Notifier(); 
    202  
    203     private: 
    204         Device &m_device; 
    205     }; 
    20666 
    20767    /** 
     
    20969     * available on some devices 
    21070     */ 
    211     class EAP 
     71    class EAP : public Control::Container 
    21272    { 
    21373    public: 
    214         class Router; 
    215         class Mixer; 
    216  
    217     private: 
    21874        enum eWaitReturn { 
    21975            eWR_Error, 
     
    23389            eRT_Standalone, 
    23490            eRT_Application, 
     91            eRT_None, 
     92        }; 
     93        enum eRouteSource { 
     94            eRS_AES = 0, 
     95            eRS_ADAT = 1, 
     96            eRS_Mixer = 2, 
     97            eRS_InS0 = 4, 
     98            eRS_InS1 = 5, 
     99            eRS_ARM = 10, 
     100            eRS_ARX0 = 11, 
     101            eRS_ARX1 = 12, 
     102            eRS_Muted = 15, 
     103            eRS_Invalid = 16, 
     104        }; 
     105        enum eRouteDestination { 
     106            eRD_AES = 0, 
     107            eRD_ADAT = 1, 
     108            eRD_Mixer0 = 2, 
     109            eRD_Mixer1 = 3, 
     110            eRD_InS0 = 4, 
     111            eRD_InS1 = 5, 
     112            eRD_ARM = 10, 
     113            eRD_ATX0 = 11, 
     114            eRD_ATX1 = 12, 
     115            eRD_Muted = 15, 
     116            eRD_Invalid = 16, 
     117        }; 
     118 
     119    public: 
     120 
     121        // ---------- 
     122        class RouterConfig { 
     123        public: 
     124            struct Route 
     125            { 
     126                enum eRouteSource src; 
     127                int srcChannel; 
     128                enum eRouteDestination dst; 
     129                int dstChannel; 
     130                int peak; 
     131            }; 
     132            typedef std::vector<RouterConfig::Route> RouteVector; 
     133            typedef std::vector<RouterConfig::Route>::iterator RouteVectorIterator; 
     134            RouterConfig(EAP &); 
     135            RouterConfig(EAP &, enum eRegBase, unsigned int offset); 
     136            virtual ~RouterConfig(); 
     137 
     138            virtual bool read() {return read(m_base, m_offset);}; 
     139            virtual bool write() {return write(m_base, m_offset);}; 
     140            virtual bool read(enum eRegBase b, unsigned offset); 
     141            virtual bool write(enum eRegBase b, unsigned offset); 
     142            virtual void show(); 
     143 
     144 
     145            bool insertRoute(struct Route r) 
     146                {return insertRoute(r, m_routes.size());}; 
     147            bool insertRoute(struct Route r, unsigned int index); 
     148            bool replaceRoute(unsigned int old_index, struct Route new_route); 
     149            bool replaceRoute(struct Route old_route, struct Route new_route); 
     150            bool removeRoute(struct Route r); 
     151            bool removeRoute(unsigned int index); 
     152            int getRouteIndex(struct Route r); 
     153            struct Route getRoute(unsigned int index); 
     154 
     155            unsigned int getNbRoutes() {return m_routes.size();}; 
     156 
     157            struct Route getRouteForDestination(enum eRouteDestination dst, int channel); 
     158            RouteVector getRoutesForSource(enum eRouteSource src, int channel); 
     159 
     160            struct Route decodeRoute(uint32_t val); 
     161            uint32_t encodeRoute(struct Route r); 
     162        public: 
     163            static enum eRouteDestination intToRouteDestination(int); 
     164            static enum eRouteSource intToRouteSource(int); 
     165        protected: 
     166            EAP &m_eap; 
     167            enum eRegBase m_base; 
     168            unsigned int m_offset; 
     169            RouteVector m_routes; 
     170        protected: 
     171            DECLARE_DEBUG_MODULE_REFERENCE; 
     172        }; 
     173 
     174        // ---------- 
     175        // the peak space is a special version of a router config 
     176        class PeakSpace : public RouterConfig { 
     177        public: 
     178            PeakSpace(EAP &p) : RouterConfig(p, eRT_Peak, 0) {}; 
     179            virtual ~PeakSpace() {}; 
     180 
     181            virtual bool read() {return read(m_base, m_offset);}; 
     182            virtual bool write() {return write(m_base, m_offset);}; 
     183            virtual bool read(enum eRegBase b, unsigned offset); 
     184            virtual bool write(enum eRegBase b, unsigned offset); 
     185            virtual void show(); 
     186        }; 
     187 
     188        // ---------- 
     189        class StreamConfig { 
     190        public: 
     191            struct ConfigBlock { // FIXME: somewhere in the DICE avdevice this is present too 
     192                uint32_t nb_audio; 
     193                uint32_t nb_midi; 
     194                uint32_t names[DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_QUADS]; 
     195                uint32_t ac3_map; 
     196            }; 
     197            void showConfigBlock(struct ConfigBlock &); 
     198            diceNameVector getNamesForBlock(struct ConfigBlock &b); 
     199        public: 
     200            StreamConfig(EAP &, enum eRegBase, unsigned int offset); 
     201            ~StreamConfig(); 
     202 
     203            bool read() {return read(m_base, m_offset);}; 
     204            bool write() {return write(m_base, m_offset);}; 
     205            bool read(enum eRegBase b, unsigned offset); 
     206            bool write(enum eRegBase b, unsigned offset); 
     207 
     208            void show(); 
     209 
     210        private: 
     211            EAP &m_eap; 
     212            enum eRegBase m_base; 
     213            unsigned int m_offset; 
     214 
     215            uint32_t m_nb_tx; 
     216            uint32_t m_nb_rx; 
     217 
     218            struct ConfigBlock *m_tx_configs; 
     219            struct ConfigBlock *m_rx_configs; 
     220 
     221            DECLARE_DEBUG_MODULE_REFERENCE; 
     222        }; 
     223 
     224    public: // mixer control subclass 
     225        class Mixer : public Control::MatrixMixer { 
     226        public: 
     227            Mixer(EAP &); 
     228            ~Mixer(); 
     229 
     230            bool init(); 
     231            void show(); 
     232 
     233            void updateNameCache(); 
     234            /** 
     235             * load the coefficients from the device into the local cache 
     236             * @return  
     237             */ 
     238            bool loadCoefficients(); 
     239            /** 
     240             * Stores the coefficients from the cache to the device 
     241             * @return  
     242             */ 
     243            bool storeCoefficients(); 
     244 
     245            virtual std::string getRowName( const int ); 
     246            virtual std::string getColName( const int ); 
     247            virtual int canWrite( const int, const int ); 
     248            virtual double setValue( const int, const int, const double ); 
     249            virtual double getValue( const int, const int ); 
     250            virtual int getRowCount( ); 
     251            virtual int getColCount( ); 
     252         
     253            // full map updates are unsupported 
     254            virtual bool getCoefficientMap(int &); 
     255            virtual bool storeCoefficientMap(int &); 
     256 
     257        private: 
     258            EAP &         m_eap; 
     259            fb_quadlet_t *m_coeff; 
     260 
     261            std::map<int, RouterConfig::Route> m_input_route_map; 
     262            std::map<int, RouterConfig::RouteVector> m_output_route_map; 
     263 
     264            DECLARE_DEBUG_MODULE_REFERENCE; 
     265        }; 
     266 
     267        // ---------- 
     268        class Router : public Control::CrossbarRouter { 
     269        private: 
     270            struct Source { 
     271                std::string name; 
     272                enum eRouteSource src; 
     273                int srcChannel; 
     274            }; 
     275            typedef std::vector<Source> SourceVector; 
     276            typedef std::vector<Source>::iterator SourceVectorIterator; 
     277 
     278            struct Destination { 
     279                std::string name; 
     280                enum eRouteDestination dst; 
     281                int dstChannel; 
     282            }; 
     283            typedef std::vector<Destination> DestinationVector; 
     284            typedef std::vector<Destination>::iterator DestinationVectorIterator; 
     285 
     286        public: 
     287            Router(EAP &); 
     288            ~Router(); 
     289 
     290            void show(); 
     291 
     292            // to be subclassed by the implementing 
     293            // devices 
     294            virtual void setupSources(); 
     295            virtual void setupDestinations(); 
     296 
     297            void setupDestinationsAddDestination(const char *name, enum eRouteDestination dstid, 
     298                                                 unsigned int base, unsigned int cnt); 
     299            void setupSourcesAddSource(const char *name, enum eRouteSource srcid, 
     300                                       unsigned int base, unsigned int cnt); 
     301 
     302            int getDestinationIndex(enum eRouteDestination dstid, int channel); 
     303            int getSourceIndex(enum eRouteSource srcid, int channel); 
     304 
     305            // per-coefficient access 
     306            virtual std::string getSourceName(const int); 
     307            virtual std::string getDestinationName(const int); 
     308            virtual int getSourceIndex(std::string); 
     309            virtual int getDestinationIndex(std::string); 
     310            virtual NameVector getSourceNames(); 
     311            virtual NameVector getDestinationNames(); 
     312 
     313            virtual IntVector getDestinationsForSource(const int); 
     314            virtual int getSourceForDestination(const int); 
     315 
     316            virtual bool canConnect( const int source, const int dest); 
     317            virtual bool setConnectionState( const int source, const int dest, const bool enable); 
     318            virtual bool getConnectionState( const int source, const int dest ); 
     319 
     320            virtual bool canConnect(std::string, std::string); 
     321            virtual bool setConnectionState(std::string, std::string, const bool enable); 
     322            virtual bool getConnectionState(std::string, std::string); 
     323 
     324            virtual bool clearAllConnections(); 
     325 
     326            virtual int getNbSources(); 
     327            virtual int getNbDestinations(); 
     328 
     329            // functions to access the entire routing map at once 
     330            // idea is that the row/col nodes that are 1 get a routing entry 
     331            virtual bool getConnectionMap(int *); 
     332            virtual bool setConnectionMap(int *); 
     333 
     334            // peak metering support 
     335            virtual bool hasPeakMetering(); 
     336            virtual bool getPeakValues(double &) {return false;}; 
     337            virtual double getPeakValue(const int source, const int dest); 
     338 
     339        private: 
     340            EAP &m_eap; 
     341            // these contain the sources and destinations available for this 
     342            // router 
     343            SourceVector      m_sources; 
     344            DestinationVector m_destinations; 
     345 
     346            PeakSpace &m_peak; 
     347 
     348            DECLARE_DEBUG_MODULE_REFERENCE; 
    235349        }; 
    236350 
     
    245359        enum eWaitReturn operationBusy(); 
    246360        enum eWaitReturn waitForOperationEnd(int max_wait_time_ms = 100); 
     361 
     362        bool updateConfigurationCache(); 
     363        RouterConfig * getActiveRouterConfig(); 
     364        StreamConfig * getActiveStreamConfig(); 
     365 
     366        bool updateRouterConfig(RouterConfig&, bool low, bool mid, bool high); 
     367        bool updateCurrentRouterConfig(RouterConfig&); 
     368        bool updateStreamConfig(StreamConfig&, bool low, bool mid, bool high); 
     369        bool updateStreamConfig(RouterConfig&, StreamConfig&, bool low, bool mid, bool high); 
     370 
     371        bool loadFlashConfig(); 
     372        bool storeFlashConfig(); 
     373 
     374    private: 
    247375        bool loadRouterConfig(bool low, bool mid, bool high); 
    248376        bool loadStreamConfig(bool low, bool mid, bool high); 
    249377        bool loadRouterAndStreamConfig(bool low, bool mid, bool high); 
    250         bool loadFlashConfig(); 
    251         bool storeFlashConfig(); 
    252          
    253378    private: 
    254379        bool     m_router_exposed; 
     
    260385        bool     m_mixer_readonly; 
    261386        bool     m_mixer_flashstored; 
    262         uint8_t  m_mixer_input_id; 
    263         uint8_t  m_mixer_output_id; 
    264         uint8_t  m_mixer_nb_inputs
    265         uint8_t  m_mixer_nb_outputs
     387        uint8_t  m_mixer_tx_id; 
     388        uint8_t  m_mixer_rx_id; 
     389        uint8_t  m_mixer_nb_tx
     390        uint8_t  m_mixer_nb_rx
    266391 
    267392        bool     m_general_support_dynstream; 
     
    283408        fb_nodeaddr_t offsetGen(enum eRegBase, unsigned, size_t); 
    284409 
    285         Device &m_device; 
     410    private: 
    286411        DECLARE_DEBUG_MODULE_REFERENCE; 
     412 
     413    private: 
     414        Device & m_device; 
     415        Mixer*   m_mixer; 
     416        Router*  m_router; 
     417        RouterConfig m_current_cfg_routing_low; 
     418        RouterConfig m_current_cfg_routing_mid; 
     419        RouterConfig m_current_cfg_routing_high; 
     420        StreamConfig m_current_cfg_stream_low; 
     421        StreamConfig m_current_cfg_stream_mid; 
     422        StreamConfig m_current_cfg_stream_high; 
     423    public: 
     424        Mixer*  getMixer() {return m_mixer;}; 
     425        Router* getRouter() {return m_router;}; 
     426 
     427    private: 
    287428 
    288429        fb_quadlet_t m_capability_offset; 
     
    304445        fb_quadlet_t m_app_offset; 
    305446        fb_quadlet_t m_app_size; 
    306  
    307     public: // mixer subclass 
    308         class Mixer { 
    309         public: 
    310             Mixer(EAP &); 
    311             ~Mixer(); 
    312  
    313             bool init(); 
    314             void show(); 
    315             bool updateCoefficients(); 
    316  
    317         private: 
    318             EAP &m_parent; 
    319             fb_quadlet_t *m_coeff; 
    320  
    321             DECLARE_DEBUG_MODULE_REFERENCE; 
    322         }; 
    323  
    324         class Router { 
    325         public: 
    326             Router(EAP &); 
    327             ~Router(); 
    328  
    329             bool init(); 
    330             void show(); 
    331  
    332         private: 
    333             EAP &m_parent; 
    334  
    335             DECLARE_DEBUG_MODULE_REFERENCE; 
    336         }; 
    337  
    338447    }; 
     448 
     449public: 
     450    Device( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )); 
     451    ~Device(); 
     452 
     453    static bool probe( Util::Configuration& c, ConfigRom& configRom, bool generic = false ); 
     454    static FFADODevice * createDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )); 
     455    virtual bool discover(); 
     456 
     457    static int getConfigurationId( ); 
     458 
     459    virtual void showDevice(); 
     460 
     461    virtual bool setSamplingFrequency( int samplingFrequency ); 
     462    virtual int getSamplingFrequency( ); 
     463    virtual std::vector<int> getSupportedSamplingFrequencies(); 
     464 
     465    virtual ClockSourceVector getSupportedClockSources(); 
     466    virtual bool setActiveClockSource(ClockSource); 
     467    virtual ClockSource getActiveClockSource(); 
     468 
     469    virtual int getStreamCount(); 
     470    virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i); 
     471 
     472    virtual bool prepare(); 
     473 
     474    virtual bool lock(); 
     475    virtual bool unlock(); 
     476 
     477    virtual bool startStreamByIndex(int i); 
     478    virtual bool stopStreamByIndex(int i); 
     479 
     480    virtual bool enableStreaming(); 
     481    virtual bool disableStreaming(); 
     482 
     483    virtual std::string getNickname(); 
     484    virtual bool setNickname(std::string name); 
     485 
     486protected: 
     487    // streaming stuff 
     488    typedef std::vector< Streaming::StreamProcessor * > StreamProcessorVector; 
     489    typedef std::vector< Streaming::StreamProcessor * >::iterator StreamProcessorVectorIterator; 
     490    StreamProcessorVector m_receiveProcessors; 
     491    StreamProcessorVector m_transmitProcessors; 
     492 
     493private: // streaming & port helpers 
     494    enum EPortTypes { 
     495        ePT_Analog, 
     496        ePT_MIDI, 
     497    }; 
     498 
     499    typedef struct { 
     500        std::string name; 
     501        enum EPortTypes portType; 
     502        unsigned int streamPosition; 
     503        unsigned int streamLocation; 
     504    } diceChannelInfo; 
     505 
     506    bool addChannelToProcessor( diceChannelInfo *, 
     507                              Streaming::StreamProcessor *, 
     508                              Streaming::Port::E_Direction direction); 
     509 
     510    int allocateIsoChannel(unsigned int packet_size); 
     511    bool deallocateIsoChannel(int channel); 
     512 
     513private: // active config 
     514    enum eDiceConfig { 
     515        eDC_Unknown, 
     516        eDC_Low, 
     517        eDC_Mid, 
     518        eDC_High, 
     519    }; 
     520 
     521    enum eDiceConfig getCurrentConfig(); 
     522 
     523private: // helper functions 
     524    bool enableIsoStreaming(); 
     525    bool disableIsoStreaming(); 
     526    bool isIsoStreamingEnabled(); 
     527 
     528    bool maskedCheckZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask); 
     529    bool maskedCheckNotZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask); 
     530 
     531    diceNameVector splitNameString(std::string in); 
     532    diceNameVector getTxNameString(unsigned int i); 
     533    diceNameVector getRxNameString(unsigned int i); 
     534    diceNameVector getClockSourceNameString(); 
     535    std::string getDeviceNickName(); 
     536    bool setDeviceNickName(std::string name); 
     537 
     538    enum eClockSourceType  clockIdToType(unsigned int id); 
     539    bool isClockSourceIdLocked(unsigned int id, quadlet_t ext_status_reg); 
     540    bool isClockSourceIdSlipping(unsigned int id, quadlet_t ext_status_reg); 
     541 
     542// EAP stuff 
     543private: 
     544    EAP*         m_eap; 
     545public: 
     546    EAP* getEAP() {return m_eap;}; 
     547 
     548private: // register I/O routines 
     549    bool initIoFunctions(); 
     550    // quadlet read/write routines 
     551    bool readReg(fb_nodeaddr_t, fb_quadlet_t *); 
     552    bool writeReg(fb_nodeaddr_t, fb_quadlet_t); 
     553    bool readRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t); 
     554    bool writeRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t); 
     555 
     556    bool readGlobalReg(fb_nodeaddr_t, fb_quadlet_t *); 
     557    bool writeGlobalReg(fb_nodeaddr_t, fb_quadlet_t); 
     558    bool readGlobalRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t); 
     559    bool writeGlobalRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t); 
     560    fb_nodeaddr_t globalOffsetGen(fb_nodeaddr_t, size_t); 
     561 
     562    bool readTxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t *); 
     563    bool writeTxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t); 
     564    bool readTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length); 
     565    bool writeTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length); 
     566    fb_nodeaddr_t txOffsetGen(unsigned int, fb_nodeaddr_t, size_t); 
     567 
     568    bool readRxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t *); 
     569    bool writeRxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t); 
     570    bool readRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length); 
     571    bool writeRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length); 
     572    fb_nodeaddr_t rxOffsetGen(unsigned int, fb_nodeaddr_t, size_t); 
     573 
     574    fb_quadlet_t m_global_reg_offset; 
     575    fb_quadlet_t m_global_reg_size; 
     576    fb_quadlet_t m_tx_reg_offset; 
     577    fb_quadlet_t m_tx_reg_size; 
     578    fb_quadlet_t m_rx_reg_offset; 
     579    fb_quadlet_t m_rx_reg_size; 
     580    fb_quadlet_t m_unused1_reg_offset; 
     581    fb_quadlet_t m_unused1_reg_size; 
     582    fb_quadlet_t m_unused2_reg_offset; 
     583    fb_quadlet_t m_unused2_reg_size; 
     584 
     585    fb_quadlet_t m_nb_tx; 
     586    fb_quadlet_t m_tx_size; 
     587    fb_quadlet_t m_nb_rx; 
     588    fb_quadlet_t m_rx_size; 
     589 
     590// private: 
     591public: 
     592    // notification 
     593    Notifier *m_notifier; 
     594 
     595    /** 
     596     * this class reacts on the DICE device writing to the 
     597     * hosts notify address 
     598     */ 
     599    #define DICE_NOTIFIER_BASE_ADDRESS 0x0000FFFFE0000000ULL 
     600    #define DICE_NOTIFIER_BLOCK_LENGTH 4 
     601    class Notifier : public Ieee1394Service::ARMHandler 
     602    { 
     603    public: 
     604        Notifier(Device &, nodeaddr_t start); 
     605        virtual ~Notifier(); 
     606 
     607    private: 
     608        Device &m_device; 
     609    }; 
     610 
     611 
    339612 
    340613}; 
  • trunk/libffado/src/dice/dice_eap.cpp

    r1569 r1630  
    3333namespace Dice { 
    3434 
     35// ----------- helper functions ------------- 
     36 
     37static const char * 
     38srcBlockToString(const char id) 
     39{ 
     40    switch(id) { 
     41        case 0: return "AES "; 
     42        case 1: return "ADAT"; 
     43        case 2: return "MXR "; 
     44        case 4: return "INS0"; 
     45        case 5: return "INS1"; 
     46        case 10: return "ARM "; 
     47        case 11: return "AVS0"; 
     48        case 12: return "AVS1"; 
     49        case 15: return "MUTE"; 
     50        default : return "RSVD"; 
     51    } 
     52} 
     53 
     54static  const char * 
     55dstBlockToString(const char id) 
     56{ 
     57    switch(id) { 
     58        case 0: return "AES "; 
     59        case 1: return "ADAT"; 
     60        case 2: return "MXR0"; 
     61        case 3: return "MXR1"; 
     62        case 4: return "INS0"; 
     63        case 5: return "INS1"; 
     64        case 10: return "ARM "; 
     65        case 11: return "AVS0"; 
     66        case 12: return "AVS1"; 
     67        case 15: return "MUTE"; 
     68        default : return "RSVD"; 
     69    } 
     70} 
     71 
     72 
    3573Device::EAP::EAP(Device &d) 
    36 : m_device(d) 
    37 , m_debugModule(d.m_debugModule) 
     74: Control::Container(&d, "EAP") 
     75, m_debugModule(d.m_debugModule) // NOTE: has to be initialized before creating the config classes 
     76                                 //       otherwise the reference content used by those is bogus 
     77, m_device(d) 
     78, m_mixer( NULL ) 
     79, m_router( NULL ) 
     80, m_current_cfg_routing_low( RouterConfig(*this, eRT_CurrentCfg, DICE_EAP_CURRCFG_LOW_ROUTER) ) 
     81, m_current_cfg_routing_mid( RouterConfig(*this, eRT_CurrentCfg, DICE_EAP_CURRCFG_MID_ROUTER) ) 
     82, m_current_cfg_routing_high( RouterConfig(*this, eRT_CurrentCfg, DICE_EAP_CURRCFG_HIGH_ROUTER) ) 
     83, m_current_cfg_stream_low( StreamConfig(*this, eRT_CurrentCfg, DICE_EAP_CURRCFG_LOW_STREAM) ) 
     84, m_current_cfg_stream_mid( StreamConfig(*this, eRT_CurrentCfg, DICE_EAP_CURRCFG_MID_STREAM) ) 
     85, m_current_cfg_stream_high( StreamConfig(*this, eRT_CurrentCfg, DICE_EAP_CURRCFG_HIGH_STREAM) ) 
    3886{ 
    3987} 
     
    4189Device::EAP::~EAP() 
    4290{ 
     91    // remove all control elements registered to this device (w/o free) 
     92    clearElements(false); 
     93 
     94    // delete the helper classes 
     95    if(m_mixer) delete m_mixer; 
     96    if(m_router) delete m_router; 
     97} 
     98 
     99// offsets and sizes are returned in quadlets, but we use byte values, hence the *= 4 
     100#define DICE_EAP_READREG_AND_CHECK(base, addr, var) { \ 
     101    if(!readReg(base, addr, &var)) { \ 
     102        debugError("Could not initialize " #var "\n"); \ 
     103        return false; \ 
     104    } \ 
     105    var *= 4; \ 
    43106} 
    44107 
     
    51114 
    52115    // offsets and sizes are returned in quadlets, but we use byte values 
    53     if(!readReg(eRT_Base, DICE_EAP_CAPABILITY_SPACE_OFF, &m_capability_offset)) { 
    54         debugError("Could not initialize m_capability_offset\n"); 
    55         return false; 
    56     } 
    57     m_capability_offset *= 4; 
    58  
    59     if(!readReg(eRT_Base, DICE_EAP_CAPABILITY_SPACE_SZ, &m_capability_size)) { 
    60         debugError("Could not initialize m_capability_size\n"); 
    61         return false; 
    62     } 
    63     m_capability_size *= 4; 
    64      
    65     if(!readReg(eRT_Base, DICE_EAP_CMD_SPACE_OFF, &m_cmd_offset)) { 
    66         debugError("Could not initialize m_cmd_offset\n"); 
    67         return false; 
    68     } 
    69     m_cmd_offset *= 4; 
    70  
    71     if(!readReg(eRT_Base, DICE_EAP_CMD_SPACE_SZ, &m_cmd_size)) { 
    72         debugError("Could not initialize m_cmd_size\n"); 
    73         return false; 
    74     } 
    75     m_cmd_size *= 4; 
    76      
    77     if(!readReg(eRT_Base, DICE_EAP_MIXER_SPACE_OFF, &m_mixer_offset)) { 
    78         debugError("Could not initialize m_mixer_offset\n"); 
    79         return false; 
    80     } 
    81     m_mixer_offset *= 4; 
    82  
    83     if(!readReg(eRT_Base, DICE_EAP_MIXER_SPACE_SZ, &m_mixer_size)) { 
    84         debugError("Could not initialize m_mixer_size\n"); 
    85         return false; 
    86     } 
    87     m_mixer_size *= 4; 
    88      
    89     if(!readReg(eRT_Base, DICE_EAP_PEAK_SPACE_OFF, &m_peak_offset)) { 
    90         debugError("Could not initialize m_peak_offset\n"); 
    91         return false; 
    92     } 
    93     m_peak_offset *= 4; 
    94  
    95     if(!readReg(eRT_Base, DICE_EAP_PEAK_SPACE_SZ, &m_peak_size)) { 
    96         debugError("Could not initialize m_peak_size\n"); 
    97         return false; 
    98     } 
    99     m_peak_size *= 4; 
    100      
    101     if(!readReg(eRT_Base, DICE_EAP_NEW_ROUTING_SPACE_OFF, &m_new_routing_offset)) { 
    102         debugError("Could not initialize m_new_routing_offset\n"); 
    103         return false; 
    104     } 
    105     m_new_routing_offset *= 4; 
    106  
    107     if(!readReg(eRT_Base, DICE_EAP_NEW_ROUTING_SPACE_SZ, &m_new_routing_size)) { 
    108         debugError("Could not initialize m_new_routing_size\n"); 
    109         return false; 
    110     } 
    111     m_new_routing_size *= 4; 
    112      
    113     if(!readReg(eRT_Base, DICE_EAP_NEW_STREAM_CFG_SPACE_OFF, &m_new_stream_cfg_offset)) { 
    114         debugError("Could not initialize m_new_stream_cfg_offset\n"); 
    115         return false; 
    116     } 
    117     m_new_stream_cfg_offset *= 4; 
    118  
    119     if(!readReg(eRT_Base, DICE_EAP_NEW_STREAM_CFG_SPACE_SZ, &m_new_stream_cfg_size)) { 
    120         debugError("Could not initialize m_new_stream_cfg_size\n"); 
    121         return false; 
    122     } 
    123     m_new_stream_cfg_size *= 4; 
    124      
    125     if(!readReg(eRT_Base, DICE_EAP_CURR_CFG_SPACE_OFF, &m_curr_cfg_offset)) { 
    126         debugError("Could not initialize m_curr_cfg_offset\n"); 
    127         return false; 
    128     } 
    129     m_curr_cfg_offset *= 4; 
    130  
    131     if(!readReg(eRT_Base, DICE_EAP_CURR_CFG_SPACE_SZ, &m_curr_cfg_size)) { 
    132         debugError("Could not initialize m_curr_cfg_size\n"); 
    133         return false; 
    134     } 
    135     m_curr_cfg_size *= 4; 
    136      
    137     if(!readReg(eRT_Base, DICE_EAP_STAND_ALONE_CFG_SPACE_OFF, &m_standalone_offset)) { 
    138         debugError("Could not initialize m_standalone_offset\n"); 
    139         return false; 
    140     } 
    141     m_standalone_offset *= 4; 
    142  
    143     if(!readReg(eRT_Base, DICE_EAP_STAND_ALONE_CFG_SPACE_SZ, &m_standalone_size)) { 
    144         debugError("Could not initialize m_standalone_size\n"); 
    145         return false; 
    146     } 
    147     m_standalone_size *= 4; 
    148      
    149     if(!readReg(eRT_Base, DICE_EAP_APP_SPACE_OFF, &m_app_offset)) { 
    150         debugError("Could not initialize m_app_offset\n"); 
    151         return false; 
    152     } 
    153     m_app_offset *= 4; 
    154  
    155     if(!readReg(eRT_Base, DICE_EAP_APP_SPACE_SZ, &m_app_size)) { 
    156         debugError("Could not initialize m_app_size\n"); 
    157         return false; 
    158     } 
    159     m_app_size *= 4; 
     116    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_CAPABILITY_SPACE_OFF, m_capability_offset); 
     117    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_CAPABILITY_SPACE_SZ, m_capability_size); 
     118    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_CMD_SPACE_OFF, m_cmd_offset); 
     119    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_CMD_SPACE_SZ, m_cmd_size); 
     120    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_MIXER_SPACE_OFF, m_mixer_offset); 
     121    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_MIXER_SPACE_SZ, m_mixer_size); 
     122    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_PEAK_SPACE_OFF, m_peak_offset); 
     123    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_PEAK_SPACE_SZ, m_peak_size); 
     124    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_NEW_ROUTING_SPACE_OFF, m_new_routing_offset); 
     125    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_NEW_ROUTING_SPACE_SZ, m_new_routing_size); 
     126    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_NEW_STREAM_CFG_SPACE_OFF, m_new_stream_cfg_offset); 
     127    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_NEW_STREAM_CFG_SPACE_SZ, m_new_stream_cfg_size); 
     128    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_CURR_CFG_SPACE_OFF, m_curr_cfg_offset); 
     129    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_CURR_CFG_SPACE_SZ, m_curr_cfg_size); 
     130    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_STAND_ALONE_CFG_SPACE_OFF, m_standalone_offset); 
     131    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_STAND_ALONE_CFG_SPACE_SZ, m_standalone_size); 
     132    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_APP_SPACE_OFF, m_app_offset); 
     133    DICE_EAP_READREG_AND_CHECK(eRT_Base, DICE_EAP_APP_SPACE_SZ, m_app_size); 
    160134 
    161135    // initialize the capability info 
     
    174148        return false; 
    175149    } 
    176     m_mixer_exposed = (tmp >> DICE_EAP_CAP_ROUTER_EXPOSED) & 0x01; 
    177     m_mixer_readonly = (tmp >> DICE_EAP_CAP_ROUTER_EXPOSED) & 0x01; 
    178     m_mixer_flashstored = (tmp >> DICE_EAP_CAP_ROUTER_EXPOSED) & 0x01; 
    179     m_mixer_input_id = (tmp >> DICE_EAP_CAP_MIXER_IN_DEV) & 0x000F; 
    180     m_mixer_output_id = (tmp >> DICE_EAP_CAP_MIXER_OUT_DEV) & 0x000F; 
    181     m_mixer_nb_inputs = (tmp >> DICE_EAP_CAP_MIXER_INPUTS) & 0x00FF; 
    182     m_mixer_nb_outputs = (tmp >> DICE_EAP_CAP_MIXER_OUTPUTS) & 0x00FF; 
     150    m_mixer_exposed = (tmp >> DICE_EAP_CAP_MIXER_EXPOSED) & 0x01; 
     151    m_mixer_readonly = (tmp >> DICE_EAP_CAP_MIXER_READONLY) & 0x01; 
     152    m_mixer_flashstored = (tmp >> DICE_EAP_CAP_MIXER_FLASHSTORED) & 0x01; 
     153    m_mixer_tx_id = (tmp >> DICE_EAP_CAP_MIXER_IN_DEV) & 0x000F; 
     154    m_mixer_rx_id = (tmp >> DICE_EAP_CAP_MIXER_OUT_DEV) & 0x000F; 
     155    m_mixer_nb_tx = (tmp >> DICE_EAP_CAP_MIXER_INPUTS) & 0x00FF; 
     156    m_mixer_nb_rx = (tmp >> DICE_EAP_CAP_MIXER_OUTPUTS) & 0x00FF; 
    183157 
    184158    if(!readReg(eRT_Capability, DICE_EAP_CAPABILITY_GENERAL, &tmp)) { 
     
    194168    m_general_chip = (tmp >> DICE_EAP_CAP_GENERAL_CHIP) & 0xFFFF; 
    195169 
     170    // update our view on the current configuration 
     171    if(!updateConfigurationCache()) { 
     172        debugError("Could not initialize configuration cache\n"); 
     173        return false; 
     174    } 
     175 
     176    // initialize the helper classes 
     177    if (m_mixer_exposed) { 
     178        // initialize the mixer 
     179        m_mixer = new EAP::Mixer(*this); 
     180        if(m_mixer == NULL) { 
     181            debugError("Could not allocate memory for mixer\n"); 
     182            return false; 
     183        } 
     184        if(!m_mixer->init()) { 
     185            debugError("Could not initialize mixer\n"); 
     186            delete m_mixer; 
     187            m_mixer = NULL; 
     188            return false; 
     189        } 
     190        // add the mixer to the EAP control container 
     191        if(!addElement(m_mixer)) { 
     192            debugWarning("Failed to add mixer to control tree\n"); 
     193        } 
     194         
     195        // initialize the peak meter 
     196        m_router = new EAP::Router(*this); 
     197        if(m_router == NULL) { 
     198            debugError("Could not allocate memory for router\n"); 
     199            return false; 
     200        } 
     201 
     202        // add the router to the EAP control container 
     203        if(!addElement(m_router)) { 
     204            debugWarning("Failed to add router to control tree\n"); 
     205        } 
     206    } 
     207 
    196208    return true; 
    197209} 
    198210 
     211bool 
     212Device::EAP::updateConfigurationCache() 
     213{ 
     214    if(!m_current_cfg_routing_low.read()) { 
     215        debugError("Could not initialize current routing configuration (low rates)\n"); 
     216        return false; 
     217    } 
     218    if(!m_current_cfg_routing_mid.read()) { 
     219        debugError("Could not initialize current routing configuration (mid rates)\n"); 
     220        return false; 
     221    } 
     222    if(!m_current_cfg_routing_high.read()) { 
     223        debugError("Could not initialize current routing configuration (high rates)\n"); 
     224        return false; 
     225    } 
     226    if(!m_current_cfg_stream_low.read()) { 
     227        debugError("Could not initialize current stream configuration (low rates)\n"); 
     228        return false; 
     229    } 
     230    if(!m_current_cfg_stream_mid.read()) { 
     231        debugError("Could not initialize current stream configuration (mid rates)\n"); 
     232        return false; 
     233    } 
     234    if(!m_current_cfg_stream_high.read()) { 
     235        debugError("Could not initialize current stream configuration (high rates)\n"); 
     236        return false; 
     237    } 
     238    if(m_mixer) m_mixer->updateNameCache(); 
     239    return true; 
     240} 
     241 
     242/** 
     243 * Returns the router configuration for the current rate mode 
     244 * @return  
     245 */ 
     246Device::EAP::RouterConfig * 
     247Device::EAP::getActiveRouterConfig() 
     248{ 
     249    switch(m_device.getCurrentConfig()) { 
     250        case eDC_Low: return &m_current_cfg_routing_low; 
     251        case eDC_Mid: return &m_current_cfg_routing_mid; 
     252        case eDC_High: return &m_current_cfg_routing_high; 
     253        default: 
     254            debugError("Unsupported configuration mode\n"); 
     255            return NULL; 
     256    } 
     257} 
     258 
     259/** 
     260 * Returns the stream configuration for the current rate mode 
     261 * @return  
     262 */ 
     263Device::EAP::StreamConfig * 
     264Device::EAP::getActiveStreamConfig() 
     265{ 
     266    switch(m_device.getCurrentConfig()) { 
     267        case eDC_Low: return &m_current_cfg_stream_low; 
     268        case eDC_Mid: return &m_current_cfg_stream_mid; 
     269        case eDC_High: return &m_current_cfg_stream_high; 
     270        default: 
     271            debugError("Unsupported configuration mode\n"); 
     272            return NULL; 
     273    } 
     274} 
     275 
     276/** 
     277 * Uploads a new router configuration to the device 
     278 * @param  rcfg The new RouterConfig 
     279 * @param low store as config for the low rates 
     280 * @param mid store as config for the mid rates 
     281 * @param high store as config for the high rates 
     282 * @return true if successful, false otherwise 
     283 */ 
     284bool 
     285Device::EAP::updateRouterConfig(RouterConfig& rcfg, bool low, bool mid, bool high) { 
     286    // write the router config to the appropriate memory space on the device 
     287    if(!rcfg.write(eRT_NewRouting, 0)) { 
     288        debugError("Could not write new router configuration\n"); 
     289        return false; 
     290    } 
     291    // perform the store operation 
     292    if(!loadRouterConfig(low, mid, high)) { 
     293        debugError("Could not activate new router configuration\n"); 
     294        updateConfigurationCache(); // for consistency 
     295        return false; 
     296    } 
     297    return updateConfigurationCache(); 
     298} 
     299 
     300/** 
     301 * Uploads a new router configuration to replace the configuration 
     302 * for the current rate. 
     303 * @param  rcfg The new RouterConfig 
     304 * @return true if successful, false otherwise 
     305 */ 
     306bool 
     307Device::EAP::updateCurrentRouterConfig(RouterConfig& rcfg) { 
     308    switch(m_device.getCurrentConfig()) { 
     309        case eDC_Low: return updateRouterConfig(rcfg, true, false, false); 
     310        case eDC_Mid: return updateRouterConfig(rcfg, false, true, false); 
     311        case eDC_High: return updateRouterConfig(rcfg, false, false, true); 
     312        default: 
     313            debugError("Unsupported configuration mode\n"); 
     314            return false; 
     315    } 
     316} 
     317 
     318/** 
     319 * Uploads a new stream configuration to the device 
     320 * @param scfg The new StreamConfig 
     321 * @param low store as config for the low rates 
     322 * @param mid store as config for the mid rates 
     323 * @param high store as config for the high rates 
     324 * @return true if successful, false otherwise 
     325 */ 
     326bool 
     327Device::EAP::updateStreamConfig(StreamConfig& scfg, bool low, bool mid, bool high) { 
     328    // write the stream config to the appropriate memory space on the device 
     329    if(!scfg.write(eRT_NewStreamCfg, 0)) { 
     330        debugError("Could not write new stream configuration\n"); 
     331        return false; 
     332    } 
     333    // perform the store operation 
     334    if(!loadStreamConfig(low, mid, high)) { 
     335        debugError("Could not activate new stream configuration\n"); 
     336        updateConfigurationCache(); // for consistency 
     337        return false; 
     338    } 
     339    return updateConfigurationCache(); 
     340} 
     341 
     342/** 
     343 * Uploads a new router and stream configuration to the device 
     344 * @param  rcfg The new RouterConfig 
     345 * @param  scfg The new StreamConfig 
     346 * @param low store as config for the low rates 
     347 * @param mid store as config for the mid rates 
     348 * @param high store as config for the high rates 
     349 * @return true if successful, false otherwise 
     350 */ 
     351bool 
     352Device::EAP::updateStreamConfig(RouterConfig& rcfg, StreamConfig& scfg, bool low, bool mid, bool high) { 
     353    // write the router config to the appropriate memory space on the device 
     354    if(!rcfg.write(eRT_NewRouting, 0)) { 
     355        debugError("Could not write new router configuration\n"); 
     356        return false; 
     357    } 
     358    // write the stream config to the appropriate memory space on the device 
     359    if(!scfg.write(eRT_NewStreamCfg, 0)) { 
     360        debugError("Could not write new stream configuration\n"); 
     361        return false; 
     362    } 
     363    // perform the store operation 
     364    if(!loadRouterAndStreamConfig(low, mid, high)) { 
     365        debugError("Could not activate new router/stream configuration\n"); 
     366        updateConfigurationCache(); // for consistency 
     367        return false; 
     368    } 
     369    return updateConfigurationCache(); 
     370} 
     371 
     372 
     373bool 
     374Device::EAP::loadFlashConfig() { 
     375    bool retval = true; 
     376    debugWarning("Untested code\n"); 
     377    fb_quadlet_t cmd = DICE_EAP_CMD_OPCODE_LD_FLASH_CFG; 
     378    cmd |= DICE_EAP_CMD_OPCODE_FLAG_LD_EXECUTE; 
     379    if(!commandHelper(cmd)) { 
     380        debugWarning("Command failed\n"); 
     381        retval = false; 
     382    } 
     383    retval &= updateConfigurationCache(); 
     384    return retval; 
     385} 
     386 
     387bool 
     388Device::EAP::storeFlashConfig() { 
     389    debugWarning("Untested code\n"); 
     390    fb_quadlet_t cmd = DICE_EAP_CMD_OPCODE_ST_FLASH_CFG; 
     391    cmd |= DICE_EAP_CMD_OPCODE_FLAG_LD_EXECUTE; 
     392    return commandHelper(cmd); 
     393} 
     394 
     395// helpers 
    199396void 
    200 Device::EAP::show() { 
     397Device::EAP::show() 
     398
    201399    printMessage("== DICE EAP ==\n"); 
    202400    debugOutput(DEBUG_LEVEL_VERBOSE, "Parameter Space info:\n"); 
     
    221419                                     (m_mixer_readonly?"not ":""), 
    222420                                     (m_mixer_flashstored?"":"not ")); 
    223     debugOutput(DEBUG_LEVEL_VERBOSE, "         input id: %d, output id: %d\n", m_mixer_input_id, m_mixer_output_id); 
    224     debugOutput(DEBUG_LEVEL_VERBOSE, "         nb inputs: %d, nb outputs: %d\n", m_mixer_nb_inputs, m_mixer_nb_outputs); 
     421    debugOutput(DEBUG_LEVEL_VERBOSE, "         tx id: %s [%d], rx id: %s [%d]\n",  
     422                                     dstBlockToString(m_mixer_tx_id), m_mixer_tx_id, 
     423                                     srcBlockToString(m_mixer_rx_id), m_mixer_rx_id); 
     424    debugOutput(DEBUG_LEVEL_VERBOSE, "         nb tx channels: %d, nb rx channels: %d\n", m_mixer_nb_tx, m_mixer_nb_rx); 
    225425    debugOutput(DEBUG_LEVEL_VERBOSE, " General: dynamic stream config %ssupported\n", 
    226426                                     (m_general_support_dynstream?"":"not ")); 
     
    241441        debugOutput(DEBUG_LEVEL_VERBOSE, "          Chip: DICE Junior (TCD2220)\n"); 
    242442    } 
     443 
     444    debugOutput(DEBUG_LEVEL_VERBOSE, "--- Mixer configuration ---\n"); 
     445    if(m_mixer) { 
     446        m_mixer->show(); 
     447    } 
     448    debugOutput(DEBUG_LEVEL_VERBOSE, "--- Router/Peak space ---\n"); 
     449    if(m_router) { 
     450        m_router->show(); 
     451    } 
     452 
     453    RouterConfig *rcfg = getActiveRouterConfig(); 
     454    if(rcfg) { 
     455        rcfg->show(); 
     456    } 
     457    StreamConfig *scfg = getActiveStreamConfig(); 
     458    if(scfg) { 
     459        scfg->show(); 
     460    } 
     461 
     462// fixme 
     463//     size_t len = 0x1000; 
     464//     quadlet_t tmp[len]; 
     465//     if(!readRegBlock( eRT_CurrentCfg, DICE_EAP_CURRCFG_LOW_STREAM, tmp, len*4) ) { 
     466//         debugError("Failed to read block\n"); 
     467//     } else { 
     468//         hexDumpQuadlets(tmp, len); 
     469//     } 
     470 
    243471} 
    244472 
     
    282510Device::EAP::commandHelper(fb_quadlet_t cmd) { 
    283511    // check whether another command is still running 
    284     if(operationBusy()) { 
     512    if(operationBusy() == eWR_Busy) { 
    285513        debugError("Other operation in progress\n"); 
    286514        return false; 
     
    323551bool 
    324552Device::EAP::loadRouterConfig(bool low, bool mid, bool high) { 
    325     debugWarning("Untested code\n"); 
    326553    fb_quadlet_t cmd = DICE_EAP_CMD_OPCODE_LD_ROUTER; 
    327554    if(low) cmd |= DICE_EAP_CMD_OPCODE_FLAG_LD_LOW; 
     
    350577    if(mid) cmd |= DICE_EAP_CMD_OPCODE_FLAG_LD_MID; 
    351578    if(high) cmd |= DICE_EAP_CMD_OPCODE_FLAG_LD_HIGH; 
    352     cmd |= DICE_EAP_CMD_OPCODE_FLAG_LD_EXECUTE; 
    353     return commandHelper(cmd); 
    354 } 
    355  
    356 bool 
    357 Device::EAP::loadFlashConfig() { 
    358     debugWarning("Untested code\n"); 
    359     fb_quadlet_t cmd = DICE_EAP_CMD_OPCODE_LD_FLASH_CFG; 
    360     cmd |= DICE_EAP_CMD_OPCODE_FLAG_LD_EXECUTE; 
    361     return commandHelper(cmd); 
    362 } 
    363  
    364 bool 
    365 Device::EAP::storeFlashConfig() { 
    366     debugWarning("Untested code\n"); 
    367     fb_quadlet_t cmd = DICE_EAP_CMD_OPCODE_ST_FLASH_CFG; 
    368579    cmd |= DICE_EAP_CMD_OPCODE_FLAG_LD_EXECUTE; 
    369580    return commandHelper(cmd); 
     
    440651            maxlen = m_app_size; 
    441652            break; 
     653        default: 
     654            debugError("Unsupported base address\n"); 
     655            return 0; 
    442656    }; 
    443657 
     
    477691// ----------- Mixer ------------- 
    478692Device::EAP::Mixer::Mixer(EAP &p) 
    479 : m_parent(p) 
     693: Control::MatrixMixer(&p.m_device, "MatrixMixer") 
     694, m_eap(p) 
    480695, m_coeff(NULL) 
    481696, m_debugModule(p.m_debugModule) 
     
    494709Device::EAP::Mixer::init() 
    495710{ 
    496     if(!m_parent.m_mixer_exposed) { 
     711    if(!m_eap.m_mixer_exposed) { 
    497712        debugError("Device does not expose mixer\n"); 
    498713        return false; 
     
    506721     
    507722    // allocate coefficient array 
    508     int nb_inputs = m_parent.m_mixer_nb_inputs
    509     int nb_outputs = m_parent.m_mixer_nb_outputs
     723    int nb_inputs = m_eap.m_mixer_nb_tx
     724    int nb_outputs = m_eap.m_mixer_nb_rx
    510725 
    511726    m_coeff = (fb_quadlet_t *)calloc(nb_outputs * nb_inputs, sizeof(fb_quadlet_t)); 
    512727 
    513728    // load initial values 
    514     if(!updateCoefficients()) { 
     729    if(!loadCoefficients()) { 
    515730        debugWarning("Could not initialize coefficients\n"); 
    516731        return false; 
    517732    } 
    518      
     733    updateNameCache(); 
    519734    return true; 
    520735} 
    521736 
    522737bool 
    523 Device::EAP::Mixer::updateCoefficients() 
     738Device::EAP::Mixer::loadCoefficients() 
    524739{ 
    525740    if(m_coeff == NULL) { 
    526         debugError("Coefficients not initialized\n"); 
    527         return false; 
    528     } 
    529     int nb_inputs = m_parent.m_mixer_nb_inputs
    530     int nb_outputs = m_parent.m_mixer_nb_outputs
    531     if(!m_parent.readRegBlock(eRT_Mixer, 4, m_coeff, nb_inputs * nb_outputs * 4)) { 
     741        debugError("Coefficient cache not initialized\n"); 
     742        return false; 
     743    } 
     744    int nb_inputs = m_eap.m_mixer_nb_tx
     745    int nb_outputs = m_eap.m_mixer_nb_rx
     746    if(!m_eap.readRegBlock(eRT_Mixer, 4, m_coeff, nb_inputs * nb_outputs * 4)) { 
    532747        debugError("Failed to read coefficients\n"); 
    533748        return false; 
    534749    } 
    535750    return true; 
     751} 
     752 
     753bool 
     754Device::EAP::Mixer::storeCoefficients() 
     755{ 
     756    if(m_coeff == NULL) { 
     757        debugError("Coefficient cache not initialized\n"); 
     758        return false; 
     759    } 
     760    if(m_eap.m_mixer_readonly) { 
     761        debugWarning("Mixer is read-only\n"); 
     762        return false; 
     763    } 
     764    int nb_inputs = m_eap.m_mixer_nb_tx; 
     765    int nb_outputs = m_eap.m_mixer_nb_rx; 
     766    if(!m_eap.writeRegBlock(eRT_Mixer, 4, m_coeff, nb_inputs * nb_outputs * 4)) { 
     767        debugError("Failed to read coefficients\n"); 
     768        return false; 
     769    } 
     770    return true; 
     771} 
     772 
     773void 
     774Device::EAP::Mixer::updateNameCache() 
     775{ 
     776    // figure out the number of i/o's 
     777    int nb_inputs = m_eap.m_mixer_nb_tx; 
     778    int nb_outputs = m_eap.m_mixer_nb_rx; 
     779 
     780    // clear the previous map 
     781    m_input_route_map.clear(); 
     782    m_output_route_map.clear(); 
     783 
     784    // find the active router configuration 
     785    RouterConfig * rcfg = m_eap.getActiveRouterConfig(); 
     786    if(rcfg == NULL) { 
     787        debugError("Could not get active routing info\n"); 
     788        return; 
     789    } 
     790 
     791    // find the inputs 
     792    for(int i=0; i < nb_inputs; i++) { 
     793        int ch = i; 
     794        // the destination id of the mixer input 
     795        int dest_int = m_eap.m_mixer_tx_id; 
     796 
     797        // from the DICE mixer spec: 
     798        // we can have 16 channels per "block" 
     799        // if there are more, consecutive block id's are assumed 
     800        while(ch > 15) { 
     801            ch -= 16; 
     802            dest_int += 1; 
     803        } 
     804        // the destination block and channel corresponding with this 
     805        // mixer input is now known 
     806        enum eRouteDestination dest = rcfg->intToRouteDestination(dest_int); 
     807 
     808        // get the source for this mixer channel 
     809        m_input_route_map[i] = rcfg->getRouteForDestination(dest, ch); 
     810 
     811        debugOutput(DEBUG_LEVEL_VERBOSE, "Mixer input channel %2d source: %s\n", i, 
     812                                          srcBlockToString(m_input_route_map[i].src), 
     813                                          m_input_route_map[i].srcChannel); 
     814    } 
     815 
     816    // find where the outputs are connected to 
     817    for(int i=0; i < nb_outputs; i++) { 
     818        int ch = i; 
     819        // the source id of the mixer input 
     820        int src_int = m_eap.m_mixer_rx_id; 
     821 
     822        // from the DICE mixer spec: 
     823        // we can have 16 channels per "block" 
     824        // if there are more, consecutive block id's are assumed 
     825        while(ch > 15) { 
     826            ch -= 16; 
     827            src_int += 1; 
     828        } 
     829 
     830        // the source block and channel corresponding with this 
     831        // mixer output is now known 
     832        enum eRouteSource src = rcfg->intToRouteSource(src_int); 
     833 
     834        // get the routing destinations for this mixer channel 
     835        m_output_route_map[i] = rcfg->getRoutesForSource(src, ch); 
     836 
     837        #ifdef DEBUG 
     838        std::string destinations; 
     839        for ( RouterConfig::RouteVectorIterator it = m_output_route_map[i].begin(); 
     840            it != m_output_route_map[i].end(); 
     841            ++it ) 
     842        { 
     843            RouterConfig::Route r = *it; 
     844            // check whether the destination is valid 
     845            if((r.dst != eRD_Invalid) && (r.dstChannel >= 0)) { 
     846                char tmp[128]; 
     847                snprintf(tmp, 128, "%s:%d,", dstBlockToString(r.dst), r.dstChannel); 
     848                destinations += tmp; 
     849            } 
     850        } 
     851        debugOutput(DEBUG_LEVEL_VERBOSE, "Mixer output channel %2d destinations: %s\n", i, destinations.c_str()); 
     852        #endif 
     853    } 
    536854} 
    537855 
     
    539857Device::EAP::Mixer::show() 
    540858{ 
    541     int nb_inputs = m_parent.m_mixer_nb_inputs; 
    542     int nb_outputs = m_parent.m_mixer_nb_outputs; 
     859    int nb_inputs = m_eap.m_mixer_nb_tx; 
     860    int nb_outputs = m_eap.m_mixer_nb_rx; 
     861 
     862    updateNameCache(); 
    543863 
    544864    const size_t bufflen = 4096; 
     
    547867 
    548868    cnt = 0; 
    549     cnt += snprintf(tmp+cnt, bufflen-cnt, "%3s ", ""); 
    550     for(int j=0; j<nb_inputs; j++) { 
    551         cnt += snprintf(tmp+cnt, bufflen-cnt, "%8d ", j); 
     869    for(int j=0; j < nb_inputs; j++) { 
     870        cnt += snprintf(tmp+cnt, bufflen-cnt, "   %02d   ", j); 
    552871    } 
    553872    printMessage("%s\n", tmp); 
    554873 
     874    cnt = 0; 
     875    for(int j=0; j < nb_inputs; j++) { 
     876        cnt += snprintf(tmp+cnt, bufflen-cnt, "%s:%02d ", 
     877                        srcBlockToString(m_input_route_map[j].src), 
     878                        m_input_route_map[j].srcChannel); 
     879    } 
     880    printMessage("%s\n", tmp); 
     881 
    555882    // display coefficients 
    556     for(int i=0; i<nb_outputs; i++) { 
     883    for(int i=0; i < nb_outputs; i++) { 
    557884        cnt = 0; 
    558         cnt += snprintf(tmp+cnt, bufflen-cnt, "%03d: ", i); 
    559         for(int j=0; j<nb_inputs; j++) { 
    560             cnt += snprintf(tmp+cnt, bufflen-cnt, "%08X ", *(m_coeff + nb_inputs * i + j)); 
    561         } 
     885        for(int j=0; j < nb_inputs; j++) { 
     886            cnt += snprintf(tmp+cnt, bufflen-cnt, "%07d ", *(m_coeff + nb_inputs * i + j)); 
     887        } 
     888 
     889        // construct the set of destinations 
     890        std::string destinations; 
     891        for ( RouterConfig::RouteVectorIterator it = m_output_route_map[i].begin(); 
     892            it != m_output_route_map[i].end(); 
     893            ++it ) 
     894        { 
     895            RouterConfig::Route r = *it; 
     896            // check whether the destination is valid 
     897            if((r.dst != eRD_Invalid) && (r.dstChannel >= 0)) { 
     898                char tmp[128]; 
     899                snprintf(tmp, 128, "%s:%d,", dstBlockToString(r.dst), r.dstChannel); 
     900                destinations += tmp; 
     901            } 
     902        } 
     903 
     904        cnt += snprintf(tmp+cnt, bufflen-cnt, "=[%02d]=> %s ", i, destinations.c_str()); 
    562905        printMessage("%s\n", tmp); 
    563906    } 
     
    565908} 
    566909 
     910// The control interface to the mixer 
     911std::string 
     912Device::EAP::Mixer::getRowName( const int row ) 
     913{ 
     914    return "FIXME"; 
     915} 
     916 
     917std::string 
     918Device::EAP::Mixer::getColName( const int col ) 
     919{ 
     920    return "FIXME"; 
     921} 
     922 
     923int 
     924Device::EAP::Mixer::canWrite( const int row, const int col) 
     925{ 
     926    if(m_eap.m_mixer_readonly) { 
     927        return false; 
     928    } 
     929    return (row >= 0 && row < m_eap.m_mixer_nb_tx && col >= 0 && col < m_eap.m_mixer_nb_rx); 
     930} 
     931 
     932double 
     933Device::EAP::Mixer::setValue( const int row, const int col, const double val) 
     934{ 
     935    if(m_eap.m_mixer_readonly) { 
     936        debugWarning("Mixer is read-only\n"); 
     937        return false; 
     938    } 
     939    int nb_inputs = m_eap.m_mixer_nb_tx; 
     940    int addr = ((nb_inputs * row) + col) * 4; 
     941    quadlet_t tmp = (quadlet_t) val; 
     942    if(!m_eap.writeRegBlock(eRT_Mixer, 4+addr, &tmp, 4)) { 
     943        debugError("Failed to write coefficient\n"); 
     944        return 0; 
     945    } 
     946    return (double)(tmp); 
     947} 
     948 
     949double 
     950Device::EAP::Mixer::getValue( const int row, const int col) 
     951{ 
     952    int nb_inputs = m_eap.m_mixer_nb_tx; 
     953    int addr = ((nb_inputs * row) + col) * 4; 
     954    quadlet_t tmp; 
     955    if(!m_eap.readRegBlock(eRT_Mixer, 4+addr, &tmp, 4)) { 
     956        debugError("Failed to read coefficient\n"); 
     957        return 0; 
     958    } 
     959    return (double)(tmp); 
     960} 
     961 
     962int 
     963Device::EAP::Mixer::getRowCount() 
     964{ 
     965    return m_eap.m_mixer_nb_tx; 
     966} 
     967 
     968int 
     969Device::EAP::Mixer::getColCount() 
     970{ 
     971    return m_eap.m_mixer_nb_rx; 
     972} 
     973 
     974// full map updates are unsupported 
     975bool 
     976Device::EAP::Mixer::getCoefficientMap(int &) { 
     977    return false; 
     978} 
     979 
     980bool 
     981Device::EAP::Mixer::storeCoefficientMap(int &) { 
     982    if(m_eap.m_mixer_readonly) { 
     983        debugWarning("Mixer is read-only\n"); 
     984        return false; 
     985    } 
     986    return false; 
     987} 
     988 
    567989// ----------- Router ------------- 
     990// FIXME: some more efficient datastructure for the  
     991//        sources and destinations might be good 
     992 
     993 
    568994Device::EAP::Router::Router(EAP &p) 
    569 : m_parent(p) 
     995: Control::CrossbarRouter(&p.m_device, "Router") 
     996, m_eap(p) 
     997, m_peak( *(new PeakSpace(p)) ) 
    570998, m_debugModule(p.m_debugModule) 
    571999{ 
    572  
     1000    setupSources(); 
     1001    setupDestinations(); 
    5731002} 
    5741003 
    5751004Device::EAP::Router::~Router() 
    5761005{ 
    577 
    578  
    579 bool 
    580 Device::EAP::Router::init() 
     1006    delete &m_peak; 
     1007
     1008 
     1009void 
     1010Device::EAP::Router::setupSourcesAddSource(const char *basename, enum eRouteSource srcid,  
     1011                                           unsigned int base, unsigned int cnt) 
     1012
     1013    unsigned int i=0; 
     1014    char name[16]; 
     1015    for (i=0; i<cnt; i++) { 
     1016        snprintf(name, 16, "%s:%02d", basename, base+i); 
     1017        struct Source s = {name, srcid, i}; 
     1018        m_sources.push_back(s); 
     1019    } 
     1020
     1021 
     1022void 
     1023Device::EAP::Router::setupDestinationsAddDestination(const char *basename, enum eRouteDestination dstid, 
     1024                                                     unsigned int base, unsigned int cnt) 
     1025
     1026    unsigned int i=0; 
     1027    char name[16]; 
     1028    for (i=0; i<cnt; i++) { 
     1029        snprintf(name, 16, "%s:%02d", basename, base+i); 
     1030        struct Destination d = {name, dstid, i}; 
     1031        m_destinations.push_back(d); 
     1032    } 
     1033
     1034 
     1035 
     1036void 
     1037Device::EAP::Router::setupSources() { 
     1038    // add the routing sources and destinations for a DICE chip 
     1039    switch(m_eap.m_general_chip) { 
     1040        case DICE_EAP_CAP_GENERAL_CHIP_DICEII: 
     1041            // router/EAP currently not supported 
     1042            break; 
     1043        case DICE_EAP_CAP_GENERAL_CHIP_DICEJR: 
     1044            // these are unique to the junior 
     1045 
     1046            // second audio port 
     1047            setupSourcesAddSource("InS1", eRS_InS1, 0, 8); 
     1048 
     1049        case DICE_EAP_CAP_GENERAL_CHIP_DICEMINI: 
     1050            // these are common to the mini and junior 
     1051 
     1052            // the AES receiver 
     1053            setupSourcesAddSource("AES", eRS_AES, 0, 8); 
     1054 
     1055            // the ADAT receiver 
     1056            setupSourcesAddSource("ADAT", eRS_ADAT, 0, 8); 
     1057 
     1058            // the Mixer outputs 
     1059            setupSourcesAddSource("MixerOut", eRS_Mixer, 0, 16); 
     1060 
     1061            // the first audio port 
     1062            setupSourcesAddSource("InS0", eRS_InS0, 0, 8); 
     1063 
     1064            // the ARM audio port 
     1065            setupSourcesAddSource("ARM", eRS_ARM, 0, 8); 
     1066 
     1067            // the 1394 stream receivers 
     1068            setupSourcesAddSource("1394_0", eRS_ARX0, 0, 16); 
     1069            setupSourcesAddSource("1394_1", eRS_ARX1, 0, 16); 
     1070 
     1071            // mute 
     1072            setupSourcesAddSource("Mute", eRS_Muted, 0, 1); 
     1073 
     1074            break; 
     1075        default: 
     1076            // this is an unsupported chip 
     1077            break; 
     1078    } 
     1079
     1080 
     1081void 
     1082Device::EAP::Router::setupDestinations() { 
     1083    // add the routing sources and destinations for a DICE chip 
     1084    switch(m_eap.m_general_chip) { 
     1085        case DICE_EAP_CAP_GENERAL_CHIP_DICEII: 
     1086            // router/EAP currently not supported 
     1087            break; 
     1088        case DICE_EAP_CAP_GENERAL_CHIP_DICEJR: 
     1089            // these are unique to the junior 
     1090 
     1091            // second audio port 
     1092            setupDestinationsAddDestination("InS1", eRD_InS1, 0, 8); 
     1093 
     1094        case DICE_EAP_CAP_GENERAL_CHIP_DICEMINI: 
     1095            // these are common to the mini and junior 
     1096 
     1097            // the AES receiver 
     1098            setupDestinationsAddDestination("AES", eRD_AES, 0, 8); 
     1099 
     1100            // the ADAT receiver 
     1101            setupDestinationsAddDestination("ADAT", eRD_ADAT, 0, 8); 
     1102 
     1103            // the Mixer outputs 
     1104            setupDestinationsAddDestination("MixerIn", eRD_Mixer0, 0, 16); 
     1105            setupDestinationsAddDestination("MixerIn", eRD_Mixer1, 16, 2); 
     1106 
     1107            // the first audio port 
     1108            setupDestinationsAddDestination("InS0", eRD_InS0, 0, 8); 
     1109 
     1110            // the ARM audio port 
     1111            setupDestinationsAddDestination("ARM", eRD_ARM, 0, 8); 
     1112 
     1113            // the 1394 stream receivers 
     1114            setupDestinationsAddDestination("1394_0", eRD_ATX0, 0, 16); 
     1115            setupDestinationsAddDestination("1394_1", eRD_ATX1, 0, 16); 
     1116 
     1117            // mute 
     1118            setupDestinationsAddDestination("Mute", eRD_Muted, 0, 1); 
     1119 
     1120            break; 
     1121        default: 
     1122            // this is an unsupported chip 
     1123            break; 
     1124    } 
     1125
     1126 
     1127std::string 
     1128Device::EAP::Router::getSourceName(const int srcid) 
     1129
     1130    if((unsigned)srcid < m_sources.size()) { 
     1131        return m_sources.at(srcid).name; 
     1132    } else { 
     1133        debugWarning("source id out of range (%d)\n", srcid); 
     1134        return ""; 
     1135    } 
     1136
     1137 
     1138std::string 
     1139Device::EAP::Router::getDestinationName(const int dstid) 
     1140
     1141    if((unsigned)dstid < m_destinations.size()) { 
     1142        return m_destinations.at(dstid).name; 
     1143    } else { 
     1144        debugWarning("destination id out of range (%d)\n", dstid); 
     1145        return ""; 
     1146    } 
     1147
     1148 
     1149int 
     1150Device::EAP::Router::getSourceIndex(std::string name) 
     1151
     1152    int i = 0; 
     1153    for ( SourceVectorIterator it = m_sources.begin(); 
     1154        it != m_sources.end(); 
     1155        ++it ) 
     1156    { 
     1157        if(it->name == name) return i; 
     1158        i++; 
     1159    } 
     1160    return -1; 
     1161
     1162 
     1163int 
     1164Device::EAP::Router::getDestinationIndex(std::string name) 
     1165
     1166    int i = 0; 
     1167    for ( DestinationVectorIterator it = m_destinations.begin(); 
     1168        it != m_destinations.end(); 
     1169        ++it ) 
     1170    { 
     1171        if(it->name == name) return i; 
     1172        i++; 
     1173    } 
     1174    return -1; 
     1175
     1176 
     1177int 
     1178Device::EAP::Router::getSourceIndex(enum eRouteSource srcid, int channel) 
     1179
     1180    int i = 0; 
     1181    for ( SourceVectorIterator it = m_sources.begin(); 
     1182        it != m_sources.end(); 
     1183        ++it ) 
     1184    { 
     1185        if((it->src == srcid) && (it->srcChannel == channel)) return i; 
     1186        i++; 
     1187    } 
     1188    return -1; 
     1189
     1190 
     1191int 
     1192Device::EAP::Router::getDestinationIndex(enum eRouteDestination dstid, int channel) 
     1193
     1194    int i = 0; 
     1195    for ( DestinationVectorIterator it = m_destinations.begin(); 
     1196        it != m_destinations.end(); 
     1197        ++it ) 
     1198    { 
     1199        if((it->dst == dstid) && (it->dstChannel == channel)) return i; 
     1200        i++; 
     1201    } 
     1202    return -1; 
     1203
     1204 
     1205Control::CrossbarRouter::NameVector 
     1206Device::EAP::Router::getSourceNames() 
     1207
     1208    Control::CrossbarRouter::NameVector n; 
     1209    for ( SourceVectorIterator it = m_sources.begin(); 
     1210        it != m_sources.end(); 
     1211        ++it ) 
     1212    { 
     1213        n.push_back(it->name); 
     1214    } 
     1215    return n; 
     1216
     1217 
     1218Control::CrossbarRouter::NameVector 
     1219Device::EAP::Router::getDestinationNames() 
     1220
     1221    Control::CrossbarRouter::NameVector n; 
     1222    for ( DestinationVectorIterator it = m_destinations.begin(); 
     1223        it != m_destinations.end(); 
     1224        ++it ) 
     1225    { 
     1226        n.push_back(it->name); 
     1227    } 
     1228    return n; 
     1229
     1230 
     1231Control::CrossbarRouter::IntVector 
     1232Device::EAP::Router::getDestinationsForSource(const int srcid) 
     1233
     1234    IntVector retval; 
     1235    if((unsigned)srcid < m_sources.size()) { 
     1236        Source s = m_sources.at(srcid); 
     1237 
     1238        // get the routing configuration 
     1239        RouterConfig *rcfg = m_eap.getActiveRouterConfig(); 
     1240        if(rcfg == NULL) { 
     1241            debugError("Could not request active router configuration\n"); 
     1242            return retval; 
     1243        } 
     1244        // get the source routes 
     1245        RouterConfig::RouteVector v = rcfg->getRoutesForSource(s.src, s.srcChannel); 
     1246 
     1247        for ( RouterConfig::RouteVectorIterator it = v.begin(); 
     1248            it != v.end(); 
     1249            ++it ) 
     1250        { 
     1251            // FIXME: some more efficient datastructure might be good to 
     1252            // avoid this loop 
     1253            RouterConfig::Route &r = *it; 
     1254            int i = 0; 
     1255            for ( DestinationVectorIterator it = m_destinations.begin(); 
     1256                it != m_destinations.end(); 
     1257                ++it ) 
     1258            { 
     1259                if((it->dst == r.dst) && (it->dstChannel == r.dstChannel)) { 
     1260                    retval.push_back(i); 
     1261                    break; // can only match once 
     1262                } 
     1263                i++; 
     1264            } 
     1265        } 
     1266        return retval; 
     1267    } else { 
     1268        debugWarning("source id out of range (%d)\n", srcid); 
     1269        return retval; 
     1270    } 
     1271
     1272 
     1273int 
     1274Device::EAP::Router::getSourceForDestination(const int dstid) 
     1275
     1276    if((unsigned)dstid < m_destinations.size()) { 
     1277        Destination d = m_destinations.at(dstid); 
     1278 
     1279        // get the routing configuration 
     1280        RouterConfig *rcfg = m_eap.getActiveRouterConfig(); 
     1281        if(rcfg == NULL) { 
     1282            debugError("Could not request active router configuration\n"); 
     1283            return false; 
     1284        } 
     1285 
     1286        RouterConfig::Route r = rcfg->getRouteForDestination(d.dst, d.dstChannel); 
     1287        if(r.src == eRS_Invalid) { 
     1288            return -1; 
     1289        } else { 
     1290            // FIXME: some more efficient datastructure might be good to 
     1291            // avoid this loop 
     1292            int i = 0; 
     1293            for ( SourceVectorIterator it = m_sources.begin(); 
     1294                it != m_sources.end(); 
     1295                ++it ) 
     1296            { 
     1297                if((it->src == r.src) && (it->srcChannel == r.srcChannel)) return i; 
     1298                i++; 
     1299            } 
     1300            return -1; 
     1301        } 
     1302    } else { 
     1303        debugWarning("destination id out of range (%d)\n", dstid); 
     1304        return -1; 
     1305    } 
     1306
     1307 
     1308int 
     1309Device::EAP::Router::getNbSources() 
     1310
     1311    return m_sources.size(); 
     1312
     1313 
     1314int 
     1315Device::EAP::Router::getNbDestinations() 
     1316
     1317    return m_destinations.size(); 
     1318
     1319 
     1320bool 
     1321Device::EAP::Router::canConnect(const int source, const int dest) 
     1322
     1323    if((unsigned)source >= m_sources.size()) { 
     1324        debugWarning("source id out of range (%d)\n", source); 
     1325        return false; 
     1326    } 
     1327    Source s = m_sources.at(source); 
     1328 
     1329    if((unsigned)dest >= m_destinations.size()) { 
     1330        debugWarning("destination id out of range (%d)\n", dest); 
     1331        return false; 
     1332    } 
     1333    Destination d = m_destinations.at(dest); 
     1334 
     1335    // we can connect anything 
     1336    // FIXME: can we? 
     1337    return true; 
     1338
     1339 
     1340bool 
     1341Device::EAP::Router::setConnectionState(const int source, const int dest, const bool enable) 
     1342
     1343    if((unsigned)source >= m_sources.size()) { 
     1344        debugWarning("source id out of range (%d)\n", source); 
     1345        return false; 
     1346    } 
     1347    Source s = m_sources.at(source); 
     1348 
     1349    if((unsigned)dest >= m_destinations.size()) { 
     1350        debugWarning("destination id out of range (%d)\n", dest); 
     1351        return false; 
     1352    } 
     1353    Destination d = m_destinations.at(dest); 
     1354 
     1355    // get the routing configuration 
     1356    RouterConfig *rcfg = m_eap.getActiveRouterConfig(); 
     1357    if(rcfg == NULL) { 
     1358        debugError("Could not request active router configuration\n"); 
     1359        return false; 
     1360    } 
     1361 
     1362    // build a new routing configuration 
     1363    RouterConfig newcfg = Device::EAP::RouterConfig(*rcfg); 
     1364 
     1365    // construct the routing entry to find 
     1366    RouterConfig::Route r = {s.src, s.srcChannel, d.dst, d.dstChannel}; 
     1367 
     1368    // find the appropriate entry 
     1369    int idx = newcfg.getRouteIndex(r); 
     1370 
     1371    if (idx < 0) { 
     1372        // we have to add the route 
     1373        newcfg.insertRoute(r); 
     1374    } else { 
     1375        // the route is already present, so we can replace it 
     1376        if(enable) { 
     1377            debugOutput(DEBUG_LEVEL_VERBOSE, "connection %d => %d already present\n", source, dest); 
     1378            return true; 
     1379        } else { 
     1380            // remove the route 
     1381            newcfg.removeRoute(idx); 
     1382        } 
     1383    } 
     1384 
     1385    // if we get here it means we have to upload a new router config 
     1386    if(!m_eap.updateCurrentRouterConfig(newcfg)) { 
     1387        debugError("Could not update router config\n"); 
     1388        return false; 
     1389    } 
     1390 
     1391    return true; 
     1392
     1393 
     1394bool 
     1395Device::EAP::Router::getConnectionState(const int source, const int dest) 
     1396
     1397    if((unsigned)source >= m_sources.size()) { 
     1398        debugWarning("source id out of range (%d)\n", source); 
     1399        return false; 
     1400    } 
     1401    Source s = m_sources.at(source); 
     1402 
     1403    if((unsigned)dest >= m_destinations.size()) { 
     1404        debugWarning("destination id out of range (%d)\n", dest); 
     1405        return false; 
     1406    } 
     1407    Destination d = m_destinations.at(dest); 
     1408 
     1409    // get the routing configuration 
     1410    RouterConfig *rcfg = m_eap.getActiveRouterConfig(); 
     1411    if(rcfg == NULL) { 
     1412        debugError("Could not request active router configuration\n"); 
     1413        return false; 
     1414    } 
     1415 
     1416    // build a new routing configuration 
     1417    RouterConfig newcfg = Device::EAP::RouterConfig(*rcfg); 
     1418 
     1419    // construct the routing entry to find 
     1420    RouterConfig::Route r = {s.src, s.srcChannel, d.dst, d.dstChannel}; 
     1421 
     1422    // find the appropriate entry 
     1423    int idx = newcfg.getRouteIndex(r); 
     1424 
     1425    if (idx < 0) { 
     1426        // the route is not present 
     1427        return false; 
     1428    } else { 
     1429        // the route is already present 
     1430        return true; 
     1431    } 
     1432
     1433 
     1434bool 
     1435Device::EAP::Router::canConnect(std::string src, std::string dst) 
     1436
     1437    int srcidx = getSourceIndex(src); 
     1438    int dstidx = getDestinationIndex(dst); 
     1439    return canConnect(srcidx, dstidx); 
     1440
     1441 
     1442bool 
     1443Device::EAP::Router::setConnectionState(std::string src, std::string dst, const bool enable) 
     1444
     1445    int srcidx = getSourceIndex(src); 
     1446    int dstidx = getDestinationIndex(dst); 
     1447    return setConnectionState(srcidx, dstidx, enable); 
     1448
     1449 
     1450bool 
     1451Device::EAP::Router::getConnectionState(std::string src, std::string dst) 
     1452
     1453    int srcidx = getSourceIndex(src); 
     1454    int dstidx = getDestinationIndex(dst); 
     1455    return getConnectionState(srcidx, dstidx); 
     1456
     1457 
     1458// the map is organized as a matrix where the  
     1459// rows are the destinations and the columns are 
     1460// the sources 
     1461 
     1462// note that map as assumed to be big enough and 
     1463// allocated by the user 
     1464bool 
     1465Device::EAP::Router::getConnectionMap(int *map) 
     1466
     1467    unsigned int nb_sources = getNbSources(); 
     1468    unsigned int nb_destinations = getNbDestinations(); 
     1469 
     1470    // clear the map 
     1471    memset(map, 0, nb_sources * nb_destinations * sizeof(int)); 
     1472 
     1473    // get the routing configuration 
     1474    RouterConfig *rcfg = m_eap.getActiveRouterConfig(); 
     1475    if(rcfg == NULL) { 
     1476        debugError("Could not request active router configuration\n"); 
     1477        return false; 
     1478    } 
     1479 
     1480    unsigned int nb_routes = rcfg->getNbRoutes(); 
     1481 
     1482    for(unsigned int i=0; i<nb_routes; i++) { 
     1483        struct RouterConfig::Route r = rcfg->getRoute(i); 
     1484        int srcidx = getSourceIndex(r.src, r.srcChannel); 
     1485        int dstidx = getDestinationIndex(r.dst, r.dstChannel); 
     1486        if(srcidx < 0) { 
     1487            debugWarning("bogus source (%d, %d) in route table\n", r.src, r.srcChannel); 
     1488        } else if(dstidx < 0) { 
     1489            debugWarning("bogus destination (%d, %d) in route table\n", r.dst, r.dstChannel); 
     1490        } else { 
     1491            int *ptr = map; 
     1492            ptr += dstidx * nb_sources; 
     1493            ptr += srcidx; 
     1494            *ptr = 1; // route present 
     1495        } 
     1496    } 
     1497    return true; 
     1498
     1499 
     1500bool 
     1501Device::EAP::Router::setConnectionMap(int *map) 
    5811502{ 
    5821503    return false; 
     1504} 
     1505 
     1506bool 
     1507Device::EAP::Router::clearAllConnections() 
     1508{ 
     1509    // build a new empty routing configuration 
     1510    RouterConfig newcfg = Device::EAP::RouterConfig(m_eap); 
     1511 
     1512    // upload the new router config 
     1513    if(!m_eap.updateCurrentRouterConfig(newcfg)) { 
     1514        debugError("Could not update router config\n"); 
     1515        return false; 
     1516    } 
     1517    return true; 
     1518} 
     1519 
     1520bool 
     1521Device::EAP::Router::hasPeakMetering() 
     1522{ 
     1523    return m_eap.m_router_exposed; 
     1524} 
     1525 
     1526double 
     1527Device::EAP::Router::getPeakValue(const int source, const int dest) 
     1528{ 
     1529    if((unsigned)source >= m_sources.size()) { 
     1530        debugWarning("source id out of range (%d)\n", source); 
     1531        return false; 
     1532    } 
     1533    Source s = m_sources.at(source); 
     1534 
     1535    if((unsigned)dest >= m_destinations.size()) { 
     1536        debugWarning("destination id out of range (%d)\n", dest); 
     1537        return false; 
     1538    } 
     1539    Destination d = m_destinations.at(dest); 
     1540 
     1541    debugOutput(DEBUG_LEVEL_VERBOSE, "getting peak info for [%d] %s => [%d] %s\n",  
     1542                                     source, s.name.c_str(), 
     1543                                     dest, d.name.c_str()); 
     1544 
     1545    // update the peak information 
     1546    m_peak.read(); 
     1547 
     1548    // construct the routing entry to find 
     1549    RouterConfig::Route r = {s.src, s.srcChannel, d.dst, d.dstChannel, 0}; 
     1550 
     1551    // find the appropriate entry 
     1552    int idx = m_peak.getRouteIndex(r); 
     1553 
     1554    if (idx < 0) { 
     1555        // the route is not present 
     1556        return -1; 
     1557    } else { 
     1558        // the route is present 
     1559        r = m_peak.getRoute(idx); 
     1560        return r.peak; 
     1561    } 
     1562 
    5831563} 
    5841564 
     
    5861566Device::EAP::Router::show() 
    5871567{ 
    588  
     1568    // print the peak space as it also contains the routing configuration 
     1569    printMessage("Active router config:\n"); 
     1570    m_peak.read(); 
     1571    m_peak.show(); 
     1572
     1573 
     1574// ----------- routing config ------------- 
     1575Device::EAP::RouterConfig::RouterConfig(EAP &p) 
     1576: m_eap(p) 
     1577, m_base(eRT_None), m_offset(0) 
     1578, m_debugModule(p.m_debugModule) 
     1579{} 
     1580 
     1581Device::EAP::RouterConfig::RouterConfig(EAP &p, enum eRegBase b, unsigned int o) 
     1582: m_eap(p) 
     1583, m_base(b), m_offset(o) 
     1584, m_debugModule(p.m_debugModule) 
     1585{} 
     1586 
     1587Device::EAP::RouterConfig::~RouterConfig() 
     1588{} 
     1589 
     1590bool 
     1591Device::EAP::RouterConfig::read(enum eRegBase base, unsigned offset) 
     1592
     1593    // first clear the current route vector 
     1594    m_routes.clear(); 
     1595 
     1596    uint32_t nb_routes; 
     1597    if(!m_eap.readRegBlock(base, offset, &nb_routes, 4)) { 
     1598        debugError("Failed to read number of entries\n"); 
     1599        return false; 
     1600    } 
     1601    if(nb_routes == 0) { 
     1602        debugWarning("No routes found\n"); 
     1603    } 
     1604 
     1605    // read the route info 
     1606    uint32_t tmp_entries[nb_routes]; 
     1607    if(!m_eap.readRegBlock(base, offset+4, tmp_entries, nb_routes*4)) { 
     1608        debugError("Failed to read router config block information\n"); 
     1609        return false; 
     1610    } 
     1611 
     1612    // decode into the routing vector 
     1613    for(unsigned int i=0; i < nb_routes; i++) { 
     1614        m_routes.push_back(decodeRoute(tmp_entries[i])); 
     1615    } 
     1616    return true; 
     1617
     1618 
     1619bool 
     1620Device::EAP::RouterConfig::write(enum eRegBase base, unsigned offset) 
     1621
     1622    uint32_t nb_routes = m_routes.size(); 
     1623    if(nb_routes == 0) { 
     1624        debugWarning("Writing 0 routes?\n"); 
     1625    } 
     1626    uint32_t tmp_entries[nb_routes]; 
     1627 
     1628    // encode from the routing vector 
     1629    int i=0; 
     1630    for ( RouteVectorIterator it = m_routes.begin(); 
     1631        it != m_routes.end(); 
     1632        ++it ) 
     1633    { 
     1634        tmp_entries[i] = encodeRoute( *it ); 
     1635        i++; 
     1636    } 
     1637 
     1638    // write the result to the device 
     1639    if(!m_eap.writeRegBlock(base, offset+4, tmp_entries, nb_routes*4)) { 
     1640        debugError("Failed to write router config block information\n"); 
     1641        return false; 
     1642    } 
     1643    if(!m_eap.writeRegBlock(base, offset, &nb_routes, 4)) { 
     1644        debugError("Failed to write number of entries\n"); 
     1645        return false; 
     1646    } 
     1647    return true; 
     1648
     1649 
     1650bool 
     1651Device::EAP::RouterConfig::insertRoute(struct Route r, unsigned int index) 
     1652
     1653    unsigned int nb_routes = getNbRoutes(); 
     1654    if(index > nb_routes) { 
     1655        debugError("Index out of range\n"); 
     1656        return false; 
     1657    } 
     1658    if (index == nb_routes) { // append 
     1659        m_routes.push_back(r); 
     1660        return true; 
     1661    } 
     1662    // insert 
     1663    RouteVectorIterator pos = m_routes.begin() + index; 
     1664    m_routes.insert(pos, r); 
     1665    return true; 
     1666
     1667 
     1668bool 
     1669Device::EAP::RouterConfig::replaceRoute(unsigned int old_index, struct Route new_route) 
     1670
     1671    if(old_index >= getNbRoutes()) { 
     1672        debugError("Index out of range\n"); 
     1673        return false; 
     1674    } 
     1675    if(!removeRoute(old_index)) { 
     1676        debugError("Could not remove old route\n"); 
     1677        return false; 
     1678    } 
     1679    return insertRoute(new_route, old_index); 
     1680
     1681 
     1682bool 
     1683Device::EAP::RouterConfig::replaceRoute(struct Route old_route, struct Route new_route) 
     1684
     1685    int idx = getRouteIndex(old_route); 
     1686    if(idx < 0) { 
     1687        debugWarning("Route not found\n"); 
     1688        return false; 
     1689    } 
     1690    return replaceRoute((unsigned int)idx, new_route); 
     1691
     1692 
     1693bool 
     1694Device::EAP::RouterConfig::removeRoute(struct Route r) 
     1695
     1696    int idx = getRouteIndex(r); 
     1697    if(idx < 0) { 
     1698        debugWarning("Route not found\n"); 
     1699        return false; 
     1700    } 
     1701    return removeRoute((unsigned int)idx); 
     1702
     1703 
     1704bool 
     1705Device::EAP::RouterConfig::removeRoute(unsigned int index) 
     1706
     1707    if(index >= getNbRoutes()) { 
     1708        debugError("Index out of range\n"); 
     1709        return false; 
     1710    } 
     1711    RouteVectorIterator pos = m_routes.begin() + index; 
     1712    m_routes.erase(pos); 
     1713    return true; 
     1714
     1715 
     1716int 
     1717Device::EAP::RouterConfig::getRouteIndex(struct Route r) 
     1718
     1719    int i = 0; 
     1720    for ( RouteVectorIterator it = m_routes.begin(); 
     1721        it != m_routes.end(); 
     1722        ++it ) 
     1723    { 
     1724        struct Route t = *it; 
     1725        if ((t.src == r.src) && (t.srcChannel == r.srcChannel) && (t.dst == r.dst) && (t.dstChannel == r.dstChannel)) return i; 
     1726        i++; 
     1727    } 
     1728    return -1; 
     1729
     1730 
     1731struct Device::EAP::RouterConfig::Route 
     1732Device::EAP::RouterConfig::getRoute(unsigned int idx) 
     1733
     1734    if( (idx < 0) || (idx >= m_routes.size()) ) { 
     1735        debugWarning("Route index out of range (%d)\n", idx); 
     1736        Route r = {eRS_Invalid, -1, eRD_Invalid, -1, 0}; 
     1737        return r; 
     1738    } 
     1739    return m_routes.at(idx); 
     1740
     1741 
     1742#define CASE_INT_EQUAL_RETURN(_x) case (int)(_x): return _x; 
     1743enum Device::EAP::eRouteDestination 
     1744Device::EAP::RouterConfig::intToRouteDestination(int dst) 
     1745
     1746    switch(dst) { 
     1747        CASE_INT_EQUAL_RETURN(eRD_AES); 
     1748        CASE_INT_EQUAL_RETURN(eRD_ADAT); 
     1749        CASE_INT_EQUAL_RETURN(eRD_Mixer0); 
     1750        CASE_INT_EQUAL_RETURN(eRD_Mixer1); 
     1751        CASE_INT_EQUAL_RETURN(eRD_InS0); 
     1752        CASE_INT_EQUAL_RETURN(eRD_InS1); 
     1753        CASE_INT_EQUAL_RETURN(eRD_ARM); 
     1754        CASE_INT_EQUAL_RETURN(eRD_ATX0); 
     1755        CASE_INT_EQUAL_RETURN(eRD_ATX1); 
     1756        CASE_INT_EQUAL_RETURN(eRD_Muted); 
     1757        default: return eRD_Invalid; 
     1758    } 
     1759
     1760 
     1761enum Device::EAP::eRouteSource 
     1762Device::EAP::RouterConfig::intToRouteSource(int src) 
     1763
     1764    switch(src) { 
     1765        CASE_INT_EQUAL_RETURN(eRS_AES); 
     1766        CASE_INT_EQUAL_RETURN(eRS_ADAT); 
     1767        CASE_INT_EQUAL_RETURN(eRS_Mixer); 
     1768        CASE_INT_EQUAL_RETURN(eRS_InS0); 
     1769        CASE_INT_EQUAL_RETURN(eRS_InS1); 
     1770        CASE_INT_EQUAL_RETURN(eRS_ARM); 
     1771        CASE_INT_EQUAL_RETURN(eRS_ARX0); 
     1772        CASE_INT_EQUAL_RETURN(eRS_ARX1); 
     1773        CASE_INT_EQUAL_RETURN(eRS_Muted); 
     1774        default: return eRS_Invalid; 
     1775    } 
     1776
     1777 
     1778struct Device::EAP::RouterConfig::Route 
     1779Device::EAP::RouterConfig::decodeRoute(uint32_t val) { 
     1780    int routerval = val & 0xFFFF; 
     1781    int peak = (val >> 16) & 0x0FFF; 
     1782    int src_blk = (routerval >> 12) & 0xF; 
     1783    int src_ch = (routerval >> 8) & 0xF; 
     1784    int dst_blk = (routerval >> 4) & 0xF; 
     1785    int dst_ch = (routerval >> 0) & 0xF; 
     1786    struct Route r = {intToRouteSource(src_blk), src_ch, intToRouteDestination(dst_blk), dst_ch, peak}; 
     1787    return r; 
     1788
     1789 
     1790uint32_t 
     1791Device::EAP::RouterConfig::encodeRoute(struct Route r) { 
     1792    if(r.src == eRS_Invalid || r.dst == eRD_Invalid) { 
     1793        debugWarning("Encoding invalid source/dest (%d/%d)\n", r.src, r.dst); 
     1794//         return 0xFFFFFFFF; 
     1795    } 
     1796    unsigned int src_blk = ((unsigned int)r.src) & 0xF; 
     1797    unsigned int src_ch = ((unsigned int)r.srcChannel) & 0xF; 
     1798    unsigned int dst_blk = ((unsigned int)r.dst) & 0xF; 
     1799    unsigned int dst_ch = ((unsigned int)r.dstChannel) & 0xF; 
     1800    uint32_t routerval = 0; 
     1801    routerval |= (src_blk << 12); 
     1802    routerval |= (src_ch << 8); 
     1803    routerval |= (dst_blk << 4); 
     1804    routerval |= (dst_ch << 0); 
     1805    return routerval; 
     1806
     1807 
     1808struct Device::EAP::RouterConfig::Route 
     1809Device::EAP::RouterConfig::getRouteForDestination(enum eRouteDestination dst, int channel) 
     1810
     1811    for ( RouteVectorIterator it = m_routes.begin(); 
     1812        it != m_routes.end(); 
     1813        ++it ) 
     1814    { 
     1815        struct Route r = *it; 
     1816        if((r.dst == (int)dst) && (r.dstChannel == channel)) { 
     1817            debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "%s:%02d comes from %s:%02d\n", 
     1818                                                  dstBlockToString(r.dst), r.dstChannel, 
     1819                                                  srcBlockToString(r.src), r.srcChannel); 
     1820            return r; 
     1821        } 
     1822    } 
     1823    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "%s:%02d source can't be found\n", 
     1824                                          dstBlockToString((int)dst), channel); 
     1825    struct Route r = {eRS_Invalid, -1, eRD_Invalid, 0, 0}; 
     1826    return r; 
     1827
     1828 
     1829std::vector<struct Device::EAP::RouterConfig::Route> 
     1830Device::EAP::RouterConfig::getRoutesForSource(enum eRouteSource src, int channel) 
     1831
     1832    std::vector<struct Route>routes; 
     1833    for ( RouteVectorIterator it = m_routes.begin(); 
     1834        it != m_routes.end(); 
     1835        ++it ) 
     1836    { 
     1837        struct Route r = *it; 
     1838        if((r.src == (int)src) && (r.srcChannel == channel)) { 
     1839            debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "%s:%02d goes to %s:%02d\n", 
     1840                                                  srcBlockToString(r.src), r.srcChannel, 
     1841                                                  dstBlockToString(r.dst), r.dstChannel); 
     1842            routes.push_back(r); 
     1843        } 
     1844    } 
     1845    return routes; 
     1846
     1847 
     1848void 
     1849Device::EAP::RouterConfig::show() 
     1850
     1851    for ( RouteVectorIterator it = m_routes.begin(); 
     1852        it != m_routes.end(); 
     1853        ++it ) 
     1854    { 
     1855        struct Route r = *it; 
     1856        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "%s:%02d => %s:%02d\n", 
     1857                                              srcBlockToString(r.src), r.srcChannel, 
     1858                                              dstBlockToString(r.dst), r.dstChannel); 
     1859    } 
     1860
     1861 
     1862 
     1863// ----------- peak space ------------- 
     1864 
     1865bool 
     1866Device::EAP::PeakSpace::read(enum eRegBase base, unsigned offset) 
     1867
     1868    // first clear the current route vector 
     1869    m_routes.clear(); 
     1870 
     1871    uint32_t nb_routes; 
     1872    // we have to figure out the number of entries through the currently 
     1873    // active router config 
     1874    RouterConfig *rcfg = m_eap.getActiveRouterConfig(); 
     1875    if(rcfg == NULL) { 
     1876        debugError("Could not get active router config\n"); 
     1877        return false; 
     1878    } 
     1879    nb_routes = rcfg->getNbRoutes(); 
     1880 
     1881    // read the route info 
     1882    uint32_t tmp_entries[nb_routes]; 
     1883    if(!m_eap.readRegBlock(base, offset, tmp_entries, nb_routes*4)) { 
     1884        debugError("Failed to read peak block information\n"); 
     1885        return false; 
     1886    } 
     1887 
     1888    // decode into the routing vector 
     1889    for(unsigned int i=0; i < nb_routes; i++) { 
     1890        m_routes.push_back(decodeRoute(tmp_entries[i])); 
     1891    } 
     1892//     show(); 
     1893    return true; 
     1894
     1895 
     1896bool 
     1897Device::EAP::PeakSpace::write(enum eRegBase base, unsigned offset) 
     1898
     1899    debugError("Peak space is read-only\n"); 
     1900    return true; 
     1901
     1902 
     1903void 
     1904Device::EAP::PeakSpace::show() 
     1905
     1906    for ( RouteVectorIterator it = m_routes.begin(); 
     1907        it != m_routes.end(); 
     1908        ++it ) 
     1909    { 
     1910        struct Route r = *it; 
     1911        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "%s:%02d => %s:%02d : %06d\n", 
     1912                                              srcBlockToString(r.src), r.srcChannel, 
     1913                                              dstBlockToString(r.dst), r.dstChannel, 
     1914                                              r.peak); 
     1915    } 
     1916
     1917 
     1918// ----------- stream config block ------------- 
     1919Device::EAP::StreamConfig::StreamConfig(EAP &p, enum eRegBase b, unsigned int o) 
     1920: m_eap(p) 
     1921, m_base(b), m_offset(o) 
     1922, m_nb_tx(0), m_nb_rx(0) 
     1923, m_tx_configs(NULL), m_rx_configs(NULL) 
     1924, m_debugModule(p.m_debugModule) 
     1925
     1926 
     1927
     1928 
     1929Device::EAP::StreamConfig::~StreamConfig() 
     1930
     1931    if(m_tx_configs) delete[]m_tx_configs; 
     1932    if(m_rx_configs) delete[]m_rx_configs; 
     1933
     1934 
     1935bool 
     1936Device::EAP::StreamConfig::read(enum eRegBase base, unsigned offset) 
     1937
     1938    if(!m_eap.readRegBlock(base, offset, &m_nb_tx, 4)) { 
     1939        debugError("Failed to read number of tx entries\n"); 
     1940        return false; 
     1941    } 
     1942    if(!m_eap.readRegBlock(base, offset+4, &m_nb_rx, 4)) { 
     1943        debugError("Failed to read number of rx entries\n"); 
     1944        return false; 
     1945    } 
     1946    debugOutput(DEBUG_LEVEL_VERBOSE, " Entries: TX: %lu, RX: %lu\n", m_nb_tx, m_nb_rx); 
     1947 
     1948    if(m_tx_configs) { 
     1949        delete[]m_tx_configs; 
     1950        m_tx_configs = NULL; 
     1951    } 
     1952    if(m_rx_configs) { 
     1953        delete[]m_rx_configs; 
     1954        m_rx_configs = NULL; 
     1955    } 
     1956     
     1957    offset += 8; 
     1958    if(m_nb_tx > 0) { 
     1959        m_tx_configs = new struct ConfigBlock[m_nb_tx]; 
     1960        for(unsigned int i=0; i<m_nb_tx; i++) { 
     1961            fb_quadlet_t *ptr = reinterpret_cast<fb_quadlet_t *>(&(m_tx_configs[i])); 
     1962            if(!m_eap.readRegBlock(base, offset, ptr, sizeof(struct ConfigBlock))) { 
     1963                debugError("Failed to read tx entry %d\n", i); 
     1964                return false; 
     1965            } 
     1966            offset += sizeof(struct ConfigBlock); 
     1967        } 
     1968    } 
     1969 
     1970    if(m_nb_rx > 0) { 
     1971        m_rx_configs = new struct ConfigBlock[m_nb_rx]; 
     1972        for(unsigned int i=0; i<m_nb_rx; i++) { 
     1973            fb_quadlet_t *ptr = reinterpret_cast<fb_quadlet_t *>(&(m_rx_configs[i])); 
     1974            if(!m_eap.readRegBlock(base, offset, ptr, sizeof(struct ConfigBlock))) { 
     1975                debugError("Failed to read rx entry %d\n", i); 
     1976                return false; 
     1977            } 
     1978            offset += sizeof(struct ConfigBlock); 
     1979        } 
     1980    } 
     1981    return true; 
     1982
     1983 
     1984bool 
     1985Device::EAP::StreamConfig::write(enum eRegBase base, unsigned offset) 
     1986
     1987    if(!m_eap.writeRegBlock(base, offset, &m_nb_tx, 4)) { 
     1988        debugError("Failed to write number of tx entries\n"); 
     1989        return false; 
     1990    } 
     1991    if(!m_eap.writeRegBlock(base, offset+4, &m_nb_rx, 4)) { 
     1992        debugError("Failed to write number of rx entries\n"); 
     1993        return false; 
     1994    } 
     1995 
     1996    offset += 8; 
     1997    for(unsigned int i=0; i<m_nb_tx; i++) { 
     1998        fb_quadlet_t *ptr = reinterpret_cast<fb_quadlet_t *>(&(m_tx_configs[i])); 
     1999        if(!m_eap.writeRegBlock(base, offset, ptr, sizeof(struct ConfigBlock))) { 
     2000            debugError("Failed to write tx entry %d\n", i); 
     2001            return false; 
     2002        } 
     2003        offset += sizeof(struct ConfigBlock); 
     2004    } 
     2005 
     2006    for(unsigned int i=0; i<m_nb_rx; i++) { 
     2007        fb_quadlet_t *ptr = reinterpret_cast<fb_quadlet_t *>(&(m_rx_configs[i])); 
     2008        if(!m_eap.writeRegBlock(base, offset, ptr, sizeof(struct ConfigBlock))) { 
     2009            debugError("Failed to write rx entry %d\n", i); 
     2010            return false; 
     2011        } 
     2012        offset += sizeof(struct ConfigBlock); 
     2013    } 
     2014    return true; 
     2015
     2016 
     2017Device::diceNameVector 
     2018Device::EAP::StreamConfig::getNamesForBlock(struct ConfigBlock &b) 
     2019
     2020    diceNameVector names; 
     2021    char namestring[DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_BYTES+1]; 
     2022 
     2023    memcpy(namestring, b.names, DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_BYTES); 
     2024 
     2025    // Strings from the device are always little-endian, 
     2026    // so byteswap for big-endian machines 
     2027    #if __BYTE_ORDER == __BIG_ENDIAN 
     2028    byteSwapBlock((quadlet_t *)namestring, DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_QUADS); 
     2029    #endif 
     2030 
     2031    namestring[DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_BYTES]='\0'; 
     2032    return m_eap.m_device.splitNameString(std::string(namestring)); 
     2033
     2034 
     2035void 
     2036Device::EAP::StreamConfig::showConfigBlock(struct ConfigBlock &b) 
     2037
     2038    debugOutput(DEBUG_LEVEL_VERBOSE, " Channel count : %lu audio, %lu midi\n", b.nb_audio, b.nb_midi); 
     2039    debugOutput(DEBUG_LEVEL_VERBOSE, " AC3 Map       : 0x%08X\n", b.ac3_map); 
     2040    diceNameVector channel_names  = getNamesForBlock(b); 
     2041    debugOutput(DEBUG_LEVEL_VERBOSE,"  Channel names :\n"); 
     2042    for ( diceNameVectorIterator it = channel_names.begin(); 
     2043        it != channel_names.end(); 
     2044        ++it ) 
     2045    { 
     2046        debugOutput(DEBUG_LEVEL_VERBOSE,"     %s\n", (*it).c_str()); 
     2047    } 
     2048
     2049 
     2050void 
     2051Device::EAP::StreamConfig::show() 
     2052
     2053    for(unsigned int i=0; i<m_nb_tx; i++) { 
     2054        debugOutput(DEBUG_LEVEL_VERBOSE, "TX Config block %d\n", i); 
     2055        showConfigBlock(m_tx_configs[i]); 
     2056    } 
     2057    for(unsigned int i=0; i<m_nb_rx; i++) { 
     2058        debugOutput(DEBUG_LEVEL_VERBOSE, "RX Config block %d\n", i); 
     2059        showConfigBlock(m_rx_configs[i]); 
     2060    } 
    5892061} 
    5902062 
  • trunk/libffado/src/dice/dice_eap.h

    r1550 r1630  
    9696 
    9797// MIXER registers 
     98// TODO 
     99 
     100// PEAK registers 
     101// TODO 
     102 
     103// NEW ROUTER registers 
     104// TODO 
     105 
     106// NEW STREAM CFG registers 
     107// TODO 
     108 
     109// CURRENT CFG registers 
     110#define DICE_EAP_CURRCFG_LOW_ROUTER         0x0000 
     111#define DICE_EAP_CURRCFG_LOW_STREAM         0x1000 
     112#define DICE_EAP_CURRCFG_MID_ROUTER         0x2000 
     113#define DICE_EAP_CURRCFG_MID_STREAM         0x3000 
     114#define DICE_EAP_CURRCFG_HIGH_ROUTER        0x4000 
     115#define DICE_EAP_CURRCFG_HIGH_STREAM        0x5000 
     116 
     117#define DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_QUADS  (64) 
     118#define DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_BYTES  (4*DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_QUADS) 
  • trunk/libffado/src/fireworks/fireworks_control.h

    r1336 r1630  
    6868    virtual int getRowCount( ); 
    6969    virtual int getColCount( ); 
     70 
     71    // full map updates are unsupported 
     72    virtual bool getCoefficientMap(int &) {return false;}; 
     73    virtual bool storeCoefficientMap(int &) {return false;}; 
    7074 
    7175protected: 
  • trunk/libffado/src/libcontrol/Element.cpp

    r1498 r1630  
    216216} 
    217217 
     218/** 
     219 * Finds an element by name 
     220 * Note that you have to run this with the lock held, 
     221 * otherwise there is no guarantee that the element will 
     222 * not be deleted from the tree by an async event (e.g. busreset) 
     223 * 
     224 * @param name element name 
     225 * @return element or null if not found 
     226 */ 
     227Element * 
     228Container::getElementByName(std::string name) { 
     229    if(!getLock().isLocked()) debugWarning("Getting a Config::Element without locking the control tree, dangerous!\n"); 
     230    for ( ElementVectorIterator it = m_Children.begin(); 
     231      it != m_Children.end(); 
     232      ++it ) 
     233    { 
     234        if((*it)->getName() == name) { 
     235            debugOutput( DEBUG_LEVEL_VERBOSE, "Found Element %s (%s) \n", 
     236                (*it)->getName().c_str(), (*it)->getDescription().c_str()); 
     237            return *it; 
     238        } 
     239    } 
     240    return NULL; 
     241} 
     242 
    218243bool 
    219244Container::addElement(Element *e) 
  • trunk/libffado/src/libcontrol/Element.h

    r1568 r1630  
    163163    const ElementVector & getElementVector(); 
    164164 
     165    Element * getElementByName(std::string name); 
     166 
     167 
    165168    virtual void show(); 
    166169    virtual void setVerboseLevel(int l); 
  • trunk/libffado/src/libcontrol/MatrixMixer.h

    r1158 r1630  
    4747    virtual void show() = 0; 
    4848 
    49     virtual std::string getRowName( const int ) = 0; 
    50     virtual std::string getColName( const int ) = 0; 
    51     virtual int canWrite( const int, const int ) = 0; 
    52     virtual double setValue( const int, const int, const double ) = 0; 
    53     virtual double getValue( const int, const int ) = 0; 
    54     virtual int getRowCount( ) = 0; 
    55     virtual int getColCount( ) = 0; 
     49    // per-coefficient access 
     50    virtual std::string getRowName(const int) = 0; 
     51    virtual std::string getColName(const int) = 0; 
     52    virtual int canWrite(const int, const int) = 0; 
     53    virtual double setValue(const int, const int, const double) = 0; 
     54    virtual double getValue(const int, const int) = 0; 
     55    virtual int getRowCount() = 0; 
     56    virtual int getColCount() = 0; 
     57 
     58    // functions to access the entire coefficient map at once 
     59    virtual bool getCoefficientMap(int &) = 0; 
     60    virtual bool storeCoefficientMap(int &) = 0; 
    5661 
    5762protected: 
  • trunk/libffado/src/motu/motu_controls.h

    r1531 r1630  
    190190    virtual int getColCount(); 
    191191 
     192    // full map updates are unsupported 
     193    virtual bool getCoefficientMap(int &) {return false;}; 
     194    virtual bool storeCoefficientMap(int &) {return false;}; 
     195 
    192196protected: 
    193197     struct sSignalInfo { 
  • trunk/libffado/src/rme/fireface_settings_ctrls.h

    r1616 r1630  
    9999    virtual double getValue(const int row, const int col); 
    100100 
     101    // functions to access the entire coefficient map at once 
     102    virtual bool getCoefficientMap(int &) {return false;}; 
     103    virtual bool storeCoefficientMap(int &) {return false;}; 
     104 
    101105protected: 
    102106    Device &m_parent; 
  • trunk/libffado/src/SConscript

    r1626 r1630  
    6767        libcontrol/BasicElements.cpp \ 
    6868        libcontrol/MatrixMixer.cpp \ 
     69        libcontrol/CrossbarRouter.cpp \ 
    6970        libcontrol/ClockSelect.cpp \ 
    7071        libcontrol/Nickname.cpp \ 
     
    158159        dice/dice_avdevice.cpp \ 
    159160        dice/dice_eap.cpp \ 
     161        dice/focusrite/saffire_pro40.cpp \ 
    160162' ) 
    161163 
  • trunk/libffado/support/dbus/control-interface.xml

    r1498 r1630  
    203203          <arg type="i" name="nbrows" direction="out"/> 
    204204      </method> 
    205  
     205  </interface> 
     206 
     207  <interface name="org.ffado.Control.Element.CrossbarRouter"> 
     208      <method name="getSourceName"> 
     209          <arg type="i" name="srcid" direction="in"/> 
     210          <arg type="s" name="sourcename" direction="out"/> 
     211      </method> 
     212      <method name="getDestinationName"> 
     213          <arg type="i" name="dstid" direction="in"/> 
     214          <arg type="s" name="destinationname" direction="out"/> 
     215      </method> 
     216      <method name="getSourceIndex"> 
     217          <arg type="s" name="sourcename" direction="in"/> 
     218          <arg type="i" name="srcid" direction="out"/> 
     219      </method> 
     220      <method name="getDestinationIndex"> 
     221          <arg type="s" name="destinationname" direction="in"/> 
     222          <arg type="i" name="dstid" direction="out"/> 
     223      </method> 
     224      <method name="getSourceNames"> 
     225          <arg type="as" name="sourcenames" direction="out"/> 
     226      </method> 
     227      <method name="getDestinationNames"> 
     228          <arg type="as" name="destinationnames" direction="out"/> 
     229      </method> 
     230      <method name="getDestinationsForSource"> 
     231          <arg type="i" name="srcid" direction="in"/> 
     232          <arg type="ai" name="dstids" direction="out"/> 
     233      </method> 
     234      <method name="getSourceForDestination"> 
     235          <arg type="i" name="dstid" direction="in"/> 
     236          <arg type="i" name="srcid" direction="out"/> 
     237      </method> 
     238      <method name="canConnect"> 
     239          <arg type="i" name="srcid" direction="in"/> 
     240          <arg type="i" name="dstid" direction="in"/> 
     241          <arg type="i" name="canconnect" direction="out"/> 
     242      </method> 
     243      <method name="setConnectionState"> 
     244          <arg type="i" name="srcid" direction="in"/> 
     245          <arg type="i" name="dstid" direction="in"/> 
     246          <arg type="i" name="state" direction="in"/> 
     247          <arg type="i" name="result" direction="out"/> 
     248      </method> 
     249      <method name="getConnectionState"> 
     250          <arg type="i" name="srcid" direction="in"/> 
     251          <arg type="i" name="dstid" direction="in"/> 
     252          <arg type="i" name="state" direction="out"/> 
     253      </method> 
     254      <method name="canConnectNamed"> 
     255          <arg type="s" name="srcname" direction="in"/> 
     256          <arg type="s" name="dstname" direction="in"/> 
     257          <arg type="i" name="canconnect" direction="out"/> 
     258      </method> 
     259      <method name="setConnectionStateNamed"> 
     260          <arg type="s" name="srcname" direction="in"/> 
     261          <arg type="s" name="dstname" direction="in"/> 
     262          <arg type="i" name="state" direction="in"/> 
     263          <arg type="i" name="result" direction="out"/> 
     264      </method> 
     265      <method name="getConnectionStateNamed"> 
     266          <arg type="s" name="srcname" direction="in"/> 
     267          <arg type="s" name="dstname" direction="in"/> 
     268          <arg type="i" name="state" direction="out"/> 
     269      </method> 
     270      <method name="clearAllConnections"> 
     271          <arg type="i" name="state" direction="out"/> 
     272      </method> 
     273      <method name="getNbSources"> 
     274          <arg type="i" name="state" direction="out"/> 
     275      </method> 
     276      <method name="getNbDestinations"> 
     277          <arg type="i" name="state" direction="out"/> 
     278      </method> 
     279      <method name="getConnectionMap"> 
     280          <arg type="ai" name="map" direction="out"/> 
     281      </method> 
     282      <method name="setConnectionMap"> 
     283          <arg type="ai" name="map" direction="in"/> 
     284          <arg type="i" name="state" direction="out"/> 
     285      </method> 
     286      <method name="hasPeakMetering"> 
     287          <arg type="i" name="hasmetering" direction="out"/> 
     288      </method> 
     289      <method name="getPeakValue"> 
     290          <arg type="i" name="srcid" direction="in"/> 
     291          <arg type="i" name="dstid" direction="in"/> 
     292          <arg type="d" name="value" direction="out"/> 
     293      </method> 
    206294  </interface> 
    207295 
  • trunk/libffado/support/dbus/controlserver.cpp

    r1621 r1630  
    2626#include "libcontrol/BasicElements.h" 
    2727#include "libcontrol/MatrixMixer.h" 
     28#include "libcontrol/CrossbarRouter.h" 
    2829#include "libutil/Time.h" 
    2930#include "libutil/PosixMutex.h" 
     
    423424        } 
    424425         
     426        if (dynamic_cast<Control::CrossbarRouter *>(&e) != NULL) { 
     427            debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::CrossbarRouter\n"); 
     428             
     429            return new CrossbarRouter(conn(), std::string(path()+"/"+e.getName()), 
     430                parent, *dynamic_cast<Control::CrossbarRouter *>(&e)); 
     431        } 
     432         
    425433        debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Element\n"); 
    426434        return new Element(conn(), std::string(path()+"/"+e.getName()), parent, e); 
     
    811819} 
    812820 
     821// --- CrossbarRouter 
     822 
     823CrossbarRouter::CrossbarRouter( DBus::Connection& connection, std::string p, Element* parent, Control::CrossbarRouter &slave) 
     824: Element(connection, p, parent, slave) 
     825, m_Slave(slave) 
     826{ 
     827    debugOutput( DEBUG_LEVEL_VERBOSE, "Created CrossbarRouter on '%s'\n", 
     828                 path().c_str() ); 
     829} 
     830 
     831DBus::String 
     832CrossbarRouter::getSourceName(const DBus::Int32 &idx) 
     833{ 
     834    return m_Slave.getSourceName(idx); 
     835} 
     836 
     837DBus::String 
     838CrossbarRouter::getDestinationName(const DBus::Int32 &idx) 
     839{ 
     840    return m_Slave.getDestinationName(idx); 
     841} 
     842 
     843DBus::Int32 
     844CrossbarRouter::getSourceIndex(const DBus::String &name) 
     845{ 
     846    return m_Slave.getSourceIndex(name); 
     847} 
     848 
     849DBus::Int32 
     850CrossbarRouter::getDestinationIndex(const DBus::String &name) 
     851{ 
     852    return m_Slave.getDestinationIndex(name); 
     853} 
     854 
     855std::vector< DBus::String > 
     856CrossbarRouter::getSourceNames() 
     857{ 
     858    return m_Slave.getSourceNames(); 
     859} 
     860 
     861std::vector< DBus::String > 
     862CrossbarRouter::getDestinationNames() 
     863{ 
     864    return m_Slave.getDestinationNames(); 
     865} 
     866 
     867std::vector< DBus::Int32 > 
     868CrossbarRouter::getDestinationsForSource(const DBus::Int32 &idx) 
     869{ 
     870    return m_Slave.getDestinationsForSource(idx); 
     871} 
     872 
     873DBus::Int32 
     874CrossbarRouter::getSourceForDestination(const DBus::Int32 &idx) 
     875{ 
     876    return m_Slave.getSourceForDestination(idx); 
     877} 
     878 
     879DBus::Int32 
     880CrossbarRouter::canConnect(const DBus::Int32 &source, const DBus::Int32 &dest) 
     881{ 
     882    return m_Slave.canConnect(source, dest); 
     883} 
     884 
     885DBus::Int32 
     886CrossbarRouter::setConnectionState(const DBus::Int32 &source, const DBus::Int32 &dest, const DBus::Int32 &enable) 
     887{ 
     888    return m_Slave.setConnectionState(source, dest, enable); 
     889} 
     890 
     891DBus::Int32 
     892CrossbarRouter::getConnectionState(const DBus::Int32 &source, const DBus::Int32 &dest) 
     893{ 
     894    return m_Slave.getConnectionState(source, dest); 
     895} 
     896 
     897DBus::Int32 
     898CrossbarRouter::canConnectNamed(const DBus::String& source, const DBus::String& dest) 
     899{ 
     900    return m_Slave.canConnect(source, dest); 
     901} 
     902 
     903DBus::Int32 
     904CrossbarRouter::setConnectionStateNamed(const DBus::String &source, const DBus::String &dest, const DBus::Int32 &enable) 
     905{ 
     906    return m_Slave.setConnectionState(source, dest, enable); 
     907} 
     908 
     909DBus::Int32 
     910CrossbarRouter::getConnectionStateNamed(const DBus::String &source, const DBus::String &dest) 
     911{ 
     912    return m_Slave.getConnectionState(source, dest); 
     913} 
     914 
     915DBus::Int32 
     916CrossbarRouter::clearAllConnections() 
     917{ 
     918    return m_Slave.clearAllConnections(); 
     919} 
     920 
     921DBus::Int32 
     922CrossbarRouter::getNbSources() 
     923{ 
     924    return m_Slave.getNbSources(); 
     925} 
     926 
     927DBus::Int32 
     928CrossbarRouter::getNbDestinations() 
     929{ 
     930    return m_Slave.getNbDestinations(); 
     931} 
     932 
     933DBus::Int32 
     934CrossbarRouter::hasPeakMetering() 
     935{ 
     936    return m_Slave.hasPeakMetering(); 
     937} 
     938 
     939DBus::Double 
     940CrossbarRouter::getPeakValue(const DBus::Int32 &source, const DBus::Int32 &dest) 
     941{ 
     942    return m_Slave.getPeakValue(source, dest); 
     943} 
     944 
     945std::vector< DBus::Int32 > 
     946CrossbarRouter::getConnectionMap() 
     947{ 
     948    std::vector< DBus::Int32 >connmap; 
     949    unsigned int nb_sources = m_Slave.getNbSources(); 
     950    unsigned int nb_destinations = m_Slave.getNbDestinations(); 
     951    unsigned int nb_entries = nb_sources * nb_destinations; 
     952 
     953    int map_data[nb_entries]; 
     954 
     955    if(!m_Slave.getConnectionMap(map_data)) { 
     956        debugError("Could not fetch connection map\n"); 
     957        return connmap; 
     958    } 
     959 
     960    for(unsigned int i=0; i<nb_entries; i++) { 
     961        connmap.push_back(map_data[i]); 
     962    } 
     963    return connmap; 
     964} 
     965 
     966DBus::Int32 
     967CrossbarRouter::setConnectionMap(const std::vector< DBus::Int32 >&connmap) 
     968{ 
     969    unsigned int nb_sources = m_Slave.getNbSources(); 
     970    unsigned int nb_destinations = m_Slave.getNbDestinations(); 
     971    unsigned int nb_entries = nb_sources * nb_destinations; 
     972 
     973    if(connmap.size() != nb_entries) { 
     974        debugError("bogus map size\n"); 
     975        return false; 
     976    } 
     977 
     978    int map_data[nb_entries]; 
     979    for (unsigned int i=0; i<nb_entries; i++) { 
     980        map_data[i] = connmap.at(i); 
     981    } 
     982    return m_Slave.setConnectionMap(map_data); 
     983} 
     984 
     985 
    813986} // end of namespace Control 
  • trunk/libffado/support/dbus/controlserver.h

    r1498 r1630  
    3737namespace Control { 
    3838    class MatrixMixer; 
     39    class CrossbarRouter; 
    3940}; 
    4041 
     
    318319}; 
    319320 
     321class CrossbarRouter 
     322: public org::ffado::Control::Element::CrossbarRouter 
     323, public Element 
     324{ 
     325public: 
     326    CrossbarRouter(  DBus::Connection& connection, 
     327                  std::string p, Element *, 
     328                  Control::CrossbarRouter &slave ); 
     329 
     330    DBus::String getSourceName(const DBus::Int32 &); 
     331    DBus::String getDestinationName(const DBus::Int32 &); 
     332    DBus::Int32 getSourceIndex(const DBus::String &); 
     333    DBus::Int32 getDestinationIndex(const DBus::String &); 
     334 
     335    std::vector< DBus::String > getSourceNames(); 
     336    std::vector< DBus::String > getDestinationNames(); 
     337 
     338    std::vector< DBus::Int32 > getDestinationsForSource(const DBus::Int32 &); 
     339    DBus::Int32 getSourceForDestination(const DBus::Int32 &); 
     340 
     341    DBus::Int32 canConnect(const DBus::Int32 &source, const DBus::Int32 &dest); 
     342    DBus::Int32 setConnectionState(const DBus::Int32 &source, const DBus::Int32 &dest, const DBus::Int32 &enable); 
     343    DBus::Int32 getConnectionState(const DBus::Int32 &source, const DBus::Int32 &dest); 
     344 
     345    DBus::Int32 canConnectNamed(const DBus::String&, const DBus::String&); 
     346    DBus::Int32 setConnectionStateNamed(const DBus::String&, const DBus::String&, const DBus::Int32 &enable); 
     347    DBus::Int32 getConnectionStateNamed(const DBus::String&, const DBus::String&); 
     348 
     349    DBus::Int32 clearAllConnections(); 
     350 
     351    DBus::Int32 getNbSources(); 
     352    DBus::Int32 getNbDestinations(); 
     353 
     354    DBus::Int32 hasPeakMetering(); 
     355    DBus::Double getPeakValue(const DBus::Int32 &source, const DBus::Int32 &dest); 
     356 
     357    std::vector< DBus::Int32 > getConnectionMap(); 
     358    DBus::Int32 setConnectionMap(const std::vector< DBus::Int32 >&); 
     359 
     360private: 
     361    Control::CrossbarRouter &m_Slave; 
     362}; 
     363 
    320364} 
    321365 
  • trunk/libffado/support/tools/ffado-diag.in

    r1499 r1630  
    3636 
    3737## message strings 
    38 FFADODIAG_VERSION = "0.1
     38FFADODIAG_VERSION = "$VERSION-$REVISION
    3939 
    4040welcome_msg = """ 
     
    7777    for l in lines: 
    7878        mod = l.split()[0] 
    79         if mod == modulename
     79        if mod == modulename or mod == modulename.replace('-', '_')
    8080            log.info(" found") 
    8181            return True 
    8282    log.info(" not found") 
    8383    return False 
    84      
     84 
    8585def check_for_module_present(modulename): 
    8686    log.info("Checking if module '%s' is present... " % modulename) 
     
    118118def check_1394newstack_loaded(): 
    119119    retval = True 
    120     if not check_for_module_loaded('fw-core'): 
    121         retval = False 
    122     if not check_for_module_loaded('fw-ohci'): 
     120    if not check_for_module_loaded('firewire-core'): 
     121        retval = False 
     122    if not check_for_module_loaded('firewire-ohci'): 
    123123        retval = False 
    124124    return retval 
     
    126126def check_1394newstack_present(): 
    127127    retval = True 
    128     if not check_for_module_present('fw-core'): 
    129         retval = False 
    130     if not check_for_module_present('fw-ohci'): 
     128    if not check_for_module_present('firewire-core'): 
     129        retval = False 
     130    if not check_for_module_present('firewire-ohci'): 
    131131        retval = False 
    132132    return retval 
  • trunk/libffado/tests/test-dice-eap.cpp

    r1551 r1630  
    3434#include "libutil/Configuration.h" 
    3535 
     36#include "libcontrol/MatrixMixer.h" 
     37#include "libcontrol/CrossbarRouter.h" 
     38 
    3639#include "dice/dice_avdevice.h" 
    3740using namespace Dice; 
     
    4144#include <cstdlib> 
    4245#include <cstring> 
     46 
     47#include <signal.h> 
     48int run; 
     49 
     50static void sighandler(int sig) 
     51{ 
     52    run = 0; 
     53} 
    4354 
    4455using namespace std; 
     
    143154main(int argc, char **argv) 
    144155{ 
     156    run=1; 
     157 
     158    signal (SIGINT, sighandler); 
     159    signal (SIGPIPE, sighandler); 
     160 
    145161    // arg parsing 
    146162    if ( argp_parse ( &argp, argc, argv, 0, 0, &arguments ) ) { 
     
    213229    } 
    214230    printMessage("device supports EAP\n"); 
    215      
    216     Device::EAP eap = Device::EAP(*avDevice); 
    217  
    218     if(!eap.init()) { 
    219         printMessage("Could not init EAP\n"); 
    220         delete m_deviceManager; 
    221         return -1; 
    222     } 
     231 
     232    Device::EAP &eap = *(avDevice->getEAP()); 
    223233 
    224234    eap.show(); 
    225  
    226     Device::EAP::Mixer m = Device::EAP::Mixer(eap); 
    227     m.init(); 
    228     m.show(); 
     235    eap.lockControl(); 
     236    Control::Element *e = eap.getElementByName("MatrixMixer"); 
     237    if(e == NULL) { 
     238        printMessage("Could not get MatrixMixer control element\n"); 
     239    } else { 
     240        Control::MatrixMixer *m = dynamic_cast<Control::MatrixMixer *>(e); 
     241        if(m == NULL) { 
     242            printMessage("Element is not a MatrixMixer control element\n"); 
     243        } else { 
     244            for(int row=0; row < 16; row++) { 
     245                for(int col=0; col < 18; col++) { 
     246//                     m->setValue(row, col, 0); 
     247                } 
     248            } 
     249        } 
     250    } 
     251    // after unlocking, these should not be used anymore 
     252    e = NULL; 
     253    eap.unlockControl(); 
     254 
     255    int cnt = 0; 
     256 
     257    while(run) { 
     258        eap.lockControl(); 
     259        Control::Element *e = eap.getElementByName("Router"); 
     260        if(e == NULL) { 
     261            printMessage("Could not get CrossbarRouter control element\n"); 
     262        } else { 
     263            Control::CrossbarRouter *c = dynamic_cast<Control::CrossbarRouter *>(e); 
     264            if(c == NULL) { 
     265                printMessage("Element is not a CrossbarRouter control element\n"); 
     266            } else { 
     267//                 if(cnt == 0) { 
     268//                     Control::CrossbarRouter::NameVector n; 
     269//                     n = c->getSourceNames(); 
     270//                     for(int i=0; i<n.size(); i++) { 
     271//                         printMessage("Src  %02d: %s\n", i, n.at(i).c_str()); 
     272//                     } 
     273//                     n = c->getDestinationNames(); 
     274//                     for(int i=0; i<n.size(); i++) { 
     275//                         printMessage("Dest %02d: %s\n", i, n.at(i).c_str()); 
     276//                     } 
     277//                 } 
     278                #define NELEMS 10 
     279                double peaks[NELEMS]; 
     280                int srcids[NELEMS]; 
     281                int dstidx = c->getDestinationIndex("MixerIn:00"); 
     282                for(int i=0; i<NELEMS; i++) { 
     283                    srcids[i] = c->getSourceForDestination(dstidx + i); 
     284                    peaks[i] = c->getPeakValue(srcids[i], dstidx + i); 
     285                } 
     286                for(int i=0; i<NELEMS; i++) { 
     287                    std::string srcname = c->getSourceName(srcids[i]); 
     288                    std::string dstname = c->getDestinationName(dstidx + i); 
     289                    printMessage("Peak %3d (%10s => %10s): %f\n", i, srcname.c_str(), dstname.c_str(), peaks[i]); 
     290                } 
     291            } 
     292        } 
     293        // after unlocking, these should not be used anymore 
     294        e = NULL; 
     295        eap.unlockControl(); 
     296        sleep(1); 
     297    } 
    229298 
    230299    // cleanup