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

Revision 1592, 11.4 kB (checked in by jwoithe, 15 years ago)

RME: begin tidy-up of sampling rate control.
RME: start implementation of device status retrieval.

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 // Template for an RME Device object method which intelligently returns a
80 // register or value applicable to the connected model and warns if something
81 // isn't quite right.
82 #define MODEL_SELECTOR(_name,_ff400_arg,_ff800_arg) \
83 unsigned long long int \
84 Device::_name() { \
85     switch (m_rme_model) { \
86         case RME_MODEL_FIREFACE400: return _ff400_arg; \
87         case RME_MODEL_FIREFACE800: return _ff800_arg; \
88     default: \
89       debugOutput( DEBUG_LEVEL_WARNING, "Bad RME model %d\n", m_rme_model ); \
90   } \
91   return 0xffffffffffffffffLL; \
92 }
93
94 Device::Device( DeviceManager& d,
95                       std::auto_ptr<ConfigRom>( configRom ))
96     : FFADODevice( d, configRom )
97     , m_rme_model( RME_MODEL_NONE )
98     , is_streaming( 0 )
99     , m_dds_freq( -1 )
100     , m_software_freq( -1 )
101     , tco_present( 0 )
102 {
103     debugOutput( DEBUG_LEVEL_VERBOSE, "Created Rme::Device (NodeID %d)\n",
104                  getConfigRom().getNodeId() );
105 }
106
107 Device::~Device()
108 {
109
110 }
111
112 MODEL_SELECTOR(cmd_buffer_addr, RME_FF400_CMD_BUFFER, RME_FF800_CMD_BUFFER)
113 MODEL_SELECTOR(stream_init_reg, RME_FF400_STREAM_INIT_REG, RME_FF800_STREAM_INIT_REG)
114 MODEL_SELECTOR(stream_start_reg, RME_FF400_STREAM_START_REG, RME_FF800_STREAM_START_REG)
115 MODEL_SELECTOR(stream_end_reg, RME_FF400_STREAM_END_REG, RME_FF800_STREAM_END_REG)
116 MODEL_SELECTOR(flash_settings_addr, RME_FF400_FLASH_SETTINGS_ADDR, RME_FF800_FLASH_SETTINGS_ADDR)
117 MODEL_SELECTOR(flash_mixer_vol_addr, RME_FF400_FLASH_MIXER_VOLUME_ADDR, RME_FF800_FLASH_MIXER_VOLUME_ADDR)
118 MODEL_SELECTOR(flash_mixer_pan_addr, RME_FF400_FLASH_MIXER_PAN_ADDR, RME_FF800_FLASH_MIXER_PAN_ADDR)
119 MODEL_SELECTOR(flash_mixer_hw_addr, RME_FF400_FLASH_MIXER_HW_ADDR, RME_FF800_FLASH_MIXER_HW_ADDR)
120
121 bool
122 Device::probe( Util::Configuration& c, ConfigRom& configRom, bool generic )
123 {
124     if (generic) {
125         return false;
126     } else {
127         // check if device is in supported devices list.  Note that the RME
128         // devices use the unit version to identify the individual devices.
129         // To avoid having to extend the configuration file syntax to
130         // include this at this point, we'll use the configuration file
131         // model ID to test against the device unit version.  This can be
132         // tidied up if the configuration file is extended at some point to
133         // include the unit version.
134         unsigned int vendorId = configRom.getNodeVendorId();
135         unsigned int unitVersion = configRom.getUnitVersion();
136
137         Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, unitVersion );
138         return c.isValid(vme) && vme.driver == Util::Configuration::eD_RME;
139     }
140 }
141
142 FFADODevice *
143 Device::createDevice(DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
144 {
145     return new Device(d, configRom );
146 }
147
148 bool
149 Device::discover()
150 {
151     unsigned int vendorId = getConfigRom().getNodeVendorId();
152     // See note in Device::probe() about why we use the unit version here.
153     unsigned int unitVersion = getConfigRom().getUnitVersion();
154
155     Util::Configuration &c = getDeviceManager().getConfiguration();
156     Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, unitVersion );
157
158     if (c.isValid(vme) && vme.driver == Util::Configuration::eD_RME) {
159         debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
160                      vme.vendor_name.c_str(),
161                      vme.model_name.c_str());
162     } else {
163         debugWarning("Device '%s %s' unsupported by RME driver (no generic RME support)\n",
164                      getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str());
165     }
166
167     if (unitVersion == RME_UNITVERSION_FF800) {
168         m_rme_model = RME_MODEL_FIREFACE800;
169     } else
170     if (unitVersion == RME_MODEL_FIREFACE400) {
171         m_rme_model = RME_MODEL_FIREFACE400;
172     } else {
173         debugError("Unsupported model\n");
174         return false;
175     }
176
177     // If device is FF800, check to see if the TCO is fitted
178     if (m_rme_model == RME_MODEL_FIREFACE800) {
179         tco_present = (read_tco(NULL, 0) == 0);
180     }
181
182     init_hardware();
183
184     // This is just for testing
185     read_device_flash_settings(NULL);
186
187     return true;
188 }
189
190 int
191 Device::getSamplingFrequency( ) {
192 /*
193  * Retrieve the current sample rate from the RME device.  At this stage it
194  * seems that the "current rate" can't be retrieved from the device.  Other
195  * drivers don't read the DDS control register and there isn't anywhere else
196  * where the frequency is sent back to the PC.  Unless we test the DDS
197  * control register for readabilty and find it can be read we'll assume it
198  * can't and instead cache the DDS frequency.
199  *
200  * If the device frequency has not been set this function will return -1
201  * (the default value of m_ddsFreq).
202  */
203     return m_software_freq;
204 }
205
206 int
207 Device::getConfigurationId()
208 {
209     return 0;
210 }
211
212 bool
213 Device::setSamplingFrequency( int samplingFrequency )
214 {
215     // Request a sampling rate on behalf of software.  Software is limited
216     // to sample rates of 32k, 44.1k, 48k and the 2x/4x multiples of these.
217     // The user may lock the device to a much wider range of frequencies via
218     // the explicit DDS controls in the control panel.  If the explicit DDS
219     // control is active the software is limited to the "standard" speeds
220     // corresponding to the multiplier in use by the DDS.
221     //
222     // Similarly, if the device is externally clocked the software is
223     // limited to the external clock frequency.
224     //
225     // Otherwise the software has free choice of the software speeds noted
226     // above.
227
228     bool ret = -1;
229     signed int i, j;
230     signed int mult[3] = {1, 2, 4};
231     signed int freq[3] = {32000, 44100, 48000};
232
233     /* Work out whether the requested rate is supported */
234     for (i=0; i<3; i++) {
235         for (j=0; j<3; i++) {
236             if (samplingFrequency==freq[j]*mult[i]) {
237                 ret = 0;
238                 break;
239             }
240         }
241     }
242     if (ret == -1)
243         return false;
244
245     // FIXME: still have to verify compatibility with current rate if
246     // running, DDS if set or external clock if relevant.
247
248     if (set_hardware_dds_freq(samplingFrequency) != 0)
249         return false;
250
251     m_software_freq = samplingFrequency;
252     return true;
253 }
254
255 std::vector<int>
256 Device::getSupportedSamplingFrequencies()
257 {
258     std::vector<int> frequencies;
259     signed int i, j;
260     signed int mult[3] = {1, 2, 4};
261     signed int freq[3] = {32000, 44100, 48000};
262
263     // Generate the list of supported frequencies
264     // FIXME: this could be limited based on the device's current status
265     for (i=0; i<3; i++) {
266         for (j=0; j<3; i++) {
267             frequencies.push_back(freq[j]*mult[i]);
268         }
269     }
270     return frequencies;
271 }
272
273 FFADODevice::ClockSourceVector
274 Device::getSupportedClockSources() {
275     FFADODevice::ClockSourceVector r;
276     return r;
277 }
278
279 bool
280 Device::setActiveClockSource(ClockSource s) {
281     return false;
282 }
283
284 FFADODevice::ClockSource
285 Device::getActiveClockSource() {
286     ClockSource s;
287     return s;
288 }
289
290 bool
291 Device::lock() {
292
293     return true;
294 }
295
296
297 bool
298 Device::unlock() {
299
300     return true;
301 }
302
303 void
304 Device::showDevice()
305 {
306     unsigned int vendorId = getConfigRom().getNodeVendorId();
307     unsigned int modelId = getConfigRom().getModelId();
308
309     Util::Configuration &c = getDeviceManager().getConfiguration();
310     Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId );
311
312     debugOutput(DEBUG_LEVEL_VERBOSE,
313         "%s %s at node %d\n", vme.vendor_name.c_str(), vme.model_name.c_str(), getNodeId());
314 }
315
316 bool
317 Device::prepare() {
318
319         debugOutput(DEBUG_LEVEL_NORMAL, "Preparing Device...\n" );
320
321         return true;
322 }
323
324 int
325 Device::getStreamCount() {
326         return 0; // one receive, one transmit
327 }
328
329 Streaming::StreamProcessor *
330 Device::getStreamProcessorByIndex(int i) {
331     return NULL;
332 }
333
334 bool
335 Device::startStreamByIndex(int i) {
336     return false;
337 }
338
339 bool
340 Device::stopStreamByIndex(int i) {
341     return false;
342
343 }
344
345 unsigned int
346 Device::readRegister(fb_nodeaddr_t reg) {
347
348     quadlet_t quadlet;
349    
350     quadlet = 0;
351     if (get1394Service().read(0xffc0 | getNodeId(), reg, 1, &quadlet) <= 0) {
352         debugError("Error doing RME read from register 0x%06x\n",reg);
353     }
354     return ByteSwapFromDevice32(quadlet);
355 }
356
357 signed int
358 Device::readBlock(fb_nodeaddr_t reg, quadlet_t *buf, unsigned int n_quads) {
359
360     unsigned int i;
361
362     if (get1394Service().read(0xffc0 | getNodeId(), reg, n_quads, buf) <= 0) {
363         debugError("Error doing RME block read of %d quadlets from register 0x%06x\n",
364             n_quads, reg);
365         return -1;
366     }
367     for (i=0; i<n_quads; i++) {
368        buf[i] = ByteSwapFromDevice32(buf[i]);
369     }
370
371     return 0;
372 }
373
374 signed int
375 Device::writeRegister(fb_nodeaddr_t reg, quadlet_t data) {
376
377     unsigned int err = 0;
378     data = ByteSwapToDevice32(data);
379     if (get1394Service().write(0xffc0 | getNodeId(), reg, 1, &data) <= 0) {
380         err = 1;
381         debugError("Error doing RME write to register 0x%06x\n",reg);
382     }
383     return (err==0)?0:-1;
384 }
385
386 signed int
387 Device::writeBlock(fb_nodeaddr_t reg, quadlet_t *data, unsigned int n_quads) {
388 //
389 // Write a block of data to the device starting at address "reg".  Note that
390 // the conditional byteswap is done "in place" on data, so the contents of
391 // data may be modified by calling this function.
392 //
393     unsigned int err = 0;
394     unsigned int i;
395
396     for (i=0; i<n_quads; i++) {
397       data[i] = ByteSwapToDevice32(data[i]);
398     }
399     if (get1394Service().write(0xffc0 | getNodeId(), reg, n_quads, data) <= 0) {
400         err = 1;
401         debugError("Error doing RME block write of %d quadlets to register 0x%06x\n",
402           n_quads, reg);
403     }
404     return (err==0)?0:-1;
405 }
406                  
407 }
Note: See TracBrowser for help on using the browser.