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

Revision 1190, 56.9 kB (checked in by ppalmers, 13 years ago)

remove unused code, clean up for release

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