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

Revision 1594, 20.1 kB (checked in by jwoithe, 14 years ago)

RME driver:

  • add some missing status bit defines, fix naming of some others
  • add full decoding of device status registers
  • cache device run status
  • take external clock rates and device run status into account when evaluating the validity of sampling rates
  • minor bugfixes
  • implement function to configure a fixed DDS frequency on the device
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_state(FF_state_t *state)
82 {
83     // Retrieve the hardware status and deduce the device state.  Return
84     // -1 on error, 0 on success.  The given state structure will be
85     // cleared by this call.
86     unsigned int stat0, stat1;
87     memset(state, 0, sizeof(*state));
88     if (get_hardware_status(&stat0, &stat1) != 0)
89         return -1;
90
91     state->is_streaming = (stat0 & SR0_IS_STREAMING) != 0;
92
93     state->clock_mode = (settings.clock_mode == FF_SWPARAM_CLOCK_MODE_MASTER)?FF_STATE_CLOCKMODE_MASTER:FF_STATE_CLOCKMODE_AUTOSYNC;
94
95     switch (stat0 & SR0_AUTOSYNC_SRC_MASK) {
96         case SR0_AUTOSYNC_SRC_ADAT1:
97             state->autosync_source = FF_STATE_AUTOSYNC_SRC_ADAT1;
98             break;
99         case SR0_AUTOSYNC_SRC_ADAT2:
100             state->autosync_source = FF_STATE_AUTOSYNC_SRC_ADAT2;
101             break;
102         case SR0_AUTOSYNC_SRC_SPDIF:
103             state->autosync_source = FF_STATE_AUTOSYNC_SRC_SPDIF;
104             break;
105         case SR0_AUTOSYNC_SRC_WCLK:
106             state->autosync_source = FF_STATE_AUTOSYNC_SRC_WCLK;
107             break;
108         case SR0_AUTOSYNC_SRC_TCO:
109             state->autosync_source = FF_STATE_AUTOSYNC_SRC_TCO;
110             break;
111         default: state->autosync_source = FF_STATE_AUTOSYNC_SRC_NOLOCK;
112     }
113
114     switch (stat0 & SR0_AUTOSYNC_FREQ_MASK) {
115         case SR0_AUTOSYNC_FREQ_32k:  state->autosync_freq = 32000; break;
116         case SR0_AUTOSYNC_FREQ_44k1: state->autosync_freq = 44100; break;
117         case SR0_AUTOSYNC_FREQ_48k:  state->autosync_freq = 48000; break;
118         case SR0_AUTOSYNC_FREQ_64k:  state->autosync_freq = 64000; break;
119         case SR0_AUTOSYNC_FREQ_88k2: state->autosync_freq = 88200; break;
120         case SR0_AUTOSYNC_FREQ_96k:  state->autosync_freq = 96000; break;
121         case SR0_AUTOSYNC_FREQ_128k: state->autosync_freq = 128000; break;
122         case SR0_AUTOSYNC_FREQ_176k4:state->autosync_freq = 176400; break;
123         case SR0_AUTOSYNC_FREQ_192k: state->autosync_freq = 192000; break;
124     }
125
126     switch (stat0 & SR0_SPDIF_FREQ_MASK) {
127         case SR0_SPDIF_FREQ_32k:  state->spdif_freq = 32000; break;
128         case SR0_SPDIF_FREQ_44k1: state->spdif_freq = 41000; break;
129         case SR0_SPDIF_FREQ_48k:  state->spdif_freq = 48000; break;
130         case SR0_SPDIF_FREQ_64k:  state->spdif_freq = 64000; break;
131         case SR0_SPDIF_FREQ_88k2: state->spdif_freq = 88200; break;
132         case SR0_SPDIF_FREQ_96k:  state->spdif_freq = 96000; break;
133         case SR0_SPDIF_FREQ_128k: state->spdif_freq = 128000; break;
134         case SR0_SPDIF_FREQ_176k4:state->spdif_freq = 176400; break;
135         case SR0_SPDIF_FREQ_192k: state->spdif_freq = 192000; break;
136     }
137
138     switch (stat0 & SR0_ADAT1_STATUS_MASK) {
139         case SR0_ADAT1_STATUS_NOLOCK:
140             state->adat1_sync_status = FF_STATE_SYNC_NOLOCK; break;
141         case SR0_ADAT1_STATUS_LOCK:
142             state->adat1_sync_status = FF_STATE_SYNC_LOCKED; break;
143         case SR0_ADAT1_STATUS_SYNC:
144             state->adat1_sync_status = FF_STATE_SYNC_SYNCED; break;
145     }
146     switch (stat0 & SR0_ADAT2_STATUS_MASK) {
147         case SR0_ADAT2_STATUS_NOLOCK:
148             state->adat2_sync_status = FF_STATE_SYNC_NOLOCK; break;
149         case SR0_ADAT2_STATUS_LOCK:
150             state->adat2_sync_status = FF_STATE_SYNC_LOCKED; break;
151         case SR0_ADAT2_STATUS_SYNC:
152             state->adat2_sync_status = FF_STATE_SYNC_SYNCED; break;
153     }
154     switch (stat0 & SR0_SPDIF_STATUS_MASK) {
155         case SR0_SPDIF_STATUS_NOLOCK:
156             state->spdif_sync_status = FF_STATE_SYNC_NOLOCK; break;
157         case SR0_SPDIF_STATUS_LOCK:
158             state->spdif_sync_status = FF_STATE_SYNC_LOCKED; break;
159         case SR0_SPDIF_STATUS_SYNC:
160             state->spdif_sync_status = FF_STATE_SYNC_SYNCED; break;
161     }
162     switch (stat0 & SR0_WCLK_STATUS_MASK) {
163         case SR0_WCLK_STATUS_NOLOCK:
164             state->wclk_sync_status = FF_STATE_SYNC_NOLOCK; break;
165         case SR0_WCLK_STATUS_LOCK:
166             state->wclk_sync_status = FF_STATE_SYNC_LOCKED; break;
167         case SR0_WCLK_STATUS_SYNC:
168             state->wclk_sync_status = FF_STATE_SYNC_SYNCED; break;
169     }
170     switch (stat1 & SR1_TCO_STATUS_MASK) {
171        case SR1_TCO_STATUS_NOLOCK:
172            state->tco_sync_status = FF_STATE_SYNC_NOLOCK; break;
173        case SR1_TCO_STATUS_LOCK:
174            state->tco_sync_status = FF_STATE_SYNC_LOCKED; break;
175        case SR1_TCO_STATUS_SYNC:
176            state->tco_sync_status = FF_STATE_SYNC_SYNCED; break;
177     }
178
179     return 0;
180 }
181
182 signed int
183 Device::set_hardware_params(FF_software_settings_t *sw_settings)
184 {
185     // Initialises the hardware to the state defined by the supplied
186     // software settings structure (which will usually be the device's
187     // "settings" structure).  This has the side effect of extinguishing the
188     // "Host" LED on the FF400 when done for the first time after the
189     // interface has been powered up.
190
191     quadlet_t data[3] = {0, 0, 0};
192     unsigned int conf_reg;
193
194     if (sw_settings->mic_phantom[0])
195       data[0] |= CR0_PHANTOM_MIC0;
196     if (sw_settings->mic_phantom[1])
197       data[0] |= CR0_PHANTOM_MIC1;
198     if (sw_settings->mic_phantom[2])
199       data[0] |= CR0_PHANTOM_MIC2;
200     if (sw_settings->mic_phantom[3])
201       data[0] |= CR0_PHANTOM_MIC3;
202
203     /* Phones level */
204     switch (sw_settings->phones_level) {
205         case FF_SWPARAM_PHONESLEVEL_HIGAIN:
206             data[0] |= CRO_PHLEVEL_HIGAIN;
207             break;
208         case FF_SWPARAM_PHONESLEVEL_4dBU:
209             data[0] |= CR0_PHLEVEL_4dBU;
210             break;
211         case FF_SWPARAM_PHONESLEVEL_m10dBV:
212             data[0] |= CRO_PHLEVEL_m10dBV;
213             break;
214     }
215
216     /* Input level */
217     switch (sw_settings->input_level) {
218         case FF_SWPARAM_ILEVEL_LOGAIN: // Low gain
219             data[1] |= CR1_ILEVEL_CPLD_LOGAIN;    // CPLD
220             data[0] |= CR0_ILEVEL_FPGA_LOGAIN;    // LED control (used on FF800 only)
221             break;
222         case FF_SWPARAM_ILEVEL_4dBU:   // +4 dBu
223             data[1] |= CR1_ILEVEL_CPLD_4dBU;
224             data[0] |= CR0_ILEVEL_FPGA_4dBU;
225             break;
226         case FF_SWPARAM_ILEVEL_m10dBV: // -10 dBV
227             data[1] |= CR1_ILEVEL_CPLD_m10dBV;
228             data[0] |= CR0_ILEVEL_FPGA_m10dBV;
229             break;
230     }
231
232     /* Output level */
233     switch (sw_settings->output_level) {
234         case FF_SWPARAM_OLEVEL_HIGAIN: // High gain
235             data[1] |= CR1_OLEVEL_CPLD_HIGAIN;   // CPLD
236             data[0] |= CR0_OLEVEL_FPGA_HIGAIN;   // LED control (used on FF800 only)
237             break;
238         case FF_SWPARAM_OLEVEL_4dBU:   // +4 dBu
239             data[1] |= CR1_OLEVEL_CPLD_4dBU;
240             data[0] |= CR0_OLEVEL_FPGA_4dBU;
241             break;
242         case FF_SWPARAM_OLEVEL_m10dBV: // -10 dBV
243             data[1] |= CR1_OLEVEL_CPLD_m10dBV;
244             data[0] |= CR0_OLEVEL_FPGA_m10dBV;
245             break;
246     }
247
248     /* Set input options.  The meaning of the options differs between
249      * devices, so we use the generic identifiers here.
250      */
251     data[1] |= (sw_settings->input_opt[1] & FF_SWPARAM_INPUT_OPT_A) ? CR1_INPUT_OPT1_A : 0;
252     data[1] |= (sw_settings->input_opt[1] & FF_SWPARAM_INPUT_OPT_B) ? CR1_INPUT_OPT1_B : 0;
253     data[1] |= (sw_settings->input_opt[2] & FF_SWPARAM_INPUT_OPT_A) ? CR1_INPUT_OPT2_A : 0;
254     data[1] |= (sw_settings->input_opt[2] & FF_SWPARAM_INPUT_OPT_B) ? CR1_INPUT_OPT2_B : 0;
255
256     // Drive the speaker emulation / filter LED via FPGA
257     data[0] |= (sw_settings->filter) ? CR0_FILTER_FPGA : 0;
258
259     // Set the "rear" option for input 0 if selected
260     data[1] |= (sw_settings->input_opt[0] & FF_SWPARAM_FF800_INPUT_OPT_REAR) ? CR1_FF800_INPUT1_REAR : 0;
261
262     // The input 0 "front" option is activated using one of two bits
263     // depending on whether the filter (aka "speaker emulation") setting is
264     // active.
265     if (sw_settings->input_opt[0] & FF_SWPARAM_FF800_INPUT_OPT_FRONT) {
266         data[1] |= (sw_settings->filter) ? CR1_FF800_INPUT1_FRONT_WITH_FILTER : CR1_FF800_INPUT1_FRONT;
267     }
268
269     data[2] |= (sw_settings->spdif_output_emphasis==FF_SWPARAM_SPDIF_OUTPUT_EMPHASIS_ON) ? CR2_SPDIF_OUT_EMP : 0;
270     data[2] |= (sw_settings->spdif_output_pro==FF_SWPARAM_SPDIF_OUTPUT_PRO_ON) ? CR2_SPDIF_OUT_PRO : 0;
271     data[2] |= (sw_settings->spdif_output_nonaudio==FF_SWPARAM_SPDIF_OUTPUT_NONAUDIO_ON) ? CR2_SPDIF_OUT_NONAUDIO : 0;
272     data[2] |= (sw_settings->spdif_output_mode==FF_SWPARAM_SPDIF_OUTPUT_OPTICAL) ? CR2_SPDIF_OUT_ADAT2 : 0;
273     data[2] |= (sw_settings->clock_mode==FF_SWPARAM_CLOCK_MODE_AUTOSYNC) ? CR2_CLOCKMODE_AUTOSYNC : CR2_CLOCKMODE_MASTER;
274     data[2] |= (sw_settings->spdif_input_mode==FF_SWPARAM_SPDIF_INPUT_COAX) ? CR2_SPDIF_IN_COAX : CR2_SPDIF_IN_ADAT2;
275     data[2] |= (sw_settings->word_clock_single_speed=FF_SWPARAM_WORD_CLOCK_1x) ? CR2_WORD_CLOCK_1x : 0;
276
277     /* TMS / TCO toggle bits in CR2 are not set by other drivers */
278
279     /* Drive / fuzz */
280     if (sw_settings->fuzz)
281       data[0] |= CR0_INSTR_DRIVE_FPGA; // FPGA LED control
282     else
283       data[1] |= CR1_INSTR_DRIVE;      // CPLD
284
285     /* Drop-and-stop is hardwired on in other drivers */
286     data[2] |= CR2_DROP_AND_STOP;
287
288     if (m_rme_model == RME_MODEL_FIREFACE400) {
289         data[2] |= CR2_FF400_BIT;
290     }
291
292     switch (sw_settings->sync_ref) {
293         case FF_SWPARAM_SYNCREF_WORDCLOCK:
294             data[2] |= CR2_SYNC_WORDCLOCK;
295             break;
296         case FF_SWPARAM_SYNCREF_ADAT1:
297             data[2] |= CR2_SYNC_ADAT1;
298             break;
299         case FF_SWPARAM_SYNCREF_ADAT2:
300             data[2] |= CR2_SYNC_ADAT2;
301             break;
302         case FF_SWPARAM_SYNCREF_SPDIF:
303             data[2] |= CR2_SYNC_SPDIF;
304             break;
305         case FF_SWPARAM_SYNCREC_TCO:
306             data[2] |= CR2_SYNC_TCO;
307             break;
308     }
309
310     // This is hardwired in other drivers
311     data[2] |= (CR2_FREQ0 + CR2_FREQ1 + CR2_DSPEED + CR2_QSSPEED);
312
313     // The FF800 limiter applies to the front panel instrument input, so it
314     // only makes sense that it is disabled when that input is in use.
315     data[2] |= (sw_settings->limiter_disable &&
316                 (sw_settings->input_opt[0] & FF_SWPARAM_FF800_INPUT_OPT_FRONT)) ?
317                 CR2_DISABLE_LIMITER : 0;
318
319 //This is just for testing - it's a known consistent configuration
320 //data[0] = 0x00020811;      // Phantom off
321 data[0] = 0x00020811;      // Phantom on
322 data[1] = 0x0000031e;
323 data[2] = 0xc400101f;
324
325     conf_reg = (m_rme_model==RME_MODEL_FIREFACE800)?RME_FF800_CONF_REG:RME_FF400_CONF_REG;
326     if (writeBlock(conf_reg, data, 3) != 0)
327         return -1;
328
329     return -0;
330 }
331
332 signed int
333 Device::read_tco(quadlet_t *tco_data, signed int size)
334 {
335     // Read the TCO registers and return the respective values in *tco_data.
336     // Return value is 0 on success, or -1 if there is no TCO present.
337     // "size" is the size (in quadlets) of the array pointed to by tco_data.
338     // To obtain all TCO data "size" should be at least 4.  If the caller
339     // doesn't care about the data returned by the TCO, tco_data can be
340     // NULL.
341     quadlet_t buf[4];
342     signed int i;
343
344     // The Fireface 400 can't have the TCO fitted
345     if (m_rme_model==RME_MODEL_FIREFACE400)
346         return -1;
347
348     if (readBlock(RME_FF_TCO_READ_REG, buf, 4) != 0)
349         return -1;
350
351     if (tco_data != NULL) {
352         for (i=0; i<(size<4)?size:4; i++)
353             tco_data[i] = buf[i];
354     }
355
356     if ( (buf[0] & 0x80808080) == 0x80808080 &&
357          (buf[1] & 0x80808080) == 0x80808080 &&
358          (buf[2] & 0x80808080) == 0x80808080 &&
359          (buf[3] & 0x8000FFFF) == 0x80008000) {
360         // A TCO is present
361         return 0;
362     }
363
364     return -1;
365 }
366
367 signed int
368 Device::write_tco(quadlet_t *tco_data, signed int size)
369 {
370     // Writes data to the TCO.  No check is made as to whether a TCO is
371     // present in the current device.  Return value is 0 on success or -1 on
372     // error.  "size" is the size (in quadlets) of the data pointed to by
373     // "tco_data".  The first 4 quadlets of tco_data are significant; all
374     // others are ignored.  If fewer than 4 quadlets are supplied (as
375     // indicated by the "size" parameter, -1 will be returned.
376     if (size < 4)
377         return -1;
378
379     // Don't bother trying to write if the device is a FF400 since the TCO
380     // can't be fitted to this device.
381     if (m_rme_model==RME_MODEL_FIREFACE400)
382         return -1;
383
384     if (writeBlock(RME_FF_TCO_WRITE_REG, tco_data, 4) != 0)
385         return -1;
386
387     return 0;
388 }
389
390 signed int
391 Device::hardware_is_streaming(void)
392 {
393     // Return 1 if the hardware is streaming, 0 if not.
394     unsigned int s1, s2;
395     if (get_hardware_status(&s1, &s2) != 0)
396         return 0;
397     return (s1 & SR0_IS_STREAMING) != 0;
398 }
399
400 signed int
401 Device::read_tco_state(FF_TCO_state_t *tco_state)
402 {
403     // Reads the current TCO state into the supplied state structure
404
405     quadlet_t tc[4];
406     unsigned int PLL_phase;
407
408     if (read_tco(tc, 4) != 0)
409       return -1;
410
411     // The timecode is stored in BCD (binary coded decimal) in register 0.
412     tco_state->frames = (tc[0] & 0xf) + ((tc[0] & 0x30) >> 4)*10;
413     tco_state->seconds = ((tc[0] & 0xf00) >> 8) + ((tc[0] & 0x7000) >> 12)*10;
414     tco_state->minutes = ((tc[0] & 0xf0000) >> 16) + ((tc[0] & 0x700000) >> 20)*10;
415     tco_state->hours = ((tc[0] & 0xf000000) >> 24) + ((tc[0] & 0x30000000) >> 28)*10;
416
417     tco_state->locked = (tc[1] & FF_TCO1_TCO_lock) != 0;
418     tco_state->ltc_valid = (tc[1] & FF_TCO1_LTC_INPUT_VALID) != 0;
419
420     switch (tc[1] & FF_TCO1_LTC_FORMAT_MASK) {
421         case FF_TC01_LTC_FORMAT_24fps:
422           tco_state->frame_rate = FF_TCOSTATE_FRAMERATE_24fps; break;
423         case FF_TCO1_LTC_FORMAT_25fps:
424           tco_state->frame_rate = FF_TCOSTATE_FRAMERATE_25fps; break;
425         case FF_TC01_LTC_FORMAT_29_97fps:
426           tco_state->frame_rate = FF_TCOSTATE_FRAMERATE_29_97fps; break;
427         case FF_TCO1_LTC_FORMAT_30fps:
428           tco_state->frame_rate = FF_TCOSTATE_FRAMERATE_30fps; break;
429     }
430
431     tco_state->drop_frame = (tc[1] & FF_TCO1_SET_DROPFRAME) != 0;
432
433     switch (tc[1] & FF_TCO1_VIDEO_INPUT_MASK) {
434         case FF_TCO1_VIDEO_INPUT_NTSC:
435             tco_state->video_input = FF_TCOSTATE_VIDEO_NTSC; break;
436         case FF_TCO1_VIDEO_INPUT_PAL:
437             tco_state->video_input = FF_TCOSTATE_VIDEO_PAL; break;
438         default:
439             tco_state->video_input = FF_TCOSTATE_VIDEO_NONE;
440     }
441
442     if ((tc[1] & FF_TCO1_WORD_CLOCK_INPUT_VALID) == 0) {
443         tco_state->word_clock_state = FF_TCOSTATE_WORDCLOCK_NONE;
444     } else {
445         switch (tc[1] & FF_TCO1_WORD_CLOCK_INPUT_MASK) {
446             case FF_TCO1_WORD_CLOCK_INPUT_1x:
447                 tco_state->word_clock_state = FF_TCOSTATE_WORDCLOCK_1x; break;
448             case FF_TCO1_WORD_CLOCK_INPUT_2x:
449                 tco_state->word_clock_state = FF_TCOSTATE_WORDCLOCK_2x; break;
450             case FF_TCO1_WORD_CLOCK_INPUT_4x:
451                 tco_state->word_clock_state = FF_TCOSTATE_WORDCLOCK_4x; break;
452         }
453     }
454
455     PLL_phase = (tc[2] & 0x7f) + ((tc[2] & 0x7f00) >> 1);
456     tco_state->sample_rate = (25000000.0 * 16.0)/PLL_phase;
457
458     return 0;
459 }
460
461 signed int
462 Device::write_tco_settings(FF_TCO_settings_t *tco_settings)
463 {
464     // Writes the supplied application-level settings to the device's TCO
465     // (Time Code Option).  Don't bother doing anything if the device doesn't
466     // have a TCO fitted.  Returns 0 on success, -1 on error.
467
468     quadlet_t tc[4] = {0, 0, 0, 0};
469
470     if (!tco_present) {
471         return -1;
472     }
473
474     if (tco_settings->MTC)
475         tc[0] |= FF_TCO0_MTC;
476
477     switch (tco_settings->input) {
478         case FF_TCOPARAM_INPUT_LTC:
479             tc[2] |= FF_TCO2_INPUT_LTC; break;
480         case FF_TCOPARAM_INPUT_VIDEO:
481             tc[2] |= FF_TCO2_INPUT_VIDEO; break;
482         case FF_TCOPARAM_INPUT_WCK:
483             tc[2] |= FF_TCO2_INPUT_WORD_CLOCK; break;
484     }
485
486     switch (tco_settings->frame_rate) {
487         case FF_TCOPARAM_FRAMERATE_24fps:
488             tc[1] |= FF_TC01_LTC_FORMAT_24fps; break;
489         case FF_TCOPARAM_FRAMERATE_25fps:
490             tc[1] |= FF_TCO1_LTC_FORMAT_25fps; break;
491         case FF_TCOPARAM_FRAMERATE_29_97fps:
492             tc[1] |= FF_TC01_LTC_FORMAT_29_97fps; break;
493         case FF_TCOPARAM_FRAMERATE_29_97dfps:
494             tc[1] |= FF_TCO1_LTC_FORMAT_29_97dpfs; break;
495         case FF_TCOPARAM_FRAMERATE_30fps:
496             tc[1] |= FF_TCO1_LTC_FORMAT_30fps; break;
497         case FF_TCOPARAM_FRAMERATE_30dfps:
498             tc[1] |= FF_TCO1_LTC_FORMAT_30dfps; break;
499     }
500
501     switch (tco_settings->word_clock) {
502         case FF_TCOPARAM_WORD_CLOCK_CONV_1_1:
503             tc[2] |= FF_TCO2_WORD_CLOCK_CONV_1_1; break;
504         case FF_TCOPARAM_WORD_CLOCK_CONV_44_48:
505             tc[2] |= FF_TCO2_WORD_CLOCK_CONV_44_48; break;
506         case FF_TCOPARAM_WORD_CLOCK_CONV_48_44:
507             tc[2] |= FF_TCO2_WORD_CLOCK_CONV_48_44; break;
508     }
509
510     switch (tco_settings->sample_rate) {
511         case FF_TCOPARAM_SRATE_44_1:
512             tc[2] |= FF_TCO2_SRATE_44_1; break;
513         case FF_TCOPARAM_SRATE_48:
514             tc[2] |= FF_TCO2_SRATE_48; break;
515         case FF_TCOPARAM_SRATE_FROM_APP:
516             tc[2] |= FF_TCO2_SRATE_FROM_APP; break;
517     }
518
519     switch (tco_settings->pull) {
520         case FF_TCPPARAM_PULL_NONE:
521             tc[2] |= FF_TCO2_PULL_0; break;
522         case FF_TCOPARAM_PULL_UP_01:
523             tc[2] |= FF_TCO2_PULL_UP_01; break;
524         case FF_TCOPARAM_PULL_DOWN_01:
525             tc[2] |= FF_TCO2_PULL_DOWN_01; break;
526         case FF_TCOPARAM_PULL_UP_40:
527             tc[2] |= FF_TCO2_PULL_UP_40; break;
528         case FF_TCOPARAM_PULL_DOWN_40:
529             tc[2] |= FF_TCO2_PULL_DOWN_40; break;
530     }
531
532     if (tco_settings->termination == FF_TCOPARAM_TERMINATION_ON)
533         tc[2] |= FF_TCO2_SET_TERMINATION;
534
535     return write_tco(tc, 4);
536
537     return 0;
538 }
539
540 signed int
541 Device::set_hardware_dds_freq(signed int freq)
542 {
543     // Set the device's DDS to the given frequency (which in turn determines
544     // the sampling frequency).  Returns 0 on success, -1 on error.
545
546     unsigned int ret = 0;
547
548     if (freq < MIN_SPEED || freq > MAX_SPEED)
549         return -1;
550
551     if (m_rme_model == RME_MODEL_FIREFACE400)
552         ret = writeRegister(RME_FF400_STREAM_SRATE, freq);
553     else
554         ret = writeRegister(RME_FF800_STREAM_SRATE, freq);
555
556     return ret;
557 }
558
559 }
Note: See TracBrowser for help on using the browser.