From 5f1ac35511b91a9683ce16398bc1c5b49098545e Mon Sep 17 00:00:00 2001 From: markster Date: Wed, 14 Sep 2005 04:46:47 +0000 Subject: Allow number of VPM spans with hardware echo can to be adjusted git-svn-id: http://svn.digium.com/svn/zaptel/trunk@765 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- wct4xxp.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 11 deletions(-) diff --git a/wct4xxp.c b/wct4xxp.c index 92bb889..a5cf785 100755 --- a/wct4xxp.c +++ b/wct4xxp.c @@ -174,6 +174,7 @@ static int loopback = 0; static int alarmdebounce = 0; #ifdef VPM_SUPPORT static int vpmsupport = 1; +static int vpmspans = 4; #define VPM_DEFAULT_DTMFTHRESHOLD 1000 static int dtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD; static int lastdtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD; @@ -691,6 +692,25 @@ static int t4_dacs(struct zt_chan *dst, struct zt_chan *src) } #ifdef VPM_SUPPORT + +static int t4_vpm_unit(int span, int channel) +{ + int unit = 0; + switch(vpmspans) { + case 4: + unit = span; + unit += (channel & 1) << 2; + break; + case 2: + unit = span; + unit += (channel & 0x3) << 1; + case 1: + unit = span; + unit += (channel & 0x7); + } + return unit; +} + static int t4_echocan(struct zt_chan *chan, int eclen) { struct t4 *wc = chan->pvt; @@ -698,13 +718,15 @@ static int t4_echocan(struct zt_chan *chan, int eclen) int unit; if (!wc->vpm) return -ENODEV; - unit = chan->span->offset; + + if (chan->span->offset >= vpmspans) + return -ENODEV; + if (wc->t1e1) channel = chan->chanpos; else channel = chan->chanpos + 4; - if ((channel & 1)) - unit += 4; + unit = t4_vpm_unit(chan->span->offset, channel); if(debug & DEBUG_ECHOCAN) printk("echocan: Card is %d, Channel is %d, Span is %d, unit is %d, unit offset is %d length %d\n", wc->num, chan->chanpos, chan->span->offset, unit, channel, eclen); @@ -2308,6 +2330,53 @@ static void t4_vpm_set_dtmf_threshold(struct t4 *wc, unsigned int threshold) printk("VPM: DTMF threshold set to %d\n", threshold); } +static unsigned int t4_vpm_mask(int chip) +{ + unsigned int mask=0; + switch(vpmspans) { + case 4: + mask = 0x55555555 << (chip >> 2); + break; + case 2: + mask = 0x11111111 << (chip >> 1); + break; + case 1: + mask = 0x01010101 << chip; + break; + } + return mask; +} + +static int t4_vpm_spanno(int chip) +{ + int spanno = 0; + switch(vpmspans) { + case 4: + spanno = chip & 0x3; + break; + case 2: + spanno = chip & 0x1; + break; + /* Case 1 is implicit */ + } + return spanno; +} + +static int t4_vpm_echotail(void) +{ + int echotail = 0x01ff; + switch(vpmspans) { + case 4: + echotail = 0x007f; + break; + case 2: + echotail = 0x00ff; + break; + /* Case 1 is implicit */ + } + return echotail; +} + static void t4_vpm_init(struct t4 *wc) { unsigned char reg; @@ -2320,9 +2389,20 @@ static void t4_vpm_init(struct t4 *wc) return; } + switch(vpmspans) { + case 4: + case 2: + case 1: + break; + default: + printk("VPM: %d is not a valid vpmspans value, using 4\n", vpmspans); + vpmspans = 4; + } + for (x=0;x<8;x++) { - int spanno = x & 0x3; + int spanno = t4_vpm_spanno(x); struct t4_span *ts = wc->tspans[spanno]; + int echotail = t4_vpm_echotail(); ver = t4_vpm_in(wc, x, 0x1a0); /* revision */ if (ver != 0x26) { @@ -2345,11 +2425,11 @@ static void t4_vpm_init(struct t4 *wc) t4_vpm_out(wc, x, 0x02f, 0x20 | (spanno << 3)); /* Setup Echo length (128 taps) */ - t4_vpm_out(wc, x, 0x022, 0x00); - t4_vpm_out(wc, x, 0x023, 0x7f); + t4_vpm_out(wc, x, 0x022, (echotail >> 8)); + t4_vpm_out(wc, x, 0x023, (echotail & 0xff)); /* Setup the tdm channel masks for all chips*/ - mask = (x < 4) ? 0x55555555 : 0xaaaaaaaa; + mask = t4_vpm_mask(x); for (i = 0; i < 4; i++) t4_vpm_out(wc, x, 0x30 + i, (mask >> (i << 3)) & 0xff); @@ -2357,11 +2437,11 @@ static void t4_vpm_init(struct t4 *wc) reg = t4_vpm_in(wc,x,0x20); reg &= 0xE0; if (ts->spantype == TYPE_E1) { - if (x < 4) + if (x < vpmspans) printk("VPM: Span %d A-law mode\n", spanno); reg |= 0x01; } else { - if (x < 4) + if (x < vpmspans) printk("VPM: Span %d U-law mode\n", spanno); reg &= ~0x01; } @@ -2391,7 +2471,7 @@ static void t4_vpm_init(struct t4 *wc) /* set DTMF detection threshold */ t4_vpm_set_dtmf_threshold(wc, dtmfthreshold); - /* Enable DTMF detectors */ + /* Enable DTMF detectors (always DTMF detect all spans) */ for (i = 0; i < MAX_DTMF_DET; i++) { t4_vpm_out(wc, x, 0x98 + i, 0x40 | (i * 2) | ((x < 4) ? 0 : 1)); } @@ -2401,7 +2481,7 @@ static void t4_vpm_init(struct t4 *wc) t4_vpm_out(wc, x, i, (x < 4) ? 0x55 : 0xAA); } - printk("VPM: Present and operational\n"); + printk("VPM: Present and operational servicing %d span(s)\n", vpmspans); wc->vpm = T4_VPM_PRESENT; } @@ -2885,6 +2965,7 @@ module_param(alarmdebounce, int, 0600); module_param(j1mode, int, 0600); #ifdef VPM_SUPPORT module_param(vpmsupport, int, 0600); +module_param(vpmspans, int, 0600); module_param(dtmfthreshold, int, 0600); #endif #else @@ -2899,6 +2980,7 @@ MODULE_PARM(alarmdebounce, "i"); MODULE_PARM(j1mode, "i"); #ifdef VPM_SUPPORT MODULE_PARM(vpmsupport, "i"); +MODULE_PARM(vpmspans, "i"); MODULE_PARM(dtmfthreshold, "i"); #endif #endif -- cgit v1.2.3