[][Add Proslic SI3218x audio codec driver]
[Description]
Add Proslic SI3218x audio codec driver
[Release-log]
N/A
Change-Id: I30edf714fda413b220b6a0f3e301a7bc3f899c08
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/5396999
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/proslic.c b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/proslic.c
new file mode 100644
index 0000000..7a75cc8
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/proslic.c
@@ -0,0 +1,4651 @@
+// 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);
+}
+