root/branches/libffado-2.0/src/motu/motu_avdevice.cpp

Revision 1355, 65.6 kB (checked in by jwoithe, 12 years ago)

MOTU: centralise event/frame size calculations to getEventSize(). Needed because some interfaces (eg: the Ultralite) don't seem to use DBS CIP header field in a consistent way.
MOTU: Add a "pad" port flag to indicate padding in a packet. Needed to support the Ultralite cleanly.
MOTU: Tweaks to the Ultralite configuration information.

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