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

Revision 1605, 14.5 kB (checked in by jwoithe, 15 years ago)

RME: implement the beginnings of a device control interface via the ffado dbus framework.
MOTU: fix error handling code paths in buildMixer() and destroyMixer().

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