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

Revision 965, 13.7 kB (checked in by ppalmers, 15 years ago)

add generic register read for focusrite devices

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