2 * Copyright (C) 2005-2008 by Pieter Palmers
4 * This file is part of FFADO
5 * FFADO = Free Firewire (pro-)audio drivers for linux
7 * FFADO is based upon FreeBoB.
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.
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.
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/>.
24 // #include "config.h"
25 #include "devicemanager.h"
26 #include "fireworks_device.h"
27 #include "efc/efc_avc_cmd.h"
28 #include "efc/efc_cmds_flash.h"
30 #include "audiofire/audiofire_device.h"
32 #include "libieee1394/configrom.h"
33 #include "libieee1394/ieee1394service.h"
35 #include "fireworks/fireworks_control.h"
37 #include "libutil/PosixMutex.h"
39 #include "IntelFlashMap.h"
41 #define ECHO_FLASH_ERASE_TIMEOUT_MILLISECS 2000
42 #define FIREWORKS_MIN_FIRMWARE_VERSION 0x04080000
48 // FireWorks is the platform used and developed by ECHO AUDIO
51 Device::Device(DeviceManager
& d
, std::auto_ptr
<ConfigRom
>( configRom
))
52 : GenericAVC::Device( d
, configRom
)
53 , m_poll_lock( new Util::PosixMutex("DEVPOLL") )
54 , m_efc_discovery_done ( false )
55 , m_MixerContainer ( NULL
)
56 , m_HwInfoContainer ( NULL
)
58 debugOutput( DEBUG_LEVEL_VERBOSE
, "Created FireWorks::Device (NodeID %d)\n",
59 getConfigRom().getNodeId() );
70 debugOutput(DEBUG_LEVEL_VERBOSE
, "This is a FireWorks::Device\n");
71 if ( !m_efc_discovery_done
) {
72 if (!discoverUsingEFC()) {
73 debugError("EFC discovery failed\n");
76 m_HwInfo
.showEfcCmd();
77 GenericAVC::Device::showDevice();
81 Device::probe( Util::Configuration
& c
, ConfigRom
& configRom
, bool generic
)
85 EfcOverAVCCmd
cmd( configRom
.get1394Service() );
86 cmd
.setCommandType( AVC::AVCCommand::eCT_Control
);
87 cmd
.setNodeId( configRom
.getNodeId() );
88 cmd
.setSubunitType( AVC::eST_Unit
);
89 cmd
.setSubunitId( 0xff );
90 cmd
.setVerbose( configRom
.getVerboseLevel() );
92 EfcHardwareInfoCmd hwInfo
;
93 hwInfo
.setVerboseLevel(configRom
.getVerboseLevel());
100 if ( cmd
.getResponse() != AVC::AVCCommand::eR_Accepted
) {
103 if ( hwInfo
.m_header
.retval
!= EfcCmd::eERV_Ok
104 && hwInfo
.m_header
.retval
!= EfcCmd::eERV_FlashBusy
) {
105 debugError( "EFC command failed\n" );
110 unsigned int vendorId
= configRom
.getNodeVendorId();
111 unsigned int modelId
= configRom
.getModelId();
112 Util::Configuration::VendorModelEntry vme
= c
.findDeviceVME( vendorId
, modelId
);
113 return c
.isValid(vme
) && vme
.driver
== Util::Configuration::eD_FireWorks
;
120 unsigned int vendorId
= getConfigRom().getNodeVendorId();
121 unsigned int modelId
= getConfigRom().getModelId();
123 Util::Configuration
&c
= getDeviceManager().getConfiguration();
124 Util::Configuration::VendorModelEntry vme
= c
.findDeviceVME( vendorId
, modelId
);
126 if (c
.isValid(vme
) && vme
.driver
== Util::Configuration::eD_FireWorks
) {
127 debugOutput( DEBUG_LEVEL_VERBOSE
, "found %s %s\n",
128 vme
.vendor_name
.c_str(),
129 vme
.model_name
.c_str());
131 debugWarning("Using generic ECHO Audio FireWorks support for unsupported device '%s %s'\n",
132 getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str());
135 // get the info from the EFC
136 if ( !discoverUsingEFC() ) {
141 if ( !GenericAVC::Device::discoverGeneric() ) {
142 debugError( "Could not discover GenericAVC::Device\n" );
147 debugWarning("Could not build mixer\n");
154 Device::discoverUsingEFC()
156 m_efc_discovery_done
= false;
157 m_HwInfo
.setVerboseLevel(getDebugLevel());
159 if (!doEfcOverAVC(m_HwInfo
)) {
160 debugError("Could not read hardware capabilities\n");
164 // check the firmware version
165 if (m_HwInfo
.m_arm_version
< FIREWORKS_MIN_FIRMWARE_VERSION
) {
166 debugError("Firmware version %u.%u (rev %u) not recent enough. FFADO requires at least version %u.%u (rev %u).\n",
167 (m_HwInfo
.m_arm_version
>> 24) & 0xFF,
168 (m_HwInfo
.m_arm_version
>> 16) & 0xFF,
169 (m_HwInfo
.m_arm_version
>> 0) & 0xFFFF,
170 (FIREWORKS_MIN_FIRMWARE_VERSION
>> 24) & 0xFF,
171 (FIREWORKS_MIN_FIRMWARE_VERSION
>> 16) & 0xFF,
172 (FIREWORKS_MIN_FIRMWARE_VERSION
>> 0) & 0xFFFF
177 m_current_clock
= -1;
179 m_efc_discovery_done
= true;
184 Device::createDevice(DeviceManager
& d
, std::auto_ptr
<ConfigRom
>( configRom
))
186 unsigned int vendorId
= configRom
->getNodeVendorId();
187 // unsigned int modelId = configRom->getModelId();
190 case FW_VENDORID_ECHO
: return new ECHO::AudioFire(d
, configRom
);
191 default: return new Device(d
, configRom
);
195 bool Device::doEfcOverAVC(EfcCmd
&c
)
197 EfcOverAVCCmd
cmd( get1394Service() );
198 cmd
.setCommandType( AVC::AVCCommand::eCT_Control
);
199 cmd
.setNodeId( getConfigRom().getNodeId() );
200 cmd
.setSubunitType( AVC::eST_Unit
);
201 cmd
.setSubunitId( 0xff );
203 cmd
.setVerbose( getDebugLevel() );
207 debugError( "EfcOverAVCCmd command failed\n" );
212 if ( cmd
.getResponse() != AVC::AVCCommand::eR_Accepted
) {
213 debugError( "EfcOverAVCCmd not accepted\n" );
217 if ( c
.m_header
.retval
!= EfcCmd::eERV_Ok
218 && c
.m_header
.retval
!= EfcCmd::eERV_FlashBusy
) {
219 debugError( "EFC command failed\n" );
231 debugOutput(DEBUG_LEVEL_VERBOSE
, "Building a FireWorks mixer...\n");
235 // create the mixer object container
236 m_MixerContainer
= new Control::Container(this, "Mixer");
238 if (!m_MixerContainer
) {
239 debugError("Could not create mixer container...\n");
243 // create control objects for the audiofire
245 // matrix mix controls
246 result
&= m_MixerContainer
->addElement(
247 new MonitorControl(*this, MonitorControl::eMC_Gain
, "MonitorGain"));
249 result
&= m_MixerContainer
->addElement(
250 new MonitorControl(*this, MonitorControl::eMC_Mute
, "MonitorMute"));
252 result
&= m_MixerContainer
->addElement(
253 new MonitorControl(*this, MonitorControl::eMC_Solo
, "MonitorSolo"));
255 result
&= m_MixerContainer
->addElement(
256 new MonitorControl(*this, MonitorControl::eMC_Pan
, "MonitorPan"));
258 // Playback mix controls
259 for (unsigned int ch
=0;ch
<m_HwInfo
.m_nb_1394_playback_channels
;ch
++) {
260 std::ostringstream node_name
;
261 node_name
<< "PC" << ch
;
263 result
&= m_MixerContainer
->addElement(
264 new BinaryControl(*this, eMT_PlaybackMix
, eMC_Mute
, ch
, 0, node_name
.str()+"Mute"));
265 result
&= m_MixerContainer
->addElement(
266 new BinaryControl(*this, eMT_PlaybackMix
, eMC_Solo
, ch
, 0, node_name
.str()+"Solo"));
267 result
&= m_MixerContainer
->addElement(
268 new SimpleControl(*this, eMT_PlaybackMix
, eMC_Gain
, ch
, node_name
.str()+"Gain"));
271 // Physical output mix controls
272 for (unsigned int ch
=0;ch
<m_HwInfo
.m_nb_phys_audio_out
;ch
++) {
273 std::ostringstream node_name
;
274 node_name
<< "OUT" << ch
;
276 result
&= m_MixerContainer
->addElement(
277 new BinaryControl(*this, eMT_PhysicalOutputMix
, eMC_Mute
, ch
, 0, node_name
.str()+"Mute"));
278 result
&= m_MixerContainer
->addElement(
279 new BinaryControl(*this, eMT_PhysicalOutputMix
, eMC_Nominal
, ch
, 1, node_name
.str()+"Nominal"));
280 result
&= m_MixerContainer
->addElement(
281 new SimpleControl(*this, eMT_PhysicalOutputMix
, eMC_Gain
, ch
, node_name
.str()+"Gain"));
284 // Physical input mix controls
285 for (unsigned int ch
=0;ch
<m_HwInfo
.m_nb_phys_audio_in
;ch
++) {
286 std::ostringstream node_name
;
287 node_name
<< "IN" << ch
;
289 // result &= m_MixerContainer->addElement(
290 // new BinaryControl(*this, eMT_PhysicalInputMix, eMC_Pad, ch, 0, node_name.str()+"Pad"));
291 result
&= m_MixerContainer
->addElement(
292 new BinaryControl(*this, eMT_PhysicalInputMix
, eMC_Nominal
, ch
, 1, node_name
.str()+"Nominal"));
295 // add hardware information controls
296 m_HwInfoContainer
= new Control::Container(this, "HwInfo");
297 result
&= m_HwInfoContainer
->addElement(
298 new HwInfoControl(*this, HwInfoControl::eHIF_PhysicalAudioOutCount
, "PhysicalAudioOutCount"));
299 result
&= m_HwInfoContainer
->addElement(
300 new HwInfoControl(*this, HwInfoControl::eHIF_PhysicalAudioInCount
, "PhysicalAudioInCount"));
301 result
&= m_HwInfoContainer
->addElement(
302 new HwInfoControl(*this, HwInfoControl::eHIF_1394PlaybackCount
, "1394PlaybackCount"));
303 result
&= m_HwInfoContainer
->addElement(
304 new HwInfoControl(*this, HwInfoControl::eHIF_1394RecordCount
, "1394RecordCount"));
305 result
&= m_HwInfoContainer
->addElement(
306 new HwInfoControl(*this, HwInfoControl::eHIF_GroupOutCount
, "GroupOutCount"));
307 result
&= m_HwInfoContainer
->addElement(
308 new HwInfoControl(*this, HwInfoControl::eHIF_GroupInCount
, "GroupInCount"));
309 result
&= m_HwInfoContainer
->addElement(
310 new HwInfoControl(*this, HwInfoControl::eHIF_PhantomPower
, "PhantomPower"));
311 result
&= m_HwInfoContainer
->addElement(
312 new HwInfoControl(*this, HwInfoControl::eHIF_OpticalInterface
, "OpticalInterface"));
313 result
&= m_HwInfoContainer
->addElement(
314 new HwInfoControl(*this, HwInfoControl::eHIF_PlaybackRouting
, "PlaybackRouting"));
316 // add a save settings control
317 result
&= this->addElement(
318 new MultiControl(*this, MultiControl::eT_SaveSession
, "SaveSettings"));
320 // add an identify control
321 result
&= this->addElement(
322 new MultiControl(*this, MultiControl::eT_Identify
, "Identify"));
324 // spdif mode control
325 result
&= this->addElement(
326 new SpdifModeControl(*this, "SpdifMode"));
328 // check for IO config controls and add them if necessary
329 if(m_HwInfo
.hasMirroring()) {
330 result
&= this->addElement(
331 new IOConfigControl(*this, eCR_Mirror
, "ChannelMirror"));
333 if(m_HwInfo
.hasOpticalInterface()) {
334 result
&= this->addElement(
335 new IOConfigControl(*this, eCR_DigitalInterface
, "DigitalInterface"));
337 if(m_HwInfo
.hasSoftwarePhantom()) {
338 result
&= this->addElement(
339 new IOConfigControl(*this, eCR_Phantom
, "PhantomPower"));
341 if(m_HwInfo
.hasPlaybackRouting()) {
342 result
&= this->addElement(
343 new PlaybackRoutingControl(*this, "PlaybackRouting"));
347 debugWarning("One or more control elements could not be created.");
348 // clean up those that couldn't be created
353 if (!addElement(m_MixerContainer
)) {
354 debugWarning("Could not register mixer to device\n");
360 if (!addElement(m_HwInfoContainer
)) {
361 debugWarning("Could not register hwinfo to device\n");
367 // load the session block
368 if (!loadSession()) {
369 debugWarning("Could not load session\n");
376 Device::destroyMixer()
378 debugOutput(DEBUG_LEVEL_VERBOSE
, "destroy mixer...\n");
380 if (m_MixerContainer
== NULL
) {
381 debugOutput(DEBUG_LEVEL_VERBOSE
, "no mixer to destroy...\n");
383 if (!deleteElement(m_MixerContainer
)) {
384 debugError("Mixer present but not registered to the avdevice\n");
388 // remove and delete (as in free) child control elements
389 m_MixerContainer
->clearElements(true);
390 delete m_MixerContainer
;
391 m_MixerContainer
= NULL
;
394 if (m_HwInfoContainer
== NULL
) {
395 debugOutput(DEBUG_LEVEL_VERBOSE
, "no hwinfo to destroy...\n");
397 if (!deleteElement(m_HwInfoContainer
)) {
398 debugError("HwInfo present but not registered to the avdevice\n");
402 // remove and delete (as in free) child control elements
403 m_HwInfoContainer
->clearElements(true);
404 delete m_HwInfoContainer
;
405 m_HwInfoContainer
= NULL
;
411 Device::saveSession()
413 // save the session block
414 // if ( !updateSession() ) {
415 // debugError( "Could not update session\n" );
417 if ( !m_session
.saveToDevice(*this) ) {
418 debugError( "Could not save session block\n" );
426 Device::loadSession()
428 if ( !m_session
.loadFromDevice(*this) ) {
429 debugError( "Could not load session block\n" );
437 * Firmware version 5.0 or later for AudioFire12 returns invalid values to
438 * contents of response against this command.
441 Device::updatePolledValues() {
442 Util::MutexLockHelper
lock(*m_poll_lock
);
443 return doEfcOverAVC(m_Polled
);
446 #define ECHO_CHECK_AND_ADD_SR(v, x) \
447 { if(x >= m_HwInfo.m_min_sample_rate && x <= m_HwInfo.m_max_sample_rate) \
450 Device::getSupportedSamplingFrequencies()
452 std::vector
<int> frequencies
;
453 ECHO_CHECK_AND_ADD_SR(frequencies
, 22050);
454 ECHO_CHECK_AND_ADD_SR(frequencies
, 24000);
455 ECHO_CHECK_AND_ADD_SR(frequencies
, 32000);
456 ECHO_CHECK_AND_ADD_SR(frequencies
, 44100);
457 ECHO_CHECK_AND_ADD_SR(frequencies
, 48000);
458 ECHO_CHECK_AND_ADD_SR(frequencies
, 88200);
459 ECHO_CHECK_AND_ADD_SR(frequencies
, 96000);
460 ECHO_CHECK_AND_ADD_SR(frequencies
, 176400);
461 ECHO_CHECK_AND_ADD_SR(frequencies
, 192000);
465 FFADODevice::ClockSourceVector
466 Device::getSupportedClockSources() {
467 FFADODevice::ClockSourceVector r
;
469 if (!m_efc_discovery_done
) {
470 debugError("EFC discovery not done yet!\n");
474 uint32_t active_clock
= getClockSrc();
476 if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo
.m_supported_clocks
, EFC_CMD_HW_CLOCK_INTERNAL
)) {
477 debugOutput(DEBUG_LEVEL_VERBOSE
, "Internal clock supported\n");
478 ClockSource s
=clockIdToClockSource(EFC_CMD_HW_CLOCK_INTERNAL
);
479 s
.active
=(active_clock
== EFC_CMD_HW_CLOCK_INTERNAL
);
480 if (s
.type
!= eCT_Invalid
) r
.push_back(s
);
482 if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo
.m_supported_clocks
, EFC_CMD_HW_CLOCK_SYTMATCH
)) {
483 debugOutput(DEBUG_LEVEL_VERBOSE
, "Syt Match clock supported\n");
484 ClockSource s
=clockIdToClockSource(EFC_CMD_HW_CLOCK_SYTMATCH
);
485 s
.active
=(active_clock
== EFC_CMD_HW_CLOCK_SYTMATCH
);
486 if (s
.type
!= eCT_Invalid
) r
.push_back(s
);
488 if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo
.m_supported_clocks
, EFC_CMD_HW_CLOCK_WORDCLOCK
)) {
489 debugOutput(DEBUG_LEVEL_VERBOSE
, "WordClock supported\n");
490 ClockSource s
=clockIdToClockSource(EFC_CMD_HW_CLOCK_WORDCLOCK
);
491 s
.active
=(active_clock
== EFC_CMD_HW_CLOCK_WORDCLOCK
);
492 if (s
.type
!= eCT_Invalid
) r
.push_back(s
);
494 if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo
.m_supported_clocks
, EFC_CMD_HW_CLOCK_SPDIF
)) {
495 debugOutput(DEBUG_LEVEL_VERBOSE
, "SPDIF clock supported\n");
496 ClockSource s
=clockIdToClockSource(EFC_CMD_HW_CLOCK_SPDIF
);
497 s
.active
=(active_clock
== EFC_CMD_HW_CLOCK_SPDIF
);
498 if (s
.type
!= eCT_Invalid
) r
.push_back(s
);
500 if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo
.m_supported_clocks
, EFC_CMD_HW_CLOCK_ADAT_1
)) {
501 debugOutput(DEBUG_LEVEL_VERBOSE
, "ADAT 1 clock supported\n");
502 ClockSource s
=clockIdToClockSource(EFC_CMD_HW_CLOCK_ADAT_1
);
503 s
.active
=(active_clock
== EFC_CMD_HW_CLOCK_ADAT_1
);
504 if (s
.type
!= eCT_Invalid
) r
.push_back(s
);
506 if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo
.m_supported_clocks
, EFC_CMD_HW_CLOCK_ADAT_2
)) {
507 debugOutput(DEBUG_LEVEL_VERBOSE
, "ADAT 2 clock supported\n");
508 ClockSource s
=clockIdToClockSource(EFC_CMD_HW_CLOCK_ADAT_2
);
509 s
.active
=(active_clock
== EFC_CMD_HW_CLOCK_ADAT_2
);
510 if (s
.type
!= eCT_Invalid
) r
.push_back(s
);
516 Device::isClockValid(uint32_t id
) {
518 if (id
==EFC_CMD_HW_CLOCK_INTERNAL
)
521 // the polled values tell whether each clock source is detected or not
522 if (!updatePolledValues()) {
523 debugError("Could not update polled values\n");
526 return EFC_CMD_HW_CHECK_FLAG(m_Polled
.m_status
,id
);
530 Device::setActiveClockSource(ClockSource s
) {
533 debugOutput(DEBUG_LEVEL_VERBOSE
, "setting clock source to id: %d\n",s
.id
);
535 if(!isClockValid(s
.id
)) {
536 debugError("Clock not valid\n");
540 result
= setClockSrc(s
.id
);
542 // From the ECHO sources:
543 // "If this is a 1200F and the sample rate is being set via EFC, then
544 // send the "phy reconnect command" so the device will vanish and reappear
545 // with a new descriptor."
547 // EfcPhyReconnectCmd rccmd;
548 // if(!doEfcOverAVC(rccmd)) {
549 // debugError("Phy reconnect failed\n");
551 // // sleep for one second such that the phy can get reconnected
558 FFADODevice::ClockSource
559 Device::getActiveClockSource() {
561 uint32_t active_clock
= getClockSrc();
562 s
=clockIdToClockSource(active_clock
);
567 FFADODevice::ClockSource
568 Device::clockIdToClockSource(uint32_t clockid
) {
570 debugOutput(DEBUG_LEVEL_VERBOSE
, "clock id: %u\n", clockid
);
573 case EFC_CMD_HW_CLOCK_INTERNAL
:
574 debugOutput(DEBUG_LEVEL_VERBOSE
, "Internal clock\n");
576 s
.description
="Internal sync";
579 case EFC_CMD_HW_CLOCK_SYTMATCH
:
580 debugOutput(DEBUG_LEVEL_VERBOSE
, "Syt Match\n");
582 s
.description
="SYT Match";
585 case EFC_CMD_HW_CLOCK_WORDCLOCK
:
586 debugOutput(DEBUG_LEVEL_VERBOSE
, "WordClock\n");
587 s
.type
=eCT_WordClock
;
588 s
.description
="Word Clock";
591 case EFC_CMD_HW_CLOCK_SPDIF
:
592 debugOutput(DEBUG_LEVEL_VERBOSE
, "SPDIF clock\n");
594 s
.description
="SPDIF";
597 case EFC_CMD_HW_CLOCK_ADAT_1
:
598 debugOutput(DEBUG_LEVEL_VERBOSE
, "ADAT 1 clock\n");
600 s
.description
="ADAT 1";
603 case EFC_CMD_HW_CLOCK_ADAT_2
:
604 debugOutput(DEBUG_LEVEL_VERBOSE
, "ADAT 2 clock\n");
606 s
.description
="ADAT 2";
610 debugError("Invalid clock id: %d\n",clockid
);
611 return s
; // return an invalid ClockSource
615 s
.valid
=isClockValid(clockid
);
620 bool Device::getClock(EfcGetClockCmd
&gccmd
)
622 if (!doEfcOverAVC(gccmd
))
627 * Firmware version 5.0 or later for AudioFire12 returns invalid
628 * values in contents of response against this command.
630 if (gccmd
.m_samplerate
> 192000) {
631 debugOutput(DEBUG_LEVEL_NORMAL
,
632 "Could not get sampling rate. Do fallback\n");
635 /* fallback to 'input/output plug signal format' command */
636 sampling_rate
= GenericAVC::Device::getSamplingFrequency();
637 /* fallback failed */
638 if (!sampling_rate
) {
639 debugOutput(DEBUG_LEVEL_NORMAL
, "Fallback failed\n");
643 gccmd
.m_samplerate
= sampling_rate
;
646 if (gccmd
.m_clock
> EFC_CMD_HW_CLOCK_COUNT
) {
647 debugOutput(DEBUG_LEVEL_NORMAL
,
648 "Could not get clock info. Do fallback\n");
649 if (m_current_clock
< 0) {
650 /* fallback to internal clock source */
651 EfcSetClockCmd sccmd
;
652 sccmd
.m_clock
= EFC_CMD_HW_CLOCK_INTERNAL
;
653 sccmd
.m_samplerate
= gccmd
.m_samplerate
;
656 if (!doEfcOverAVC(sccmd
)) {
657 debugOutput(DEBUG_LEVEL_NORMAL
, "Fallback failed\n");
661 /* Cache clock source */
662 m_current_clock
= sccmd
.m_clock
;
665 /* Fallback to cache */
666 gccmd
.m_clock
= m_current_clock
;
671 uint32_t Device::getClockSrc()
673 EfcGetClockCmd gccmd
;
674 if (!getClock(gccmd
))
675 return EFC_CMD_HW_CLOCK_UNSPECIFIED
;
677 debugOutput(DEBUG_LEVEL_VERBOSE
, "Get current clock source: %d\n",
680 return gccmd
.m_clock
;
682 int Device::getSamplingFrequency()
684 EfcGetClockCmd gccmd
;
685 if (!getClock(gccmd
))
688 debugOutput(DEBUG_LEVEL_VERBOSE
, "Get current sample rate: %d\n",
691 return gccmd
.m_samplerate
;
694 bool Device::setClock(EfcSetClockCmd sccmd
)
696 if (!doEfcOverAVC(sccmd
)) {
697 debugError("Could not set clock info\n");
701 /* Cache clock source for fallback. */
702 m_current_clock
= sccmd
.m_clock
;
706 bool Device::setClockSrc(uint32_t id
)
710 EfcGetClockCmd gccmd
;
711 err
= getClock(gccmd
);
715 EfcSetClockCmd sccmd
;
717 sccmd
.m_samplerate
= gccmd
.m_samplerate
;
720 err
= setClock(sccmd
);
722 debugOutput(DEBUG_LEVEL_VERBOSE
, "Set current clock source: %d\n",
727 bool Device::setSamplingFrequency(int samplerate
)
731 EfcGetClockCmd gccmd
;
732 err
= getClock(gccmd
);
736 EfcSetClockCmd sccmd
;
737 sccmd
.m_clock
= gccmd
.m_clock
;
738 sccmd
.m_samplerate
= samplerate
;
741 err
= setClock(sccmd
);
743 debugOutput(DEBUG_LEVEL_VERBOSE
, "Set current sample rate: %d\n",
750 Device::lockFlash(bool lock
) {
751 // some hardware doesn't need/support flash lock
752 if (m_HwInfo
.hasDSP()) {
753 debugOutput(DEBUG_LEVEL_VERBOSE
, "flash lock not needed\n");
760 if(!doEfcOverAVC(cmd
)) {
761 debugError("Flash lock failed\n");
768 Device::writeFlash(uint32_t start
, uint32_t len
, uint32_t* buffer
) {
770 if(len
<= 0 || 0xFFFFFFFF - len
*4 < start
) {
771 debugError("bogus start/len: 0x%08X / %u\n", start
, len
);
775 debugError("start address not quadlet aligned: 0x%08X\n", start
);
779 uint32_t start_addr
= start
;
780 uint32_t stop_addr
= start
+ len
*4;
781 uint32_t *target_buffer
= buffer
;
783 EfcFlashWriteCmd cmd
;
784 // write EFC_FLASH_SIZE_BYTES at a time
785 for(start_addr
= start
; start_addr
< stop_addr
; start_addr
+= EFC_FLASH_SIZE_BYTES
) {
786 cmd
.m_address
= start_addr
;
787 unsigned int quads_to_write
= (stop_addr
- start_addr
)/4;
788 if (quads_to_write
> EFC_FLASH_SIZE_QUADS
) {
789 quads_to_write
= EFC_FLASH_SIZE_QUADS
;
791 cmd
.m_nb_quadlets
= quads_to_write
;
792 for(unsigned int i
=0; i
<quads_to_write
; i
++) {
793 cmd
.m_data
[i
] = *target_buffer
;
796 if(!doEfcOverAVC(cmd
)) {
797 debugError("Flash write failed for block 0x%08X (%d quadlets)\n", start_addr
, quads_to_write
);
805 Device::readFlash(uint32_t start
, uint32_t len
, uint32_t* buffer
) {
807 if(len
<= 0 || 0xFFFFFFFF - len
*4 < start
) {
808 debugError("bogus start/len: 0x%08X / %u\n", start
, len
);
812 debugError("start address not quadlet aligned: 0x%08X\n", start
);
816 uint32_t start_addr
= start
;
817 uint32_t stop_addr
= start
+ len
*4;
818 uint32_t *target_buffer
= buffer
;
821 // read EFC_FLASH_SIZE_BYTES at a time
822 for(start_addr
= start
; start_addr
< stop_addr
; start_addr
+= EFC_FLASH_SIZE_BYTES
) {
823 unsigned int quads_to_read
= (stop_addr
- start_addr
)/4;
824 if (quads_to_read
> EFC_FLASH_SIZE_QUADS
) {
825 quads_to_read
= EFC_FLASH_SIZE_QUADS
;
827 uint32_t quadlets_read
= 0;
830 cmd
.m_address
= start_addr
+ quadlets_read
*4;
831 unsigned int new_to_read
= quads_to_read
- quadlets_read
;
832 cmd
.m_nb_quadlets
= new_to_read
;
833 if(!doEfcOverAVC(cmd
)) {
834 debugError("Flash read failed for block 0x%08X (%d quadlets)\n", start_addr
, quads_to_read
);
837 if(cmd
.m_nb_quadlets
!= new_to_read
) {
838 debugOutput(DEBUG_LEVEL_VERBOSE
,
839 "Flash read didn't return enough data (%u/%u) \n",
840 cmd
.m_nb_quadlets
, new_to_read
);
843 quadlets_read
+= cmd
.m_nb_quadlets
;
846 for(unsigned int i
=0; i
<cmd
.m_nb_quadlets
; i
++) {
847 *target_buffer
= cmd
.m_data
[i
];
850 } while(quadlets_read
< quads_to_read
&& ntries
--);
852 debugError("deadlock while reading flash\n");
860 Device::eraseFlash(uint32_t addr
) {
862 debugError("start address not quadlet aligned: 0x%08X\n", addr
);
865 EfcFlashEraseCmd cmd
;
866 cmd
.m_address
= addr
;
867 if(!doEfcOverAVC(cmd
)) {
868 if (cmd
.m_header
.retval
== EfcCmd::eERV_FlashBusy
) {
871 debugError("Flash erase failed for block 0x%08X\n", addr
);
878 Device::eraseFlashBlocks(uint32_t start_address
, unsigned int nb_quads
)
880 uint32_t blocksize_bytes
;
881 uint32_t blocksize_quads
;
882 unsigned int quads_left
= nb_quads
;
885 const unsigned int max_nb_tries
= 10;
886 unsigned int nb_tries
= 0;
889 // the erase block size is fixed by the HW, and depends
890 // on the flash section we're in
891 if (start_address
< MAINBLOCKS_BASE_OFFSET_BYTES
)
892 blocksize_bytes
= PROGRAMBLOCK_SIZE_BYTES
;
894 blocksize_bytes
= MAINBLOCK_SIZE_BYTES
;
895 start_address
&= ~(blocksize_bytes
- 1);
896 blocksize_quads
= blocksize_bytes
/ 4;
898 uint32_t verify
[blocksize_quads
];
900 // corner case: requested to erase less than one block
901 if (blocksize_quads
> quads_left
) {
902 blocksize_quads
= quads_left
;
905 // do the actual erase
906 if (!eraseFlash(start_address
)) {
907 debugWarning("Could not erase flash block at 0x%08X\n", start_address
);
910 // wait for the flash to become ready again
911 if (!waitForFlash(ECHO_FLASH_ERASE_TIMEOUT_MILLISECS
)) {
912 debugError("Wait for flash timed out at address 0x%08X\n", start_address
);
916 // verify that the block is empty as an extra precaution
917 if (!readFlash(start_address
, blocksize_quads
, verify
)) {
918 debugError("Could not read flash block at 0x%08X\n", start_address
);
922 // everything should be 0xFFFFFFFF if the erase was successful
923 for (unsigned int i
= 0; i
< blocksize_quads
; i
++) {
924 if (0xFFFFFFFF != verify
[i
]) {
925 debugWarning("Flash erase verification failed.\n");
933 start_address
+= blocksize_bytes
;
934 quads_left
-= blocksize_quads
;
939 if (nb_tries
> max_nb_tries
) {
940 debugError("Needed too many tries to erase flash at 0x%08X\n", start_address
);
943 } while (quads_left
> 0);
949 Device::waitForFlash(unsigned int msecs
)
953 EfcFlashGetStatusCmd statusCmd
;
954 const unsigned int time_to_sleep_usecs
= 10000;
955 int wait_cycles
= msecs
* 1000 / time_to_sleep_usecs
;
958 if (!doEfcOverAVC(statusCmd
)) {
959 debugError("Could not read flash status\n");
962 if (statusCmd
.m_header
.retval
== EfcCmd::eERV_FlashBusy
) {
965 ready
= statusCmd
.m_ready
;
967 usleep(time_to_sleep_usecs
);
968 } while (!ready
&& wait_cycles
--);
970 if(wait_cycles
== 0) {
971 debugError("Timeout while waiting for flash\n");
979 Device::getSessionBase()
981 EfcFlashGetSessionBaseCmd cmd
;
982 if(!doEfcOverAVC(cmd
)) {
983 debugError("Could not get session base address\n");
984 return 0; // FIXME: arbitrary
986 return cmd
.m_address
;