root/trunk/libffado/src/rme/rme_avdevice.cpp

Revision 1604, 12.5 kB (checked in by jwoithe, 14 years ago)

RME: remove some macros which are unlikely to be used anymore.

Line 
1 /*
2  * Copyright (C) 2005-2009 by Jonathan Woithe
3  * Copyright (C) 2005-2008 by Pieter Palmers
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 #warning RME support is at an early development stage and is not functional
26
27 #include "rme/rme_avdevice.h"
28 #include "rme/fireface_def.h"
29
30 #include "libieee1394/configrom.h"
31 #include "libieee1394/ieee1394service.h"
32
33 #include "debugmodule/debugmodule.h"
34
35 #include "devicemanager.h"
36
37 #include <string>
38 #include <stdint.h>
39 #include <assert.h>
40 #include "libutil/ByteSwap.h"
41
42 #include <iostream>
43 #include <sstream>
44
45 #include <libraw1394/csr.h>
46
47 // Known values for the unit version of RME devices
48 #define RME_UNITVERSION_FF800  0x0001
49 #define RME_UNITVERSION_FF400  0x0002
50
51 namespace Rme {
52
53 // The RME devices expect async packet data in little endian format (as
54 // opposed to bus order, which is big endian).  Therefore define our own
55 // 32-bit byteswap function to do this.
56 #if __BYTE_ORDER == __BIG_ENDIAN
57 static inline uint32_t
58 ByteSwapToDevice32(uint32_t d)
59 {
60     return byteswap_32(d);
61 }
62 ByteSwapFromDevice32(uint32_t d)
63 {
64     return byteswap_32(d);
65 }
66 #else
67 static inline uint32_t
68 ByteSwapToDevice32(uint32_t d)
69 {
70     return d;
71 }
72 static inline uint32_t
73 ByteSwapFromDevice32(uint32_t d)
74 {
75     return d;
76 }
77 #endif
78
79 Device::Device( DeviceManager& d,
80                       std::auto_ptr<ConfigRom>( configRom ))
81     : FFADODevice( d, configRom )
82     , m_rme_model( RME_MODEL_NONE )
83     , is_streaming( 0 )
84     , m_dds_freq( -1 )
85     , m_software_freq( -1 )
86     , tco_present( 0 )
87     , num_channels( 0 )
88     , samples_per_packet( 0 )
89     , speed800( 0 )
90 {
91     debugOutput( DEBUG_LEVEL_VERBOSE, "Created Rme::Device (NodeID %d)\n",
92                  getConfigRom().getNodeId() );
93 }
94
95 Device::~Device()
96 {
97
98 }
99
100 bool
101 Device::probe( Util::Configuration& c, ConfigRom& configRom, bool generic )
102 {
103     if (generic) {
104         return false;
105     } else {
106         // check if device is in supported devices list.  Note that the RME
107         // devices use the unit version to identify the individual devices.
108         // To avoid having to extend the configuration file syntax to
109         // include this at this point, we'll use the configuration file
110         // model ID to test against the device unit version.  This can be
111         // tidied up if the configuration file is extended at some point to
112         // include the unit version.
113         unsigned int vendorId = configRom.getNodeVendorId();
114         unsigned int unitVersion = configRom.getUnitVersion();
115
116         Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, unitVersion );
117         return c.isValid(vme) && vme.driver == Util::Configuration::eD_RME;
118     }
119 }
120
121 FFADODevice *
122 Device::createDevice(DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
123 {
124     return new Device(d, configRom );
125 }
126
127 bool
128 Device::discover()
129 {
130     unsigned int vendorId = getConfigRom().getNodeVendorId();
131     // See note in Device::probe() about why we use the unit version here.
132     unsigned int unitVersion = getConfigRom().getUnitVersion();
133
134     Util::Configuration &c = getDeviceManager().getConfiguration();
135     Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, unitVersion );
136
137     if (c.isValid(vme) && vme.driver == Util::Configuration::eD_RME) {
138         debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
139                      vme.vendor_name.c_str(),
140                      vme.model_name.c_str());
141     } else {
142         debugWarning("Device '%s %s' unsupported by RME driver (no generic RME support)\n",
143                      getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str());
144     }
145
146     if (unitVersion == RME_UNITVERSION_FF800) {
147         m_rme_model = RME_MODEL_FIREFACE800;
148     } else
149     if (unitVersion == RME_MODEL_FIREFACE400) {
150         m_rme_model = RME_MODEL_FIREFACE400;
151     } else {
152         debugError("Unsupported model\n");
153         return false;
154     }
155
156     // If device is FF800, check to see if the TCO is fitted
157     if (m_rme_model == RME_MODEL_FIREFACE800) {
158         tco_present = (read_tco(NULL, 0) == 0);
159     }
160
161     // Find out the device's streaming status
162     is_streaming = hardware_is_streaming();
163
164     init_hardware();
165
166     // This is just for testing
167     read_device_flash_settings(NULL);
168
169     return true;
170 }
171
172 int
173 Device::getSamplingFrequency( ) {
174
175     // Retrieve the current sample rate.  For practical purposes this
176     // is the software rate currently in use.
177     return m_software_freq;
178 }
179
180 int
181 Device::getConfigurationId()
182 {
183     return 0;
184 }
185
186 bool
187 Device::setDDSFrequency( int dds_freq )
188 {
189     // Set a fixed DDS frequency.  If the device is the clock master this
190     // will immediately be copied to the hardware DDS register.  Otherwise
191     // it will take effect as required at the time the sampling rate is
192     // changed or streaming is started.
193
194     // If the device is streaming, the new DDS rate must have the same
195     // multiplier as the software sample rate
196     if (hardware_is_streaming()) {
197         if (multiplier_of_freq(dds_freq) != multiplier_of_freq(m_software_freq))
198             return false;
199     }
200
201     m_dds_freq = dds_freq;
202     if (settings.clock_mode == FF_STATE_CLOCKMODE_MASTER) {
203         if (set_hardware_dds_freq(dds_freq) != 0)
204             return false;
205     }
206
207     return true;
208 }
209
210 bool
211 Device::setSamplingFrequency( int samplingFrequency )
212 {
213     // Request a sampling rate on behalf of software.  Software is limited
214     // to sample rates of 32k, 44.1k, 48k and the 2x/4x multiples of these.
215     // The user may lock the device to a much wider range of frequencies via
216     // the explicit DDS controls in the control panel.  If the explicit DDS
217     // control is active the software is limited to the "standard" speeds
218     // corresponding to the multiplier in use by the DDS.
219     //
220     // Similarly, if the device is externally clocked the software is
221     // limited to the external clock frequency.
222     //
223     // Otherwise the software has free choice of the software speeds noted
224     // above.
225
226     bool ret = -1;
227     signed int i, j;
228     signed int mult[3] = {1, 2, 4};
229     signed int base_freq[3] = {32000, 44100, 48000};
230     signed int freq = samplingFrequency;
231     FF_state_t state;
232     signed int fixed_freq = 0;
233
234     get_hardware_state(&state);
235
236     // If device is locked to a frequency via external clock, explicit
237     // setting of the DDS or by virtue of streaming being active, get that
238     // frequency.
239     if (state.clock_mode == FF_STATE_CLOCKMODE_AUTOSYNC) {
240         // FIXME: if synced to TCO, is autosync_freq valid?
241         fixed_freq = state.autosync_freq;
242     } else
243     if (m_dds_freq > 0) {
244         fixed_freq = m_dds_freq;
245     } else
246     if (hardware_is_streaming()) {
247         fixed_freq = m_software_freq;
248     }
249
250     // If the device is running to a fixed frequency, software can only
251     // request frequencies with the same multiplier.  Similarly, the
252     // multiplier is locked in "master" clock mode if the device is
253     // streaming.
254     if (fixed_freq > 0) {
255         signed int fixed_mult = multiplier_of_freq(fixed_freq);
256         if (multiplier_of_freq(freq) != multiplier_of_freq(fixed_freq))
257             return -1;
258         for (j=0; j<3; j++) {
259             if (freq == base_freq[j]*fixed_mult) {
260                 ret = 0;
261                 break;
262             }
263         }
264     } else {
265         for (i=0; i<3; i++) {
266             for (j=0; j<3; j++) {
267                 if (freq == base_freq[j]*mult[i]) {
268                     ret = 0;
269                     break;
270                 }
271             }
272         }
273     }
274     // If requested frequency is unavailable, return -1
275     if (ret == -1)
276         return false;
277
278     // If a DDS frequency has been explicitly requested this is always
279     // used to programm the hardware DDS regardless of the rate requested
280     // by the software.  Otherwise we use the requested sampling rate.
281     if (m_dds_freq > 0)
282         freq = m_dds_freq;
283     if (set_hardware_dds_freq(freq) != 0)
284         return false;
285
286     m_software_freq = samplingFrequency;
287     return true;
288 }
289
290 std::vector<int>
291 Device::getSupportedSamplingFrequencies()
292 {
293     std::vector<int> frequencies;
294     signed int i, j;
295     signed int mult[3] = {1, 2, 4};
296     signed int freq[3] = {32000, 44100, 48000};
297     FF_state_t state;
298
299     get_hardware_state(&state);
300
301     // Generate the list of supported frequencies.  If the device is
302     // externally clocked the frequency is limited to the external clock
303     // frequency.  If the device is running the multiplier is fixed.
304     if (state.clock_mode == FF_STATE_CLOCKMODE_MASTER) {
305         // FIXME: if synced to TCO, is autosync_freq valid?
306         frequencies.push_back(state.autosync_freq);
307     } else
308     if (hardware_is_streaming()) {
309         unsigned int fixed_mult = multiplier_of_freq(m_software_freq);
310         for (j=0; j<3; j++) {
311             frequencies.push_back(freq[j]*fixed_mult);
312         }
313     } else {
314         for (i=0; i<3; i++) {
315             for (j=0; j<3; j++) {
316                 frequencies.push_back(freq[j]*mult[i]);
317             }
318         }
319     }
320     return frequencies;
321 }
322
323 FFADODevice::ClockSourceVector
324 Device::getSupportedClockSources() {
325     FFADODevice::ClockSourceVector r;
326     return r;
327 }
328
329 bool
330 Device::setActiveClockSource(ClockSource s) {
331     return false;
332 }
333
334 FFADODevice::ClockSource
335 Device::getActiveClockSource() {
336     ClockSource s;
337     return s;
338 }
339
340 bool
341 Device::lock() {
342
343     return true;
344 }
345
346
347 bool
348 Device::unlock() {
349
350     return true;
351 }
352
353 void
354 Device::showDevice()
355 {
356     unsigned int vendorId = getConfigRom().getNodeVendorId();
357     unsigned int modelId = getConfigRom().getModelId();
358
359     Util::Configuration &c = getDeviceManager().getConfiguration();
360     Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId );
361
362     debugOutput(DEBUG_LEVEL_VERBOSE,
363         "%s %s at node %d\n", vme.vendor_name.c_str(), vme.model_name.c_str(), getNodeId());
364 }
365
366 bool
367 Device::prepare() {
368
369         debugOutput(DEBUG_LEVEL_NORMAL, "Preparing Device...\n" );
370
371         return true;
372 }
373
374 int
375 Device::getStreamCount() {
376         return 0; // one receive, one transmit
377 }
378
379 Streaming::StreamProcessor *
380 Device::getStreamProcessorByIndex(int i) {
381     return NULL;
382 }
383
384 bool
385 Device::startStreamByIndex(int i) {
386     return false;
387 }
388
389 bool
390 Device::stopStreamByIndex(int i) {
391     return false;
392
393 }
394
395 unsigned int
396 Device::readRegister(fb_nodeaddr_t reg) {
397
398     quadlet_t quadlet;
399    
400     quadlet = 0;
401     if (get1394Service().read(0xffc0 | getNodeId(), reg, 1, &quadlet) <= 0) {
402         debugError("Error doing RME read from register 0x%06x\n",reg);
403     }
404     return ByteSwapFromDevice32(quadlet);
405 }
406
407 signed int
408 Device::readBlock(fb_nodeaddr_t reg, quadlet_t *buf, unsigned int n_quads) {
409
410     unsigned int i;
411
412     if (get1394Service().read(0xffc0 | getNodeId(), reg, n_quads, buf) <= 0) {
413         debugError("Error doing RME block read of %d quadlets from register 0x%06x\n",
414             n_quads, reg);
415         return -1;
416     }
417     for (i=0; i<n_quads; i++) {
418        buf[i] = ByteSwapFromDevice32(buf[i]);
419     }
420
421     return 0;
422 }
423
424 signed int
425 Device::writeRegister(fb_nodeaddr_t reg, quadlet_t data) {
426
427     unsigned int err = 0;
428     data = ByteSwapToDevice32(data);
429     if (get1394Service().write(0xffc0 | getNodeId(), reg, 1, &data) <= 0) {
430         err = 1;
431         debugError("Error doing RME write to register 0x%06x\n",reg);
432     }
433     return (err==0)?0:-1;
434 }
435
436 signed int
437 Device::writeBlock(fb_nodeaddr_t reg, quadlet_t *data, unsigned int n_quads) {
438 //
439 // Write a block of data to the device starting at address "reg".  Note that
440 // the conditional byteswap is done "in place" on data, so the contents of
441 // data may be modified by calling this function.
442 //
443     unsigned int err = 0;
444     unsigned int i;
445
446     for (i=0; i<n_quads; i++) {
447       data[i] = ByteSwapToDevice32(data[i]);
448     }
449     if (get1394Service().write(0xffc0 | getNodeId(), reg, n_quads, data) <= 0) {
450         err = 1;
451         debugError("Error doing RME block write of %d quadlets to register 0x%06x\n",
452           n_quads, reg);
453     }
454     return (err==0)?0:-1;
455 }
456                  
457 }
Note: See TracBrowser for help on using the browser.