[zaptel-commits] trunk r1099 - /trunk/wctdm24xxp.c

zaptel-commits at lists.digium.com zaptel-commits at lists.digium.com
Wed May 31 09:17:10 MST 2006


Author: markster
Date: Wed May 31 11:17:10 2006
New Revision: 1099

URL: http://svn.digium.com/view/zaptel?rev=1099&view=rev
Log:
Implement native bridging on TDM2400P

Modified:
    trunk/wctdm24xxp.c

Modified: trunk/wctdm24xxp.c
URL: http://svn.digium.com/view/zaptel/trunk/wctdm24xxp.c?rev=1099&r1=1098&r2=1099&view=diff
==============================================================================
--- trunk/wctdm24xxp.c (original)
+++ trunk/wctdm24xxp.c Wed May 31 11:17:10 2006
@@ -358,6 +358,7 @@
 	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 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 @@
 	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 @@
 	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 @@
 			} 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 @@
 			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(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(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");



More information about the zaptel-commits mailing list