summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-11-09 16:41:24 +0000
committerkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-11-09 16:41:24 +0000
commitc77a44d1b7e5e581ceae0821d981790c58cff267 (patch)
treebd107235a2923a5e1796dceeaccceac9b52369a7
parent996307700b3d542eb78099e5e7f54ae3b5b34940 (diff)
merge changes from HEAD branch
git-svn-id: http://svn.digium.com/svn/zaptel/branches/v1-0@814 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rwxr-xr-xwct4xxp.c116
1 files changed, 100 insertions, 16 deletions
diff --git a/wct4xxp.c b/wct4xxp.c
index 92bb889..1bc11b6 100755
--- a/wct4xxp.c
+++ b/wct4xxp.c
@@ -174,6 +174,8 @@ static int loopback = 0;
static int alarmdebounce = 0;
#ifdef VPM_SUPPORT
static int vpmsupport = 1;
+static int vpmdtmfsupport = 1;
+static int vpmspans = 4;
#define VPM_DEFAULT_DTMFTHRESHOLD 1000
static int dtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD;
static int lastdtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD;
@@ -691,6 +693,26 @@ 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;
+ break;
+ 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 +720,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);
@@ -743,10 +767,6 @@ static int t4_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data)
regs.regs[x] = t4_framer_in(wc, chan->span->offset, x);
if (copy_to_user((struct t4_regs *)data, &regs, sizeof(regs)))
return -EFAULT;
- {
- static unsigned char filldata = 0;
- memset(wc->tspans[0]->writechunk, filldata, ZT_CHUNKSIZE * 32);
- }
break;
#ifdef VPM_SUPPORT
case ZT_TONEDETECT:
@@ -754,6 +774,8 @@ static int t4_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data)
return -EFAULT;
if (!wc->vpm)
return -ENOSYS;
+ if (j && !vpmdtmfsupport)
+ return -ENOSYS;
if (j & ZT_TONEDETECT_ON)
ts->dtmfmask |= (1 << (chan->chanpos - 1));
else
@@ -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;
}
@@ -2856,7 +2936,7 @@ static struct pci_driver t4_driver = {
static int __init t4_init(void)
{
int res;
- res = pci_module_init(&t4_driver);
+ res = zap_pci_module(&t4_driver);
if (res)
return -ENODEV;
return 0;
@@ -2885,6 +2965,8 @@ module_param(alarmdebounce, int, 0600);
module_param(j1mode, int, 0600);
#ifdef VPM_SUPPORT
module_param(vpmsupport, int, 0600);
+module_param(vpmdtmfsupport, int, 0600);
+module_param(vpmspans, int, 0600);
module_param(dtmfthreshold, int, 0600);
#endif
#else
@@ -2899,6 +2981,8 @@ MODULE_PARM(alarmdebounce, "i");
MODULE_PARM(j1mode, "i");
#ifdef VPM_SUPPORT
MODULE_PARM(vpmsupport, "i");
+MODULE_PARM(vpmdtmfsupport, "i");
+MODULE_PARM(vpmspans, "i");
MODULE_PARM(dtmfthreshold, "i");
#endif
#endif