summaryrefslogtreecommitdiff
path: root/drivers/dahdi/wctdm24xxp
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2011-08-30 16:38:36 +0000
committerShaun Ruffell <sruffell@digium.com>2011-08-30 16:38:36 +0000
commited9d6ec1e397916c69cee2dd1ebd3c7e3e18793b (patch)
tree70399de57ec39436a712f1982cee22442ce437d1 /drivers/dahdi/wctdm24xxp
parent6ec60e48a7c141b8b4c8288e7654ee982dff9ad1 (diff)
wctdm24xxp: Use interval for debouncing FXO battery.
Allows the driver the option of not calling the misc function for every frame. This is part of preparation for moving misc processing out of the interrupt handler. Also use a state machine for the various battery states to unify the technique for debouncing the various signals in the driver. 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@10169 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/wctdm24xxp')
-rw-r--r--drivers/dahdi/wctdm24xxp/base.c253
-rw-r--r--drivers/dahdi/wctdm24xxp/wctdm24xxp.h8
2 files changed, 148 insertions, 113 deletions
diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c
index 6ad45a3..aa6a2b6 100644
--- a/drivers/dahdi/wctdm24xxp/base.c
+++ b/drivers/dahdi/wctdm24xxp/base.c
@@ -1940,13 +1940,141 @@ 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:
+ mod_hooksig(wc, mod, 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
+ mod_hooksig(wc, mod, 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(get_dahdi_chan(wc, mod),
+ 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
+ mod_hooksig(wc, mod, 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(get_dahdi_chan(wc, mod),
+ 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:
+ mod_hooksig(wc, mod, 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;
+ u8 abs_voltage;
struct fxo *const fxo = &mod->mod.fxo;
/* Try to track issues that plague slot one FXO's */
@@ -1962,15 +2090,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 == get_dahdi_chan(wc, mod)->rxhooksig)) {
@@ -1985,125 +2112,31 @@ 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)
- */
-
fxo->lastpol = fxo->polarity;
fxo->polaritydebounce = 0;
- 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
- mod_hooksig(wc, mod, 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;
- mod_hooksig(wc, mod, DAHDI_RXSIG_OFFHOOK);
- if (debug)
- dev_info(&wc->vb.pdev->dev, "Signalled Off Hook\n");
- }
-#else
- mod_hooksig(wc, mod, 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) {
+ if (fxo->line_voltage_status < 0) {
fxo->lastpol = -1;
fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK;
}
}
if (fxo->lastpol <= 0) {
- if (b > 0) {
+ if (fxo->line_voltage_status > 0) {
fxo->lastpol = 1;
fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK;
}
}
}
- if (fxo->battalarm) {
- if (--fxo->battalarm == 0) {
- /* the alarm timer has expired, so update the battery alarm state
- for this channel */
- dahdi_alarm_channel(get_dahdi_chan(wc, mod),
- (fxo->battery == BATTERY_LOST) ?
- DAHDI_ALARM_RED :
- DAHDI_ALARM_NONE);
- }
- }
-
if (fxo->polaritydebounce) {
fxo->polaritydebounce--;
if (fxo->polaritydebounce < 1) {
@@ -2124,12 +2157,12 @@ 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 &&
- b <= fxo->neonmwi_last_voltage + neonmwi_envelope ))) {
- fxo->neonmwi_last_voltage = b;
+ (fxo->line_voltage_status >= fxo->neonmwi_last_voltage - neonmwi_envelope &&
+ fxo->line_voltage_status <= fxo->neonmwi_last_voltage + neonmwi_envelope))) {
+ fxo->neonmwi_last_voltage = fxo->line_voltage_status;
if (NEONMWI_ON_DEBOUNCE == fxo->neonmwi_debounce) {
fxo->neonmwi_offcounter = neonmwi_offlimit_cycles;
if (0 == fxo->neonmwi_state) {
diff --git a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
index 81ec1c2..e7547b3 100644
--- a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
+++ b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
@@ -105,7 +105,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,
};
@@ -159,9 +163,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;
@@ -171,6 +172,7 @@ struct fxo {
unsigned int neonmwi_offcounter;
unsigned long display_fxovoltage;
unsigned long ringdebounce_timer;
+ unsigned long battdebounce_timer;
};
struct fxs {