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

Revision 1382, 65.7 kB (checked in by jwoithe, 12 years ago)

MOTU: Allow dbus matrix elements to be flagged as non-existent "pad" controls so other controls remain at their respective places within the matrix.
MOTU: Use pad controls in Ultralite mixer so SPDIF controls remain at their usual index within the dbus matrix mixer elements.

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