root/trunk/libffado/src/ffadodevice.h

Revision 745, 13.4 kB (checked in by ppalmers, 16 years ago)

implement clock source selection for DICE EVM

Line 
1 /*
2  * Copyright (C) 2005-2007 by Daniel Wagner
3  * Copyright (C) 2005-2007 by Pieter Palmers
4  *
5  * This file is part of FFADO
6  * FFADO = Free Firewire (pro-)audio drivers for linux
7  *
8  * FFADO is based upon FreeBoB
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #ifndef FFADODEVICE_H
26 #define FFADODEVICE_H
27
28 #include "libutil/OptionContainer.h"
29 #include "libcontrol/BasicElements.h"
30
31 #include "libieee1394/vendor_model_ids.h"
32
33 #include <vector>
34 #include <string>
35
36 class ConfigRom;
37 class Ieee1394Service;
38
39 namespace Streaming {
40     class StreamProcessor;
41 }
42
43 /*!
44 @brief Base class for device support
45
46  This class should be subclassed to implement ffado support
47  for a specific device.
48
49 */
50 class FFADODevice
51     : public Util::OptionContainer,
52       public Control::Container
53 {
54 public:
55     FFADODevice( std::auto_ptr< ConfigRom >( configRom ) );
56
57     virtual ~FFADODevice();
58
59     /**
60      * @brief Compares the GUID of two FFADODevices
61      *
62      * This function compares the GUID of two FFADODevices and returns true
63      * if the GUID of @ref a is larger than the GUID of @ref b . This is intended
64      * to be used with the STL sort() algorithm.
65      *
66      * Note that GUID's are converted to integers for this.
67      *
68      * @param a pointer to first FFADODevice
69      * @param b pointer to second FFADODevice
70      *
71      * @returns true if the GUID of @ref a is larger than the GUID of @ref b .
72      */
73     static bool compareGUID( FFADODevice *a, FFADODevice *b );
74
75     /// Returns the 1394 service of the FFADO device
76     virtual Ieee1394Service& get1394Service();
77     /// Returns the ConfigRom object of the device node.
78     virtual ConfigRom& getConfigRom() const;
79
80     /**
81      * @brief Called by DeviceManager to load device model from cache.
82      *
83      * This function is called before discover in order to speed up
84      * system initializing.
85      *
86      * @returns true if device was cached and successfully loaded from cache
87      */
88     virtual bool loadFromCache();
89
90     /**
91      * @brief Called by DeviceManager to allow device driver to save a cache version
92      * of the current configuration.
93      *
94      * @returns true if caching was successful. False doesn't mean an error just,
95      * the driver was unable to store the configuration
96      */
97     virtual bool saveCache();
98
99     /**
100      * @brief This is called by the DeviceManager to create an instance of the device
101      *
102      * This function enables the FFADODevice to return a subclass of itself should that
103      * be needed. If we don't do this we'd need to know about the subclasses in the
104      * devicemanager, whilst now we don't.
105      *
106      * The function should return an instance of either the class itself or a subclass
107      * of itself.
108      *
109      * This should be overridden in any subclass.
110      *
111      * @return a new instance of the AvDevice type, NULL when unsuccessful
112      */
113     static FFADODevice * createDevice( std::auto_ptr<ConfigRom>( x ));
114
115     /**
116      * @brief This is called by the DeviceManager to discover & configure the device
117      *
118      * @return true if the device was discovered successfuly
119      */
120     virtual bool discover() = 0;
121
122     /**
123      * @brief Set the samping frequency
124      * @param samplingFrequency
125      * @return true if successful
126      */
127     virtual bool setSamplingFrequency( int samplingFrequency ) = 0;
128     /**
129      * @brief get the samplingfrequency as an integer
130      * @return the sampling frequency as integer
131      */
132     virtual int getSamplingFrequency( ) = 0;
133
134     /**
135      * @brief sync state enum
136      */
137     enum eSyncState {
138         eSS_Unknown=0,
139         eSS_Locked=1,
140         eSS_Unlocked=2,
141     };
142
143     /**
144      * @brief gets the devices current synchronization state
145      * @return the device's sync state
146      */
147     virtual enum eSyncState getSyncState( );
148
149     /**
150      * @brief clock source types
151      */
152     enum eClockSourceType {
153         eCT_Invalid,   ///> invalid entry (e.g. on error)
154         eCT_Internal,  ///> internal sync (unspecified)
155         eCT_1394Bus,   ///> Sync on the 1394 bus clock (e.g. CSP)
156         eCT_SytMatch,  ///> SYT match on incoming audio stream
157         eCT_SytStream, ///> SYT match on incoming sync stream
158         eCT_WordClock, ///> SYT on WordClock input
159         eCT_SPDIF,     ///> SYT on SPDIF input
160         eCT_ADAT,      ///> SYT on ADAT input
161         eCT_TDIF,      ///> SYT on TDIF input
162         eCT_AES,       ///> SYT on AES input
163     };
164
165     /**
166      * @brief convert the clock source type to a C string
167      * @return a C string describing the clock source type
168      */
169     static const char *ClockSourceTypeToString(enum eClockSourceType);
170
171     /**
172      * @brief Clock source identification struct
173      */
174     struct sClockSource {
175         sClockSource()
176             : type( eCT_Invalid )
177             , id( 0 )
178             , valid( false )
179             , active( false )
180             , locked( true )
181             , slipping( false )
182             , description( "" )
183         {}
184         /// indicates the type of the clock source (e.g. eCT_ADAT)
185         enum eClockSourceType type;
186         /// indicated the id of the clock source (e.g. id=1 => clocksource is ADAT_1)
187         unsigned int id;
188         /// is the clock source valid (i.e. can be selected) at this moment?
189         bool valid;
190         /// is the clock source active at this moment?
191         bool active;
192         /// is the clock source locked?
193         bool locked;
194         /// is the clock source slipping?
195         bool slipping;
196         /// description of the clock struct (optional)
197         std::string description;
198     };
199     typedef struct sClockSource ClockSource;
200
201     typedef std::vector< ClockSource > ClockSourceVector;
202     typedef std::vector< ClockSource >::iterator ClockSourceVectorIterator;
203
204     /**
205      * @brief Get the clocksources supported by this device
206      *
207      * This function returns a vector of ClockSource structures that contains
208      * one entry for every clock source supported by the device.
209      *
210      * @returns a vector of ClockSource structures
211      */
212     virtual ClockSourceVector getSupportedClockSources() = 0;
213
214
215     /**
216      * @brief Sets the active clock source of this device
217      *
218      * This function sets the clock source of the device.
219      *
220      * @returns true upon success. false upon failure.
221      */
222     virtual bool setActiveClockSource(ClockSource) = 0;
223
224     /**
225      * @brief Returns the active clock source of this device
226      *
227      * This function returns the active clock source of the device.
228      *
229      * @returns the active ClockSource
230      */
231     virtual ClockSource getActiveClockSource() = 0;
232
233     /**
234      * @brief This is called by the device manager to give the device a unique ID.
235      *
236      * The purpose of this is to allow for unique port naming
237      * in case there are multiple identical devices on the bus.
238      * Some audio API's (e.g. jack) don't work properly when the
239      * port names are not unique.
240      *
241      * Say you have two devices having a port named OutputLeft.
242      * This can cause the streaming
243      * part to present two OutputLeft ports to the audio API,
244      * which won't work. This ID will allow you to construct
245      * the port names as 'dev1_OutputLeft' and 'dev2_OutputLeft'
246      *
247      * @note Currently this is a simple integer that is equal to
248      *       the position of the device in the devicemanager's
249      *       device list. Therefore it is dependant on the order
250      *       in which the devices are detected. The side-effect
251      *       of this is that it is dependant on the bus topology
252      *       and history (e.g. busresets etc). This makes that
253      *       these ID's are not fixed to a specific physical device.
254      *       At some point, we will replaced this with a GUID based
255      *       approach, which is tied to a physical device and is
256      *       bus & time independant.
257      *
258      * @param id
259      * @return true if successful
260      */
261     bool setId(unsigned int id);
262
263     /**
264      * @brief Outputs the device configuration to stderr/stdout [debug helper]
265      *
266      * This function prints out a (detailed) description of the
267      * device detected, and its configuration.
268      */
269     virtual void showDevice();
270
271     /**
272      * @brief Lock the device
273      *
274      * This is called by the streaming layer before we start manipulating
275      * and/or using the device.
276      *
277      * It should implement the mechanisms provided by the device to
278      * make sure that no other controller claims control of the device.
279      *
280      * @return true if successful, false if not
281      */
282     virtual bool lock() = 0;
283
284     /**
285      * @brief Unlock the device
286      *
287      * This is called by the streaming layer after we finish manipulating
288      * and/or using the device.
289      *
290      * It should implement the mechanisms provided by the device to
291      * give up exclusive control of the device.
292      *
293      * @return true if successful, false if not
294      */
295     virtual bool unlock() = 0;
296
297     /**
298      * @brief Enable streaming on all 'started' streams
299      *
300      * Enables the ISO streaming on all streams that are 'started'
301      * using startStreamByIndex. This is useful to control a 'master enable'
302      * function on the device.
303      *
304      * @return true if successful
305      */
306     virtual bool enableStreaming();
307
308     /**
309      * @brief Disable streaming on all streams
310      *
311      * Disables ISO streaming on all streams.
312      * This is useful to control a 'master enable'
313      * function on the device.
314      *
315      * @return true if successful
316      */
317     virtual bool disableStreaming();
318
319     /**
320      * @brief Prepare the device
321      *
322      * This is called by the streaming layer after the configuration
323      * parameters (e.g. sample rate) are set, and before
324      * getStreamProcessor[*] functions are called.
325      *
326      * It should be used to prepare the device's streamprocessors
327      * based upon the device's current configuration. Normally
328      * the streaming layer will not change the device's configuration
329      * after calling this function.
330      *
331      * @return true if successful, false if not
332      */
333     virtual bool prepare() = 0;
334
335     /**
336      * @brief Returns the number of ISO streams implemented/used by this device
337      *
338      * Most likely this is 2 streams, i.e. one transmit stream and one
339      * receive stream. However there are devices that implement more, for
340      * example BeBoB's implement 4 streams:
341      * - 2 audio streams (1 xmit/1 recv)
342      * - 2 sync streams (1 xmit/1 recv), which are an optional sync source
343      *   for the device.
344      *
345      * @note you have to have a StreamProcessor for every stream. I.e.
346      *       getStreamProcessorByIndex(i) should return a valid StreamProcessor
347      *       for i=0 to i=getStreamCount()-1
348      *
349      * @return number of streams available (both transmit and receive)
350      */
351     virtual int getStreamCount() = 0;
352
353     /**
354      * @brief Returns the StreamProcessor object for the stream with index i
355      *
356      * @note a streamprocessor returned by getStreamProcessorByIndex(i)
357      *       cannot be the same object as one returned by
358      *       getStreamProcessorByIndex(j) if i isn't equal to j
359      * @note you cannot have two streamprocessors handling the same ISO
360      *       channel (on the same port)
361      *
362      * @param i : Stream index
363      * @pre @ref i smaller than getStreamCount()
364      * @return a StreamProcessor object if successful, NULL otherwise
365      */
366     virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i) = 0;
367
368     /**
369      * @brief starts the stream with index i
370      *
371      * This function is called by the streaming layer when this stream should
372      * be started, i.e. the device should start sending data or should be prepared to
373      * be ready to receive data.
374      *
375      * It returns the channel number that was assigned for this stream.
376      * Channel allocation should be done using the allocation functions provided by the
377      * Ieee1394Service object that is passed in the constructor.
378      *
379      * @param i : Stream index
380      * @pre @ref i smaller than getStreamCount()
381      * @return true if successful, false if not
382      */
383     virtual bool startStreamByIndex(int i) = 0;
384
385     /**
386      * @brief stops the stream with index @ref i
387      *
388      * @param i : Stream index
389      * @pre @ref i smaller than getStreamCount()
390      * @return true if successful, false if not
391      */
392     virtual bool stopStreamByIndex(int i) = 0;
393
394     /**
395      * set verbosity level
396      */
397     virtual void setVerboseLevel(int l);
398
399     /**
400      * @brief return the node id of this device
401      *
402      * @return the node id
403      */
404     int getNodeId();
405
406     /**
407      * @brief handle a bus reset
408      *
409      * Called whenever a bus reset is detected. Handle everything
410      * that has to be done to cope with a bus reset.
411      *
412      */
413     void handleBusReset();
414
415     // the Control::Container functions
416     virtual std::string getName();
417     virtual bool setName( std::string n )
418         { return false; };
419
420
421 private:
422     std::auto_ptr<ConfigRom>( m_pConfigRom );
423 protected:
424     DECLARE_DEBUG_MODULE;
425 };
426
427 #endif
Note: See TracBrowser for help on using the browser.