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 <sruffell@digium.com>
Acked-by: Russ Meyerriecks <rmeyerriecks@digium.com>

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10170 a0bf4364-ded3-4de4-8d8a-66a801d63aff
This commit is contained in:
Shaun Ruffell 2011-08-30 16:38:41 +00:00
parent 874b76bd22
commit 17f0170829
2 changed files with 90 additions and 33 deletions

View File

@ -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

View File

@ -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 {