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

Revision 1361, 64.7 kB (checked in by ppalmers, 14 years ago)

Merge 2.0 branch changes.

svn merge -r1349:HEAD svn+ssh://ffadosvn@ffado.org/ffado/branches/libffado-2.0

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