root/trunk/libffado/src/fireworks/fireworks_device.cpp

Revision 2394, 28.8 kB (checked in by jwoithe, 5 years ago)

fireworks: add playback routing function, patch 3/4: add playback routing mixer elements in driver. From Takashi Sakamoto.

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 "config.h"
25 #include "devicemanager.h"
26 #include "fireworks_device.h"
27 #include "efc/efc_avc_cmd.h"
28 #include "efc/efc_cmd.h"
29 #include "efc/efc_cmds_hardware.h"
30 #include "efc/efc_cmds_hardware_ctrl.h"
31 #include "efc/efc_cmds_flash.h"
32
33 #include "audiofire/audiofire_device.h"
34
35 #include "libieee1394/configrom.h"
36 #include "libieee1394/ieee1394service.h"
37
38 #include "fireworks/fireworks_control.h"
39
40 #include "libutil/PosixMutex.h"
41
42 #include "IntelFlashMap.h"
43
44 #define ECHO_FLASH_ERASE_TIMEOUT_MILLISECS 2000
45 #define FIREWORKS_MIN_FIRMWARE_VERSION 0x04080000
46
47 #include <sstream>
48 #include <unistd.h>
49 using namespace std;
50
51 // FireWorks is the platform used and developed by ECHO AUDIO
52 namespace FireWorks {
53
54 Device::Device(DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
55     : GenericAVC::Device( d, configRom)
56     , m_poll_lock( new Util::PosixMutex("DEVPOLL") )
57     , m_efc_discovery_done ( false )
58     , m_MixerContainer ( NULL )
59     , m_HwInfoContainer ( NULL )
60 {
61     debugOutput( DEBUG_LEVEL_VERBOSE, "Created FireWorks::Device (NodeID %d)\n",
62                  getConfigRom().getNodeId() );
63 }
64
65 Device::~Device()
66 {
67     destroyMixer();
68 }
69
70 void
71 Device::showDevice()
72 {
73     debugOutput(DEBUG_LEVEL_VERBOSE, "This is a FireWorks::Device\n");
74     if ( !m_efc_discovery_done) {
75         if (!discoverUsingEFC()) {
76             debugError("EFC discovery failed\n");
77         }
78     }
79     m_HwInfo.showEfcCmd();
80     GenericAVC::Device::showDevice();
81 }
82
83 bool
84 Device::probe( Util::Configuration& c, ConfigRom& configRom, bool generic )
85 {
86     if(generic) {
87         // try an EFC command
88         EfcOverAVCCmd cmd( configRom.get1394Service() );
89         cmd.setCommandType( AVC::AVCCommand::eCT_Control );
90         cmd.setNodeId( configRom.getNodeId() );
91         cmd.setSubunitType( AVC::eST_Unit  );
92         cmd.setSubunitId( 0xff );
93         cmd.setVerbose( configRom.getVerboseLevel() );
94
95         EfcHardwareInfoCmd hwInfo;
96         hwInfo.setVerboseLevel(configRom.getVerboseLevel());
97         cmd.m_cmd = &hwInfo;
98
99         if ( !cmd.fire()) {
100             return false;
101         }
102
103         if ( cmd.getResponse() != AVC::AVCCommand::eR_Accepted) {
104             return false;
105         }
106         if ( hwInfo.m_header.retval != EfcCmd::eERV_Ok
107              && hwInfo.m_header.retval != EfcCmd::eERV_FlashBusy) {
108              debugError( "EFC command failed\n" );
109              return false;
110         }
111         return true;
112     } else {
113         unsigned int vendorId = configRom.getNodeVendorId();
114         unsigned int modelId = configRom.getModelId();
115         Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId );
116         return c.isValid(vme) && vme.driver == Util::Configuration::eD_FireWorks;
117     }
118 }
119
120 bool
121 Device::discover()
122 {
123     unsigned int vendorId = getConfigRom().getNodeVendorId();
124     unsigned int modelId = getConfigRom().getModelId();
125
126     Util::Configuration &c = getDeviceManager().getConfiguration();
127     Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId );
128
129     if (c.isValid(vme) && vme.driver == Util::Configuration::eD_FireWorks) {
130         debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
131                      vme.vendor_name.c_str(),
132                      vme.model_name.c_str());
133     } else {
134         debugWarning("Using generic ECHO Audio FireWorks support for unsupported device '%s %s'\n",
135                      getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str());
136     }
137
138     // get the info from the EFC
139     if ( !discoverUsingEFC() ) {
140         return false;
141     }
142
143     // discover AVC-wise
144     if ( !GenericAVC::Device::discoverGeneric() ) {
145         debugError( "Could not discover GenericAVC::Device\n" );
146         return false;
147     }
148
149     if(!buildMixer()) {
150         debugWarning("Could not build mixer\n");
151     }
152
153     return true;
154 }
155
156 bool
157 Device::discoverUsingEFC()
158 {
159     m_efc_discovery_done = false;
160     m_HwInfo.setVerboseLevel(getDebugLevel());
161
162     if (!doEfcOverAVC(m_HwInfo)) {
163         debugError("Could not read hardware capabilities\n");
164         return false;
165     }
166
167     // check the firmware version
168     if (m_HwInfo.m_arm_version < FIREWORKS_MIN_FIRMWARE_VERSION) {
169         debugError("Firmware version %u.%u (rev %u) not recent enough. FFADO requires at least version %u.%u (rev %u).\n",
170                     (m_HwInfo.m_arm_version >> 24) & 0xFF,
171                     (m_HwInfo.m_arm_version >> 16) & 0xFF,
172                     (m_HwInfo.m_arm_version >> 0) & 0xFFFF,
173                     (FIREWORKS_MIN_FIRMWARE_VERSION >> 24) & 0xFF,
174                     (FIREWORKS_MIN_FIRMWARE_VERSION >> 16) & 0xFF,
175                     (FIREWORKS_MIN_FIRMWARE_VERSION >> 0) & 0xFFFF
176                     );
177         return false;
178     }
179
180     // save the EFC version, since some stuff
181     // depends on this
182     m_efc_version = m_HwInfo.m_header.version;
183
184     if (!updatePolledValues()) {
185         debugError("Could not update polled values\n");
186         return false;
187     }
188
189     m_efc_discovery_done = true;
190     return true;
191 }
192
193 FFADODevice *
194 Device::createDevice(DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
195 {
196     unsigned int vendorId = configRom->getNodeVendorId();
197 //     unsigned int modelId = configRom->getModelId();
198
199     switch(vendorId) {
200         case FW_VENDORID_ECHO: return new ECHO::AudioFire(d, configRom );
201         default: return new Device(d, configRom );
202     }
203 }
204
205 bool
206 Device::doEfcOverAVC(EfcCmd &c) {
207     EfcOverAVCCmd cmd( get1394Service() );
208     cmd.setCommandType( AVC::AVCCommand::eCT_Control );
209     cmd.setNodeId( getConfigRom().getNodeId() );
210     cmd.setSubunitType( AVC::eST_Unit  );
211     cmd.setSubunitId( 0xff );
212
213     cmd.setVerbose( getDebugLevel() );
214     cmd.m_cmd = &c;
215
216     if ( !cmd.fire()) {
217         debugError( "EfcOverAVCCmd command failed\n" );
218         c.showEfcCmd();
219         return false;
220     }
221
222     if ( cmd.getResponse() != AVC::AVCCommand::eR_Accepted) {
223         debugError( "EfcOverAVCCmd not accepted\n" );
224         return false;
225     }
226
227     if (   c.m_header.retval != EfcCmd::eERV_Ok
228         && c.m_header.retval != EfcCmd::eERV_FlashBusy) {
229         debugError( "EFC command failed\n" );
230         c.showEfcCmd();
231         return false;
232     }
233
234     return true;
235 }
236
237 bool
238 Device::buildMixer()
239 {
240     bool result=true;
241     debugOutput(DEBUG_LEVEL_VERBOSE, "Building a FireWorks mixer...\n");
242    
243     destroyMixer();
244    
245     // create the mixer object container
246     m_MixerContainer = new Control::Container(this, "Mixer");
247
248     if (!m_MixerContainer) {
249         debugError("Could not create mixer container...\n");
250         return false;
251     }
252
253     // create control objects for the audiofire
254
255     // matrix mix controls
256     result &= m_MixerContainer->addElement(
257         new MonitorControl(*this, MonitorControl::eMC_Gain, "MonitorGain"));
258
259     result &= m_MixerContainer->addElement(
260         new MonitorControl(*this, MonitorControl::eMC_Mute, "MonitorMute"));
261
262     result &= m_MixerContainer->addElement(
263         new MonitorControl(*this, MonitorControl::eMC_Solo, "MonitorSolo"));
264
265     result &= m_MixerContainer->addElement(
266         new MonitorControl(*this, MonitorControl::eMC_Pan, "MonitorPan"));
267
268     // Playback mix controls
269     for (unsigned int ch=0;ch<m_HwInfo.m_nb_1394_playback_channels;ch++) {
270         std::ostringstream node_name;
271         node_name << "PC" << ch;
272        
273         result &= m_MixerContainer->addElement(
274             new BinaryControl(*this, eMT_PlaybackMix, eMC_Mute, ch, 0, node_name.str()+"Mute"));
275         result &= m_MixerContainer->addElement(
276             new BinaryControl(*this, eMT_PlaybackMix, eMC_Solo, ch, 0, node_name.str()+"Solo"));
277         result &= m_MixerContainer->addElement(
278             new SimpleControl(*this, eMT_PlaybackMix, eMC_Gain, ch, node_name.str()+"Gain"));
279     }
280    
281     // Physical output mix controls
282     for (unsigned int ch=0;ch<m_HwInfo.m_nb_phys_audio_out;ch++) {
283         std::ostringstream node_name;
284         node_name << "OUT" << ch;
285        
286         result &= m_MixerContainer->addElement(
287             new BinaryControl(*this, eMT_PhysicalOutputMix, eMC_Mute, ch, 0, node_name.str()+"Mute"));
288         result &= m_MixerContainer->addElement(
289             new BinaryControl(*this, eMT_PhysicalOutputMix, eMC_Nominal, ch, 1, node_name.str()+"Nominal"));
290         result &= m_MixerContainer->addElement(
291             new SimpleControl(*this, eMT_PhysicalOutputMix, eMC_Gain, ch, node_name.str()+"Gain"));
292     }
293    
294     // Physical input mix controls
295     for (unsigned int ch=0;ch<m_HwInfo.m_nb_phys_audio_in;ch++) {
296         std::ostringstream node_name;
297         node_name << "IN" << ch;
298        
299         // result &= m_MixerContainer->addElement(
300         //     new BinaryControl(*this, eMT_PhysicalInputMix, eMC_Pad, ch, 0, node_name.str()+"Pad"));
301         result &= m_MixerContainer->addElement(
302             new BinaryControl(*this, eMT_PhysicalInputMix, eMC_Nominal, ch, 1, node_name.str()+"Nominal"));
303     }
304
305     // add hardware information controls
306     m_HwInfoContainer = new Control::Container(this, "HwInfo");
307     result &= m_HwInfoContainer->addElement(
308         new HwInfoControl(*this, HwInfoControl::eHIF_PhysicalAudioOutCount, "PhysicalAudioOutCount"));
309     result &= m_HwInfoContainer->addElement(
310         new HwInfoControl(*this, HwInfoControl::eHIF_PhysicalAudioInCount, "PhysicalAudioInCount"));
311     result &= m_HwInfoContainer->addElement(
312         new HwInfoControl(*this, HwInfoControl::eHIF_1394PlaybackCount, "1394PlaybackCount"));
313     result &= m_HwInfoContainer->addElement(
314         new HwInfoControl(*this, HwInfoControl::eHIF_1394RecordCount, "1394RecordCount"));
315     result &= m_HwInfoContainer->addElement(
316         new HwInfoControl(*this, HwInfoControl::eHIF_GroupOutCount, "GroupOutCount"));
317     result &= m_HwInfoContainer->addElement(
318         new HwInfoControl(*this, HwInfoControl::eHIF_GroupInCount, "GroupInCount"));
319     result &= m_HwInfoContainer->addElement(
320         new HwInfoControl(*this, HwInfoControl::eHIF_PhantomPower, "PhantomPower"));
321     result &= m_HwInfoContainer->addElement(
322         new HwInfoControl(*this, HwInfoControl::eHIF_OpticalInterface, "OpticalInterface"));
323     result &= m_HwInfoContainer->addElement(
324         new HwInfoControl(*this, HwInfoControl::eHIF_PlaybackRouting, "PlaybackRouting"));
325
326     // add a save settings control
327     result &= this->addElement(
328         new MultiControl(*this, MultiControl::eT_SaveSession, "SaveSettings"));
329
330     // add an identify control
331     result &= this->addElement(
332         new MultiControl(*this, MultiControl::eT_Identify, "Identify"));
333
334     // spdif mode control
335     result &= this->addElement(
336         new SpdifModeControl(*this, "SpdifMode"));
337
338     // check for IO config controls and add them if necessary
339     if(m_HwInfo.hasMirroring()) {
340         result &= this->addElement(
341             new IOConfigControl(*this, eCR_Mirror, "ChannelMirror"));
342     }
343     if(m_HwInfo.hasOpticalInterface()) {
344         result &= this->addElement(
345             new IOConfigControl(*this, eCR_DigitalInterface, "DigitalInterface"));
346     }
347     if(m_HwInfo.hasSoftwarePhantom()) {
348         result &= this->addElement(
349             new IOConfigControl(*this, eCR_Phantom, "PhantomPower"));
350     }
351     if(m_HwInfo.hasPlaybackRouting()) {
352         result &= this->addElement(
353             new PlaybackRoutingControl(*this, "PlaybackRouting"));
354     }
355
356     if (!result) {
357         debugWarning("One or more control elements could not be created.");
358         // clean up those that couldn't be created
359         destroyMixer();
360         return false;
361     }
362
363     if (!addElement(m_MixerContainer)) {
364         debugWarning("Could not register mixer to device\n");
365         // clean up
366         destroyMixer();
367         return false;
368     }
369
370     if (!addElement(m_HwInfoContainer)) {
371         debugWarning("Could not register hwinfo to device\n");
372         // clean up
373         destroyMixer();
374         return false;
375     }
376
377     // load the session block
378     if (!loadSession()) {
379         debugWarning("Could not load session\n");
380     }
381
382     return true;
383 }
384
385 bool
386 Device::destroyMixer()
387 {
388     debugOutput(DEBUG_LEVEL_VERBOSE, "destroy mixer...\n");
389
390     if (m_MixerContainer == NULL) {
391         debugOutput(DEBUG_LEVEL_VERBOSE, "no mixer to destroy...\n");
392     } else {
393         if (!deleteElement(m_MixerContainer)) {
394             debugError("Mixer present but not registered to the avdevice\n");
395             return false;
396         }
397
398         // remove and delete (as in free) child control elements
399         m_MixerContainer->clearElements(true);
400         delete m_MixerContainer;
401         m_MixerContainer = NULL;
402     }
403
404     if (m_HwInfoContainer == NULL) {
405         debugOutput(DEBUG_LEVEL_VERBOSE, "no hwinfo to destroy...\n");
406     } else {
407         if (!deleteElement(m_HwInfoContainer)) {
408             debugError("HwInfo present but not registered to the avdevice\n");
409             return false;
410         }
411
412         // remove and delete (as in free) child control elements
413         m_HwInfoContainer->clearElements(true);
414         delete m_HwInfoContainer;
415         m_HwInfoContainer = NULL;
416     }
417     return true;
418 }
419
420 bool
421 Device::saveSession()
422 {
423     // save the session block
424 //     if ( !updateSession() ) {
425 //         debugError( "Could not update session\n" );
426 //     } else {
427         if ( !m_session.saveToDevice(*this) ) {
428             debugError( "Could not save session block\n" );
429         }
430 //     }
431
432     return true;
433 }
434
435 bool
436 Device::loadSession()
437 {
438     if ( !m_session.loadFromDevice(*this) ) {
439         debugError( "Could not load session block\n" );
440         return false;
441     }
442     return true;
443 }
444
445 bool
446 Device::updatePolledValues() {
447     Util::MutexLockHelper lock(*m_poll_lock);
448     return doEfcOverAVC(m_Polled);
449 }
450
451 #define ECHO_CHECK_AND_ADD_SR(v, x) \
452     { if(x >= m_HwInfo.m_min_sample_rate && x <= m_HwInfo.m_max_sample_rate) \
453       v.push_back(x); }
454 std::vector<int>
455 Device::getSupportedSamplingFrequencies()
456 {
457     std::vector<int> frequencies;
458     ECHO_CHECK_AND_ADD_SR(frequencies, 22050);
459     ECHO_CHECK_AND_ADD_SR(frequencies, 24000);
460     ECHO_CHECK_AND_ADD_SR(frequencies, 32000);
461     ECHO_CHECK_AND_ADD_SR(frequencies, 44100);
462     ECHO_CHECK_AND_ADD_SR(frequencies, 48000);
463     ECHO_CHECK_AND_ADD_SR(frequencies, 88200);
464     ECHO_CHECK_AND_ADD_SR(frequencies, 96000);
465     ECHO_CHECK_AND_ADD_SR(frequencies, 176400);
466     ECHO_CHECK_AND_ADD_SR(frequencies, 192000);
467     return frequencies;
468 }
469
470 FFADODevice::ClockSourceVector
471 Device::getSupportedClockSources() {
472     FFADODevice::ClockSourceVector r;
473
474     if (!m_efc_discovery_done) {
475         debugError("EFC discovery not done yet!\n");
476         return r;
477     }
478
479     uint32_t active_clock=getClock();
480
481     if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_INTERNAL)) {
482         debugOutput(DEBUG_LEVEL_VERBOSE, "Internal clock supported\n");
483         ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_INTERNAL);
484         s.active=(active_clock == EFC_CMD_HW_CLOCK_INTERNAL);
485         if (s.type != eCT_Invalid) r.push_back(s);
486     }
487     if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_SYTMATCH)) {
488         debugOutput(DEBUG_LEVEL_VERBOSE, "Syt Match clock supported\n");
489         ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_SYTMATCH);
490         s.active=(active_clock == EFC_CMD_HW_CLOCK_SYTMATCH);
491         if (s.type != eCT_Invalid) r.push_back(s);
492     }
493     if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_WORDCLOCK)) {
494         debugOutput(DEBUG_LEVEL_VERBOSE, "WordClock supported\n");
495         ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_WORDCLOCK);
496         s.active=(active_clock == EFC_CMD_HW_CLOCK_WORDCLOCK);
497         if (s.type != eCT_Invalid) r.push_back(s);
498     }
499     if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_SPDIF)) {
500         debugOutput(DEBUG_LEVEL_VERBOSE, "SPDIF clock supported\n");
501         ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_SPDIF);
502         s.active=(active_clock == EFC_CMD_HW_CLOCK_SPDIF);
503         if (s.type != eCT_Invalid) r.push_back(s);
504     }
505     if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_ADAT_1)) {
506         debugOutput(DEBUG_LEVEL_VERBOSE, "ADAT 1 clock supported\n");
507         ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_ADAT_1);
508         s.active=(active_clock == EFC_CMD_HW_CLOCK_ADAT_1);
509         if (s.type != eCT_Invalid) r.push_back(s);
510     }
511     if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_ADAT_2)) {
512         debugOutput(DEBUG_LEVEL_VERBOSE, "ADAT 2 clock supported\n");
513         ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_ADAT_2);
514         s.active=(active_clock == EFC_CMD_HW_CLOCK_ADAT_2);
515         if (s.type != eCT_Invalid) r.push_back(s);
516     }
517     return r;
518 }
519
520 bool
521 Device::isClockValid(uint32_t id) {
522     // always valid
523     if (id==EFC_CMD_HW_CLOCK_INTERNAL) return true;
524
525     // the polled values are used to detect
526     // whether clocks are valid
527     if (!updatePolledValues()) {
528         debugError("Could not update polled values\n");
529         return false;
530     }
531     return EFC_CMD_HW_CHECK_FLAG(m_Polled.m_status,id);
532 }
533
534 bool
535 Device::setActiveClockSource(ClockSource s) {
536     bool result;
537
538     debugOutput(DEBUG_LEVEL_VERBOSE, "setting clock source to id: %d\n",s.id);
539
540     if(!isClockValid(s.id)) {
541         debugError("Clock not valid\n");
542         return false;
543     }
544
545     result=setClock(s.id);
546
547     // From the ECHO sources:
548     // "If this is a 1200F and the sample rate is being set via EFC, then
549     // send the "phy reconnect command" so the device will vanish and reappear
550     // with a new descriptor."
551
552 //     EfcPhyReconnectCmd rccmd;
553 //     if(!doEfcOverAVC(rccmd)) {
554 //         debugError("Phy reconnect failed\n");
555 //     } else {
556 //         // sleep for one second such that the phy can get reconnected
557 //         sleep(1);
558 //     }
559
560     return result;
561 }
562
563 FFADODevice::ClockSource
564 Device::getActiveClockSource() {
565     ClockSource s;
566     uint32_t active_clock=getClock();
567     s=clockIdToClockSource(active_clock);
568     s.active=true;
569     return s;
570 }
571
572 FFADODevice::ClockSource
573 Device::clockIdToClockSource(uint32_t clockid) {
574     ClockSource s;
575     debugOutput(DEBUG_LEVEL_VERBOSE, "clock id: %u\n", clockid);
576
577     // the polled values are used to detect
578     // whether clocks are valid
579     if (!updatePolledValues()) {
580         debugError("Could not update polled values\n");
581         return s;
582     }
583
584     switch (clockid) {
585         case EFC_CMD_HW_CLOCK_INTERNAL:
586             debugOutput(DEBUG_LEVEL_VERBOSE, "Internal clock\n");
587             s.type=eCT_Internal;
588             s.description="Internal sync";
589             break;
590
591         case EFC_CMD_HW_CLOCK_SYTMATCH:
592             debugOutput(DEBUG_LEVEL_VERBOSE, "Syt Match\n");
593             s.type=eCT_SytMatch;
594             s.description="SYT Match";
595             break;
596
597         case EFC_CMD_HW_CLOCK_WORDCLOCK:
598             debugOutput(DEBUG_LEVEL_VERBOSE, "WordClock\n");
599             s.type=eCT_WordClock;
600             s.description="Word Clock";
601             break;
602
603         case EFC_CMD_HW_CLOCK_SPDIF:
604             debugOutput(DEBUG_LEVEL_VERBOSE, "SPDIF clock\n");
605             s.type=eCT_SPDIF;
606             s.description="SPDIF";
607             break;
608
609         case EFC_CMD_HW_CLOCK_ADAT_1:
610             debugOutput(DEBUG_LEVEL_VERBOSE, "ADAT 1 clock\n");
611             s.type=eCT_ADAT;
612             s.description="ADAT 1";
613             break;
614
615         case EFC_CMD_HW_CLOCK_ADAT_2:
616             debugOutput(DEBUG_LEVEL_VERBOSE, "ADAT 2 clock\n");
617             s.type=eCT_ADAT;
618             s.description="ADAT 2";
619             break;
620
621         default:
622             debugError("Invalid clock id: %d\n",clockid);
623             return s; // return an invalid ClockSource
624     }
625
626     s.id=clockid;
627     s.valid=isClockValid(clockid);
628
629     return s;
630 }
631
632 uint32_t
633 Device::getClock() {
634     EfcGetClockCmd gccmd;
635     if (!doEfcOverAVC(gccmd)) {
636         debugError("Could not get clock info\n");
637         return EFC_CMD_HW_CLOCK_UNSPECIFIED;
638     }
639     debugOutput(DEBUG_LEVEL_VERBOSE, "Active clock: 0x%08X\n",gccmd.m_clock);
640     gccmd.showEfcCmd();
641
642     return gccmd.m_clock;
643 }
644
645 bool
646 Device::setClock(uint32_t id) {
647     EfcGetClockCmd gccmd;
648     if (!doEfcOverAVC(gccmd)) {
649         debugError("Could not get clock info\n");
650         return false;
651     }
652     debugOutput(DEBUG_LEVEL_VERBOSE, "Set clock: 0x%08X\n", id);
653
654     EfcSetClockCmd sccmd;
655     sccmd.m_clock=id;
656     sccmd.m_samplerate=gccmd.m_samplerate;
657     sccmd.m_index=0;
658     if (!doEfcOverAVC(sccmd)) {
659         debugError("Could not set clock info\n");
660         return false;
661     }
662     return true;
663 }
664
665 bool
666 Device::lockFlash(bool lock) {
667     // some hardware doesn't need/support flash lock
668     if (m_HwInfo.hasDSP()) {
669         debugOutput(DEBUG_LEVEL_VERBOSE, "flash lock not needed\n");
670         return true;
671     }
672
673     EfcFlashLockCmd cmd;
674     cmd.m_lock = lock;
675
676     if(!doEfcOverAVC(cmd)) {
677         debugError("Flash lock failed\n");
678         return false;
679     }
680     return true;
681 }
682
683 bool
684 Device::writeFlash(uint32_t start, uint32_t len, uint32_t* buffer) {
685
686     if(len <= 0 || 0xFFFFFFFF - len*4 < start) {
687         debugError("bogus start/len: 0x%08X / %u\n", start, len);
688         return false;
689     }
690     if(start & 0x03) {
691         debugError("start address not quadlet aligned: 0x%08X\n", start);
692         return false;
693     }
694
695     uint32_t start_addr = start;
696     uint32_t stop_addr = start + len*4;
697     uint32_t *target_buffer = buffer;
698
699     EfcFlashWriteCmd cmd;
700     // write EFC_FLASH_SIZE_BYTES at a time
701     for(start_addr = start; start_addr < stop_addr; start_addr += EFC_FLASH_SIZE_BYTES) {
702         cmd.m_address = start_addr;
703         unsigned int quads_to_write = (stop_addr - start_addr)/4;
704         if (quads_to_write > EFC_FLASH_SIZE_QUADS) {
705             quads_to_write = EFC_FLASH_SIZE_QUADS;
706         }
707         cmd.m_nb_quadlets = quads_to_write;
708         for(unsigned int i=0; i<quads_to_write; i++) {
709             cmd.m_data[i] = *target_buffer;
710             target_buffer++;
711         }
712         if(!doEfcOverAVC(cmd)) {
713             debugError("Flash write failed for block 0x%08X (%d quadlets)\n", start_addr, quads_to_write);
714             return false;
715         }
716     }
717     return true;
718 }
719
720 bool
721 Device::readFlash(uint32_t start, uint32_t len, uint32_t* buffer) {
722
723     if(len <= 0 || 0xFFFFFFFF - len*4 < start) {
724         debugError("bogus start/len: 0x%08X / %u\n", start, len);
725         return false;
726     }
727     if(start & 0x03) {
728         debugError("start address not quadlet aligned: 0x%08X\n", start);
729         return false;
730     }
731
732     uint32_t start_addr = start;
733     uint32_t stop_addr = start + len*4;
734     uint32_t *target_buffer = buffer;
735
736     EfcFlashReadCmd cmd;
737     // read EFC_FLASH_SIZE_BYTES at a time
738     for(start_addr = start; start_addr < stop_addr; start_addr += EFC_FLASH_SIZE_BYTES) {
739         unsigned int quads_to_read = (stop_addr - start_addr)/4;
740         if (quads_to_read > EFC_FLASH_SIZE_QUADS) {
741             quads_to_read = EFC_FLASH_SIZE_QUADS;
742         }
743         uint32_t quadlets_read = 0;
744         int ntries = 10000;
745         do {
746             cmd.m_address = start_addr + quadlets_read*4;
747             unsigned int new_to_read = quads_to_read - quadlets_read;
748             cmd.m_nb_quadlets = new_to_read;
749             if(!doEfcOverAVC(cmd)) {
750                 debugError("Flash read failed for block 0x%08X (%d quadlets)\n", start_addr, quads_to_read);
751                 return false;
752             }
753             if(cmd.m_nb_quadlets != new_to_read) {
754                 debugOutput(DEBUG_LEVEL_VERBOSE,
755                             "Flash read didn't return enough data (%u/%u) \n",
756                             cmd.m_nb_quadlets, new_to_read);
757                 // continue trying
758             }
759             quadlets_read += cmd.m_nb_quadlets;
760
761             // copy content
762             for(unsigned int i=0; i<cmd.m_nb_quadlets; i++) {
763                 *target_buffer = cmd.m_data[i];
764                 target_buffer++;
765             }
766         } while(quadlets_read < quads_to_read && ntries--);
767         if(ntries==0) {
768             debugError("deadlock while reading flash\n");
769             return false;
770         }
771     }
772     return true;
773 }
774
775 bool
776 Device::eraseFlash(uint32_t addr) {
777     if(addr & 0x03) {
778         debugError("start address not quadlet aligned: 0x%08X\n", addr);
779         return false;
780     }
781     EfcFlashEraseCmd cmd;
782     cmd.m_address = addr;
783     if(!doEfcOverAVC(cmd)) {
784         if (cmd.m_header.retval == EfcCmd::eERV_FlashBusy) {
785             return true;
786         }
787         debugError("Flash erase failed for block 0x%08X\n", addr);
788         return false;
789     }
790     return true;
791 }
792
793 bool
794 Device::eraseFlashBlocks(uint32_t start_address, unsigned int nb_quads)
795 {
796     uint32_t blocksize_bytes;
797     uint32_t blocksize_quads;
798     unsigned int quads_left = nb_quads;
799     bool success = true;
800
801     const unsigned int max_nb_tries = 10;
802     unsigned int nb_tries = 0;
803
804     do {
805         // the erase block size is fixed by the HW, and depends
806         // on the flash section we're in
807         if (start_address < MAINBLOCKS_BASE_OFFSET_BYTES)
808                 blocksize_bytes = PROGRAMBLOCK_SIZE_BYTES;
809         else
810                 blocksize_bytes = MAINBLOCK_SIZE_BYTES;
811         start_address &= ~(blocksize_bytes - 1);
812         blocksize_quads = blocksize_bytes / 4;
813
814         uint32_t verify[blocksize_quads];
815
816         // corner case: requested to erase less than one block
817         if (blocksize_quads > quads_left) {
818             blocksize_quads = quads_left;
819         }
820
821         // do the actual erase
822         if (!eraseFlash(start_address)) {
823             debugWarning("Could not erase flash block at 0x%08X\n", start_address);
824             success = false;
825         } else {
826             // wait for the flash to become ready again
827             if (!waitForFlash(ECHO_FLASH_ERASE_TIMEOUT_MILLISECS)) {
828                 debugError("Wait for flash timed out at address 0x%08X\n", start_address);
829                 return false;
830             }
831
832             // verify that the block is empty as an extra precaution
833             if (!readFlash(start_address, blocksize_quads, verify)) {
834                 debugError("Could not read flash block at 0x%08X\n", start_address);
835                 return false;
836             }
837
838             // everything should be 0xFFFFFFFF if the erase was successful
839             for (unsigned int i = 0; i < blocksize_quads; i++) {
840                 if (0xFFFFFFFF != verify[i]) {
841                     debugWarning("Flash erase verification failed.\n");
842                     success = false;
843                     break;
844                 }
845             }
846         }
847
848         if (success) {
849             start_address += blocksize_bytes;
850             quads_left -= blocksize_quads;
851             nb_tries = 0;
852         } else {
853             nb_tries++;
854         }
855         if (nb_tries > max_nb_tries) {
856             debugError("Needed too many tries to erase flash at 0x%08X\n", start_address);
857             return false;
858         }
859     } while (quads_left > 0);
860
861     return true;
862 }
863
864 bool
865 Device::waitForFlash(unsigned int msecs)
866 {
867     bool ready;
868
869     EfcFlashGetStatusCmd statusCmd;
870     const unsigned int time_to_sleep_usecs = 10000;
871     int wait_cycles = msecs * 1000 / time_to_sleep_usecs;
872
873     do {
874         if (!doEfcOverAVC(statusCmd)) {
875             debugError("Could not read flash status\n");
876             return false;
877         }
878         if (statusCmd.m_header.retval == EfcCmd::eERV_FlashBusy) {
879             ready = false;
880         } else {
881             ready = statusCmd.m_ready;
882         }
883         usleep(time_to_sleep_usecs);
884     } while (!ready && wait_cycles--);
885
886     if(wait_cycles == 0) {
887         debugError("Timeout while waiting for flash\n");
888         return false;
889     }
890
891     return ready;
892 }
893
894 uint32_t
895 Device::getSessionBase()
896 {
897     EfcFlashGetSessionBaseCmd cmd;
898     if(!doEfcOverAVC(cmd)) {
899         debugError("Could not get session base address\n");
900         return 0; // FIXME: arbitrary
901     }
902     return cmd.m_address;
903 }
904
905 int
906 Device::getSamplingFrequency( ) {
907     EfcGetClockCmd gccmd;
908     if (!doEfcOverAVC(gccmd)) {
909         debugError("Could not get clock info\n");
910         return false;
911     }
912     return gccmd.m_samplerate;
913 }
914 bool
915 Device::setSamplingFrequency( int s )
916 {
917     EfcGetClockCmd gccmd;
918     if (!doEfcOverAVC(gccmd)) {
919         debugError("Could not get clock info\n");
920         return false;
921     }
922     debugOutput(DEBUG_LEVEL_VERBOSE, "Set samplerate: %d\n", s);
923
924     EfcSetClockCmd sccmd;
925     sccmd.m_clock=gccmd.m_clock;
926     sccmd.m_samplerate=s;
927     sccmd.m_index=0;
928     if (!doEfcOverAVC(sccmd)) {
929         debugError("Could not set sample rate\n");
930         return false;
931     }
932     return true;
933 }
934
935
936 } // FireWorks
Note: See TracBrowser for help on using the browser.