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

Revision 1627, 25.0 kB (checked in by jwoithe, 15 years ago)

RME: implement initial use of shared data object for configuration data. Some rough edges remain and are being addressed.

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