root/branches/libffado-2.0/src/bebob/focusrite/focusrite_generic.cpp

Revision 1371, 15.8 kB (checked in by ppalmers, 15 years ago)

* implement our own code to do FCP transactions. the code from libavc had too much side-effects.
* remove libavc1394 as a dependency
* set the SPLIT_TIMEOUT value for the host controller such that late responses by the DM1x00 based devices are not discarded. Should fix the issues with FA-101 discovery. (re:
#155, #162)

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
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 #include "focusrite_saffirepro.h"
25 #include "focusrite_cmd.h"
26
27 #include "libutil/ByteSwap.h"
28 #include "libutil/SystemTimeSource.h"
29
30 namespace BeBoB {
31 namespace Focusrite {
32
33 FocusriteDevice::FocusriteDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
34     : BeBoB::AvDevice( d, configRom)
35 {
36     debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::Focusrite::FocusriteDevice (NodeID %d)\n",
37                  getConfigRom().getNodeId() );
38     addOption(Util::OptionContainer::Option("useAvcForParameters", false));
39 }
40
41 void
42 FocusriteDevice::showDevice()
43 {
44     debugOutput(DEBUG_LEVEL_NORMAL, "This is a BeBoB::Focusrite::FocusriteDevice\n");
45     BeBoB::AvDevice::showDevice();
46 }
47
48 void
49 FocusriteDevice::setVerboseLevel(int l)
50 {
51     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
52
53     BeBoB::AvDevice::setVerboseLevel(l);
54 }
55
56 bool
57 FocusriteDevice::setSpecificValue(uint32_t id, uint32_t v)
58 {
59     debugOutput(DEBUG_LEVEL_VERBOSE, "Writing parameter address space id 0x%08lX (%u), data: 0x%08lX\n",
60         id, id, v);
61     bool use_avc = false;
62     if(!getOption("useAvcForParameters", use_avc)) {
63         debugWarning("Could not retrieve useAvcForParameters parameter, defauling to false\n");
64     }
65     if (use_avc) {
66         return setSpecificValueAvc(id, v);
67     } else {
68         return setSpecificValueARM(id, v);
69     }
70 }
71
72 bool
73 FocusriteDevice::getSpecificValue(uint32_t id, uint32_t *v)
74 {
75     bool retval;
76     bool use_avc = false;
77     if(!getOption("useAvcForParameters", use_avc)) {
78         debugWarning("Could not retrieve useAvcForParameters parameter, defauling to false\n");
79     }
80     if (use_avc) {
81         retval = getSpecificValueAvc(id, v);
82     } else {
83         retval = getSpecificValueARM(id, v);
84     }
85     debugOutput(DEBUG_LEVEL_VERBOSE,"Read parameter address space id 0x%08lX (%u): %08lX\n", id, id, *v);
86     return retval;
87 }
88
89 // The AV/C methods to set parameters
90 bool
91 FocusriteDevice::setSpecificValueAvc(uint32_t id, uint32_t v)
92 {
93    
94     FocusriteVendorDependentCmd cmd( get1394Service() );
95     cmd.setCommandType( AVC::AVCCommand::eCT_Control );
96     cmd.setNodeId( getConfigRom().getNodeId() );
97     cmd.setSubunitType( AVC::eST_Unit  );
98     cmd.setSubunitId( 0xff );
99    
100     cmd.setVerbose( getDebugLevel() );
101 //         cmd.setVerbose( DEBUG_LEVEL_VERY_VERBOSE );
102    
103     cmd.m_id=id;
104     cmd.m_value=v;
105    
106     if ( !cmd.fire() ) {
107         debugError( "FocusriteVendorDependentCmd info command failed\n" );
108         return false;
109     }
110     return true;
111 }
112
113 bool
114 FocusriteDevice::getSpecificValueAvc(uint32_t id, uint32_t *v)
115 {
116    
117     FocusriteVendorDependentCmd cmd( get1394Service() );
118     cmd.setCommandType( AVC::AVCCommand::eCT_Status );
119     cmd.setNodeId( getConfigRom().getNodeId() );
120     cmd.setSubunitType( AVC::eST_Unit  );
121     cmd.setSubunitId( 0xff );
122    
123     cmd.setVerbose( getDebugLevel() );
124 //         cmd.setVerbose( DEBUG_LEVEL_VERY_VERBOSE );
125    
126     cmd.m_id=id;
127    
128     if ( !cmd.fire() ) {
129         debugError( "FocusriteVendorDependentCmd info command failed\n" );
130         return false;
131     }
132
133     *v=cmd.m_value;
134     return true;
135 }
136
137 // The ARM methods to set parameters
138 bool
139 FocusriteDevice::setSpecificValueARM(uint32_t id, uint32_t v)
140 {
141     fb_quadlet_t data=v;
142     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing parameter address space id 0x%08lX (%u), data: 0x%08lX\n",
143         id, id, data);
144
145     fb_nodeaddr_t addr = FR_PARAM_SPACE_START + (id * 4);
146     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
147
148     if(!get1394Service().write_quadlet( nodeId, addr, CondSwapToBus32(data) ) ) {
149         debugError("Could not write to node 0x%04X addr 0x%012X\n", nodeId, addr);
150         return false;
151     }
152     return true;
153 }
154
155 bool
156 FocusriteDevice::getSpecificValueARM(uint32_t id, uint32_t *v)
157 {
158     fb_quadlet_t result;
159     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading parameter address space id 0x%08lX\n", id);
160
161     fb_nodeaddr_t addr = FR_PARAM_SPACE_START + (id * 4);
162     fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
163
164     if(!get1394Service().read_quadlet( nodeId, addr, &result ) ) {
165         debugError("Could not read from node 0x%04llX addr 0x%012llX\n", nodeId, addr);
166         return false;
167     }
168
169     result=CondSwapFromBus32(result);
170     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Read result: 0x%08llX\n", result);
171
172     *v = result;
173     return true;
174 }
175
176 int
177 FocusriteDevice::convertDefToSr( uint32_t def ) {
178     switch(def) {
179         case FOCUSRITE_CMD_SAMPLERATE_44K1:  return 44100;
180         case FOCUSRITE_CMD_SAMPLERATE_48K:   return 48000;
181         case FOCUSRITE_CMD_SAMPLERATE_88K2:  return 88200;
182         case FOCUSRITE_CMD_SAMPLERATE_96K:   return 96000;
183         case FOCUSRITE_CMD_SAMPLERATE_176K4: return 176400;
184         case FOCUSRITE_CMD_SAMPLERATE_192K:  return 192000;
185         default:
186             debugWarning("Unsupported samplerate def: %08X\n", def);
187             return 0;
188     }
189 }
190
191 uint32_t
192 FocusriteDevice::convertSrToDef( int sr ) {
193     switch(sr) {
194         case 44100:  return FOCUSRITE_CMD_SAMPLERATE_44K1;
195         case 48000:  return FOCUSRITE_CMD_SAMPLERATE_48K;
196         case 88200:  return FOCUSRITE_CMD_SAMPLERATE_88K2;
197         case 96000:  return FOCUSRITE_CMD_SAMPLERATE_96K;
198         case 176400: return FOCUSRITE_CMD_SAMPLERATE_176K4;
199         case 192000: return FOCUSRITE_CMD_SAMPLERATE_192K;
200         default:
201             debugWarning("Unsupported samplerate: %d\n", sr);
202             return 0;
203     }
204 }
205
206 // --- element implementation classes
207
208 BinaryControl::BinaryControl(FocusriteDevice& parent, int id, int bit)
209 : Control::Discrete(&parent)
210 , m_Parent(parent)
211 , m_cmd_id ( id )
212 , m_cmd_bit ( bit )
213 {}
214 BinaryControl::BinaryControl(FocusriteDevice& parent, int id, int bit,
215                 std::string name, std::string label, std::string descr)
216 : Control::Discrete(&parent)
217 , m_Parent(parent)
218 , m_cmd_id ( id )
219 , m_cmd_bit ( bit )
220 {
221     setName(name);
222     setLabel(label);
223     setDescription(descr);
224 }
225
226 bool
227 BinaryControl::setValue(int v)
228 {
229     uint32_t reg;
230     uint32_t old_reg;
231
232     if ( !m_Parent.getSpecificValue(m_cmd_id, &reg) ) {
233         debugError( "getSpecificValue failed\n" );
234         return 0;
235     }
236    
237     old_reg=reg;
238     if (v) {
239         reg |= (1<<m_cmd_bit);
240     } else {
241         reg &= ~(1<<m_cmd_bit);
242     }
243     debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for id %d to %d (reg: 0x%08X => 0x%08X)\n",
244                                      m_cmd_id, v, old_reg, reg);
245
246     if ( !m_Parent.setSpecificValue(m_cmd_id, reg) ) {
247         debugError( "setSpecificValue failed\n" );
248         return false;
249     } else return true;
250 }
251
252 int
253 BinaryControl::getValue()
254 {
255     uint32_t reg;
256
257     if ( !m_Parent.getSpecificValue(m_cmd_id, &reg) ) {
258         debugError( "getSpecificValue failed\n" );
259         return 0;
260     } else {
261         bool val= (reg & (1<<m_cmd_bit)) != 0;
262         debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for %d: reg: 0x%08X, result=%d\n",
263                                          m_cmd_id, reg, val);
264         return val;
265     }
266 }
267
268 // --- element implementation classes
269
270 VolumeControl::VolumeControl(FocusriteDevice& parent, int id)
271 : Control::Discrete(&parent)
272 , m_Parent(parent)
273 , m_cmd_id ( id )
274 {}
275 VolumeControl::VolumeControl(FocusriteDevice& parent, int id,
276                 std::string name, std::string label, std::string descr)
277 : Control::Discrete(&parent)
278 , m_Parent(parent)
279 , m_cmd_id ( id )
280 {
281     setName(name);
282     setLabel(label);
283     setDescription(descr);
284 }
285
286 bool
287 VolumeControl::setValue(int v)
288 {
289     if (v>0x07FFF) v=0x07FFF;
290     else if (v<0) v=0;
291
292     debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for id %d to %d\n",
293                                      m_cmd_id, v);
294
295     if ( !m_Parent.setSpecificValue(m_cmd_id, v) ) {
296         debugError( "setSpecificValue failed\n" );
297         return false;
298     } else return true;
299 }
300
301 int
302 VolumeControl::getValue()
303 {
304     uint32_t val=0;
305
306     if ( !m_Parent.getSpecificValue(m_cmd_id, &val) ) {
307         debugError( "getSpecificValue failed\n" );
308         return 0;
309     } else {
310         debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for %d = %d\n",
311                                          m_cmd_id, val);
312         return val;
313     }
314 }
315
316 MeteringControl::MeteringControl(FocusriteDevice& parent, int id)
317 : Control::Discrete(&parent)
318 , m_Parent(parent)
319 , m_cmd_id ( id )
320 {}
321 MeteringControl::MeteringControl(FocusriteDevice& parent, int id,
322                 std::string name, std::string label, std::string descr)
323 : Control::Discrete(&parent)
324 , m_Parent(parent)
325 , m_cmd_id ( id )
326 {
327     setName(name);
328     setLabel(label);
329     setDescription(descr);
330 }
331
332 int
333 MeteringControl::getValue()
334 {
335     uint32_t val=0;
336
337     if ( !m_Parent.getSpecificValue(m_cmd_id, &val) ) {
338         debugError( "getSpecificValue failed\n" );
339         return 0;
340     } else {
341         debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for %d = %d\n",
342                                          m_cmd_id, val);
343         return val;
344     }
345 }
346
347 // reg control
348 RegisterControl::RegisterControl(FocusriteDevice& parent)
349 : Control::Register(&parent)
350 , m_Parent(parent)
351 {}
352 RegisterControl::RegisterControl(FocusriteDevice& parent,
353                  std::string name, std::string label, std::string descr)
354 : Control::Register(&parent)
355 , m_Parent(parent)
356 {
357     setName(name);
358     setLabel(label);
359     setDescription(descr);
360 }
361
362 bool
363 RegisterControl::setValue(uint64_t addr, uint64_t v)
364 {
365     debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for addr %llu to %llu\n",
366                                      addr, v);
367
368     if ( !m_Parent.setSpecificValue(addr, v) ) {
369         debugError( "setSpecificValue failed\n" );
370         return false;
371     } else return true;
372 }
373
374 uint64_t
375 RegisterControl::getValue(uint64_t addr)
376 {
377     uint32_t val=0;
378
379     if ( !m_Parent.getSpecificValue(addr, &val) ) {
380         debugError( "getSpecificValue failed\n" );
381         return 0;
382     } else {
383         debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for %llu = %lu\n",
384                                          addr, val);
385         return val;
386     }
387 }
388
389 // low resolution volume control
390 VolumeControlLowRes::VolumeControlLowRes(FocusriteDevice& parent, int id, int shift)
391 : Control::Discrete(&parent)
392 , m_Parent(parent)
393 , m_cmd_id ( id )
394 , m_bit_shift( shift )
395 {}
396 VolumeControlLowRes::VolumeControlLowRes(FocusriteDevice& parent, int id, int shift,
397                 std::string name, std::string label, std::string descr)
398 : Control::Discrete(&parent)
399 , m_Parent(parent)
400 , m_cmd_id ( id )
401 , m_bit_shift( shift )
402 {
403     setName(name);
404     setLabel(label);
405     setDescription(descr);
406 }
407
408 bool
409 VolumeControlLowRes::setValue(int v)
410 {
411     uint32_t reg;
412     uint32_t old_reg;
413    
414     if (v>0xFF) v=0xFF;
415     else if (v<0) v=0;
416
417     if ( !m_Parent.getSpecificValue(m_cmd_id, &reg) ) {
418         debugError( "getSpecificValue failed\n" );
419         return 0;
420     }
421    
422     old_reg=reg;
423     reg &= ~(0xFF<<m_bit_shift);
424     reg |= (v<<m_bit_shift);
425
426     debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for id %d to %d, shift %d (reg: 0x%08X => 0x%08X)\n",
427                                      m_cmd_id, v, m_bit_shift, old_reg, reg);
428
429     if ( !m_Parent.setSpecificValue(m_cmd_id, reg) ) {
430         debugError( "setSpecificValue failed\n" );
431         return false;
432     } else return true;
433 }
434
435 int
436 VolumeControlLowRes::getValue()
437 {
438     uint32_t val, reg;
439
440     if ( !m_Parent.getSpecificValue(m_cmd_id, &reg) ) {
441         debugError( "getSpecificValue failed\n" );
442         return 0;
443     } else {
444         val = (reg & 0xFF)>>m_bit_shift;
445         debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for %d: reg: 0x%08X, result=%d\n",
446                                          m_cmd_id, reg, val);
447         return val;
448     }
449 }
450
451 // hardware dial control
452 DialPositionControl::DialPositionControl(FocusriteDevice& parent, int id, int shift)
453 : Control::Discrete(&parent)
454 , m_Parent(parent)
455 , m_cmd_id ( id )
456 , m_shift ( shift )
457 {}
458 DialPositionControl::DialPositionControl(FocusriteDevice& parent, int id, int shift,
459                 std::string name, std::string label, std::string descr)
460 : Control::Discrete(&parent)
461 , m_Parent(parent)
462 , m_cmd_id ( id )
463 , m_shift ( shift )
464 {
465     setName(name);
466     setLabel(label);
467     setDescription(descr);
468 }
469
470 int
471 DialPositionControl::getValue()
472 {
473     uint32_t val=0;
474
475     if ( !m_Parent.getSpecificValue(m_cmd_id, &val) ) {
476         debugError( "getSpecificValue failed\n" );
477         return 0;
478     } else {
479         if (m_shift > 0) {
480             val = val >> m_shift;
481         } else if (m_shift < 0) {
482             val = val << -m_shift;
483         }
484         debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for %d = %d\n",
485                                          m_cmd_id, val);
486         return val;
487     }
488 }
489
490 // Saffire pro matrix mixer element
491 FocusriteMatrixMixer::FocusriteMatrixMixer(FocusriteDevice& p)
492 : Control::MatrixMixer(&p, "MatrixMixer")
493 , m_Parent(p)
494 {
495 }
496
497 FocusriteMatrixMixer::FocusriteMatrixMixer(FocusriteDevice& p,std::string n)
498 : Control::MatrixMixer(&p, n)
499 , m_Parent(p)
500 {
501 }
502
503 void FocusriteMatrixMixer::addSignalInfo(std::vector<struct sSignalInfo> &target,
504     std::string name, std::string label, std::string descr)
505 {
506     struct sSignalInfo s;
507     s.name=name;
508     s.label=label;
509     s.description=descr;
510
511     target.push_back(s);
512 }
513
514 void FocusriteMatrixMixer::setCellInfo(int row, int col, int addr, bool valid)
515 {
516     struct sCellInfo c;
517     c.row=row;
518     c.col=col;
519     c.valid=valid;
520     c.address=addr;
521
522     m_CellInfo.at(row).at(col) = c;
523 }
524
525 void FocusriteMatrixMixer::show()
526 {
527     debugOutput(DEBUG_LEVEL_NORMAL, "Focusrite Matrix mixer\n");
528 }
529
530 std::string FocusriteMatrixMixer::getRowName( const int row )
531 {
532     debugOutput(DEBUG_LEVEL_VERBOSE, "name for row %d is %s\n",
533                                      row, m_RowInfo.at(row).name.c_str());
534     return m_RowInfo.at(row).name;
535 }
536
537 std::string FocusriteMatrixMixer::getColName( const int col )
538 {
539     debugOutput(DEBUG_LEVEL_VERBOSE, "name for col %d is %s\n",
540                                      col, m_ColInfo.at(col).name.c_str());
541     return m_ColInfo.at(col).name;
542 }
543
544 int FocusriteMatrixMixer::canWrite( const int row, const int col )
545 {
546     debugOutput(DEBUG_LEVEL_VERBOSE, "canWrite for row %d col %d is %d\n",
547                                      row, col, m_CellInfo.at(row).at(col).valid);
548     return m_CellInfo.at(row).at(col).valid;
549 }
550
551 double FocusriteMatrixMixer::setValue( const int row, const int col, const double val )
552 {
553     int32_t v = (int32_t)val;
554     struct sCellInfo c = m_CellInfo.at(row).at(col);
555
556     debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for id %d row %d col %d to %lf (%ld)\n",
557                                      c.address, row, col, val, v);
558
559     if (v>0x07FFF) v=0x07FFF;
560     else if (v<0) v=0;
561
562     if ( !m_Parent.setSpecificValue(c.address, v) ) {
563         debugError( "setSpecificValue failed\n" );
564         return false;
565     } else return true;
566 }
567
568 double FocusriteMatrixMixer::getValue( const int row, const int col )
569 {
570     struct sCellInfo c=m_CellInfo.at(row).at(col);
571     uint32_t val=0;
572
573     if ( !m_Parent.getSpecificValue(c.address, &val) ) {
574         debugError( "getSpecificValue failed\n" );
575         return 0;
576     } else {
577         debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for id %d row %d col %d = %lu\n",
578                                          c.address, row, col, val);
579         return val;
580     }
581 }
582
583 int FocusriteMatrixMixer::getRowCount( )
584 {
585     return m_RowInfo.size();
586 }
587
588 int FocusriteMatrixMixer::getColCount( )
589 {
590     return m_ColInfo.size();
591 }
592
593
594 } // Focusrite
595 } // BeBoB
Note: See TracBrowser for help on using the browser.