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:
parent
874b76bd22
commit
17f0170829
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue