[svn-commits] sruffell: branch linux/sruffell/wctdm24xxp-updates r10133 - /linux/team/sruff...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Aug 12 19:36:36 CDT 2011


Author: sruffell
Date: Fri Aug 12 19:36:33 2011
New Revision: 10133

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=10133
Log:
wctdm24xxp: Use time interval for debouncing ring detect.

We do not necessarily want to assume that the ring dection function is
called for every frame. Also change the debounce logic to a state
machine to, in my opinion, clarify what state we're actually in.

Signed-off-by: Shaun Ruffell <sruffell at digium.com>

Modified:
    linux/team/sruffell/wctdm24xxp-updates/drivers/dahdi/wctdm24xxp/base.c
    linux/team/sruffell/wctdm24xxp-updates/drivers/dahdi/wctdm24xxp/wctdm24xxp.h

Modified: linux/team/sruffell/wctdm24xxp-updates/drivers/dahdi/wctdm24xxp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/team/sruffell/wctdm24xxp-updates/drivers/dahdi/wctdm24xxp/base.c?view=diff&rev=10133&r1=10132&r2=10133
==============================================================================
--- linux/team/sruffell/wctdm24xxp-updates/drivers/dahdi/wctdm24xxp/base.c (original)
+++ linux/team/sruffell/wctdm24xxp-updates/drivers/dahdi/wctdm24xxp/base.c Fri Aug 12 19:36:33 2011
@@ -1843,101 +1843,139 @@
 	return;
 }
 
+static inline bool is_fxo_ringing(const struct fxo *const fxo)
+{
+	return ((fxo->hook_ring_shadow & 0x60) &&
+		(fxo->battery_state == BATTERY_PRESENT));
+}
+
+static inline bool is_fxo_ringing_positive(const struct fxo *const fxo)
+{
+	return (((fxo->hook_ring_shadow & 0x60) == 0x20) &&
+		(fxo->battery_state == BATTERY_PRESENT));
+}
+
+static inline bool is_fxo_ringing_negative(const struct fxo *const fxo)
+{
+	return (((fxo->hook_ring_shadow & 0x60) == 0x40) &&
+		(fxo->battery_state == BATTERY_PRESENT));
+}
+
+static inline void set_ring(struct fxo *fxo, enum ring_detector_state new)
+{
+	fxo->ring_state = new;
+}
+
+static void wctdm_fxo_ring_detect(struct wctdm *wc, struct wctdm_module *mod)
+{
+	struct fxo *const fxo = &mod->mod.fxo;
+
+	/* 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 giving 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 traversals) */
+
+	switch (fxo->ring_state) {
+	case DEBOUNCING_RINGING_POSITIVE:
+		if (is_fxo_ringing_negative(fxo)) {
+			if (++fxo->ring_polarity_change_count > 4) {
+				mod_hooksig(wc, mod, DAHDI_RXSIG_RING);
+				set_ring(fxo, RINGING);
+				if (debug) {
+					dev_info(&wc->vb.pdev->dev,
+						 "RING on %s!\n",
+						 get_dahdi_chan(wc, mod)->name);
+				}
+			} else {
+				set_ring(fxo, DEBOUNCING_RINGING_NEGATIVE);
+			}
+			
+		} else if (time_after(wc->framecount,
+			   	      fxo->ringdebounce_timer)) {
+			set_ring(fxo, RINGOFF);
+		}
+		break;
+	case DEBOUNCING_RINGING_NEGATIVE:
+		if (is_fxo_ringing_positive(fxo)) {
+			if (++fxo->ring_polarity_change_count > 4) {
+				mod_hooksig(wc, mod, DAHDI_RXSIG_RING);
+				set_ring(fxo, RINGING);
+				if (debug) {
+					dev_info(&wc->vb.pdev->dev,
+						 "RING on %s!\n",
+						 get_dahdi_chan(wc, mod)->name);
+				}
+			} else {
+				set_ring(fxo, DEBOUNCING_RINGING_POSITIVE);
+			}
+			
+		} else if (time_after(wc->framecount,
+				      fxo->ringdebounce_timer)) {
+			set_ring(fxo, RINGOFF);
+		}
+		break;
+	case RINGING:
+		if (!is_fxo_ringing(fxo)) {
+			set_ring(fxo, DEBOUNCING_RINGOFF);
+			fxo->ringdebounce_timer =
+					wc->framecount + ringdebounce / 2;
+		}
+		break;
+	case DEBOUNCING_RINGOFF:
+		if (!is_fxo_ringing(fxo)) {
+			if (time_after(wc->framecount,
+				       fxo->ringdebounce_timer)) {
+				if (debug) {
+					dev_info(&wc->vb.pdev->dev,
+						 "NO RING on %s!\n",
+						 get_dahdi_chan(wc, mod)->name);
+				}
+				mod_hooksig(wc, mod, DAHDI_RXSIG_OFFHOOK);
+				set_ring(fxo, RINGOFF);
+			}
+		} else {
+			set_ring(fxo, RINGING);
+		}
+		break;
+	case RINGOFF:
+		if (is_fxo_ringing(fxo)) {
+			/* Look for positive/negative crossings in ring status
+			 * reg */
+			if (is_fxo_ringing_positive(fxo))
+				set_ring(fxo, DEBOUNCING_RINGING_POSITIVE);
+			else
+				set_ring(fxo, DEBOUNCING_RINGING_NEGATIVE);
+			fxo->ringdebounce_timer =
+					wc->framecount + ringdebounce / 8;
+			fxo->ring_polarity_change_count = 0;
+		}
+		break;
+	}
+}
+
 static void
 wctdm_voicedaa_check_hook(struct wctdm *wc, struct wctdm_module *const mod)
 {
 #define MS_PER_CHECK_HOOK 1
 
-	unsigned char res;
 	signed char b;
 	unsigned int abs_voltage;
 	struct fxo *const fxo = &mod->mod.fxo;
 
 	/* Try to track issues that plague slot one FXO's */
-	b = fxo->hook_ring_shadow;
-	b &= 0x9b;
+	b = fxo->hook_ring_shadow & 0x9b;
+
 	if (fxo->offhook) {
 		if (b != 0x9)
 			wctdm_setreg_intr(wc, mod, 5, 0x9);
 	} else {
 		if (b != 0x8)
 			wctdm_setreg_intr(wc, mod, 5, 0x8);
-	}
-	if (!fxo->offhook) {
-		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 = fxo->hook_ring_shadow & 0x60;
-			if (0 == 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)
-							dev_info(&wc->vb.pdev->dev, "FW RING on %d/%d!\n", wc->aspan->span.spanno, mod->card + 1);
-						mod_hooksig(wc, mod, DAHDI_RXSIG_RING);
-						fxo->ringdebounce = ringdebounce / 16;
-					} else {
-						fxo->lastrdtx = res;
-						fxo->ringdebounce = ringdebounce / 16;
-					}
-					/* ring indicator (positve or negative) has not transitioned, check debounce count */
-				} else if (--fxo->ringdebounce == 0) {
-					fxo->wasringing = 0;
-				}
-			} 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)
-						dev_info(&wc->vb.pdev->dev, "FW NO RING on %d/%d!\n", wc->aspan->span.spanno, mod->card + 1);
-					mod_hooksig(wc, mod, DAHDI_RXSIG_OFFHOOK);
-				}
-			}
-		} else {
-			res = fxo->hook_ring_shadow;
-			if ((res & 0x60) && (fxo->battery == BATTERY_PRESENT)) {
-				fxo->ringdebounce += (DAHDI_CHUNKSIZE * 16);
-				if (fxo->ringdebounce >= DAHDI_CHUNKSIZE * ringdebounce) {
-					if (!fxo->wasringing) {
-						fxo->wasringing = 1;
-						mod_hooksig(wc, mod, DAHDI_RXSIG_RING);
-						if (debug)
-							dev_info(&wc->vb.pdev->dev, "RING on %d/%d!\n", wc->aspan->span.spanno, mod->card + 1);
-					}
-					fxo->ringdebounce = DAHDI_CHUNKSIZE * ringdebounce;
-				}
-			} else {
-				fxo->ringdebounce -= DAHDI_CHUNKSIZE * 4;
-				if (fxo->ringdebounce <= 0) {
-					if (fxo->wasringing) {
-						fxo->wasringing = 0;
-						mod_hooksig(wc, mod, DAHDI_RXSIG_OFFHOOK);
-						if (debug)
-							dev_info(&wc->vb.pdev->dev, "NO RING on %d/%d!\n", wc->aspan->span.spanno, mod->card + 1);
-					}
-					fxo->ringdebounce = 0;
-				}
-					
-			}
-		}
+
+		wctdm_fxo_ring_detect(wc, mod);
 	}
 
 	b = fxo->line_voltage_status;

Modified: linux/team/sruffell/wctdm24xxp-updates/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
URL: http://svnview.digium.com/svn/dahdi/linux/team/sruffell/wctdm24xxp-updates/drivers/dahdi/wctdm24xxp/wctdm24xxp.h?view=diff&rev=10133&r1=10132&r2=10133
==============================================================================
--- linux/team/sruffell/wctdm24xxp-updates/drivers/dahdi/wctdm24xxp/wctdm24xxp.h (original)
+++ linux/team/sruffell/wctdm24xxp-updates/drivers/dahdi/wctdm24xxp/wctdm24xxp.h Fri Aug 12 19:36:33 2011
@@ -107,6 +107,15 @@
 	BATTERY_UNKNOWN = 0,
 	BATTERY_PRESENT,
 	BATTERY_LOST,
+};
+
+enum ring_detector_state {
+	RINGOFF = 0,
+	DEBOUNCING_RINGING_POSITIVE,
+	DEBOUNCING_RINGING_NEGATIVE,
+	DEBOUNCING_RINGING_OFF,
+	RINGING,
+	DEBOUNCING_RINGOFF,
 };
 
 struct wctdm_cmd {
@@ -144,10 +153,11 @@
 };
 
 struct fxo {
-	int wasringing;
-	int lastrdtx;
-	int lastrdtx_count;
-	int ringdebounce;
+	enum ring_detector_state ring_state:4;
+	enum battery_state battery_state:4;
+	u8 ring_polarity_change_count:4;
+	u8 hook_ring_shadow;
+	s8 line_voltage_status;
 	int offhook;
 	int battdebounce;
 	int battalarm;
@@ -160,8 +170,7 @@
 	unsigned int neonmwi_debounce;
 	unsigned int neonmwi_offcounter;
 	unsigned long display_fxovoltage;
-	u8 hook_ring_shadow;
-	s8 line_voltage_status;
+	unsigned long ringdebounce_timer;
 };
 
 struct fxs {
@@ -219,7 +228,7 @@
 };
 
 struct wctdm_module {
-	union {
+	union modtypes {
 		struct fxo fxo;
 		struct fxs fxs;
 		struct qrv qrv;




More information about the svn-commits mailing list