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

Revision 1743, 56.3 kB (checked in by jwoithe, 11 years ago)

MOTU: first cut at optical mode setting for the original 828. There's still a missing piece though, since we don't currently know how to differentiate between OFF and ADAT modes at the device level.

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