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

Revision 1300, 59.1 kB (checked in by jwoithe, 13 years ago)

MOTU: merge recent trunk mixer changes to 2.0 branch from revisions 1257, 1265 and 1274 ("svn merge -r REV" for REV = 1256:1257, 1264:1265, 1273:1274). Not yet tested.

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