blob: 7a75cc8a2c0d22a11be6c1d3ec471b2d59208543 [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0
/*
* Distributed by:
* Silicon Laboratories, Inc
*
* This file contains proprietary information.
* No dissemination allowed without prior written permission from
* Silicon Laboratories, Inc.
*
* File Description:
* This is the generic interface file for the ProSLIC drivers.
*
* Customers should be calling this level for ProSLIC specific
* functions (vs. chipset specific versions of the code)
*
*/
#include "../config_inc/si_voice_datatypes.h"
#include "../inc/si_voice_ctrl.h"
#include "../inc/si_voice_timer_intf.h"
#include "../inc/proslic.h"
#include "../config_inc/proslic_api_config.h"
#ifdef ENABLE_DEBUG
#define LOGPRINT_PREFIX "ProSLIC:"
#endif
#ifdef SI3217X
#include "si3217x.h"
#include "si3217x_intf.h"
extern Si3217x_General_Cfg Si3217x_General_Configuration;
#ifndef DISABLE_FSK_SETUP
extern ProSLIC_FSK_Cfg Si3217x_FSK_Presets[];
#endif
#ifndef DISABLE_TONE_SETUP
extern ProSLIC_Tone_Cfg Si3217x_Tone_Presets[];
#endif
#endif /* 17X */
#ifdef SI3218X
#include "../inc/si3218x.h"
#include "../inc/si3218x_intf.h"
extern Si3218x_General_Cfg Si3218x_General_Configuration;
#ifndef DISABLE_FSK_SETUP
extern ProSLIC_FSK_Cfg Si3218x_FSK_Presets[];
#endif
#ifndef DISABLE_TONE_SETUP
extern ProSLIC_Tone_Cfg Si3218x_Tone_Presets[];
#endif
#endif /* 18X */
#ifdef SI3219X
#include "si3219x.h"
#include "si3219x_intf.h"
extern Si3219x_General_Cfg Si3219x_General_Configuration;
#ifndef DISABLE_FSK_SETUP
extern ProSLIC_FSK_Cfg Si3219x_FSK_Presets[];
#endif
#ifndef DISABLE_TONE_SETUP
extern ProSLIC_Tone_Cfg Si3219x_Tone_Presets[];
#endif
#endif /* 19X */
#ifdef SI3226X
#include "si3226x.h"
#include "si3226x_intf.h"
extern Si3226x_General_Cfg Si3226x_General_Configuration;
#ifndef DISABLE_FSK_SETUP
extern ProSLIC_FSK_Cfg Si3226x_FSK_Presets[];
#endif
#ifndef DISABLE_TONE_SETUP
extern ProSLIC_Tone_Cfg Si3226x_Tone_Presets[];
#endif
#endif /* 26X */
#ifdef SI3228X
#include "si3228x.h"
#include "si3228x_intf.h"
extern Si3228x_General_Cfg Si3228x_General_Configuration;
#ifndef DISABLE_FSK_SETUP
extern ProSLIC_FSK_Cfg Si3228x_FSK_Presets[];
#endif
#ifndef DISABLE_TONE_SETUP
extern ProSLIC_Tone_Cfg Si3228x_Tone_Presets[];
#endif
#endif /* 28X */
#define pCtrl(X) (X)->deviceId->ctrlInterface
#define pProHW(X) pCtrl((X))->hCtrl
#define WriteRAM(PCHAN, CHANNEL, RAMADDR, RAMDATA) (PCHAN)->deviceId->ctrlInterface->WriteRAM_fptr(pProHW(PCHAN), (CHANNEL), (RAMADDR), (RAMDATA))
#define ReadRAM(PCHAN, CHANNEL, RAMADDR) (PCHAN)->deviceId->ctrlInterface->ReadRAM_fptr(pProHW(PCHAN), (CHANNEL), (RAMADDR))
#define SetSemaphore(X) (X)->deviceId->ctrlInterface->Semaphore_fptr
#define ReadReg(PCHAN, CHANNEL, REGADDR) (PCHAN)->deviceId->ctrlInterface->ReadRegister_fptr(pProHW(PCHAN), (CHANNEL), (REGADDR))
#define WriteReg(PCHAN, CHANNEL, REGADDR, REGDATA) (PCHAN)->deviceId->ctrlInterface->WriteRegister_fptr(pProHW(PCHAN), (CHANNEL), (REGADDR), (REGDATA))
/*
** Timers
*/
#define TimeElapsed pProslic->deviceId->ctrlInterface->timeElapsed_fptr
#define getTime pProslic->deviceId->ctrlInterface->getTime_fptr
#define pProTimer pProslic->deviceId->ctrlInterface->hTimer
#define Delay pProslic->deviceId->ctrlInterface->Delay_fptr
#define pProTimerX(X) ((X)->deviceId->ctrlInterface->hTimer)
#define DelayX(X,Y) ((X)->deviceId->ctrlInterface->Delay_fptr(pProTimerX(X),Y))
#define PROSLIC_TIMEOUT_DCDC_DOWN 200 /* Number of 10 mSec ticks */
/*****************************************************************************************************/
int32 ProSLIC_ReadMADCScaled(proslicChanType_ptr hProslic,uInt16 addr,
int32 scale)
{
TRACEPRINT(hProslic,"addr: %u scale: %ld\n", addr, scale);
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return Si3217x_ReadMADCScaled(hProslic,addr,scale);
}
#endif
#ifdef SI3218X
if (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
{
return Si3218x_ReadMADCScaled(hProslic,addr,scale);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(hProslic->deviceId) )
{
return Si3219x_ReadMADCScaled(hProslic,addr,scale);
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return Si3226x_ReadMADCScaled(hProslic,addr,scale);
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
return Si3228x_ReadMADCScaled(hProslic,addr,scale);
}
#endif
return -1;
}
/*****************************************************************************************************/
ramData ProSLIC_ReadRAM(proslicChanType_ptr hProslic,uInt16 addr)
{
TRACEPRINT(hProslic, "addr: %u\n", addr);
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
return (ReadRAM(hProslic, hProslic->channel, addr));
}
/*****************************************************************************************************/
int ProSLIC_WriteRAM(proslicChanType_ptr hProslic,uInt16 addr, ramData data)
{
TRACEPRINT(hProslic, "addr: %u data: 0x%04X\n", addr, data);
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
return (WriteRAM(hProslic, hProslic->channel, addr,data));
}
/*****************************************************************************************************/
int ProSLIC_PrintDebugData(proslicChanType_ptr hProslic)
{
TRACEPRINT(hProslic, "\n", NULL);
#ifdef ENABLE_DEBUG
ProSLIC_PrintDebugReg(hProslic);
return ProSLIC_PrintDebugRAM(hProslic);
#else
SILABS_UNREFERENCED_PARAMETER(hProslic);
return RC_NONE;
#endif
}
/*****************************************************************************************************/
int ProSLIC_PrintDebugReg(proslicChanType_ptr hProslic)
{
#ifdef ENABLE_DEBUG
uInt8 regAddr;
TRACEPRINT(hProslic, "\n", NULL);
/*
NOTE: Not all ProSLICs have defined values after location 99
(and have 1 location after that), but for simplicity, we print them anyway...
*/
for(regAddr = 0; regAddr < 127; regAddr++)
{
LOGPRINT("%sRegister %03u = 0x%02X\n", LOGPRINT_PREFIX, regAddr,
ReadReg(hProslic, hProslic->channel, regAddr));
}
#else
SILABS_UNREFERENCED_PARAMETER(hProslic);
#endif
return RC_NONE;
}
/*****************************************************************************************************/
/* NOTE: locations above 1024 are protected, the API disables protection during initialization, but if this
function is called prior to initialization, then UAM is not set and will impact the ReadRAM call...
Upper limit is based upon chipset type...
*/
int ProSLIC_PrintDebugRAM(proslicChanType_ptr hProslic)
{
#ifdef ENABLE_DEBUG
uInt16 ramAddr;
uInt16 maxAddr= 0;
TRACEPRINT(hProslic, "\n",NULL);
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
maxAddr = 1596;
}
#endif
#ifdef SI3218X
if (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
{
maxAddr = 1644;
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(hProslic->deviceId) )
{
maxAddr = 1644;
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
maxAddr = 1646;
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
maxAddr = 1646;
}
#endif
for(ramAddr = 0; ramAddr < maxAddr; ramAddr++)
{
LOGPRINT("%sRAM %04u = 0x%08X\n", LOGPRINT_PREFIX, ramAddr,
(unsigned int)(ReadRAM(hProslic, hProslic->channel, ramAddr)));
}
#else
SILABS_UNREFERENCED_PARAMETER(hProslic);
#endif /* ENABLE_DEBUG */
return RC_NONE;
}
/*****************************************************************************************************/
/*
** Function: isVerifiedProslic
**
** Description:
** Determine if DAA or ProSLIC present
**
** Input Parameters:
** pProslic: pointer to PROSLIC channel object
**
** Return:
** channelType
*/
int ProSLIC_identifyChannelType(proslicChanType *pProslic)
{
uInt8 data;
TRACEPRINT(pProslic, "\n",NULL);
/*
** Register 13 (DAA) always has bits 0:1 set to 0 and bit 6 set to 1
** Register 13 (PROSLIC) can have bits 0:1, and 4 set, while all others are undefined
** Write 0x13 to Reg 13. The following return values are expected -
**
** 0x00 or 0xFF : No device present
** 0x4X : DAA
** 0x13 : PROSLIC
*/
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMTXHI,0x13);
Delay(pProTimer,5);
/* Now check if the value took */
data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_PCMTXHI);
if( data == 0x13)
{
return PROSLIC;
}
else if (data == 0x40)
{
return DAA;
}
else
{
return UNKNOWN;
}
}
/*****************************************************************************************************/
int ProSLIC_VerifyControlInterface(proslicChanType_ptr hProslic)
{
TRACEPRINT(hProslic, "\n",NULL);
if (ProSLIC_identifyChannelType(hProslic) != PROSLIC)
{
return RC_CHANNEL_TYPE_ERR;
}
/* Note: ProSLIC_identifyChannelType() did a register w/r test earlier */
/* Verify RAM rd/wr with innocuous RAM location */
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VERIFY_IO,0x12345678L);
if (ReadRAM(hProslic,hProslic->channel, PROSLIC_RAM_VERIFY_IO) != 0x12345678L)
{
hProslic->error = RC_SPI_FAIL;
DEBUG_PRINT(hProslic, "%sProslic %d RAM not communicating. RAM access fail.\n",
LOGPRINT_PREFIX, hProslic->channel);
return RC_SPI_FAIL;
}
return RC_NONE;
}
/*****************************************************************************************************/
int ProSLIC_VerifyMasterStat(proslicChanType_ptr pProslic)
{
uInt8 regData;
TRACEPRINT(pProslic, "\n", NULL);
WriteReg(pProslic,pProslic->channel, PROSLIC_REG_MSTRSTAT,
0xFF); /* Clear Master status */
regData = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_MSTRSTAT);
if( regData != 0x1F )
{
return RC_SPI_FAIL;
}
else
{
return RC_NONE;
}
}
/*****************************************************************************************************/
#ifdef SIVOICE_MULTI_BOM_SUPPORT
int ProSLIC_Init_MultiBOM (proslicChanType_ptr *hProslic,int size, int preset)
{
TRACEPRINT(*hProslic, "size: %d preset: %d\n", size, preset);
#ifdef SI3217X
if ((*hProslic)->deviceId->chipType >= SI32171
&& (*hProslic)->deviceId->chipType <= SI32179)
{
return Si3217x_Init_MultiBOM(hProslic,size,preset);
}
#endif
#ifdef SI3218X
if ((*hProslic)->deviceId->chipType >= SI32180
&& (*hProslic)->deviceId->chipType <= SI32189)
{
return Si3218x_Init_MultiBOM(hProslic,size,preset);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X((*hProslic)->deviceId) )
{
return Si3219x_Init_MultiBOM(hProslic,size,preset);
}
#endif
#ifdef SI3226X
if ((*hProslic)->deviceId->chipType >= SI32260
&& (*hProslic)->deviceId->chipType <= SI32269)
{
return Si3226x_Init_MultiBOM(hProslic,size,preset);
}
#endif
#ifdef SI3228X
if ((*hProslic)->deviceId->chipType >= SI32280
&& (*hProslic)->deviceId->chipType <= SI32289)
{
return Si3228x_Init_MultiBOM(hProslic,size,preset);
}
#endif
return RC_COMPLETE_NO_ERR;
}
#endif
/*****************************************************************************************************/
int ProSLIC_Init (proslicChanType_ptr *hProslic,int size)
{
TRACEPRINT(*hProslic, "size: %d\n", size);
return ProSLIC_Init_with_Options(hProslic, size, INIT_NO_OPT);
}
/*****************************************************************************************************/
int ProSLIC_Reinit (proslicChanType_ptr *hProslic,int size)
{
TRACEPRINT(*hProslic, "size: %d\n", size);
return ProSLIC_Init_with_Options(hProslic, size, INIT_REINIT);
}
/*****************************************************************************************************/
int ProSLIC_Init_with_Options (proslicChanType_ptr *hProslic,int size,
int option)
{
TRACEPRINT(*hProslic, "size: %d option: %d\n", size, option);
#ifdef SI3226X
if ((*hProslic)->deviceId->chipType >= SI32260
&& (*hProslic)->deviceId->chipType <= SI32269)
{
return Si3226x_Init_with_Options(hProslic,size, option);
}
#endif
#ifdef SI3228X
if ((*hProslic)->deviceId->chipType >= SI32280
&& (*hProslic)->deviceId->chipType <= SI32289)
{
return Si3228x_Init_with_Options(hProslic,size, option);
}
#endif
#ifdef SI3217X
if ((*hProslic)->deviceId->chipType >= SI32171
&& (*hProslic)->deviceId->chipType <= SI32179)
{
return Si3217x_Init_with_Options(hProslic,size, option);
}
#endif
#ifdef SI3218X
if ((*hProslic)->deviceId->chipType >= SI32180
&& (*hProslic)->deviceId->chipType <= SI32189)
{
return Si3218x_Init_with_Options(hProslic,size, option);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X((*hProslic)->deviceId) )
{
return Si3219x_Init_with_Options(hProslic,size, option);
}
#endif
return RC_IGNORE;
}
/*****************************************************************************************************/
#if defined(SI3217X) || defined(SI3218X) || defined SI3226X || defined SI3228X || defined(SI3219X)
/* Check patch data - returns TRUE if no error.*/
static BOOLEAN ProSLIC_VerifyPatchData(proslicChanType *pProslic,
const ramData *data, uInt16 maxCount )
{
int loop;
ramData read_data;
TRACEPRINT(pProslic, "dataptr: %p, count: %d\n", data, maxCount);
for(loop = 0; loop < maxCount; loop++)
{
if(*data)
{
read_data = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_PRAM_DATA);
if( ((*data) << 9) != read_data)
{
return FALSE;
}
}
else
{
break;
}
data++;
}
return TRUE;
}
/* Check if the jump table is written correctly.. */
static BOOLEAN ProSLIC_VerifyPatchJMPLow(proslicChanType *pProslic,
const uInt16 *data)
{
uInt8 address = PATCH_JMPTBL_START_ADDR;
int regData;
TRACEPRINT(pProslic, "dataptr: %p\n", data);
for(address = PATCH_JMPTBL_START_ADDR;
address < (PATCH_JMPTBL_START_ADDR+(2*PATCH_NUM_LOW_ENTRIES)); address++)
{
if(*data)
{
regData = ReadReg(pProslic, pProslic->channel, address);
if(regData != ((*data) & 0xFF))
{
return FALSE;
}
address++;
regData = ReadReg(pProslic, pProslic->channel, address);
if(regData != (((*data)>>8) & 0xFF))
{
return FALSE;
}
data++;
}
else
{
break;
}
}
return TRUE;
}
#if defined SI3226X || defined SI3228X || defined SI3218X || defined SI3219X
/* For chipsets supporting more than 8 jump entries, verify them */
static BOOLEAN ProSLIC_VerifyPatchJMPHigh(proslicChanType *pProslic,
const uInt16 *data)
{
uInt16 address = PATCH_JMPTBL_HIGH_ADDR;
ramData read_data;
TRACEPRINT(pProslic, "dataptr: %p\n", data);
for(address = PATCH_JMPTBL_HIGH_ADDR;
address < (PATCH_JMPTBL_HIGH_ADDR+PATCH_NUM_HIGH_ENTRIES); address++)
{
read_data = (ReadRAM(pProslic, pProslic->channel, address) & 0x1FFFL);
if(*data != read_data)
{
return FALSE;
}
data++;
}
return TRUE;
}
#endif /* SI3226X, SI3228X, SI3218X, SI3219X */
static BOOLEAN ProSLIC_VerifyPatchSupportRAM(proslicChanType *pProslic,
const uInt16 *ramAddr, const ramData *ramData)
{
int i;
for(i = 0; ramAddr[i]; i++)
{
if( ReadRAM(pProslic, pProslic->channel, ramAddr[i]) != ramData[i])
{
return FALSE;
}
}
return TRUE;
}
/* Load the first 8 jump table entries */
static void ProSLIC_LoadPatchJMPLow(proslicChanType *pProslic, uInt8 channel,
const uInt16 *data)
{
uInt8 address;
TRACEPRINT(pProslic, "chan: %d dataptr: %p\n", channel, data);
for(address = PATCH_JMPTBL_START_ADDR;
address < (PATCH_JMPTBL_START_ADDR+(2*PATCH_NUM_LOW_ENTRIES)); address++)
{
WriteReg(pProslic, channel, address,((*data) & 0xFF));
address++;
WriteReg(pProslic, channel, address,(((*data)>>8) & 0xFF));
data++;
}
}
/* Load Patch data */
static void ProSLIC_LoadPatchData(proslicChanType *pProslic, uInt8 channel,
const ramData *data)
{
int loop;
TRACEPRINT(pProslic, "chan: %d dataptr: %p\n", channel, data);
WriteRAM(pProslic, channel, PROSLIC_RAM_PRAM_ADDR, 0);
for(loop = 0; loop < PATCH_MAX_SIZE; loop++)
{
if(*data)
{
/* Can we take advantage of auto increment, if not, set the address */
if( (pProslic->deviceId->chipRev < 3)
&& (channel == PROSLIC_CHAN_BROADCAST))
{
WriteRAM(pProslic, channel, PROSLIC_RAM_PRAM_ADDR, loop << 19);
}
WriteRAM(pProslic, channel, PROSLIC_RAM_PRAM_DATA, (*data) << 9);
}
else
{
return;
}
data++;
}
}
/* Load Support RAM - basically RAM address/data pairs to be written as part of the Patch process - do not call directly */
void ProSLIC_LoadSupportRAM(proslicChanType *pProslic, uInt8 channel,
const uInt16 *address, const ramData *data)
{
TRACEPRINT(pProslic, "chan: %d addressptr: %p dataptr: %p\n", channel, address,
data);
while( *address )
{
WriteRAM(pProslic, channel, *address, *data);
address++;
data++;
}
}
#if defined SI3226X || defined SI3228X || defined SI3218X || defined SI3219X
/* Load Jump table high for chipsets supporting more than 8 jump entries */
static void ProSLIC_LoadJMPHigh(proslicChanType *pProslic, uInt8 channel,
const uInt16 *data)
{
uInt16 loop;
TRACEPRINT(pProslic, "chan: %d dataptr: %p\n", channel, data);
for(loop = PATCH_JMPTBL_HIGH_ADDR;
loop < (PATCH_JMPTBL_HIGH_ADDR+PATCH_NUM_HIGH_ENTRIES); loop++)
{
WriteRAM(pProslic, channel, loop, ((*data) & 0x1FFFL) );
data++;
}
}
#endif /* SI3226X, SI3228X, SI3218X, SI3219X */
/* Code assumes ProSLIC_LoadPatch has verified chip type. This is NOT meant to be called
* by the user directly.
*/
BOOLEAN ProSLIC_LoadPatch_extended(proslicChanType *pProslic,
const proslicPatch *pPatch,
BOOLEAN is_broadcast, BOOLEAN is_second_chan)
{
uInt8 channel;
const uInt16 jmp_disable[PATCH_NUM_LOW_ENTRIES] = {0,0,0,0,0,0,0,0};
#if defined SI3226X || defined SI3228X || defined SI3218X ||defined SI3219X
BOOLEAN hasJmpTableHigh = FALSE;
const uInt16 jmphigh_disable[PATCH_NUM_HIGH_ENTRIES] = {0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL};
#endif
TRACEPRINT(pProslic, "patchptr: %p bcast: %d\n", pPatch, is_broadcast);
if(pPatch == NULL)
{
return RC_NONE;
}
if(is_broadcast == TRUE)
{
channel = PROSLIC_CHAN_BROADCAST;
}
else
{
channel = pProslic->channel;
}
ProSLIC_SetUserMode(pProslic,TRUE, is_broadcast);
/* Disable Patch */
WriteReg(pProslic, channel, PROSLIC_REG_JMPEN, 0);
if(is_second_chan == FALSE)
{
DEBUG_PRINT(pProslic, "%sloading patch: %08lx\n", LOGPRINT_PREFIX,
(long unsigned int)pPatch->patchSerial);
ProSLIC_LoadPatchJMPLow(pProslic, channel, jmp_disable);
#if defined SI3226X || defined SI3228X || defined SI3218X || defined SI3219X
if( 0
#ifdef SI3226X
|| (pProslic->deviceId->chipType >= SI32260
&& pProslic->deviceId->chipType <= SI32269)
#endif
#ifdef SI3228X
|| (pProslic->deviceId->chipType >= SI32280
&& pProslic->deviceId->chipType <= SI32289)
#endif
#ifdef SI3218X
|| (pProslic->deviceId->chipType >= SI32180
&& pProslic->deviceId->chipType <= SI32189)
#endif
#ifdef SI3219X
|| ( IS_SI3219X(pProslic->deviceId) )
#endif
)
{
hasJmpTableHigh = TRUE;
ProSLIC_LoadJMPHigh(pProslic, channel, jmphigh_disable);
}
#endif
ProSLIC_LoadPatchData(pProslic, channel, pPatch->patchData);
WriteReg(pProslic, channel, PROSLIC_REG_RAM_ADDR_HI, 0);
ProSLIC_LoadPatchJMPLow(pProslic, channel, pPatch->patchEntries);
#if defined SI3226X || defined SI3228X || defined SI3218X || defined SI3219X
if(hasJmpTableHigh == TRUE)
{
ProSLIC_LoadJMPHigh(pProslic, channel,
&(pPatch->patchEntries[PATCH_NUM_LOW_ENTRIES]));
}
#endif
WriteRAM(pProslic, channel, PROSLIC_RAM_PATCHID,
pPatch->patchSerial); /* write the patch ID */
} /* !second channel */
ProSLIC_LoadSupportRAM(pProslic, channel, pPatch->psRamAddr, pPatch->psRamData);
return RC_NONE;
}
#endif /* patch helper functions */
int ProSLIC_LoadPatch (proslicChanType_ptr pProslic,const proslicPatch *pPatch)
{
int rc;
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
if( (rc = ProSLIC_LoadPatch_extended(pProslic, pPatch, FALSE, FALSE) ) == RC_NONE)
{
#ifdef DISABLE_VERIFY_PATCH
return WriteReg(pProslic, pProslic->channel, PROSLIC_REG_JMPEN, 1);
#endif
}
return rc;
}
/*****************************************************************************************************/
int ProSLIC_VerifyPatch (proslicChanType_ptr hProslic,const proslicPatch *pPatch)
{
TRACEPRINT(hProslic, "patchptr: %p\n", pPatch);
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
if(pPatch == NULL)
{
return RC_NONE;
}
WriteReg(hProslic, hProslic->channel, PROSLIC_REG_JMPEN, 0);
WriteRAM(hProslic, hProslic->channel, PROSLIC_RAM_PRAM_ADDR, 0);
if(ProSLIC_VerifyPatchData(hProslic, pPatch->patchData,
PATCH_MAX_SIZE) == FALSE)
{
DEBUG_PRINT(hProslic, "%sPatch data corrupted: channel %d\n",LOGPRINT_PREFIX,
hProslic->channel);
WriteRAM(hProslic, hProslic->channel, PROSLIC_RAM_PATCHID,
0UL); /* Mark patch as invalid */
return RC_PATCH_RAM_VERIFY_FAIL;
}
/*zero out RAM_ADDR_HI*/
WriteReg (hProslic, hProslic->channel, PROSLIC_REG_RAM_ADDR_HI,0);
if( ProSLIC_VerifyPatchJMPLow(hProslic, pPatch->patchEntries) == FALSE)
{
DEBUG_PRINT(hProslic,"%sPatch jumptable corrupted: channel %d\n",
LOGPRINT_PREFIX,hProslic->channel);
WriteRAM(hProslic, hProslic->channel, PROSLIC_RAM_PATCHID,
0UL); /* Mark patch as invalid */
return RC_PATCH_RAM_VERIFY_FAIL;
}
#if defined SI3226X || defined SI3228X || defined SI3218X || defined SI3219X
if( 0
#ifdef SI3226X
|| (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
#endif
#ifdef SI3228X
|| (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
#endif
#ifdef SI3218X
|| (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
#endif
#ifdef SI3219X
|| ( IS_SI3219X(hProslic->deviceId) )
#endif
)
{
if( ProSLIC_VerifyPatchJMPHigh(hProslic,
&(pPatch->patchEntries[PATCH_NUM_LOW_ENTRIES])) == FALSE)
{
DEBUG_PRINT(hProslic,"%sPatch jumptable high corrupted: channel %d\n",
LOGPRINT_PREFIX,hProslic->channel);
WriteRAM(hProslic, hProslic->channel, PROSLIC_RAM_PATCHID,
0UL); /* Mark patch as invalid */
return RC_PATCH_ENTRY_VERIFY_FAIL;
}
}
#endif
if( ProSLIC_VerifyPatchSupportRAM( hProslic, pPatch->psRamAddr, pPatch->psRamData) == FALSE)
{
DEBUG_PRINT(hProslic,"%sPatch init data corrupted: channel %d\n",
LOGPRINT_PREFIX,hProslic->channel);
WriteRAM(hProslic, hProslic->channel, PROSLIC_RAM_PATCHID,
0UL); /* Mark patch as invalid */
return RC_PATCH_ENTRY_VERIFY_FAIL;
}
WriteReg (hProslic, hProslic->channel, PROSLIC_REG_JMPEN,
1); /*enable the patch*/
return RC_NONE;
}
/*****************************************************************************************************/
int ProSLIC_SetMuteStatus (proslicChanType_ptr pProslic,
ProslicMuteModes muteEn)
{
uInt8 regTemp;
uInt8 newRegValue;
TRACEPRINT(pProslic, "muteEn: %d\n", muteEn);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
regTemp = ReadReg (pProslic,pProslic->channel,PROSLIC_REG_DIGCON);
WriteReg (pProslic,pProslic->channel,PROSLIC_REG_DIGCON,regTemp&~(0x3));
newRegValue = regTemp &~(0x3);
if (muteEn & PROSLIC_MUTE_RX)
{
newRegValue |= 1;
}
if (muteEn & PROSLIC_MUTE_TX)
{
newRegValue |= 2;
}
if(newRegValue != regTemp)
{
return WriteReg (pProslic,pProslic->channel,PROSLIC_REG_DIGCON,newRegValue);
}
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_SetLoopbackMode (proslicChanType_ptr pProslic,
ProslicLoopbackModes newMode)
{
uInt8 regTemp, newValue;
TRACEPRINT(pProslic, "mode: %d\n", newMode);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
newValue = regTemp = ReadReg (pProslic,pProslic->channel,PROSLIC_REG_LOOPBACK);
switch (newMode)
{
case PROSLIC_LOOPBACK_NONE:
newValue &= ~(0x11);
break;
case PROSLIC_LOOPBACK_DIG:
newValue |= 1;
break;
case PROSLIC_LOOPBACK_ANA:
newValue |= 0x10;
break;
}
if(newValue != regTemp)
{
return WriteReg (pProslic,pProslic->channel,PROSLIC_REG_LOOPBACK, newValue);
}
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_EnableInterrupts (proslicChanType_ptr hProslic)
{
TRACEPRINT(hProslic, "\n", NULL);
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return Si3217x_EnableInterrupts(hProslic);
}
#endif
#ifdef SI3218X
if (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
{
return Si3218x_EnableInterrupts(hProslic);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(hProslic->deviceId) )
{
return Si3219x_EnableInterrupts(hProslic);
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return Si3226x_EnableInterrupts(hProslic);
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
return Si3228x_EnableInterrupts(hProslic);
}
#endif
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_DisableInterrupts (proslicChanType_ptr hProslic)
{
#ifdef GCI_MODE
uInt8 data;
#endif
uInt8 i;
TRACEPRINT(hProslic, "\n", NULL);
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
for(i = PROSLIC_REG_IRQEN1; i < PROSLIC_REG_IRQEN4; i++)
{
/* Disable the interrupts */
WriteReg(hProslic, hProslic->channel, i, 0);
}
/* Clear the pending interrupts */
for(i = PROSLIC_REG_IRQ1; i < PROSLIC_REG_IRQ4; i++)
{
#ifdef GCI_MODE
data = ReadReg(hProslic, hProslic->channel, i);
WriteReg( hProslic, hProslic->channel, i, data);
#else
(void)ReadReg(hProslic, hProslic->channel, i);
#endif
}
return RC_NONE;
}
/*****************************************************************************************************/
int ProSLIC_RingSetup (proslicChanType_ptr hProslic,int preset)
{
TRACEPRINT(hProslic, "preset: %d\n", preset);
#ifndef DISABLE_RING_SETUP
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return Si3217x_RingSetup(hProslic,preset);
}
#endif
#ifdef SI3218X
if (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
{
return Si3218x_RingSetup(hProslic,preset);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(hProslic->deviceId) )
{
return Si3219x_RingSetup(hProslic,preset);
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return Si3226x_RingSetup(hProslic,preset);
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
return Si3228x_RingSetup(hProslic,preset);
}
#endif
#else
SILABS_UNREFERENCED_PARAMETER(hProslic);
SILABS_UNREFERENCED_PARAMETER(preset);
#endif /*DISABLE_RING_SETUP*/
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_ToneGenSetup (proslicChanType_ptr hProslic,int preset)
{
TRACEPRINT(hProslic, "preset: %d\n", preset);
#ifndef DISABLE_TONE_SETUP
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return ProSLIC_ToneGenSetupPtr(hProslic,&(Si3217x_Tone_Presets[preset]));
}
#endif
#ifdef SI3218X
if (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
{
return ProSLIC_ToneGenSetupPtr(hProslic, &(Si3218x_Tone_Presets[preset]));
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(hProslic->deviceId) )
{
return ProSLIC_ToneGenSetupPtr(hProslic, &(Si3219x_Tone_Presets[preset]));
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return ProSLIC_ToneGenSetupPtr(hProslic, &(Si3226x_Tone_Presets[preset]));
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
return ProSLIC_ToneGenSetupPtr(hProslic, &(Si3228x_Tone_Presets[preset]));
}
#endif
#else
SILABS_UNREFERENCED_PARAMETER(hProslic);
SILABS_UNREFERENCED_PARAMETER(preset);
#endif /*DISABLE_TONE_SETUP*/
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_FSKSetup (proslicChanType_ptr hProslic,int preset)
{
TRACEPRINT(hProslic, "preset: %d\n", preset);
#ifndef DISABLE_FSK_SETUP
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return ProSLIC_FSKSetupPtr(hProslic, &Si3217x_FSK_Presets[preset]);
}
#endif
#ifdef SI3218X
if (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
{
return ProSLIC_FSKSetupPtr(hProslic, &Si3218x_FSK_Presets[preset]);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(hProslic->deviceId) )
{
return ProSLIC_FSKSetupPtr(hProslic, &Si3219x_FSK_Presets[preset]);
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return ProSLIC_FSKSetupPtr(hProslic, &Si3226x_FSK_Presets[preset]);
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
return ProSLIC_FSKSetupPtr(hProslic,&Si3228x_FSK_Presets[preset]);
}
#endif
#else
SILABS_UNREFERENCED_PARAMETER(hProslic);
SILABS_UNREFERENCED_PARAMETER(preset);
#endif /*DISABLE_FSK_SETUP*/
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_ZsynthSetup (proslicChanType_ptr hProslic,int preset)
{
TRACEPRINT(hProslic, "preset: %d\n", preset);
#ifndef DISABLE_ZSYNTH_SETUP
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return Si3217x_ZsynthSetup(hProslic,preset);
}
#endif
#ifdef SI3218X
if (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
{
return Si3218x_ZsynthSetup(hProslic,preset);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(hProslic->deviceId) )
{
return Si3219x_ZsynthSetup(hProslic,preset);
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return Si3226x_ZsynthSetup(hProslic,preset);
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
return Si3228x_ZsynthSetup(hProslic,preset);
}
#endif
#else
SILABS_UNREFERENCED_PARAMETER(hProslic);
SILABS_UNREFERENCED_PARAMETER(preset);
#endif /*DISABLE_ZSYNTH_SETUP*/
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
#ifndef DISABLE_CI_SETUP
int ProSLIC_GciCISetup (proslicChanType_ptr hProslic,int preset)
{
TRACEPRINT(hProslic, "preset: %d\n", preset);
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return Si3217x_GciCISetup(hProslic,preset);
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return Si3226x_GciCISetup(hProslic,preset);
}
#endif
#if !defined(SI3217X) && !defined(SI3226X)
SILABS_UNREFERENCED_PARAMETER(hProslic);
SILABS_UNREFERENCED_PARAMETER(preset);
#endif
return RC_COMPLETE_NO_ERR;
}
#endif /*DISABLE_CI_SETUP*/
/*****************************************************************************************************/
int ProSLIC_TXAudioGainSetup (proslicChanType_ptr hProslic,int preset)
{
TRACEPRINT(hProslic, "preset: %d\n", preset);
#ifndef DISABLE_AUDIOGAIN_SETUP
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return Si3217x_TXAudioGainSetup(hProslic,preset);
}
#endif
#ifdef SI3218X
if (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
{
return Si3218x_TXAudioGainSetup(hProslic,preset);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(hProslic->deviceId) )
{
return Si3219x_TXAudioGainSetup(hProslic,preset);
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return Si3226x_TXAudioGainSetup(hProslic,preset);
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
return Si3228x_TXAudioGainSetup(hProslic,preset);
}
#endif
#else
SILABS_UNREFERENCED_PARAMETER(hProslic);
SILABS_UNREFERENCED_PARAMETER(preset);
#endif /*DISABLE_AUDIOGAIN_SETUP*/
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_RXAudioGainSetup (proslicChanType_ptr hProslic,int preset)
{
TRACEPRINT(hProslic, "preset: %d\n", preset);
#ifndef DISABLE_AUDIOGAIN_SETUP
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return Si3217x_RXAudioGainSetup(hProslic,preset);
}
#endif
#ifdef SI3218X
if (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
{
return Si3218x_RXAudioGainSetup(hProslic,preset);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(hProslic->deviceId) )
{
return Si3219x_RXAudioGainSetup(hProslic,preset);
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return Si3226x_RXAudioGainSetup(hProslic,preset);
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
return Si3228x_RXAudioGainSetup(hProslic,preset);
}
#endif
#else
SILABS_UNREFERENCED_PARAMETER(hProslic);
SILABS_UNREFERENCED_PARAMETER(preset);
#endif /*DISABLE_AUDIOGAIN_SETUP*/
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_TXAudioGainScale (proslicChanType_ptr hProslic,int preset,
uInt32 pga_scale, uInt32 eq_scale)
{
TRACEPRINT(hProslic, "preset: %d pga_scale: %u eq_scale: %u\n", preset,
pga_scale, eq_scale);
#ifndef DISABLE_AUDIOGAIN_SETUP
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return Si3217x_TXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
}
#endif
#ifdef SI3218X
if (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
{
return Si3218x_TXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(hProslic->deviceId) )
{
return Si3219x_TXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return Si3226x_TXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
return Si3228x_TXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
}
#endif
#else
SILABS_UNREFERENCED_PARAMETER(hProslic);
SILABS_UNREFERENCED_PARAMETER(preset);
#endif /*DISABLE_AUDIOGAIN_SETUP*/
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_RXAudioGainScale (proslicChanType_ptr hProslic,int preset,
uInt32 pga_scale, uInt32 eq_scale)
{
TRACEPRINT(hProslic, "preset: %d pga_scale: %u eq_scale: %u\n", preset,
pga_scale, eq_scale);
#ifndef DISABLE_AUDIOGAIN_SETUP
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return Si3217x_RXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
}
#endif
#ifdef SI3218X
if (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
{
return Si3218x_RXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(hProslic->deviceId) )
{
return Si3219x_RXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return Si3226x_RXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
return Si3228x_RXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
}
#endif
#else
SILABS_UNREFERENCED_PARAMETER(hProslic);
SILABS_UNREFERENCED_PARAMETER(preset);
#endif /*DISABLE_AUDIOGAIN_SETUP*/
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_AudioGainSetup (proslicChanType_ptr pProslic,int32 rxgain,
int32 txgain,int preset)
{
int rc;
#ifndef DISABLE_AUDIOGAIN_SETUP
int atx_preset = TXACGAIN_SEL;
int arx_preset = RXACGAIN_SEL;
TRACEPRINT(pProslic, "rxgain: %d txgain: %d preset: %d\n", rxgain, txgain,
preset);
rc = ProSLIC_dbgSetTXGain(pProslic,txgain,preset,atx_preset);
if( rc == RC_NONE)
{
rc = ProSLIC_TXAudioGainSetup(pProslic,TXACGAIN_SEL);
}
if( rc == RC_NONE)
{
rc = ProSLIC_dbgSetRXGain(pProslic,rxgain,preset,arx_preset);
}
if( rc == RC_NONE)
{
rc = ProSLIC_RXAudioGainSetup(pProslic,RXACGAIN_SEL);
}
return rc;
#else
SILABS_UNREFERENCED_PARAMETER(pProslic);
SILABS_UNREFERENCED_PARAMETER(preset);
return RC_IGNORE;
#endif /*DISABLE_AUDIOGAIN_SETUP*/
}
/*****************************************************************************************************/
int ProSLIC_DCFeedSetup (proslicChanType_ptr hProslic,int preset)
{
TRACEPRINT(hProslic, "preset: %d\n", preset);
#ifndef DISABLE_DCFEED_SETUP
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return Si3217x_DCFeedSetup(hProslic,preset);
}
#endif
#ifdef SI3218X
if (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
{
return Si3218x_DCFeedSetup(hProslic,preset);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(hProslic->deviceId) )
{
return Si3219x_DCFeedSetupCfg(hProslic, Si3219x_DCfeed_Presets, preset);
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return Si3226x_DCFeedSetup(hProslic,preset);
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
return Si3228x_DCFeedSetup(hProslic,preset);
}
#endif
#else
SILABS_UNREFERENCED_PARAMETER(hProslic);
SILABS_UNREFERENCED_PARAMETER(preset);
#endif /*DISABLE_DCFEED_SETUP*/
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_DCFeedSetupCfg (proslicChanType_ptr hProslic,
ProSLIC_DCfeed_Cfg *cfg, int preset)
{
TRACEPRINT(hProslic, "cfgPtr = %p preset = %d\n", cfg, preset);
#ifndef DISABLE_DCFEED_SETUP
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return Si3217x_DCFeedSetupCfg(hProslic,cfg,preset);
}
#endif
#ifdef SI3218X
if (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
{
return Si3218x_DCFeedSetupCfg(hProslic,cfg,preset);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(hProslic->deviceId) )
{
return Si3219x_DCFeedSetupCfg(hProslic,cfg,preset);
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return Si3226x_DCFeedSetupCfg(hProslic,cfg,preset);
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
return Si3228x_DCFeedSetupCfg(hProslic,cfg,preset);
}
#endif
#else
SILABS_UNREFERENCED_PARAMETER(hProslic);
SILABS_UNREFERENCED_PARAMETER(preset);
SILABS_UNREFERENCED_PARAMETER(cfg);
#endif /*DISABLE_DCFEED_SETUP*/
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_GPIOSetup (proslicChanType_ptr hProslic)
{
TRACEPRINT(hProslic, "\n", NULL);
#ifndef DISABLE_GPIO_SETUP
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return Si3217x_GPIOSetup(hProslic);
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return Si3226x_GPIOSetup(hProslic);
}
#endif
#else
SILABS_UNREFERENCED_PARAMETER(hProslic);
#endif /*DISABLE_GPIO_SETUP*/
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
#ifndef DISABLE_PULSEMETERING
int ProSLIC_PulseMeterSetup (proslicChanType_ptr hProslic,int preset)
{
TRACEPRINT(hProslic, "preset = %d\n", preset);
#ifndef DISABLE_PULSE_SETUP
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return Si3217x_PulseMeterSetup(hProslic,preset);
}
#endif
#ifdef SI3218X
if (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
{
return Si3218x_PulseMeterSetup(hProslic,preset);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(hProslic->deviceId) )
{
return Si3219x_PulseMeterSetup(hProslic,preset);
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return Si3226x_PulseMeterSetup(hProslic,preset);
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
return Si3228x_PulseMeterSetup(hProslic,preset);
}
#endif
#else
SILABS_UNREFERENCED_PARAMETER(hProslic);
SILABS_UNREFERENCED_PARAMETER(preset);
#endif /*DISABLE_PULSE_SETUP*/
return RC_COMPLETE_NO_ERR;
}
#endif
/*****************************************************************************************************/
int ProSLIC_PCMSetup (proslicChanType_ptr hProslic,int preset)
{
TRACEPRINT(hProslic, "preset = %d\n", preset);
#ifndef DISABLE_PCM_SETUP
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return Si3217x_PCMSetup(hProslic,preset);
}
#endif
#ifdef SI3218X
if (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
{
return Si3218x_PCMSetup(hProslic,preset);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(hProslic->deviceId) )
{
return Si3219x_PCMSetup(hProslic,preset);
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return Si3226x_PCMSetup(hProslic,preset);
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
return Si3228x_PCMSetup(hProslic,preset);
}
#endif
#else
SILABS_UNREFERENCED_PARAMETER(hProslic);
SILABS_UNREFERENCED_PARAMETER(preset);
#endif /*DISABLE_PCM_SETUP*/
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_PCMTimeSlotSetup (proslicChanType_ptr pProslic, uInt16 rxcount,
uInt16 txcount)
{
uInt8 data;
TRACEPRINT(pProslic, "rx = %u tx = %u\n", rxcount, txcount);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
data = txcount & 0xff;
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMTXLO,data);
data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_PCMTXHI);
data &= 0x10; /* keep TX_EDGE bit */
data |= ((txcount >> 8)&0x03) ;
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMTXHI,data);
data = rxcount & 0xff;
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMRXLO,data);
data = (rxcount >> 8) & 0x3; /* PCMRXHI has only 2 bits for timeslot */
/* add to the calculated timeslot values the non timeslot bits */
data |= (ReadReg(pProslic,pProslic->channel,PROSLIC_REG_PCMRXHI) & 0xFC);
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMRXHI,data);
return RC_NONE;
}
/*****************************************************************************************************/
typedef ProslicInt proslicIntTypeMap[SI_MAX_INTERRUPTS][8];
static int ProSLIC_ReadInterruptsHelper(proslicChanType_ptr pProslic,
uInt8 *regData, uInt8 numChannels)
{
uInt8 i;
uInt8 intsActive;
uInt8 *currentData = regData;
SILABS_UNREFERENCED_PARAMETER(numChannels);
intsActive = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_IRQ0);
#ifdef PROSLIC_OPTIMIZE_INTERRUPTS
/* For dual channel devices, we need to shift the upper nibble for the second channel
if the caller requested the second channel. We determine this by channel ID being
even or odd. If this is NOT true - for example a Si3217x and then a Si3226x chipset
configuration on the same daisychain, then this optimization logic will not work */
#if defined(SI3226X) || defined(SI3228X)
if( (numChannels != 0) && ((pProslic->channel) & 0x1))
{
intsActive = intsActive >> 4;
}
#endif /* Multichannel devices */
#endif
/* If there are no interrupts, stop... return back to calling function */
if((intsActive &0xF) == 0)
{
return RC_IGNORE;
}
for(i = PROSLIC_REG_IRQ1; i <= PROSLIC_REG_IRQ4; i++)
{
#ifdef PROSLIC_OPTIMIZE_INTERRUPTS
/* Read IRQn Register only if IRQ0 states there was an interrupt pending, otherwise
skip it. This eliminates unneeded SPI transactions.
*/
if( (intsActive & (1<<(i-PROSLIC_REG_IRQ1))) == 0)
{
*currentData++ = 0;
continue;
}
#endif
*currentData = (uInt8)ReadReg(pProslic, pProslic->channel, i);
#ifdef GCI_MODDE
WriteReg(pProslic, pProslic->channel, i, *current_data);
#endif
currentData++;
} /* for loop */
return RC_COMPLETE_NO_ERR;
}
/*
Reads IRQ0 to determine if an interrupt has occurred for the particular device,
if so, reads the interrupt register(s) that fired the interrupt and then
maps the interrupt(s) to the generic interrupt value to return to the caller.
Code assumes normal chipset/compatibility testing has already been done.
*/
static int ProSLIC_GetInterruptHelper(proslicChanType_ptr pProslic,
const proslicIntTypeMap intMap, proslicIntType *pIntData, uInt8 numChannels)
{
int i,j;
uInt8 intData[SI_MAX_INTERRUPTS];
uInt8 *currentData;
uInt8 map, intCount;
BOOLEAN safetyInt = FALSE;
/* Initialize interrupt count to 0 */
pIntData-> number = 0;
if( ProSLIC_ReadInterruptsHelper(pProslic, intData, numChannels) == RC_IGNORE)
{
/* No interrupts for the given channel. */
return RC_NONE;
}
/* At this point we've collected all the registers, now decode the data */
currentData = intData;
intCount = 0;
for(i = 0; i < SI_MAX_INTERRUPTS; i++)
{
if(*currentData)
{
for(j = 0; j < 8; j++)
{
if( *currentData & (1<<j) )
{
map = intMap[i][j];
pIntData->irqs[intCount] = map;
if( (map == IRQ_P_HVIC)
|| (map == IRQ_P_THERM) )
{
safetyInt = TRUE;
}
intCount++;
}
}
}
currentData++;
}
pIntData->number = intCount;
if( safetyInt == TRUE)
{
if(ProSLIC_isReinitRequired(pProslic))
{
return RC_REINIT_REQUIRED;
}
}
return pIntData->number;
}
int ProSLIC_GetInterrupts (proslicChanType_ptr hProslic,
proslicIntType *pIntData)
{
const proslicIntTypeMap interruptMap =
{
{IRQ_OSC1_T1, IRQ_OSC1_T2, IRQ_OSC2_T1, IRQ_OSC2_T2, IRQ_RING_T1, IRQ_RING_T2, IRQ_FSKBUF_AVAIL, IRQ_VBAT},
{IRQ_RING_TRIP, IRQ_LOOP_STATUS, IRQ_LONG_STAT, IRQ_VOC_TRACK, IRQ_DTMF, IRQ_INDIRECT, IRQ_RXMDM, IRQ_TXMDM},
{IRQ_P_HVIC, IRQ_P_THERM, IRQ_PQ3, IRQ_PQ4, IRQ_PQ5, IRQ_PQ6, IRQ_DSP, IRQ_MADC_FS},
{IRQ_USER_0, IRQ_USER_1, IRQ_USER_2, IRQ_USER_3, IRQ_USER_4, IRQ_USER_5, IRQ_USER_6, IRQ_USER_7}
};
pIntData->number=0;
/* TRACEPRINT(hProslic, "\n", NULL); */
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#if defined (SI3217X) || defined (SI3218X) || defined(SI3219X)
if (0
#ifdef SI3217X
|| (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
#endif
#ifdef SI3218X
|| (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
#endif
#ifdef SI3219X
|| ( IS_SI3219X(hProslic->deviceId) )
#endif
)
{
return ProSLIC_GetInterruptHelper(hProslic, interruptMap, pIntData, 1);
}
#endif
#if defined (SI3226X) || defined (SI3228X)
if( 0
#ifdef SI3226X
|| (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
#endif
#ifdef SI3228X
|| (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
#endif
)
{
return ProSLIC_GetInterruptHelper(hProslic, interruptMap, pIntData, 2);
}
#endif
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_ReadHookStatus (proslicChanType_ptr pProslic,uInt8 *pHookStat)
{
TRACEPRINT(pProslic, "\n", NULL);
*pHookStat = PROSLIC_ONHOOK;
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
if (ReadReg(pProslic,pProslic->channel,PROSLIC_REG_LCRRTP) & 2)
{
*pHookStat=PROSLIC_OFFHOOK;
}
return RC_NONE;
}
/*****************************************************************************************************/
int ProSLIC_SetLinefeedStatus (proslicChanType_ptr pProslic, uInt8 newLinefeed)
{
uInt8 lfState;
uInt8 irqen1=0;
TRACEPRINT(pProslic, "linefeed = %u\n", newLinefeed);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
/* Get the irqen1 setting - used to determine if vbat interrupt was set... */
#ifdef SI3217X
if (pProslic->deviceId->chipType >= SI32171
&& pProslic->deviceId->chipType <= SI32179)
{
irqen1 = Si3217x_General_Configuration.irqen1;
}
#endif
#ifdef SI3218X
if (pProslic->deviceId->chipType >= SI32180
&& pProslic->deviceId->chipType <= SI32189)
{
irqen1 = Si3218x_General_Configuration.irqen1;
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(pProslic->deviceId) )
{
irqen1 = Si3219x_General_Configuration.irqen1;
}
#endif
#ifdef SI3226X
if (pProslic->deviceId->chipType >= SI32260
&& pProslic->deviceId->chipType <= SI32269)
{
irqen1 = Si3226x_General_Configuration.irqen1;
}
#endif
#ifdef SI3228X
if (pProslic->deviceId->chipType >= SI32280
&& pProslic->deviceId->chipType <= SI32289)
{
irqen1 = Si3228x_General_Configuration.irqen1;
}
#endif
if( (newLinefeed& 0xF) == LF_RINGING )
{
uInt8 regTemp;
lfState = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_LINEFEED);
/* Only change to ringing state if not ringing... */
if( (lfState & 0xF) != LF_RINGING )
{
if(irqen1 & 0x80)
{
/*disable vbat interrupt during ringing*/
regTemp = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_IRQEN1 );
WriteReg (pProslic, pProslic->channel, PROSLIC_REG_IRQEN1, regTemp&(~0x80));
}
WriteReg(pProslic, pProslic->channel, PROSLIC_REG_LINEFEED, LF_RINGING);
}
else
{
return RC_IGNORE;
}
}
else
{
uInt8 autord;
/* Preserve the auto register so we can restore it at the end */
autord = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_AUTORD );
WriteReg(pProslic, pProslic->channel, PROSLIC_REG_AUTORD, (autord & 0xFB) ); /* Disable AutoRD */
lfState = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_LINEFEED);
if( (lfState & 0xF) == LF_RINGING )
{
WriteReg(pProslic, pProslic->channel, PROSLIC_REG_LINEFEED, newLinefeed);
}
else
{
/* We are already doing a state transition, abort request */
if( ((lfState & 0xF0) == (LF_RINGING << 4) )
&& ( (lfState & 0xF) != LF_RINGING) )
{
WriteReg(pProslic, pProslic->channel, PROSLIC_REG_AUTORD, autord ); /* restore the autord bit */
return RC_IGNORE;
}
WriteReg(pProslic, pProslic->channel, PROSLIC_REG_LINEFEED, newLinefeed);
}
/* Restore autord */
WriteReg(pProslic, pProslic->channel, PROSLIC_REG_AUTORD, autord );
/* Restore IRQEN1 to what the user specified - if we changed it.. */
if(irqen1 & 0x80)
{
WriteReg (pProslic, pProslic->channel, PROSLIC_REG_IRQEN1, irqen1);
}
}
return RC_NONE;
}
/*****************************************************************************************************/
int ProSLIC_SetLinefeedStatusBroadcast (proslicChanType_ptr hProslic,
uInt8 newLinefeed)
{
TRACEPRINT(hProslic, "linefeed = %u\n", newLinefeed);
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
WriteReg(hProslic, PROSLIC_CHAN_BROADCAST, PROSLIC_REG_LINEFEED, newLinefeed);
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_PolRev (proslicChanType_ptr pProslic,uInt8 abrupt,
uInt8 newPolRevState)
{
uInt8 data = 0;
TRACEPRINT(pProslic, "abrupt = %u newPolRevState = %u\n", abrupt,
newPolRevState);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
switch (newPolRevState)
{
case POLREV_STOP:
data = 0;
break;
case POLREV_START:
data = 2;
break;
case WINK_START:
data = 6;
break;
case WINK_STOP:
data = 4;
break;
}
/* Cannot polrev/wink while low power mode is active */
ProSLIC_SetPowersaveMode(pProslic,PWRSAVE_DISABLE);
if (abrupt)
{
data |= 1;
}
WriteReg(pProslic, pProslic->channel, PROSLIC_REG_POLREV,data);
return RC_NONE;
}
/*****************************************************************************************************/
int ProSLIC_GPIOControl (proslicChanType_ptr pProslic,uInt8 *pGpioData,
uInt8 read)
{
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#if defined(SI3217X) || defined (SI3226X)
if( 0
#ifdef SI3217X
|| (pProslic->deviceId->chipType >= SI32171
&& pProslic->deviceId->chipType <= SI32179)
#endif
#ifdef SI3226X
|| (pProslic->deviceId->chipType >= SI32260
&& pProslic->deviceId->chipType <= SI32269)
#endif
)
{
if (read)
{
*pGpioData = 0xf & ReadReg(pProslic,pProslic->channel,PROSLIC_REG_GPIO);
}
else
{
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_GPIO,
(*pGpioData)|(ReadReg(pProslic,pProslic->channel,PROSLIC_REG_GPIO)&0xf0));
}
return RC_NONE;
}
#else
SILABS_UNREFERENCED_PARAMETER(read);
SILABS_UNREFERENCED_PARAMETER(pGpioData);
#endif
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
/*
** Optional Neon Message Waiting Support
*/
#ifdef SIVOICE_NEON_MWI_SUPPORT
int ProSLIC_MWISetV (proslicChanType_ptr hProslic, uInt16 vpk_mag)
{
uInt32 ram_val;
uInt8 max;
TRACEPRINT(hProslic, "vpk_mag = %u\n", vpk_mag);
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
/* Set the maximum MWI voltage according to the chipset */
#if defined (SI3217X) || defined (SI3226X)
if( 0
#ifdef SI3217X
|| (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
#endif
#ifdef SI3226X
|| (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
#endif
)
{
max = SIL_MWI_VPK_MAX;
}
#endif /*17x/26x */
#if defined (SI3218X) || defined (SI3228X) || defined(SI3219X)
if( 0
#ifdef SI3218X
|| (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
#endif
#ifdef SI3228X
|| (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
#endif
#ifdef SI3219X
|| IS_SI3219X(hProslic->deviceId)
#endif
#ifdef SI3228X
|| (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
#endif
)
{
max = SIL_MWI_VPK_MAX_LO;
}
#endif /* 18x, 28x, 19x */
/* Voltage mod */
if(vpk_mag > 0) /* Skip if 0 passed */
{
/* Clamp supplied value to allowable range */
if(vpk_mag > max)
{
vpk_mag = max;
}
if(vpk_mag < SIL_MWI_VPK_MIN)
{
vpk_mag = SIL_MWI_VPK_MIN;
}
ram_val = vpk_mag * SCALE_R_MADC * 1000L;
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_MWI_V,ram_val);
}
return RC_COMPLETE_NO_ERR;
}
#endif
/*****************************************************************************************************/
#ifdef SIVOICE_NEON_MWI_SUPPORT
int ProSLIC_MWIEnable (proslicChanType_ptr hProslic)
{
uInt8 val;
ramData ram_val;
TRACEPRINT(hProslic, "\n", NULL);
/*
** Check for conditions that would prevent enabling MWI
*/
ProSLIC_ReadHookStatus(hProslic,&val);
if(val != PROSLIC_ONHOOK)
{
return RC_MWI_ENABLE_FAIL;
}
val = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT);
/* Check if PROSLIC and disabled MWI, if not, ignore this request. */
if( (hProslic->channelType != PROSLIC)
|| (val & SIL_MWI_USTAT_SET ) )
{
return RC_IGNORE;
}
/* Save parameters */
hProslic->mwiSave.ringof = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGOF);
hProslic->mwiSave.ringamp = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGAMP);
hProslic->mwiSave.vbatr_expect = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_VBATR_EXPECT);
hProslic->mwiSave.vov_ring_bat = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_BAT);
hProslic->mwiSave.vov_ring_gnd = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_GND);
hProslic->mwiSave.rtacth = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTACTH);
hProslic->mwiSave.rtdcth = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCTH);
hProslic->mwiSave.iring_lim = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_IRING_LIM);
hProslic->mwiSave.dcdc_rngtype = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_RNGTYPE);
hProslic->mwiSave.slope_ring = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_SLOPE_RING);
hProslic->mwiSave.rtper = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTPER);
hProslic->mwiSave.ringfr = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGFR);
hProslic->mwiSave.rtdcdb = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCDB);
hProslic->mwiSave.lcrmask = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_LCRMASK);
hProslic->mwiSave.dcdc_oithresh_lo = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_OITHRESH_LO);
hProslic->mwiSave.enhance = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE);
hProslic->mwiSave.ringcon = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_RINGCON);
hProslic->mwiSave.userstat = val;
hProslic->mwiSave.linefeed = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_LINEFEED);
/* Modify parameters */
ProSLIC_SetLinefeedStatus(hProslic,LF_FWD_ACTIVE);
ram_val = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_MWI_V);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGOF,ram_val);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGAMP,0x0L);
/* Set the VBATR_EXPECT according to the chipset */
#if defined (SI3217X) || defined (SI3226X)
if( 0
#ifdef SI3217X
|| (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
#endif
#ifdef SI3226X
|| (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
#endif
)
{
ram_val = 0x7FFFFC2L;
}
#endif
#if defined (SI3218X) || defined (SI3228X) || defined(SI3219X)
if( 0
#ifdef SI3218X
|| (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
#endif
#ifdef SI3228X
|| (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
#endif
#ifdef SI3219X
|| IS_SI3219X(hProslic->deviceId)
#endif
)
{
ram_val = 0x06866635L;
}
#endif /* 18x,28x, 19x */
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VBATR_EXPECT,ram_val);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_BAT,0x0L);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_GND,0x051EB80L);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTACTH,0x0FFFFFFFL);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCTH,0x38E38EL);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_IRING_LIM,0x380000L);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_RNGTYPE,0x100000L);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_SLOPE_RING,0x15E5200EL);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTPER,0x50000L);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGFR,0x07EFE000L);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCDB,0x0000A000L);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_LCRMASK,0x000F0000L);
ram_val = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_OITHRESH_HI);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_OITHRESH_LO,ram_val);
WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE,hProslic->mwiSave.enhance&0xEF);
WriteReg(hProslic,hProslic->channel,PROSLIC_REG_RINGCON,0x00);
WriteReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT,0x0C);
return RC_COMPLETE_NO_ERR;
}
#endif
/*****************************************************************************************************/
#ifdef SIVOICE_NEON_MWI_SUPPORT
int ProSLIC_MWIDisable (proslicChanType_ptr hProslic)
{
TRACEPRINT(hProslic, "\n", NULL);
/* Check if PROSLIC and enabled MWI, if not, ignore this request. */
if( (hProslic->channelType != PROSLIC)
|| !(ReadReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
{
return RC_IGNORE;
}
ProSLIC_SetLinefeedStatus(hProslic,LF_FWD_ACTIVE);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGOF,hProslic->mwiSave.ringof);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGAMP,hProslic->mwiSave.ringamp);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VBATR_EXPECT,hProslic->mwiSave.vbatr_expect);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_BAT,hProslic->mwiSave.vov_ring_bat);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_GND,hProslic->mwiSave.vov_ring_gnd);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTACTH,hProslic->mwiSave.rtacth);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCTH,hProslic->mwiSave.rtdcth);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_IRING_LIM,hProslic->mwiSave.iring_lim);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_RNGTYPE,hProslic->mwiSave.dcdc_rngtype);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_SLOPE_RING,hProslic->mwiSave.slope_ring);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTPER,hProslic->mwiSave.rtper);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGFR,hProslic->mwiSave.ringfr);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCDB,hProslic->mwiSave.rtdcdb);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_LCRMASK,hProslic->mwiSave.lcrmask);
WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_OITHRESH_LO,hProslic->mwiSave.dcdc_oithresh_lo);
WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE,hProslic->mwiSave.enhance);
WriteReg(hProslic,hProslic->channel,PROSLIC_REG_RINGCON,hProslic->mwiSave.ringcon);
WriteReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT,hProslic->mwiSave.userstat);
ProSLIC_SetLinefeedStatus(hProslic,hProslic->mwiSave.linefeed);
return RC_COMPLETE_NO_ERR;
}
#endif
/*****************************************************************************************************/
#ifdef SIVOICE_NEON_MWI_SUPPORT
int ProSLIC_SetMWIState (proslicChanType_ptr hProslic,uInt8 flash_on)
{
TRACEPRINT(hProslic, "flash_on = %u\n", flash_on);
/* Check if PROSLIC and enabled MWI, if not, ignore this request. */
if( (hProslic->channelType != PROSLIC)
|| !(ReadReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
{
return RC_IGNORE;
}
if(flash_on)
{
ProSLIC_SetLinefeedStatus(hProslic,LF_RINGING);
}
else
{
ProSLIC_SetLinefeedStatus(hProslic,LF_FWD_ACTIVE);
}
return RC_COMPLETE_NO_ERR;
}
#endif
/*****************************************************************************************************/
#ifdef SIVOICE_NEON_MWI_SUPPORT
int ProSLIC_GetMWIState (proslicChanType_ptr hProslic)
{
TRACEPRINT(hProslic, "\n", NULL);
/* Check if PROSLIC and enabled MWI, if not, ignore this request. */
if( (hProslic->channelType != PROSLIC)
|| !(ReadReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
{
return RC_IGNORE;
}
if(ReadReg(hProslic,hProslic->channel,PROSLIC_REG_LINEFEED) == 0x44)
{
return SIL_MWI_FLASH_ON;
}
else
{
return SIL_MWI_FLASH_OFF;
}
return RC_COMPLETE_NO_ERR;
}
#endif
/******************************************************************************/
#ifdef SIVOICE_NEON_MWI_SUPPORT
int ProSLIC_MWIRampPoll(proslicChanType_ptr pProslic)
{
uInt32 mwi_voltage;
/* Check if PROSLIC and enabled MWI, if not, ignore this request. */
if( (pProslic->channelType != PROSLIC)
|| !(ReadReg(pProslic,pProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
{
return RC_IGNORE;
}
switch(pProslic->mwiState.state)
{
case PROSLIC_MWI_RAMP_ON:
{
if(pProslic->mwiState.ticks == pProslic->mwiState.poll.steps)
{
mwi_voltage = pProslic->mwiState.poll.voff + pProslic->mwiState.poll.step_size;
WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_RINGOF,mwi_voltage);
ProSLIC_SetLinefeedStatus(pProslic,LF_RINGING);
}
else if(pProslic->mwiState.ticks == 0)
{
mwi_voltage = pProslic->mwiState.poll.von;
WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_RINGOF,mwi_voltage);
pProslic->mwiState.ticks = pProslic->mwiState.poll.onTime+1;
pProslic->mwiState.state = PROSLIC_MWI_ON;
}
else
{
mwi_voltage = pProslic->mwiState.poll.voff + pProslic->mwiState.poll.step_size*(pProslic->mwiState.poll.steps - pProslic->mwiState.ticks + 1);
WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_RINGOF,mwi_voltage);
}
}
break;
case PROSLIC_MWI_RAMP_OFF:
{
if(pProslic->mwiState.ticks == 0)
{
pProslic->mwiState.ticks = pProslic->mwiState.poll.offTime+1;
pProslic->mwiState.state = PROSLIC_MWI_OFF;
ProSLIC_SetLinefeedStatus(pProslic,LF_FWD_ACTIVE);
}
else
{
mwi_voltage = pProslic->mwiState.poll.von - (pProslic->mwiState.poll.steps - pProslic->mwiState.ticks + 1)*pProslic->mwiState.poll.step_size;
WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_RINGOF,mwi_voltage);
}
break;
}
case PROSLIC_MWI_ON:
if(pProslic->mwiState.ticks == 0)
{
pProslic->mwiState.ticks = pProslic->mwiState.poll.steps+1;
pProslic->mwiState.state = PROSLIC_MWI_RAMP_OFF;
}
break;
case PROSLIC_MWI_OFF:
if(pProslic->mwiState.ticks == 0)
{
pProslic->mwiState.ticks = pProslic->mwiState.poll.steps+1;
pProslic->mwiState.state = PROSLIC_MWI_RAMP_ON;
}
break;
default:
/* Do nothing */
break;
}
(pProslic->mwiState.ticks)--;
return RC_COMPLETE_NO_ERR;
}
#endif
/******************************************************************************/
#ifdef SIVOICE_NEON_MWI_SUPPORT
int ProSLIC_MWIRampStart(proslicChanType_ptr pProslic, uInt32 steps, uInt32 onTime, uInt32 offTime)
{
/* Check if PROSLIC and enabled MWI, if not, ignore this request. */
if( (pProslic->channelType != PROSLIC)
|| !(ReadReg(pProslic,pProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
{
return RC_IGNORE;
}
pProslic->mwiState.poll.steps = steps-1;
pProslic->mwiState.poll.onTime = onTime;
pProslic->mwiState.poll.offTime = offTime;
pProslic->mwiState.poll.von = ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_MWI_V);
pProslic->mwiState.poll.voff = (ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_V_VLIM)*5)/6;
pProslic->mwiState.poll.step_size = (pProslic->mwiState.poll.von - pProslic->mwiState.poll.voff)/steps;
pProslic->mwiState.state = PROSLIC_MWI_RAMP_ON;
pProslic->mwiState.ticks = pProslic->mwiState.poll.steps;
return RC_COMPLETE_NO_ERR;
}
#endif
/******************************************************************************/
#ifdef SIVOICE_NEON_MWI_SUPPORT
int ProSLIC_MWIRampStop(proslicChanType_ptr pProslic)
{
/* Check if PROSLIC and enabled MWI, if not, ignore this request. */
if( (pProslic->channelType != PROSLIC)
|| !(ReadReg(pProslic,pProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
{
return RC_IGNORE;
}
pProslic->mwiState.state = PROSLIC_MWI_OFF;
return RC_COMPLETE_NO_ERR;
}
#endif
/*****************************************************************************************************/
int ProSLIC_ToneGenStart (proslicChanType_ptr pProslic,uInt8 timerEn)
{
uInt8 data;
TRACEPRINT(pProslic, "timerEn = %u\n", timerEn);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
DEBUG_PRINT(pProslic, "%s%s on channel %d\n",LOGPRINT_PREFIX, __FUNCTION__,
pProslic->channel);
data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OCON);
data |= 0x11 + (timerEn ? 0x66 : 0);
return WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OCON,data);
}
/*****************************************************************************************************/
int ProSLIC_ToneGenStop (proslicChanType_ptr pProslic)
{
uInt8 data;
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
DEBUG_PRINT(pProslic,"%s%s on channel %d\n",LOGPRINT_PREFIX, __FUNCTION__,
pProslic->channel);
data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OCON);
data &= ~(0x77);
return WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OCON,data);
}
/*****************************************************************************************************/
int ProSLIC_RingStart (proslicChanType_ptr pProslic)
{
TRACEPRINT(pProslic, "\n", NULL);
return(ProSLIC_SetLinefeedStatus(pProslic, LF_RINGING));
}
/*****************************************************************************************************/
int ProSLIC_RingStop (proslicChanType_ptr pProslic)
{
TRACEPRINT(pProslic, "\n", NULL);
return(ProSLIC_SetLinefeedStatus(pProslic, LF_FWD_ACTIVE));
}
#ifndef DISABLE_FSK_SETUP
/*****************************************************************************************************/
int ProSLIC_CheckCIDBuffer (proslicChanType_ptr pProslic, uInt8 *fsk_buf_avail)
{
uInt8 data;
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
data = ReadReg(pProslic,pProslic->channel, PROSLIC_REG_IRQ1);
#ifdef GCI_MODE
WriteReg(pProslic,pProslic->channel, PROSLIC_REG_IRQ1,data); /*clear (for GCI)*/
#endif
*fsk_buf_avail = (data&0x40) ? 1 : 0;
return RC_NONE;
}
/*****************************************************************************************************/
int ProSLIC_EnableCID (proslicChanType_ptr pProslic)
{
uInt8 data;
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
DEBUG_PRINT(pProslic, "%sEnableCID on channel %d\n",LOGPRINT_PREFIX,
pProslic->channel);
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OCON,0);
data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE);
data |= 0xA;
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE,data);
return(WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OCON,0x5));
}
/*****************************************************************************************************/
int ProSLIC_DisableCID (proslicChanType_ptr pProslic)
{
uInt8 data;
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
DEBUG_PRINT(pProslic, "%sDisableCID on channel %d\n",LOGPRINT_PREFIX,
pProslic->channel);
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OCON,0);
data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE);
data &= ~(0x8);
return(WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE,data));
}
/*****************************************************************************************************/
int ProSLIC_SendCID (proslicChanType_ptr pProslic, uInt8 *buffer,
uInt8 numBytes)
{
TRACEPRINT(pProslic, "numBytes = %u\n", numBytes);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
DEBUG_PRINT (pProslic, "%sSendCID on channel %d\n",LOGPRINT_PREFIX,
pProslic->channel);
while (numBytes-- > 0)
{
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_FSKDAT,*(buffer++));
}
return RC_NONE;
}
/*****************************************************************************************************/
int ProSLIC_ModifyCIDStartBits(proslicChanType_ptr pProslic,
uInt8 enable_startStop)
{
uInt8 data;
TRACEPRINT(pProslic, "enable_startStop = %u\n", enable_startStop);
if(pProslic->channelType != PROSLIC)
{
return RC_CHANNEL_TYPE_ERR;
}
data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE);
if(enable_startStop == FALSE)
{
data &= ~0x80;
}
else
{
data |= 0x80;
}
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE,data);
return RC_NONE;
}
#endif /* DISABLE_FSK_SETUP */
/*****************************************************************************************************/
int ProSLIC_PCMStart (proslicChanType_ptr pProslic)
{
uInt8 data;
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
DEBUG_PRINT(pProslic, "%sPCMStart\n", LOGPRINT_PREFIX);
data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_PCMMODE);
data |= 0x10;
return WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMMODE,data);
}
/*****************************************************************************************************/
int ProSLIC_PCMStop (proslicChanType_ptr pProslic)
{
uInt8 data;
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
DEBUG_PRINT(pProslic, "%sPCMStart\n", LOGPRINT_PREFIX);
data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_PCMMODE);
data &= ~0x10;
return WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMMODE,data);
}
#ifndef DISABLE_HOOKCHANGE
/*****************************************************************************************************/
/*
** Function: ProSLIC_ResetDialPulseDetect
**
** Description:
** reset dial pulse detection state machine (helper function for
** ProSLIC_InitializeHookChangeDetect.
*/
static void ProSLIC_ResetDialPulseDetect(hookChangeType *pPulse)
{
pPulse->currentPulseDigit = 0;
pPulse->lookingForTimeout = 0;
}
/*****************************************************************************************************/
/*
** Function: ProSLIC_InitializeHookChangeDetect
**
** Description:
** Initialize dial pulse detection parameters
*/
int ProSLIC_InitializeHookChangeDetect(hookChangeType *pPulse,void *hookTime)
{
TRACEPRINT_NOCHAN("\n", NULL);
pPulse->hookTime = hookTime;
pPulse->last_state_reported = SI_HC_NO_ACTIVITY;
ProSLIC_ResetDialPulseDetect(pPulse);
return RC_NONE;
}
/*****************************************************************************************************/
/*
** Function: ProSLIC_HookChangeDetect
**
** Description:
** implements pulse dial detection and should be called at every hook transition
*/
uInt8 ProSLIC_HookChangeDetect (proslicChanType *pProslic,
hookChange_Cfg *pHookChangeCfg, hookChangeType *pHookChangeData)
{
uInt8 hookStat;
int delta_time;
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
TimeElapsed(pProTimer,pHookChangeData->hookTime,&delta_time);
ProSLIC_ReadHookStatus(pProslic,&hookStat);
/* Did we have a hook state change? */
if(hookStat != pHookChangeData->last_hook_state)
{
pHookChangeData->last_hook_state = hookStat;
getTime(pProTimer,pHookChangeData->hookTime);
pHookChangeData->lookingForTimeout = 1;
if (hookStat == PROSLIC_OFFHOOK)
{
if ((delta_time >= (pHookChangeCfg->minOnHook))
&& (delta_time <= (pHookChangeCfg->maxOnHook)))
{
pHookChangeData->currentPulseDigit++;
}
else
{
/* Did we see a hook flash? */
if( (delta_time >= pHookChangeCfg->minHookFlash)
&& (delta_time <= pHookChangeCfg->maxHookFlash) )
{
pHookChangeData->last_state_reported = SI_HC_HOOKFLASH;
ProSLIC_ResetDialPulseDetect(pHookChangeData);
return SI_HC_HOOKFLASH;
}
}
}
return SI_HC_NEED_MORE_POLLS;
}
if( (pHookChangeData->lookingForTimeout == 1)
&& (delta_time >= pHookChangeCfg->minInterDigit) )
{
if(delta_time > pHookChangeCfg->minHook)
{
if(pHookChangeData->last_hook_state == PROSLIC_ONHOOK)
{
ProSLIC_ResetDialPulseDetect(pHookChangeData);
pHookChangeData->last_state_reported = SI_HC_ONHOOK_TIMEOUT;
return SI_HC_ONHOOK_TIMEOUT;
}
if(pHookChangeData->last_hook_state == PROSLIC_OFFHOOK)
{
ProSLIC_ResetDialPulseDetect(pHookChangeData);
/* Check if we saw either a pulse digit or hook flash prior to this,
* if so, we're already offhook, so do not report a offhook event,
* just stop polling.
*/
if((pHookChangeData->last_state_reported == SI_HC_ONHOOK_TIMEOUT)
|| (pHookChangeData->last_state_reported == SI_HC_NO_ACTIVITY) )
{
pHookChangeData->last_state_reported = SI_HC_OFFHOOK_TIMEOUT;
return SI_HC_OFFHOOK_TIMEOUT;
}
else
{
return SI_HC_NO_ACTIVITY;
}
}
}
else
{
uInt8 last_digit = pHookChangeData->currentPulseDigit;
if(last_digit)
{
pHookChangeData->last_state_reported = last_digit;
ProSLIC_ResetDialPulseDetect(pHookChangeData);
return last_digit;
}
}
return SI_HC_NEED_MORE_POLLS;
}
return SI_HC_NEED_MORE_POLLS;
}
#endif /* DISABLE_HOOKCHANGE */
/*****************************************************************************************************/
int ProSLIC_DTMFReadDigit (proslicChanType_ptr pProslic,uInt8 *pDigit)
{
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
DEBUG_PRINT(pProslic, "%sDTMFReadDigit on channel %d\n",LOGPRINT_PREFIX,
pProslic->channel);
*pDigit = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_TONDTMF) & 0xf;
return RC_NONE;
}
/*****************************************************************************************************/
int ProSLIC_PLLFreeRunStart (proslicChanType_ptr hProslic)
{
uInt8 tmp;
TRACEPRINT(hProslic, "\n", NULL);
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ZCAL_EN,0x00);
tmp = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE);
return(WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE,tmp|0x4));
}
/*****************************************************************************************************/
int ProSLIC_PLLFreeRunStop (proslicChanType_ptr hProslic)
{
uInt8 tmp;
TRACEPRINT(hProslic, "\n", NULL);
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
tmp = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE);
WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE,tmp&~(0x4));
return WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ZCAL_EN,0x04);
}
/*****************************************************************************************************/
int ProSLIC_GetPLLFreeRunStatus (proslicChanType_ptr hProslic)
{
uInt8 tmp;
TRACEPRINT(hProslic, "\n", NULL);
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
tmp = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE);
if(tmp & 0x02)
{
return RC_PLL_FREERUN_ACTIVE;
}
return RC_NONE;
}
/*****************************************************************************************************/
#ifndef DISABLE_PULSEMETERING
int ProSLIC_PulseMeterEnable (proslicChanType_ptr hProslic)
{
uInt8 widebandEn;
TRACEPRINT(hProslic, "\n", NULL);
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
widebandEn = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE) & 0x01;
if (widebandEn)
{
DEBUG_PRINT (hProslic,
"%s Pulse Metering is not supported while Wideband Mode is enabled.\n",
LOGPRINT_PREFIX);
}
#if defined (SI3217X) || defined (SI3218X) || defined (SI3226X) || defined (SI3228X) || defined(SI3219X)
if(!widebandEn && (0
#ifdef SI3217X
|| (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
#endif
#ifdef SI3218X
||(hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
#endif
#ifdef SI3219X
|| (IS_SI3219X(hProslic->deviceId) )
#endif
#ifdef SI3226X
|| (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
#endif
#ifdef SI3228X
|| (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289 )
#endif
))
{
return WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
hProslic->channel,PROSLIC_REG_PMCON) | (0x01));
}
#endif
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_PulseMeterDisable (proslicChanType_ptr hProslic)
{
TRACEPRINT(hProslic, "\n", NULL);
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
return(WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
hProslic->channel,PROSLIC_REG_PMCON) & ~(0x05)));
}
/*****************************************************************************************************/
int ProSLIC_PulseMeterStart (proslicChanType_ptr hProslic)
{
TRACEPRINT(hProslic, "\n", NULL);
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
return WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
hProslic->channel,PROSLIC_REG_PMCON) | (0x5));
}
/*****************************************************************************************************/
int ProSLIC_PulseMeterStop (proslicChanType_ptr hProslic)
{
TRACEPRINT(hProslic, "\n", NULL);
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return(WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
hProslic->channel,PROSLIC_REG_PMCON) & ~(0x04)));
}
#endif
#ifdef SI3218X
if (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
{
return(WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
hProslic->channel,PROSLIC_REG_PMCON) & ~(0x04)));
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(hProslic->deviceId) )
{
return(WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
hProslic->channel,PROSLIC_REG_PMCON) & ~(0x04)));
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return ProSLIC_PulseMeterDisable(hProslic);
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
return ProSLIC_PulseMeterDisable(hProslic);
}
#endif
return RC_COMPLETE_NO_ERR;
}
#endif /* DISABLE_PULSEMETERING */
/*****************************************************************************************************/
int ProSLIC_SetDCDCInversionFlag (proslicChanType_ptr hProslic, uInt8 flag)
{
TRACEPRINT(hProslic, "flag = %u\n", flag);
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
hProslic->dcdc_polarity_invert = flag;
return RC_COMPLETE_NO_ERR;
}
int ProSLIC_PowerUpConverter (proslicChanType_ptr hProslic)
{
if(hProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (hProslic->deviceId->chipType >= SI32171
&& hProslic->deviceId->chipType <= SI32179)
{
return Si3217x_PowerUpConverter(hProslic);
}
#endif
#ifdef SI3218X
if (hProslic->deviceId->chipType >= SI32180
&& hProslic->deviceId->chipType <= SI32189)
{
return Si3218x_PowerUpConverter(hProslic);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(hProslic->deviceId) )
{
return Si3219x_PowerUpConverter(hProslic);
}
#endif
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return Si3226x_PowerUpConverter(hProslic);
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
return Si3228x_PowerUpConverter(hProslic);
}
#endif
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
static int ProSLIC_GetBatType(proslicChanType_ptr hProslic)
{
#ifdef SI3226X
if (hProslic->deviceId->chipType >= SI32260
&& hProslic->deviceId->chipType <= SI32269)
{
return Si3226x_General_Configuration.batType;
}
#endif
#ifdef SI3228X
if (hProslic->deviceId->chipType >= SI32280
&& hProslic->deviceId->chipType <= SI32289)
{
return Si3228x_General_Configuration.batType;
}
#endif
#if !defined(SI3226X) && !defined(SI3228X)
SILABS_UNREFERENCED_PARAMETER(hProslic);
#endif
return BO_DCDC_UNKNOWN;
}
/*****************************************************************************************************/
int ProSLIC_PowerDownConverter (proslicChanType_ptr pProslic)
{
errorCodeType error = RC_NONE;
int32 vbat;
int timer = 0;
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
/* Force channel out of powersavings mode and then put it in open state */
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_LINEFEED,LF_FWD_OHT);
Delay(pProTimer,10);
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_LINEFEED, LF_OPEN);
Delay(pProTimer,50);
/* Don't try to shutdown converter if we're using external supplies or if the
converter is already shutdown.
*/
if((ProSLIC_GetBatType(pProslic) == BO_DCDC_EXTERNAL) ||
(ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_PD_DCDC) & 0x100000) )
{
return RC_NONE;
}
WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_PD_DCDC,0x900000L);
Delay(pProTimer,50);
do
{
vbat = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_MADC_VBAT);
if(vbat & 0x10000000L)
{
vbat |= 0xF0000000L;
}
Delay(pProTimer,10);
}
while((vbat > COMP_5V) && (timer++ < PROSLIC_TIMEOUT_DCDC_DOWN));
DEBUG_PRINT(pProslic, "%s VBAT Down = %d.%d v\n", LOGPRINT_PREFIX,
(int)((vbat/SCALE_V_MADC)/1000),
SIVOICE_ABS(((vbat/SCALE_V_MADC) - (vbat/SCALE_V_MADC)/1000*1000)));
if(timer > PROSLIC_TIMEOUT_DCDC_DOWN)
{
/* Error handling - shutdown converter, disable channel, set error tag */
pProslic->channelEnable = 0;
pProslic->error = error = RC_VBAT_DOWN_TIMEOUT;
DEBUG_PRINT(pProslic, "%sDCDC Power Down timeout channel %d\n", LOGPRINT_PREFIX,
pProslic->channel);
}
return error;
}
/*****************************************************************************************************/
int ProSLIC_LBCal (proslicChanType_ptr *pProslic, int size)
{
int k;
int timeout;
uInt8 data;
uInt8 lfState, enhance_value;
TRACEPRINT(*pProslic, "size = %d\n", size);
if((*pProslic)->channelType != PROSLIC)
{
return RC_IGNORE;
}
/* For all channels, save settings, initiate LBCAL */
for(k = 0; k < size; k++)
{
if( (pProslic[k]->channelEnable) && (pProslic[k]->channelType == PROSLIC) )
{
DEBUG_PRINT(pProslic[k], "%sStarting LB Cal on channel %d\n", LOGPRINT_PREFIX,
pProslic[k]->channel);
/* Preserve old settings */
lfState = ReadReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_LINEFEED);
enhance_value = ReadReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_ENHANCE);
ProSLIC_SetPowersaveMode(pProslic[k], PWRSAVE_DISABLE);
ProSLIC_SetLinefeedStatus(pProslic[k], LF_FWD_ACTIVE);
WriteReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_CALR0, CAL_LB_ALL);
WriteReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_CALR3, 0x80);
pProslic[k]->error = RC_CAL_TIMEOUT; /* Assume failure */
timeout = 0;
do
{
data = ReadReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_CALR3);
DelayX(*pProslic, 10);
timeout++;
}
while((data & 0x80) && (timeout < TIMEOUT_LB_CAL));
if( (data & 0x80) )
{
DEBUG_PRINT(pProslic[k], "%sLB Cal timeout on channel %d\n", LOGPRINT_PREFIX,
pProslic[k]->channel);
WriteReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_LINEFEED, LF_OPEN);
return RC_CAL_TIMEOUT;
}
else
{
WriteReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_LINEFEED, lfState);
WriteReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_ENHANCE, enhance_value);
pProslic[k]->error = RC_NONE;
}
}
}
return RC_NONE;
}
/*****************************************************************************************************/
#define PROSLIC_RAM_CMDAC_FWD 1476
#define PROSLIC_RAM_CMDAC_REV 1477
#define PROSLIC_RAM_CAL_TRNRD_DACT 1458
#define PROSLIC_RAM_CAL_TRNRD_DACR 1459
int ProSLIC_GetLBCalResult (proslicChanType *pProslic,int32 *result1,
int32 *result2, int32 *result3, int32 *result4)
{
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
*result1 = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_CMDAC_FWD);
*result2 = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_CMDAC_REV);
*result3 = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_CAL_TRNRD_DACT);
*result4 = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_CAL_TRNRD_DACR);
return RC_NONE;
}
/*****************************************************************************************************/
int ProSLIC_GetLBCalResultPacked (proslicChanType *pProslic,int32 *result)
{
int32 results[4];
int rc;
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
rc = ProSLIC_GetLBCalResult(pProslic, &(results[0]), &(results[1]),
&(results[2]), &(results[3]));
if(rc == RC_NONE)
{
/*
Bits 31:24 CMDAC_FWD[25:18]
Bits 23:16 CMDAC_REV[25:18]
Bits 15:8 CAL_TRNRD_DACT[20:13]
Bits 7:0 CAL_TRNRD_DACR[20:13]
*/
*result = (results[0]<<6) & 0xff000000L;
*result |=(results[1]>>1) & 0x00ff0000L;
*result |=(results[2]>>5) & 0x0000ff00L;
*result |=(results[3]>>13)& 0x000000ffL;
}
return rc;
}
/*****************************************************************************************************/
int ProSLIC_LoadPreviousLBCal (proslicChanType *pProslic,int32 result1,
int32 result2,int32 result3,int32 result4)
{
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_CMDAC_FWD,result1);
WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_CMDAC_REV,result2);
WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_CAL_TRNRD_DACT,result3);
WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_CAL_TRNRD_DACR,result4);
#ifdef API_TEST
ramVal = ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_CMDAC_FWD);
LOGPRINT ("%s UNPACKED CMDAC_FWD = %08x\n", LOGPRINT_PREFIX, ramVal);
ramVal = ReadRAM(pProslic, pProslic->channel,PROSLIC_RAM_CMDAC_REV);
LOGPRINT ("%s UNPACKED CMDAC_REF = %08x\n", LOGPRINT_PREFIX, ramVal);
ramVal = ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_CAL_TRNRD_DACT);
LOGPRINT ("%s UNPACKED CAL_TRNRD_DACT = %08x\n", LOGPRINT_PREFIX, ramVal);
ramVal = ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_CAL_TRNRD_DACR);
LOGPRINT ("%s UNPACKED CAL_TRNRD_DACR = %08x\n", LOGPRINT_PREFIX, ramVal);
#endif
return RC_NONE;
}
/*****************************************************************************************************/
int ProSLIC_LoadPreviousLBCalPacked (proslicChanType *pProslic,int32 *result)
{
ramData ramVal[4];
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
ramVal[0] = (*result&0xff000000L)>>6;
ramVal[1] = (*result&0x00ff0000L)<<1;
ramVal[2] = (*result&0x0000ff00L)<<5;
ramVal[3] = (*result&0x000000ffL)<<13;
return ProSLIC_LoadPreviousLBCal(pProslic, ramVal[0], ramVal[1], ramVal[2],
ramVal[3]);
}
/*****************************************************************************************************/
int ProSLIC_dbgSetDCFeedVopen (proslicChanType *pProslic, uInt32 v_vlim_val,
int32 preset)
{
TRACEPRINT(pProslic, "v_vlim_val = %u preset = %d\n", v_vlim_val, preset);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (pProslic->deviceId->chipType >= SI32171
&& pProslic->deviceId->chipType <= SI32179)
{
return Si3217x_dbgSetDCFeedVopen (pProslic,v_vlim_val,preset);
}
#endif
#ifdef SI3218X
if (pProslic->deviceId->chipType >= SI32180
&& pProslic->deviceId->chipType <= SI32189)
{
return Si3218x_dbgSetDCFeedVopen (pProslic,v_vlim_val,preset);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(pProslic->deviceId) )
{
return Si3219x_dbgSetDCFeedVopen (pProslic,v_vlim_val,preset);
}
#endif
#ifdef SI3226X
if (pProslic->deviceId->chipType >= SI32260
&& pProslic->deviceId->chipType <= SI32269)
{
return Si3226x_dbgSetDCFeedVopen (pProslic,v_vlim_val,preset);
}
#endif
#ifdef SI3228X
if (pProslic->deviceId->chipType >= SI32280
&& pProslic->deviceId->chipType <= SI32289)
{
return Si3228x_dbgSetDCFeedVopen (pProslic,v_vlim_val,preset);
}
#endif
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_dbgSetDCFeedIloop (proslicChanType *pProslic, uInt32 i_ilim_val,
int32 preset)
{
TRACEPRINT(pProslic, "i_ilim_val = %u preset = %d\n", i_ilim_val, preset);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (pProslic->deviceId->chipType >= SI32171
&& pProslic->deviceId->chipType <= SI32179)
{
return Si3217x_dbgSetDCFeedIloop (pProslic,i_ilim_val,preset);
}
#endif
#ifdef SI3218X
if (pProslic->deviceId->chipType >= SI32180
&& pProslic->deviceId->chipType <= SI32189)
{
return Si3218x_dbgSetDCFeedIloop (pProslic,i_ilim_val,preset);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(pProslic->deviceId) )
{
return Si3219x_dbgSetDCFeedIloop (pProslic,i_ilim_val,preset);
}
#endif
#ifdef SI3226X
if (pProslic->deviceId->chipType >= SI32260
&& pProslic->deviceId->chipType <= SI32269)
{
return Si3226x_dbgSetDCFeedIloop (pProslic,i_ilim_val,preset);
}
#endif
#ifdef SI3228X
if (pProslic->deviceId->chipType >= SI32280
&& pProslic->deviceId->chipType <= SI32289)
{
return Si3228x_dbgSetDCFeedIloop (pProslic,i_ilim_val,preset);
}
#endif
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_dbgSetRinging (proslicChanType *pProslic,
ProSLIC_dbgRingCfg *ringCfg, int preset)
{
TRACEPRINT(pProslic, "preset = %d\n", preset);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (pProslic->deviceId->chipType >= SI32171
&& pProslic->deviceId->chipType <= SI32179)
{
return Si3217x_dbgSetRinging (pProslic,ringCfg,preset);
}
#endif
#ifdef SI3218X
if (pProslic->deviceId->chipType >= SI32180
&& pProslic->deviceId->chipType <= SI32189)
{
return Si3218x_dbgSetRinging (pProslic,ringCfg,preset);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(pProslic->deviceId) )
{
return Si3219x_dbgSetRinging (pProslic,ringCfg,preset);
}
#endif
#ifdef SI3226X
if (pProslic->deviceId->chipType >= SI32260
&& pProslic->deviceId->chipType <= SI32269)
{
return Si3226x_dbgSetRinging (pProslic,ringCfg,preset);
}
#endif
#ifdef SI3228X
if (pProslic->deviceId->chipType >= SI32280
&& pProslic->deviceId->chipType <= SI32289)
{
return Si3228x_dbgSetRinging (pProslic,ringCfg,preset);
}
#endif
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_dbgSetRXGain (proslicChanType *pProslic, int32 gain,
int impedance_preset, int audio_gain_preset)
{
TRACEPRINT(pProslic, "gain = %d imp_preset = %d audio_gain_preset = %d\n", gain,
impedance_preset, audio_gain_preset);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (pProslic->deviceId->chipType >= SI32171
&& pProslic->deviceId->chipType <= SI32179)
{
return Si3217x_dbgSetRXGain (pProslic,gain,impedance_preset,audio_gain_preset);
}
#endif
#ifdef SI3218X
if (pProslic->deviceId->chipType >= SI32180
&& pProslic->deviceId->chipType <= SI32189)
{
return Si3218x_dbgSetRXGain (pProslic,gain,impedance_preset,audio_gain_preset);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(pProslic->deviceId) )
{
return Si3219x_dbgSetRXGain (pProslic,gain,impedance_preset,audio_gain_preset);
}
#endif
#ifdef SI3226X
if (pProslic->deviceId->chipType >= SI32260
&& pProslic->deviceId->chipType <= SI32269)
{
return Si3226x_dbgSetRXGain (pProslic,gain,impedance_preset,audio_gain_preset);
}
#endif
#ifdef SI3228X
if (pProslic->deviceId->chipType >= SI32280
&& pProslic->deviceId->chipType <= SI32289)
{
return Si3228x_dbgSetRXGain (pProslic,gain,impedance_preset,audio_gain_preset);
}
#endif
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
int ProSLIC_dbgSetTXGain (proslicChanType *pProslic, int32 gain,
int impedance_preset, int audio_gain_preset)
{
TRACEPRINT(pProslic, "gain = %d imp_preset = %d audio_gain_preset = %d\n", gain,
impedance_preset, audio_gain_preset);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (pProslic->deviceId->chipType >= SI32171
&& pProslic->deviceId->chipType <= SI32179)
{
return Si3217x_dbgSetTXGain (pProslic,gain,impedance_preset,audio_gain_preset);
}
#endif
#ifdef SI3218X
if (pProslic->deviceId->chipType >= SI32180
&& pProslic->deviceId->chipType <= SI32189)
{
return Si3218x_dbgSetTXGain (pProslic,gain,impedance_preset,audio_gain_preset);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(pProslic->deviceId) )
{
return Si3219x_dbgSetTXGain (pProslic,gain,impedance_preset,audio_gain_preset);
}
#endif
#ifdef SI3226X
if (pProslic->deviceId->chipType >= SI32260
&& pProslic->deviceId->chipType <= SI32269)
{
return Si3226x_dbgSetTXGain (pProslic,gain,impedance_preset,audio_gain_preset);
}
#endif
#ifdef SI3228X
if (pProslic->deviceId->chipType >= SI32280
&& pProslic->deviceId->chipType <= SI32289)
{
return Si3228x_dbgSetTXGain (pProslic,gain,impedance_preset,audio_gain_preset);
}
#endif
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
/*
** Function: ProSLIC_LineMonitor
**
** Description:
** Generic monitoring function
**
** Returns:
** 0
*/
int ProSLIC_LineMonitor (proslicChanType *pProslic, proslicMonitorType *monitor)
{
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (pProslic->deviceId->chipType >= SI32171
&& pProslic->deviceId->chipType <= SI32179)
{
return Si3217x_LineMonitor (pProslic, monitor);
}
#endif
#ifdef SI3218X
if (pProslic->deviceId->chipType >= SI32180
&& pProslic->deviceId->chipType <= SI32189)
{
return Si3218x_LineMonitor (pProslic, monitor);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(pProslic->deviceId) )
{
return Si3219x_LineMonitor (pProslic, monitor);
}
#endif
#ifdef SI3226X
if (pProslic->deviceId->chipType >= SI32260
&& pProslic->deviceId->chipType <= SI32269)
{
return Si3226x_LineMonitor (pProslic, monitor);
}
#endif
#ifdef SI3228X
if (pProslic->deviceId->chipType >= SI32280
&& pProslic->deviceId->chipType <= SI32289)
{
return Si3228x_LineMonitor (pProslic, monitor);
}
#endif
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
/*
** Function: ProSLIC_PSTNCheck
**
** Description:
** Monitor for excessive longitudinal current, which
** would be present if a live pstn line was connected
** to the port.
**
** Returns:
** 0 - no pstn detected
** 1 - pstn detected
*/
int ProSLIC_PSTNCheck (proslicChanType *pProslic,
proslicPSTNCheckObjType *pPSTNCheck)
{
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (pProslic->deviceId->chipType >= SI32171
&& pProslic->deviceId->chipType <= SI32179)
{
return Si3217x_PSTNCheck (pProslic,pPSTNCheck);
}
#endif
#ifdef SI3218X
if (pProslic->deviceId->chipType >= SI32180
&& pProslic->deviceId->chipType <= SI32189)
{
return Si3218x_PSTNCheck (pProslic,pPSTNCheck);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(pProslic->deviceId) )
{
return Si3219x_PSTNCheck (pProslic,pPSTNCheck);
}
#endif
#ifdef SI3226X
if (pProslic->deviceId->chipType >= SI32260
&& pProslic->deviceId->chipType <= SI32269)
{
return Si3226x_PSTNCheck (pProslic,pPSTNCheck);
}
#endif
#ifdef SI3228X
if (pProslic->deviceId->chipType >= SI32280
&& pProslic->deviceId->chipType <= SI32289)
{
return Si3228x_PSTNCheck (pProslic,pPSTNCheck);
}
#endif
return RC_COMPLETE_NO_ERR;
}
/*****************************************************************************************************/
/*
** Function: ProSLIC_DiffPSTNCheck
**
** Description:
** Monitor for excessive longitudinal current, which
** would be present if a live pstn line was connected
** to the port.
**
** Returns:
** RC_NONE - test in progress
** RC_IGNORE - non-ProSLIC channel
** RC_COMPLETE_NO_ERR - ProSLIC does not support feature.
** RC_PSTN_OPEN_FEMF | RC_COMPLETE_NO_ERR - test completed.
**
*/
#ifdef PSTN_DET_ENABLE
int ProSLIC_DiffPSTNCheck (proslicChanType *pProslic,
proslicDiffPSTNCheckObjType *pPSTNCheck)
{
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
if (pProslic->deviceId->chipType >= SI32171
&& pProslic->deviceId->chipType <= SI32179)
{
return Si3217x_DiffPSTNCheck (pProslic,pPSTNCheck);
}
#endif
#ifdef SI3218X
if (pProslic->deviceId->chipType >= SI32180
&& pProslic->deviceId->chipType <= SI32189)
{
return Si3218x_DiffPSTNCheck (pProslic,pPSTNCheck);
}
#endif
#ifdef SI3219X
if ( IS_SI3219X(pProslic->deviceId) )
{
return Si3219x_DiffPSTNCheck (pProslic,pPSTNCheck);
}
#endif
#ifdef SI3226X
if (pProslic->deviceId->chipType >= SI32260
&& pProslic->deviceId->chipType <= SI32269)
{
return Si3226x_DiffPSTNCheck (pProslic,pPSTNCheck);
}
#endif
#ifdef SI3228X
if (pProslic->deviceId->chipType >= SI32280
&& pProslic->deviceId->chipType <= SI32289)
{
return Si3228x_DiffPSTNCheck (pProslic,pPSTNCheck);
}
#endif
return RC_COMPLETE_NO_ERR;
}
#endif
/*****************************************************************************************************/
/*
** Function: ProSLIC_CreatePSTNCheckObj
**
** Description:
** Allocate memory for pstnCheckObj
**
** Returns:
** RC_NONE
** RC_NO_MEM if failed to allocate memory.
** RC_UNSUPPORTED_FEATER if malloc disabled
*/
int ProSLIC_CreatePSTNCheckObjs(proslicPSTNCheckObjType_ptr *pstnCheckObj,
unsigned int num_objs)
{
TRACEPRINT_NOCHAN("num_objs = %u\n", num_objs);
#ifndef DISABLE_MALLOC
*pstnCheckObj = SIVOICE_CALLOC(sizeof(proslicPSTNCheckObjType),num_objs);
if(*pstnCheckObj == NULL)
{
#ifdef ENABLE_DEBUG
LOGPRINT("%s: %s: failed to allocate memory", LOGPRINT_PREFIX, __FUNCTION__);
#endif
return RC_NO_MEM;
}
return RC_NONE;
#else
SILABS_UNREFERENCED_PARAMETER(pstnCheckObj);
SILABS_UNREFERENCED_PARAMETER(num_objs);
return RC_UNSUPPORTED_FEATURE;
#endif
}
/*****************************************************************************************************/
/*
** Function: ProSLIC_CreateDiffPSTNCheckObjs
**
** Description:
** Allocate memory for proslicDiffPstnCheckObjs
**
** Returns:
** RC_NONE
** RC_NO_MEM if failed to allocate memory.
** RC_UNSUPPORTED_FEATURE if malloc disabled
*/
#ifdef PSTN_DET_ENABLE
int ProSLIC_CreateDiffPSTNCheckObjs(proslicDiffPSTNCheckObjType_ptr
*pstnCheckObj, unsigned int num_objs)
{
TRACEPRINT_NOCHAN("num_objs = %u\n", num_objs);
#ifndef DISABLE_MALLOC
*pstnCheckObj = SIVOICE_CALLOC(sizeof(proslicDiffPSTNCheckObjType),num_objs);
if(*pstnCheckObj == NULL)
{
#ifdef ENABLE_DEBUG
LOGPRINT("%s: %s: failed to allocate memory", LOGPRINT_PREFIX, __FUNCTION__);
#endif
return RC_NO_MEM;
}
return RC_NONE;
#else
SILABS_UNREFERENCED_PARAMETER(pstnCheckObj);
SILABS_UNREFERENCED_PARAMETER(num_objs);
return RC_UNSUPPORTED_FEATURE;
#endif
}
#endif
/*****************************************************************************************************/
/*
** Function: ProSLIC_DestroyPSTNCheckObjs
**
** Description:
** Free memory for pstnCheckObj
**
** Returns:
** RC_NONE
** RC_UNSUPPORTED_FEATER if malloc disabled
*/
int ProSLIC_DestroyPSTNCheckObjs(proslicPSTNCheckObjType_ptr *pstnCheckObj)
{
TRACEPRINT_NOCHAN("\n", NULL);
#ifndef DISABLE_MALLOC
if(pstnCheckObj)
{
SIVOICE_FREE((proslicPSTNCheckObjType_ptr)*pstnCheckObj);
}
return RC_NONE;
#else
SILABS_UNREFERENCED_PARAMETER(pstnCheckObj);
return RC_UNSUPPORTED_FEATURE;
#endif
}
/*****************************************************************************************************/
/*
** Function: ProSLIC_DestroyDiffPSTNCheckObjs
**
** Description:
** Free memory for pstnDiffCheckObj
**
** Returns:
** RC_NONE
** RC_UNSUPPORTED_FEATER if malloc disabled
*/
#ifdef PSTN_DET_ENABLE
int ProSLIC_DestroyDiffPSTNCheckObjs(proslicDiffPSTNCheckObjType_ptr
*pstnCheckObj)
{
TRACEPRINT_NOCHAN("\n", NULL);
#ifndef DISABLE_MALLOC
if(pstnCheckObj)
{
SIVOICE_FREE((proslicDiffPSTNCheckObjType_ptr)*pstnCheckObj);
}
return RC_NONE;
#else
SILABS_UNREFERENCED_PARAMETER(pstnCheckObj);
return RC_UNSUPPORTED_FEATURE;
#endif
}
#endif
/*****************************************************************************************************/
/*
** Function: ProSLIC_InitPSTNCheckObj
**
** Description:
** Initialize pstnCheckObj structure members
**
** Returns:
** RC_NONE
*/
int ProSLIC_InitPSTNCheckObj(proslicPSTNCheckObjType_ptr pstnCheckObj,
int32 avgThresh, int32 singleThresh, uInt8 samples)
{
TRACEPRINT_NOCHAN("avgThres = %d singleThresh = %d samples = %u\n", avgThresh,
avgThresh, samples);
pstnCheckObj->avgThresh = avgThresh;
pstnCheckObj->singleThresh = singleThresh;
pstnCheckObj->samples = samples;
pstnCheckObj->avgIlong = 0;
pstnCheckObj->count = 0;
pstnCheckObj->buffFull = 0;
return RC_NONE;
}
/*****************************************************************************************************/
/*
** Function: ProSLIC_InitDiffPSTNCheckObj
**
** Description:
** Initialize pstnCheckObj structure members
**
** Returns:
** RC_NONE
*/
#ifdef PSTN_DET_ENABLE
int ProSLIC_InitDiffPSTNCheckObj(proslicDiffPSTNCheckObjType_ptr
pstnDiffCheckObj,
int preset1,
int preset2,
int entry_preset,
int femf_enable)
{
TRACEPRINT_NOCHAN("p1 = %d p2 = %d ep = %d femf_enable = %d\n", preset1,
preset2, entry_preset, femf_enable);
pstnDiffCheckObj->samples = PSTN_DET_DIFF_SAMPLES;
pstnDiffCheckObj->max_femf_vopen = PSTN_DET_MAX_FEMF;
pstnDiffCheckObj->entryDCFeedPreset = entry_preset;
pstnDiffCheckObj->dcfPreset1 = preset1;
pstnDiffCheckObj->dcfPreset2 = preset2;
pstnDiffCheckObj->femf_enable = femf_enable;
pstnDiffCheckObj->pState.stage = 0;
pstnDiffCheckObj->pState.sampleIterations = 0;
pstnDiffCheckObj->pState.waitIterations = 0;
return RC_NONE;
}
#endif
/*****************************************************************************************************/
/*
** Function: ProSLIC_SetPwrsaveMode
**
** Description:
** Enable or disable powersave mode
**
** Returns:
** RC_NONE
*/
#define PROSLIC_REG_ENHANCE 47
int ProSLIC_SetPowersaveMode (proslicChanType *pProslic, int pwrsave)
{
uInt8 regData;
TRACEPRINT(pProslic, "pwrsave = %d\n", pwrsave);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
regData = ReadReg(pProslic,pProslic->channel, PROSLIC_REG_ENHANCE);
if(pwrsave == PWRSAVE_DISABLE)
{
#ifdef SI3217X
if (pProslic->deviceId->chipType >= SI32171
&& pProslic->deviceId->chipType <= SI32179)
{
regData &= 0x27;
}
else
{
#endif
regData &= 0x07;
#ifdef SI3217X
}
#endif
}
else
{
regData |= 0x10;
}
return WriteReg(pProslic,pProslic->channel, PROSLIC_REG_ENHANCE, regData);
}
/*****************************************************************************************************/
/*
** Function: ProSLIC_SetDAAEnable
**
** Description:
** Enable or disable adjacent FXO (Si32178 only)
**
** Returns:
** RC_NONE
*/
int ProSLIC_SetDAAEnable (proslicChanType *pProslic, int enable)
{
TRACEPRINT(pProslic, "\n", NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
#ifdef SI3217X
return Si3217x_SetDAAEnable (pProslic,enable);
#else
SILABS_UNREFERENCED_PARAMETER(enable);
return RC_NONE;
#endif
}
/*****************************************************************************************************/
/*
** Function: ProSLIC_SetUserMode
**
** Description: Enables User Access Mode (UAM) if the part supports it.
**
** Returns:
** RC_NONE if successful.
*/
#define PROSLIC_REG_USERMODE_ENABLE 126
int ProSLIC_SetUserMode(proslicChanType *pProslic,BOOLEAN isEnabled,
BOOLEAN isBcast)
{
uInt8 data;
uInt8 channel;
TRACEPRINT(pProslic, "enable = %d bcast = %d\n", (int)isEnabled, (int)isBcast);
if(isEnabled == FALSE)
{
return RC_NONE;
}
if( pProslic->channelType != PROSLIC )
{
return RC_UNSUPPORTED_FEATURE;
}
if(isBcast == TRUE)
{
channel = PROSLIC_CHAN_BROADCAST;
}
else
{
channel = pProslic->channel;
}
data = ReadReg(pProslic,pProslic->channel,
PROSLIC_REG_USERMODE_ENABLE); /*we check first channel. we assume all channels same user mode state for broadcast */
if (((data&1) != 0) == isEnabled)
{
return RC_NONE;
}
WriteReg(pProslic,channel,PROSLIC_REG_USERMODE_ENABLE,2);
WriteReg(pProslic,channel,PROSLIC_REG_USERMODE_ENABLE,8);
WriteReg(pProslic,channel,PROSLIC_REG_USERMODE_ENABLE,0xe);
return WriteReg(pProslic,channel,PROSLIC_REG_USERMODE_ENABLE,0);
}
/*****************************************************************************************************/
/*
** Function: ProSLIC_isReinitRequired
**
** Description:
** Checks for improper ring exit
**
** Returns:
** RC_NONE - Reinit not required
** RC_REINIT_REQUIRED - Corrupted state machine - reinit required
**
*/
int ProSLIC_isReinitRequired(proslicChanType *pProslic)
{
uInt8 lf;
ramData rkdc_sum;
TRACEPRINT(pProslic, "\n", NULL);
if( pProslic->channelType != PROSLIC)
{
return RC_IGNORE;
}
/* Check for improper ring exit which may cause dcfeed corruption */
lf = ReadReg(pProslic, pProslic->channel,PROSLIC_REG_LINEFEED);
rkdc_sum = ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_RDC_SUM);
DEBUG_PRINT(pProslic, "%sisReinitRequired: Linefeed = 0x%02X RDC_SUM = %d\n",
LOGPRINT_PREFIX, (int)lf, (int) rkdc_sum);
if((rkdc_sum & 0x400000)&&(lf != 0x44))
{
return RC_REINIT_REQUIRED;
}
else
{
return RC_NONE;
}
}
/*****************************************************************************************************/
/*
** Function: LoadRegTable
**
** Description:
** Generic function to load register/RAM with predefined addr/value
*/
int ProSLIC_LoadRegTable (proslicChanType *pProslic,
const ProslicRAMInit *pRamTable,
const ProslicRegInit *pRegTable,
int broadcast)
{
uInt16 i;
uInt8 channel;
TRACEPRINT(pProslic, "bcast = %d\n", broadcast);
/* DAA doesn't have a RAM table.. skip it... */
if( (pRamTable != 0)
&& (pProslic->channelType != PROSLIC) )
{
return RC_IGNORE;
}
if (broadcast)
{
channel = PROSLIC_CHAN_BROADCAST;
}
else
{
channel = pProslic->channel;
}
i=0;
if (pRamTable != 0)
{
while (pRamTable[i].address != 0xffff)
{
WriteRAM(pProslic,channel,pRamTable[i].address,pRamTable[i].initValue);
i++;
}
}
i=0;
if (pRegTable != 0)
{
while (pRegTable[i].address != 0xff)
{
WriteReg(pProslic,channel,pRegTable[i].address,pRegTable[i].initValue);
i++;
}
}
return RC_NONE;
}
/*****************************************************************************************************/
/*
** Function: LoadRegTables
**
** Description:
** Generic function to load register/RAM with predefined addr/value
*/
int ProSLIC_LoadRegTables(proslicChanType_ptr *pProslic,
const ProslicRAMInit *pRamTable, const ProslicRegInit *pRegTable, int size)
{
int i;
TRACEPRINT(*pProslic, "size = %d\n", size);
for (i=0; i<size; i++)
{
if (pProslic[i]->channelEnable)
{
ProSLIC_LoadRegTable(pProslic[i],pRamTable,pRegTable,FALSE);
}
}
return RC_NONE;
}
/*****************************************************************************************************/
int ProSLIC_UnsupportedFeatureNoArg(proslicChanType_ptr pProslic,
const char *function_name)
{
#ifdef ENABLE_DEBUG
LOGPRINT("%s: unsupported %s was called on channel %d\n", LOGPRINT_PREFIX,
function_name, pProslic->channel);
#else
SILABS_UNREFERENCED_PARAMETER(pProslic);
SILABS_UNREFERENCED_PARAMETER(function_name);
#endif
return RC_UNSUPPORTED_FEATURE;
}
/*****************************************************************************************************/
/*
** Function: ProSLIC_PSTN_delay_poll
**
** Description:
** Delay function called within PSTN detection functions
**
** Return Value:
** none
*/
#ifdef PSTN_DET_ENABLE
void ProSLIC_PSTN_delay_poll(proslicTestStateType *pState, uInt16 delay)
{
uInt16 delayCount;
if((delay/PSTN_DET_POLL_RATE) < 2)
{
delayCount = 0;
}
else
{
delayCount = (delay/PSTN_DET_POLL_RATE) - 2;
}
pState->waitIterations++;
if((pState->waitIterations == delayCount) || (delayCount == 0))
{
pState->waitIterations = 0;
pState->stage++;
}
}
#endif
/*****************************************************************************************************/
/*
** Function: ProSLIC_Calibrate
**
** Description:
** Performs calibration based on passed ptr to array of
** desired CALRn settings.
**
** Starts calibration on all channels sequentially (not broadcast)
** and continuously polls for completion. Return error code if
** CAL_EN does not clear for each enabled channel within the passed
** timeout period.
*/
int ProSLIC_Calibrate(proslicChanType_ptr *pProslic, int maxChan, uInt8 *calr,
int maxTime)
{
int i,j, cal_en;
int cal_en_chan = 0;
int timer = 0;
TRACEPRINT(*pProslic, "maxChan = %d time = %d\n", maxChan, maxTime );
if ((*pProslic)->channelType != PROSLIC)
{
return RC_CHANNEL_TYPE_ERR;
}
for(i = 0; i < maxChan; i++)
{
if((pProslic[i]->channelEnable)&&(pProslic[i]->channelType == PROSLIC))
{
for(j = 0; j < 4; j++)
{
WriteReg(pProslic[i], pProslic[i]->channel, (PROSLIC_REG_CALR0+j), calr[j]);
}
}
}
/* Wait for calibration to complete */
do
{
cal_en = 0;
DelayX(*pProslic, 10);
for(i = 0; i < maxChan; i++)
{
if( (pProslic[i]->channelEnable) && (pProslic[i]->channelType == PROSLIC))
{
cal_en_chan = ReadReg(pProslic[i], pProslic[i]->channel, PROSLIC_REG_CALR3);
if( (cal_en_chan & 0x80) && (timer == maxTime) )
{
DEBUG_PRINT(pProslic[i], "%sCalibration timed out on channel %d\n",
LOGPRINT_PREFIX, pProslic[i]->channel);
pProslic[i]->channelEnable = 0;
pProslic[i]->error = RC_CAL_TIMEOUT;
}
cal_en |= cal_en_chan;
}
}
}
while( (timer++ <= maxTime) && (cal_en & 0x80) );
if(timer <= maxTime)
{
return RC_NONE;
}
else
{
return RC_CAL_TIMEOUT;
}
}
/*****************************************************************************************************/
/* This function is used by the xxxx_Init_with_Options - do not call this directly... */
int ProSLIC_ReInit_helper(proslicChanType_ptr *pProslic, int size,
initOptionsType init_option, int numChanPerDevice)
{
int i;
/* Preserve linefeed state.. */
for(i = 0; i < size; i++)
{
pProslic[i]->scratch = ReadReg( pProslic[i], pProslic[i]->channel,
PROSLIC_REG_LINEFEED);
ProSLIC_PowerDownConverter( pProslic[i] );
/* Clear MSTRSTAT on a device basis */
if( (numChanPerDevice == 1)
|| ((numChanPerDevice == 2) && ((i&1) == 0) ) )
{
ProSLIC_WriteReg(pProslic[i], PROSLIC_REG_MSTRSTAT, 0xFF); /* Clear master status register */
}
}
DelayX(*pProslic, 10); /* Wait to ensure system is powered down... */
/* Do a soft reset if reinit is requested...*/
if(init_option == INIT_REINIT)
{
for(i = 0; i < size; i++)
{
if(numChanPerDevice == 2)
{
WriteReg(pProslic[i], (pProslic[i])->channel, PROSLIC_REG_RESET,
(((pProslic[i])->channel)&1)+1); /* reset 1 channel at a time */
}
else
{
WriteReg(pProslic[i], (pProslic[i])->channel, PROSLIC_REG_RESET, 1);
}
pProslic[i]->error = RC_NONE; /* Clear any errors we may have seen in powering down the converter */
}
DelayX(*pProslic, 100); /* Wait for a soft reset */
}
return RC_NONE;
}
/*****************************************************************************************************/
int ProSLIC_SoftReset(proslicChanType_ptr pProslic, uInt16 resetOptions)
{
uInt8 data;
TRACEPRINT(pProslic, "reset option: %d\n",resetOptions);
/* We can't use channelType since it may not been set. We assume at least
* SWInit was called... */
if( pProslic->deviceId->chipType == SI3050 )
{
return RC_CHANNEL_TYPE_ERR;
}
/* Check if we're in free-run mode, if so abort */
data = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_ENHANCE);
if(data & 0x6)
{
return RC_PLL_FREERUN_ACTIVE;
}
if(resetOptions & PROSLIC_BCAST_RESET)
{
return WriteReg(pProslic, PROSLIC_CHAN_BROADCAST, PROSLIC_REG_RESET, (uInt8)(resetOptions & 0xFF));
}
else
{
return WriteReg(pProslic, pProslic->channel, PROSLIC_REG_RESET, (uInt8)(resetOptions & 0xFF));
}
}
/*****************************************************************************************************/
#ifndef DISABLE_TONE_SETUP
int ProSLIC_ToneGenSetupPtr(proslicChanType_ptr pProslic, ProSLIC_Tone_Cfg *cfg)
{
TRACEPRINT(pProslic, "\n",NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_CHANNEL_TYPE_ERR;
}
WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC1FREQ, cfg->osc1.freq);
WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC1AMP, cfg->osc1.amp);
WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC1PHAS, cfg->osc1.phas);
WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O1TAHI,cfg->osc1.tahi);
WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O1TALO,cfg->osc1.talo);
WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O1TIHI,cfg->osc1.tihi);
WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O1TILO,cfg->osc1.tilo);
WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC2FREQ, cfg->osc2.freq);
WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC2AMP, cfg->osc2.amp);
WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC2PHAS, cfg->osc2.phas);
WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O2TAHI,cfg->osc2.tahi);
WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O2TALO,cfg->osc2.talo);
WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O2TIHI,cfg->osc2.tihi);
WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O2TILO,cfg->osc2.tilo);
WriteReg(pProslic, pProslic->channel,PROSLIC_REG_OMODE,cfg->omode);
return RC_NONE;
}
#endif /* DISABLE_TONE_SETUP */
/*****************************************************************************************************/
#ifndef DISABLE_FSK_SETUP
int ProSLIC_FSKSetupPtr (proslicChanType_ptr pProslic, ProSLIC_FSK_Cfg *cfg)
{
uInt8 data;
int i;
TRACEPRINT(pProslic, "\n",NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_CHANNEL_TYPE_ERR;
}
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_FSKDEPTH,
0x08); /* Clear Buffer */
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_O1TAHI,0);
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_O1TIHI,0);
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_O1TILO,0);
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_O1TALO,0x13);
data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE);
if (cfg->eightBit)
{
data |= 0x80;
}
else
{
data &= ~(0x80);
}
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_FSKDEPTH,cfg->fskdepth);
WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE,data);
for(i = 0; i < 2; i++)
{
WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_FSK01+i,cfg->fsk[i]);
WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_FSKAMP0+i,cfg->fskamp[i]);
WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_FSKFREQ0+i,cfg->fskfreq[i]);
}
return RC_NONE;
}
#endif
/*****************************************************************************************************/
int ProSLIC_EnableFastRingStart(proslicChanType_ptr pProslic, BOOLEAN isEnabled)
{
uInt8 data;
TRACEPRINT(pProslic, "\n",NULL);
if(pProslic->channelType != PROSLIC)
{
return RC_CHANNEL_TYPE_ERR;
}
#if defined(SI3217X) && !defined(Si3217X_REVC_ONLY)
if (pProslic->deviceId->chipType >= SI32171
&& pProslic->deviceId->chipType <= SI32179)
{
if(pProslic->deviceId->chipRev < 2)
{
return RC_UNSUPPORTED_FEATURE;
}
}
#endif
data = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_USERSTAT);
if( isEnabled )
{
data |= 8;
}
else
{
data &= ~8;
}
return WriteReg(pProslic, pProslic->channel, PROSLIC_REG_USERSTAT, data);
}