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

Revision 1737, 6.6 kB (checked in by arnonym, 14 years ago)

Be less noisy. And output a wanring if writing to the application space fails.

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 "focusrite_eap.h"
26
27 namespace Dice {
28 namespace Focusrite {
29
30 const int msgSet = 0x68;
31
32 FocusriteEAP::Poti::Poti(Dice::Focusrite::FocusriteEAP* eap, std::string name, size_t offset)
33     : Control::Discrete(eap, name)
34     , m_eap(eap)
35     , m_offset(offset)
36 {
37     m_eap->readApplicationReg(m_offset, &m_tmp);
38     //printf("%s: Value: %i\n", name.c_str(), m_tmp);
39     m_value = /*127*/-m_tmp;
40 }
41
42 int FocusriteEAP::Poti::getValue() {
43     return m_value;
44 }
45 bool FocusriteEAP::Poti::setValue(int n) {
46     if (n == m_value)
47         return true;
48     m_value = n;
49     return m_eap->writeApplicationReg(m_offset, -n);
50 }
51
52
53 FocusriteEAP::FocusriteEAP(Dice::Device& dev) : Dice::Device::EAP(dev) {
54 }
55
56 bool FocusriteEAP::readApplicationReg(unsigned offset, quadlet_t* quadlet) {
57     return readReg(eRT_Application, offset, quadlet);
58 }
59 bool FocusriteEAP::writeApplicationReg(unsigned offset, quadlet_t quadlet) {
60     bool ret = writeReg(eRT_Application, offset, quadlet);
61     if (!ret) {
62         debugWarning("Couldn't write %i to register %x!\n", quadlet, offset);
63         return false;
64     }
65     debugOutput(DEBUG_LEVEL_VERBOSE, "Will sent command %i.\n", commandToFix(offset));
66     return writeReg(eRT_Application, msgSet, commandToFix(offset));
67 }
68
69
70 FocusriteEAP::Switch::Switch(Dice::Focusrite::FocusriteEAP* eap, std::string name, size_t offset, int activevalue )
71     : Control::Boolean(eap, name)
72     , m_eap(eap)
73     , m_selected(0)
74     , m_offset(offset)
75     , m_activevalue(activevalue)
76 {
77     m_eap->readApplicationReg(m_offset, &m_state_tmp);
78     //printf("%s: %s\n", name.c_str(), (m_state_tmp&m_activevalue)?"true":"false");
79     //debugOutput(DEBUG_LEVEL_VERBOSE, "Probably the initialization is the other way round.\n");
80     m_selected = (m_state_tmp&m_activevalue)?true:false;
81 }
82
83 bool FocusriteEAP::Switch::selected() {
84     return m_selected;
85 }
86
87 bool FocusriteEAP::Switch::select(bool n) {
88     if ( n != m_selected ) {
89         m_selected = n;
90         m_eap->readApplicationReg(m_offset, &m_state_tmp);
91         m_eap->writeApplicationReg(m_offset, m_state_tmp^m_activevalue);
92     }
93     return true;
94 }
95
96
97 class VolumeControl : public Control::Discrete
98 {
99 public:
100     VolumeControl(FocusriteEAP* eap, std::string name, size_t offset, int bitshift)
101         : Control::Discrete(eap, name)
102         , m_eap(eap)
103         , m_offset(offset)
104         , m_bitshift(bitshift)
105     {
106         quadlet_t tmp;
107         m_eap->readApplicationReg(m_offset, &tmp);
108         m_value = - ((tmp>>m_bitshift)&0xff);
109         //printf("%s: %i -> %i\n", name.c_str(), tmp, m_value);
110     }
111
112     int getValue(int) { return getValue(); }
113     bool setValue(int, int n) { return setValue(n); }
114
115     int getMinimum() { return -255; }
116     int getMaximum() { return 0; }
117
118     int getValue() { return m_value; }
119     bool setValue(int n) {
120         if (n == m_value)
121             return true;
122         m_value = n;
123         return m_eap->writeApplicationReg(m_offset, (-n)<<m_bitshift);
124     }
125 private:
126     FocusriteEAP* m_eap;
127     size_t m_offset;
128     int m_bitshift;
129     int m_value;
130 };
131
132
133 FocusriteEAP::MonitorSection::MonitorSection(Dice::Focusrite::FocusriteEAP* eap, std::string name)
134     : Control::Container(eap, name)
135     , m_eap(eap)
136     , m_monitorlevel(0)
137     , m_dimlevel(0)
138 {
139     Control::Container* grp_globalmute = new Control::Container(m_eap, "GlobalMute");
140     addElement(grp_globalmute);
141     m_mute = new Switch(m_eap, "State", 0x0C, 1);
142     grp_globalmute->addElement(m_mute);
143
144     Control::Container* grp_globaldim = new Control::Container(m_eap, "GlobalDim");
145     addElement(grp_globaldim);
146     m_dim = new Switch(m_eap, "State", 0x10, 1);
147     grp_globaldim->addElement(m_dim);
148     m_dimlevel = m_eap->getDimPoti("Level");
149     grp_globaldim->addElement(m_dimlevel);
150
151     Control::Container* grp_mono = new Control::Container(m_eap, "Mono");
152     addElement(grp_mono);
153
154     Control::Container* grp_globalvolume = new Control::Container(m_eap, "GlobalVolume");
155     addElement(grp_globalvolume);
156     m_monitorlevel = m_eap->getMonitorPoti("Level");
157     grp_globalvolume->addElement(m_monitorlevel);
158
159     Control::Container* grp_perchannel = new Control::Container(m_eap, "PerChannel");
160     addElement(grp_perchannel);
161
162     for (int i=0; i<10; ++i) {
163         std::stringstream stream;
164         stream << "AffectsCh" << i;
165         Switch* s = new Switch(m_eap, stream.str(), 0x3C, 1<<i);
166         grp_globalmute->addElement(s);
167         //m_mute_affected.push_back(s);
168         s = new Switch(m_eap, stream.str(), 0x3C, 1<<(10+i));
169         grp_globaldim->addElement(s);
170         //m_dim_affected.push_back(s);
171     }
172     for (int i=0; i<5; ++i) {
173         std::stringstream stream;
174         stream << "Ch" << i*2 << "Ch" << i*2+1;
175         Switch* s = new Switch(m_eap, stream.str(), 0x3C, 1<<(20+i));
176         grp_mono->addElement(s);
177         //m_mono.push_back(s);
178
179         stream.str(std::string());
180         stream << "AffectsCh" << i*2;
181         s = new Switch(m_eap, stream.str(), 0x28+i*4, 1);
182         grp_globalvolume->addElement(s);
183         stream.str(std::string());
184         stream << "AffectsCh" << i*2+1;
185         s = new Switch(m_eap, stream.str(), 0x28+i*4, 2);
186         grp_globalvolume->addElement(s);
187
188         stream.str(std::string());
189         stream << "Mute" << i*2;
190         s = new Switch(m_eap, stream.str(), 0x28+i*4, 4);
191         grp_perchannel->addElement(s);
192         stream.str(std::string());
193         stream << "Mute" << i*2+1;
194         s = new Switch(m_eap, stream.str(), 0x28+i*4, 8);
195         grp_perchannel->addElement(s);
196
197         stream.str(std::string());
198         stream << "Volume" << i*2;
199         VolumeControl* vol = new VolumeControl(m_eap, stream.str(), 0x14+i*4, 0);
200         grp_perchannel->addElement(vol);
201         stream.str(std::string());
202         stream << "Volume" << i*2+1;
203         vol = new VolumeControl(m_eap, stream.str(), 0x14+i*4, 8);
204         grp_perchannel->addElement(vol);
205     }
206 }
207
208 }
209 }
210
211 // vim: et
Note: See TracBrowser for help on using the browser.