Adding a dummy Sound driver for BeagleBoard
authorarunabha
Tue, 02 Feb 2010 21:04:35 +0000
changeset 20 3999188eafd0
parent 16 ff677160c7d9
child 21 524118fd998f
Adding a dummy Sound driver for BeagleBoard
omap3530/beagle_drivers/soundsc/bld.inf
omap3530/beagle_drivers/soundsc/shared_sound.h
omap3530/beagle_drivers/soundsc/shared_txsound.cpp
omap3530/beagle_drivers/soundsc/soundsc.mmp
omap3530/beagle_drivers/soundsc/variant_sound.cpp
omap3530/beagle_drivers/soundsc/variant_sound.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omap3530/beagle_drivers/soundsc/bld.inf	Tue Feb 02 21:04:35 2010 +0000
@@ -0,0 +1,22 @@
+// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// omap3530/beagle_drivers/soundsc/bld.inf
+//
+
+PRJ_PLATFORMS
+ARMV5
+
+PRJ_MMPFILES
+soundsc
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omap3530/beagle_drivers/soundsc/shared_sound.h	Tue Feb 02 21:04:35 2010 +0000
@@ -0,0 +1,95 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef __BEAGLESHARED_SOUND_H__
+#define __BEAGLESHARED_SOUND_H__
+
+#include <soundsc.h>
+
+#ifdef _DEBUG
+#define BEAGLE_SOUND_DEBUG(x...) Kern::Printf(x)
+#else
+#define BEAGLE_SOUND_DEBUG(x...)
+#endif
+
+class DDriverBeagleSoundScPddFactory;
+
+class DDriverBeagleSoundScPdd : public DSoundScPdd
+	{
+public:
+
+	DDriverBeagleSoundScPdd();
+	~DDriverBeagleSoundScPdd();
+	TInt DoCreate();
+	void GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo);
+	void Caps(TDes8& aCapsBuf) const;
+	TInt MaxTransferLen() const;
+	TInt SetConfig(const TDesC8& aConfigBuf);
+	TInt SetVolume(TInt aVolume);
+	TInt StartTransfer();
+	TInt TransferData(TUint aTransferID, TLinAddr aLinAddr, TPhysAddr aPhysAddr, TInt aNumBytes);
+	void StopTransfer();
+	TInt PauseTransfer();
+	TInt ResumeTransfer();
+	TInt PowerUp();
+	void PowerDown();
+	TInt CustomConfig(TInt aFunction, TAny* aParam);
+	void Callback(TUint aTransferID, TInt aTransferResult, TInt aBytesTransferred);
+
+	void SetCaps();
+        // There was a change in the signature for DfcQ() which
+        // is a pure virtual method in the parent.
+        //  for Symbian^2
+        TDfcQue* DfcQ();
+        //  for Symbian^3
+	TDfcQue* DfcQ(TInt aUnit);
+	
+	TInt CalculateBufferTime(TInt aNumBytes);
+
+public:
+	
+	DDriverBeagleSoundScPddFactory*	iPhysicalDevice;
+	
+	class TTransferArrayInfo{
+
+public:
+	TUint 						iTransferID;
+	TLinAddr 					iLinAddr;
+	TInt 						iNumBytes;
+	TInt						iPlayTime;
+	};
+	
+	RArray<TTransferArrayInfo> iTransferArray;
+	
+	NTimer						iTimer;
+	
+	TInt						iUnitType; //Play or Record
+	
+private:
+
+	TSoundFormatsSupportedV02	iCaps;
+	
+	TCurrentSoundFormatV02		iConfig;
+	
+
+
+	};
+
+
+
+
+#endif 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omap3530/beagle_drivers/soundsc/shared_txsound.cpp	Tue Feb 02 21:04:35 2010 +0000
@@ -0,0 +1,316 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "shared_sound.h"
+#include "variant_sound.h"
+
+void TimerCallback(TAny* aData)
+	{
+	DDriverBeagleSoundScPdd * soundscpdd = (DDriverBeagleSoundScPdd*) aData;
+		
+	soundscpdd->Callback(soundscpdd->iTransferArray[0].iTransferID, KErrNone, soundscpdd->iTransferArray[0].iNumBytes);
+	
+	}
+
+
+DDriverBeagleSoundScPdd::DDriverBeagleSoundScPdd() : iTimer(TimerCallback,this)
+	{
+
+	}
+
+DDriverBeagleSoundScPdd::~DDriverBeagleSoundScPdd()
+	{
+	iTimer.Cancel();
+	}
+
+
+TInt DDriverBeagleSoundScPdd::DoCreate()
+	{
+
+	SetCaps();
+
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPdd::DoCreate TxPdd");
+	
+	return KErrNone;
+	}
+
+void DDriverBeagleSoundScPdd::GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo)
+	{
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPdd::GetChunkCreateInfo TxPdd");
+	
+	aChunkCreateInfo.iType = TChunkCreateInfo::ESharedKernelMultiple;
+	aChunkCreateInfo.iMapAttr = EMapAttrFullyBlocking; 	// No caching
+	aChunkCreateInfo.iOwnsMemory = ETrue; 				// Using RAM pages
+	aChunkCreateInfo.iDestroyedDfc = NULL; 				// No chunk destroy DFC
+	}
+
+void DDriverBeagleSoundScPdd::Caps(TDes8& aCapsBuf) const
+	{
+
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPdd::Caps TxPdd");
+	
+	// Fill the structure with zeros in case it is a newer version than we know about
+	aCapsBuf.FillZ(aCapsBuf.MaxLength());
+
+	// And copy the capabilities into the packaged structure
+	TPtrC8 ptr((const TUint8*) &iCaps, sizeof(iCaps));
+	aCapsBuf = ptr.Left(Min(ptr.Length(), aCapsBuf.MaxLength()));
+	}
+
+TInt DDriverBeagleSoundScPdd::SetConfig(const TDesC8& aConfigBuf)
+	{
+
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPdd::SetConfig TxPdd");
+	
+	// Read the new configuration from the LDD
+	TCurrentSoundFormatV02 config;
+	TPtr8 ptr((TUint8*) &config, sizeof(config));
+	Kern::InfoCopy(ptr, aConfigBuf);
+
+	iConfig = config;
+	
+	return KErrNone;
+	}
+
+
+TInt DDriverBeagleSoundScPdd::SetVolume(TInt aVolume)
+	{
+	
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPdd::Setvolume TxPdd");
+	
+	return KErrNone;
+	}
+
+
+TInt DDriverBeagleSoundScPdd::StartTransfer()
+	{
+	
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPdd::starttransfer TxPdd");
+	
+	//Prepare for transfer
+	return KErrNone;
+	
+	}
+
+TInt DDriverBeagleSoundScPdd::CalculateBufferTime(TInt aNumBytes)
+	{
+	
+	TUint samplerate=0;
+
+	// Let the compiler perform an integer division of rates
+	switch(iConfig.iRate)
+		{
+		case ESoundRate7350Hz: 	samplerate = 7350; break;
+		case ESoundRate8000Hz: 	samplerate = 8000; break;
+		case ESoundRate8820Hz: 	samplerate = 8820; break;
+		case ESoundRate9600Hz: 	samplerate = 9600; break;
+		case ESoundRate11025Hz: samplerate = 11025; break;
+		case ESoundRate12000Hz: samplerate = 12000; break;
+		case ESoundRate14700Hz:	samplerate = 14700; break;
+		case ESoundRate16000Hz: samplerate = 16000; break;
+		case ESoundRate22050Hz: samplerate = 22050; break;
+		case ESoundRate24000Hz: samplerate = 24000; break;
+		case ESoundRate29400Hz: samplerate = 29400; break;
+		case ESoundRate32000Hz: samplerate = 32000; break;
+		case ESoundRate44100Hz: samplerate = 44100; break;
+		case ESoundRate48000Hz: samplerate = 48000; break;
+		}
+
+
+	// integer division by number of channels
+	aNumBytes /= iConfig.iChannels;
+
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPdd::iChannels =%d", iConfig.iChannels);
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPdd::iEncoding =%d", iConfig.iEncoding);
+	
+	// integer division by bytes per sample
+	switch(iConfig.iEncoding)
+		{
+		case ESoundEncoding8BitPCM: break;
+		case ESoundEncoding16BitPCM: aNumBytes /= 2; break;
+		case ESoundEncoding24BitPCM: aNumBytes /= 3; break;
+		}
+
+	return (aNumBytes * 1000) / samplerate; //return time in milliseconds
+	
+
+	}
+
+TInt DDriverBeagleSoundScPdd::TransferData(TUint aTransferID, TLinAddr aLinAddr, TPhysAddr /*aPhysAddr*/, TInt aNumBytes)
+	{
+
+	//function wil get called multiple times while transfer is in progress therefore keep fifo queue of requests
+	TTransferArrayInfo transfer;	
+		
+	transfer.iTransferID = aTransferID;
+	transfer.iLinAddr = aLinAddr;
+	transfer.iNumBytes = aNumBytes;
+	
+	//calculate the amount of time required to play/record buffer
+	TInt buffer_play_time = CalculateBufferTime(aNumBytes);
+	TInt timerticks = NKern::TimerTicks(buffer_play_time);
+	transfer.iPlayTime = timerticks;
+	
+	iTransferArray.Append(transfer);
+	
+	//Timer will callback when correct time has elapsed, will return KErrInUse if transfer
+	//already active, this is ok becuase will be started again in callback
+	TInt err = iTimer.OneShot(timerticks, ETrue);
+	
+	
+	return KErrNone;
+	}
+
+void DDriverBeagleSoundScPdd::StopTransfer()
+	{
+	// Stop transfer
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPdd::stoptransfer TxPdd");
+	
+	//If timer is currently active then cancel it and call back buffer
+	if(iTimer.Cancel())
+		{
+		Callback(iTransferArray[0].iTransferID, KErrNone, iTransferArray[0].iNumBytes);
+		}
+		
+
+	}
+
+
+TInt DDriverBeagleSoundScPdd::PauseTransfer()
+	{
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPdd::pausetransfer TxPdd");
+	//Pause Transfer
+	
+	return KErrNone;
+	}
+
+
+TInt DDriverBeagleSoundScPdd::ResumeTransfer()
+	{
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPdd::resumetransfer TxPdd");
+	//Resume Transfer
+	
+	return KErrNone;
+	}
+
+TInt DDriverBeagleSoundScPdd::PowerUp()
+	{
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPdd::PowerUp TxPdd");
+	return KErrNone;
+	}
+
+void DDriverBeagleSoundScPdd::PowerDown()
+	{
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPdd::Powerdown TxPdd");
+	}
+
+TInt DDriverBeagleSoundScPdd::CustomConfig(TInt /*aFunction*/,TAny* /*aParam*/)
+	{
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPdd::customconfig TxPdd");
+	return KErrNotSupported;
+	}
+
+
+void DDriverBeagleSoundScPdd::Callback(TUint aTransferID, TInt aTransferResult, TInt aBytesTransferred)
+	{
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPdd::playcallback TxPdd");
+	//Callback when Transfer completes or is stopped
+	
+	iTransferArray.Remove(0);
+	
+	if(iUnitType == KSoundScTxUnit0)
+		{
+		Ldd()->PlayCallback(aTransferID, aTransferResult, aBytesTransferred);
+		}
+	else if(iUnitType == KSoundScRxUnit0)
+		{
+		Ldd()->RecordCallback(aTransferID, aTransferResult, aBytesTransferred);
+		}
+	
+	if(	iTransferArray.Count()>0)
+		{
+		iTimer.OneShot(iTransferArray[0].iPlayTime, ETrue);
+		}
+	
+	}
+
+TDfcQue*DDriverBeagleSoundScPdd::DfcQ(TInt /* aUnit*/ )
+        {
+        return this->DfcQ();
+        }
+
+TDfcQue*DDriverBeagleSoundScPdd::DfcQ()
+        {
+        return iPhysicalDevice->iDfcQ;
+        }
+
+TInt DDriverBeagleSoundScPdd::MaxTransferLen() const
+	{
+	
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPdd::MaxTransferLen TxPdd");
+	
+	TInt maxlength = 200*1024;
+	return maxlength;
+	}
+
+
+void DDriverBeagleSoundScPdd::SetCaps()
+	{
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPdd::SetCaps TxPdd");
+	
+	if(iUnitType == KSoundScTxUnit0)
+		{
+		// The data transfer direction for this unit is play
+		iCaps.iDirection = ESoundDirPlayback;
+		}
+	else if(iUnitType == KSoundScRxUnit0)
+		{
+		// The data transfer direction for this unit is record 
+		iCaps.iDirection = ESoundDirRecord;
+		}
+	
+	// This unit supports both mono and stereo
+	iCaps.iChannels = (KSoundMonoChannel | KSoundStereoChannel);
+
+	// This unit supports only some of the sample rates offered by Symbian OS
+	iCaps.iRates = (KSoundRate8000Hz | KSoundRate11025Hz | KSoundRate12000Hz | KSoundRate16000Hz |
+					KSoundRate22050Hz | KSoundRate24000Hz | KSoundRate32000Hz | KSoundRate44100Hz |
+					KSoundRate48000Hz);
+
+	// This unit only supports 16bit PCM encoding
+	iCaps.iEncodings = KSoundEncoding16BitPCM;
+
+	// This unit only supports interleaved data format when playing stereo;  that is, a PCM data
+	// stream where the left and right channel samples are interleaved as L-R-L-R-L-R etc.
+	iCaps.iDataFormats = KSoundDataFormatInterleaved;
+
+	// The iRequestMinSize member is named badly.  It is actually the value of which the length samples
+	// must be a multiple of.  ie.  The sample length % iRequestMinSize must == 0.  This value must always
+	// be a power of 2
+	iCaps.iRequestMinSize = 4;
+
+	// The logarithm to base 2 of the alignment required for request arguments.  DMA requests must be
+	// aligned to a 32 bit boundary
+	iCaps.iRequestAlignment = 2;
+
+	// This unit is not capable of detecting changes in hardware configuration
+	iCaps.iHwConfigNotificationSupport = EFalse;
+	}
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omap3530/beagle_drivers/soundsc/soundsc.mmp	Tue Feb 02 21:04:35 2010 +0000
@@ -0,0 +1,32 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include			"beagle/variant.mmh"
+#include			"kernel/kern_ext.mmh"
+
+SYSTEMINCLUDE		/epoc32/include/drivers
+
+
+TARGET			VariantTarget(soundsc,pdd)
+TARGETTYPE		pdd
+ROMTARGET		soundsc.pdd
+
+SOURCE			shared_txsound.cpp
+SOURCE			variant_sound.cpp
+
+CAPABILITY		all
+EPOCALLOWDLLDATA
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omap3530/beagle_drivers/soundsc/variant_sound.cpp	Tue Feb 02 21:04:35 2010 +0000
@@ -0,0 +1,128 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "variant_sound.h"
+
+_LIT(KSoundScPddName, "SoundSc.Beagle");
+
+
+DECLARE_STANDARD_PDD()
+	{
+	return new DDriverBeagleSoundScPddFactory;
+	}
+
+
+DDriverBeagleSoundScPddFactory::DDriverBeagleSoundScPddFactory()
+	{
+
+	iUnitsMask = ((1 << KSoundScTxUnit0) | (1 << KSoundScRxUnit0));
+
+	iVersion = RSoundSc::VersionRequired();
+	}
+
+
+TInt DDriverBeagleSoundScPddFactory::Install()
+	{
+	_LIT(KAudioDFC, "AUDIO DFC");
+	// Get a pointer to the the McBSP's DFC Queue so that handling of both McBSP callbacks and requests
+	// made to the LDD from user mode can be processed in the same thread, to avoid the use of semaphores
+	TInt r = Kern::DfcQCreate(iDfcQ, 26, &KAudioDFC);
+
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPddFactory::PDD install");
+
+	if(r==KErrNone)
+		{
+		// All PDD factories must have a unique name
+		TInt r = SetName(&KSoundScPddName);
+		}
+
+	return r;
+	}
+
+void DDriverBeagleSoundScPddFactory::GetCaps(TDes8& /*aDes*/) const
+	{
+	}
+
+
+TInt DDriverBeagleSoundScPddFactory::Validate(TInt aUnit, const TDesC8* /*aInfo*/, const TVersion& aVer)
+	{
+	// Check that the version requested is less than or equal to the version of this PDD
+	if (!Kern::QueryVersionSupported(RSoundSc::VersionRequired(), aVer))
+		{
+		BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPddFactory::Validate KErrNotSup1");
+		return KErrNotSupported;
+		}
+
+	// Check the unit number specifies either playback or recording
+	if ((aUnit != KSoundScTxUnit0) && (aUnit != KSoundScRxUnit0))
+		{
+		BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPddFactory::Validate KErrNotSup2");
+		return KErrNotSupported;
+		}
+
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPddFactory::Validate KErrNone");
+	return KErrNone;
+	}
+
+TInt DDriverBeagleSoundScPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
+	{
+
+	DSoundScPdd* pD = NULL;
+
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPddFactory::PDD create aUnit %d TxUnitId %d", aUnit, KSoundScTxUnit0);
+
+	// Assume failure
+	TInt r = KErrNoMemory;
+	aChannel = NULL;
+
+				
+	DDriverBeagleSoundScPdd* pTxD = new DDriverBeagleSoundScPdd;
+
+	BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPddFactory::TxPdd %d", pTxD);
+		
+	if (pTxD)
+		{
+		pD = pTxD;
+
+		// Save a pointer to the factory so that it is accessible by the PDD and call the PDD's
+		// second stage constructor
+		pTxD->iPhysicalDevice = this;
+			
+		pTxD->iUnitType = aUnit; // Either KSoundScTxUnit0 or KSoundScRxUnit0 (play or record)
+			
+		BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPddFactory::TxPdd2 %d", pTxD);
+			
+		r = pTxD->DoCreate();
+			
+		BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPddFactory::Create ret %d", r);
+			
+		}
+	
+	// If everything succeeded, save a pointer to the PDD.  This should only be done if DoCreate() succeeded,
+	// as some LDDs have been known to access this pointer even if Create() returns an error!
+	if (r == KErrNone)
+		{
+		aChannel = pD;
+		BEAGLE_SOUND_DEBUG("DDriverBeagleSoundScPddFactory::TxPdd set AChannel %d", aChannel);
+		}
+	else
+		{
+		delete pD;
+		}
+
+	return r;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omap3530/beagle_drivers/soundsc/variant_sound.h	Tue Feb 02 21:04:35 2010 +0000
@@ -0,0 +1,40 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef __BEAGLEVARIANT_SOUND_H__
+#define __BEAGLEVARIANT_SOUND_H__
+
+#include "shared_sound.h"
+
+class DDriverBeagleSoundScPddFactory : public DPhysicalDevice
+	{
+public:
+
+	DDriverBeagleSoundScPddFactory();
+	TInt Install();
+	void GetCaps(TDes8 &aDes) const;
+	TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion &aVer);
+	TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer);
+
+public:
+
+	/** The DFC queue to be used by both the LDD and the PDD to serialise access to the PDD */
+	TDfcQue*		iDfcQ;
+
+	};
+
+#endif