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

Revision 949, 38.9 kB (checked in by jwoithe, 16 years ago)

Add detection support for the 896HD (other functionality is still to be verified).
Fixed typos in some ADAT channel offsets for the Traveler and 828Mk2.

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