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

Revision 1516, 73.3 kB (checked in by jwoithe, 15 years ago)

MOTU: define separate mix control structure for the 896HD by copying the Traveler one. Make SPDIF channels follow the ADAT channels since experimentation shows that the ADAT controls start at 0x0028 on the 896HD. Further tests will be needed to determine whether the current register placement of the AES/EBU and SPDIF controls are correct.

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