summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-09-14 04:46:47 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-09-14 04:46:47 +0000
commit5f1ac35511b91a9683ce16398bc1c5b49098545e (patch)
tree0bfb17363b9fa3f556e0c0b678d909017e05af47
parentc820d5e9860649bc05cb0d952bcb76621114ce4c (diff)
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
-rwxr-xr-xwct4xxp.c104
1 files 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