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

Revision 1910, 28.2 kB (checked in by arnonym, 10 years ago)

Fix #308: Do the sample-rate changing the way the echo devices need them. I can't test this due to a lack of echo devices, if this breaks anything (specially the non pre8-devices), please re-open the ticket #308.

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