summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-01-11 23:37:37 +0000
committerkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-01-11 23:37:37 +0000
commit6efe8c558f64bd3eb1497b6065e3a6558408ede9 (patch)
treeecd2cb6c3a6472074033b7f530c4556d4977b808
parent82006e400dded9c66d9dbcd187b5d6573af0095f (diff)
Improve ring detection when polarity reversals are present.
(closes issue #9264) Reported by: mjagdis Patches: zaptel-ring.diff uploaded by mjagdis (modified by me to add support in wctdm24xxp as well) Tested by: benbrown git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@3674 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rw-r--r--wctdm.c33
-rw-r--r--wctdm24xxp/base.c34
-rw-r--r--wctdm24xxp/wctdm24xxp.h1
3 files changed, 38 insertions, 30 deletions
diff --git a/wctdm.c b/wctdm.c
index 9d6e503..9040c75 100644
--- a/wctdm.c
+++ b/wctdm.c
@@ -1,5 +1,5 @@
/*
- * Wilcard TDM400P TDM FXS/FXO Interface Driver for Zapata Telephony interface
+ * Wildcard TDM400P TDM FXS/FXO Interface Driver for Zapata Telephony interface
*
* Written by Mark Spencer <markster@digium.com>
* Matthew Fredrickson <creslin@digium.com>
@@ -312,6 +312,7 @@ struct wctdm {
#else
int wasringing;
#endif
+ int lastrdtx;
int ringdebounce;
int offhook;
int battdebounce;
@@ -857,30 +858,28 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card)
return;
#ifndef AUDIO_RINGCHECK
if (!wc->mod[card].fxo.offhook) {
- res = wc->reg0shadow[card];
- if ((res & 0x60) && wc->mod[card].fxo.battery) {
- wc->mod[card].fxo.ringdebounce += (ZT_CHUNKSIZE * 16);
- if (wc->mod[card].fxo.ringdebounce >= ZT_CHUNKSIZE * ringdebounce) {
+ res = wc->reg0shadow[card] & 0x60;
+ if (wc->mod[card].fxo.ringdebounce--) {
+ if (res && (res != wc->mod[card].fxo.lastrdtx) && wc->mod[card].fxo.battery) {
if (!wc->mod[card].fxo.wasringing) {
wc->mod[card].fxo.wasringing = 1;
- zt_hooksig(&wc->chans[card], ZT_RXSIG_RING);
if (debug)
printk("RING on %d/%d!\n", wc->span.spanno, card + 1);
+ zt_hooksig(&wc->chans[card], ZT_RXSIG_RING);
}
- wc->mod[card].fxo.ringdebounce = ZT_CHUNKSIZE * ringdebounce;
- }
- } else {
- wc->mod[card].fxo.ringdebounce -= ZT_CHUNKSIZE * 4;
- if (wc->mod[card].fxo.ringdebounce <= 0) {
- if (wc->mod[card].fxo.wasringing) {
+ wc->mod[card].fxo.lastrdtx = res;
+ wc->mod[card].fxo.ringdebounce = 10;
+ } else if (!res) {
+ if ((wc->mod[card].fxo.ringdebounce == 0) && wc->mod[card].fxo.wasringing) {
wc->mod[card].fxo.wasringing = 0;
- zt_hooksig(&wc->chans[card], ZT_RXSIG_OFFHOOK);
if (debug)
printk("NO RING on %d/%d!\n", wc->span.spanno, card + 1);
+ zt_hooksig(&wc->chans[card], ZT_RXSIG_OFFHOOK);
}
- wc->mod[card].fxo.ringdebounce = 0;
}
-
+ } else if (res && wc->mod[card].fxo.battery) {
+ wc->mod[card].fxo.lastrdtx = res;
+ wc->mod[card].fxo.ringdebounce = 10;
}
}
#endif
@@ -1505,6 +1504,10 @@ static int wctdm_init_voicedaa(struct wctdm *wc, int card, int fast, int manual,
reg16 |= (fxo_modes[_opermode].rz << 1);
reg16 |= (fxo_modes[_opermode].rt);
wctdm_setreg(wc, card, 16, reg16);
+
+ /* Enable ring detector full-wave rectifier mode */
+ wctdm_setreg(wc, card, 18, 2);
+ wctdm_setreg(wc, card, 24, 0);
/* Set DC Termination:
Tip/Ring voltage adjust, minimum operational current, current limitation */
diff --git a/wctdm24xxp/base.c b/wctdm24xxp/base.c
index 32b4230..b67cae5 100644
--- a/wctdm24xxp/base.c
+++ b/wctdm24xxp/base.c
@@ -1327,33 +1327,33 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card)
if (b != 0x8)
wctdm_setreg_intr(wc, card, 5, 0x8);
}
+
if (!wc->mods[card].fxo.offhook) {
res = wc->cmdq[card].isrshadow[0]; /* Hook/Ring state */
- if ((res & 0x60) && wc->mods[card].fxo.battery) {
- wc->mods[card].fxo.ringdebounce += (ZT_CHUNKSIZE * 4);
- if (wc->mods[card].fxo.ringdebounce >= ZT_CHUNKSIZE * ringdebounce) {
+ if (wc->mods[card].fxo.ringdebounce--) {
+ if (res && (res != wc->mods[card].fxo.lastrdtx) && wc->mods[card].fxo.battery) {
if (!wc->mods[card].fxo.wasringing) {
wc->mods[card].fxo.wasringing = 1;
- zt_hooksig(&wc->chans[card], ZT_RXSIG_RING);
- if (debug & DEBUG_CARD)
+ if (debug)
printk("RING on %d/%d!\n", wc->span.spanno, card + 1);
+ zt_hooksig(&wc->chans[card], ZT_RXSIG_RING);
}
- wc->mods[card].fxo.ringdebounce = ZT_CHUNKSIZE * ringdebounce;
- }
- } else {
- wc->mods[card].fxo.ringdebounce -= ZT_CHUNKSIZE;
- if (wc->mods[card].fxo.ringdebounce <= 0) {
- if (wc->mods[card].fxo.wasringing) {
+ wc->mods[card].fxo.lastrdtx = res;
+ wc->mods[card].fxo.ringdebounce = 10;
+ } else if (!res) {
+ if ((wc->mods[card].fxo.ringdebounce == 0) && wc->mods[card].fxo.wasringing) {
wc->mods[card].fxo.wasringing = 0;
- zt_hooksig(&wc->chans[card], ZT_RXSIG_OFFHOOK);
- if (debug & DEBUG_CARD)
+ if (debug)
printk("NO RING on %d/%d!\n", wc->span.spanno, card + 1);
+ zt_hooksig(&wc->chans[card], ZT_RXSIG_OFFHOOK);
}
- wc->mods[card].fxo.ringdebounce = 0;
}
-
+ } else if (res && wc->mods[card].fxo.battery) {
+ wc->mods[card].fxo.lastrdtx = res;
+ wc->mods[card].fxo.ringdebounce = 10;
}
}
+
b = wc->cmdq[card].isrshadow[1]; /* Voltage */
if (fxovoltage) {
@@ -2097,6 +2097,10 @@ static int wctdm_init_voicedaa(struct wctdm *wc, int card, int fast, int manual,
reg16 |= (fxo_modes[_opermode].rt);
wctdm_setreg(wc, card, 16, reg16);
+ /* Enable ring detector full-wave rectifier mode */
+ wctdm_setreg(wc, card, 18, 2);
+ wctdm_setreg(wc, card, 24, 0);
+
/* Set DC Termination:
Tip/Ring voltage adjust, minimum operational current, current limitation */
reg26 |= (fxo_modes[_opermode].dcv << 6);
diff --git a/wctdm24xxp/wctdm24xxp.h b/wctdm24xxp/wctdm24xxp.h
index c801c24..7f76a0a 100644
--- a/wctdm24xxp/wctdm24xxp.h
+++ b/wctdm24xxp/wctdm24xxp.h
@@ -225,6 +225,7 @@ struct wctdm {
int lastpol;
int polarity;
int polaritydebounce;
+ int lastrdtx;
} fxo;
struct {
int oldrxhook;