From 3d61697e688c99ff9265238b2eab474f7f1bcfc8 Mon Sep 17 00:00:00 2001 From: Octasic Inc Date: Wed, 23 Nov 2005 15:07:18 +0200 Subject: importing OCT612x-01.00-PR38 --- .../oct6100api/oct6100_api/oct6100_mixer.c | 1542 ++++++++++++++++++++ 1 file changed, 1542 insertions(+) create mode 100644 software/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.c (limited to 'software/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.c') diff --git a/software/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.c b/software/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.c new file mode 100644 index 0000000..680bf7e --- /dev/null +++ b/software/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.c @@ -0,0 +1,1542 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_mixer.c + + Copyright (c) 2001-2005 Octasic Inc. + +Description: + + This file contains the functions used to manage the allocation of mixer + blocks in memories. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR38 $ + +$Octasic_Revision: 42 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_mixer_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_mixer_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_mixer_priv.h" + +/**************************** PUBLIC FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100MixerCopyEventCreate + +Description: This function creates a mixer copy event used to copy + information from one channel port to another channel port. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventCreate Pointer to a mixer copy event structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100MixerCopyEventCreateDef( + tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate ) +{ + f_pCopyEventCreate->pulCopyEventHndl = NULL; + + f_pCopyEventCreate->ulSourceChanHndl = cOCT6100_INVALID_HANDLE; + f_pCopyEventCreate->ulSourcePort = cOCT6100_INVALID_PORT; + + f_pCopyEventCreate->ulDestinationChanHndl = cOCT6100_INVALID_HANDLE; + f_pCopyEventCreate->ulDestinationPort = cOCT6100_INVALID_PORT; + + return cOCT6100_ERR_OK; +} + + +UINT32 Oct6100MixerCopyEventCreate( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100MixerCopyEventCreateSer( f_pApiInstance, f_pCopyEventCreate ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100MixerCopyEventDestroy + +Description: This function destroys a mixer copy event used to copy + information from one channel port to another. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventDestroy Pointer to a destroy copy event structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100MixerCopyEventDestroyDef( + tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy ) +{ + f_pCopyEventDestroy->ulCopyEventHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} + + +UINT32 Oct6100MixerCopyEventDestroy( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100MixerCopyEventDestroySer( f_pApiInstance, f_pCopyEventDestroy ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} + + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetMixerSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of mixer events. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pOpenChip User chip configuration. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiGetMixerSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Calculate the API memory required for the resource entry lists. */ + f_pInstSizes->ulMixerEventList = cOCT6100_MAX_MIXER_EVENTS * sizeof( tOCT6100_API_MIXER_EVENT ); + + /* Calculate memory needed for mixers entry allocation. */ + ulResult = OctapiLlmAllocGetSize( cOCT6100_MAX_MIXER_EVENTS, &f_pInstSizes->ulMixerEventAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1D; + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulMixerEventList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulMixerEventAlloc, ulTempVar ) + + + f_pInstSizes->ulCopyEventList = cOCT6100_MAX_MIXER_EVENTS * sizeof( tOCT6100_API_COPY_EVENT ); + + ulResult = OctapiLlmAllocGetSize( cOCT6100_MAX_MIXER_EVENTS, &f_pInstSizes->ulCopyEventAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1D; + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulCopyEventList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulCopyEventAlloc, ulTempVar ) + + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMixerSwInit + +Description: Initializes all elements of the instance structure associated + to the mixer events. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This mixer is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiMixerSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_MIXER_EVENT pMixerEventList; + PVOID pMixerEventAlloc; + PVOID pCopyEventAlloc; + UINT32 ulTempVar; + UINT32 ulResult; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /*===================================================================*/ + /* Initialize the mixer event list. */ + mOCT6100_GET_MIXER_EVENT_LIST_PNT( pSharedInfo, pMixerEventList ); + + /* Initialize the mixer event allocation software to "all free". */ + Oct6100UserMemSet( pMixerEventList, 0x00, cOCT6100_MAX_MIXER_EVENTS * sizeof( tOCT6100_API_MIXER_EVENT )); + + mOCT6100_GET_MIXER_EVENT_ALLOC_PNT( pSharedInfo, pMixerEventAlloc ) + + ulResult = OctapiLlmAllocInit( &pMixerEventAlloc, cOCT6100_MAX_MIXER_EVENTS ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1F; + + /* Now reserve the first entry as the first node. */ + ulResult = OctapiLlmAllocAlloc( pMixerEventAlloc, &ulTempVar ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_20; + } + + /* Check that we obtain the first event. */ + if ( ulTempVar != 0 ) + return cOCT6100_ERR_FATAL_21; + + /* Now reserve the tail entry. */ + ulResult = OctapiLlmAllocAlloc( pMixerEventAlloc, &ulTempVar ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_AA; + } + /* Check that we obtain the first event. */ + if ( ulTempVar != 1 ) + return cOCT6100_ERR_FATAL_AB; + + /* Program the head node. */ + pMixerEventList[ cOCT6100_MIXER_HEAD_NODE ].fReserved = TRUE; + pMixerEventList[ cOCT6100_MIXER_HEAD_NODE ].usNextEventPtr = cOCT6100_MIXER_TAIL_NODE; + pMixerEventList[ cOCT6100_MIXER_HEAD_NODE ].usEventType = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + /* Program the tail node. */ + pMixerEventList[ cOCT6100_MIXER_TAIL_NODE ].fReserved = TRUE; + pMixerEventList[ cOCT6100_MIXER_TAIL_NODE ].usNextEventPtr = cOCT6100_INVALID_INDEX; + pMixerEventList[ cOCT6100_MIXER_TAIL_NODE ].usEventType = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + /* Now reserve the entry used for channel recording if the feature is enabled. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + { + UINT32 ulAllocIndex; + + /* Reserve an entry to copy the desire SOUT signal to the SIN signal of the recording channel. */ + ulResult = OctapiLlmAllocAlloc( pMixerEventAlloc, &ulAllocIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_90; + } + + pSharedInfo->MixerInfo.usRecordCopyEventIndex = (UINT16)( ulAllocIndex & 0xFFFF ); + + /* Reserve an entry to copy the saved SIN signal of the debugged channel into it's original location. */ + ulResult = OctapiLlmAllocAlloc( pMixerEventAlloc, &ulAllocIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_90; + } + + pSharedInfo->MixerInfo.usRecordSinEventIndex = (UINT16)( ulAllocIndex & 0xFFFF ); + + /* Configure the SIN event. */ + pMixerEventList[ pSharedInfo->MixerInfo.usRecordSinEventIndex ].fReserved = TRUE; + pMixerEventList[ pSharedInfo->MixerInfo.usRecordSinEventIndex ].usNextEventPtr = cOCT6100_MIXER_TAIL_NODE; + pMixerEventList[ pSharedInfo->MixerInfo.usRecordSinEventIndex ].usEventType = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + /* Configure the SOUT copy event. */ + pMixerEventList[ pSharedInfo->MixerInfo.usRecordCopyEventIndex ].fReserved = TRUE; + pMixerEventList[ pSharedInfo->MixerInfo.usRecordCopyEventIndex ].usNextEventPtr = pSharedInfo->MixerInfo.usRecordSinEventIndex; + pMixerEventList[ pSharedInfo->MixerInfo.usRecordCopyEventIndex ].usEventType = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + /* Program the head node. */ + pMixerEventList[ cOCT6100_MIXER_HEAD_NODE ].usNextEventPtr = pSharedInfo->MixerInfo.usRecordCopyEventIndex; + } + + /* Initialize the copy event list. */ + mOCT6100_GET_COPY_EVENT_ALLOC_PNT( pSharedInfo, pCopyEventAlloc ) + + ulResult = OctapiLlmAllocInit( &pCopyEventAlloc, cOCT6100_MAX_MIXER_EVENTS ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_B4; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMixerEventAdd + +Description: This function adds a mixer event event to the list of events + based on the event type passed to the function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. +f_usEventIndex Index of the event within the API's mixer event list. +f_usEventType Type of mixer event. +f_usDestinationChanIndex Index of the destination channel within the API's + channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiMixerEventAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex, + IN UINT16 f_usEventType, + IN UINT16 f_usDestinationChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_MIXER_EVENT pCurrentEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEventEntry; + tPOCT6100_API_CHANNEL pDestinationEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + UINT16 usTempEventIndex; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Get a pointer to the event entry. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pCurrentEventEntry, f_usEventIndex ); + + /* Get a pointer to the destination channel entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pDestinationEntry, f_usDestinationChanIndex ); + + /* Now proceed according to the event type. */ + switch ( f_usEventType ) + { + case cOCT6100_EVENT_TYPE_SOUT_COPY: + + /* Now insert the Sin copy event */ + if ( pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + /* The only node in the list before the point where the node needs to */ + /* be inserted is the head node. */ + usTempEventIndex = cOCT6100_MIXER_HEAD_NODE; + + /* This node will be the first one in the Sout copy section. */ + pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr = f_usEventIndex; + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = f_usEventIndex; + } + else /* pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr != cOCT6100_INVALID_INDEX */ + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = f_usEventIndex; + } + + break; + + case cOCT6100_EVENT_TYPE_SIN_COPY: + + /* Now insert the Sin copy event. */ + if ( pSharedInfo->MixerInfo.usFirstSinCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + /* This is the first Sin copy event. We must find the event that comes before */ + /* the event we want to add. First let's check for a bridge event. */ + if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr == cOCT6100_INVALID_INDEX ) + { + /* No event in the bridge section, now let's check in the Sout copy section. */ + if ( pSharedInfo->MixerInfo.usLastSoutCopyEventPtr == cOCT6100_INVALID_INDEX ) + { + /* The only node in the list then is the head node. */ + usTempEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + else + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + } + else + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastBridgeEventPtr; + } + + /* This node will be the first one in the Sin copy section. */ + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = f_usEventIndex; + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = f_usEventIndex; + } + else /* pSharedInfo->MixerInfo.usFirstSinCopyEventPtr != cOCT6100_INVALID_INDEX */ + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastSinCopyEventPtr; + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = f_usEventIndex; + } + + break; + + default: + return cOCT6100_ERR_FATAL_AF; + + } + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, usTempEventIndex ); + + /*=======================================================================*/ + /* Program the Copy event. */ + + /* Set the Copy event first. */ + pCurrentEventEntry->usEventType = cOCT6100_MIXER_CONTROL_MEM_COPY; + pCurrentEventEntry->usNextEventPtr = pTempEventEntry->usNextEventPtr; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + WriteParams.usWriteData = pCurrentEventEntry->usNextEventPtr; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Modify the previous node. */ + + /* Set the last Sub-store entry. */ + pTempEventEntry->usNextEventPtr = f_usEventIndex; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usTempEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + WriteParams.usWriteData = f_usEventIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Save the destination channel index, needed when removing the event from the mixer. */ + pCurrentEventEntry->usDestinationChanIndex = f_usDestinationChanIndex; + + /* Mark the entry as reserved. */ + pCurrentEventEntry->fReserved = TRUE; + + /* Increment the event count on that particular destination channel */ + pDestinationEntry->usMixerEventCnt++; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMixerEventRemove + +Description: This function removes a mixer event event from the list of events based + on the event type passed to the function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usEventIndex Index of event within the API's mixer event list. +f_usEventType Type of mixer event. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiMixerEventRemove( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex, + IN UINT16 f_usEventType ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_MIXER_EVENT pCurrentEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEventEntry; + tPOCT6100_API_CHANNEL pDestinationEntry; + tOCT6100_WRITE_BURST_PARAMS BurstWriteParams; + tOCT6100_WRITE_PARAMS WriteParams; + BOOL fFirstSinCopyEvent = FALSE; + UINT32 ulResult; + UINT16 usTempEventIndex; + UINT32 ulLoopCount = 0; + UINT16 ausWriteData[ 4 ] = { 0 }; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + BurstWriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstWriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + BurstWriteParams.pusWriteData = ausWriteData; + BurstWriteParams.ulWriteLength = 4; + + /* Get a pointer to the event entry. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pCurrentEventEntry, f_usEventIndex ); + + /* Get the pointer to the channel entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pDestinationEntry, pCurrentEventEntry->usDestinationChanIndex ); + + /* Now proceed according to the event type. */ + switch ( f_usEventType ) + { + case cOCT6100_EVENT_TYPE_SOUT_COPY: + + if ( f_usEventIndex == pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr ) + { + usTempEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + else + { + /* Now insert the Sin copy event. */ + usTempEventIndex = pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr; + } + + /* Find the copy entry before the entry to remove. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, usTempEventIndex ); + + while( pTempEventEntry->usNextEventPtr != f_usEventIndex ) + { + usTempEventIndex = pTempEventEntry->usNextEventPtr; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, usTempEventIndex ); + + ulLoopCount++; + if ( ulLoopCount == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_FATAL_B2; + } + + /*=======================================================================*/ + /* Update the global mixer pointers. */ + if ( f_usEventIndex == pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr ) + { + if ( f_usEventIndex == pSharedInfo->MixerInfo.usLastSoutCopyEventPtr ) + { + /* This event was the only of the list.*/ + pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = cOCT6100_INVALID_INDEX; + } + else + { + pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr = pCurrentEventEntry->usNextEventPtr; + } + } + else if ( f_usEventIndex == pSharedInfo->MixerInfo.usLastSoutCopyEventPtr ) + { + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = usTempEventIndex; + } + /*=======================================================================*/ + + break; + + + case cOCT6100_EVENT_TYPE_SIN_COPY: + + if ( f_usEventIndex == pSharedInfo->MixerInfo.usFirstSinCopyEventPtr ) + { + fFirstSinCopyEvent = TRUE; + + if ( pSharedInfo->MixerInfo.usLastBridgeEventPtr != cOCT6100_INVALID_INDEX ) + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastBridgeEventPtr; + } + else if ( pSharedInfo->MixerInfo.usLastSoutCopyEventPtr != cOCT6100_INVALID_INDEX ) + { + usTempEventIndex = pSharedInfo->MixerInfo.usLastSoutCopyEventPtr; + } + else + { + usTempEventIndex = cOCT6100_MIXER_HEAD_NODE; + } + } + else + { + /* Now insert the Sin copy event. */ + usTempEventIndex = pSharedInfo->MixerInfo.usFirstSinCopyEventPtr; + } + + /* Find the copy entry before the entry to remove. */ + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, usTempEventIndex ); + + /* If we are not the first event of the Sin copy list. */ + if ( fFirstSinCopyEvent == FALSE ) + { + while( pTempEventEntry->usNextEventPtr != f_usEventIndex ) + { + usTempEventIndex = pTempEventEntry->usNextEventPtr; + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, usTempEventIndex ); + + ulLoopCount++; + if ( ulLoopCount == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_FATAL_B1; + } + } + + /*=======================================================================*/ + /* Update the global mixer pointers. */ + if ( f_usEventIndex == pSharedInfo->MixerInfo.usFirstSinCopyEventPtr ) + { + if ( f_usEventIndex == pSharedInfo->MixerInfo.usLastSinCopyEventPtr ) + { + /* This event was the only of the list. */ + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = cOCT6100_INVALID_INDEX; + } + else + { + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = pCurrentEventEntry->usNextEventPtr; + } + } + else if ( f_usEventIndex == pSharedInfo->MixerInfo.usLastSinCopyEventPtr ) + { + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = usTempEventIndex; + } + /*=======================================================================*/ + + break; + + default: + return cOCT6100_ERR_FATAL_B0; + + } + + /*=======================================================================*/ + /* Modify the previous event. */ + + pTempEventEntry->usNextEventPtr = pCurrentEventEntry->usNextEventPtr; + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( usTempEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.ulWriteAddress += 4; + WriteParams.usWriteData = pTempEventEntry->usNextEventPtr; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Clear the current event. */ + + BurstWriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + mOCT6100_DRIVER_WRITE_BURST_API( BurstWriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Decrement the mixer event count active on that channel. */ + pDestinationEntry->usMixerEventCnt--; + + /*=======================================================================*/ + + + /*=======================================================================*/ + + /* This index of this channel is not valid anymore! */ + pCurrentEventEntry->usDestinationChanIndex = cOCT6100_INVALID_INDEX; + + /* Mark this entry as free. */ + pCurrentEventEntry->fReserved = FALSE; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100MixerCopyEventCreateSer + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventCreate Pointer to a create copy event structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100MixerCopyEventCreateSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate ) +{ + UINT16 usCopyEventIndex; + UINT16 usMixerEventIndex; + UINT16 usSourceChanIndex; + UINT16 usDestinationChanIndex; + UINT32 ulResult; + + /* Check the user's configuration of the copy event for errors. */ + ulResult = Oct6100ApiCheckCopyEventCreateParams( f_pApiInstance, + f_pCopyEventCreate, + &usSourceChanIndex, + &usDestinationChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the copy event. */ + ulResult = Oct6100ApiReserveCopyEventCreateResources( f_pApiInstance, + &usCopyEventIndex, + &usMixerEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write all necessary structures to activate the echo cancellation channel. */ + ulResult = Oct6100ApiWriteCopyEventCreateStructs( f_pApiInstance, + f_pCopyEventCreate, + usMixerEventIndex, + usSourceChanIndex, + usDestinationChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the new echo cancellation channels's entry in the ECHO channel list. */ + ulResult = Oct6100ApiUpdateCopyEventCreateEntry( f_pApiInstance, + f_pCopyEventCreate, + usCopyEventIndex, + usMixerEventIndex, + usSourceChanIndex, + usDestinationChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckCopyEventCreateParams + +Description: Checks the user's parameter passed to the create + copy event function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventCreate Pointer to a create copy event structure. +f_pusSourceChanIndex Pointer to the index of the input channel. +f_pusDestinationChanIndex Pointer to the index of the output channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiCheckCopyEventCreateParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate, + OUT PUINT16 f_pusSourceChanIndex, + OUT PUINT16 f_pusDestinationChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pSourceEntry; + tPOCT6100_API_CHANNEL pDestinationEntry; + UINT32 ulEntryOpenCnt; + + /* Obtain shared resources pointer. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + if ( f_pCopyEventCreate->pulCopyEventHndl == NULL ) + return cOCT6100_ERR_MIXER_COPY_EVENT_HANDLE; + + if ( f_pCopyEventCreate->ulSourceChanHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_MIXER_SOURCE_CHAN_HANDLE; + if ( f_pCopyEventCreate->ulDestinationChanHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_MIXER_DESTINATION_CHAN_HANDLE; + + if ( f_pCopyEventCreate->ulSourcePort != cOCT6100_CHANNEL_PORT_RIN && + f_pCopyEventCreate->ulSourcePort != cOCT6100_CHANNEL_PORT_SIN ) + return cOCT6100_ERR_MIXER_SOURCE_PORT; + + if ( f_pCopyEventCreate->ulDestinationPort != cOCT6100_CHANNEL_PORT_RIN && + f_pCopyEventCreate->ulDestinationPort != cOCT6100_CHANNEL_PORT_SIN ) + return cOCT6100_ERR_MIXER_DESTINATION_PORT; + + /*=======================================================================*/ + /* Verify the first channel handle. */ + + if ( (f_pCopyEventCreate->ulSourceChanHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_MIXER_SOURCE_CHAN_HANDLE; + + *f_pusSourceChanIndex = (UINT16)( f_pCopyEventCreate->ulSourceChanHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusSourceChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_MIXER_SOURCE_CHAN_HANDLE; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSourceEntry, *f_pusSourceChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pCopyEventCreate->ulSourceChanHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pSourceEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pSourceEntry->byEntryOpenCnt ) + return cOCT6100_ERR_MIXER_SOURCE_CHAN_HANDLE; + if ( pSourceEntry->CodecConfig.byDecoderPort == f_pCopyEventCreate->ulSourcePort ) + return cOCT6100_ERR_MIXER_SOURCE_ADPCM_RESOURCES_ACTIVATED; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Verify the second channel handle. */ + + if ( (f_pCopyEventCreate->ulDestinationChanHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_MIXER_DESTINATION_CHAN_HANDLE; + + *f_pusDestinationChanIndex = (UINT16)( f_pCopyEventCreate->ulDestinationChanHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusDestinationChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_MIXER_DESTINATION_CHAN_HANDLE; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pDestinationEntry, *f_pusDestinationChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pCopyEventCreate->ulDestinationChanHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pDestinationEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pDestinationEntry->byEntryOpenCnt ) + return cOCT6100_ERR_MIXER_DESTINATION_CHAN_HANDLE; + if ( pDestinationEntry->CodecConfig.byDecoderPort == f_pCopyEventCreate->ulDestinationPort ) + return cOCT6100_ERR_MIXER_DEST_ADPCM_RESOURCES_ACTIVATED; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveCopyEventCreateResources + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pusCopyEntryIndex Pointer to the index of the copy entry within the API's list. +f_pusCopyEventIndex Pointer to the index of the mixer copy event. +. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiReserveCopyEventCreateResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusCopyEntryIndex, + IN OUT PUINT16 f_pusCopyEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 ulTempVar; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /*===============================================================================*/ + /* Verify and reserve the resources that might already be allocated. */ + + ulResult = Oct6100ApiReserveCopyEventEntry( f_pApiInstance, + f_pusCopyEntryIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Reserve the source copy event for the first channel. */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, + f_pusCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Reserve the Sin copy event for the first channel. */ + ulTempVar = Oct6100ApiReleaseCopyEventEntry ( f_pApiInstance, + *f_pusCopyEntryIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + } + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteCopyEventCreateStructs + +Description: Performs all the required structure writes to configure the + new copy event + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventCreate Pointer to a create copy event structure. +f_usMixerEventIndex Index of the copy event within the mixer memory. +f_usSourceChanIndex Index of the source channel within the API's channel list. +f_usDestinationChanIndex Index of the destination channel within the API's channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiWriteCopyEventCreateStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate, + IN UINT16 f_usMixerEventIndex, + IN UINT16 f_usSourceChanIndex, + IN UINT16 f_usDestinationChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pSourceEntry; + tPOCT6100_API_CHANNEL pDestinationEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*==============================================================================*/ + /* Get a pointer to the two channel entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSourceEntry, f_usSourceChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pDestinationEntry, f_usDestinationChanIndex ); + + /*==============================================================================*/ + /* Configure the TSST control memory and add the Sin copy event if necessary. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usMixerEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + + if ( f_pCopyEventCreate->ulSourcePort == cOCT6100_CHANNEL_PORT_RIN ) + { + WriteParams.usWriteData |= pSourceEntry->usRinRoutTsiMemIndex; + WriteParams.usWriteData |= pSourceEntry->TdmConfig.byRinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + } + else /* f_pCopyEventCreate->ulSourcePort == cOCT6100_CHANNEL_PORT_SIN */ + { + if ( pSourceEntry->usExtraSinTsiMemIndex != cOCT6100_INVALID_INDEX ) + { + WriteParams.usWriteData |= pSourceEntry->usExtraSinTsiMemIndex; + } + else + { + WriteParams.usWriteData |= pSourceEntry->usSinSoutTsiMemIndex; + } + + WriteParams.usWriteData |= pSourceEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + + if ( f_pCopyEventCreate->ulDestinationPort == cOCT6100_CHANNEL_PORT_RIN ) + { + WriteParams.usWriteData = (UINT16)( pDestinationEntry->usRinRoutTsiMemIndex ); + } + else /* f_pCopyEventCreate->ulDestinationPort == cOCT6100_CHANNEL_PORT_SIN */ + { + WriteParams.usWriteData = (UINT16)( pDestinationEntry->usSinSoutTsiMemIndex ); + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Now insert the event into the event list. */ + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usMixerEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_usDestinationChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Increment the copy event count on this channel. */ + pDestinationEntry->usCopyEventCnt++; + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateCopyEventCreateEntry + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. +f_pCopyEventCreate Pointer to a create copy event structure. +f_usCopyEventIndex Index of the copy event within the API's event list. +f_usMixerEventIndex Index of the copy event within the mixer memory. +f_usSourceChanIndex Index of the source channel within the API's channel list. +f_usDestinationChanIndex Index of the destination channel within the API's channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiUpdateCopyEventCreateEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate, + IN UINT16 f_usCopyEventIndex, + IN UINT16 f_usMixerEventIndex, + IN UINT16 f_usSourceChanIndex, + IN UINT16 f_usDestinationChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_COPY_EVENT pCopyEventEntry; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_COPY_EVENT_ENTRY_PNT( pSharedInfo, pCopyEventEntry, f_usCopyEventIndex ); + + /*=======================================================================*/ + /* Copy the channel's configuration and allocated resources. */ + + /* Save the channel info in the copy event. */ + pCopyEventEntry->usSourceChanIndex = f_usSourceChanIndex; + pCopyEventEntry->bySourcePort = (UINT8)( f_pCopyEventCreate->ulSourcePort & 0xFF ); + + pCopyEventEntry->usDestinationChanIndex = f_usDestinationChanIndex; + pCopyEventEntry->byDestinationPort = (UINT8)( f_pCopyEventCreate->ulDestinationPort & 0xFF ); + + pCopyEventEntry->usMixerEventIndex = f_usMixerEventIndex; + + /*=======================================================================*/ + + /* Form handle returned to user. */ + *f_pCopyEventCreate->pulCopyEventHndl = cOCT6100_HNDL_TAG_COPY_EVENT | (pCopyEventEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_usCopyEventIndex; + + /* Finally, mark the event as used. */ + pCopyEventEntry->fReserved = TRUE; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100MixerCopyEventDestroySer + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventDestroy Pointer to a destroy copy event structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100MixerCopyEventDestroySer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy ) +{ + UINT16 usCopyEventIndex; + UINT16 usMixerEventIndex; + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertCopyEventDestroyParams( f_pApiInstance, + f_pCopyEventDestroy, + &usCopyEventIndex, + &usMixerEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiInvalidateCopyEventStructs( f_pApiInstance, + usCopyEventIndex, + usMixerEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiReleaseCopyEventResources( f_pApiInstance, + usCopyEventIndex, + usMixerEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Invalidate the handle. */ + f_pCopyEventDestroy->ulCopyEventHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertCopyEventDestroyParams + +Description: + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pCopyEventDestroy Pointer to a destroy copy event structure. +f_pusCopyEventIndex Pointer to the index of the copy event in the API. +f_pusMixerEventIndex Pointer to the index of the copy event in the mixer memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiAssertCopyEventDestroyParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy, + IN OUT PUINT16 f_pusCopyEventIndex, + IN OUT PUINT16 f_pusMixerEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_COPY_EVENT pCopyEventEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pCopyEventDestroy->ulCopyEventHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_COPY_EVENT ) + return cOCT6100_ERR_MIXER_COPY_EVENT_HANDLE; + + *f_pusCopyEventIndex = (UINT16)( f_pCopyEventDestroy->ulCopyEventHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusCopyEventIndex >= cOCT6100_MAX_MIXER_EVENTS ) + return cOCT6100_ERR_MIXER_COPY_EVENT_HANDLE; + + /*=======================================================================*/ + + mOCT6100_GET_COPY_EVENT_ENTRY_PNT( pSharedInfo, pCopyEventEntry, *f_pusCopyEventIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pCopyEventDestroy->ulCopyEventHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pCopyEventEntry->fReserved != TRUE ) + return cOCT6100_ERR_MIXER_EVENT_NOT_OPEN; + if ( ulEntryOpenCnt != pCopyEventEntry->byEntryOpenCnt ) + return cOCT6100_ERR_MIXER_COPY_EVENT_HANDLE; + + /*=======================================================================*/ + + /* Return the index of the associated event. */ + *f_pusMixerEventIndex = pCopyEventEntry->usMixerEventIndex; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateCopyEventStructs + +Description: Destroy the link between the two channels. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usCopyEventIndex Index of the copy event in the API. +f_usMixerEventIndex Index of the copy event in the mixer memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiInvalidateCopyEventStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usCopyEventIndex, + IN UINT16 f_usMixerEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*=======================================================================*/ + /* Clear the Copy event. */ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usMixerEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Remove the event from the list. */ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + f_usMixerEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseCopyEventResources + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usCopyEventIndex Index of the copy event in the API. +f_usMixerEventIndex Index of the copy event in the mixer memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiReleaseCopyEventResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usCopyEventIndex, + IN UINT16 f_usMixerEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pDestinationEntry; + tPOCT6100_API_COPY_EVENT pCopyEventEntry; + tPOCT6100_API_MIXER_EVENT pTempEventEntry; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_COPY_EVENT_ENTRY_PNT( pSharedInfo, pCopyEventEntry, f_usCopyEventIndex ); + + ulResult = Oct6100ApiReleaseCopyEventEntry( f_pApiInstance, f_usCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_AC; + + /* Relese the SIN copy event. */ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, f_usMixerEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_B3; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, f_usMixerEventIndex ); + + /* Invalidate the entry. */ + pTempEventEntry->fReserved = FALSE; + pTempEventEntry->usEventType = cOCT6100_INVALID_INDEX; + pTempEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pDestinationEntry, pCopyEventEntry->usDestinationChanIndex ); + + /* Decrement the copy event count on this channel. */ + pDestinationEntry->usCopyEventCnt--; + + /*=======================================================================*/ + + /* Mark the event entry as unused. */ + pCopyEventEntry->fReserved = FALSE; + pCopyEventEntry->byEntryOpenCnt++; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveMixerEventEntry + +Description: Reserves a free entry in the mixer event list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pusEventIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiReserveMixerEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusEventIndex ) +{ + PVOID pMixerEventAlloc; + UINT32 ulResult; + UINT32 ulEventIndex; + + mOCT6100_GET_MIXER_EVENT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pMixerEventAlloc ) + + ulResult = OctapiLlmAllocAlloc( pMixerEventAlloc, &ulEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_MIXER_ALL_MIXER_EVENT_ENTRY_OPENED; + else + return cOCT6100_ERR_FATAL_2B; + } + + *f_pusEventIndex = (UINT16)( ulEventIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseMixerEventEntry + +Description: Release an entry from the mixer event list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usEventIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiReleaseMixerEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex ) +{ + PVOID pMixerEventAlloc; + UINT32 ulResult; + + mOCT6100_GET_MIXER_EVENT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pMixerEventAlloc ) + + ulResult = OctapiLlmAllocDealloc( pMixerEventAlloc, f_usEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_2C; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetFreeMixerEventCnt + +Description: Retrieve the number of events left in the list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pulFreeEventCnt How many events left. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiGetFreeMixerEventCnt( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT32 f_pulFreeEventCnt ) +{ + PVOID pMixerEventAlloc; + UINT32 ulResult; + UINT32 ulAllocatedEvents; + UINT32 ulAvailableEvents; + + mOCT6100_GET_MIXER_EVENT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pMixerEventAlloc ) + + ulResult = OctapiLlmAllocInfo( pMixerEventAlloc, &ulAllocatedEvents, &ulAvailableEvents ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E8; + + /* Return number of free events. */ + *f_pulFreeEventCnt = ulAvailableEvents; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveCopyEventEntry + +Description: Reserves a free entry in the copy event list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pusEventIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiReserveCopyEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusEventIndex ) +{ + PVOID pCopyEventAlloc; + UINT32 ulResult; + UINT32 ulEventIndex; + + mOCT6100_GET_COPY_EVENT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pCopyEventAlloc ) + + ulResult = OctapiLlmAllocAlloc( pCopyEventAlloc, &ulEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_MIXER_ALL_COPY_EVENT_ENTRY_OPENED; + else + return cOCT6100_ERR_FATAL_AD; + } + + *f_pusEventIndex = (UINT16)( ulEventIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseCopyEventEntry + +Description: Release an entry from the copy event list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usEventIndex List entry reserved. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiReleaseCopyEventEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEventIndex ) +{ + PVOID pCopyEventAlloc; + UINT32 ulResult; + + mOCT6100_GET_COPY_EVENT_ALLOC_PNT( f_pApiInstance->pSharedInfo, pCopyEventAlloc ) + + ulResult = OctapiLlmAllocDealloc( pCopyEventAlloc, f_usEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_AE; + + return cOCT6100_ERR_OK; +} -- cgit v1.2.3