diff options
Diffstat (limited to 'wctdm24xxp/base.c')
-rw-r--r-- | wctdm24xxp/base.c | 80 |
1 files changed, 61 insertions, 19 deletions
diff --git a/wctdm24xxp/base.c b/wctdm24xxp/base.c index 5a63894..0d04d7f 100644 --- a/wctdm24xxp/base.c +++ b/wctdm24xxp/base.c @@ -264,6 +264,8 @@ static char *opermode = "FCC"; static int fxshonormode = 0; static int alawoverride = 0; static int fxo_addrs[4] = { 0x00, 0x08, 0x04, 0x0c }; +static int ringdebounce = DEFAULT_RING_DEBOUNCE; +static int fwringdetect = 0; #ifdef VPM_SUPPORT static int vpmsupport = 1; static int vpmdtmfsupport = 0; @@ -1216,30 +1218,56 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card) 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 * RING_DEBOUNCE) { - if (!wc->mods[card].fxo.wasringing) { - wc->mods[card].fxo.wasringing = 1; - zt_hooksig(&wc->chans[card], ZT_RXSIG_RING); - if (debug & DEBUG_CARD) - printk("RING on %d/%d!\n", wc->span.spanno, card + 1); + if (fwringdetect) { + res = wc->cmdq[card].isrshadow[0] & 0x60; + 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; + 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.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; + 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 = ZT_CHUNKSIZE * RING_DEBOUNCE; + } else if (res && wc->mods[card].fxo.battery) { + wc->mods[card].fxo.lastrdtx = res; + wc->mods[card].fxo.ringdebounce = 10; } } 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.wasringing = 0; - zt_hooksig(&wc->chans[card], ZT_RXSIG_OFFHOOK); - if (debug & DEBUG_CARD) - printk("NO RING on %d/%d!\n", wc->span.spanno, card + 1); + res = wc->cmdq[card].isrshadow[0]; + if ((res & 0x60) && wc->mods[card].fxo.battery) { + wc->mods[card].fxo.ringdebounce += (ZT_CHUNKSIZE * 16); + if (wc->mods[card].fxo.ringdebounce >= ZT_CHUNKSIZE * ringdebounce) { + if (!wc->mods[card].fxo.wasringing) { + wc->mods[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); + } + wc->mods[card].fxo.ringdebounce = ZT_CHUNKSIZE * ringdebounce; } - wc->mods[card].fxo.ringdebounce = 0; + } else { + wc->mods[card].fxo.ringdebounce -= ZT_CHUNKSIZE * 4; + if (wc->mods[card].fxo.ringdebounce <= 0) { + if (wc->mods[card].fxo.wasringing) { + wc->mods[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); + } + wc->mods[card].fxo.ringdebounce = 0; + } + } - } } b = wc->cmdq[card].isrshadow[1]; /* Voltage */ @@ -1929,6 +1957,16 @@ 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); + + if(fwringdetect) { + /* Enable ring detector full-wave rectifier mode */ + wctdm_setreg(wc, card, 18, 2); + wctdm_setreg(wc, card, 24, 0); + } else { + /* Set to the device defaults */ + wctdm_setreg(wc, card, 18, 0); + wctdm_setreg(wc, card, 24, 0x19); + } /* Set DC Termination: Tip/Ring voltage adjust, minimum operational current, current limitation */ @@ -3703,6 +3741,8 @@ module_param(fxshonormode, int, 0600); module_param(battdebounce, int, 0600); module_param(battthresh, int, 0600); module_param(alawoverride, int, 0600); +module_param(ringdebounce, int, 0600); +module_param(fwringdetect, int, 0600); #ifdef VPM_SUPPORT module_param(vpmsupport, int, 0600); module_param(vpmdtmfsupport, int, 0600); @@ -3725,6 +3765,8 @@ MODULE_PARM(fxshonormode, "i"); MODULE_PARM(battdebounce, "i"); MODULE_PARM(battthresh, "i"); MODULE_PARM(alawoverride, "i"); +MODULE_PARM(ringdebounce, "i"); +MODULE_PARM(fwringdetect, "i"); #ifdef VPM_SUPPORT MODULE_PARM(vpmsupport, "i"); MODULE_PARM(vpmdtmfsupport, "i"); |