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

Revision 1616, 16.0 kB (checked in by jwoithe, 14 years ago)

RME: minor documentation corrections
RME: the Fireface-400 input gain mixer controls now drive the hardware. Control of the output gains is also included in this infrastructure but is not connected to any mixer controls yet - they will be controlled by the mixer proper once that's implemented.

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