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

Revision 783, 36.1 kB (checked in by ppalmers, 15 years ago)

cleanup time/wait/sleep code

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