sl@0: // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // template\template_variant\specific\soundsc_rx.cpp sl@0: // Implementation of the Template record shared chunk sound physical device driver (PDD). sl@0: // This file is part of the Template Base port sl@0: // sl@0: // sl@0: sl@0: /** sl@0: @file sl@0: */ sl@0: sl@0: #include "soundsc_plat.h" sl@0: sl@0: sl@0: /** sl@0: Constructor for the Template record shared chunk sound driver physical device driver (PDD). sl@0: */ sl@0: DTemplateSoundScRxPdd::DTemplateSoundScRxPdd() sl@0: { sl@0: __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::DTemplateSoundScRxPdd")); sl@0: sl@0: // iDmaChan=NULL; sl@0: // iPendingRecord=0; sl@0: // iFlag=0; sl@0: } sl@0: sl@0: /** sl@0: Destructor for the Template record shared chunk sound driver physical device driver (PDD). sl@0: */ sl@0: DTemplateSoundScRxPdd::~DTemplateSoundScRxPdd() sl@0: { sl@0: // Delete the DMA request objects sl@0: for (TInt i=0; iClose(); sl@0: } sl@0: sl@0: /** sl@0: Second stage constructor for the Template record shared chunk sound driver physical device driver (PDD). sl@0: Note that this constructor is called before the second stage constructor for the LDD so it is not sl@0: possible to call methods on the LDD here. sl@0: @return KErrNone if successful, otherwise one of the other system wide error codes. sl@0: */ sl@0: TInt DTemplateSoundScRxPdd::DoCreate() sl@0: { sl@0: __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::DoCreate")); sl@0: sl@0: SetCaps(); // Setup the capabilities of this device. sl@0: sl@0: // Setup a DMA channel for record sl@0: // TO DO: (mandatory) sl@0: // Setup the DMA channel information for this record device. sl@0: TDmaChannel::SCreateInfo info; sl@0: // info.iCookie=??? sl@0: info.iDfcQ=DfcQ(KSoundScRxUnit0); sl@0: // info.iDfcPriority=??? sl@0: info.iDesCount=KTemplateMaxRxDmaRequests; sl@0: // coverity[uninit_use_in_call] sl@0: // The values info.iCookie and info.iDfcPriority are to be initialized when implemented sl@0: TInt r=TDmaChannel::Open(info,iDmaChannel); sl@0: sl@0: // Create the DMA request objects for use with the DMA channel. sl@0: if (r==KErrNone) sl@0: { sl@0: for (TInt i=0; iiDfcQ); sl@0: } sl@0: sl@0: /** sl@0: Called from the LDD to return the shared chunk create information to be used by this record device. sl@0: @param aChunkCreateInfo A chunk create info. object to be to be filled with the settings sl@0: required for this device. sl@0: */ sl@0: void DTemplateSoundScRxPdd::GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo) sl@0: { sl@0: __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::GetChunkCreateInfo")); sl@0: sl@0: // TO DO: (mandatory) sl@0: // Setup the shared chunk create information in aChunkCreateInfo for this record device. sl@0: aChunkCreateInfo.iType=TChunkCreateInfo::ESharedKernelMultiple; sl@0: // aChunkCreateInfo.iMapAttr=??? sl@0: aChunkCreateInfo.iOwnsMemory=ETrue; // Using RAM pages. sl@0: aChunkCreateInfo.iDestroyedDfc=NULL; // No chunk destroy DFC. sl@0: } sl@0: sl@0: /** sl@0: Called from the LDD to return the capabilities of this device. sl@0: @param aCapsBuf A packaged TSoundFormatsSupportedV02 object to be filled with the record sl@0: capabilities of this device. This descriptor is in kernel memory and can be accessed directly. sl@0: @see TSoundFormatsSupportedV02. sl@0: */ sl@0: void DTemplateSoundScRxPdd::Caps(TDes8& aCapsBuf) const sl@0: { sl@0: __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::Caps")); sl@0: sl@0: // Copy iCaps back. sl@0: TPtrC8 ptr((const TUint8*)&iCaps,sizeof(iCaps)); sl@0: aCapsBuf.FillZ(aCapsBuf.MaxLength()); sl@0: aCapsBuf=ptr.Left(Min(ptr.Length(),aCapsBuf.MaxLength())); sl@0: } sl@0: sl@0: /** sl@0: Called from the LDD to return the maximum transfer length in bytes that this device can support in a single data transfer. sl@0: @return The maximum transfer length in bytes. sl@0: */ sl@0: TInt DTemplateSoundScRxPdd::MaxTransferLen() const sl@0: { sl@0: return(KTemplateMaxRxDmaTransferLen); sl@0: } sl@0: sl@0: /** sl@0: Called from the LDD to configure or reconfigure the device using the the configuration supplied. sl@0: @param aConfigBuf A packaged TCurrentSoundFormatV02 object which contains the new configuration settings. sl@0: This descriptor is in kernel memory and can be accessed directly. sl@0: @return KErrNone if successful, otherwise one of the other system wide error codes. sl@0: @see TCurrentSoundFormatV02. sl@0: */ sl@0: TInt DTemplateSoundScRxPdd::SetConfig(const TDesC8& aConfigBuf) sl@0: { sl@0: __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::SetConfig")); sl@0: sl@0: // Read the new configuration from the LDD. sl@0: TCurrentSoundFormatV02 config; sl@0: TPtr8 ptr((TUint8*)&config,sizeof(config)); sl@0: Kern::InfoCopy(ptr,aConfigBuf); sl@0: sl@0: // TO DO: (mandatory) sl@0: // Apply the specified audio configuration to the audio device. sl@0: TInt r=KErrNone; sl@0: sl@0: __KTRACE_SND(Kern::Printf("DTemplateSoundScRxPdd::SetVolume")); sl@0: sl@0: // TO DO: (mandatory) sl@0: // Set the specified record volume on the audio device. sl@0: TInt r=KErrNone; sl@0: sl@0: return(r); sl@0: } sl@0: sl@0: /** sl@0: Called from the LDD to prepare the audio device for recording. sl@0: @return KErrNone if successful, otherwise one of the other system wide error codes. sl@0: */ sl@0: TInt DTemplateSoundScRxPdd::StartTransfer() sl@0: { sl@0: __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::StartTransfer")); sl@0: sl@0: // TO DO: (mandatory) sl@0: // Prepare the audio device for record. sl@0: TInt r=KErrNone; sl@0: sl@0: __KTRACE_SND(Kern::Printf("DTemplateSoundScRxPdd::TransferData(ID:%xH,Addr:%xH,Len:%d)",aLinAddr,aNumBytes)); sl@0: sl@0: TInt r=KErrNone; sl@0: sl@0: // Check that we can accept the request sl@0: if (iPendingRecord>=KTemplateMaxRxDmaRequests) sl@0: r=KErrNotReady; sl@0: else sl@0: { sl@0: // Start a DMA transfer. sl@0: iDmaRequest[iFlag]->iTransferID=aTransferID; sl@0: iDmaRequest[iFlag]->iTransferSize=aNumBytes; sl@0: // TO DO: (mandatory) sl@0: // Supply the DMA source information. sl@0: TUint32 src=0; // ??? sl@0: r=iDmaRequest[iFlag]->Fragment(src,aLinAddr,aNumBytes,KDmaMemDest|KDmaIncDest,0); sl@0: if (r==KErrNone) sl@0: { sl@0: iDmaRequest[iFlag]->Queue(); sl@0: iPendingRecord++; sl@0: if ((++iFlag)>=KTemplateMaxRxDmaRequests) sl@0: iFlag=0; sl@0: sl@0: // TO DO: (mandatory) sl@0: // Start the audio device transfering data. sl@0: } sl@0: } sl@0: sl@0: __KTRACE_SND(Kern::Printf("DTemplateSoundScRxPdd::StopTransfer")); sl@0: sl@0: // Stop the DMA channel. sl@0: iDmaChannel->CancelAll(); sl@0: iFlag=0; sl@0: iPendingRecord=0; sl@0: sl@0: // TO DO: (mandatory) sl@0: // Stop the audio device transfering data. sl@0: } sl@0: sl@0: /** sl@0: Called from the LDD to halt the recording of data from the sound device but not to release any resources necessary for sl@0: recording. sl@0: All active transfers should be aborted. When recording is halted the PDD signals this event with a single call of the LDD sl@0: function RecordCallback() - reporting back any partial data already received. If transfer is resumed later, the LDD will sl@0: issue a new TransferData() request to re-commence data transfer. sl@0: @return KErrNone if successful, otherwise one of the other system wide error codes. sl@0: */ sl@0: TInt DTemplateSoundScRxPdd::PauseTransfer() sl@0: { sl@0: __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::PauseTransfer")); sl@0: sl@0: // Stop the DMA channel. sl@0: iDmaChannel->CancelAll(); sl@0: sl@0: if (iPendingRecord) sl@0: { sl@0: // TO DO: (mandatory) sl@0: // Determine how much data was successfully transferred to the record buffer before transfer was aborted. sl@0: TInt byteCount=0; // ??? sl@0: Ldd()->RecordCallback(0,KErrNone,byteCount); // We can use a NULL transfer ID when pausing. sl@0: iPendingRecord=0; sl@0: } sl@0: iFlag=0; sl@0: sl@0: // TO DO: (mandatory) sl@0: // Halt recording on the audio device. sl@0: TInt r=KErrNone; sl@0: sl@0: return(r); sl@0: } sl@0: sl@0: /** sl@0: Called from the LDD to resume the recording of data from the sound device following a request to halt recording. sl@0: Any active transfer would have been aborted when the device was halted so its just a case of re-creating the same setup sl@0: acheived following StartTransfer(). sl@0: @return KErrNone if successful, otherwise one of the other system wide error codes. sl@0: */ sl@0: TInt DTemplateSoundScRxPdd::ResumeTransfer() sl@0: { sl@0: __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::ResumeTransfer")); sl@0: sl@0: // TO DO: (mandatory) sl@0: // Resume recording on the audio device. sl@0: TInt r=KErrNone; sl@0: sl@0: return(r); sl@0: } sl@0: sl@0: /** sl@0: Called from the LDD to power up the sound device when the channel is first opened and if ever the phone is brought out sl@0: of standby mode. sl@0: @return KErrNone if successful, otherwise one of the other system wide error codes. sl@0: */ sl@0: TInt DTemplateSoundScRxPdd::PowerUp() sl@0: { sl@0: // TO DO: (mandatory) sl@0: // Power up the audio device. sl@0: sl@0: return(KErrNone); sl@0: } sl@0: sl@0: /** sl@0: Called from the LDD to power down the sound device when the channel is closed and just before the phone powers down when sl@0: being turned off or going into standby. sl@0: */ sl@0: void DTemplateSoundScRxPdd::PowerDown() sl@0: { sl@0: // TO DO: (mandatory) sl@0: // Power down the audio device. sl@0: } sl@0: sl@0: /** sl@0: Called from the LDD to handle a custom configuration request. sl@0: @param aFunction A number identifying the request. sl@0: @param aParam A 32-bit value passed to the driver. Its meaning depends on the request. sl@0: @return KErrNone if successful, otherwise one of the other system wide error codes. sl@0: */ sl@0: TInt DTemplateSoundScRxPdd::CustomConfig(TInt /*aFunction*/,TAny* /*aParam*/) sl@0: { sl@0: return(KErrNotSupported); sl@0: } sl@0: sl@0: /** sl@0: Called from the LDD to find out how many microseconds of data have been recorded. This is called sl@0: in the context of the DFC thread. sl@0: @param aTimeTransferred A reference to a variable into which to place the number of microseconds of audio. sl@0: @param aStatus The current status of this channel sl@0: @return KErrNone if time is valid or KErrNotSupported. sl@0: */ sl@0: TInt DTemplateSoundScRxPdd::TimeTransferred(TInt64& aTimeTransferred, TInt aStatus) sl@0: { sl@0: return(KErrNotSupported); sl@0: } sl@0: sl@0: /** sl@0: Called each time a record DMA transfer completes - from the DMA callback function in the sound thread's DFC context. sl@0: @param aTransferID The transfer ID of the DMA transfer. sl@0: @param aTransferResult The result of the DMA transfer. sl@0: @param aBytesTransferred The number of bytes transferred. sl@0: */ sl@0: void DTemplateSoundScRxPdd::RecordCallback(TUint aTransferID,TInt aTransferResult,TInt aBytesTransferred) sl@0: { sl@0: __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::RecordCallback")); sl@0: sl@0: iPendingRecord--; sl@0: sl@0: Ldd()->RecordCallback(aTransferID,aTransferResult,aBytesTransferred); sl@0: } sl@0: sl@0: /** sl@0: Initialise the data member DTemplateSoundScRxPdd::iCaps with the record capabilities of this audio device. sl@0: */ sl@0: void DTemplateSoundScRxPdd::SetCaps() sl@0: { sl@0: __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::SetCaps")); sl@0: sl@0: // The data transfer direction for this unit is record. sl@0: iCaps.iDirection=ESoundDirRecord; sl@0: sl@0: // TO DO: (mandatory) sl@0: // Setup the rest of the capabilities structure DTemplateSoundScRxPdd::iCaps with the capabilities of this sl@0: // audio record device. sl@0: } sl@0: sl@0: /** sl@0: Constructor for a shared chunk sound driver record DMA request. sl@0: */ sl@0: DTemplateSoundScRxDmaRequest::DTemplateSoundScRxDmaRequest(TDmaChannel& aChannel,DTemplateSoundScRxPdd* aPdd,TInt aMaxTransferSize) sl@0: : DDmaRequest(aChannel,DTemplateSoundScRxDmaRequest::DmaService,this,aMaxTransferSize), sl@0: iPdd(aPdd) sl@0: {} sl@0: sl@0: /** sl@0: DMA rx service routine. Called in the sound thread's DFC context by the s/w DMA controller. sl@0: @param aResult Status of DMA transfer. sl@0: @param aArg Argument passed to DMA controller. sl@0: */ sl@0: void DTemplateSoundScRxDmaRequest::DmaService(TResult aResult, TAny* aArg) sl@0: { sl@0: __KTRACE_SND(Kern::Printf(">SndRxDmaService - %d",aResult)); sl@0: DTemplateSoundScRxDmaRequest& req=*(DTemplateSoundScRxDmaRequest*)aArg; sl@0: sl@0: TInt res=KErrNone; sl@0: TInt bytesTransferred=req.iTransferSize; sl@0: if (aResult!=DDmaRequest::EOk) sl@0: { sl@0: res=KErrCorrupt; sl@0: bytesTransferred=0; sl@0: } sl@0: sl@0: // Inform the LDD of the result of the transfer. sl@0: req.iPdd->RecordCallback(req.iTransferID,res,bytesTransferred); sl@0: return; sl@0: } sl@0: