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

Revision 1622, 16.5 kB (checked in by jwoithe, 14 years ago)

RME: input, output and phones mixer/control elements now control respective device parameters

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