diff options
author | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-05-31 16:17:10 +0000 |
---|---|---|
committer | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-05-31 16:17:10 +0000 |
commit | cb603ecd4c11c62eac1bbf1d73ef425dc3dcef30 (patch) | |
tree | 587917407f4a2bc8f8825f189c752bbf7e5e7e8d /wctdm24xxp.c | |
parent | 8a097c0e718f77cad9613bd1be6911845b0f6ee6 (diff) |
Implement native bridging on TDM2400P
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@1099 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'wctdm24xxp.c')
-rw-r--r-- | wctdm24xxp.c | 109 |
1 files changed, 107 insertions, 2 deletions
diff --git a/wctdm24xxp.c b/wctdm24xxp.c index 61d972a..3612304 100644 --- a/wctdm24xxp.c +++ b/wctdm24xxp.c @@ -358,6 +358,7 @@ struct wctdm { int modtype[NUM_CARDS + NUM_EC]; /* Set hook */ int sethook[NUM_CARDS + NUM_EC]; + int dacssrc[NUM_CARDS]; #ifdef VPM_SUPPORT int vpm; @@ -407,6 +408,7 @@ static char *opermode = "FCC"; static int fxshonormode = 0; static int alawoverride = 0; static int fxo_addrs[4] = { 0x00, 0x08, 0x04, 0x0c }; +static int nativebridge = 1; #ifdef VPM_SUPPORT static int vpmsupport = 1; static int vpmdtmfsupport = 0; @@ -2284,6 +2286,101 @@ static int wctdm_hooksig(struct zt_chan *chan, zt_txsig_t txsig) return 0; } +static void wctdm_dacs_connect(struct wctdm *wc, int srccard, int dstcard) +{ + + if (wc->dacssrc[dstcard] > - 1) { + printk("wctdm_dacs_connect: Can't have double sourcing yet!\n"); + return; + } + if (!((wc->modtype[srccard] == MOD_TYPE_FXS)||(wc->modtype[srccard] == MOD_TYPE_FXO))){ + printk("wctdm_dacs_connect: Unsupported modtype for card %d\n", srccard); + return; + } + if (!((wc->modtype[dstcard] == MOD_TYPE_FXS)||(wc->modtype[dstcard] == MOD_TYPE_FXO))){ + printk("wctdm_dacs_connect: Unsupported modtype for card %d\n", dstcard); + return; + } + if (debug) + printk("connect %d => %d\n", srccard, dstcard); + wc->dacssrc[dstcard] = srccard; + + /* make srccard transmit to srccard+24 on the TDM bus */ + if (wc->modtype[srccard] == MOD_TYPE_FXS) { + /* proslic */ + wctdm_setreg(wc, srccard, PCM_XMIT_START_COUNT_LSB, ((srccard+24) * 8) & 0xff); + wctdm_setreg(wc, srccard, PCM_XMIT_START_COUNT_MSB, ((srccard+24) * 8) >> 8); + } else if(wc->modtype[srccard] == MOD_TYPE_FXO) { + /* daa */ + wctdm_setreg(wc, srccard, 34, ((srccard+24) * 8) & 0xff); /* TX */ + wctdm_setreg(wc, srccard, 35, ((srccard+24) * 8) >> 8); /* TX */ + } + + /* have dstcard receive from srccard+24 on the TDM bus */ + if (wc->modtype[dstcard] == MOD_TYPE_FXS) { + /* proslic */ + wctdm_setreg(wc, dstcard, PCM_RCV_START_COUNT_LSB, ((srccard+24) * 8) & 0xff); + wctdm_setreg(wc, dstcard, PCM_RCV_START_COUNT_MSB, ((srccard+24) * 8) >> 8); + } else if(wc->modtype[dstcard] == MOD_TYPE_FXO) { + /* daa */ + wctdm_setreg(wc, dstcard, 36, ((srccard+24) * 8) & 0xff); /* RX */ + wctdm_setreg(wc, dstcard, 37, ((srccard+24) * 8) >> 8); /* RX */ + } + +} + +static void wctdm_dacs_disconnect(struct wctdm *wc, int card) +{ + if (wc->dacssrc[card] > -1) { + printk("wctdm_dacs_disconnect: restoring TX for %d and RX for %d\n",wc->dacssrc[card], card); + + /* restore TX (source card) */ + if(wc->modtype[wc->dacssrc[card]] == MOD_TYPE_FXS){ + wctdm_setreg(wc, wc->dacssrc[card], PCM_XMIT_START_COUNT_LSB, (wc->dacssrc[card] * 8) & 0xff); + wctdm_setreg(wc, wc->dacssrc[card], PCM_XMIT_START_COUNT_MSB, (wc->dacssrc[card] * 8) >> 8); + } else if(wc->modtype[wc->dacssrc[card]] == MOD_TYPE_FXO){ + wctdm_setreg(wc, card, 34, (card * 8) & 0xff); + wctdm_setreg(wc, card, 35, (card * 8) >> 8); + } else { + printk("WARNING: wctdm_dacs_disconnect() called on unsupported modtype\n"); + } + + /* restore RX (this card) */ + if(wc->modtype[card] == MOD_TYPE_FXS){ + wctdm_setreg(wc, card, PCM_RCV_START_COUNT_LSB, (card * 8) & 0xff); + wctdm_setreg(wc, card, PCM_RCV_START_COUNT_MSB, (card * 8) >> 8); + } else if(wc->modtype[card] == MOD_TYPE_FXO){ + wctdm_setreg(wc, card, 36, (card * 8) & 0xff); + wctdm_setreg(wc, card, 37, (card * 8) >> 8); + } else { + printk("WARNING: wctdm_dacs_disconnect() called on unsupported modtype\n"); + } + + wc->dacssrc[card] = -1; + } +} + +static int wctdm_dacs(struct zt_chan *dst, struct zt_chan *src) +{ + struct wctdm *wc; + + if(!nativebridge) + return 0; /* should this return -1 since unsuccessful? */ + + wc = dst->pvt; + + if(src) { + wctdm_dacs_connect(wc, src->chanpos - 1, dst->chanpos - 1); + if (debug) + printk("dacs connecct: %d -> %d!\n\n", src->chanpos, dst->chanpos); + } else { + wctdm_dacs_disconnect(wc, dst->chanpos - 1); + if (debug) + printk("dacs disconnect: %d!\n", dst->chanpos); + } + return 0; +} + static int wctdm_initialize(struct wctdm *wc) { int x; @@ -2311,6 +2408,7 @@ static int wctdm_initialize(struct wctdm *wc) wc->span.flags = ZT_FLAG_RBS; wc->span.ioctl = wctdm_ioctl; wc->span.watchdog = wctdm_watchdog; + wc->span.dacs= wctdm_dacs; #ifdef VPM_SUPPORT wc->span.echocan = wctdm_echocan; #endif @@ -2654,8 +2752,11 @@ static void wctdm_locate_modules(struct wctdm *wc) } else if (!(ret = wctdm_init_voicedaa(wc, x, 0, 0, sane))) { wc->cardflag |= (1 << x); printk("Port %d: Installed -- AUTO FXO (%s mode)\n",x + 1, fxo_modes[_opermode].name); - } else + } else { printk("Port %d: Not installed\n", x + 1); + wc->modtype[x] = MOD_TYPE_NONE; + wc->cardflag |= (1 << x); + } } } #ifdef VPM_SUPPORT @@ -2701,8 +2802,10 @@ static int __devinit wctdm_init_one(struct pci_dev *pdev, const struct pci_devic wc->dev = pdev; wc->pos = x; wc->variety = d->name; - for (y=0;y<NUM_CARDS;y++) + for (y=0;y<NUM_CARDS;y++) { wc->flags[y] = d->flags; + wc->dacssrc[y] = -1; + } /* Keep track of whether we need to free the region */ if (request_region(wc->iobase, 0xff, "wctdm")) wc->freeregion = 1; @@ -2890,6 +2993,7 @@ module_param(fxshonormode, int, 0600); module_param(battdebounce, int, 0600); module_param(battthresh, int, 0600); module_param(alawoverride, int, 0600); +module_param(nativebridge, int, 0600); #ifdef VPM_SUPPORT module_param(vpmsupport, int, 0600); module_param(vpmdtmfsupport, int, 0600); @@ -2910,6 +3014,7 @@ MODULE_PARM(fxshonormode, "i"); MODULE_PARM(battdebounce, "i"); MODULE_PARM(battthresh, "i"); MODULE_PARM(alawoverride, "i"); +MODULE_PARM(nativebridge, "i"); #ifdef VPM_SUPPORT MODULE_PARM(vpmsupport, "i"); MODULE_PARM(vpmdtmfsupport, "i"); |