From c0a1a6e0ad42680c1b25623dbeb46be6d4f82d26 Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Wed, 23 Mar 2011 16:22:50 -0500 Subject: wctdm24xxp: Use time range for debouncing polarity. Eliminate the assumption that the check function is going to be called for every frame. Also, use a state machine to make polarity debouncing similar to the other debouncing code. Signed-off-by: Shaun Ruffell --- drivers/dahdi/wctdm24xxp/base.c | 85 ++++++++++++++++++++++++----------- drivers/dahdi/wctdm24xxp/wctdm24xxp.h | 13 ++++-- 2 files changed, 68 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c index 05637a0..eaad245 100644 --- a/drivers/dahdi/wctdm24xxp/base.c +++ b/drivers/dahdi/wctdm24xxp/base.c @@ -1984,6 +1984,62 @@ wctdm_check_battery_present(struct wctdm *wc, struct wctdm_module *const mod) } } +static void +wctdm_fxo_check_polarity(struct wctdm *wc, struct wctdm_module *const mod, + const bool positive_polarity) +{ + struct fxo *const fxo = &mod->mod.fxo; + + switch (fxo->polarity_state) { + case UNKNOWN_POLARITY: + fxo->polarity_state = (positive_polarity) ? POLARITY_POSITIVE : + POLARITY_NEGATIVE; + break; + case POLARITY_DEBOUNCE_POSITIVE: + if (!positive_polarity) { + fxo->polarity_state = POLARITY_NEGATIVE; + } else if (time_after(wc->framecount, fxo->poldebounce_timer)) { + fxo->polarity_state = POLARITY_POSITIVE; + dahdi_qevent_lock(&mod->chan->chan, + DAHDI_EVENT_POLARITY); + if (debug & DEBUG_CARD) { + dev_info(&wc->vb.pdev->dev, + "%s: Polarity NEGATIVE -> POSITIVE\n", + mod->chan->chan.name); + } + } + break; + case POLARITY_POSITIVE: + if (!positive_polarity) { + fxo->polarity_state = POLARITY_DEBOUNCE_NEGATIVE; + fxo->poldebounce_timer = wc->framecount + + POLARITY_DEBOUNCE; + } + break; + case POLARITY_DEBOUNCE_NEGATIVE: + if (positive_polarity) { + fxo->polarity_state = POLARITY_POSITIVE; + } else if (time_after(wc->framecount, fxo->poldebounce_timer)) { + dahdi_qevent_lock(&mod->chan->chan, + DAHDI_EVENT_POLARITY); + if (debug & DEBUG_CARD) { + dev_info(&wc->vb.pdev->dev, + "%s: Polarity POSITIVE -> NEGATIVE\n", + mod->chan->chan.name); + } + fxo->polarity_state = POLARITY_NEGATIVE; + } + break; + case POLARITY_NEGATIVE: + if (positive_polarity) { + fxo->polarity_state = POLARITY_DEBOUNCE_POSITIVE; + fxo->poldebounce_timer = wc->framecount + + POLARITY_DEBOUNCE; + } + break; + }; +} + static void wctdm_voicedaa_check_hook(struct wctdm *wc, struct wctdm_module *const mod) { @@ -2033,35 +2089,10 @@ wctdm_voicedaa_check_hook(struct wctdm *wc, struct wctdm_module *const mod) wctdm_check_battery_lost(wc, mod); } else { wctdm_check_battery_present(wc, mod); - - if (fxo->lastpol >= 0) { - if (b < 0) { - fxo->lastpol = -1; - fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK; - } - } - if (fxo->lastpol <= 0) { - if (b > 0) { - fxo->lastpol = 1; - fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK; - } - } + wctdm_fxo_check_polarity(wc, mod, + (fxo->line_voltage_status > 0)); } - if (fxo->polaritydebounce) { - fxo->polaritydebounce--; - if (fxo->polaritydebounce < 1) { - if (fxo->lastpol != fxo->polarity) { - if (debug & DEBUG_CARD) - dev_info(&wc->vb.pdev->dev, "%lu Polarity reversed (%d -> %d)\n", jiffies, - fxo->polarity, - fxo->lastpol); - if (fxo->polarity) - dahdi_qevent_lock(&mod->chan->chan, DAHDI_EVENT_POLARITY); - fxo->polarity = fxo->lastpol; - } - } - } /* Look for neon mwi pulse */ if (neonmwi_monitor && !fxo->offhook) { /* Look for 4 consecutive voltage readings diff --git a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h index 16dd8c7..21235f5 100644 --- a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h +++ b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h @@ -129,6 +129,14 @@ enum ring_detector_state { DEBOUNCING_RINGOFF, }; +enum polarity_state { + UNKNOWN_POLARITY = 0, + POLARITY_DEBOUNCE_POSITIVE, + POLARITY_POSITIVE, + POLARITY_DEBOUNCE_NEGATIVE, + POLARITY_NEGATIVE, +}; + struct wctdm_cmd { struct list_head node; struct completion *complete; @@ -165,13 +173,11 @@ struct wctdm_chan { struct fxo { enum ring_detector_state ring_state:4; enum battery_state battery_state:4; + enum polarity_state polarity_state:4; u8 ring_polarity_change_count:4; u8 hook_ring_shadow; s8 line_voltage_status; int offhook; - int lastpol; - int polarity; - int polaritydebounce; int neonmwi_state; int neonmwi_last_voltage; unsigned int neonmwi_debounce; @@ -179,6 +185,7 @@ struct fxo { unsigned long display_fxovoltage; unsigned long ringdebounce_timer; unsigned long battdebounce_timer; + unsigned long poldebounce_timer; }; struct fxs { -- cgit v1.2.3