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

Revision 1315, 61.6 kB (checked in by jwoithe, 12 years ago)

MOTU: first cut at supporting the meter controls of the 896HD. Please test and report what works and what doesn't.

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