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

Revision 1336, 64.4 kB (checked in by ppalmers, 16 years ago)

Bring trunk up to date with branches/libffado-2.0:

"""
svn merge -r 1254:1299 svn+ssh://ffadosvn@ffado.org/ffado/branches/libffado-2.0
svn merge -r 1301:1320 svn+ssh://ffadosvn@ffado.org/ffado/branches/libffado-2.0
svn merge -r 1322:1323 svn+ssh://ffadosvn@ffado.org/ffado/branches/libffado-2.0
svn merge -r 1329:HEAD svn+ssh://ffadosvn@ffado.org/ffado/branches/libffado-2.0
"""

Add getSupportedSamplingFrequencies() to DICE, RME and Metric Halo AvDevices?

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