diff options
author | kpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2008-01-11 23:37:37 +0000 |
---|---|---|
committer | kpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2008-01-11 23:37:37 +0000 |
commit | 6efe8c558f64bd3eb1497b6065e3a6558408ede9 (patch) | |
tree | ecd2cb6c3a6472074033b7f530c4556d4977b808 | |
parent | 82006e400dded9c66d9dbcd187b5d6573af0095f (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.c | 33 | ||||
-rw-r--r-- | wctdm24xxp/base.c | 34 | ||||
-rw-r--r-- | wctdm24xxp/wctdm24xxp.h | 1 |
3 files changed, 38 insertions, 30 deletions
@@ -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; |