summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2003-09-17 16:26:48 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2003-09-17 16:26:48 +0000
commit2aff1ceedf24d5ddf41e55569dee4056e9d6a248 (patch)
tree9f52aed295df98f5eee17faae8e9c5c36f873f32
parent0197f3e452d7599b80b2cc24dad1af7e2a3c72cd (diff)
Auto reset if loopback is detected
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@243 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rwxr-xr-x.cvsignore2
-rwxr-xr-xwcfxs.c75
-rwxr-xr-xwctdm.c75
3 files changed, 92 insertions, 60 deletions
diff --git a/.cvsignore b/.cvsignore
index 186cacd..ef9f9d5 100755
--- a/.cvsignore
+++ b/.cvsignore
@@ -10,3 +10,5 @@ tones.h
makefw
libtonezone.so.1.0
gendigits
+fxstest
+
diff --git a/wcfxs.c b/wcfxs.c
index d66076c..56f712c 100755
--- a/wcfxs.c
+++ b/wcfxs.c
@@ -1,5 +1,5 @@
/*
- * Wilcard S100P FXS Interface Driver for Zapata Telephony interface
+ * Wilcard TDM400P FXS Interface Driver for Zapata Telephony interface
*
* Written by Mark Spencer <markster@linux-support.net>
* Matthew Fredrickson <creslin@linux-support.net>
@@ -187,6 +187,8 @@ static void wcfxs_release(struct wcfxs *wc);
static int debug = 0;
+static int wcfxs_init_proslic(struct wcfxs *wc, int card, int fast);
+
static inline void wcfxs_transmitprep(struct wcfxs *wc, unsigned char ints)
{
volatile unsigned int *writechunk;
@@ -282,7 +284,7 @@ static void wcfxs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
if (!(wc->intcount % 10000)) {
/* Accept an alarm once per 10 seconds */
- for (x=0;x<4;x++)
+ for (x=0;x<4;x++)
if (wc->palarms[x])
wc->palarms[x]--;
}
@@ -586,7 +588,7 @@ static int wcfxs_powerleak_test(struct wcfxs *wc, int card)
return 0;
}
-static int wcfxs_powerup_proslic(struct wcfxs *wc, int card)
+static int wcfxs_powerup_proslic(struct wcfxs *wc, int card, int fast)
{
unsigned char vbat;
unsigned long origjiffies;
@@ -603,6 +605,10 @@ static int wcfxs_powerup_proslic(struct wcfxs *wc, int card)
/* Disable powerdown */
wcfxs_setreg(wc, card, 14, 0);
+ /* If fast, don't bother checking anymore */
+ if (fast)
+ return 0;
+
while((vbat = wcfxs_getreg(wc, card, 82)) < 0xc0) {
/* Wait no more than 500ms */
if ((jiffies - origjiffies) > HZ/2) {
@@ -748,7 +754,7 @@ static int wcfxs_calibrate(struct wcfxs *wc, int card)
return 0;
}
#endif
-static int wcfxs_init_proslic(struct wcfxs *wc, int card)
+static int wcfxs_init_proslic(struct wcfxs *wc, int card, int fast)
{
unsigned short tmp[5];
@@ -790,29 +796,31 @@ static int wcfxs_init_proslic(struct wcfxs *wc, int card)
}
/* Power up the DC-DC converter */
- if (wcfxs_powerup_proslic(wc, card)) {
+ if (wcfxs_powerup_proslic(wc, card, fast)) {
printk("Unable to do INITIAL ProSLIC powerup on module %d\n", card);
return -1;
}
- /* Check for power leaks */
- if (wcfxs_powerleak_test(wc, card)) {
- printk("ProSLIC module %d failed leakage test. Check for short circuit\n", card);
- }
+ if (!fast) {
- /* Power up again */
- if (wcfxs_powerup_proslic(wc, card)) {
- printk("Unable to do FINAL ProSLIC powerup on module %d\n", card);
- return -1;
- }
+ /* Check for power leaks */
+ if (wcfxs_powerleak_test(wc, card)) {
+ printk("ProSLIC module %d failed leakage test. Check for short circuit\n", card);
+ }
+ /* Power up again */
+ if (wcfxs_powerup_proslic(wc, card, fast)) {
+ printk("Unable to do FINAL ProSLIC powerup on module %d\n", card);
+ return -1;
+ }
#ifndef NO_CALIBRATION
- /* Perform calibration */
- if (wcfxs_manual_calibrate(wc, card)) {
- printk("ProSlic died on Calibration (try -DNO_CALIBRATION in Makefile).\n");
- return -1;
- }
+ /* Perform calibration */
+ if (wcfxs_manual_calibrate(wc, card)) {
+ printk("ProSlic died on Calibration (try -DNO_CALIBRATION in Makefile).\n");
+ return -1;
+ }
#endif
+ }
/* Calibration complete, restore original values */
for (x=0;x<5;x++) {
wcfxs_setreg_indirect(wc, card, x + 35, tmp[x]);
@@ -879,16 +887,23 @@ static inline void wcfxs_check_hook(struct wcfxs *wc, int card)
/* For some reason we have to debounce the
hook detector. */
- res = wcfxs_getreg(wc, card, 64);
- if (!res && (res != wc->lasttxhook[card])) {
- if (wc->palarms[card]++ < MAX_ALARMS) {
- printk("Power alarm on module %d, resetting!\n", card + 1);
- if (wc->lasttxhook[card] == 4)
- wc->lasttxhook[card] = 1;
- wcfxs_setreg(wc, card, 64, wc->lasttxhook[card]);
- } else {
- if (wc->palarms[card] == MAX_ALARMS)
- printk("Too many power alarms on card %d, NOT resetting!\n", card + 1);
+ /* Check loopback */
+ res = wcfxs_getreg(wc, card, 8);
+ if (res) {
+ printk("Ouch, part reset, quickly restoring reality (%d)\n", card);
+ wcfxs_init_proslic(wc, card, 1);
+ } else {
+ res = wcfxs_getreg(wc, card, 64);
+ if (!res && (res != wc->lasttxhook[card])) {
+ if (wc->palarms[card]++ < MAX_ALARMS) {
+ printk("Power alarm on module %d, resetting!\n", card + 1);
+ if (wc->lasttxhook[card] == 4)
+ wc->lasttxhook[card] = 1;
+ wcfxs_setreg(wc, card, 64, wc->lasttxhook[card]);
+ } else {
+ if (wc->palarms[card] == MAX_ALARMS)
+ printk("Too many power alarms on card %d, NOT resetting!\n", card + 1);
+ }
}
}
res = wcfxs_getreg(wc, card, 68);
@@ -1162,7 +1177,7 @@ static int wcfxs_hardware_init(struct wcfxs *wc)
while(jiffies - oldjiffies < (HZ / 4) + 1);
for (x=0;x<wc->cards;x++) {
- if (!wcfxs_init_proslic(wc, x)) {
+ if (!wcfxs_init_proslic(wc, x, 0)) {
printk("Module %d: Initialized\n", x);
wc->cardflag |= (1 << x);
} else
diff --git a/wctdm.c b/wctdm.c
index d66076c..56f712c 100755
--- a/wctdm.c
+++ b/wctdm.c
@@ -1,5 +1,5 @@
/*
- * Wilcard S100P FXS Interface Driver for Zapata Telephony interface
+ * Wilcard TDM400P FXS Interface Driver for Zapata Telephony interface
*
* Written by Mark Spencer <markster@linux-support.net>
* Matthew Fredrickson <creslin@linux-support.net>
@@ -187,6 +187,8 @@ static void wcfxs_release(struct wcfxs *wc);
static int debug = 0;
+static int wcfxs_init_proslic(struct wcfxs *wc, int card, int fast);
+
static inline void wcfxs_transmitprep(struct wcfxs *wc, unsigned char ints)
{
volatile unsigned int *writechunk;
@@ -282,7 +284,7 @@ static void wcfxs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
if (!(wc->intcount % 10000)) {
/* Accept an alarm once per 10 seconds */
- for (x=0;x<4;x++)
+ for (x=0;x<4;x++)
if (wc->palarms[x])
wc->palarms[x]--;
}
@@ -586,7 +588,7 @@ static int wcfxs_powerleak_test(struct wcfxs *wc, int card)
return 0;
}
-static int wcfxs_powerup_proslic(struct wcfxs *wc, int card)
+static int wcfxs_powerup_proslic(struct wcfxs *wc, int card, int fast)
{
unsigned char vbat;
unsigned long origjiffies;
@@ -603,6 +605,10 @@ static int wcfxs_powerup_proslic(struct wcfxs *wc, int card)
/* Disable powerdown */
wcfxs_setreg(wc, card, 14, 0);
+ /* If fast, don't bother checking anymore */
+ if (fast)
+ return 0;
+
while((vbat = wcfxs_getreg(wc, card, 82)) < 0xc0) {
/* Wait no more than 500ms */
if ((jiffies - origjiffies) > HZ/2) {
@@ -748,7 +754,7 @@ static int wcfxs_calibrate(struct wcfxs *wc, int card)
return 0;
}
#endif
-static int wcfxs_init_proslic(struct wcfxs *wc, int card)
+static int wcfxs_init_proslic(struct wcfxs *wc, int card, int fast)
{
unsigned short tmp[5];
@@ -790,29 +796,31 @@ static int wcfxs_init_proslic(struct wcfxs *wc, int card)
}
/* Power up the DC-DC converter */
- if (wcfxs_powerup_proslic(wc, card)) {
+ if (wcfxs_powerup_proslic(wc, card, fast)) {
printk("Unable to do INITIAL ProSLIC powerup on module %d\n", card);
return -1;
}
- /* Check for power leaks */
- if (wcfxs_powerleak_test(wc, card)) {
- printk("ProSLIC module %d failed leakage test. Check for short circuit\n", card);
- }
+ if (!fast) {
- /* Power up again */
- if (wcfxs_powerup_proslic(wc, card)) {
- printk("Unable to do FINAL ProSLIC powerup on module %d\n", card);
- return -1;
- }
+ /* Check for power leaks */
+ if (wcfxs_powerleak_test(wc, card)) {
+ printk("ProSLIC module %d failed leakage test. Check for short circuit\n", card);
+ }
+ /* Power up again */
+ if (wcfxs_powerup_proslic(wc, card, fast)) {
+ printk("Unable to do FINAL ProSLIC powerup on module %d\n", card);
+ return -1;
+ }
#ifndef NO_CALIBRATION
- /* Perform calibration */
- if (wcfxs_manual_calibrate(wc, card)) {
- printk("ProSlic died on Calibration (try -DNO_CALIBRATION in Makefile).\n");
- return -1;
- }
+ /* Perform calibration */
+ if (wcfxs_manual_calibrate(wc, card)) {
+ printk("ProSlic died on Calibration (try -DNO_CALIBRATION in Makefile).\n");
+ return -1;
+ }
#endif
+ }
/* Calibration complete, restore original values */
for (x=0;x<5;x++) {
wcfxs_setreg_indirect(wc, card, x + 35, tmp[x]);
@@ -879,16 +887,23 @@ static inline void wcfxs_check_hook(struct wcfxs *wc, int card)
/* For some reason we have to debounce the
hook detector. */
- res = wcfxs_getreg(wc, card, 64);
- if (!res && (res != wc->lasttxhook[card])) {
- if (wc->palarms[card]++ < MAX_ALARMS) {
- printk("Power alarm on module %d, resetting!\n", card + 1);
- if (wc->lasttxhook[card] == 4)
- wc->lasttxhook[card] = 1;
- wcfxs_setreg(wc, card, 64, wc->lasttxhook[card]);
- } else {
- if (wc->palarms[card] == MAX_ALARMS)
- printk("Too many power alarms on card %d, NOT resetting!\n", card + 1);
+ /* Check loopback */
+ res = wcfxs_getreg(wc, card, 8);
+ if (res) {
+ printk("Ouch, part reset, quickly restoring reality (%d)\n", card);
+ wcfxs_init_proslic(wc, card, 1);
+ } else {
+ res = wcfxs_getreg(wc, card, 64);
+ if (!res && (res != wc->lasttxhook[card])) {
+ if (wc->palarms[card]++ < MAX_ALARMS) {
+ printk("Power alarm on module %d, resetting!\n", card + 1);
+ if (wc->lasttxhook[card] == 4)
+ wc->lasttxhook[card] = 1;
+ wcfxs_setreg(wc, card, 64, wc->lasttxhook[card]);
+ } else {
+ if (wc->palarms[card] == MAX_ALARMS)
+ printk("Too many power alarms on card %d, NOT resetting!\n", card + 1);
+ }
}
}
res = wcfxs_getreg(wc, card, 68);
@@ -1162,7 +1177,7 @@ static int wcfxs_hardware_init(struct wcfxs *wc)
while(jiffies - oldjiffies < (HZ / 4) + 1);
for (x=0;x<wc->cards;x++) {
- if (!wcfxs_init_proslic(wc, x)) {
+ if (!wcfxs_init_proslic(wc, x, 0)) {
printk("Module %d: Initialized\n", x);
wc->cardflag |= (1 << x);
} else