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

Revision 1776, 18.4 kB (checked in by arnonym, 11 years ago)

Reduce the LOC:

  • Use only strings as identifiers for the Dice::EAP::Router. Updating the router doesn't happen that often, using strings only is acceptable. And it eases handling so much.
  • Adapt the control interface.
  • Adapt the dbus interface.
  • Adapt the routers gui.
  • The peak-space is not yet working (I didn't actually test it), the peak-functions of EAP::Router return nothing.
  • And the test for the dice has to be adopted when the peaks are working again.

TODO:

  • Re-activate the peaks.
  • Adopt the mixer interface.
Line 
1 /*
2  * Copyright (C) 2005-2009 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 #ifndef __DICE_EAP_H
24 #define __DICE_EAP_H
25
26 #include "dice_avdevice.h"
27
28 #define DICE_EAP_BASE                  0x0000000000200000ULL
29 #define DICE_EAP_MAX_SIZE              0x0000000000F00000ULL
30
31 #define DICE_EAP_CAPABILITY_SPACE_OFF      0x0000
32 #define DICE_EAP_CAPABILITY_SPACE_SZ       0x0004
33 #define DICE_EAP_CMD_SPACE_OFF             0x0008
34 #define DICE_EAP_CMD_SPACE_SZ              0x000C
35 #define DICE_EAP_MIXER_SPACE_OFF           0x0010
36 #define DICE_EAP_MIXER_SPACE_SZ            0x0014
37 #define DICE_EAP_PEAK_SPACE_OFF            0x0018
38 #define DICE_EAP_PEAK_SPACE_SZ             0x001C
39 #define DICE_EAP_NEW_ROUTING_SPACE_OFF     0x0020
40 #define DICE_EAP_NEW_ROUTING_SPACE_SZ      0x0024
41 #define DICE_EAP_NEW_STREAM_CFG_SPACE_OFF  0x0028
42 #define DICE_EAP_NEW_STREAM_CFG_SPACE_SZ   0x002C
43 #define DICE_EAP_CURR_CFG_SPACE_OFF        0x0030
44 #define DICE_EAP_CURR_CFG_SPACE_SZ         0x0034
45 #define DICE_EAP_STAND_ALONE_CFG_SPACE_OFF 0x0038
46 #define DICE_EAP_STAND_ALONE_CFG_SPACE_SZ  0x003C
47 #define DICE_EAP_APP_SPACE_OFF             0x0040
48 #define DICE_EAP_APP_SPACE_SZ              0x0044
49 #define DICE_EAP_ZERO_MARKER_1             0x0048
50
51 // CAPABILITY registers
52 #define DICE_EAP_CAPABILITY_ROUTER         0x0000
53 #define DICE_EAP_CAPABILITY_MIXER          0x0004
54 #define DICE_EAP_CAPABILITY_GENERAL        0x0008
55 #define DICE_EAP_CAPABILITY_RESERVED       0x000C
56
57 // CAPABILITY bit definitions
58 #define DICE_EAP_CAP_ROUTER_EXPOSED         0
59 #define DICE_EAP_CAP_ROUTER_READONLY        1
60 #define DICE_EAP_CAP_ROUTER_FLASHSTORED     2
61 #define DICE_EAP_CAP_ROUTER_MAXROUTES      16
62
63 #define DICE_EAP_CAP_MIXER_EXPOSED          0
64 #define DICE_EAP_CAP_MIXER_READONLY         1
65 #define DICE_EAP_CAP_MIXER_FLASHSTORED      2
66 #define DICE_EAP_CAP_MIXER_IN_DEV           4
67 #define DICE_EAP_CAP_MIXER_OUT_DEV          8
68 #define DICE_EAP_CAP_MIXER_INPUTS          16
69 #define DICE_EAP_CAP_MIXER_OUTPUTS         24
70
71 #define DICE_EAP_CAP_GENERAL_STRM_CFG_EN    0
72 #define DICE_EAP_CAP_GENERAL_FLASH_EN       1
73 #define DICE_EAP_CAP_GENERAL_PEAK_EN        2
74 #define DICE_EAP_CAP_GENERAL_MAX_TX_STREAM  4
75 #define DICE_EAP_CAP_GENERAL_MAX_RX_STREAM  8
76 #define DICE_EAP_CAP_GENERAL_STRM_CFG_FLS  12
77 #define DICE_EAP_CAP_GENERAL_CHIP          16
78
79 #define DICE_EAP_CAP_GENERAL_CHIP_DICEII    0
80 #define DICE_EAP_CAP_GENERAL_CHIP_DICEMINI  1
81 #define DICE_EAP_CAP_GENERAL_CHIP_DICEJR    2
82
83 // COMMAND registers
84 #define DICE_EAP_COMMAND_OPCODE         0x0000
85 #define DICE_EAP_COMMAND_RETVAL         0x0004
86
87 // opcodes
88 #define DICE_EAP_CMD_OPCODE_NO_OP            0x0000
89 #define DICE_EAP_CMD_OPCODE_LD_ROUTER        0x0001
90 #define DICE_EAP_CMD_OPCODE_LD_STRM_CFG      0x0002
91 #define DICE_EAP_CMD_OPCODE_LD_RTR_STRM_CFG  0x0003
92 #define DICE_EAP_CMD_OPCODE_LD_FLASH_CFG     0x0004
93 #define DICE_EAP_CMD_OPCODE_ST_FLASH_CFG     0x0005
94
95 #define DICE_EAP_CMD_OPCODE_FLAG_LD_LOW      (1U<<16)
96 #define DICE_EAP_CMD_OPCODE_FLAG_LD_MID      (1U<<17)
97 #define DICE_EAP_CMD_OPCODE_FLAG_LD_HIGH     (1U<<18)
98 #define DICE_EAP_CMD_OPCODE_FLAG_LD_EXECUTE  (1U<<31)
99
100
101 // MIXER registers
102 // TODO
103
104 // PEAK registers
105 // TODO
106
107 // NEW ROUTER registers
108 // TODO
109
110 // NEW STREAM CFG registers
111 // TODO
112
113 // CURRENT CFG registers
114 #define DICE_EAP_CURRCFG_LOW_ROUTER         0x0000
115 #define DICE_EAP_CURRCFG_LOW_STREAM         0x1000
116 #define DICE_EAP_CURRCFG_MID_ROUTER         0x2000
117 #define DICE_EAP_CURRCFG_MID_STREAM         0x3000
118 #define DICE_EAP_CURRCFG_HIGH_ROUTER        0x4000
119 #define DICE_EAP_CURRCFG_HIGH_STREAM        0x5000
120
121 #define DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_QUADS  (64)
122 #define DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_BYTES  (4*DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_QUADS)
123
124 namespace Dice {
125
126 /**
127   @brief Sources for audio hitting the router
128   */
129 enum eRouteSource {
130     eRS_AES = 0,
131     eRS_ADAT = 1,
132     eRS_Mixer = 2,
133     eRS_InS0 = 4,
134     eRS_InS1 = 5,
135     eRS_ARM = 10,
136     eRS_ARX0 = 11,
137     eRS_ARX1 = 12,
138     eRS_Muted = 15,
139     eRS_Invalid = 16,
140 };
141 /**
142   @brief Destinations for audio exiting the router
143   */
144 enum eRouteDestination {
145     eRD_AES = 0,
146     eRD_ADAT = 1,
147     eRD_Mixer0 = 2,
148     eRD_Mixer1 = 3,
149     eRD_InS0 = 4,
150     eRD_InS1 = 5,
151     eRD_ARM = 10,
152     eRD_ATX0 = 11,
153     eRD_ATX1 = 12,
154     eRD_Muted = 15,
155     eRD_Invalid = 16,
156 };
157
158 /**
159   @brief represents the EAP interface available on some devices
160
161   When available, the mixer and router are visible. This class is also the base for custom
162   implementations of EAP extensions.
163   */
164 class EAP : public Control::Container
165 {
166 public:
167     /**
168       @brief Command status
169       */
170     enum eWaitReturn {
171         eWR_Error,
172         eWR_Timeout,
173         eWR_Busy,
174         eWR_Done,
175     };
176     /**
177       @brief Constants for the EAP spaces
178
179       @see offsetGen for the calculation of the real offsets.
180       */
181     enum eRegBase {
182         eRT_Base,
183         eRT_Capability,
184         eRT_Command,
185         eRT_Mixer,
186         eRT_Peak,
187         eRT_NewRouting,
188         eRT_NewStreamCfg,
189         eRT_CurrentCfg,
190         eRT_Standalone,
191         eRT_Application,
192         eRT_None,
193     };
194
195 private:
196
197     /**
198       @brief Description of the routing in the hardware
199       */
200     class RouterConfig {
201     private:
202         friend class Dice::EAP;
203         RouterConfig(EAP &);
204         RouterConfig(EAP &, enum eRegBase, unsigned int offset);
205         virtual ~RouterConfig();
206
207     public:
208         struct Route
209         {
210             enum eRouteSource src;
211             int srcChannel;
212             enum eRouteDestination dst;
213             int dstChannel;
214             int peak;
215         };
216         typedef std::vector<RouterConfig::Route> RouteVector;
217         typedef std::vector<RouterConfig::Route>::iterator RouteVectorIterator;
218
219         virtual bool read() {return read(m_base, m_offset);};
220         virtual bool write() {return write(m_base, m_offset);};
221         virtual bool read(enum eRegBase b, unsigned offset);
222         virtual bool write(enum eRegBase b, unsigned offset);
223         virtual void show();
224
225         bool insertRoute(struct Route r)
226             {return insertRoute(r, m_routes.size());};
227         bool insertRoute(struct Route r, unsigned int index);
228         bool replaceRoute(unsigned int old_index, struct Route new_route);
229         bool replaceRoute(struct Route old_route, struct Route new_route);
230         bool removeRoute(struct Route r);
231         bool removeRoute(unsigned int index);
232         int getRouteIndex(struct Route r);
233         struct Route getRoute(unsigned int index);
234
235         unsigned int getNbRoutes() {return m_routes.size();};
236
237         struct Route getRouteForDestination(enum eRouteDestination dst, int channel);
238         RouteVector getRoutesForSource(enum eRouteSource src, int channel);
239
240         struct Route decodeRoute(uint32_t val);
241         uint32_t encodeRoute(struct Route r);
242     public:
243         static enum eRouteDestination intToRouteDestination(int);
244         static enum eRouteSource intToRouteSource(int);
245     protected:
246         EAP &m_eap;
247         enum eRegBase m_base;
248         unsigned int m_offset;
249         RouteVector m_routes;
250     protected:
251         DECLARE_DEBUG_MODULE_REFERENCE;
252     };
253
254     /**
255       the peak space is a special version of a router config
256       */
257     class PeakSpace : public RouterConfig {
258     private:
259         friend class Dice::EAP;
260         PeakSpace(EAP &p) : RouterConfig(p, eRT_Peak, 0) {};
261         virtual ~PeakSpace() {};
262
263     public:
264         virtual bool read() {return read(m_base, m_offset);};
265         virtual bool write() {return write(m_base, m_offset);};
266         virtual bool read(enum eRegBase b, unsigned offset);
267         virtual bool write(enum eRegBase b, unsigned offset);
268         virtual void show();
269     };
270
271     /**
272       @brief Description of the streams in the hardware
273       */
274     class StreamConfig {
275     private:
276         friend class Dice::EAP;
277         StreamConfig(EAP &, enum eRegBase, unsigned int offset);
278         ~StreamConfig();
279
280     public:
281         struct ConfigBlock { // FIXME: somewhere in the DICE avdevice this is present too
282             uint32_t nb_audio;
283             uint32_t nb_midi;
284             uint32_t names[DICE_EAP_CHANNEL_CONFIG_NAMESTR_LEN_QUADS];
285             uint32_t ac3_map;
286         };
287         void showConfigBlock(struct ConfigBlock &);
288         stringlist getNamesForBlock(struct ConfigBlock &b);
289
290         bool read() {return read(m_base, m_offset);};
291         bool write() {return write(m_base, m_offset);};
292         bool read(enum eRegBase b, unsigned offset);
293         bool write(enum eRegBase b, unsigned offset);
294
295         void show();
296
297     private:
298         EAP &m_eap;
299         enum eRegBase m_base;
300         unsigned int m_offset;
301
302         uint32_t m_nb_tx;
303         uint32_t m_nb_rx;
304
305         struct ConfigBlock *m_tx_configs;
306         struct ConfigBlock *m_rx_configs;
307
308         DECLARE_DEBUG_MODULE_REFERENCE;
309     };
310
311 public:
312
313     /**
314       @brief The matrixmixer exposed
315       */
316     class Mixer : public Control::MatrixMixer {
317     public:
318         Mixer(EAP &);
319         ~Mixer();
320
321         bool init();
322         void show();
323
324         void updateNameCache();
325         /**
326          * load the coefficients from the device into the local cache
327          * @return
328          */
329         bool loadCoefficients();
330         /**
331          * Stores the coefficients from the cache to the device
332          * @return
333          */
334         bool storeCoefficients();
335
336         virtual int getRowCount( );
337         virtual int getColCount( );
338
339         virtual int canWrite( const int, const int );
340         virtual double setValue( const int, const int, const double );
341         virtual double getValue( const int, const int );
342
343         bool hasNames() const { return true; }
344         std::string getRowName( const int );
345         std::string getColName( const int );
346
347         // TODO: implement connections.
348         bool canConnect() const { return false; }
349
350         // full map updates are unsupported
351         virtual bool getCoefficientMap(int &);
352         virtual bool storeCoefficientMap(int &);
353
354     private:
355         EAP &         m_eap;
356         fb_quadlet_t *m_coeff;
357
358         std::map<int, RouterConfig::Route> m_input_route_map;
359         std::map<int, RouterConfig::RouteVector> m_output_route_map;
360
361         DECLARE_DEBUG_MODULE_REFERENCE;
362     };
363
364     /**
365       @brief The router exposed
366       */
367     class Router : public Control::CrossbarRouter {
368     public:
369         Router(EAP &);
370         ~Router();
371
372         void show();
373
374         void addDestination(const std::string& name, enum eRouteDestination dstid,
375                             unsigned int base, unsigned int cnt, unsigned int offset=0);
376         void addSource(const std::string& name, enum eRouteSource srcid,
377                        unsigned int base, unsigned int cnt, unsigned int offset=0);
378
379         // per-coefficient access
380         virtual std::string getSourceName(const int);
381         virtual std::string getDestinationName(const int);
382         virtual int getSourceIndex(std::string);
383         virtual int getDestinationIndex(std::string);
384         virtual stringlist getSourceNames();
385         virtual stringlist getDestinationNames();
386
387         std::string getSourceForDestination(const std::string& dstname);
388         stringlist getDestinationsForSource(const std::string& srcname);
389
390         virtual bool canConnect(const int srcidx, const int dstidx);
391         virtual bool setConnectionState(const int srcidx, const int dstidx, const bool enable);
392         virtual bool getConnectionState(const int srcidx, const int dstidx);
393
394         virtual bool canConnect(const std::string& srcname, const std::string& dstname);
395         virtual bool setConnectionState(const std::string& srcname, const std::string& dstname, const bool enable);
396         virtual bool getConnectionState(const std::string& srcname, const std::string& dstname);
397
398         virtual bool clearAllConnections();
399
400         // peak metering support
401         virtual bool hasPeakMetering();
402         virtual double getPeakValue(const std::string& dest);
403         virtual std::map<std::string, double> getPeakValues();
404
405     private:
406         EAP &m_eap;
407         /**
408           @{
409           @brief Name-Index pairs for the sources and destinations
410
411           The index is 'artificial' and is the block/channel combination used in the dice.
412           */
413         std::map<std::string, int> m_sources;
414         std::map<std::string, int> m_destinations;
415         // @}
416
417         PeakSpace &m_peak;
418
419         DECLARE_DEBUG_MODULE_REFERENCE;
420     };
421
422 public:
423     /** constructor */
424     EAP(Device &);
425     /** destructor */
426     virtual ~EAP();
427
428     /**
429       @brief Does this device support the EAP?
430
431       When subclassing EAP, return true only on devices that actually have an EAP.
432
433       @todo Shouldn't this be inside Dice::Device?
434       */
435     static bool supportsEAP(Device &);
436
437     /**
438       @brief Initialize the EAP
439       */
440     bool init();
441
442     /// Show information about the EAP
443     void show();
444     /// Dump the first parts of the application space
445     void showApplication();
446
447     /// Restore from flash
448     bool loadFlashConfig();
449     /// Store to flash
450     bool storeFlashConfig();
451
452     /// Is the current operation still busy?
453     enum eWaitReturn operationBusy();
454     /// Block until the current operation is done
455     enum eWaitReturn waitForOperationEnd(int max_wait_time_ms = 100);
456
457     /// Update all configurations from the device
458     bool updateConfigurationCache();
459
460     /**
461       @{
462       @brief Read and write registers on the device
463       */
464     bool readReg(enum eRegBase, unsigned offset, quadlet_t *);
465     bool writeReg(enum eRegBase, unsigned offset, quadlet_t);
466     bool readRegBlock(enum eRegBase, unsigned, fb_quadlet_t *, size_t);
467     bool writeRegBlock(enum eRegBase, unsigned, fb_quadlet_t *, size_t);
468     bool readRegBlockSwapped(enum eRegBase, unsigned, fb_quadlet_t *, size_t);
469     bool writeRegBlockSwapped(enum eRegBase, unsigned, fb_quadlet_t *, size_t);
470     //@}
471
472     /** @brief Get access to the mixer */
473     Mixer*  getMixer() {return m_mixer;};
474     /** @brief Get access to the router */
475     Router* getRouter() {return m_router;};
476
477 protected:
478     /**
479       @brief Setup all the available sources
480
481       This adds the needed entries for sources to the router. The default implementation decides on
482       the chip which sources to add, subclasses should only add the sources actually usable for the
483       device.
484
485       To ease custom device support, this function is not in EAP::Router but here.
486       */
487     virtual void setupSources();
488     /**
489       @brief Setup all the available destinations
490
491       This adds the needed entries for destinations to the router. The default implementation
492       decides on the chip which destinations to add, subclasses should only add the destinations
493       actually usable for the device.
494
495       To ease custom device support, this function is not in EAP::Router but here.
496       */
497     virtual void setupDestinations();
498
499     /**
500       @brief Actually add the source
501       */
502     void addSource(const std::string name, unsigned int base, unsigned int count,
503                    enum eRouteSource srcid, unsigned int offset=0);
504     /**
505       @brief Actually add the destination
506       */
507     void addDestination(const std::string name, unsigned int base, unsigned int count,
508                         enum eRouteDestination destid, unsigned int offset=0);
509
510 private:
511     /// Return the router configuration for the current rate
512     RouterConfig * getActiveRouterConfig();
513     /// Return the stream configuration for the current rate
514     StreamConfig * getActiveStreamConfig();
515
516     /// Write a new router configuration to the device
517     bool updateRouterConfig(RouterConfig&, bool low, bool mid, bool high);
518     /// Write a new router configuration to the device
519     bool updateCurrentRouterConfig(RouterConfig&);
520     /// Write a new stream configuration to the device
521     bool updateStreamConfig(StreamConfig&, bool low, bool mid, bool high);
522     /// Write a new stream configuration to the device
523     bool updateStreamConfig(RouterConfig&, StreamConfig&, bool low, bool mid, bool high);
524
525     bool loadRouterConfig(bool low, bool mid, bool high);
526     bool loadStreamConfig(bool low, bool mid, bool high);
527     bool loadRouterAndStreamConfig(bool low, bool mid, bool high);
528
529 private:
530     bool     m_router_exposed;
531     bool     m_router_readonly;
532     bool     m_router_flashstored;
533     uint16_t m_router_nb_entries;
534
535     bool     m_mixer_exposed;
536     bool     m_mixer_readonly;
537     bool     m_mixer_flashstored;
538     uint8_t  m_mixer_tx_id;
539     uint8_t  m_mixer_rx_id;
540     uint8_t  m_mixer_nb_tx;
541     uint8_t  m_mixer_nb_rx;
542
543     bool     m_general_support_dynstream;
544     bool     m_general_support_flash;
545     bool     m_general_peak_enabled;
546     uint8_t  m_general_max_tx;
547     uint8_t  m_general_max_rx;
548     bool     m_general_stream_cfg_stored;
549     uint16_t m_general_chip;
550
551     bool commandHelper(fb_quadlet_t cmd);
552
553     /// Calculate the real offset for the different spaces
554     fb_nodeaddr_t offsetGen(enum eRegBase, unsigned, size_t);
555
556 private:
557     Device & m_device;
558     Mixer*   m_mixer;
559     Router*  m_router;
560     RouterConfig m_current_cfg_routing_low;
561     RouterConfig m_current_cfg_routing_mid;
562     RouterConfig m_current_cfg_routing_high;
563     StreamConfig m_current_cfg_stream_low;
564     StreamConfig m_current_cfg_stream_mid;
565     StreamConfig m_current_cfg_stream_high;
566
567     fb_quadlet_t m_capability_offset;
568     fb_quadlet_t m_capability_size;
569     fb_quadlet_t m_cmd_offset;
570     fb_quadlet_t m_cmd_size;
571     fb_quadlet_t m_mixer_offset;
572     fb_quadlet_t m_mixer_size;
573     fb_quadlet_t m_peak_offset;
574     fb_quadlet_t m_peak_size;
575     fb_quadlet_t m_new_routing_offset;
576     fb_quadlet_t m_new_routing_size;
577     fb_quadlet_t m_new_stream_cfg_offset;
578     fb_quadlet_t m_new_stream_cfg_size;
579     fb_quadlet_t m_curr_cfg_offset;
580     fb_quadlet_t m_curr_cfg_size;
581     fb_quadlet_t m_standalone_offset;
582     fb_quadlet_t m_standalone_size;
583     fb_quadlet_t m_app_offset;
584     fb_quadlet_t m_app_size;
585
586 protected:
587     DECLARE_DEBUG_MODULE;
588 };
589
590 };
591
592 #endif // __DICE_EAP_H
Note: See TracBrowser for help on using the browser.