root/trunk/libffado/src/dice/focusrite/saffire_pro24.cpp

Revision 1794, 5.6 kB (checked in by arnonym, 11 years ago)

This might (or might not) fix #256 by actually implementing EAP-support for the Pro40.

Please someone test this and report back.

Everything should work except:

  • The volume knob doesn't seem to have an effect on the Pro24, don't know about the Pro40. It writes to the right registers but somehow the hardware doesn't recognise it.
  • The "Use ADAT-Out as S/PDIF" and "Pad Output" are not implemented yet.
  • I don't know whether changing to nickname works with the Pro40. It doesn't with the Pro24 altough the correct registers are written to. Probably sending an OP-code is missing...
Line 
1 /*
2  * Copyright (C) 2009 by Pieter Palmers
3  * Copyright (C) 2009 by Arnold Krille
4  *
5  * This file is part of FFADO
6  * FFADO = Free Firewire (pro-)audio drivers for linux
7  *
8  * FFADO is based upon FreeBoB.
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 2 of the License, or
13  * (at your option) version 3 of the License.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #include "saffire_pro24.h"
26 #include "focusrite_eap.h"
27
28 namespace Dice {
29 namespace Focusrite {
30
31 int SaffirePro24::SaffirePro24EAP::commandToFix(unsigned offset) {
32     if (offset<0x14) return 2;
33     if (offset<0x3C && offset>=0x14) return 1;
34     if (offset<0x58 && offset>=0x50) return 1;
35     if (offset<0x40 && offset>=0x3C) return 3;
36     if (offset<0x60 && offset>=0x58) return 4;
37     return 0;
38 }
39 FocusriteEAP::Poti* SaffirePro24::SaffirePro24EAP::getMonitorPoti(std::string name) {
40     return new FocusriteEAP::Poti(this, name, 0x50);
41 }
42 FocusriteEAP::Poti* SaffirePro24::SaffirePro24EAP::getDimPoti(std::string name) {
43     return new FocusriteEAP::Poti(this, name, 0x54);
44 }
45
46 void SaffirePro24::SaffirePro24EAP::setupSources() {
47     addSource("SPDIF",  6,  2, eRS_AES);
48     addSource("ADAT",   0,  8, eRS_ADAT);
49     addSource("Analog", 0,  4, eRS_InS0);
50     addSource("Mixer",  0, 16, eRS_Mixer);
51     addSource("1394",   0,  8, eRS_ARX0);
52     addSource("Mute",   0,  1, eRS_Muted);
53 }
54 void SaffirePro24::SaffirePro24EAP::setupDestinations() {
55     addDestination("SPDIF",  6,  2, eRD_AES);
56     addDestination("Analog", 0,  6, eRD_InS0);
57     addDestination("Mixer",  0, 16, eRD_Mixer0);
58     addDestination("Mixer",  0,  2, eRD_Mixer1, 16);
59     addDestination("1394",   0, 16, eRD_ATX0);
60     addDestination("Mute",   0,  1, eRD_Muted);
61 }
62
63
64 class SaffirePro24::LineInstSwitch : public Dice::Focusrite::FocusriteEAP::Switch
65 {
66 public:
67     LineInstSwitch(Dice::Focusrite::FocusriteEAP* eap, std::string name, size_t offset, int activevalue)
68         : Dice::Focusrite::FocusriteEAP::Switch(eap, name, offset, activevalue) {}
69     std::string getBooleanLabel(bool n) {
70         if ( n ) return "Instrument";
71         return "Line";
72     }
73 };
74 class SaffirePro24::LevelSwitch : public Dice::Focusrite::FocusriteEAP::Switch
75 {
76 public:
77     LevelSwitch(Dice::Focusrite::FocusriteEAP* eap, std::string name, size_t offset, int activevalue)
78         : Dice::Focusrite::FocusriteEAP::Switch(eap, name, offset, activevalue) {}
79     std::string getBooleanLabel(bool n) {
80         if ( n ) return "High";
81         return "Low";
82     }
83 };
84
85 SaffirePro24::SaffirePro24( DeviceManager& d,
86                             std::auto_ptr<ConfigRom>( configRom ))
87     : Dice::Device(d , configRom)
88     , m_ch1(NULL)
89     , m_ch2(NULL)
90 {
91     debugOutput(DEBUG_LEVEL_VERBOSE, "Created Dice::Focusrite::SaffirePro24 (NodeID %d)\n",
92                 getConfigRom().getNodeId());
93 }
94
95 SaffirePro24::~SaffirePro24()
96 {
97     //debugOutput(DEBUG_LEVEL_VERBOSE, "Deleting the saffirePro24\n");
98     /// I wonder whether we should really save only on clean exits or also each time a setting is
99     //  changed. Or should we provide a function (and thus gui-button) to save the state of the
100     //  device?
101     getEAP()->storeFlashConfig();
102     getEAP()->deleteElement(m_ch1);
103     getEAP()->deleteElement(m_ch2);
104     if (m_ch1) delete m_ch1;
105     if (m_ch2) delete m_ch2;
106 }
107
108 bool SaffirePro24::discover() {
109     if (Dice::Device::discover()) {
110         fb_quadlet_t* tmp = (fb_quadlet_t *)calloc(2, sizeof(fb_quadlet_t));
111         getEAP()->readRegBlock(Dice::EAP::eRT_Application, 0x00, tmp, 1*sizeof(fb_quadlet_t));
112         //hexDumpQuadlets(tmp, 2); // DEBUG
113         if (tmp[0] != 0x00010004 ) {
114             debugError("This is a Focusrite Saffire Pro24 but not the right firmware. Better stop here before something goes wrong.\n");
115             debugError("This device has firmware 0x%x while we only know about version 0x%x.\n", tmp[0], 0x10004);
116             return false;
117         }
118         //getEAP()->readRegBlock(Dice::EAP::eRT_Command, 0x00, tmp, 2*sizeof(fb_quadlet_t)); // DEBUG
119         //hexDumpQuadlets(tmp, 2); // DEBUG
120
121         FocusriteEAP* eap = dynamic_cast<FocusriteEAP*>(getEAP());
122         m_ch1 = new LineInstSwitch(eap, "Ch1LineInst", 0x58, 2);
123         getEAP()->addElement(m_ch1);
124         m_ch2 = new LineInstSwitch(eap, "Ch2LineInst", 0x58, 2<<16);
125         getEAP()->addElement(m_ch2);
126         m_ch3 = new LevelSwitch(eap, "Ch3Level", 0x5C, 1);
127         getEAP()->addElement(m_ch3);
128         m_ch4 = new LevelSwitch(eap, "Ch4Level", 0x5C, 1<<16);
129         getEAP()->addElement(m_ch4);
130
131         m_monitor = new FocusriteEAP::MonitorSection(eap, "Monitoring");
132         getEAP()->addElement(m_monitor);
133         return true;
134     }
135     return false;
136 }
137
138 void SaffirePro24::showDevice()
139 {
140     debugOutput(DEBUG_LEVEL_VERBOSE, "This is a Dice::Focusrite::SaffirePro24\n");
141     Dice::Device::showDevice();
142 }
143 Dice::EAP* SaffirePro24::createEAP() {
144     return new SaffirePro24EAP(*this);
145 }
146
147 bool SaffirePro24::setNickName( std::string name ) {
148     return getEAP()->writeRegBlock( Dice::EAP::eRT_Application, 0x40, (fb_quadlet_t*)name.c_str(), name.size() );
149 }
150
151 std::string SaffirePro24::getNickName() {
152     char name[16];
153     getEAP()->readRegBlock( Dice::EAP::eRT_Application, 0x40, (fb_quadlet_t*)name, 16 );
154     return std::string( name );
155 }
156
157 }
158 }
159
160 // vim: et
Note: See TracBrowser for help on using the browser.