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

Revision 1596, 22.4 kB (checked in by jwoithe, 14 years ago)

RME:

  • implement lowlevel streaming control/setup/status functions
  • fill in further status register details
  • update documentation
Line 
1 /*
2  * Copyright (C) 2009 by Jonathan Woithe
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB.
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 /* This file implements miscellaneous lower-level hardware functions for the Fireface */
25
26 #include "rme/rme_avdevice.h"
27 #include "rme/fireface_def.h"
28
29 #include "debugmodule/debugmodule.h"
30
31 namespace Rme {
32
33 unsigned int
34 Device::multiplier_of_freq(unsigned int freq)
35 {
36   if (freq > MIN_QUAD_SPEED)
37     return 4;
38   if (freq > MIN_DOUBLE_SPEED)
39     return 2;
40   return 1;
41 }
42
43 signed int
44 Device::init_hardware(void)
45 {
46     // Initialises the device's settings structure to a known state and then
47     // sets the hardware to reflect this state.
48     //
49     // In time this function may read a cached device setup and initialise
50     // based on that.  It may also read the device configuration from the
51     // device flash and adopt that.  For now (for initial testing purposes)
52     // we'll go with a static state.
53     memset(&settings, 0, sizeof(settings));
54     settings.spdif_input_mode = FF_SWPARAM_SPDIF_INPUT_COAX;
55     settings.spdif_output_mode = FF_SWPARAM_SPDIF_OUTPUT_COAX;
56     settings.clock_mode = FF_SWPARAM_CLOCK_MODE_MASTER;
57     settings.sync_ref = FF_SWPARAM_SYNCREF_WORDCLOCK;
58     settings.input_level = FF_SWPARAM_ILEVEL_LOGAIN;
59     settings.output_level = FF_SWPARAM_OLEVEL_HIGAIN;
60
61     // A default sampling rate.  An explicit DDS frequency is not enabled
62     // by default.
63     m_software_freq = 44100;
64     m_dds_freq = 0;
65
66     return set_hardware_params(&settings);
67 }
68
69 signed int
70 Device::get_hardware_status(unsigned int *stat0, unsigned int *stat1)
71 {
72     unsigned int buf[2];
73     if (readBlock(RME_FF_STATUS_REG0, buf, 2) != 0)
74         return -1;
75     *stat0 = buf[0];
76     *stat1 = buf[1];
77     return 0;
78 }
79
80 signed int
81 Device::get_hardware_streaming_status(unsigned int *stat, unsigned int n)
82 {
83     // Get the hardware status as it applies to the streaming system.  This
84     // involves a request of 4 quadlets from the status register.  It
85     // appears that the first register's definition is slightly different in
86     // this situation compared to when only 2 quadlets are requested as is
87     // done in get_hardware_status().
88     //
89     // "n" is the size of the passed-in stat array.  It must be >= 4.
90     if (n < 4)
91         return -1;
92     if (readBlock(RME_FF_STATUS_REG0, stat, 4) != 0)
93         return -1;
94     return 0;
95 }
96
97 signed int
98 Device::get_hardware_state(FF_state_t *state)
99 {
100     // Retrieve the hardware status and deduce the device state.  Return
101     // -1 on error, 0 on success.  The given state structure will be
102     // cleared by this call.
103     unsigned int stat0, stat1;
104     memset(state, 0, sizeof(*state));
105     if (get_hardware_status(&stat0, &stat1) != 0)
106         return -1;
107
108     state->is_streaming = (stat0 & SR0_IS_STREAMING) != 0;
109
110     state->clock_mode = (settings.clock_mode == FF_SWPARAM_CLOCK_MODE_MASTER)?FF_STATE_CLOCKMODE_MASTER:FF_STATE_CLOCKMODE_AUTOSYNC;
111
112     switch (stat0 & SR0_AUTOSYNC_SRC_MASK) {
113         case SR0_AUTOSYNC_SRC_ADAT1:
114             state->autosync_source = FF_STATE_AUTOSYNC_SRC_ADAT1;
115             break;
116         case SR0_AUTOSYNC_SRC_ADAT2:
117             state->autosync_source = FF_STATE_AUTOSYNC_SRC_ADAT2;
118             break;
119         case SR0_AUTOSYNC_SRC_SPDIF:
120             state->autosync_source = FF_STATE_AUTOSYNC_SRC_SPDIF;
121             break;
122         case SR0_AUTOSYNC_SRC_WCLK:
123             state->autosync_source = FF_STATE_AUTOSYNC_SRC_WCLK;
124             break;
125         case SR0_AUTOSYNC_SRC_TCO:
126             state->autosync_source = FF_STATE_AUTOSYNC_SRC_TCO;
127             break;
128         default: state->autosync_source = FF_STATE_AUTOSYNC_SRC_NOLOCK;
129     }
130
131     switch (stat0 & SR0_AUTOSYNC_FREQ_MASK) {
132         case SR0_AUTOSYNC_FREQ_32k:  state->autosync_freq = 32000; break;
133         case SR0_AUTOSYNC_FREQ_44k1: state->autosync_freq = 44100; break;
134         case SR0_AUTOSYNC_FREQ_48k:  state->autosync_freq = 48000; break;
135         case SR0_AUTOSYNC_FREQ_64k:  state->autosync_freq = 64000; break;
136         case SR0_AUTOSYNC_FREQ_88k2: state->autosync_freq = 88200; break;
137         case SR0_AUTOSYNC_FREQ_96k:  state->autosync_freq = 96000; break;
138         case SR0_AUTOSYNC_FREQ_128k: state->autosync_freq = 128000; break;
139         case SR0_AUTOSYNC_FREQ_176k4:state->autosync_freq = 176400; break;
140         case SR0_AUTOSYNC_FREQ_192k: state->autosync_freq = 192000; break;
141     }
142
143     switch (stat0 & SR0_SPDIF_FREQ_MASK) {
144         case SR0_SPDIF_FREQ_32k:  state->spdif_freq = 32000; break;
145         case SR0_SPDIF_FREQ_44k1: state->spdif_freq = 41000; break;
146         case SR0_SPDIF_FREQ_48k:  state->spdif_freq = 48000; break;
147         case SR0_SPDIF_FREQ_64k:  state->spdif_freq = 64000; break;
148         case SR0_SPDIF_FREQ_88k2: state->spdif_freq = 88200; break;
149         case SR0_SPDIF_FREQ_96k:  state->spdif_freq = 96000; break;
150         case SR0_SPDIF_FREQ_128k: state->spdif_freq = 128000; break;
151         case SR0_SPDIF_FREQ_176k4:state->spdif_freq = 176400; break;
152         case SR0_SPDIF_FREQ_192k: state->spdif_freq = 192000; break;
153     }
154
155     switch (stat0 & SR0_ADAT1_STATUS_MASK) {
156         case SR0_ADAT1_STATUS_NOLOCK:
157             state->adat1_sync_status = FF_STATE_SYNC_NOLOCK; break;
158         case SR0_ADAT1_STATUS_LOCK:
159             state->adat1_sync_status = FF_STATE_SYNC_LOCKED; break;
160         case SR0_ADAT1_STATUS_SYNC:
161             state->adat1_sync_status = FF_STATE_SYNC_SYNCED; break;
162     }
163     switch (stat0 & SR0_ADAT2_STATUS_MASK) {
164         case SR0_ADAT2_STATUS_NOLOCK:
165             state->adat2_sync_status = FF_STATE_SYNC_NOLOCK; break;
166         case SR0_ADAT2_STATUS_LOCK:
167             state->adat2_sync_status = FF_STATE_SYNC_LOCKED; break;
168         case SR0_ADAT2_STATUS_SYNC:
169             state->adat2_sync_status = FF_STATE_SYNC_SYNCED; break;
170     }
171     switch (stat0 & SR0_SPDIF_STATUS_MASK) {
172         case SR0_SPDIF_STATUS_NOLOCK:
173             state->spdif_sync_status = FF_STATE_SYNC_NOLOCK; break;
174         case SR0_SPDIF_STATUS_LOCK:
175             state->spdif_sync_status = FF_STATE_SYNC_LOCKED; break;
176         case SR0_SPDIF_STATUS_SYNC:
177             state->spdif_sync_status = FF_STATE_SYNC_SYNCED; break;
178     }
179     switch (stat0 & SR0_WCLK_STATUS_MASK) {
180         case SR0_WCLK_STATUS_NOLOCK:
181             state->wclk_sync_status = FF_STATE_SYNC_NOLOCK; break;
182         case SR0_WCLK_STATUS_LOCK:
183             state->wclk_sync_status = FF_STATE_SYNC_LOCKED; break;
184         case SR0_WCLK_STATUS_SYNC:
185             state->wclk_sync_status = FF_STATE_SYNC_SYNCED; break;
186     }
187     switch (stat1 & SR1_TCO_STATUS_MASK) {
188        case SR1_TCO_STATUS_NOLOCK:
189            state->tco_sync_status = FF_STATE_SYNC_NOLOCK; break;
190        case SR1_TCO_STATUS_LOCK:
191            state->tco_sync_status = FF_STATE_SYNC_LOCKED; break;
192        case SR1_TCO_STATUS_SYNC:
193            state->tco_sync_status = FF_STATE_SYNC_SYNCED; break;
194     }
195
196     return 0;
197 }
198
199 signed int
200 Device::set_hardware_params(FF_software_settings_t *sw_settings)
201 {
202     // Initialises the hardware to the state defined by the supplied
203     // software settings structure (which will usually be the device's
204     // "settings" structure).  This has the side effect of extinguishing the
205     // "Host" LED on the FF400 when done for the first time after the
206     // interface has been powered up.
207
208     quadlet_t data[3] = {0, 0, 0};
209     unsigned int conf_reg;
210
211     if (sw_settings->mic_phantom[0])
212       data[0] |= CR0_PHANTOM_MIC0;
213     if (sw_settings->mic_phantom[1])
214       data[0] |= CR0_PHANTOM_MIC1;
215     if (sw_settings->mic_phantom[2])
216       data[0] |= CR0_PHANTOM_MIC2;
217     if (sw_settings->mic_phantom[3])
218       data[0] |= CR0_PHANTOM_MIC3;
219
220     /* Phones level */
221     switch (sw_settings->phones_level) {
222         case FF_SWPARAM_PHONESLEVEL_HIGAIN:
223             data[0] |= CRO_PHLEVEL_HIGAIN;
224             break;
225         case FF_SWPARAM_PHONESLEVEL_4dBU:
226             data[0] |= CR0_PHLEVEL_4dBU;
227             break;
228         case FF_SWPARAM_PHONESLEVEL_m10dBV:
229             data[0] |= CRO_PHLEVEL_m10dBV;
230             break;
231     }
232
233     /* Input level */
234     switch (sw_settings->input_level) {
235         case FF_SWPARAM_ILEVEL_LOGAIN: // Low gain
236             data[1] |= CR1_ILEVEL_CPLD_LOGAIN;    // CPLD
237             data[0] |= CR0_ILEVEL_FPGA_LOGAIN;    // LED control (used on FF800 only)
238             break;
239         case FF_SWPARAM_ILEVEL_4dBU:   // +4 dBu
240             data[1] |= CR1_ILEVEL_CPLD_4dBU;
241             data[0] |= CR0_ILEVEL_FPGA_4dBU;
242             break;
243         case FF_SWPARAM_ILEVEL_m10dBV: // -10 dBV
244             data[1] |= CR1_ILEVEL_CPLD_m10dBV;
245             data[0] |= CR0_ILEVEL_FPGA_m10dBV;
246             break;
247     }
248
249     /* Output level */
250     switch (sw_settings->output_level) {
251         case FF_SWPARAM_OLEVEL_HIGAIN: // High gain
252             data[1] |= CR1_OLEVEL_CPLD_HIGAIN;   // CPLD
253             data[0] |= CR0_OLEVEL_FPGA_HIGAIN;   // LED control (used on FF800 only)
254             break;
255         case FF_SWPARAM_OLEVEL_4dBU:   // +4 dBu
256             data[1] |= CR1_OLEVEL_CPLD_4dBU;
257             data[0] |= CR0_OLEVEL_FPGA_4dBU;
258             break;
259         case FF_SWPARAM_OLEVEL_m10dBV: // -10 dBV
260             data[1] |= CR1_OLEVEL_CPLD_m10dBV;
261             data[0] |= CR0_OLEVEL_FPGA_m10dBV;
262             break;
263     }
264
265     /* Set input options.  The meaning of the options differs between
266      * devices, so we use the generic identifiers here.
267      */
268     data[1] |= (sw_settings->input_opt[1] & FF_SWPARAM_INPUT_OPT_A) ? CR1_INPUT_OPT1_A : 0;
269     data[1] |= (sw_settings->input_opt[1] & FF_SWPARAM_INPUT_OPT_B) ? CR1_INPUT_OPT1_B : 0;
270     data[1] |= (sw_settings->input_opt[2] & FF_SWPARAM_INPUT_OPT_A) ? CR1_INPUT_OPT2_A : 0;
271     data[1] |= (sw_settings->input_opt[2] & FF_SWPARAM_INPUT_OPT_B) ? CR1_INPUT_OPT2_B : 0;
272
273     // Drive the speaker emulation / filter LED via FPGA
274     data[0] |= (sw_settings->filter) ? CR0_FILTER_FPGA : 0;
275
276     // Set the "rear" option for input 0 if selected
277     data[1] |= (sw_settings->input_opt[0] & FF_SWPARAM_FF800_INPUT_OPT_REAR) ? CR1_FF800_INPUT1_REAR : 0;
278
279     // The input 0 "front" option is activated using one of two bits
280     // depending on whether the filter (aka "speaker emulation") setting is
281     // active.
282     if (sw_settings->input_opt[0] & FF_SWPARAM_FF800_INPUT_OPT_FRONT) {
283         data[1] |= (sw_settings->filter) ? CR1_FF800_INPUT1_FRONT_WITH_FILTER : CR1_FF800_INPUT1_FRONT;
284     }
285
286     data[2] |= (sw_settings->spdif_output_emphasis==FF_SWPARAM_SPDIF_OUTPUT_EMPHASIS_ON) ? CR2_SPDIF_OUT_EMP : 0;
287     data[2] |= (sw_settings->spdif_output_pro==FF_SWPARAM_SPDIF_OUTPUT_PRO_ON) ? CR2_SPDIF_OUT_PRO : 0;
288     data[2] |= (sw_settings->spdif_output_nonaudio==FF_SWPARAM_SPDIF_OUTPUT_NONAUDIO_ON) ? CR2_SPDIF_OUT_NONAUDIO : 0;
289     data[2] |= (sw_settings->spdif_output_mode==FF_SWPARAM_SPDIF_OUTPUT_OPTICAL) ? CR2_SPDIF_OUT_ADAT2 : 0;
290     data[2] |= (sw_settings->clock_mode==FF_SWPARAM_CLOCK_MODE_AUTOSYNC) ? CR2_CLOCKMODE_AUTOSYNC : CR2_CLOCKMODE_MASTER;
291     data[2] |= (sw_settings->spdif_input_mode==FF_SWPARAM_SPDIF_INPUT_COAX) ? CR2_SPDIF_IN_COAX : CR2_SPDIF_IN_ADAT2;
292     data[2] |= (sw_settings->word_clock_single_speed=FF_SWPARAM_WORD_CLOCK_1x) ? CR2_WORD_CLOCK_1x : 0;
293
294     /* TMS / TCO toggle bits in CR2 are not set by other drivers */
295
296     /* Drive / fuzz */
297     if (sw_settings->fuzz)
298       data[0] |= CR0_INSTR_DRIVE_FPGA; // FPGA LED control
299     else
300       data[1] |= CR1_INSTR_DRIVE;      // CPLD
301
302     /* Drop-and-stop is hardwired on in other drivers */
303     data[2] |= CR2_DROP_AND_STOP;
304
305     if (m_rme_model == RME_MODEL_FIREFACE400) {
306         data[2] |= CR2_FF400_BIT;
307     }
308
309     switch (sw_settings->sync_ref) {
310         case FF_SWPARAM_SYNCREF_WORDCLOCK:
311             data[2] |= CR2_SYNC_WORDCLOCK;
312             break;
313         case FF_SWPARAM_SYNCREF_ADAT1:
314             data[2] |= CR2_SYNC_ADAT1;
315             break;
316         case FF_SWPARAM_SYNCREF_ADAT2:
317             data[2] |= CR2_SYNC_ADAT2;
318             break;
319         case FF_SWPARAM_SYNCREF_SPDIF:
320             data[2] |= CR2_SYNC_SPDIF;
321             break;
322         case FF_SWPARAM_SYNCREC_TCO:
323             data[2] |= CR2_SYNC_TCO;
324             break;
325     }
326
327     // This is hardwired in other drivers
328     data[2] |= (CR2_FREQ0 + CR2_FREQ1 + CR2_DSPEED + CR2_QSSPEED);
329
330     // The FF800 limiter applies to the front panel instrument input, so it
331     // only makes sense that it is disabled when that input is in use.
332     data[2] |= (sw_settings->limiter_disable &&
333                 (sw_settings->input_opt[0] & FF_SWPARAM_FF800_INPUT_OPT_FRONT)) ?
334                 CR2_DISABLE_LIMITER : 0;
335
336 //This is just for testing - it's a known consistent configuration
337 //data[0] = 0x00020811;      // Phantom off
338 data[0] = 0x00020811;      // Phantom on
339 data[1] = 0x0000031e;
340 data[2] = 0xc400101f;
341
342     conf_reg = (m_rme_model==RME_MODEL_FIREFACE800)?RME_FF800_CONF_REG:RME_FF400_CONF_REG;
343     if (writeBlock(conf_reg, data, 3) != 0)
344         return -1;
345
346     return -0;
347 }
348
349 signed int
350 Device::read_tco(quadlet_t *tco_data, signed int size)
351 {
352     // Read the TCO registers and return the respective values in *tco_data.
353     // Return value is 0 on success, or -1 if there is no TCO present.
354     // "size" is the size (in quadlets) of the array pointed to by tco_data.
355     // To obtain all TCO data "size" should be at least 4.  If the caller
356     // doesn't care about the data returned by the TCO, tco_data can be
357     // NULL.
358     quadlet_t buf[4];
359     signed int i;
360
361     // The Fireface 400 can't have the TCO fitted
362     if (m_rme_model==RME_MODEL_FIREFACE400)
363         return -1;
364
365     if (readBlock(RME_FF_TCO_READ_REG, buf, 4) != 0)
366         return -1;
367
368     if (tco_data != NULL) {
369         for (i=0; i<(size<4)?size:4; i++)
370             tco_data[i] = buf[i];
371     }
372
373     if ( (buf[0] & 0x80808080) == 0x80808080 &&
374          (buf[1] & 0x80808080) == 0x80808080 &&
375          (buf[2] & 0x80808080) == 0x80808080 &&
376          (buf[3] & 0x8000FFFF) == 0x80008000) {
377         // A TCO is present
378         return 0;
379     }
380
381     return -1;
382 }
383
384 signed int
385 Device::write_tco(quadlet_t *tco_data, signed int size)
386 {
387     // Writes data to the TCO.  No check is made as to whether a TCO is
388     // present in the current device.  Return value is 0 on success or -1 on
389     // error.  "size" is the size (in quadlets) of the data pointed to by
390     // "tco_data".  The first 4 quadlets of tco_data are significant; all
391     // others are ignored.  If fewer than 4 quadlets are supplied (as
392     // indicated by the "size" parameter, -1 will be returned.
393     if (size < 4)
394         return -1;
395
396     // Don't bother trying to write if the device is a FF400 since the TCO
397     // can't be fitted to this device.
398     if (m_rme_model==RME_MODEL_FIREFACE400)
399         return -1;
400
401     if (writeBlock(RME_FF_TCO_WRITE_REG, tco_data, 4) != 0)
402         return -1;
403
404     return 0;
405 }
406
407 signed int
408 Device::hardware_is_streaming(void)
409 {
410     // Return 1 if the hardware is streaming, 0 if not.
411     unsigned int s1, s2;
412     if (get_hardware_status(&s1, &s2) != 0)
413         return 0;
414     return (s1 & SR0_IS_STREAMING) != 0;
415 }
416
417 signed int
418 Device::read_tco_state(FF_TCO_state_t *tco_state)
419 {
420     // Reads the current TCO state into the supplied state structure
421
422     quadlet_t tc[4];
423     unsigned int PLL_phase;
424
425     if (read_tco(tc, 4) != 0)
426       return -1;
427
428     // The timecode is stored in BCD (binary coded decimal) in register 0.
429     tco_state->frames = (tc[0] & 0xf) + ((tc[0] & 0x30) >> 4)*10;
430     tco_state->seconds = ((tc[0] & 0xf00) >> 8) + ((tc[0] & 0x7000) >> 12)*10;
431     tco_state->minutes = ((tc[0] & 0xf0000) >> 16) + ((tc[0] & 0x700000) >> 20)*10;
432     tco_state->hours = ((tc[0] & 0xf000000) >> 24) + ((tc[0] & 0x30000000) >> 28)*10;
433
434     tco_state->locked = (tc[1] & FF_TCO1_TCO_lock) != 0;
435     tco_state->ltc_valid = (tc[1] & FF_TCO1_LTC_INPUT_VALID) != 0;
436
437     switch (tc[1] & FF_TCO1_LTC_FORMAT_MASK) {
438         case FF_TC01_LTC_FORMAT_24fps:
439           tco_state->frame_rate = FF_TCOSTATE_FRAMERATE_24fps; break;
440         case FF_TCO1_LTC_FORMAT_25fps:
441           tco_state->frame_rate = FF_TCOSTATE_FRAMERATE_25fps; break;
442         case FF_TC01_LTC_FORMAT_29_97fps:
443           tco_state->frame_rate = FF_TCOSTATE_FRAMERATE_29_97fps; break;
444         case FF_TCO1_LTC_FORMAT_30fps:
445           tco_state->frame_rate = FF_TCOSTATE_FRAMERATE_30fps; break;
446     }
447
448     tco_state->drop_frame = (tc[1] & FF_TCO1_SET_DROPFRAME) != 0;
449
450     switch (tc[1] & FF_TCO1_VIDEO_INPUT_MASK) {
451         case FF_TCO1_VIDEO_INPUT_NTSC:
452             tco_state->video_input = FF_TCOSTATE_VIDEO_NTSC; break;
453         case FF_TCO1_VIDEO_INPUT_PAL:
454             tco_state->video_input = FF_TCOSTATE_VIDEO_PAL; break;
455         default:
456             tco_state->video_input = FF_TCOSTATE_VIDEO_NONE;
457     }
458
459     if ((tc[1] & FF_TCO1_WORD_CLOCK_INPUT_VALID) == 0) {
460         tco_state->word_clock_state = FF_TCOSTATE_WORDCLOCK_NONE;
461     } else {
462         switch (tc[1] & FF_TCO1_WORD_CLOCK_INPUT_MASK) {
463             case FF_TCO1_WORD_CLOCK_INPUT_1x:
464                 tco_state->word_clock_state = FF_TCOSTATE_WORDCLOCK_1x; break;
465             case FF_TCO1_WORD_CLOCK_INPUT_2x:
466                 tco_state->word_clock_state = FF_TCOSTATE_WORDCLOCK_2x; break;
467             case FF_TCO1_WORD_CLOCK_INPUT_4x:
468                 tco_state->word_clock_state = FF_TCOSTATE_WORDCLOCK_4x; break;
469         }
470     }
471
472     PLL_phase = (tc[2] & 0x7f) + ((tc[2] & 0x7f00) >> 1);
473     tco_state->sample_rate = (25000000.0 * 16.0)/PLL_phase;
474
475     return 0;
476 }
477
478 signed int
479 Device::write_tco_settings(FF_TCO_settings_t *tco_settings)
480 {
481     // Writes the supplied application-level settings to the device's TCO
482     // (Time Code Option).  Don't bother doing anything if the device doesn't
483     // have a TCO fitted.  Returns 0 on success, -1 on error.
484
485     quadlet_t tc[4] = {0, 0, 0, 0};
486
487     if (!tco_present) {
488         return -1;
489     }
490
491     if (tco_settings->MTC)
492         tc[0] |= FF_TCO0_MTC;
493
494     switch (tco_settings->input) {
495         case FF_TCOPARAM_INPUT_LTC:
496             tc[2] |= FF_TCO2_INPUT_LTC; break;
497         case FF_TCOPARAM_INPUT_VIDEO:
498             tc[2] |= FF_TCO2_INPUT_VIDEO; break;
499         case FF_TCOPARAM_INPUT_WCK:
500             tc[2] |= FF_TCO2_INPUT_WORD_CLOCK; break;
501     }
502
503     switch (tco_settings->frame_rate) {
504         case FF_TCOPARAM_FRAMERATE_24fps:
505             tc[1] |= FF_TC01_LTC_FORMAT_24fps; break;
506         case FF_TCOPARAM_FRAMERATE_25fps:
507             tc[1] |= FF_TCO1_LTC_FORMAT_25fps; break;
508         case FF_TCOPARAM_FRAMERATE_29_97fps:
509             tc[1] |= FF_TC01_LTC_FORMAT_29_97fps; break;
510         case FF_TCOPARAM_FRAMERATE_29_97dfps:
511             tc[1] |= FF_TCO1_LTC_FORMAT_29_97dpfs; break;
512         case FF_TCOPARAM_FRAMERATE_30fps:
513             tc[1] |= FF_TCO1_LTC_FORMAT_30fps; break;
514         case FF_TCOPARAM_FRAMERATE_30dfps:
515             tc[1] |= FF_TCO1_LTC_FORMAT_30dfps; break;
516     }
517
518     switch (tco_settings->word_clock) {
519         case FF_TCOPARAM_WORD_CLOCK_CONV_1_1:
520             tc[2] |= FF_TCO2_WORD_CLOCK_CONV_1_1; break;
521         case FF_TCOPARAM_WORD_CLOCK_CONV_44_48:
522             tc[2] |= FF_TCO2_WORD_CLOCK_CONV_44_48; break;
523         case FF_TCOPARAM_WORD_CLOCK_CONV_48_44:
524             tc[2] |= FF_TCO2_WORD_CLOCK_CONV_48_44; break;
525     }
526
527     switch (tco_settings->sample_rate) {
528         case FF_TCOPARAM_SRATE_44_1:
529             tc[2] |= FF_TCO2_SRATE_44_1; break;
530         case FF_TCOPARAM_SRATE_48:
531             tc[2] |= FF_TCO2_SRATE_48; break;
532         case FF_TCOPARAM_SRATE_FROM_APP:
533             tc[2] |= FF_TCO2_SRATE_FROM_APP; break;
534     }
535
536     switch (tco_settings->pull) {
537         case FF_TCPPARAM_PULL_NONE:
538             tc[2] |= FF_TCO2_PULL_0; break;
539         case FF_TCOPARAM_PULL_UP_01:
540             tc[2] |= FF_TCO2_PULL_UP_01; break;
541         case FF_TCOPARAM_PULL_DOWN_01:
542             tc[2] |= FF_TCO2_PULL_DOWN_01; break;
543         case FF_TCOPARAM_PULL_UP_40:
544             tc[2] |= FF_TCO2_PULL_UP_40; break;
545         case FF_TCOPARAM_PULL_DOWN_40:
546             tc[2] |= FF_TCO2_PULL_DOWN_40; break;
547     }
548
549     if (tco_settings->termination == FF_TCOPARAM_TERMINATION_ON)
550         tc[2] |= FF_TCO2_SET_TERMINATION;
551
552     return write_tco(tc, 4);
553
554     return 0;
555 }
556
557 signed int
558 Device::set_hardware_dds_freq(signed int freq)
559 {
560     // Set the device's DDS to the given frequency (which in turn determines
561     // the sampling frequency).  Returns 0 on success, -1 on error.
562
563     unsigned int ret = 0;
564
565     if (freq < MIN_SPEED || freq > MAX_SPEED)
566         return -1;
567
568     if (m_rme_model == RME_MODEL_FIREFACE400)
569         ret = writeRegister(RME_FF400_STREAM_SRATE, freq);
570     else
571         ret = writeRegister(RME_FF800_STREAM_SRATE, freq);
572
573     return ret;
574 }
575
576 signed int
577 Device::hardware_init_streaming(unsigned int sample_rate,
578     unsigned int tx_channel)
579 {
580     // tx_channel is the ISO channel the PC will transmit on.
581     quadlet_t buf[4];
582     fb_nodeaddr_t addr;
583     unsigned int size;
584
585     buf[0] = sample_rate;
586     buf[1] = (num_channels << 11) + tx_channel;
587     buf[2] = num_channels;
588     buf[3] = 0;
589     buf[4] = 0;
590     if (speed800) {
591         buf[2] |= RME_FF800_STREAMING_SPEED_800;
592     }
593
594     if (m_rme_model == RME_MODEL_FIREFACE400) {
595         addr = RME_FF400_STREAM_INIT_REG;
596         size = RME_FF400_STREAM_INIT_SIZE;
597     } else {
598         addr = RME_FF800_STREAM_INIT_REG;
599         size = RME_FF800_STREAM_INIT_SIZE;
600     }
601
602     return writeBlock(addr, buf, size);
603 }
604
605 signed int
606 Device::hardware_start_streaming(unsigned int listen_channel)
607 {
608     // Listen_channel is the ISO channel the PC will listen on for data sent
609     // by the Fireface.
610     fb_nodeaddr_t addr;
611     quadlet_t data = num_channels;
612
613     if (m_rme_model == RME_MODEL_FIREFACE400) {
614         addr = RME_FF400_STREAM_START_REG;
615         data |= (listen_channel << 5);
616     } else {
617         addr = RME_FF800_STREAM_START_REG;
618         if (speed800)
619             data |= RME_FF800_STREAMING_SPEED_800; // Flag 800 Mbps speed
620     }
621
622     return writeRegister(addr, data);
623 }
624
625 signed int
626 Device::hardware_stop_streaming(void)
627 {
628     fb_nodeaddr_t addr;
629     quadlet_t buf[4] = {0, 0, 0, 1};
630     unsigned int size;
631
632     if (m_rme_model == RME_MODEL_FIREFACE400) {
633       addr = RME_FF400_STREAM_END_REG;
634       size = RME_FF400_STREAM_END_SIZE;
635     } else {
636       addr = RME_FF800_STREAM_END_REG;
637       size = RME_FF800_STREAM_END_SIZE;
638     }
639
640     return writeBlock(addr, buf, size);
641 }
642
643 }
Note: See TracBrowser for help on using the browser.