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

Revision 1635, 50.9 kB (checked in by jwoithe, 14 years ago)

MOTU: make the MOTU driver aware of the new mixer definition for the 8pre.

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