From cd95077826aa2b3348f384b6972c9619efc7b00c Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Tue, 30 Aug 2011 16:38:41 +0000 Subject: wctdm24xxp: Use interval for debouncing FXO polarity detection. 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 Acked-by: Russ Meyerriecks git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10170 a0bf4364-ded3-4de4-8d8a-66a801d63aff --- drivers/dahdi/wctdm24xxp/base.c | 110 ++++++++++++++++++++++++---------- drivers/dahdi/wctdm24xxp/wctdm24xxp.h | 13 +++- 2 files changed, 90 insertions(+), 33 deletions(-) (limited to 'drivers/dahdi') diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c index aa6a2b6..fc79b73 100644 --- a/drivers/dahdi/wctdm24xxp/base.c +++ b/drivers/dahdi/wctdm24xxp/base.c @@ -2070,6 +2070,83 @@ wctdm_check_battery_present(struct wctdm *wc, struct wctdm_module *const mod) } } +static void +wctdm_fxo_stop_debouncing_polarity(struct wctdm *wc, + struct wctdm_module *const mod) +{ + struct fxo *const fxo = &mod->mod.fxo; + switch (fxo->polarity_state) { + case UNKNOWN_POLARITY: + break; + case POLARITY_DEBOUNCE_POSITIVE: + fxo->polarity_state = POLARITY_NEGATIVE; + break; + case POLARITY_POSITIVE: + break; + case POLARITY_DEBOUNCE_NEGATIVE: + fxo->polarity_state = POLARITY_POSITIVE; + break; + case POLARITY_NEGATIVE: + break; + }; +} + +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(get_dahdi_chan(wc, mod), + DAHDI_EVENT_POLARITY); + if (debug & DEBUG_CARD) { + dev_info(&wc->vb.pdev->dev, + "%s: Polarity NEGATIVE -> POSITIVE\n", + get_dahdi_chan(wc, mod)->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(get_dahdi_chan(wc, mod), + DAHDI_EVENT_POLARITY); + if (debug & DEBUG_CARD) { + dev_info(&wc->vb.pdev->dev, + "%s: Polarity POSITIVE -> NEGATIVE\n", + get_dahdi_chan(wc, mod)->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) { @@ -2116,41 +2193,14 @@ wctdm_voicedaa_check_hook(struct wctdm *wc, struct wctdm_module *const mod) } if (abs_voltage < battthresh) { - fxo->lastpol = fxo->polarity; - fxo->polaritydebounce = 0; - + wctdm_fxo_stop_debouncing_polarity(wc, mod); wctdm_check_battery_lost(wc, mod); } else { wctdm_check_battery_present(wc, mod); - - if (fxo->lastpol >= 0) { - if (fxo->line_voltage_status < 0) { - fxo->lastpol = -1; - fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK; - } - } - if (fxo->lastpol <= 0) { - if (fxo->line_voltage_status > 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(get_dahdi_chan(wc, mod), 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 e7547b3..467c5fa 100644 --- a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h +++ b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h @@ -122,6 +122,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; @@ -159,13 +167,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; @@ -173,6 +179,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