summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2011-03-19 23:50:53 -0500
committerShaun Ruffell <sruffell@digium.com>2011-04-15 14:19:03 -0500
commit63fe68cc24f38cb68118634cb83e30cf44fb5c9e (patch)
treefd96b3d4a5bf73bfc54e7107c7e08cf5266349a0
parent5e850c02b8a4410d607ae23d78a121100406997b (diff)
wctdm24xxp: Use interval for debouncing FXO battery.
Allows the driver the option of not calling the misc function for every frame. Preparation for moving this processing out of the interrupt handler. This also introduces a state machine for the various battery states to (I hope) make the code easier to read. Signed-off-by: Shaun Ruffell <sruffell@digium.com>
-rw-r--r--drivers/dahdi/wctdm24xxp/base.c239
-rw-r--r--drivers/dahdi/wctdm24xxp/wctdm24xxp.h8
2 files changed, 140 insertions, 107 deletions
diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c
index 3535ed5..05637a0 100644
--- a/drivers/dahdi/wctdm24xxp/base.c
+++ b/drivers/dahdi/wctdm24xxp/base.c
@@ -1856,11 +1856,137 @@ static void wctdm_fxo_ring_detect(struct wctdm *wc, struct wctdm_module *mod)
}
}
+#define MS_PER_CHECK_HOOK 1
+
static void
-wctdm_voicedaa_check_hook(struct wctdm *wc, struct wctdm_module *const mod)
+wctdm_check_battery_lost(struct wctdm *wc, struct wctdm_module *const mod)
{
-#define MS_PER_CHECK_HOOK 1
+ struct fxo *const fxo = &mod->mod.fxo;
+
+ /* possible existing states:
+ battery lost, no debounce timer
+ battery lost, debounce timer (going to battery present)
+ battery present or unknown, no debounce timer
+ battery present or unknown, debounce timer (going to battery lost)
+ */
+ switch (fxo->battery_state) {
+ case BATTERY_DEBOUNCING_PRESENT:
+ /* we were going to BATTERY_PRESENT, but
+ * battery was lost again. */
+ fxo->battery_state = BATTERY_LOST;
+ break;
+ case BATTERY_UNKNOWN:
+ dahdi_hooksig(&mod->chan->chan, DAHDI_RXSIG_ONHOOK);
+ case BATTERY_DEBOUNCING_PRESENT_ALARM: /* intentional drop through */
+ case BATTERY_PRESENT:
+ fxo->battery_state = BATTERY_DEBOUNCING_LOST;
+ fxo->battdebounce_timer = wc->framecount + battdebounce;
+ break;
+ case BATTERY_DEBOUNCING_LOST:
+ if (time_after(wc->framecount, fxo->battdebounce_timer)) {
+ if (debug) {
+ dev_info(&wc->vb.pdev->dev,
+ "NO BATTERY on %d/%d!\n",
+ wc->aspan->span.spanno,
+ mod->card + 1);
+ }
+#ifdef JAPAN
+ if (!wc->ohdebounce && wc->offhook) {
+ dahdi_hooksig(wc->aspan->chans[card],
+ DAHDI_RXSIG_ONHOOK);
+ if (debug) {
+ dev_info(&wc->vb.pdev->dev,
+ "Signalled On Hook\n");
+ }
+#ifdef ZERO_BATT_RING
+ wc->onhook++;
+#endif
+ }
+#else
+ dahdi_hooksig(&mod->chan->chan, DAHDI_RXSIG_ONHOOK);
+#endif
+ /* set the alarm timer, taking into account that part
+ * of its time period has already passed while
+ * debouncing occurred */
+ fxo->battery_state = BATTERY_DEBOUNCING_LOST_ALARM;
+ fxo->battdebounce_timer = wc->framecount +
+ battalarm - battdebounce;
+ }
+ break;
+ case BATTERY_DEBOUNCING_LOST_ALARM:
+ if (time_after(wc->framecount, fxo->battdebounce_timer)) {
+ fxo->battery_state = BATTERY_LOST;
+ dahdi_alarm_channel(&mod->chan->chan, DAHDI_ALARM_RED);
+ }
+ break;
+ case BATTERY_LOST:
+ break;
+ }
+}
+
+static void
+wctdm_check_battery_present(struct wctdm *wc, struct wctdm_module *const mod)
+{
+ struct fxo *const fxo = &mod->mod.fxo;
+
+ switch (fxo->battery_state) {
+ case BATTERY_DEBOUNCING_PRESENT:
+ if (time_after(jiffies, fxo->battdebounce_timer)) {
+ if (debug) {
+ dev_info(&wc->vb.pdev->dev,
+ "BATTERY on %d/%d (%s)!\n",
+ wc->aspan->span.spanno, mod->card + 1,
+ (fxo->line_voltage_status < 0) ?
+ "-" : "+");
+ }
+#ifdef ZERO_BATT_RING
+ if (wc->onhook) {
+ wc->onhook = 0;
+ dahdi_hooksig(wc->aspan->chans[card],
+ DAHDI_RXSIG_OFFHOOK);
+ if (debug) {
+ dev_info(&wc->vb.pdev->dev,
+ "Signalled Off Hook\n");
+ }
+ }
+#else
+ dahdi_hooksig(&mod->chan->chan, DAHDI_RXSIG_OFFHOOK);
+#endif
+ /* set the alarm timer, taking into account that part
+ * of its time period has already passed while
+ * debouncing occurred */
+ fxo->battery_state = BATTERY_DEBOUNCING_PRESENT_ALARM;
+ fxo->battdebounce_timer = jiffies +
+ msecs_to_jiffies(battalarm - battdebounce);
+ }
+ break;
+ case BATTERY_DEBOUNCING_PRESENT_ALARM:
+ if (time_after(jiffies, fxo->battdebounce_timer)) {
+ fxo->battery_state = BATTERY_PRESENT;
+ dahdi_alarm_channel(&mod->chan->chan, DAHDI_ALARM_NONE);
+ }
+ break;
+ case BATTERY_PRESENT:
+ break;
+ case BATTERY_DEBOUNCING_LOST:
+ /* we were going to BATTERY_LOST, but battery appeared again,
+ * so clear the debounce timer */
+ fxo->battery_state = BATTERY_PRESENT;
+ break;
+ case BATTERY_UNKNOWN:
+ dahdi_hooksig(&mod->chan->chan, DAHDI_RXSIG_OFFHOOK);
+ case BATTERY_LOST: /* intentional drop through */
+ case BATTERY_DEBOUNCING_LOST_ALARM:
+ fxo->battery_state = BATTERY_DEBOUNCING_PRESENT;
+ fxo->battdebounce_timer = jiffies +
+ msecs_to_jiffies(battdebounce);
+ break;
+ }
+}
+static void
+wctdm_voicedaa_check_hook(struct wctdm *wc, struct wctdm_module *const mod)
+{
signed char b;
unsigned int abs_voltage;
struct fxo *const fxo = &mod->mod.fxo;
@@ -1878,15 +2004,14 @@ wctdm_voicedaa_check_hook(struct wctdm *wc, struct wctdm_module *const mod)
wctdm_fxo_ring_detect(wc, mod);
}
- b = fxo->line_voltage_status;
- abs_voltage = abs(b);
+ abs_voltage = abs(fxo->line_voltage_status);
if (fxovoltage && time_after(wc->framecount, fxo->display_fxovoltage)) {
/* Every 100 ms */
fxo->display_fxovoltage = wc->framecount + 100;
dev_info(&wc->vb.pdev->dev,
- "Port %d: Voltage: %d Debounce %d\n",
- mod->card + 1, b, fxo->battdebounce);
+ "Port %d: Voltage: %d\n",
+ mod->card + 1, fxo->line_voltage_status);
}
if (unlikely(DAHDI_RXSIG_INITIAL == mod->chan->chan.rxhooksig)) {
@@ -1901,96 +2026,13 @@ wctdm_voicedaa_check_hook(struct wctdm *wc, struct wctdm_module *const mod)
* to force us to report it again via dahdi_hooksig.
*
*/
- fxo->battery = BATTERY_UNKNOWN;
+ fxo->battery_state = BATTERY_UNKNOWN;
}
if (abs_voltage < battthresh) {
- /* possible existing states:
- battery lost, no debounce timer
- battery lost, debounce timer (going to battery present)
- battery present or unknown, no debounce timer
- battery present or unknown, debounce timer (going to battery lost)
- */
-
- if (fxo->battery == BATTERY_LOST) {
- if (fxo->battdebounce) {
- /* we were going to BATTERY_PRESENT, but battery was lost again,
- so clear the debounce timer */
- fxo->battdebounce = 0;
- }
- } else {
- if (fxo->battdebounce) {
- /* going to BATTERY_LOST, see if we are there yet */
- if (--fxo->battdebounce == 0) {
- fxo->battery = BATTERY_LOST;
- if (debug)
- dev_info(&wc->vb.pdev->dev, "NO BATTERY on %d/%d!\n", wc->aspan->span.spanno, mod->card + 1);
-#ifdef JAPAN
- if (!wc->ohdebounce && wc->offhook) {
- dahdi_hooksig(wc->aspan->chans[card], DAHDI_RXSIG_ONHOOK);
- if (debug)
- dev_info(&wc->vb.pdev->dev, "Signalled On Hook\n");
-#ifdef ZERO_BATT_RING
- wc->onhook++;
-#endif
- }
-#else
- dahdi_hooksig(&mod->chan->chan, DAHDI_RXSIG_ONHOOK);
- /* set the alarm timer, taking into account that part of its time
- period has already passed while debouncing occurred */
- fxo->battalarm = (battalarm - battdebounce) / MS_PER_CHECK_HOOK;
-#endif
- }
- } else {
- /* start the debounce timer to verify that battery has been lost */
- fxo->battdebounce = battdebounce / MS_PER_CHECK_HOOK;
- }
- }
+ wctdm_check_battery_lost(wc, mod);
} else {
- /* possible existing states:
- battery lost or unknown, no debounce timer
- battery lost or unknown, debounce timer (going to battery present)
- battery present, no debounce timer
- battery present, debounce timer (going to battery lost)
- */
-
- if (fxo->battery == BATTERY_PRESENT) {
- if (fxo->battdebounce) {
- /* we were going to BATTERY_LOST, but battery appeared again,
- so clear the debounce timer */
- fxo->battdebounce = 0;
- }
- } else {
- if (fxo->battdebounce) {
- /* going to BATTERY_PRESENT, see if we are there yet */
- if (--fxo->battdebounce == 0) {
- fxo->battery = BATTERY_PRESENT;
- if (debug) {
- dev_info(&wc->vb.pdev->dev,
- "BATTERY on %d/%d (%s)!\n",
- wc->aspan->span.spanno,
- mod->card + 1,
- (b < 0) ? "-" : "+");
- }
-#ifdef ZERO_BATT_RING
- if (wc->onhook) {
- wc->onhook = 0;
- dahdi_hooksig(wc->aspan->chans[card], DAHDI_RXSIG_OFFHOOK);
- if (debug)
- dev_info(&wc->vb.pdev->dev, "Signalled Off Hook\n");
- }
-#else
- dahdi_hooksig(&mod->chan->chan, DAHDI_RXSIG_OFFHOOK);
-#endif
- /* set the alarm timer, taking into account that part of its time
- period has already passed while debouncing occurred */
- fxo->battalarm = (battalarm - battdebounce) / MS_PER_CHECK_HOOK;
- }
- } else {
- /* start the debounce timer to verify that battery has appeared */
- fxo->battdebounce = battdebounce / MS_PER_CHECK_HOOK;
- }
- }
+ wctdm_check_battery_present(wc, mod);
if (fxo->lastpol >= 0) {
if (b < 0) {
@@ -2006,17 +2048,6 @@ wctdm_voicedaa_check_hook(struct wctdm *wc, struct wctdm_module *const mod)
}
}
- if (fxo->battalarm) {
- if (--fxo->battalarm == 0) {
- /* the alarm timer has expired, so update the battery alarm state
- for this channel */
- dahdi_alarm_channel(&mod->chan->chan,
- (fxo->battery == BATTERY_LOST) ?
- DAHDI_ALARM_RED :
- DAHDI_ALARM_NONE);
- }
- }
-
if (fxo->polaritydebounce) {
fxo->polaritydebounce--;
if (fxo->polaritydebounce < 1) {
@@ -2037,7 +2068,7 @@ wctdm_voicedaa_check_hook(struct wctdm *wc, struct wctdm_module *const mod)
* where the voltage is over the neon limit but
* does not vary greatly from the last reading
*/
- if (fxo->battery == 1 &&
+ if (fxo->battery_state == BATTERY_PRESENT &&
abs_voltage > neonmwi_level &&
(0 == fxo->neonmwi_last_voltage ||
(b >= fxo->neonmwi_last_voltage - neonmwi_envelope &&
diff --git a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
index 47e72af..16dd8c7 100644
--- a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
+++ b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
@@ -104,7 +104,11 @@ struct calregs {
enum battery_state {
BATTERY_UNKNOWN = 0,
+ BATTERY_DEBOUNCING_PRESENT,
+ BATTERY_DEBOUNCING_PRESENT_ALARM,
BATTERY_PRESENT,
+ BATTERY_DEBOUNCING_LOST,
+ BATTERY_DEBOUNCING_LOST_ALARM,
BATTERY_LOST,
};
@@ -165,9 +169,6 @@ struct fxo {
u8 hook_ring_shadow;
s8 line_voltage_status;
int offhook;
- int battdebounce;
- int battalarm;
- enum battery_state battery;
int lastpol;
int polarity;
int polaritydebounce;
@@ -177,6 +178,7 @@ struct fxo {
unsigned int neonmwi_offcounter;
unsigned long display_fxovoltage;
unsigned long ringdebounce_timer;
+ unsigned long battdebounce_timer;
};
struct fxs {