summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2011-03-23 16:22:50 -0500
committerShaun Ruffell <sruffell@digium.com>2011-04-15 14:19:03 -0500
commitc0a1a6e0ad42680c1b25623dbeb46be6d4f82d26 (patch)
tree204746007354d110d8b6b25d58bbafe45ddaaff2
parent63fe68cc24f38cb68118634cb83e30cf44fb5c9e (diff)
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 <sruffell@digium.com>
-rw-r--r--drivers/dahdi/wctdm24xxp/base.c85
-rw-r--r--drivers/dahdi/wctdm24xxp/wctdm24xxp.h13
2 files changed, 68 insertions, 30 deletions
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
@@ -1985,6 +1985,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)
{
signed char b;
@@ -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 {