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

Revision 2452, 29.7 kB (checked in by mocchi, 5 years ago)

[Fireworks] add a workaround for Audiofire12 (and maybe Audiofire8)

EfcGetClockCmd? over FCP is often failed or return invalid data. This commit add retry for doEfcOverFCP().

When the trials are completely failed, for sampling rate operation, a fallback to 'input/output plug signal format' command is executed. This command seems to be supported by all models.

But the driver can't know current clock source via 'plug signal format' command. This commit add 'm_current_clock' member to keep the id. This member is updated by setClock(). When getClock() is faled even if this member is not set, fallback to internal clock.

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