578 lines
16 KiB
C
578 lines
16 KiB
C
|
|
||
|
#include "voiceband/daa/daa.h"
|
||
|
#include "voiceband/tdm/mvTdm.h"
|
||
|
|
||
|
#undef DEBUG
|
||
|
#ifdef DEBUG
|
||
|
#define DBG(fmt, arg...) mvOsPrintf(KERN_INFO fmt, ##arg)
|
||
|
#else
|
||
|
#define DBG(fmt, arg...)
|
||
|
#endif
|
||
|
|
||
|
/* Static APIs */
|
||
|
static unsigned char mvDaaDirectRegRead(unsigned int lineId, unsigned char address);
|
||
|
static void mvDaaDirectRegWrite(unsigned int lineId, unsigned char address, unsigned char data);
|
||
|
static void mvDaaPrintInfo(unsigned int lineId);
|
||
|
static void mvDaaIntEnable(unsigned int lineId);
|
||
|
static void mvDaaIntDisable(unsigned int lineId);
|
||
|
static void mvDaaPcmStartCountRegsSet(unsigned int lineId);
|
||
|
static int mvDaaIntCheck(unsigned int lineId);
|
||
|
static void mvDaaCalibrate(unsigned int lineId);
|
||
|
static void mvDaaDigitalHybridSet(unsigned int index, unsigned int lineId);
|
||
|
|
||
|
typedef struct {
|
||
|
unsigned char lineId;
|
||
|
unsigned short txSample;
|
||
|
unsigned short rxSample;
|
||
|
unsigned char hook;
|
||
|
unsigned char ring;
|
||
|
unsigned char reverse_polarity;
|
||
|
unsigned char drop_out;
|
||
|
|
||
|
} MV_DAA_LINE_INFO;
|
||
|
|
||
|
#define COUNTRY_INDEX 29 /* SET TO ISRAEL */
|
||
|
#define NUM_OF_REGS 59
|
||
|
#define SPI_READ_CONTROL_BYTE 0x60
|
||
|
#define SPI_WRITE_CONTROL_BYTE 0x20
|
||
|
|
||
|
static MV_DAA_LINE_INFO* daaLineInfo = NULL;
|
||
|
static int totalDAAs = 0;
|
||
|
static unsigned char spiMode;
|
||
|
static mv_band_mode_t mvBandMode;
|
||
|
static mv_pcm_format_t mvPcmFormat;
|
||
|
static unsigned short firstDaa = 0;
|
||
|
static unsigned short lastDaa = 0;
|
||
|
|
||
|
static struct MV_DAA_MODE {
|
||
|
char *name;
|
||
|
int ohs;
|
||
|
int ohs2;
|
||
|
int rz;
|
||
|
int rt;
|
||
|
int ilim;
|
||
|
int dcv;
|
||
|
int mini;
|
||
|
int acim;
|
||
|
} daaModes[] =
|
||
|
{
|
||
|
{ "ARGENTINA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "AUSTRALIA", 1, 0, 0, 0, 0, 0, 0x3, 0x3, },
|
||
|
{ "AUSTRIA", 0, 1, 0, 0, 1, 0x3, 0, 0x3, },
|
||
|
{ "BAHRAIN", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "BELGIUM", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "BRAZIL", 0, 0, 0, 0, 0, 0, 0x3, 0, },
|
||
|
{ "BULGARIA", 0, 0, 0, 0, 1, 0x3, 0x0, 0x3, },
|
||
|
{ "CANADA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "CHILE", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "CHINA", 0, 0, 0, 0, 0, 0, 0x3, 0xf, },
|
||
|
{ "COLUMBIA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "CROATIA", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "CYRPUS", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "CZECH", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "DENMARK", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "ECUADOR", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "EGYPT", 0, 0, 0, 0, 0, 0, 0x3, 0, },
|
||
|
{ "ELSALVADOR", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "FINLAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "FRANCE", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "GERMANY", 0, 1, 0, 0, 1, 0x3, 0, 0x3, },
|
||
|
{ "GREECE", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "GUAM", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "HONGKONG", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "HUNGARY", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "ICELAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "INDIA", 0, 0, 0, 0, 0, 0x3, 0, 0x4, },
|
||
|
{ "INDONESIA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "IRELAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "ISRAEL", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "ITALY", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "JAPAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
|
||
|
{ "JORDAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
|
||
|
{ "KAZAKHSTAN", 0, 0, 0, 0, 0, 0x3, 0, },
|
||
|
{ "KUWAIT", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "LATVIA", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "LEBANON", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "LUXEMBOURG", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "MACAO", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "MALAYSIA", 0, 0, 0, 0, 0, 0, 0x3, 0, }, /* Current loop >= 20ma */
|
||
|
{ "MALTA", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "MEXICO", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "MOROCCO", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "NETHERLANDS", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "NEWZEALAND", 0, 0, 0, 0, 0, 0x3, 0, 0x4, },
|
||
|
{ "NIGERIA", 0, 0, 0, 0, 0x1, 0x3, 0, 0x2, },
|
||
|
{ "NORWAY", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "OMAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
|
||
|
{ "PAKISTAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
|
||
|
{ "PERU", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "PHILIPPINES", 0, 0, 0, 0, 0, 0, 0x3, 0, },
|
||
|
{ "POLAND", 0, 0, 1, 1, 0, 0x3, 0, 0, },
|
||
|
{ "PORTUGAL", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "ROMANIA", 0, 0, 0, 0, 0, 3, 0, 0, },
|
||
|
{ "RUSSIA", 0, 0, 0, 0, 0, 0, 0x3, 0, },
|
||
|
{ "SAUDIARABIA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "SINGAPORE", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "SLOVAKIA", 0, 0, 0, 0, 0, 0x3, 0, 0x3, },
|
||
|
{ "SLOVENIA", 0, 0, 0, 0, 0, 0x3, 0, 0x2, },
|
||
|
{ "SOUTHAFRICA", 1, 0, 1, 0, 0, 0x3, 0, 0x3, },
|
||
|
{ "SOUTHKOREA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "SPAIN", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "SWEDEN", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "SWITZERLAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
|
||
|
{ "TAIWAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
|
||
|
{ "TBR21", 0, 0, 0, 0, 1, 0x3, 0, 0x2/*, 0x7e6c, 0x023a, */},
|
||
|
/* Austria, Belgium, Denmark, Finland, France, Germany, Greece, Iceland, Ireland, Italy, Luxembourg, Netherlands,
|
||
|
Norway, Portugal, Spain, Sweden, Switzerland, and UK */
|
||
|
{ "THAILAND", 0, 0, 0, 0, 0, 0, 0x3, 0, },
|
||
|
{ "UAE", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "UK", 0, 1, 0, 0, 1, 0x3, 0, 0x5, },
|
||
|
{ "USA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "YEMEN", 0, 0, 0, 0, 0, 0x3, 0, 0, },
|
||
|
{ "FCC", 0, 0, 0, 1, 0, 0x3, 0, 0, }, /* US, Canada */
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
static unsigned char mvDaaDirectRegRead(unsigned int lineId, unsigned char address)
|
||
|
{
|
||
|
unsigned char data;
|
||
|
|
||
|
mvVbSpiRead(lineId, address, MV_LINE_FXO, &data);
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
static void mvDaaDirectRegWrite(unsigned int lineId, unsigned char address, unsigned char data)
|
||
|
{
|
||
|
mvVbSpiWrite(lineId, address, MV_LINE_FXO, data);
|
||
|
}
|
||
|
|
||
|
static void mvDaaPrintInfo(unsigned int lineId)
|
||
|
{
|
||
|
unsigned char reg11;
|
||
|
|
||
|
reg11 = mvDaaDirectRegRead(lineId, DAA_SYSTEM_AND_LINE_SIDE_REV_REG);
|
||
|
if(reg11)
|
||
|
{
|
||
|
DBG("DAA Si3050 Detected.\n");
|
||
|
|
||
|
switch((reg11 & DAA_LINE_SIDE_ID_MASK))
|
||
|
{
|
||
|
case DAA_SI3018 : DBG("Line Side ID: Si3018\n");
|
||
|
break;
|
||
|
|
||
|
case DAA_SI3019 : DBG("Line Side ID: Si3019\n");
|
||
|
break;
|
||
|
|
||
|
default: DBG("Unkown Line Side ID\n");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
switch((reg11 & DAA_SYSTEM_SIDE_REVISION_MASK))
|
||
|
{
|
||
|
case DAA_SYSTEM_SIDE_REV_A: DBG("System Side Revision: A\n");
|
||
|
break;
|
||
|
|
||
|
case DAA_SYSTEM_SIDE_REV_B: DBG("System Side Revision: B\n");
|
||
|
break;
|
||
|
|
||
|
case DAA_SYSTEM_SIDE_REV_C: DBG("System Side Revision: C\n");
|
||
|
break;
|
||
|
|
||
|
case DAA_SYSTEM_SIDE_REV_D: DBG("System Side Revision: D\n");
|
||
|
break;
|
||
|
|
||
|
default: DBG("Unkonwn System Side Revision\n");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
DBG("DAA Country Settings: %s\n",daaModes[COUNTRY_INDEX].name);
|
||
|
}
|
||
|
else
|
||
|
mvOsPrintf("Error, unable to communicate with DAA\n");
|
||
|
|
||
|
}
|
||
|
|
||
|
MV_STATUS mvDaaInit(unsigned short first, unsigned short last, unsigned short pSlotInfo[][2],
|
||
|
unsigned short lines, mv_band_mode_t bandMode, mv_pcm_format_t pcmFormat)
|
||
|
{
|
||
|
unsigned char reg2 = 0, reg24 = 0, reg33 = 0;
|
||
|
unsigned short newDelay, lineId;
|
||
|
MV_DAA_LINE_INFO *pDaaLineInfo;
|
||
|
int lineSideId;
|
||
|
|
||
|
MV_TRC_REC("->%s\n", __FUNCTION__);
|
||
|
|
||
|
/* Save parameters */
|
||
|
firstDaa = first;
|
||
|
lastDaa = last;
|
||
|
mvBandMode = bandMode;
|
||
|
mvPcmFormat = pcmFormat;
|
||
|
totalDAAs = last -first + 1;
|
||
|
spiMode = mvBoardTdmSpiModeGet();
|
||
|
|
||
|
/* Allocate MV_DAA_LINE_INFO array */
|
||
|
daaLineInfo = (MV_DAA_LINE_INFO*)mvOsMalloc(sizeof(MV_DAA_LINE_INFO) * lines);
|
||
|
if(!daaLineInfo)
|
||
|
{
|
||
|
mvOsPrintf("%s: allocation failed(daaLineInfo) !!!\n",__FUNCTION__);
|
||
|
return MV_ERROR;
|
||
|
}
|
||
|
|
||
|
pDaaLineInfo = (MV_DAA_LINE_INFO*)(daaLineInfo + first);
|
||
|
|
||
|
mvOsPrintf("Start initialization for DAA modules %u to %u...",first, last);
|
||
|
|
||
|
for(lineId = first; lineId < (last+1); lineId++)
|
||
|
{
|
||
|
pDaaLineInfo->lineId = lineId;
|
||
|
pDaaLineInfo->hook = 0;
|
||
|
pDaaLineInfo->ring = 0;
|
||
|
pDaaLineInfo->reverse_polarity = 0;
|
||
|
pDaaLineInfo->drop_out = 0;
|
||
|
|
||
|
/* Software reset */
|
||
|
mvDaaDirectRegWrite(lineId, 1, 0x80);
|
||
|
|
||
|
/* Wait just a bit */
|
||
|
mvOsDelay(100);
|
||
|
|
||
|
mvDaaDigitalHybridSet(COUNTRY_INDEX, lineId);
|
||
|
|
||
|
/* Configure tx/rx sample in DAA */
|
||
|
pDaaLineInfo->rxSample = pSlotInfo[lineId][0];
|
||
|
pDaaLineInfo->txSample = pSlotInfo[lineId][0];
|
||
|
DBG("Rx sample %d, Tx sample %d\n",pDaaLineInfo->rxSample, pDaaLineInfo->txSample);
|
||
|
pDaaLineInfo->txSample *= 8;
|
||
|
pDaaLineInfo->rxSample *= 8;
|
||
|
|
||
|
mvDaaPcmStartCountRegsSet(lineId);
|
||
|
|
||
|
/* Enable PCM & linear 16-bit/a-Law 8-bit/u-Law 8-bit */
|
||
|
switch(pcmFormat)
|
||
|
{
|
||
|
case MV_PCM_FORMAT_ALAW:
|
||
|
case MV_PCM_FORMAT_ULAW:
|
||
|
case MV_PCM_FORMAT_LINEAR:
|
||
|
reg33 = (0x20 | (pcmFormat << 3));
|
||
|
mvDaaDirectRegWrite(lineId, 33, reg33);
|
||
|
break;
|
||
|
default:
|
||
|
mvOsPrintf("Error, wrong pcm format(%d)\n", pcmFormat);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* Enable full wave rectifier */
|
||
|
mvDaaDirectRegWrite(lineId, DAA_INTERNATIONAL_CONTROL_3, DAA_RFWE);
|
||
|
|
||
|
/* Disable interrupts */
|
||
|
mvDaaIntDisable(lineId);
|
||
|
|
||
|
/* Set AOUT/INT pin as hardware interrupt */
|
||
|
reg2 = mvDaaDirectRegRead(lineId, DAA_CONTROL_2_REG);
|
||
|
mvDaaDirectRegWrite(lineId, DAA_CONTROL_2_REG, (reg2 | DAA_INTE));
|
||
|
|
||
|
/* Enable ISO-Cap */
|
||
|
mvDaaDirectRegWrite(lineId, DAA_DAA_CONTROL_2, 0);
|
||
|
|
||
|
/* Wait 2000ms for ISO-cap to come up */
|
||
|
newDelay = 2000;
|
||
|
while(newDelay > 0 && !(mvDaaDirectRegRead(lineId, DAA_SYSTEM_AND_LINE_SIDE_REV_REG) & 0xf0))
|
||
|
{
|
||
|
mvOsDelay(100);
|
||
|
newDelay -= 100;
|
||
|
}
|
||
|
|
||
|
lineSideId = mvDaaDirectRegRead(lineId, DAA_SYSTEM_AND_LINE_SIDE_REV_REG);
|
||
|
|
||
|
if (!(lineSideId & 0xf0))
|
||
|
{
|
||
|
mvOsPrintf("Error: DAA did not bring up ISO link properly!\n");
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/* Perform ADC manual calibration */
|
||
|
mvDaaCalibrate(lineId);
|
||
|
|
||
|
/* Enable Ring Validation */
|
||
|
reg24 = mvDaaDirectRegRead(lineId, DAA_RING_VALIDATION_CONTROL_3);
|
||
|
|
||
|
mvDaaDirectRegWrite(lineId, DAA_RING_VALIDATION_CONTROL_3 , reg24 | DAA_RNGV);
|
||
|
|
||
|
|
||
|
/* Print DAA info */
|
||
|
mvDaaPrintInfo(lineId);
|
||
|
|
||
|
MV_TRC_REC("ISO-Cap is now up, line side: %02x rev %02x\n",
|
||
|
mvDaaDirectRegRead(lineId, 11) >> 4,
|
||
|
( mvDaaDirectRegRead(lineId, 13) >> 2) & 0xf);
|
||
|
|
||
|
|
||
|
/* raise tx gain by 7 dB for NEWZEALAND */
|
||
|
if (!strcmp(daaModes[COUNTRY_INDEX].name, "NEWZEALAND"))
|
||
|
{
|
||
|
MV_TRC_REC("Adjusting gain\n");
|
||
|
mvDaaDirectRegWrite(lineId, 38, 0x7);
|
||
|
}
|
||
|
/* enable interrupts */
|
||
|
mvDaaIntEnable(lineId);
|
||
|
|
||
|
/* Goto next DAA module */
|
||
|
pDaaLineInfo++;
|
||
|
}
|
||
|
|
||
|
mvOsPrintf("Done\n");
|
||
|
MV_TRC_REC("<-%s\n", __FUNCTION__);
|
||
|
|
||
|
return MV_OK;
|
||
|
}
|
||
|
|
||
|
static void mvDaaIntEnable(unsigned int lineId)
|
||
|
{
|
||
|
MV_TRC_REC("enable daa-%d interrupts\n", lineId);
|
||
|
|
||
|
/* first, clear source register */
|
||
|
mvDaaDirectRegWrite(lineId, DAA_INTERRUPT_SOURCE_REG, 0);
|
||
|
/* enable interrupts in mask register */
|
||
|
mvDaaDirectRegWrite(lineId, DAA_INTERRUPT_MASK_REG, (DAA_DODM | DAA_RDTM));
|
||
|
}
|
||
|
|
||
|
static void mvDaaIntDisable(unsigned int lineId)
|
||
|
{
|
||
|
MV_TRC_REC("disable daa-%d interrupts\n", lineId);
|
||
|
mvDaaDirectRegWrite(lineId, DAA_INTERRUPT_MASK_REG, 0);
|
||
|
}
|
||
|
|
||
|
static void mvDaaPcmStartCountRegsSet(unsigned int lineId)
|
||
|
{
|
||
|
MV_DAA_LINE_INFO *pDaaLineInfo = (MV_DAA_LINE_INFO*)(daaLineInfo + lineId);
|
||
|
mvDaaDirectRegWrite(lineId, 34 , pDaaLineInfo->txSample&0xff);
|
||
|
mvDaaDirectRegWrite(lineId, 35 , (pDaaLineInfo->txSample>>8)&0x3);
|
||
|
mvDaaDirectRegWrite(lineId, 36 , pDaaLineInfo->rxSample&0xff);
|
||
|
mvDaaDirectRegWrite(lineId, 37 , (pDaaLineInfo->rxSample>>8)&0x3);
|
||
|
|
||
|
}
|
||
|
|
||
|
static int mvDaaIntCheck(unsigned int lineId)
|
||
|
{
|
||
|
unsigned char cause , mask, control, cause_and_mask;
|
||
|
MV_DAA_LINE_INFO *pDaaLineInfo = (MV_DAA_LINE_INFO*)(daaLineInfo + lineId);
|
||
|
|
||
|
cause = mvDaaDirectRegRead(lineId, DAA_INTERRUPT_SOURCE_REG);
|
||
|
mask = mvDaaDirectRegRead(lineId, DAA_INTERRUPT_MASK_REG);
|
||
|
cause_and_mask = cause & mask;
|
||
|
|
||
|
/* check ring */
|
||
|
if(cause_and_mask & DAA_RDTI)
|
||
|
{
|
||
|
MV_TRC_REC("Ring Detected\n");
|
||
|
pDaaLineInfo->ring = 1;
|
||
|
mvDaaDirectRegWrite(lineId, DAA_INTERRUPT_MASK_REG, (mask & ~DAA_POLM));
|
||
|
control = mvDaaDirectRegRead(lineId, DAA_DAA_CONTROL_2);
|
||
|
mvDaaDirectRegWrite(lineId, DAA_DAA_CONTROL_2, (control & (~DAA_PDL)));
|
||
|
}
|
||
|
|
||
|
/* check parallel phone detection */
|
||
|
if(cause_and_mask & DAA_DODI)
|
||
|
{
|
||
|
MV_TRC_REC("Drop Out Detected\n");
|
||
|
pDaaLineInfo->drop_out = 1;
|
||
|
control = mvDaaDirectRegRead(lineId, DAA_DAA_CONTROL_2);
|
||
|
mvDaaDirectRegWrite(lineId, DAA_DAA_CONTROL_2, (control & (~DAA_PDL)));
|
||
|
}
|
||
|
/* check reverse polarity */
|
||
|
if(cause_and_mask & DAA_POLI)
|
||
|
{
|
||
|
MV_TRC_REC("Reverse Polarity Detected\n");
|
||
|
pDaaLineInfo->reverse_polarity = 1;
|
||
|
}
|
||
|
|
||
|
/* clear interrupts */
|
||
|
mvDaaDirectRegWrite(lineId, DAA_INTERRUPT_SOURCE_REG, (~cause_and_mask));
|
||
|
|
||
|
|
||
|
if(cause_and_mask)
|
||
|
return 1;
|
||
|
else
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
unsigned int mvDaaIntGet(unsigned short lineId)
|
||
|
{
|
||
|
unsigned char event = 0;
|
||
|
|
||
|
if(!mvDaaIntCheck(lineId))
|
||
|
return 0;
|
||
|
|
||
|
mvDaaEventGet(&event, lineId);
|
||
|
|
||
|
return event;
|
||
|
}
|
||
|
|
||
|
void mvDaaPstnStateSet(mv_hook_t hookstate, unsigned short lineId)
|
||
|
{
|
||
|
MV_DAA_LINE_INFO *pDaaLineInfo = (MV_DAA_LINE_INFO*)(daaLineInfo + lineId);
|
||
|
unsigned char reg3, reg5;
|
||
|
|
||
|
if(hookstate == MV_OFF_HOOK)
|
||
|
{
|
||
|
/* Set OFFHOOK */
|
||
|
MV_TRC_REC("DAA goes off-hook\n");
|
||
|
reg5 = mvDaaDirectRegRead(lineId, DAA_DAA_CONTROL_1);
|
||
|
mvDaaDirectRegWrite(lineId, DAA_DAA_CONTROL_1,(reg5 | DAA_OH));
|
||
|
pDaaLineInfo->hook = 1;
|
||
|
}
|
||
|
else if(hookstate == MV_ON_HOOK)
|
||
|
{
|
||
|
MV_TRC_REC("DAA goes on-hook\n");
|
||
|
/* First disable Drop Out interrupt */
|
||
|
reg3 = mvDaaDirectRegRead(lineId, DAA_INTERRUPT_MASK_REG);
|
||
|
mvDaaDirectRegWrite(lineId, DAA_INTERRUPT_MASK_REG, (reg3 & ~DAA_DODM));
|
||
|
/* Set ONHOOK */
|
||
|
reg5 = mvDaaDirectRegRead(lineId, DAA_DAA_CONTROL_1);
|
||
|
mvDaaDirectRegWrite(lineId, DAA_DAA_CONTROL_1, (reg5 & ~DAA_OH));
|
||
|
/* Enable Drop Out interrupt */
|
||
|
mvDaaDirectRegWrite(lineId, DAA_INTERRUPT_MASK_REG, reg3);
|
||
|
pDaaLineInfo->hook = 0;
|
||
|
}
|
||
|
else
|
||
|
mvOsPrintf("Unknown PSTN state\n");
|
||
|
}
|
||
|
|
||
|
static void mvDaaCalibrate(unsigned int lineId)
|
||
|
{
|
||
|
unsigned char reg17;
|
||
|
|
||
|
DBG("Start ADC calibration\n");
|
||
|
|
||
|
/* Set CALD bit */
|
||
|
reg17 = mvDaaDirectRegRead(lineId, DAA_INTERNATIONAL_CONTROL_2);
|
||
|
mvDaaDirectRegWrite(lineId, DAA_INTERNATIONAL_CONTROL_2, (reg17 | DAA_CALD));
|
||
|
|
||
|
/* Set MCAL bit */
|
||
|
reg17 = mvDaaDirectRegRead(lineId, DAA_INTERNATIONAL_CONTROL_2);
|
||
|
mvDaaDirectRegWrite(lineId, DAA_INTERNATIONAL_CONTROL_2, (reg17 | DAA_MCAL));
|
||
|
|
||
|
/* Reset MCAL bit - start ADC calibration */
|
||
|
reg17 = mvDaaDirectRegRead(lineId, DAA_INTERNATIONAL_CONTROL_2);
|
||
|
mvDaaDirectRegWrite(lineId, DAA_INTERNATIONAL_CONTROL_2, (reg17 & ~DAA_MCAL));
|
||
|
|
||
|
/* Must wait at least 256 ms */
|
||
|
mvOsDelay(256);
|
||
|
|
||
|
DBG("ADC calibration completed\n");
|
||
|
}
|
||
|
|
||
|
void mvDaaCidStateSet(cid_state_t cid_state, unsigned short lineId)
|
||
|
{
|
||
|
unsigned char reg5;
|
||
|
|
||
|
if(cid_state == CID_ON)
|
||
|
{
|
||
|
/* Enable on-hook line monitor */
|
||
|
mvDaaDirectRegWrite(lineId, DAA_DAA_CONTROL_1, DAA_ONHM);
|
||
|
}
|
||
|
else if(cid_state == CID_OFF)
|
||
|
{
|
||
|
reg5 = mvDaaDirectRegRead(lineId, DAA_DAA_CONTROL_1);
|
||
|
mvDaaDirectRegWrite(lineId, DAA_DAA_CONTROL_1,(reg5 & ~DAA_ONHM));
|
||
|
}
|
||
|
else
|
||
|
mvOsPrintf("%s: Unknown CID state\n",__FUNCTION__);
|
||
|
|
||
|
}
|
||
|
|
||
|
void mvDaaReversePolaritySet(long enable, unsigned int lineId)
|
||
|
{
|
||
|
unsigned char mask;
|
||
|
|
||
|
if(enable)
|
||
|
{
|
||
|
mask = mvDaaDirectRegRead(lineId, DAA_INTERRUPT_MASK_REG);
|
||
|
mvDaaDirectRegWrite(lineId, DAA_INTERRUPT_MASK_REG, (mask | DAA_POLM));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
mask = mvDaaDirectRegRead(lineId, DAA_INTERRUPT_MASK_REG);
|
||
|
mvDaaDirectRegWrite(lineId, DAA_INTERRUPT_MASK_REG, (mask & ~DAA_POLM));
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void mvDaaEventGet(unsigned char *eventType, unsigned int lineId)
|
||
|
{
|
||
|
MV_DAA_LINE_INFO *pDaaLineInfo = (MV_DAA_LINE_INFO*)(daaLineInfo + lineId);
|
||
|
|
||
|
if(pDaaLineInfo->ring)
|
||
|
{
|
||
|
*eventType |= DAA_RDTI;
|
||
|
pDaaLineInfo->ring = 0;
|
||
|
}
|
||
|
|
||
|
if(pDaaLineInfo->reverse_polarity)
|
||
|
{
|
||
|
*eventType |= DAA_POLI;
|
||
|
pDaaLineInfo->reverse_polarity = 0;
|
||
|
}
|
||
|
|
||
|
if(pDaaLineInfo->drop_out)
|
||
|
{
|
||
|
*eventType |= DAA_DODI;
|
||
|
pDaaLineInfo->drop_out = 0;
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
static void mvDaaDigitalHybridSet(unsigned int index, unsigned int lineId)
|
||
|
{
|
||
|
unsigned char reg16 = 0, reg26 = 0, reg30 = 0, reg31 = 0;
|
||
|
|
||
|
/* Set On-hook speed, Ringer impedence, and ringer threshold */
|
||
|
reg16 |= (daaModes[index].ohs << 6);
|
||
|
reg16 |= (daaModes[index].rz << 1);
|
||
|
reg16 |= (daaModes[index].rt);
|
||
|
mvDaaDirectRegWrite(lineId, 16, reg16);
|
||
|
|
||
|
/* Set DC Termination:
|
||
|
Tip/Ring voltage adjust, minimum operational current, current limitation */
|
||
|
reg26 |= (daaModes[index].dcv << 6);
|
||
|
reg26 |= (daaModes[index].mini << 4);
|
||
|
reg26 |= (daaModes[index].ilim << 1);
|
||
|
mvDaaDirectRegWrite(lineId, 26, reg26);
|
||
|
|
||
|
/* Set AC Impedence */
|
||
|
reg30 = (daaModes[index].acim);
|
||
|
mvDaaDirectRegWrite(lineId, 30, reg30);
|
||
|
|
||
|
/* Misc. DAA parameters */
|
||
|
reg31 = 0xa3;
|
||
|
reg31 |= (daaModes[index].ohs2 << 3);
|
||
|
mvDaaDirectRegWrite(lineId, 31, reg31);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
int mvDaaLineVoltageGet(unsigned int lineId)
|
||
|
{
|
||
|
return (int)(mvDaaDirectRegRead(lineId, DAA_LINE_VOLTAGE_STATUS));
|
||
|
|
||
|
}
|
||
|
|
||
|
void mvDaaRelease(void)
|
||
|
{
|
||
|
if(daaLineInfo)
|
||
|
mvOsFree(daaLineInfo);
|
||
|
}
|
||
|
|
||
|
void mvDaaRegsDump(unsigned int lineId)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
for(i=1; i < NUM_OF_REGS; i++)
|
||
|
MV_TRC_REC("Register %d: 0x%x\n",i, mvDaaDirectRegRead(lineId, i));
|
||
|
}
|
||
|
|