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_cmd.h"
29 #include "efc/efc_cmds_hardware.h"
30 #include "efc/efc_cmds_hardware_ctrl.h"
31 #include "efc/efc_cmds_flash.h"
33 #include "audiofire/audiofire_device.h"
35 #include "libieee1394/configrom.h"
36 #include "libieee1394/ieee1394service.h"
38 #include "fireworks/fireworks_control.h"
40 #include "libutil/PosixMutex.h"
41 #include "libutil/SystemTimeSource.h"
43 #include "IntelFlashMap.h"
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
54 // FireWorks is the platform used and developed by ECHO AUDIO
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
)
64 debugOutput( DEBUG_LEVEL_VERBOSE
, "Created FireWorks::Device (NodeID %d)\n",
65 getConfigRom().getNodeId() );
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");
82 m_HwInfo
.showEfcCmd();
83 GenericAVC::Device::showDevice();
87 Device::probe( Util::Configuration
& c
, ConfigRom
& configRom
, bool generic
)
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() );
98 EfcHardwareInfoCmd hwInfo
;
99 hwInfo
.setVerboseLevel(configRom
.getVerboseLevel());
106 if ( cmd
.getResponse() != AVC::AVCCommand::eR_Accepted
) {
109 if ( hwInfo
.m_header
.retval
!= EfcCmd::eERV_Ok
110 && hwInfo
.m_header
.retval
!= EfcCmd::eERV_FlashBusy
) {
111 debugError( "EFC command failed\n" );
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
;
126 unsigned int vendorId
= getConfigRom().getNodeVendorId();
127 unsigned int modelId
= getConfigRom().getModelId();
129 Util::Configuration
&c
= getDeviceManager().getConfiguration();
130 Util::Configuration::VendorModelEntry vme
= c
.findDeviceVME( vendorId
, modelId
);
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());
137 debugWarning("Using generic ECHO Audio FireWorks support for unsupported device '%s %s'\n",
138 getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str());
141 // get the info from the EFC
142 if ( !discoverUsingEFC() ) {
147 if ( !GenericAVC::Device::discoverGeneric() ) {
148 debugError( "Could not discover GenericAVC::Device\n" );
153 debugWarning("Could not build mixer\n");
160 Device::discoverUsingEFC()
162 m_efc_discovery_done
= false;
163 m_HwInfo
.setVerboseLevel(getDebugLevel());
165 if (!doEfcOverAVC(m_HwInfo
)) {
166 debugError("Could not read hardware capabilities\n");
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
183 // save the EFC version, since some stuff
185 m_efc_version
= m_HwInfo
.m_header
.version
;
187 if (!updatePolledValues()) {
188 debugError("Could not update polled values\n");
192 m_current_clock
= -1;
194 m_efc_discovery_done
= true;
199 Device::createDevice(DeviceManager
& d
, std::auto_ptr
<ConfigRom
>( configRom
))
201 unsigned int vendorId
= configRom
->getNodeVendorId();
202 // unsigned int modelId = configRom->getModelId();
205 case FW_VENDORID_ECHO
: return new ECHO::AudioFire(d
, configRom
);
206 default: return new Device(d
, configRom
);
210 bool Device::doEfcOverAVC(EfcCmd
&c
)
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 );
220 cmd
.setVerbose( getDebugLevel() );
223 for (trial
= 0; trial
< AVC_MAX_TRIAL
; trial
++) {
226 Util::SystemTimeSource::SleepUsecRelative(AVC_RETRY_INTERVAL
);
229 if (trial
== AVC_MAX_TRIAL
) {
230 debugError( "EfcOverAVCCmd command failed\n" );
235 if ( cmd
.getResponse() != AVC::AVCCommand::eR_Accepted
) {
236 debugError( "EfcOverAVCCmd not accepted\n" );
240 if ( c
.m_header
.retval
!= EfcCmd::eERV_Ok
241 && c
.m_header
.retval
!= EfcCmd::eERV_FlashBusy
) {
242 debugError( "EFC command failed\n" );
254 debugOutput(DEBUG_LEVEL_VERBOSE
, "Building a FireWorks mixer...\n");
258 // create the mixer object container
259 m_MixerContainer
= new Control::Container(this, "Mixer");
261 if (!m_MixerContainer
) {
262 debugError("Could not create mixer container...\n");
266 // create control objects for the audiofire
268 // matrix mix controls
269 result
&= m_MixerContainer
->addElement(
270 new MonitorControl(*this, MonitorControl::eMC_Gain
, "MonitorGain"));
272 result
&= m_MixerContainer
->addElement(
273 new MonitorControl(*this, MonitorControl::eMC_Mute
, "MonitorMute"));
275 result
&= m_MixerContainer
->addElement(
276 new MonitorControl(*this, MonitorControl::eMC_Solo
, "MonitorSolo"));
278 result
&= m_MixerContainer
->addElement(
279 new MonitorControl(*this, MonitorControl::eMC_Pan
, "MonitorPan"));
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
;
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"));
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
;
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"));
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
;
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"));
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"));
339 // add a save settings control
340 result
&= this->addElement(
341 new MultiControl(*this, MultiControl::eT_SaveSession
, "SaveSettings"));
343 // add an identify control
344 result
&= this->addElement(
345 new MultiControl(*this, MultiControl::eT_Identify
, "Identify"));
347 // spdif mode control
348 result
&= this->addElement(
349 new SpdifModeControl(*this, "SpdifMode"));
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"));
356 if(m_HwInfo
.hasOpticalInterface()) {
357 result
&= this->addElement(
358 new IOConfigControl(*this, eCR_DigitalInterface
, "DigitalInterface"));
360 if(m_HwInfo
.hasSoftwarePhantom()) {
361 result
&= this->addElement(
362 new IOConfigControl(*this, eCR_Phantom
, "PhantomPower"));
364 if(m_HwInfo
.hasPlaybackRouting()) {
365 result
&= this->addElement(
366 new PlaybackRoutingControl(*this, "PlaybackRouting"));
370 debugWarning("One or more control elements could not be created.");
371 // clean up those that couldn't be created
376 if (!addElement(m_MixerContainer
)) {
377 debugWarning("Could not register mixer to device\n");
383 if (!addElement(m_HwInfoContainer
)) {
384 debugWarning("Could not register hwinfo to device\n");
390 // load the session block
391 if (!loadSession()) {
392 debugWarning("Could not load session\n");
399 Device::destroyMixer()
401 debugOutput(DEBUG_LEVEL_VERBOSE
, "destroy mixer...\n");
403 if (m_MixerContainer
== NULL
) {
404 debugOutput(DEBUG_LEVEL_VERBOSE
, "no mixer to destroy...\n");
406 if (!deleteElement(m_MixerContainer
)) {
407 debugError("Mixer present but not registered to the avdevice\n");
411 // remove and delete (as in free) child control elements
412 m_MixerContainer
->clearElements(true);
413 delete m_MixerContainer
;
414 m_MixerContainer
= NULL
;
417 if (m_HwInfoContainer
== NULL
) {
418 debugOutput(DEBUG_LEVEL_VERBOSE
, "no hwinfo to destroy...\n");
420 if (!deleteElement(m_HwInfoContainer
)) {
421 debugError("HwInfo present but not registered to the avdevice\n");
425 // remove and delete (as in free) child control elements
426 m_HwInfoContainer
->clearElements(true);
427 delete m_HwInfoContainer
;
428 m_HwInfoContainer
= NULL
;
434 Device::saveSession()
436 // save the session block
437 // if ( !updateSession() ) {
438 // debugError( "Could not update session\n" );
440 if ( !m_session
.saveToDevice(*this) ) {
441 debugError( "Could not save session block\n" );
449 Device::loadSession()
451 if ( !m_session
.loadFromDevice(*this) ) {
452 debugError( "Could not load session block\n" );
459 Device::updatePolledValues() {
460 Util::MutexLockHelper
lock(*m_poll_lock
);
461 return doEfcOverAVC(m_Polled
);
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) \
468 Device::getSupportedSamplingFrequencies()
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);
483 FFADODevice::ClockSourceVector
484 Device::getSupportedClockSources() {
485 FFADODevice::ClockSourceVector r
;
487 if (!m_efc_discovery_done
) {
488 debugError("EFC discovery not done yet!\n");
492 uint32_t active_clock
=getClock();
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
);
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
);
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
);
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
);
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
);
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
);
534 Device::isClockValid(uint32_t id
) {
536 if (id
==EFC_CMD_HW_CLOCK_INTERNAL
) return true;
538 // the polled values are used to detect
539 // whether clocks are valid
540 if (!updatePolledValues()) {
541 debugError("Could not update polled values\n");
544 return EFC_CMD_HW_CHECK_FLAG(m_Polled
.m_status
,id
);
548 Device::setActiveClockSource(ClockSource s
) {
551 debugOutput(DEBUG_LEVEL_VERBOSE
, "setting clock source to id: %d\n",s
.id
);
553 if(!isClockValid(s
.id
)) {
554 debugError("Clock not valid\n");
558 result
= setClock(s
.id
);
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."
565 // EfcPhyReconnectCmd rccmd;
566 // if(!doEfcOverAVC(rccmd)) {
567 // debugError("Phy reconnect failed\n");
569 // // sleep for one second such that the phy can get reconnected
576 FFADODevice::ClockSource
577 Device::getActiveClockSource() {
579 uint32_t active_clock
=getClock();
580 s
=clockIdToClockSource(active_clock
);
585 FFADODevice::ClockSource
586 Device::clockIdToClockSource(uint32_t clockid
) {
588 debugOutput(DEBUG_LEVEL_VERBOSE
, "clock id: %u\n", clockid
);
590 // the polled values are used to detect
591 // whether clocks are valid
592 if (!updatePolledValues()) {
593 debugError("Could not update polled values\n");
598 case EFC_CMD_HW_CLOCK_INTERNAL
:
599 debugOutput(DEBUG_LEVEL_VERBOSE
, "Internal clock\n");
601 s
.description
="Internal sync";
604 case EFC_CMD_HW_CLOCK_SYTMATCH
:
605 debugOutput(DEBUG_LEVEL_VERBOSE
, "Syt Match\n");
607 s
.description
="SYT Match";
610 case EFC_CMD_HW_CLOCK_WORDCLOCK
:
611 debugOutput(DEBUG_LEVEL_VERBOSE
, "WordClock\n");
612 s
.type
=eCT_WordClock
;
613 s
.description
="Word Clock";
616 case EFC_CMD_HW_CLOCK_SPDIF
:
617 debugOutput(DEBUG_LEVEL_VERBOSE
, "SPDIF clock\n");
619 s
.description
="SPDIF";
622 case EFC_CMD_HW_CLOCK_ADAT_1
:
623 debugOutput(DEBUG_LEVEL_VERBOSE
, "ADAT 1 clock\n");
625 s
.description
="ADAT 1";
628 case EFC_CMD_HW_CLOCK_ADAT_2
:
629 debugOutput(DEBUG_LEVEL_VERBOSE
, "ADAT 2 clock\n");
631 s
.description
="ADAT 2";
635 debugError("Invalid clock id: %d\n",clockid
);
636 return s
; // return an invalid ClockSource
640 s
.valid
=isClockValid(clockid
);
645 uint32_t Device::getClock()
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
;
660 clock
= EFC_CMD_HW_CLOCK_UNSPECIFIED
;
662 clock
= gccmd
.m_clock
;
664 debugOutput(DEBUG_LEVEL_VERBOSE
, "Active clock: 0x%08X\n", clock
);
670 bool Device::setClock(uint32_t id
)
672 int sampling_rate
= getSamplingFrequency();
676 debugOutput(DEBUG_LEVEL_VERBOSE
, "Set clock: 0x%08X\n", id
);
678 EfcSetClockCmd sccmd
;
680 sccmd
.m_samplerate
= sampling_rate
;
682 if (!doEfcOverAVC(sccmd
)) {
683 debugError("Could not set clock info\n");
687 m_current_clock
= id
;
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");
702 if(!doEfcOverAVC(cmd
)) {
703 debugError("Flash lock failed\n");
710 Device::writeFlash(uint32_t start
, uint32_t len
, uint32_t* buffer
) {
712 if(len
<= 0 || 0xFFFFFFFF - len
*4 < start
) {
713 debugError("bogus start/len: 0x%08X / %u\n", start
, len
);
717 debugError("start address not quadlet aligned: 0x%08X\n", start
);
721 uint32_t start_addr
= start
;
722 uint32_t stop_addr
= start
+ len
*4;
723 uint32_t *target_buffer
= buffer
;
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
;
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
;
738 if(!doEfcOverAVC(cmd
)) {
739 debugError("Flash write failed for block 0x%08X (%d quadlets)\n", start_addr
, quads_to_write
);
747 Device::readFlash(uint32_t start
, uint32_t len
, uint32_t* buffer
) {
749 if(len
<= 0 || 0xFFFFFFFF - len
*4 < start
) {
750 debugError("bogus start/len: 0x%08X / %u\n", start
, len
);
754 debugError("start address not quadlet aligned: 0x%08X\n", start
);
758 uint32_t start_addr
= start
;
759 uint32_t stop_addr
= start
+ len
*4;
760 uint32_t *target_buffer
= buffer
;
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
;
769 uint32_t quadlets_read
= 0;
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
);
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
);
785 quadlets_read
+= cmd
.m_nb_quadlets
;
788 for(unsigned int i
=0; i
<cmd
.m_nb_quadlets
; i
++) {
789 *target_buffer
= cmd
.m_data
[i
];
792 } while(quadlets_read
< quads_to_read
&& ntries
--);
794 debugError("deadlock while reading flash\n");
802 Device::eraseFlash(uint32_t addr
) {
804 debugError("start address not quadlet aligned: 0x%08X\n", addr
);
807 EfcFlashEraseCmd cmd
;
808 cmd
.m_address
= addr
;
809 if(!doEfcOverAVC(cmd
)) {
810 if (cmd
.m_header
.retval
== EfcCmd::eERV_FlashBusy
) {
813 debugError("Flash erase failed for block 0x%08X\n", addr
);
820 Device::eraseFlashBlocks(uint32_t start_address
, unsigned int nb_quads
)
822 uint32_t blocksize_bytes
;
823 uint32_t blocksize_quads
;
824 unsigned int quads_left
= nb_quads
;
827 const unsigned int max_nb_tries
= 10;
828 unsigned int nb_tries
= 0;
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
;
836 blocksize_bytes
= MAINBLOCK_SIZE_BYTES
;
837 start_address
&= ~(blocksize_bytes
- 1);
838 blocksize_quads
= blocksize_bytes
/ 4;
840 uint32_t verify
[blocksize_quads
];
842 // corner case: requested to erase less than one block
843 if (blocksize_quads
> quads_left
) {
844 blocksize_quads
= quads_left
;
847 // do the actual erase
848 if (!eraseFlash(start_address
)) {
849 debugWarning("Could not erase flash block at 0x%08X\n", start_address
);
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
);
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
);
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");
875 start_address
+= blocksize_bytes
;
876 quads_left
-= blocksize_quads
;
881 if (nb_tries
> max_nb_tries
) {
882 debugError("Needed too many tries to erase flash at 0x%08X\n", start_address
);
885 } while (quads_left
> 0);
891 Device::waitForFlash(unsigned int msecs
)
895 EfcFlashGetStatusCmd statusCmd
;
896 const unsigned int time_to_sleep_usecs
= 10000;
897 int wait_cycles
= msecs
* 1000 / time_to_sleep_usecs
;
900 if (!doEfcOverAVC(statusCmd
)) {
901 debugError("Could not read flash status\n");
904 if (statusCmd
.m_header
.retval
== EfcCmd::eERV_FlashBusy
) {
907 ready
= statusCmd
.m_ready
;
909 usleep(time_to_sleep_usecs
);
910 } while (!ready
&& wait_cycles
--);
912 if(wait_cycles
== 0) {
913 debugError("Timeout while waiting for flash\n");
921 Device::getSessionBase()
923 EfcFlashGetSessionBaseCmd cmd
;
924 if(!doEfcOverAVC(cmd
)) {
925 debugError("Could not get session base address\n");
926 return 0; // FIXME: arbitrary
928 return cmd
.m_address
;
932 Device::getSamplingFrequency()
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");
944 return sampling_rate
;
946 return gccmd
.m_samplerate
;
949 Device::setSamplingFrequency(int s
)
951 uint32_t clock
= getClock();
952 if (clock
== EFC_CMD_HW_CLOCK_UNSPECIFIED
)
955 debugOutput(DEBUG_LEVEL_VERBOSE
, "Set samplerate: %d\n", s
);
957 EfcSetClockCmd sccmd
;
958 sccmd
.m_clock
= clock
;
959 sccmd
.m_samplerate
= s
;
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");