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

Revision 1234, 56.9 kB (checked in by holin, 16 years ago)

fix gcc 4.3 compile errors and some warnings (largely from Adrian Knoth)

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 "libcontrol/BasicElements.h"
42
43 #include <string>
44 #include <stdint.h>
45 #include <assert.h>
46 #include "libutil/ByteSwap.h"
47 #include <iostream>
48 #include <sstream>
49
50 #include <libraw1394/csr.h>
51
52 namespace Motu {
53
54 // Define the supported devices.  Device ordering is arbitary here.
55 static VendorModelEntry supportedDeviceList[] =
56 {
57 //  {vendor_id, model_id, unit_version, unit_specifier_id, model, vendor_name,model_name}
58     {FW_VENDORID_MOTU, 0, 0x00000003, 0x000001f2, MOTU_MODEL_828mkII, "MOTU", "828MkII"},
59     {FW_VENDORID_MOTU, 0, 0x00000009, 0x000001f2, MOTU_MODEL_TRAVELER, "MOTU", "Traveler"},
60     {FW_VENDORID_MOTU, 0, 0x0000000d, 0x000001f2, MOTU_MODEL_ULTRALITE, "MOTU", "UltraLite"},
61     {FW_VENDORID_MOTU, 0, 0x0000000f, 0x000001f2, MOTU_MODEL_8PRE, "MOTU", "8pre"},
62     {FW_VENDORID_MOTU, 0, 0x00000001, 0x000001f2, MOTU_MODEL_828MkI, "MOTU", "828MkI"},
63     {FW_VENDORID_MOTU, 0, 0x00000005, 0x000001f2, MOTU_MODEL_896HD, "MOTU", "896HD"},
64 };
65
66 // Ports declarations
67 const PortEntry Ports_828MKI[] =
68 {
69     {"Analog1", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10},
70     {"Analog2", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13},
71     {"Analog3", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16},
72     {"Analog4", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19},
73     {"Analog5", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 22},
74     {"Analog6", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 25},
75     {"Analog7", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 28},
76     {"Analog8", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 31},
77     {"SPDIF1", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 34},
78     {"SPDIF2", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 37},
79     {"ADAT1", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 40},
80     {"ADAT2", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 43},
81     {"ADAT3", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 46},
82     {"ADAT4", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 49},
83     {"ADAT5", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 52},
84     {"ADAT6", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 55},
85     {"ADAT7", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 58},
86     {"ADAT8", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 61},
87 };
88
89 const PortEntry Ports_896HD[] =
90 {
91     {"Mix-L", MOTU_DIR_IN, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 10},
92     {"Mix-R", MOTU_DIR_IN, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 13},
93     {"Phones-L", MOTU_DIR_OUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 10},
94     {"Phones-R", MOTU_DIR_OUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 13},
95     {"Analog1", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 16},
96     {"Analog1", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 10},
97     {"Analog2", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 19},
98     {"Analog2", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 13},
99     {"Analog3", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 22},
100     {"Analog3", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 16},
101     {"Analog4", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 25},
102     {"Analog4", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 19},
103     {"Analog5", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 28},
104     {"Analog5", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 22},
105     {"Analog6", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 31},
106     {"Analog6", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 25},
107     {"Analog7", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 34},
108     {"Analog7", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 28},
109     {"Analog8", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 37},
110     {"Analog8", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 31},
111     {"MainOut-L", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 40},
112     {"MainOut-R", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 43},
113     {"AES/EBU1", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 46},
114     {"AES/EBU2", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 49},
115     {"ADAT1", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 52},
116     {"ADAT2", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 55},
117     {"ADAT3", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 58},
118     {"ADAT4", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 61},
119     {"ADAT5", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 64},
120     {"ADAT6", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 67},
121     {"ADAT7", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 70},
122     {"ADAT8", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 73},
123 };
124
125 const PortEntry Ports_828MKII[] =
126 {
127     {"Main-L", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 40},
128     {"Main-R", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 43},
129     {"Mix-L", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10},
130     {"Mix-R", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13},
131     {"Analog1", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16},
132     {"Analog2", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19},
133     {"Analog3", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 22},
134     {"Analog4", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 25},
135     {"Analog5", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 28},
136     {"Analog6", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 31},
137     {"Analog7", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 34},
138     {"Analog8", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 37},
139     {"Phones-L", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10},
140     {"Phones-R", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13},
141     {"Mic1", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 40},
142     {"Mic2", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 43},
143     {"SPDIF1", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 46},
144     {"SPDIF2", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 49},
145     {"ADAT1", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 52},
146     {"ADAT2", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 55},
147     {"ADAT3", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 58},
148     {"ADAT4", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 61},
149     {"ADAT5", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 64},
150     {"ADAT6", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 67},
151     {"ADAT7", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 70},
152     {"ADAT8", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 73},
153 };
154
155 const PortEntry Ports_TRAVELER[] =
156 {
157     {"Mix-L", MOTU_DIR_IN, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 10},
158     {"Mix-R", MOTU_DIR_IN, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 13},
159     {"Phones-L", MOTU_DIR_OUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 10},
160     {"Phones-R", MOTU_DIR_OUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 13},
161     {"Analog1", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 16},
162     {"Analog1", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 10},
163     {"Analog2", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 19},
164     {"Analog2", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 13},
165     {"Analog3", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 22},
166     {"Analog3", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 16},
167     {"Analog4", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 25},
168     {"Analog4", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 19},
169     {"Analog5", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 28},
170     {"Analog5", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 22},
171     {"Analog6", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 31},
172     {"Analog6", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 25},
173     {"Analog7", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 34},
174     {"Analog7", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 28},
175     {"Analog8", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 37},
176     {"Analog8", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 31},
177     {"AES/EBU1", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 40},
178     {"AES/EBU2", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 43},
179     {"SPDIF1", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_OFF|MOTU_PA_OPTICAL_ADAT, 46},
180     {"SPDIF2", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_OFF|MOTU_PA_OPTICAL_ADAT, 49},
181     {"Toslink1", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_TOSLINK, 46},
182     {"Toslink2", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_TOSLINK, 49},
183     {"ADAT1", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 52},
184     {"ADAT2", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 55},
185     {"ADAT3", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 58},
186     {"ADAT4", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 61},
187     {"ADAT5", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 64},
188     {"ADAT6", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 67},
189     {"ADAT7", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 70},
190     {"ADAT8", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 73},
191 };
192
193 const PortEntry Ports_ULTRALITE[] =
194 {
195     {"Main-L", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 40},
196     {"Main-R", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 43},
197     {"Mix-L", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10},
198     {"Mix-R", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13},
199     {"Mic1", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16},
200     {"Mic2", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19},
201     {"Analog1", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16},
202     {"Analog2", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19},
203     {"Analog3", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 22},
204     {"Analog4", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 25},
205     {"Analog5", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 28},
206     {"Analog6", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 31},
207     {"Analog7", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 34},
208     {"Analog8", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 37},
209     {"Phones-L", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10},
210     {"Phones-R", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13},
211     {"SPDIF1", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 46},
212     {"SPDIF2", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 49},
213 };
214
215 const PortEntry Ports_8PRE[] =
216 {
217     {"Analog1", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16},
218     {"Analog2", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19},
219     {"Analog3", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 22},
220     {"Analog4", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 25},
221     {"Analog5", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 28},
222     {"Analog6", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 31},
223     {"Analog7", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 34},
224     {"Analog8", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 37},
225     {"Mix-L", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10},
226     {"Mix-R", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13},
227     {"Main-L", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16},
228     {"Main-R", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19},
229     {"Phones-L", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10},
230     {"Phones-R", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13},
231     {"ADAT1", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 40},
232     {"ADAT1", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 22},
233     {"ADAT2", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 43},
234     {"ADAT2", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 25},
235     {"ADAT3", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 46},
236     {"ADAT3", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 28},
237     {"ADAT4", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 49},
238     {"ADAT4", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 31},
239     {"ADAT5", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 52},
240     {"ADAT5", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 34},
241     {"ADAT6", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 55},
242     {"ADAT6", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 37},
243     {"ADAT7", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 58},
244     {"ADAT7", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 40},
245     {"ADAT8", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 61},
246     {"ADAT8", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 43},
247 };
248
249 // Mixer registers
250 const MixerCtrl MixerCtrls_Traveler[] = {
251     {"Mix1/Ana1_", "Mix 1 analog 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4000, },
252     {"Mix1/Ana2_", "Mix 1 analog 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x4004, },
253     {"Mix1/Ana3_", "Mix 1 analog 3 ", "", MOTU_CTRL_STD_CHANNEL, 0x4008, },
254     {"Mix1/Ana4_", "Mix 1 analog 4 ", "", MOTU_CTRL_STD_CHANNEL, 0x400c, },
255     {"Mix1/Ana5_", "Mix 1 analog 5 ", "", MOTU_CTRL_STD_CHANNEL, 0x4010, },
256     {"Mix1/Ana6_", "Mix 1 analog 6 ", "", MOTU_CTRL_STD_CHANNEL, 0x4014, },
257     {"Mix1/Ana7_", "Mix 1 analog 7 ", "", MOTU_CTRL_STD_CHANNEL, 0x4018, },
258     {"Mix1/Ana8_", "Mix 1 analog 8 ", "", MOTU_CTRL_STD_CHANNEL, 0x401c, },
259     {"Mix1/Adat1_", "Mix 1 adat 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4030, },
260     {"Mix1/Adat2_", "Mix 1 adat 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x4034, },
261     {"Mix1/Adat3_", "Mix 1 adat 3 ", "", MOTU_CTRL_STD_CHANNEL, 0x4038, },
262     {"Mix1/Adat4_", "Mix 1 adat 4 ", "", MOTU_CTRL_STD_CHANNEL, 0x403c, },
263     {"Mix1/Adat5_", "Mix 1 adat 5 ", "", MOTU_CTRL_STD_CHANNEL, 0x4040, },
264     {"Mix1/Adat6_", "Mix 1 adat 6 ", "", MOTU_CTRL_STD_CHANNEL, 0x4044, },
265     {"Mix1/Adat7_", "Mix 1 adat 7 ", "", MOTU_CTRL_STD_CHANNEL, 0x4048, },
266     {"Mix1/Adat8_", "Mix 1 adat 8 ", "", MOTU_CTRL_STD_CHANNEL, 0x404c, },
267     {"Mix1/Aes1_", "Mix 1 AES/EBU 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4020, },
268     {"Mix1/Aes2_", "Mix 1 AES/EBU 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x4024, },
269     {"Mix1/Spdif1_", "Mix 1 SPDIF 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4028, },
270     {"Mix1/Spdif2_", "Mix 1 SPDIF 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x402c, },
271
272     {"Mix1/Mix_", "Mix 1 ", "", MOTU_CTRL_STD_MIX, 0x0c20, },
273
274     /* For mic/line input controls, the "register" is the zero-based channel number */
275     {"Control/Ana1_", "Analog 1 input ", "", MOTU_CTRL_TRAVELER_MIC_INPUT_CTRLS, 0},
276     {"Control/Ana2_", "Analog 2 input ", "", MOTU_CTRL_TRAVELER_MIC_INPUT_CTRLS, 1},
277     {"Control/Ana3_", "Analog 3 input ", "", MOTU_CTRL_TRAVELER_MIC_INPUT_CTRLS, 2},
278     {"Control/Ana4_", "Analog 4 input ", "", MOTU_CTRL_TRAVELER_MIC_INPUT_CTRLS, 3},
279     {"Control/Ana5_", "Analog 5 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 4},
280     {"Control/Ana6_", "Analog 6 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 5},
281     {"Control/Ana7_", "Analog 7 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 6},
282     {"Control/Ana8_", "Analog 8 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 7},
283
284     {"Control/Phones_", "Phones source", "", MOTU_CTRL_PHONES_SRC, 0},
285
286     {"Control/OpticalIn_mode", "Optical input mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_IN},
287     {"Control/OpticalOut_mode", "Optical output mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_OUT},
288 };
289
290 // For convenience during initial testing, just make the 828MkII and 896HD
291 // use the Traveler's mixer definition.  Separate definitions for these
292 // models will come once the final mixer structure is in place.  For now
293 // it's in a state of flux and subject to significant change.
294 #define MixerCtrls_828MkII MixerCtrls_Traveler
295 #define MixerCtrls_896HD   MixerCtrls_Traveler
296
297 /* The order of DevicesProperty entries must match the numeric order of the
298  * MOTU model enumeration (EMotuModel).
299  */
300 const DevicePropertyEntry DevicesProperty[] = {
301 //  { Ports_map,       N_ELEMENTS( Ports_map ),        MaxSR },
302     { Ports_828MKII,   N_ELEMENTS( Ports_828MKII ),    96000, MixerCtrls_828MkII, N_ELEMENTS(MixerCtrls_828MkII), },
303     { Ports_TRAVELER,  N_ELEMENTS( Ports_TRAVELER ),  192000, MixerCtrls_Traveler, N_ELEMENTS(MixerCtrls_Traveler), },
304     { Ports_ULTRALITE, N_ELEMENTS( Ports_ULTRALITE ),  96000 },
305     { Ports_8PRE,      N_ELEMENTS( Ports_8PRE ),       96000 },
306     { Ports_828MKI,    N_ELEMENTS( Ports_828MKI ),     48000 },
307     { Ports_896HD,     N_ELEMENTS( Ports_896HD ),     192000, MixerCtrls_896HD, N_ELEMENTS(MixerCtrls_896HD),  },
308 };
309
310 MotuDevice::MotuDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
311     : FFADODevice( d, configRom )
312     , m_motu_model( MOTU_MODEL_NONE )
313     , m_iso_recv_channel ( -1 )
314     , m_iso_send_channel ( -1 )
315     , m_rx_bandwidth ( -1 )
316     , m_tx_bandwidth ( -1 )
317     , m_receiveProcessor ( 0 )
318     , m_transmitProcessor ( 0 )
319     , m_MixerContainer ( NULL )
320     , m_ControlContainer ( NULL )
321 {
322     debugOutput( DEBUG_LEVEL_VERBOSE, "Created Motu::MotuDevice (NodeID %d)\n",
323                  getConfigRom().getNodeId() );
324 }
325
326 MotuDevice::~MotuDevice()
327 {
328     delete m_receiveProcessor;
329     delete m_transmitProcessor;
330
331     // Free ieee1394 bus resources if they have been allocated
332     if (m_iso_recv_channel>=0 && !get1394Service().freeIsoChannel(m_iso_recv_channel)) {
333         debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free recv iso channel %d\n", m_iso_recv_channel);
334     }
335     if (m_iso_send_channel>=0 && !get1394Service().freeIsoChannel(m_iso_send_channel)) {
336         debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free send iso channel %d\n", m_iso_send_channel);
337     }
338
339     destroyMixer();
340 }
341
342 bool
343 MotuDevice::buildMixer() {
344     unsigned int i;
345     bool result = true;
346     debugOutput(DEBUG_LEVEL_VERBOSE, "Building a MOTU mixer...\n");
347
348     destroyMixer();
349        
350     // create the mixer object container
351     m_MixerContainer = new Control::Container(this, "Mixer");
352     if (!m_MixerContainer) {
353         debugError("Could not create mixer container...\n");
354         return false;
355     }
356
357     // Mixer controls get added here
358     for (i=0; i<DevicesProperty[m_motu_model-1].n_mixer_ctrls; i++) {
359         unsigned int type = DevicesProperty[m_motu_model-1].mixer_ctrl[i].type;
360         char name[100];
361         char label[100];
362         if (type & MOTU_CTRL_CHANNEL_FADER) {
363             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "fader");
364             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"fader");
365             result &= m_MixerContainer->addElement(
366                 new ChannelFader(*this,
367                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register,
368                     name, label,
369                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc));
370             type &= ~MOTU_CTRL_CHANNEL_FADER;
371         }
372         if (type & MOTU_CTRL_CHANNEL_PAN) {
373             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "pan");
374             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"pan");
375             result &= m_MixerContainer->addElement(
376                 new ChannelPan(*this,
377                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register,
378                     name, label,
379                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc));
380             type &= ~MOTU_CTRL_CHANNEL_PAN;
381         }
382         if (type & MOTU_CTRL_CHANNEL_MUTE) {
383             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "mute");
384             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"mute");
385             result &= m_MixerContainer->addElement(
386                 new MotuBinarySwitch(*this,
387                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register,
388                     MOTU_CTRL_MASK_MUTE_VALUE, MOTU_CTRL_MASK_MUTE_SETENABLE,
389                     name, label,
390                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc));
391             type &= ~MOTU_CTRL_CHANNEL_MUTE;
392         }
393         if (type & MOTU_CTRL_CHANNEL_SOLO) {
394             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "solo");
395             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"solo");
396             result &= m_MixerContainer->addElement(
397                 new MotuBinarySwitch(*this,
398                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register,
399                     MOTU_CTRL_MASK_SOLO_VALUE, MOTU_CTRL_MASK_SOLO_SETENABLE,
400                     name, label,
401                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc));
402             type &= ~MOTU_CTRL_CHANNEL_SOLO;
403         }
404
405         if (type & MOTU_CTRL_MIX_FADER) {
406             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "fader");
407             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"fader");
408             result &= m_MixerContainer->addElement(
409                 new MixFader(*this,
410                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register,
411                     name, label,
412                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc));
413             type &= ~MOTU_CTRL_MIX_FADER;
414         }
415         if (type & MOTU_CTRL_MIX_MUTE) {
416             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "mute");
417             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"mute");
418             result &= m_MixerContainer->addElement(
419                 new MixMute(*this,
420                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register,
421                     name, label,
422                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc));
423             type &= ~MOTU_CTRL_MIX_MUTE;
424         }
425         if (type & MOTU_CTRL_MIX_DEST) {
426             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "dest");
427             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"dest");
428             result &= m_MixerContainer->addElement(
429                 new MixDest(*this,
430                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register,
431                     name, label,
432                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc));
433             type &= ~MOTU_CTRL_MIX_DEST;
434         }
435
436         if (type & MOTU_CTRL_INPUT_TRIMGAIN) {
437             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "trimgain");
438             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"trimgain");
439             result &= m_MixerContainer->addElement(
440                 new InputGainPad(*this,
441                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register, MOTU_CTRL_MODE_TRIMGAIN,
442                     name, label,
443                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc));
444             type &= ~MOTU_CTRL_INPUT_TRIMGAIN;
445         }
446         if (type & MOTU_CTRL_INPUT_PAD) {
447             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "pad");
448             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"pad");
449             result &= m_MixerContainer->addElement(
450                 new InputGainPad(*this,
451                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register, MOTU_CTRL_MODE_PAD,
452                     name, label,
453                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc));
454             type &= ~MOTU_CTRL_INPUT_PAD;
455         }
456
457         if (type & MOTU_CTRL_INPUT_LEVEL) {
458             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "level");
459             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"level");
460             result &= m_MixerContainer->addElement(
461                 new MotuBinarySwitch(*this,
462                     MOTU_REG_INPUT_LEVEL,
463                     1<<DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register, 0,
464                     name, label,
465                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc));
466             type &= ~MOTU_CTRL_INPUT_LEVEL;
467         }
468         if (type & MOTU_CTRL_INPUT_BOOST) {
469             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "boost");
470             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"boost");
471             result &= m_MixerContainer->addElement(
472                 new MotuBinarySwitch(*this,
473                     MOTU_REG_INPUT_BOOST,
474                     1<<DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register, 0,
475                     name, label,
476                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc));
477             type &= ~MOTU_CTRL_INPUT_BOOST;
478         }
479         if (type & MOTU_CTRL_PHONES_SRC) {
480             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "src");
481             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"src");
482             result &= m_MixerContainer->addElement(
483                 new PhonesSrc(*this,
484                     name, label,
485                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc));
486             type &= ~MOTU_CTRL_PHONES_SRC;
487         }
488         if (type & MOTU_CTRL_OPTICAL_MODE) {
489             result &= m_MixerContainer->addElement(
490                 new OpticalMode(*this, DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register,
491                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].name,
492                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,
493                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc));
494             type &= ~MOTU_CTRL_OPTICAL_MODE;
495         }
496
497         if (type) {
498             debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown mixer control type flag bits 0x%08x\n", DevicesProperty[m_motu_model-1].mixer_ctrl[i].type);
499         }
500     }
501
502     /* Now add some general device information controls.  These may yet
503      * become device-specific if it turns out to be easier that way.
504      */
505     result &= m_MixerContainer->addElement(
506         new InfoElement(*this, MOTU_INFO_IS_STREAMING, "Info/IsStreaming", "Is device streaming", ""));
507     result &= m_MixerContainer->addElement(
508         new InfoElement(*this, MOTU_INFO_SAMPLE_RATE, "Info/SampleRate", "Device sample rate", ""));
509     result &= m_MixerContainer->addElement(
510         new InfoElement(*this, MOTU_INFO_HAS_MIC_INPUTS, "Info/HasMicInputs", "Device has mic inputs", ""));
511     result &= m_MixerContainer->addElement(
512         new InfoElement(*this, MOTU_INFO_HAS_AESEBU_INPUTS, "Info/HasAESEBUInputs", "Device has AES/EBU inputs", ""));
513     result &= m_MixerContainer->addElement(
514         new InfoElement(*this, MOTU_INFO_HAS_SPDIF_INPUTS, "Info/HasSPDIFInputs", "Device has SPDIF inputs", ""));
515     result &= m_MixerContainer->addElement(
516         new InfoElement(*this, MOTU_INFO_HAS_OPTICAL_SPDIF, "Info/HasOpticalSPDIF", "Device has Optical SPDIF", ""));
517
518     if (!addElement(m_MixerContainer)) {
519         debugWarning("Could not register mixer to device\n");
520         // clean up
521         destroyMixer();
522         return false;
523     }
524
525     // Special controls
526     m_ControlContainer = new Control::Container(this, "Control");
527     if (!m_ControlContainer) {
528         debugError("Could not create control container...\n");
529         return false;
530     }
531
532     // Special controls get added here
533
534     if (!result) {
535         debugWarning("One or more device control elements could not be created.");
536         // clean up those that couldn't be created
537         destroyMixer();
538         return false;
539     }
540     if (!addElement(m_ControlContainer)) {
541         debugWarning("Could not register controls to device\n");
542         // clean up
543         destroyMixer();
544         return false;
545     }
546
547     return true;
548 }
549
550
551 bool
552 MotuDevice::destroyMixer() {
553     debugOutput(DEBUG_LEVEL_VERBOSE, "destroy mixer...\n");
554
555     if (m_MixerContainer == NULL) {
556         debugOutput(DEBUG_LEVEL_VERBOSE, "no mixer to destroy...\n");
557         return true;
558     }
559    
560     if (!deleteElement(m_MixerContainer)) {
561         debugError("Mixer present but not registered to the avdevice\n");
562         return false;
563     }
564
565     // remove and delete (as in free) child control elements
566     m_MixerContainer->clearElements(true);
567     delete m_MixerContainer;
568     m_MixerContainer = NULL;
569
570     // remove control container
571     if (m_ControlContainer == NULL) {
572         debugOutput(DEBUG_LEVEL_VERBOSE, "no controls to destroy...\n");
573         return true;
574     }
575    
576     if (!deleteElement(m_ControlContainer)) {
577         debugError("Controls present but not registered to the avdevice\n");
578         return false;
579     }
580    
581     // remove and delete (as in free) child control elements
582     m_ControlContainer->clearElements(true);
583     delete m_ControlContainer;
584     m_ControlContainer = NULL;
585
586     return true;
587 }
588
589 bool
590 MotuDevice::probe( ConfigRom& configRom )
591 {
592     unsigned int vendorId = configRom.getNodeVendorId();
593     unsigned int unitVersion = configRom.getUnitVersion();
594     unsigned int unitSpecifierId = configRom.getUnitSpecifierId();
595
596     for ( unsigned int i = 0;
597           i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) );
598           ++i )
599     {
600         if ( ( supportedDeviceList[i].vendor_id == vendorId )
601              && ( supportedDeviceList[i].unit_version == unitVersion )
602              && ( supportedDeviceList[i].unit_specifier_id == unitSpecifierId )
603            )
604         {
605             return true;
606         }
607     }
608
609     return false;
610 }
611
612 FFADODevice *
613 MotuDevice::createDevice(DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
614 {
615     return new MotuDevice(d, configRom);
616 }
617
618 bool
619 MotuDevice::discover()
620 {
621     unsigned int vendorId = getConfigRom().getNodeVendorId();
622     unsigned int unitVersion = getConfigRom().getUnitVersion();
623     unsigned int unitSpecifierId = getConfigRom().getUnitSpecifierId();
624
625     for ( unsigned int i = 0;
626           i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) );
627           ++i )
628     {
629         if ( ( supportedDeviceList[i].vendor_id == vendorId )
630              && ( supportedDeviceList[i].unit_version == unitVersion )
631              && ( supportedDeviceList[i].unit_specifier_id == unitSpecifierId )
632            )
633         {
634             m_model = &(supportedDeviceList[i]);
635             m_motu_model=supportedDeviceList[i].model;
636         }
637     }
638
639     if (m_model == NULL) {
640         return false;
641     }
642
643     debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
644         m_model->vendor_name, m_model->model_name);
645
646     if (!buildMixer()) {
647         debugWarning("Could not build mixer\n");
648     }
649
650     return true;
651 }
652
653 int
654 MotuDevice::getSamplingFrequency( ) {
655 /*
656  * Retrieve the current sample rate from the MOTU device.
657  */
658     quadlet_t q = ReadRegister(MOTU_REG_CLK_CTRL);
659     int rate = 0;
660
661     switch (q & MOTU_RATE_BASE_MASK) {
662         case MOTU_RATE_BASE_44100:
663             rate = 44100;
664             break;
665         case MOTU_RATE_BASE_48000:
666             rate = 48000;
667             break;
668     }
669     switch (q & MOTU_RATE_MULTIPLIER_MASK) {
670         case MOTU_RATE_MULTIPLIER_2X:
671             rate *= 2;
672             break;
673         case MOTU_RATE_MULTIPLIER_4X:
674             rate *= 4;
675             break;
676     }
677     return rate;
678 }
679
680 int
681 MotuDevice::getConfigurationId()
682 {
683     return 0;
684 }
685
686 bool
687 MotuDevice::setClockCtrlRegister(signed int samplingFrequency, unsigned int clock_source)
688 {
689 /*
690  * Set the MOTU device's samplerate and/or clock source via the clock
691  * control register.  If samplingFrequency <= 0 it remains unchanged.  If
692  * clock_source is MOTU_CLKSRC_UNCHANGED the clock source remains unchanged.
693  */
694     const char *src_name;
695     quadlet_t q, new_rate=0xffffffff;
696     int i, supported=true, cancel_adat=false;
697     quadlet_t reg;
698
699     /* Don't touch anything if there's nothing to do */
700     if (samplingFrequency<=0 && clock_source==MOTU_CLKSRC_NONE)
701         return true;
702
703     if ( samplingFrequency > DevicesProperty[m_motu_model-1].MaxSampleRate )
704        return false;
705
706     reg = ReadRegister(MOTU_REG_CLK_CTRL);
707
708     switch ( samplingFrequency ) {
709         case -1:
710             break;
711         case 44100:
712             new_rate = MOTU_RATE_BASE_44100 | MOTU_RATE_MULTIPLIER_1X;
713             break;
714         case 48000:
715             new_rate = MOTU_RATE_BASE_48000 | MOTU_RATE_MULTIPLIER_1X;
716             break;
717         case 88200:
718             new_rate = MOTU_RATE_BASE_44100 | MOTU_RATE_MULTIPLIER_2X;
719             break;
720         case 96000:
721             new_rate = MOTU_RATE_BASE_48000 | MOTU_RATE_MULTIPLIER_2X;
722             break;
723         case 176400:
724             new_rate = MOTU_RATE_BASE_44100 | MOTU_RATE_MULTIPLIER_4X;
725             cancel_adat = true;  // current ADAT protocol doesn't support sample rate > 96000
726             break;
727         case 192000:
728             new_rate = MOTU_RATE_BASE_48000 | MOTU_RATE_MULTIPLIER_4X;
729             cancel_adat = true;
730             break;
731         default:
732             supported=false;
733     }
734
735     // Sanity check the clock source
736     if ((clock_source>7 || clock_source==6) && clock_source!=MOTU_CLKSRC_UNCHANGED)
737         supported = false;
738
739     // Update the clock control register.  FIXME: while this is now rather
740     // comprehensive there may still be a need to manipulate MOTU_REG_CLK_CTRL
741     // a little more than we do.
742     if (supported) {
743
744         // If optical port must be disabled (because a 4x sample rate has
745         // been selected) then do so before changing the sample rate.  At
746         // this stage it will be up to the user to re-enable the optical
747         // port if the sample rate is set to a 1x or 2x rate later.
748         if (cancel_adat) {
749             setOpticalMode(MOTU_DIR_INOUT, MOTU_OPTICAL_MODE_OFF);
750         }
751
752         // Set up new frequency if requested
753         if (new_rate != 0xffffffff) {
754             reg &= ~(MOTU_RATE_BASE_MASK|MOTU_RATE_MULTIPLIER_MASK);
755             reg |= new_rate;
756         }
757
758         // Set up new clock source if required
759         if (clock_source != MOTU_CLKSRC_UNCHANGED) {
760             reg &= ~MOTU_CLKSRC_MASK;
761             reg |= (clock_source & MOTU_CLKSRC_MASK);
762         }
763
764         // In other OSes bit 26 of MOTU_REG_CLK_CTRL always seems
765         // to be set when this register is written to although the
766         // reason isn't currently known.  When we set it, it appears
767         // to prevent output being produced so we'll leave it unset
768         // until we work out what's going on.  Other systems write
769         // to MOTU_REG_CLK_CTRL multiple times, so that may be
770         // part of the mystery.
771         //   value |= 0x04000000;
772         if (WriteRegister(MOTU_REG_CLK_CTRL, reg) == 0) {
773             supported=true;
774         } else {
775             supported=false;
776         }
777         // A write to the rate/clock control register requires the
778         // textual name of the current clock source be sent to the
779         // clock source name registers.
780         switch (reg & MOTU_CLKSRC_MASK) {
781             case MOTU_CLKSRC_INTERNAL:
782                 src_name = "Internal        ";
783                 break;
784             case MOTU_CLKSRC_ADAT_OPTICAL:
785                 src_name = "ADAT Optical    ";
786                 break;
787             case MOTU_CLKSRC_SPDIF_TOSLINK:
788                 if (getOpticalMode(MOTU_DIR_IN) == MOTU_OPTICAL_MODE_TOSLINK)
789                     src_name = "TOSLink         ";
790                 else
791                     src_name = "SPDIF           ";
792                 break;
793             case MOTU_CLKSRC_SMPTE:
794                 src_name = "SMPTE           ";
795                 break;
796             case MOTU_CLKSRC_WORDCLOCK:
797                 src_name = "Word Clock In   ";
798                 break;
799             case MOTU_CLKSRC_ADAT_9PIN:
800                 src_name = "ADAT 9-pin      ";
801                 break;
802             case MOTU_CLKSRC_AES_EBU:
803                 src_name = "AES-EBU         ";
804                 break;
805             default:
806                 src_name = "Unknown         ";
807         }
808         for (i=0; i<16; i+=4) {
809             q = (src_name[i]<<24) | (src_name[i+1]<<16) |
810                 (src_name[i+2]<<8) | src_name[i+3];
811             WriteRegister(MOTU_REG_CLKSRC_NAME0+i, q);
812         }
813     }
814     return supported;
815 }
816
817 bool
818 MotuDevice::setSamplingFrequency( int samplingFrequency )
819 {
820 /*
821  * Set the MOTU device's samplerate.
822  */
823     return setClockCtrlRegister(samplingFrequency, MOTU_CLKSRC_UNCHANGED);
824 }
825
826 FFADODevice::ClockSource
827 MotuDevice::clockIdToClockSource(unsigned int id) {
828     ClockSource s;
829     s.id = id;
830
831     // Assume a clock source is valid/active unless otherwise overridden.
832     s.valid = true;
833     s.locked = true;
834     s.active = true;
835
836     switch (id) {
837         case MOTU_CLKSRC_INTERNAL:
838             s.type = eCT_Internal;
839             s.description = "Internal sync";
840             break;
841         case MOTU_CLKSRC_ADAT_OPTICAL:
842             s.type = eCT_ADAT;
843             s.description = "ADAT optical";
844             break;
845         case MOTU_CLKSRC_SPDIF_TOSLINK:
846             s.type = eCT_SPDIF;
847             s.description = "SPDIF/Toslink";
848             break;
849         case MOTU_CLKSRC_SMPTE:
850             s.type = eCT_SMPTE;
851             s.description = "SMPTE";
852             // Since we don't currently know how to deal with SMPTE on these devices
853             // make sure the SMPTE clock source is disabled.
854             s.valid = false;
855             s.active = false;
856             s.locked = false;
857             break;
858         case MOTU_CLKSRC_WORDCLOCK:
859             s.type = eCT_WordClock;
860             s.description = "Wordclock";
861             break;
862         case MOTU_CLKSRC_ADAT_9PIN:
863             s.type = eCT_ADAT;
864             s.description = "ADAT 9-pin";
865             break;
866         case MOTU_CLKSRC_AES_EBU:
867             s.type = eCT_AES;
868             s.description = "AES/EBU";
869             break;
870         default:
871             s.type = eCT_Invalid;
872     }
873
874     s.slipping = false;
875     return s;
876 }
877
878 FFADODevice::ClockSourceVector
879 MotuDevice::getSupportedClockSources() {
880     FFADODevice::ClockSourceVector r;
881     ClockSource s;
882
883     /* Form a list of clocks supported by MOTU interfaces */
884     s = clockIdToClockSource(MOTU_CLKSRC_INTERNAL);
885     r.push_back(s);
886     s = clockIdToClockSource(MOTU_CLKSRC_ADAT_OPTICAL);
887     r.push_back(s);
888     s = clockIdToClockSource(MOTU_CLKSRC_SPDIF_TOSLINK);
889     r.push_back(s);
890     s = clockIdToClockSource(MOTU_CLKSRC_SMPTE);
891     r.push_back(s);
892     s = clockIdToClockSource(MOTU_CLKSRC_WORDCLOCK);
893     r.push_back(s);
894     s = clockIdToClockSource(MOTU_CLKSRC_ADAT_9PIN);
895     r.push_back(s);
896     s = clockIdToClockSource(MOTU_CLKSRC_AES_EBU);
897     r.push_back(s);
898
899     return r;
900 }
901
902 bool
903 MotuDevice::setActiveClockSource(ClockSource s) {
904     debugOutput(DEBUG_LEVEL_VERBOSE, "setting clock source to id: %d\n",s.id);
905
906     // FIXME: this could do with some error checking
907     return setClockCtrlRegister(-1, s.id);
908 }
909
910 FFADODevice::ClockSource
911 MotuDevice::getActiveClockSource() {
912     ClockSource s;
913     quadlet_t clock_id = ReadRegister(MOTU_REG_CLK_CTRL) & MOTU_CLKSRC_MASK;
914     s = clockIdToClockSource(clock_id);
915     s.active = true;
916     return s;
917 }
918
919 bool
920 MotuDevice::lock() {
921
922     return true;
923 }
924
925
926 bool
927 MotuDevice::unlock() {
928
929     return true;
930 }
931
932 void
933 MotuDevice::showDevice()
934 {
935     debugOutput(DEBUG_LEVEL_VERBOSE,
936         "%s %s at node %d\n", m_model->vendor_name, m_model->model_name,
937         getNodeId());
938 }
939
940 bool
941 MotuDevice::prepare() {
942
943     int samp_freq = getSamplingFrequency();
944     unsigned int optical_in_mode = getOpticalMode(MOTU_DIR_IN);
945     unsigned int optical_out_mode = getOpticalMode(MOTU_DIR_OUT);
946     unsigned int event_size_in = getEventSize(MOTU_DIR_IN);
947     unsigned int event_size_out= getEventSize(MOTU_DIR_OUT);
948
949     debugOutput(DEBUG_LEVEL_NORMAL, "Preparing MotuDevice...\n" );
950
951     // Allocate bandwidth if not previously done.
952     // FIXME: The bandwidth allocation calculation can probably be
953     // refined somewhat since this is currently based on a rudimentary
954     // understanding of the ieee1394 iso protocol.
955     // Currently we assume the following.
956     //   * Ack/iso gap = 0.05 us
957     //   * DATA_PREFIX = 0.16 us
958     //   * DATA_END    = 0.26 us
959     // These numbers are the worst-case figures given in the ieee1394
960     // standard.  This gives approximately 0.5 us of overheads per packet -
961     // around 25 bandwidth allocation units (from the ieee1394 standard 1
962     // bandwidth allocation unit is 125/6144 us).  We further assume the
963     // MOTU is running at S400 (which it should be) so one allocation unit
964     // is equivalent to 1 transmitted byte; thus the bandwidth allocation
965     // required for the packets themselves is just the size of the packet.
966     // We used to allocate based on the maximum packet size (1160 bytes at
967     // 192 kHz for the traveler) but now do this based on the actual device
968     // state by utilising the result from getEventSize() and remembering
969     // that each packet has an 8 byte CIP header.  Note that bandwidth is
970     // allocated on a *per stream* basis - it must be allocated for both the
971     // transmit and receive streams.  While most MOTU modules are close to
972     // symmetric in terms of the number of in/out channels there are
973     // exceptions, so we deal with receive and transmit bandwidth separately.
974     signed int n_events_per_packet = samp_freq<=48000?8:(samp_freq<=96000?16:32);
975     m_rx_bandwidth = 25 + (n_events_per_packet*event_size_in);
976     m_tx_bandwidth = 25 + (n_events_per_packet*event_size_out);
977
978     // Assign iso channels if not already done
979     if (m_iso_recv_channel < 0)
980         m_iso_recv_channel = get1394Service().allocateIsoChannelGeneric(m_rx_bandwidth);
981
982     if (m_iso_send_channel < 0)
983         m_iso_send_channel = get1394Service().allocateIsoChannelGeneric(m_tx_bandwidth);
984
985     debugOutput(DEBUG_LEVEL_VERBOSE, "recv channel = %d, send channel = %d\n",
986         m_iso_recv_channel, m_iso_send_channel);
987
988     if (m_iso_recv_channel<0 || m_iso_send_channel<0) {
989         // be nice and deallocate
990         if (m_iso_recv_channel >= 0)
991             get1394Service().freeIsoChannel(m_iso_recv_channel);
992         if (m_iso_send_channel >= 0)
993             get1394Service().freeIsoChannel(m_iso_send_channel);
994
995         debugFatal("Could not allocate iso channels!\n");
996         return false;
997     }
998
999     m_receiveProcessor=new Streaming::MotuReceiveStreamProcessor(*this, event_size_in);
1000
1001     // The first thing is to initialize the processor.  This creates the
1002     // data structures.
1003     if(!m_receiveProcessor->init()) {
1004         debugFatal("Could not initialize receive processor!\n");
1005         return false;
1006     }
1007     m_receiveProcessor->setVerboseLevel(getDebugLevel());
1008
1009     // Now we add ports to the processor
1010     debugOutput(DEBUG_LEVEL_VERBOSE,"Adding ports to receive processor\n");
1011
1012     char *buff;
1013     Streaming::Port *p=NULL;
1014
1015     // retrieve the ID
1016     std::string id=std::string("dev?");
1017     if(!getOption("id", id)) {
1018         debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n");
1019     }
1020
1021     // Add audio capture ports
1022     if (!addDirPorts(Streaming::Port::E_Capture, samp_freq, optical_in_mode)) {
1023         return false;
1024     }
1025
1026     // Add MIDI port.  The MOTU only has one MIDI input port, with each
1027     // MIDI byte sent using a 3 byte sequence starting at byte 4 of the
1028     // event data.
1029     asprintf(&buff,"%s_cap_MIDI0",id.c_str());
1030     p = new Streaming::MotuMidiPort(*m_receiveProcessor, buff,
1031         Streaming::Port::E_Capture, 4);
1032     if (!p) {
1033         debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n", buff);
1034     }
1035     free(buff);
1036
1037     // example of adding an control port:
1038 //    asprintf(&buff,"%s_cap_%s",id.c_str(),"myportnamehere");
1039 //    p=new Streaming::MotuControlPort(
1040 //            buff,
1041 //            Streaming::Port::E_Capture,
1042 //            0 // you can add all other port specific stuff you
1043 //              // need to pass by extending MotuXXXPort and MotuPortInfo
1044 //    );
1045 //    free(buff);
1046 //
1047 //    if (!p) {
1048 //        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",buff);
1049 //    } else {
1050 //
1051 //        if (!m_receiveProcessor->addPort(p)) {
1052 //            debugWarning("Could not register port with stream processor\n");
1053 //            return false;
1054 //        } else {
1055 //            debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",buff);
1056 //        }
1057 //    }
1058
1059     // Do the same for the transmit processor
1060     m_transmitProcessor=new Streaming::MotuTransmitStreamProcessor(*this, event_size_out);
1061
1062     m_transmitProcessor->setVerboseLevel(getDebugLevel());
1063
1064     if(!m_transmitProcessor->init()) {
1065         debugFatal("Could not initialize transmit processor!\n");
1066         return false;
1067     }
1068
1069     // Now we add ports to the processor
1070     debugOutput(DEBUG_LEVEL_VERBOSE,"Adding ports to transmit processor\n");
1071
1072     // Add audio playback ports
1073     if (!addDirPorts(Streaming::Port::E_Playback, samp_freq, optical_out_mode)) {
1074         return false;
1075     }
1076
1077     // Add MIDI port.  The MOTU only has one output MIDI port, with each
1078     // MIDI byte transmitted using a 3 byte sequence starting at byte 4
1079     // of the event data.
1080     asprintf(&buff,"%s_pbk_MIDI0",id.c_str());
1081     p = new Streaming::MotuMidiPort(*m_transmitProcessor, buff,
1082         Streaming::Port::E_Capture, 4);
1083     if (!p) {
1084         debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n", buff);
1085     }
1086     free(buff);
1087
1088     // example of adding an control port:
1089 //    asprintf(&buff,"%s_pbk_%s",id.c_str(),"myportnamehere");
1090 //
1091 //    p=new Streaming::MotuControlPort(
1092 //            buff,
1093 //            Streaming::Port::E_Playback,
1094 //            0 // you can add all other port specific stuff you
1095 //              // need to pass by extending MotuXXXPort and MotuPortInfo
1096 //    );
1097 //    free(buff);
1098 //
1099 //    if (!p) {
1100 //        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",buff);
1101 //    } else {
1102 //        if (!m_transmitProcessor->addPort(p)) {
1103 //            debugWarning("Could not register port with stream processor\n");
1104 //            return false;
1105 //        } else {
1106 //            debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",buff);
1107 //        }
1108 //    }
1109
1110     return true;
1111 }
1112
1113 int
1114 MotuDevice::getStreamCount() {
1115      return 2; // one receive, one transmit
1116 }
1117
1118 Streaming::StreamProcessor *
1119 MotuDevice::getStreamProcessorByIndex(int i) {
1120     switch (i) {
1121     case 0:
1122         return m_receiveProcessor;
1123     case 1:
1124          return m_transmitProcessor;
1125     default:
1126         return NULL;
1127     }
1128     return 0;
1129 }
1130
1131 bool
1132 MotuDevice::startStreamByIndex(int i) {
1133
1134 quadlet_t isoctrl = ReadRegister(MOTU_REG_ISOCTRL);
1135
1136     // NOTE: this assumes that you have two streams
1137     switch (i) {
1138     case 0:
1139         // TODO: do the stuff that is nescessary to make the device
1140         // receive a stream
1141
1142         // Set the streamprocessor channel to the one obtained by
1143         // the connection management
1144         m_receiveProcessor->setChannel(m_iso_recv_channel);
1145
1146         // Mask out current transmit settings of the MOTU and replace
1147         // with new ones.  Turn bit 24 on to enable changes to the
1148         // MOTU's iso transmit settings when the iso control register
1149         // is written.  Bit 23 enables iso transmit from the MOTU.
1150         isoctrl &= 0xff00ffff;
1151         isoctrl |= (m_iso_recv_channel << 16);
1152         isoctrl |= 0x00c00000;
1153         WriteRegister(MOTU_REG_ISOCTRL, isoctrl);
1154         break;
1155     case 1:
1156         // TODO: do the stuff that is nescessary to make the device
1157         // transmit a stream
1158
1159         // Set the streamprocessor channel to the one obtained by
1160         // the connection management
1161         m_transmitProcessor->setChannel(m_iso_send_channel);
1162
1163         // Mask out current receive settings of the MOTU and replace
1164         // with new ones.  Turn bit 31 on to enable changes to the
1165         // MOTU's iso receive settings when the iso control register
1166         // is written.  Bit 30 enables iso receive by the MOTU.
1167         isoctrl &= 0x00ffffff;
1168         isoctrl |= (m_iso_send_channel << 24);
1169         isoctrl |= 0xc0000000;
1170         WriteRegister(MOTU_REG_ISOCTRL, isoctrl);
1171         break;
1172
1173     default: // Invalid stream index
1174         return false;
1175     }
1176
1177     return true;
1178 }
1179
1180 bool
1181 MotuDevice::stopStreamByIndex(int i) {
1182
1183 quadlet_t isoctrl = ReadRegister(MOTU_REG_ISOCTRL);
1184
1185     // TODO: connection management: break connection
1186     // cfr the start function
1187
1188     // NOTE: this assumes that you have two streams
1189     switch (i) {
1190     case 0:
1191         // Turn bit 22 off to disable iso send by the MOTU.  Turn
1192         // bit 23 on to enable changes to the MOTU's iso transmit
1193         // settings when the iso control register is written.
1194         isoctrl &= 0xffbfffff;
1195         isoctrl |= 0x00800000;
1196         WriteRegister(MOTU_REG_ISOCTRL, isoctrl);
1197         break;
1198     case 1:
1199         // Turn bit 30 off to disable iso receive by the MOTU.  Turn
1200         // bit 31 on to enable changes to the MOTU's iso receive
1201         // settings when the iso control register is written.
1202         isoctrl &= 0xbfffffff;
1203         isoctrl |= 0x80000000;
1204         WriteRegister(MOTU_REG_ISOCTRL, isoctrl);
1205         break;
1206
1207     default: // Invalid stream index
1208         return false;
1209     }
1210
1211     return true;
1212 }
1213
1214 signed int MotuDevice::getIsoRecvChannel(void) {
1215     return m_iso_recv_channel;
1216 }
1217
1218 signed int MotuDevice::getIsoSendChannel(void) {
1219     return m_iso_send_channel;
1220 }
1221
1222 unsigned int MotuDevice::getOpticalMode(unsigned int dir) {
1223     unsigned int reg = ReadRegister(MOTU_REG_ROUTE_PORT_CONF);
1224
1225 debugOutput(DEBUG_LEVEL_VERBOSE, "optical mode: %x %x %x %x\n",dir, reg, reg & MOTU_OPTICAL_IN_MODE_MASK,
1226 reg & MOTU_OPTICAL_OUT_MODE_MASK);
1227
1228     if (dir == MOTU_DIR_IN)
1229         return (reg & MOTU_OPTICAL_IN_MODE_MASK) >> 8;
1230     else
1231         return (reg & MOTU_OPTICAL_OUT_MODE_MASK) >> 10;
1232 }
1233
1234 signed int MotuDevice::setOpticalMode(unsigned int dir, unsigned int mode) {
1235     unsigned int reg = ReadRegister(MOTU_REG_ROUTE_PORT_CONF);
1236     unsigned int opt_ctrl = 0x0000002;
1237
1238     /* THe 896HD doesn't have an SPDIF/TOSLINK optical mode, so don't try to
1239      * set it
1240      */
1241     if (m_motu_model==MOTU_MODEL_896HD && mode==MOTU_OPTICAL_MODE_TOSLINK)
1242         return -1;
1243
1244     // Set up the optical control register value according to the current
1245     // optical port modes.  At this stage it's not completely understood
1246     // what the "Optical control" register does, so the values it's set to
1247     // are more or less "magic" numbers.
1248     if ((reg & MOTU_OPTICAL_IN_MODE_MASK) != (MOTU_OPTICAL_MODE_ADAT<<8))
1249         opt_ctrl |= 0x00000080;
1250     if ((reg & MOTU_OPTICAL_OUT_MODE_MASK) != (MOTU_OPTICAL_MODE_ADAT<<10))
1251         opt_ctrl |= 0x00000040;
1252
1253     if (mode & MOTU_DIR_IN) {
1254         reg &= ~MOTU_OPTICAL_IN_MODE_MASK;
1255         reg |= (mode << 8) & MOTU_OPTICAL_IN_MODE_MASK;
1256         if (mode != MOTU_OPTICAL_MODE_ADAT)
1257             opt_ctrl |= 0x00000080;
1258         else
1259             opt_ctrl &= ~0x00000080;
1260     }
1261     if (mode & MOTU_DIR_OUT) {
1262         reg &= ~MOTU_OPTICAL_OUT_MODE_MASK;
1263         reg |= (mode <<10) & MOTU_OPTICAL_OUT_MODE_MASK;
1264         if (mode != MOTU_OPTICAL_MODE_ADAT)
1265             opt_ctrl |= 0x00000040;
1266         else
1267             opt_ctrl &= ~0x00000040;
1268     }
1269
1270     // FIXME: there seems to be more to it than this, but for
1271     // the moment at least this seems to work.
1272     WriteRegister(MOTU_REG_ROUTE_PORT_CONF, reg);
1273     return WriteRegister(MOTU_REG_OPTICAL_CTRL, opt_ctrl);
1274 }
1275
1276 signed int MotuDevice::getEventSize(unsigned int direction) {
1277 //
1278 // Return the size in bytes of a single event sent to (dir==MOTU_OUT) or
1279 // from (dir==MOTU_IN) the MOTU as part of an iso data packet.
1280 //
1281 // FIXME: for performance it may turn out best to calculate the event
1282 // size in setOpticalMode and cache the result in a data field.  However,
1283 // as it stands this will not adapt to dynamic changes in sample rate - we'd
1284 // need a setFrameRate() for that.
1285 //
1286 // At the very least an event consists of the SPH (4 bytes) and the control/MIDI
1287 // bytes (6 bytes).
1288 // Note that all audio channels are sent using 3 bytes.
1289 signed int sample_rate = getSamplingFrequency();
1290 signed int optical_mode = getOpticalMode(direction);
1291 signed int size = 4+6;
1292
1293 unsigned int i;
1294 unsigned int dir = direction==Streaming::Port::E_Capture?MOTU_DIR_IN:MOTU_DIR_OUT;
1295 unsigned int flags = (1 << ( optical_mode + 4 ));
1296
1297     if ( sample_rate > 96000 )
1298         flags |= MOTU_PA_RATE_4x;
1299     else if ( sample_rate > 48000 )
1300         flags |= MOTU_PA_RATE_2x;
1301     else
1302         flags |= MOTU_PA_RATE_1x;
1303
1304     for (i=0; i < DevicesProperty[m_motu_model-1].n_port_entries; i++) {
1305         if (( DevicesProperty[m_motu_model-1].port_entry[i].port_dir & dir ) &&
1306            ( DevicesProperty[m_motu_model-1].port_entry[i].port_flags & MOTU_PA_RATE_MASK & flags ) &&
1307            ( DevicesProperty[m_motu_model-1].port_entry[i].port_flags & MOTU_PA_OPTICAL_MASK & flags )) {
1308             size += 3;
1309         }
1310     }
1311
1312     // Finally round size up to the next quadlet boundary
1313     return ((size+3)/4)*4;
1314 }
1315 /* ======================================================================= */
1316
1317 bool MotuDevice::addPort(Streaming::StreamProcessor *s_processor,
1318   char *name, enum Streaming::Port::E_Direction direction,
1319   int position, int size) {
1320 /*
1321  * Internal helper function to add a MOTU port to a given stream processor.
1322  * This just saves the unnecessary replication of what is essentially
1323  * boilerplate code.  Note that the port name is freed by this function
1324  * prior to exit.
1325  */
1326 Streaming::Port *p=NULL;
1327
1328     p = new Streaming::MotuAudioPort(*s_processor, name, direction, position, size);
1329
1330     if (!p) {
1331         debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",name);
1332     }
1333     free(name);
1334     return true;
1335 }
1336 /* ======================================================================= */
1337
1338 bool MotuDevice::addDirPorts(
1339   enum Streaming::Port::E_Direction direction,
1340   unsigned int sample_rate, unsigned int optical_mode) {
1341 /*
1342  * Internal helper method: adds all required ports for the given direction
1343  * based on the indicated sample rate and optical mode.
1344  *
1345  * Notes: currently ports are not created if they are disabled due to sample
1346  * rate or optical mode.  However, it might be better to unconditionally
1347  * create all ports and just disable those which are not active.
1348  */
1349 const char *mode_str = direction==Streaming::Port::E_Capture?"cap":"pbk";
1350 Streaming::StreamProcessor *s_processor;
1351 unsigned int i;
1352 char *buff;
1353 unsigned int dir = direction==Streaming::Port::E_Capture?MOTU_DIR_IN:MOTU_DIR_OUT;
1354 unsigned int flags = (1 << ( optical_mode + 4 ));
1355
1356     if ( sample_rate > 96000 )
1357         flags |= MOTU_PA_RATE_4x;
1358     else if ( sample_rate > 48000 )
1359         flags |= MOTU_PA_RATE_2x;
1360     else
1361         flags |= MOTU_PA_RATE_1x;
1362
1363     // retrieve the ID
1364     std::string id=std::string("dev?");
1365     if(!getOption("id", id)) {
1366         debugWarning("Could not retrieve id parameter, defaulting to 'dev?'\n");
1367     }
1368
1369     if (direction == Streaming::Port::E_Capture) {
1370         s_processor = m_receiveProcessor;
1371     } else {
1372         s_processor = m_transmitProcessor;
1373     }
1374
1375     for (i=0; i < DevicesProperty[m_motu_model-1].n_port_entries; i++) {
1376         if (( DevicesProperty[m_motu_model-1].port_entry[i].port_dir & dir ) &&
1377            ( DevicesProperty[m_motu_model-1].port_entry[i].port_flags & MOTU_PA_RATE_MASK & flags ) &&
1378            ( DevicesProperty[m_motu_model-1].port_entry[i].port_flags & MOTU_PA_OPTICAL_MASK & flags )) {
1379             asprintf(&buff,"%s_%s_%s" , id.c_str(), mode_str,
1380               DevicesProperty[m_motu_model-1].port_entry[i].port_name);
1381             if (!addPort(s_processor, buff, direction, DevicesProperty[m_motu_model-1].port_entry[i].port_offset, 0))
1382                 return false;
1383         }
1384     }
1385    
1386     return true;
1387 }
1388 /* ======================================================================== */
1389
1390 unsigned int MotuDevice::ReadRegister(unsigned int reg) {
1391 /*
1392  * Attempts to read the requested register from the MOTU.
1393  */
1394
1395   quadlet_t quadlet;
1396
1397   quadlet = 0;
1398   // Note: 1394Service::read() expects a physical ID, not the node id
1399   if (get1394Service().read(0xffc0 | getNodeId(), MOTU_BASE_ADDR+reg, 1, &quadlet) <= 0) {
1400     debugError("Error doing motu read from register 0x%06x\n",reg);
1401   }
1402
1403   return CondSwapFromBus32(quadlet);
1404 }
1405
1406 signed int MotuDevice::WriteRegister(unsigned int reg, quadlet_t data) {
1407 /*
1408  * Attempts to write the given data to the requested MOTU register.
1409  */
1410
1411   unsigned int err = 0;
1412   data = CondSwapToBus32(data);
1413
1414   // Note: 1394Service::write() expects a physical ID, not the node id
1415   if (get1394Service().write(0xffc0 | getNodeId(), MOTU_BASE_ADDR+reg, 1, &data) <= 0) {
1416     err = 1;
1417     debugError("Error doing motu write to register 0x%06x\n",reg);
1418   }
1419
1420   SleepRelativeUsec(100);
1421   return (err==0)?0:-1;
1422 }
1423
1424 }
Note: See TracBrowser for help on using the browser.