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

Revision 1003, 49.9 kB (checked in by jwoithe, 13 years ago)

MOTU updates:

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