summaryrefslogtreecommitdiff
path: root/wctdm24xxp.c
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-05-31 16:17:10 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-05-31 16:17:10 +0000
commitcb603ecd4c11c62eac1bbf1d73ef425dc3dcef30 (patch)
tree587917407f4a2bc8f8825f189c752bbf7e5e7e8d /wctdm24xxp.c
parent8a097c0e718f77cad9613bd1be6911845b0f6ee6 (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.c109
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");