root/trunk/libffado/src/motu/motu_avdevice.cpp

Revision 899, 36.8 kB (checked in by wagi, 14 years ago)

fix typo

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  * Copyright (C) 2005-2008 by Jonathan Woithe
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 2 of the License, or
13  * (at your option) version 3 of the License.
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 #include "motu/motu_avdevice.h"
26
27 #include "libieee1394/configrom.h"
28 #include "libieee1394/ieee1394service.h"
29
30 #include "libavc/avc_definitions.h"
31
32 #include "debugmodule/debugmodule.h"
33
34 #include "libstreaming/motu/MotuReceiveStreamProcessor.h"
35 #include "libstreaming/motu/MotuTransmitStreamProcessor.h"
36 #include "libstreaming/motu/MotuPort.h"
37
38 #include "libutil/DelayLockedLoop.h"
39 #include "libutil/Time.h"
40
41 #include <string>
42 #include <stdint.h>
43 #include <assert.h>
44 #include <netinet/in.h>
45 #include <iostream>
46 #include <sstream>
47
48 #include <libraw1394/csr.h>
49
50 namespace Motu {
51
52 // to define the supported devices
53 static VendorModelEntry supportedDeviceList[] =
54 {
55 //  {vendor_id, model_id, unit_version, unit_specifier_id, model, vendor_name,model_name}
56     {FW_VENDORID_MOTU, 0, 0x00000003, 0x000001f2, MOTUFW_MODEL_828mkII, "MOTU", "828MkII"},
57     {FW_VENDORID_MOTU, 0, 0x00000009, 0x000001f2, MOTUFW_MODEL_TRAVELER, "MOTU", "Traveler"},
58     {FW_VENDORID_MOTU, 0, 0x0000000d, 0x000001f2, MOTUFW_MODEL_ULTRALITE, "MOTU", "UltraLite"},
59     {FW_VENDORID_MOTU, 0, 0x0000000f, 0x000001f2, MOTUFW_MODEL_8PRE, "MOTU", "8pre"},
60     {FW_VENDORID_MOTU, 0, 0x00000001, 0x000001f2, MOTUFW_MODEL_828MkI, "MOTU", "828MkI"},
61 };
62
63 // Ports declarations
64 const PortEntry Ports_828MKI[] =
65 {
66     {"Analog1", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 10},
67     {"Analog2", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 13},
68     {"Analog3", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 16},
69     {"Analog4", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 19},
70     {"Analog5", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 22},
71     {"Analog6", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 25},
72     {"Analog7", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 28},
73     {"Analog8", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 31},
74     {"SPDIF1", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 34},
75     {"SPDIF2", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 37},
76     {"ADAT1", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 40},
77     {"ADAT2", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 43},
78     {"ADAT3", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 46},
79     {"ADAT4", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 49},
80     {"ADAT5", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x|MOTUFW_PA_OPTICAL_ADAT, 52},
81     {"ADAT6", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x|MOTUFW_PA_OPTICAL_ADAT, 55},
82     {"ADAT7", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x|MOTUFW_PA_OPTICAL_ADAT, 58},
83     {"ADAT8", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x|MOTUFW_PA_OPTICAL_ADAT, 61},
84 };
85
86 const PortEntry Ports_828MKII[] =
87 {
88     {"Main-L", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 40},
89     {"Main-R", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 43},
90     {"Mix-L", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 10},
91     {"Mix-R", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 13},
92     {"Analog1", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 16},
93     {"Analog2", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 19},
94     {"Analog3", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 22},
95     {"Analog4", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 25},
96     {"Analog5", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 28},
97     {"Analog6", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 31},
98     {"Analog7", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 34},
99     {"Analog8", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 37},
100     {"Phones-L", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 10},
101     {"Phones-R", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 13},
102     {"Mic1", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 40},
103     {"Mic2", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 43},
104     {"SPDIF1", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 46},
105     {"SPDIF2", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 49},
106     {"ADAT1", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 52},
107     {"ADAT2", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 55},
108     {"ADAT3", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 58},
109     {"ADAT4", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 61},
110     {"ADAT5", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x|MOTUFW_PA_OPTICAL_ADAT, 63},
111     {"ADAT6", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x|MOTUFW_PA_OPTICAL_ADAT, 66},
112     {"ADAT7", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x|MOTUFW_PA_OPTICAL_ADAT, 69},
113     {"ADAT8", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x|MOTUFW_PA_OPTICAL_ADAT, 72},
114 };
115
116 const PortEntry Ports_TRAVELER[] =
117 {
118     {"Mix-L", MOTUFW_DIR_IN, MOTUFW_PA_RATE_1x2x|MOTUFW_PA_OPTICAL_ANY, 10},
119     {"Mix-R", MOTUFW_DIR_IN, MOTUFW_PA_RATE_1x2x|MOTUFW_PA_OPTICAL_ANY, 13},
120     {"Phones-L", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_1x2x|MOTUFW_PA_OPTICAL_ANY, 10},
121     {"Phones-R", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_1x2x|MOTUFW_PA_OPTICAL_ANY, 13},
122     {"Analog1", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 16},
123     {"Analog2", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 19},
124     {"Analog3", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 22},
125     {"Analog4", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 25},
126     {"Analog5", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 28},
127     {"Analog6", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 31},
128     {"Analog7", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 34},
129     {"Analog8", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 37},
130     {"AES/EBU1", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x2x|MOTUFW_PA_OPTICAL_ANY, 40},
131     {"AES/EBU2", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x2x|MOTUFW_PA_OPTICAL_ANY, 43},
132     {"SPDIF1", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x2x|MOTUFW_PA_OPTICAL_OFF|MOTUFW_PA_OPTICAL_ADAT, 46},
133     {"SPDIF2", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x2x|MOTUFW_PA_OPTICAL_OFF|MOTUFW_PA_OPTICAL_ADAT, 49},
134     {"Toslink1", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x2x|MOTUFW_PA_OPTICAL_TOSLINK, 46},
135     {"Toslink2", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x2x|MOTUFW_PA_OPTICAL_TOSLINK, 49},
136     {"ADAT1", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x2x|MOTUFW_PA_OPTICAL_ADAT, 52},
137     {"ADAT2", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x2x|MOTUFW_PA_OPTICAL_ADAT, 55},
138     {"ADAT3", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x2x|MOTUFW_PA_OPTICAL_ADAT, 58},
139     {"ADAT4", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x2x|MOTUFW_PA_OPTICAL_ADAT, 61},
140     {"ADAT5", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x|MOTUFW_PA_OPTICAL_ADAT, 63},
141     {"ADAT6", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x|MOTUFW_PA_OPTICAL_ADAT, 66},
142     {"ADAT7", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x|MOTUFW_PA_OPTICAL_ADAT, 69},
143     {"ADAT8", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_1x|MOTUFW_PA_OPTICAL_ADAT, 72},
144 };
145
146 const PortEntry Ports_ULTRALITE[] =
147 {
148     {"Main-L", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 40},
149     {"Main-R", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 43},
150     {"Mix-L", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 10},
151     {"Mix-R", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 13},
152     {"Mic1", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 16},
153     {"Mic2", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 19},
154     {"Analog1", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 16},
155     {"Analog2", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 19},
156     {"Analog3", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 22},
157     {"Analog4", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 25},
158     {"Analog5", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 28},
159     {"Analog6", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 31},
160     {"Analog7", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 34},
161     {"Analog8", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 37},
162     {"Phones-L", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 10},
163     {"Phones-R", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 13},
164     {"SPDIF1", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 46},
165     {"SPDIF2", MOTUFW_DIR_INOUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 49},
166 };
167
168 const PortEntry Ports_8PRE[] =
169 {
170     {"Analog1", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 16},
171     {"Analog2", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 19},
172     {"Analog3", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 22},
173     {"Analog4", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 25},
174     {"Analog5", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 28},
175     {"Analog6", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 31},
176     {"Analog7", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 34},
177     {"Analog8", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 37},
178     {"Mix-L", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 10},
179     {"Mix-R", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 13},
180     {"Main-L", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 16},
181     {"Main-R", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 19},
182     {"Phones-L", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 10},
183     {"Phones-R", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ANY, 13},
184     {"ADAT1", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 40},
185     {"ADAT1", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 22},
186     {"ADAT2", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 43},
187     {"ADAT2", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 25},
188     {"ADAT3", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 46},
189     {"ADAT3", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 28},
190     {"ADAT4", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 49},
191     {"ADAT4", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 31},
192     {"ADAT5", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 52},
193     {"ADAT5", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 34},
194     {"ADAT6", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 55},
195     {"ADAT6", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 37},
196     {"ADAT7", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 58},
197     {"ADAT7", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 40},
198     {"ADAT8", MOTUFW_DIR_IN, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 61},
199     {"ADAT8", MOTUFW_DIR_OUT, MOTUFW_PA_RATE_ANY|MOTUFW_PA_OPTICAL_ADAT, 43},
200 };
201
202 const DevicePropertyEntry DevicesProperty[] = {
203 //  { Ports_map,       sizeof( Ports_map ),        MaxSR },
204     { Ports_828MKI,    sizeof( Ports_828MKI ),     48000 },
205     { Ports_828MKII,   sizeof( Ports_828MKII ),    96000 },
206     { Ports_TRAVELER,  sizeof( Ports_TRAVELER ),  192000 },
207     { Ports_ULTRALITE, sizeof( Ports_ULTRALITE ),  96000 },
208     { Ports_8PRE,      sizeof( Ports_8PRE ),       96000 },
209 };
210
211 MotuDevice::MotuDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
212     : FFADODevice( d, configRom )
213     , m_motu_model( MOTUFW_MODEL_NONE )
214     , m_iso_recv_channel ( -1 )
215     , m_iso_send_channel ( -1 )
216     , m_rx_bandwidth ( -1 )
217     , m_tx_bandwidth ( -1 )
218     , m_receiveProcessor ( 0 )
219     , m_transmitProcessor ( 0 )
220
221 {
222     debugOutput( DEBUG_LEVEL_VERBOSE, "Created Motu::MotuDevice (NodeID %d)\n",
223                  getConfigRom().getNodeId() );
224
225 }
226
227 MotuDevice::~MotuDevice()
228 {
229     delete m_receiveProcessor;
230     delete m_transmitProcessor;
231
232     // Free ieee1394 bus resources if they have been allocated
233     if (m_iso_recv_channel>=0 && !get1394Service().freeIsoChannel(m_iso_recv_channel)) {
234         debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free recv iso channel %d\n", m_iso_recv_channel);
235     }
236     if (m_iso_send_channel>=0 && !get1394Service().freeIsoChannel(m_iso_send_channel)) {
237         debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free send iso channel %d\n", m_iso_send_channel);
238     }
239 }
240
241 bool
242 MotuDevice::probe( ConfigRom& configRom )
243 {
244     unsigned int vendorId = configRom.getNodeVendorId();
245 //     unsigned int modelId = configRom.getModelId();
246     unsigned int unitVersion = configRom.getUnitVersion();
247     unsigned int unitSpecifierId = configRom.getUnitSpecifierId();
248
249     for ( unsigned int i = 0;
250           i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) );
251           ++i )
252     {
253         if ( ( supportedDeviceList[i].vendor_id == vendorId )
254 //              && ( supportedDeviceList[i].model_id == modelId )
255              && ( supportedDeviceList[i].unit_version == unitVersion )
256              && ( supportedDeviceList[i].unit_specifier_id == unitSpecifierId )
257            )
258         {
259             return true;
260         }
261     }
262
263     return false;
264 }
265
266 FFADODevice *
267 MotuDevice::createDevice(DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
268 {
269     return new MotuDevice(d, configRom);
270 }
271
272 bool
273 MotuDevice::discover()
274 {
275     unsigned int vendorId = getConfigRom().getNodeVendorId();
276 //     unsigned int modelId = getConfigRom().getModelId();
277     unsigned int unitVersion = getConfigRom().getUnitVersion();
278     unsigned int unitSpecifierId = getConfigRom().getUnitSpecifierId();
279
280     for ( unsigned int i = 0;
281           i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) );
282           ++i )
283     {
284         if ( ( supportedDeviceList[i].vendor_id == vendorId )
285 //              && ( supportedDeviceList[i].model_id == modelId )
286              && ( supportedDeviceList[i].unit_version == unitVersion )
287              && ( supportedDeviceList[i].unit_specifier_id == unitSpecifierId )
288            )
289         {
290             m_model = &(supportedDeviceList[i]);
291             m_motu_model=supportedDeviceList[i].model;
292         }
293     }
294
295     if (m_model != NULL) {
296         debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
297                 m_model->vendor_name, m_model->model_name);
298         return true;
299     }
300
301     return false;
302 }
303
304 int
305 MotuDevice::getSamplingFrequency( ) {
306 /*
307  * Retrieve the current sample rate from the MOTU device.
308  */
309     quadlet_t q = ReadRegister(MOTUFW_REG_CLK_CTRL);
310     int rate = 0;
311
312     switch (q & MOTUFW_RATE_BASE_MASK) {
313         case MOTUFW_RATE_BASE_44100:
314             rate = 44100;
315             break;
316         case MOTUFW_RATE_BASE_48000:
317             rate = 48000;
318             break;
319     }
320     switch (q & MOTUFW_RATE_MULTIPLIER_MASK) {
321         case MOTUFW_RATE_MULTIPLIER_2X:
322             rate *= 2;
323             break;
324         case MOTUFW_RATE_MULTIPLIER_4X:
325             rate *= 4;
326             break;
327     }
328     return rate;
329 }
330
331 int
332 MotuDevice::getConfigurationId()
333 {
334     return 0;
335 }
336
337 bool
338 MotuDevice::setSamplingFrequency( int samplingFrequency )
339 {
340 /*
341  * Set the MOTU device's samplerate.
342  */
343     char *src_name;
344     quadlet_t q, new_rate=0;
345     int i, supported=true, cancel_adat=false;
346
347     if ( samplingFrequency > DevicesProperty[m_motu_model-1].MaxSampleRate )
348        return false;
349
350     switch ( samplingFrequency ) {
351         case 22050:
352         case 24000:
353         case 32000:
354             supported=false;
355             break;
356         case 44100:
357             new_rate = MOTUFW_RATE_BASE_44100 | MOTUFW_RATE_MULTIPLIER_1X;
358             break;
359         case 48000:
360             new_rate = MOTUFW_RATE_BASE_48000 | MOTUFW_RATE_MULTIPLIER_1X;
361             break;
362         case 88200:
363             new_rate = MOTUFW_RATE_BASE_44100 | MOTUFW_RATE_MULTIPLIER_2X;
364             break;
365         case 96000:
366             new_rate = MOTUFW_RATE_BASE_48000 | MOTUFW_RATE_MULTIPLIER_2X;
367             break;
368         case 176400:
369             new_rate = MOTUFW_RATE_BASE_44100 | MOTUFW_RATE_MULTIPLIER_4X;
370             cancel_adat = true;  // current ADAT protocol doesn't support sample rate > 96000
371             break;
372         case 192000:
373             new_rate = MOTUFW_RATE_BASE_48000 | MOTUFW_RATE_MULTIPLIER_4X;
374             cancel_adat = true;
375             break;
376         default:
377             supported=false;
378     }
379
380     // Update the clock control register.  FIXME: while this is now rather
381     // comprehensive there may still be a need to manipulate MOTUFW_REG_CLK_CTRL
382     // a little more than we do.
383     if (supported) {
384         quadlet_t value=ReadRegister(MOTUFW_REG_CLK_CTRL);
385
386         // If optical port must be disabled (because a 4x sample rate has
387         // been selected) then do so before changing the sample rate.  At
388         // this stage it will be up to the user to re-enable the optical
389         // port if the sample rate is set to a 1x or 2x rate later.
390         if (cancel_adat) {
391             setOpticalMode(MOTUFW_DIR_INOUT, MOTUFW_OPTICAL_MODE_OFF);
392         }
393
394         value &= ~(MOTUFW_RATE_BASE_MASK|MOTUFW_RATE_MULTIPLIER_MASK);
395         value |= new_rate;
396
397         // In other OSes bit 26 of MOTUFW_REG_CLK_CTRL always seems
398         // to be set when this register is written to although the
399         // reason isn't currently known.  When we set it, it appears
400         // to prevent output being produced so we'll leave it unset
401         // until we work out what's going on.  Other systems write
402         // to MOTUFW_REG_CLK_CTRL multiple times, so that may be
403         // part of the mystery.
404         //   value |= 0x04000000;
405         if (WriteRegister(MOTUFW_REG_CLK_CTRL, value) == 0) {
406             supported=true;
407         } else {
408             supported=false;
409         }
410         // A write to the rate/clock control register requires the
411         // textual name of the current clock source be sent to the
412         // clock source name registers.
413         switch (value & MOTUFW_CLKSRC_MASK) {
414             case MOTUFW_CLKSRC_INTERNAL:
415                 src_name = "Internal        ";
416                 break;
417             case MOTUFW_CLKSRC_ADAT_OPTICAL:
418                 src_name = "ADAT Optical    ";
419                 break;
420             case MOTUFW_CLKSRC_SPDIF_TOSLINK:
421                 if (getOpticalMode(MOTUFW_DIR_IN)  == MOTUFW_OPTICAL_MODE_TOSLINK)
422                     src_name = "TOSLink         ";
423                 else
424                     src_name = "SPDIF           ";
425                 break;
426             case MOTUFW_CLKSRC_SMTPE:
427                 src_name = "SMPTE           ";
428                 break;
429             case MOTUFW_CLKSRC_WORDCLOCK:
430                 src_name = "Word Clock In   ";
431                 break;
432             case MOTUFW_CLKSRC_ADAT_9PIN:
433                 src_name = "ADAT 9-pin      ";
434                 break;
435             case MOTUFW_CLKSRC_AES_EBU:
436                 src_name = "AES-EBU         ";
437                 break;
438             default:
439                 src_name = "Unknown         ";
440         }
441         for (i=0; i<16; i+=4) {
442             q = (src_name[i]<<24) | (src_name[i+1]<<16) |
443                 (src_name[i+2]<<8) | src_name[i+3];
444             WriteRegister(MOTUFW_REG_CLKSRC_NAME0+i, q);
445         }
446     }
447     return supported;
448 }
449
450 FFADODevice::ClockSourceVector
451 MotuDevice::getSupportedClockSources() {
452     FFADODevice::ClockSourceVector r;
453     return r;
454 }
455
456 bool
457 MotuDevice::setActiveClockSource(ClockSource s) {
458     return false;
459 }
460
461 FFADODevice::ClockSource
462 MotuDevice::getActiveClockSource() {
463     ClockSource s;
464     return s;
465 }
466
467 bool
468 MotuDevice::lock() {
469
470     return true;
471 }
472
473
474 bool
475 MotuDevice::unlock() {
476
477     return true;
478 }
479
480 void
481 MotuDevice::showDevice()
482 {
483     debugOutput(DEBUG_LEVEL_VERBOSE,
484         "%s %s at node %d\n", m_model->vendor_name, m_model->model_name,
485         getNodeId());
486 }
487
488 bool
489 MotuDevice::prepare() {
490
491     int samp_freq = getSamplingFrequency();
492     unsigned int optical_in_mode = getOpticalMode(MOTUFW_DIR_IN);
493     unsigned int optical_out_mode = getOpticalMode(MOTUFW_DIR_OUT);
494     unsigned int event_size_in = getEventSize(MOTUFW_DIR_IN);
495     unsigned int event_size_out= getEventSize(MOTUFW_DIR_OUT);
496
497     debugOutput(DEBUG_LEVEL_NORMAL, "Preparing MotuDevice...\n" );
498
499     // Allocate bandwidth if not previously done.
500     // FIXME: The bandwidth allocation calculation can probably be
501     // refined somewhat since this is currently based on a rudimentary
502     // understanding of the ieee1394 iso protocol.
503     // Currently we assume the following.
504     //   * Ack/iso gap = 0.05 us
505     //   * DATA_PREFIX = 0.16 us
506     //   * DATA_END    = 0.26 us
507     // These numbers are the worst-case figures given in the ieee1394
508     // standard.  This gives approximately 0.5 us of overheads per packet -
509     // around 25 bandwidth allocation units (from the ieee1394 standard 1
510     // bandwidth allocation unit is 125/6144 us).  We further assume the
511     // MOTU is running at S400 (which it should be) so one allocation unit
512     // is equivalent to 1 transmitted byte; thus the bandwidth allocation
513     // required for the packets themselves is just the size of the packet.
514     // We used to allocate based on the maximum packet size (1160 bytes at
515     // 192 kHz for the traveler) but now do this based on the actual device
516     // state by utilising the result from getEventSize() and remembering
517     // that each packet has an 8 byte CIP header.  Note that bandwidth is
518     // allocated on a *per stream* basis - it must be allocated for both the
519     // transmit and receive streams.  While most MOTU modules are close to
520     // symmetric in terms of the number of in/out channels there are
521     // exceptions, so we deal with receive and transmit bandwidth separately.
522     signed int n_events_per_packet = samp_freq<=48000?8:(samp_freq<=96000?16:32);
523     m_rx_bandwidth = 25 + (n_events_per_packet*event_size_in);
524     m_tx_bandwidth = 25 + (n_events_per_packet*event_size_out);
525
526     // Assign iso channels if not already done
527     if (m_iso_recv_channel < 0)
528         m_iso_recv_channel = get1394Service().allocateIsoChannelGeneric(m_rx_bandwidth);
529
530     if (m_iso_send_channel < 0)
531         m_iso_send_channel = get1394Service().allocateIsoChannelGeneric(m_tx_bandwidth);
532
533     debugOutput(DEBUG_LEVEL_VERBOSE, "recv channel = %d, send channel = %d\n",
534         m_iso_recv_channel, m_iso_send_channel);
535
536     if (m_iso_recv_channel<0 || m_iso_send_channel<0) {
537         // be nice and deallocate
538         if (m_iso_recv_channel >= 0)
539             get1394Service().freeIsoChannel(m_iso_recv_channel);
540         if (m_iso_send_channel >= 0)
541             get1394Service().freeIsoChannel(m_iso_send_channel);
542
543         debugFatal("Could not allocate iso channels!\n");
544         return false;
545     }
546
547     m_receiveProcessor=new Streaming::MotuReceiveStreamProcessor(*this, event_size_in);
548
549     // The first thing is to initialize the processor.  This creates the
550     // data structures.
551     if(!m_receiveProcessor->init()) {
552         debugFatal("Could not initialize receive processor!\n");
553         return false;
554     }
555     m_receiveProcessor->setVerboseLevel(getDebugLevel());
556
557     // Now we add ports to the processor
558     debugOutput(DEBUG_LEVEL_VERBOSE,"Adding ports to receive processor\n");
559
560     char *buff;
561     Streaming::Port *p=NULL;
562
563     // retrieve the ID
564     std::string id=std::string("dev?");
565     if(!getOption("id", id)) {
566         debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n");
567     }
568
569     // Add audio capture ports
570     if (!addDirPorts(Streaming::Port::E_Capture, samp_freq, optical_in_mode)) {
571         return false;
572     }
573
574     // Add MIDI port.  The MOTU only has one MIDI input port, with each
575     // MIDI byte sent using a 3 byte sequence starting at byte 4 of the
576     // event data.
577     asprintf(&buff,"%s_cap_MIDI0",id.c_str());
578     p = new Streaming::MotuMidiPort(*m_receiveProcessor, buff,
579         Streaming::Port::E_Capture, 4);
580     if (!p) {
581         debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n", buff);
582     }
583     free(buff);
584
585     // example of adding an control port:
586 //    asprintf(&buff,"%s_cap_%s",id.c_str(),"myportnamehere");
587 //    p=new Streaming::MotuControlPort(
588 //            buff,
589 //            Streaming::Port::E_Capture,
590 //            0 // you can add all other port specific stuff you
591 //              // need to pass by extending MotuXXXPort and MotuPortInfo
592 //    );
593 //    free(buff);
594 //
595 //    if (!p) {
596 //        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",buff);
597 //    } else {
598 //
599 //        if (!m_receiveProcessor->addPort(p)) {
600 //            debugWarning("Could not register port with stream processor\n");
601 //            return false;
602 //        } else {
603 //            debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",buff);
604 //        }
605 //    }
606
607     // Do the same for the transmit processor
608     m_transmitProcessor=new Streaming::MotuTransmitStreamProcessor(*this, event_size_out);
609
610     m_transmitProcessor->setVerboseLevel(getDebugLevel());
611
612     if(!m_transmitProcessor->init()) {
613         debugFatal("Could not initialize transmit processor!\n");
614         return false;
615     }
616
617     // Now we add ports to the processor
618     debugOutput(DEBUG_LEVEL_VERBOSE,"Adding ports to transmit processor\n");
619
620     // Add audio playback ports
621     if (!addDirPorts(Streaming::Port::E_Playback, samp_freq, optical_out_mode)) {
622         return false;
623     }
624
625     // Add MIDI port.  The MOTU only has one output MIDI port, with each
626     // MIDI byte transmitted using a 3 byte sequence starting at byte 4
627     // of the event data.
628     asprintf(&buff,"%s_pbk_MIDI0",id.c_str());
629     p = new Streaming::MotuMidiPort(*m_transmitProcessor, buff,
630         Streaming::Port::E_Capture, 4);
631     if (!p) {
632         debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n", buff);
633     }
634     free(buff);
635
636     // example of adding an control port:
637 //    asprintf(&buff,"%s_pbk_%s",id.c_str(),"myportnamehere");
638 //
639 //    p=new Streaming::MotuControlPort(
640 //            buff,
641 //            Streaming::Port::E_Playback,
642 //            0 // you can add all other port specific stuff you
643 //              // need to pass by extending MotuXXXPort and MotuPortInfo
644 //    );
645 //    free(buff);
646 //
647 //    if (!p) {
648 //        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",buff);
649 //    } else {
650 //        if (!m_transmitProcessor->addPort(p)) {
651 //            debugWarning("Could not register port with stream processor\n");
652 //            return false;
653 //        } else {
654 //            debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",buff);
655 //        }
656 //    }
657
658     return true;
659 }
660
661 int
662 MotuDevice::getStreamCount() {
663      return 2; // one receive, one transmit
664 }
665
666 Streaming::StreamProcessor *
667 MotuDevice::getStreamProcessorByIndex(int i) {
668     switch (i) {
669     case 0:
670         return m_receiveProcessor;
671     case 1:
672          return m_transmitProcessor;
673     default:
674         return NULL;
675     }
676     return 0;
677 }
678
679 bool
680 MotuDevice::startStreamByIndex(int i) {
681
682 quadlet_t isoctrl = ReadRegister(MOTUFW_REG_ISOCTRL);
683
684     // NOTE: this assumes that you have two streams
685     switch (i) {
686     case 0:
687         // TODO: do the stuff that is nescessary to make the device
688         // receive a stream
689
690         // Set the streamprocessor channel to the one obtained by
691         // the connection management
692         m_receiveProcessor->setChannel(m_iso_recv_channel);
693
694         // Mask out current transmit settings of the MOTU and replace
695         // with new ones.  Turn bit 24 on to enable changes to the
696         // MOTU's iso transmit settings when the iso control register
697         // is written.  Bit 23 enables iso transmit from the MOTU.
698         isoctrl &= 0xff00ffff;
699         isoctrl |= (m_iso_recv_channel << 16);
700         isoctrl |= 0x00c00000;
701         WriteRegister(MOTUFW_REG_ISOCTRL, isoctrl);
702         break;
703     case 1:
704         // TODO: do the stuff that is nescessary to make the device
705         // transmit a stream
706
707         // Set the streamprocessor channel to the one obtained by
708         // the connection management
709         m_transmitProcessor->setChannel(m_iso_send_channel);
710
711         // Mask out current receive settings of the MOTU and replace
712         // with new ones.  Turn bit 31 on to enable changes to the
713         // MOTU's iso receive settings when the iso control register
714         // is written.  Bit 30 enables iso receive by the MOTU.
715         isoctrl &= 0x00ffffff;
716         isoctrl |= (m_iso_send_channel << 24);
717         isoctrl |= 0xc0000000;
718         WriteRegister(MOTUFW_REG_ISOCTRL, isoctrl);
719         break;
720
721     default: // Invalid stream index
722         return false;
723     }
724
725     return true;
726 }
727
728 bool
729 MotuDevice::stopStreamByIndex(int i) {
730
731 quadlet_t isoctrl = ReadRegister(MOTUFW_REG_ISOCTRL);
732
733     // TODO: connection management: break connection
734     // cfr the start function
735
736     // NOTE: this assumes that you have two streams
737     switch (i) {
738     case 0:
739         // Turn bit 22 off to disable iso send by the MOTU.  Turn
740         // bit 23 on to enable changes to the MOTU's iso transmit
741         // settings when the iso control register is written.
742         isoctrl &= 0xffbfffff;
743         isoctrl |= 0x00800000;
744         WriteRegister(MOTUFW_REG_ISOCTRL, isoctrl);
745         break;
746     case 1:
747         // Turn bit 30 off to disable iso receive by the MOTU.  Turn
748         // bit 31 on to enable changes to the MOTU's iso receive
749         // settings when the iso control register is written.
750         isoctrl &= 0xbfffffff;
751         isoctrl |= 0x80000000;
752         WriteRegister(MOTUFW_REG_ISOCTRL, isoctrl);
753         break;
754
755     default: // Invalid stream index
756         return false;
757     }
758
759     return true;
760 }
761
762 signed int MotuDevice::getIsoRecvChannel(void) {
763     return m_iso_recv_channel;
764 }
765
766 signed int MotuDevice::getIsoSendChannel(void) {
767     return m_iso_send_channel;
768 }
769
770 unsigned int MotuDevice::getOpticalMode(unsigned int dir) {
771     unsigned int reg = ReadRegister(MOTUFW_REG_ROUTE_PORT_CONF);
772
773 debugOutput(DEBUG_LEVEL_VERBOSE, "optical mode: %x %x %x %x\n",dir, reg, reg & MOTUFW_OPTICAL_IN_MODE_MASK,
774 reg & MOTUFW_OPTICAL_OUT_MODE_MASK);
775
776     if (dir == MOTUFW_DIR_IN)
777         return (reg & MOTUFW_OPTICAL_IN_MODE_MASK) >> 8;
778     else
779         return (reg & MOTUFW_OPTICAL_OUT_MODE_MASK) >> 10;
780 }
781
782 signed int MotuDevice::setOpticalMode(unsigned int dir, unsigned int mode) {
783     unsigned int reg = ReadRegister(MOTUFW_REG_ROUTE_PORT_CONF);
784     unsigned int opt_ctrl = 0x0000002;
785
786     // Set up the optical control register value according to the current
787     // optical port modes.  At this stage it's not completely understood
788     // what the "Optical control" register does, so the values it's set to
789     // are more or less "magic" numbers.
790     if (reg & MOTUFW_OPTICAL_IN_MODE_MASK != (MOTUFW_OPTICAL_MODE_ADAT<<8))
791         opt_ctrl |= 0x00000080;
792     if (reg & MOTUFW_OPTICAL_OUT_MODE_MASK != (MOTUFW_OPTICAL_MODE_ADAT<<10))
793         opt_ctrl |= 0x00000040;
794
795     if (mode & MOTUFW_DIR_IN) {
796         reg &= ~MOTUFW_OPTICAL_IN_MODE_MASK;
797         reg |= (mode << 8) & MOTUFW_OPTICAL_IN_MODE_MASK;
798         if (mode != MOTUFW_OPTICAL_MODE_ADAT)
799             opt_ctrl |= 0x00000080;
800         else
801             opt_ctrl &= ~0x00000080;
802     }
803     if (mode & MOTUFW_DIR_OUT) {
804         reg &= ~MOTUFW_OPTICAL_OUT_MODE_MASK;
805         reg |= (mode <<10) & MOTUFW_OPTICAL_OUT_MODE_MASK;
806         if (mode != MOTUFW_OPTICAL_MODE_ADAT)
807             opt_ctrl |= 0x00000040;
808         else
809             opt_ctrl &= ~0x00000040;
810     }
811
812     // FIXME: there seems to be more to it than this, but for
813     // the moment at least this seems to work.
814     WriteRegister(MOTUFW_REG_ROUTE_PORT_CONF, reg);
815     return WriteRegister(MOTUFW_REG_OPTICAL_CTRL, opt_ctrl);
816 }
817
818 signed int MotuDevice::getEventSize(unsigned int direction) {
819 //
820 // Return the size in bytes of a single event sent to (dir==MOTUFW_OUT) or
821 // from (dir==MOTUFW_IN) the MOTU as part of an iso data packet.
822 //
823 // FIXME: for performance it may turn out best to calculate the event
824 // size in setOpticalMode and cache the result in a data field.  However,
825 // as it stands this will not adapt to dynamic changes in sample rate - we'd
826 // need a setFrameRate() for that.
827 //
828 // At the very least an event consists of the SPH (4 bytes) and the control/MIDI
829 // bytes (6 bytes).
830 // Note that all audio channels are sent using 3 bytes.
831 signed int sample_rate = getSamplingFrequency();
832 signed int optical_mode = getOpticalMode(direction);
833 signed int size = 4+6;
834
835 unsigned int i;
836 unsigned int dir = direction==Streaming::Port::E_Capture?MOTUFW_DIR_IN:MOTUFW_DIR_OUT;
837 unsigned int flags = (1 << ( optical_mode + 4 ));
838
839     if ( sample_rate > 96000 )
840         flags |= MOTUFW_PA_RATE_4x;
841     else if ( sample_rate > 48000 )
842         flags |= MOTUFW_PA_RATE_2x;
843     else
844         flags |= MOTUFW_PA_RATE_1x;
845
846     for (i=0; i < ( DevicesProperty[m_motu_model-1].PortsListLength /sizeof( PortEntry ) ); i++) {
847         if (( DevicesProperty[m_motu_model-1].PortsList[i].port_dir & dir ) &&
848            ( DevicesProperty[m_motu_model-1].PortsList[i].port_flags & MOTUFW_PA_RATE_MASK & flags ) &&
849            ( DevicesProperty[m_motu_model-1].PortsList[i].port_flags & MOTUFW_PA_OPTICAL_MASK & flags )) {
850             size += 3;
851         }
852     }
853
854     // Finally round size up to the next quadlet boundary
855     return ((size+3)/4)*4;
856 }
857 /* ======================================================================= */
858
859 bool MotuDevice::addPort(Streaming::StreamProcessor *s_processor,
860   char *name, enum Streaming::Port::E_Direction direction,
861   int position, int size) {
862 /*
863  * Internal helper function to add a MOTU port to a given stream processor.
864  * This just saves the unnecessary replication of what is essentially
865  * boilerplate code.  Note that the port name is freed by this function
866  * prior to exit.
867  */
868 Streaming::Port *p=NULL;
869
870     p = new Streaming::MotuAudioPort(*s_processor, name, direction, position, size);
871
872     if (!p) {
873         debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",name);
874     }
875     free(name);
876     return true;
877 }
878 /* ======================================================================= */
879
880 bool MotuDevice::addDirPorts(
881   enum Streaming::Port::E_Direction direction,
882   unsigned int sample_rate, unsigned int optical_mode) {
883 /*
884  * Internal helper method: adds all required ports for the given direction
885  * based on the indicated sample rate and optical mode.
886  *
887  * Notes: currently ports are not created if they are disabled due to sample
888  * rate or optical mode.  However, it might be better to unconditionally
889  * create all ports and just disable those which are not active.
890  */
891 const char *mode_str = direction==Streaming::Port::E_Capture?"cap":"pbk";
892 Streaming::StreamProcessor *s_processor;
893 unsigned int i;
894 char *buff;
895 unsigned int dir = direction==Streaming::Port::E_Capture?MOTUFW_DIR_IN:MOTUFW_DIR_OUT;
896 unsigned int flags = (1 << ( optical_mode + 4 ));
897
898     if ( sample_rate > 96000 )
899         flags |= MOTUFW_PA_RATE_4x;
900     else if ( sample_rate > 48000 )
901         flags |= MOTUFW_PA_RATE_2x;
902     else
903         flags |= MOTUFW_PA_RATE_1x;
904
905     // retrieve the ID
906     std::string id=std::string("dev?");
907     if(!getOption("id", id)) {
908         debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n");
909     }
910
911     if (direction == Streaming::Port::E_Capture) {
912         s_processor = m_receiveProcessor;
913     } else {
914         s_processor = m_transmitProcessor;
915     }
916
917     for (i=0; i < ( DevicesProperty[m_motu_model-1].PortsListLength /sizeof( PortEntry ) ); i++) {
918         if (( DevicesProperty[m_motu_model-1].PortsList[i].port_dir & dir ) &&
919            ( DevicesProperty[m_motu_model-1].PortsList[i].port_flags & MOTUFW_PA_RATE_MASK & flags ) &&
920            ( DevicesProperty[m_motu_model-1].PortsList[i].port_flags & MOTUFW_PA_OPTICAL_MASK & flags )) {
921             asprintf(&buff,"%s_%s_%s" , id.c_str(), mode_str,
922               DevicesProperty[m_motu_model-1].PortsList[i].port_name);
923             if (!addPort(s_processor, buff, direction, DevicesProperty[m_motu_model-1].PortsList[i].port_offset, 0))
924                 return false;
925         }
926     }
927    
928     return true;
929 }
930 /* ======================================================================== */
931
932 unsigned int MotuDevice::ReadRegister(unsigned int reg) {
933 /*
934  * Attempts to read the requested register from the MOTU.
935  */
936
937   quadlet_t quadlet;
938
939   quadlet = 0;
940   // Note: 1394Service::read() expects a physical ID, not the node id
941   if (get1394Service().read(0xffc0 | getNodeId(), MOTUFW_BASE_ADDR+reg, 1, &quadlet) < 0) {
942     debugError("Error doing motu read from register 0x%06x\n",reg);
943   }
944
945   return ntohl(quadlet);
946 }
947
948 signed int MotuDevice::WriteRegister(unsigned int reg, quadlet_t data) {
949 /*
950  * Attempts to write the given data to the requested MOTU register.
951  */
952
953   unsigned int err = 0;
954   data = htonl(data);
955
956   // Note: 1394Service::write() expects a physical ID, not the node id
957   if (get1394Service().write(0xffc0 | getNodeId(), MOTUFW_BASE_ADDR+reg, 1, &data) < 0) {
958     err = 1;
959     debugError("Error doing motu write to register 0x%06x\n",reg);
960   }
961
962   SleepRelativeUsec(100);
963   return (err==0)?0:-1;
964 }
965
966 }
Note: See TracBrowser for help on using the browser.