root/trunk/libffado/src/bebob/focusrite/focusrite_generic.cpp

Revision 1543, 16.7 kB (checked in by ppalmers, 14 years ago)

- Clean up class names
- Change probe code for all devices (except MOTU) to use the config file based approach

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