root/trunk/libffado/src/dice/dice_avdevice.h

Revision 1630, 20.0 kB (checked in by ppalmers, 13 years ago)

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

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 #ifndef DICEDEVICE_H
25 #define DICEDEVICE_H
26
27 #include "ffadodevice.h"
28
29 #include "debugmodule/debugmodule.h"
30 #include "libavc/avc_definitions.h"
31
32 #include "libstreaming/amdtp/AmdtpReceiveStreamProcessor.h"
33 #include "libstreaming/amdtp/AmdtpTransmitStreamProcessor.h"
34 #include "libstreaming/amdtp/AmdtpPort.h"
35
36 #include "libieee1394/ieee1394service.h"
37
38 #include "libcontrol/Element.h"
39 #include "libcontrol/MatrixMixer.h"
40 #include "libcontrol/CrossbarRouter.h"
41
42 #include "dice_eap.h"
43
44 #include <string>
45 #include <vector>
46
47 class ConfigRom;
48 class Ieee1394Service;
49
50 namespace Util {
51     class Configuration;
52 }
53
54 namespace Dice {
55
56 class Notifier;
57
58 class Device : public FFADODevice {
59 // private:
60     typedef std::vector< std::string > diceNameVector;
61     typedef std::vector< std::string >::iterator diceNameVectorIterator;
62
63 public:
64     class Notifier;
65     class EAP;
66
67     /**
68      * this class represents the EAP interface
69      * available on some devices
70      */
71     class EAP : public Control::Container
72     {
73     public:
74         enum eWaitReturn {
75             eWR_Error,
76             eWR_Timeout,
77             eWR_Busy,
78             eWR_Done,
79         };
80         enum eRegBase {
81             eRT_Base,
82             eRT_Capability,
83             eRT_Command,
84             eRT_Mixer,
85             eRT_Peak,
86             eRT_NewRouting,
87             eRT_NewStreamCfg,
88             eRT_CurrentCfg,
89             eRT_Standalone,
90             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;
349         };
350
351     public:
352         EAP(Device &);
353         virtual ~EAP();
354
355         static bool supportsEAP(Device &);
356         bool init();
357
358         void show();
359         enum eWaitReturn operationBusy();
360         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:
375         bool loadRouterConfig(bool low, bool mid, bool high);
376         bool loadStreamConfig(bool low, bool mid, bool high);
377         bool loadRouterAndStreamConfig(bool low, bool mid, bool high);
378     private:
379         bool     m_router_exposed;
380         bool     m_router_readonly;
381         bool     m_router_flashstored;
382         uint16_t m_router_nb_entries;
383
384         bool     m_mixer_exposed;
385         bool     m_mixer_readonly;
386         bool     m_mixer_flashstored;
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;
391
392         bool     m_general_support_dynstream;
393         bool     m_general_support_flash;
394         bool     m_general_peak_enabled;
395         uint8_t  m_general_max_tx;
396         uint8_t  m_general_max_rx;
397         bool     m_general_stream_cfg_stored;
398         uint16_t m_general_chip;
399
400         bool commandHelper(fb_quadlet_t cmd);
401
402         bool readReg(enum eRegBase, unsigned offset, quadlet_t *);
403         bool writeReg(enum eRegBase, unsigned offset, quadlet_t);
404         bool readRegBlock(enum eRegBase, unsigned, fb_quadlet_t *, size_t);
405         bool writeRegBlock(enum eRegBase, unsigned, fb_quadlet_t *, size_t);
406         bool readRegBlockSwapped(enum eRegBase, unsigned, fb_quadlet_t *, size_t);
407         bool writeRegBlockSwapped(enum eRegBase, unsigned, fb_quadlet_t *, size_t);
408         fb_nodeaddr_t offsetGen(enum eRegBase, unsigned, size_t);
409
410     private:
411         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:
428
429         fb_quadlet_t m_capability_offset;
430         fb_quadlet_t m_capability_size;
431         fb_quadlet_t m_cmd_offset;
432         fb_quadlet_t m_cmd_size;
433         fb_quadlet_t m_mixer_offset;
434         fb_quadlet_t m_mixer_size;
435         fb_quadlet_t m_peak_offset;
436         fb_quadlet_t m_peak_size;
437         fb_quadlet_t m_new_routing_offset;
438         fb_quadlet_t m_new_routing_size;
439         fb_quadlet_t m_new_stream_cfg_offset;
440         fb_quadlet_t m_new_stream_cfg_size;
441         fb_quadlet_t m_curr_cfg_offset;
442         fb_quadlet_t m_curr_cfg_size;
443         fb_quadlet_t m_standalone_offset;
444         fb_quadlet_t m_standalone_size;
445         fb_quadlet_t m_app_offset;
446         fb_quadlet_t m_app_size;
447     };
448
449 public:
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
486 protected:
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
493 private: // 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
513 private: // active config
514     enum eDiceConfig {
515         eDC_Unknown,
516         eDC_Low,
517         eDC_Mid,
518         eDC_High,
519     };
520
521     enum eDiceConfig getCurrentConfig();
522
523 private: // 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
543 private:
544     EAP*         m_eap;
545 public:
546     EAP* getEAP() {return m_eap;};
547
548 private: // 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:
591 public:
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
612
613 };
614
615 }
616 #endif
Note: See TracBrowser for help on using the browser.