[dahdi-commits] dbailey: linux/trunk r4770 - /linux/trunk/drivers/dahdi/wctdm24xxp/

SVN commits to the DAHDI project dahdi-commits at lists.digium.com
Wed Aug 13 16:04:07 CDT 2008


Author: dbailey
Date: Wed Aug 13 16:04:07 2008
New Revision: 4770

URL: http://svn.digium.com/view/dahdi?view=rev&rev=4770
Log:
import the neon mwi detection

Modified:
    linux/trunk/drivers/dahdi/wctdm24xxp/base.c
    linux/trunk/drivers/dahdi/wctdm24xxp/wctdm24xxp.h

Modified: linux/trunk/drivers/dahdi/wctdm24xxp/base.c
URL: http://svn.digium.com/view/dahdi/linux/trunk/drivers/dahdi/wctdm24xxp/base.c?view=diff&rev=4770&r1=4769&r2=4770
==============================================================================
--- linux/trunk/drivers/dahdi/wctdm24xxp/base.c (original)
+++ linux/trunk/drivers/dahdi/wctdm24xxp/base.c Wed Aug 13 16:04:07 2008
@@ -191,6 +191,15 @@
 static int ringdebounce = DEFAULT_RING_DEBOUNCE;
 static int fwringdetect = 0;
 static int latency = VOICEBUS_DEFAULT_LATENCY;
+
+#define MS_PER_HOOKCHECK	(1)
+#define NEONMWI_ON_DEBOUNCE	(100/MS_PER_HOOKCHECK)
+static int neonmwi_monitor = 0; 	/* Note: this causes use of full wave ring detect */
+static int neonmwi_level = 75;		/* neon mwi trip voltage */
+static int neonmwi_envelope = 10;
+static int neonmwi_offlimit = 16000;  /* Time in milliseconds the monitor is checked before saying no message is waiting */
+static int neonmwi_offlimit_cycles;  /* Time in milliseconds the monitor is checked before saying no message is waiting */
+
 #ifdef VPM_SUPPORT
 static int vpmsupport = 1;
 static int vpmdtmfsupport = 0;
@@ -1127,6 +1136,7 @@
 
 	unsigned char res;
 	signed char b;
+	unsigned int abs_voltage;
 	struct fxo *fxo = &wc->mods[card].fxo;
 
 	/* Try to track issues that plague slot one FXO's */
@@ -1140,29 +1150,52 @@
 			wctdm_setreg_intr(wc, card, 5, 0x8);
 	}
 	if (!fxo->offhook) {
-		if (fwringdetect) {
+		if(fwringdetect || neonmwi_monitor) {
+			/* Look for ring status bits (Ring Detect Signal Negative and
+			* Ring Detect Signal Positive) to transition back and forth
+			* some number of times to indicate that a ring is occurring.
+			* Provide some number of samples to allow for the transitions
+			* to occur before ginving up.
+			* NOTE: neon mwi voltages will trigger one of these bits to go active
+			* but not to have transitions between the two bits (i.e. no negative
+			* to positive or positive to negative transversals )
+			*/
 			res =  wc->cmdq[card].isrshadow[0] & 0x60;
-			if (fxo->ringdebounce--) {
-				if (res && (res != fxo->lastrdtx) && (fxo->battery == 1)) {
-					if (!fxo->wasringing) {
+			if (0 == wc->mods[card].fxo.wasringing) {
+				if (res) {
+					/* Look for positive/negative crossings in ring status reg */
+					fxo->wasringing = 2;
+					fxo->ringdebounce = ringdebounce /16;
+					fxo->lastrdtx = res;
+					fxo->lastrdtx_count = 0;
+				}
+			} else if (2 == fxo->wasringing) {
+				/* If ring detect signal has transversed */
+				if (res && res != fxo->lastrdtx) {
+					/* if there are at least 3 ring polarity transversals */
+					if(++fxo->lastrdtx_count >= 2) {
 						fxo->wasringing = 1;
 						if (debug)
-							printk(KERN_DEBUG "RING on %d/%d!\n", wc->span.spanno, card + 1);
+							printk("FW RING on %d/%d!\n", wc->span.spanno, card + 1);
 						dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
+						fxo->ringdebounce = ringdebounce / 16;
+					} else {
+						fxo->lastrdtx = res;
+						fxo->ringdebounce = ringdebounce / 16;
 					}
-					fxo->lastrdtx = res;
-					fxo->ringdebounce = 10;
-				} else if (!res) {
-					if ((fxo->ringdebounce == 0) && fxo->wasringing) {
-						fxo->wasringing = 0;
-						if (debug)
-							printk(KERN_DEBUG "NO RING on %d/%d!\n", wc->span.spanno, card + 1);
-						dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
-					}
+					/* ring indicator (positve or negative) has not transitioned, check debounce count */
+				} else if (--fxo->ringdebounce == 0) {
+					fxo->wasringing = 0;
 				}
-			} else if (res && (fxo->battery == BATTERY_PRESENT)) {
-				fxo->lastrdtx = res;
-				fxo->ringdebounce = 10;
+			} else {  /* I am in ring state */
+				if (res) { /* If any ringdetect bits are still active */
+					fxo->ringdebounce = ringdebounce / 16;
+				} else if (--fxo->ringdebounce == 0) {
+					fxo->wasringing = 0;
+					if (debug)
+						printk("FW NO RING on %d/%d!\n", wc->span.spanno, card + 1);
+					dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
+				}
 			}
 		} else {
 			res =  wc->cmdq[card].isrshadow[0];
@@ -1194,6 +1227,7 @@
 	}
 
 	b = wc->cmdq[card].isrshadow[1]; /* Voltage */
+	abs_voltage = abs(b);
 
 	if (fxovoltage) {
 		if (!(wc->intcount % 100)) {
@@ -1202,7 +1236,7 @@
 		}
 	}
 
-	if (abs(b) < battthresh) {
+	if (abs_voltage < battthresh) {
 		/* possible existing states:
 		   battery lost, no debounce timer
 		   battery lost, debounce timer (going to battery present)
@@ -1320,6 +1354,47 @@
 				dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
 			fxo->polarity = fxo->lastpol;
 		    }
+		}
+	}
+	/* Look for neon mwi pulse */
+	if (neonmwi_monitor && !wc->mods[card].fxo.offhook) {
+		/* Look for 4 consecutive voltage readings
+		* where the voltage is over the neon limit but
+		* does not vary greatly from the last reading
+		*/
+		if (fxo->battery == 1 &&
+				  abs_voltage > neonmwi_level &&
+				  (0 == fxo->neonmwi_last_voltage ||
+				  (b >= fxo->neonmwi_last_voltage - neonmwi_envelope &&
+				  b <= fxo->neonmwi_last_voltage + neonmwi_envelope ))) {
+			fxo->neonmwi_last_voltage = b;
+			if (NEONMWI_ON_DEBOUNCE == fxo->neonmwi_debounce) {
+				fxo->neonmwi_offcounter = neonmwi_offlimit_cycles;
+				if(0 == fxo->neonmwi_state) {
+					dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_NEONMWI_ACTIVE);
+					fxo->neonmwi_state = 1;
+					if (debug)
+						printk("NEON MWI active for card %d\n", card+1);
+				}
+				fxo->neonmwi_debounce++;  /* terminate the processing */
+			} else if (NEONMWI_ON_DEBOUNCE > fxo->neonmwi_debounce) {
+				fxo->neonmwi_debounce++;
+			} else { /* Insure the count gets reset */
+				fxo->neonmwi_offcounter = neonmwi_offlimit_cycles;
+			}
+		} else {
+			fxo->neonmwi_debounce = 0;
+			fxo->neonmwi_last_voltage = 0;
+		}
+		/* If no neon mwi pulse for given period of time, indicte no neon mwi state */
+		if (fxo->neonmwi_state && 0 < fxo->neonmwi_offcounter ) {
+			fxo->neonmwi_offcounter--;
+			if (0 == fxo->neonmwi_offcounter) {
+				dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_NEONMWI_INACTIVE);
+				fxo->neonmwi_state = 0;
+				if (debug)
+					printk("NEON MWI cleared for card %d\n", card+1);
+			}
 		}
 	}
 #undef MS_PER_CHECK_HOOK
@@ -1874,7 +1949,7 @@
 	reg16 |= (fxo_modes[_opermode].rt);
 	wctdm_setreg(wc, card, 16, reg16);
 
-	if(fwringdetect) {
+	if(fwringdetect || neonmwi_monitor) {
 		/* Enable ring detector full-wave rectifier mode */
 		wctdm_setreg(wc, card, 18, 2);
 		wctdm_setreg(wc, card, 24, 0);
@@ -2597,12 +2672,23 @@
 static int wctdm_open(struct dahdi_chan *chan)
 {
 	struct wctdm *wc = chan->pvt;
+	int channo = chan->chanpos - 1;
+	unsigned long flags;
+
 	if (!(wc->cardflag & (1 << (chan->chanpos - 1))))
 		return -ENODEV;
 	if (wc->dead)
 		return -ENODEV;
 	wc->usecount++;
 	try_module_get(THIS_MODULE);
+	
+	/* Reset the mwi indicators */
+	spin_lock_irqsave(&wc->reglock, flags);
+	wc->mods[channo].fxo.neonmwi_debounce = 0;
+	wc->mods[channo].fxo.neonmwi_offcounter = 0;
+	wc->mods[channo].fxo.neonmwi_state = 0;
+	spin_unlock_irqrestore(&wc->reglock, flags);
+
 	return 0;
 }
 
@@ -3764,6 +3850,8 @@
 	int i;
 	int y;
 	int ret;
+	
+	neonmwi_offlimit_cycles = neonmwi_offlimit /MS_PER_HOOKCHECK;
 
 retry:
 	if (!(wc = kmalloc(sizeof(*wc), GFP_KERNEL))) {
@@ -4018,6 +4106,10 @@
 module_param(ringdebounce, int, 0600);
 module_param(fwringdetect, int, 0600);
 module_param(latency, int, 0600);
+module_param(neonmwi_monitor, int, 0600);
+module_param(neonmwi_level, int, 0600);
+module_param(neonmwi_envelope, int, 0600);
+module_param(neonmwi_offlimit, int, 0600);
 #ifdef VPM_SUPPORT
 module_param(vpmsupport, int, 0600);
 module_param(vpmdtmfsupport, int, 0600);

Modified: linux/trunk/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
URL: http://svn.digium.com/view/dahdi/linux/trunk/drivers/dahdi/wctdm24xxp/wctdm24xxp.h?view=diff&rev=4770&r1=4769&r2=4770
==============================================================================
--- linux/trunk/drivers/dahdi/wctdm24xxp/wctdm24xxp.h (original)
+++ linux/trunk/drivers/dahdi/wctdm24xxp/wctdm24xxp.h Wed Aug 13 16:04:07 2008
@@ -220,6 +220,7 @@
 		struct fxo {
 			int wasringing;
 			int lastrdtx;
+			int lastrdtx_count;
 			int ringdebounce;
 			int offhook;
 			int battdebounce;
@@ -228,6 +229,10 @@
 			int lastpol;
 			int polarity;
 			int polaritydebounce;
+			int neonmwi_state;
+			int neonmwi_last_voltage;
+			unsigned int neonmwi_debounce;
+			unsigned int neonmwi_offcounter;
 		} fxo;
 		struct fxs {
 			int oldrxhook;




More information about the dahdi-commits mailing list