summaryrefslogtreecommitdiff
path: root/xpp/card_fxs.c
diff options
context:
space:
mode:
Diffstat (limited to 'xpp/card_fxs.c')
-rw-r--r--xpp/card_fxs.c90
1 files changed, 48 insertions, 42 deletions
diff --git a/xpp/card_fxs.c b/xpp/card_fxs.c
index 5177f81..af12cd2 100644
--- a/xpp/card_fxs.c
+++ b/xpp/card_fxs.c
@@ -33,8 +33,8 @@
static const char rcsid[] = "$Id$";
-DEF_PARM(int, print_dbg, 0, "Print DBG statements"); /* must be before zap_debug.h */
-DEF_PARM(bool, poll_digital_inputs, 1, "Poll Digital Inputs"); /* must be before zap_debug.h */
+DEF_PARM(int, print_dbg, 0, 0600, "Print DBG statements"); /* must be before zap_debug.h */
+DEF_PARM_BOOL(poll_digital_inputs, 1, 0600, "Poll Digital Inputs"); /* must be before zap_debug.h */
/* Signaling is opposite (fxo signalling for fxs card) */
#if 1
@@ -92,9 +92,21 @@ struct FXS_priv_data {
xpp_line_t ledcontrol[NUM_LEDS]; /* 0 - OFF, 1 - ON */
xpp_line_t found_fsk_pattern;
xpp_line_t msg_waiting;
- int blinking[NUM_LEDS][CHANNELS_PERXPD];
+ int led_counter[NUM_LEDS][CHANNELS_PERXPD];
};
+/*
+ * LED counter values:
+ * n>1 : BLINK every n'th tick
+ */
+#define LED_COUNTER(priv,pos,color) ((priv)->led_counter[color][pos])
+#define IS_BLINKING(priv,pos,color) (LED_COUNTER(priv,pos,color) > 0)
+#define MARK_BLINK(priv,pos,color,t) ((priv)->led_counter[color][pos] = (t))
+#define MARK_OFF(priv,pos,color) do { BIT_CLR((priv)->ledcontrol[color],(pos)); MARK_BLINK((priv),(pos),(color),0); } while(0)
+#define MARK_ON(priv,pos,color) do { BIT_SET((priv)->ledcontrol[color],(pos)); MARK_BLINK((priv),(pos),(color),0); } while(0)
+
+#define LED_BLINK_RING (1000/8) /* in ticks */
+
/*---------------- FXS: Static functions ----------------------------------*/
static int do_chan_power(xbus_t *xbus, xpd_t *xpd, lineno_t chan, bool on)
{
@@ -106,10 +118,6 @@ static int do_chan_power(xbus_t *xbus, xpd_t *xpd, lineno_t chan, bool on)
return SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x42, value);
}
-#define IS_BLINKING(priv,pos,color) ((priv)->blinking[color][pos] != 0)
-#define MARK_BLINK(priv,pos,color,val) ((priv)->blinking[color][pos] = (val))
-#define MARK_LED(priv,pos,color,val) ((val)?BIT_SET((priv)->ledcontrol[color],(pos)):BIT_CLR((priv)->ledcontrol[color],(pos)))
-
/*
* LED and RELAY control is done via SLIC register 0x06:
* 7 6 5 4 3 2 1 0
@@ -191,8 +199,12 @@ static void handle_fxs_leds(xpd_t *xpd)
if(IS_SET(xpd->digital_outputs, i) || IS_SET(xpd->digital_inputs, i))
continue;
if(xpd->blink_mode || IS_BLINKING(priv, i, color)) { // Blinking
+ int mod_value = LED_COUNTER(priv, i, color);
+
+ if(!mod_value)
+ mod_value = DEFAULT_LED_PERIOD; /* safety value */
// led state is toggled
- if((timer_count % LED_BLINK_PERIOD) == 0) {
+ if((timer_count % mod_value) == 0) {
DBG("%s/%s/%d ledstate=%s\n", xpd->xbus->busname, xpd->xpdname, i,
(IS_SET(priv->ledstate[color], i))?"ON":"OFF");
if(!IS_SET(priv->ledstate[color], i)) {
@@ -273,6 +285,7 @@ static int FXS_card_init(xbus_t *xbus, xpd_t *xpd)
{
struct FXS_priv_data *priv;
int ret = 0;
+ int i;
BUG_ON(!xpd);
priv = xpd->priv;
@@ -308,6 +321,18 @@ static int FXS_card_init(xbus_t *xbus, xpd_t *xpd)
if(ret < 0)
goto err;
DBG("%s/%s: done\n", xbus->busname, xpd->xpdname);
+ for_each_line(xpd, i) {
+ do_led(xpd, i, LED_GREEN, 0);
+ do_led(xpd, i, LED_RED, 0);
+ }
+ for_each_line(xpd, i) {
+ do_led(xpd, i, LED_GREEN, 1);
+ msleep(50);
+ }
+ for_each_line(xpd, i) {
+ do_led(xpd, i, LED_GREEN, 0);
+ msleep(50);
+ }
return 0;
err:
clean_proc(xbus, xpd);
@@ -331,8 +356,6 @@ static int FXS_card_zaptel_preregistration(xpd_t *xpd, bool on)
xbus_t *xbus;
struct FXS_priv_data *priv;
int i;
- unsigned long flags;
- const enum fxs_leds color = (on) ? LED_GREEN : LED_RED;
BUG_ON(!xpd);
xbus = xpd->xbus;
@@ -357,13 +380,8 @@ static int FXS_card_zaptel_preregistration(xpd_t *xpd, bool on)
cur_chan->sigcap = FXS_DEFAULT_SIGCAP;
}
for_each_line(xpd, i) {
- spin_lock_irqsave(&xpd->lock, flags);
- do_led(xpd, i, color, LED_OFF);
- spin_unlock_irqrestore(&xpd->lock, flags);
- }
- for_each_line(xpd, i) {
- MARK_LED(priv, i, color, LED_ON);
- msleep(50);
+ MARK_ON(priv, i, LED_GREEN);
+ msleep(4);
}
return 0;
}
@@ -373,7 +391,6 @@ static int FXS_card_zaptel_postregistration(xpd_t *xpd, bool on)
xbus_t *xbus;
struct FXS_priv_data *priv;
int i;
- const enum fxs_leds color = (on) ? LED_GREEN : LED_RED;
BUG_ON(!xpd);
xbus = xpd->xbus;
@@ -382,8 +399,10 @@ static int FXS_card_zaptel_postregistration(xpd_t *xpd, bool on)
BUG_ON(!priv);
DBG("%s/%s (%d)\n", xbus->busname, xpd->xpdname, on);
for_each_line(xpd, i) {
- MARK_LED(priv, i, color, LED_OFF);
- msleep(50);
+ MARK_OFF(priv, i, LED_GREEN);
+ msleep(2);
+ MARK_OFF(priv, i, LED_RED);
+ msleep(2);
}
return 0;
}
@@ -717,9 +736,9 @@ static /* 0x0F */ HOSTCMD(FXS, XPD_STATE, bool on)
for_each_line(xpd, i)
xpd->lasttxhook[i] = value;
if(on) {
- MARK_LED(priv, ALL_CHANS, LED_GREEN, LED_ON);
+ MARK_ON(priv, ALL_CHANS, LED_GREEN);
} else {
- MARK_LED(priv, ALL_CHANS, LED_GREEN, LED_OFF);
+ MARK_OFF(priv, ALL_CHANS, LED_GREEN);
}
spin_unlock_irqrestore(&xpd->lock, flags);
return ret;
@@ -740,10 +759,10 @@ static /* 0x0F */ HOSTCMD(FXS, RING, lineno_t chan, bool on)
ret = SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x40, value);
xpd->lasttxhook[chan] = value;
if(on) {
- MARK_BLINK(priv,chan,LED_GREEN,LED_BLINK);
+ MARK_BLINK(priv, chan, LED_GREEN, LED_BLINK_RING);
} else {
if(IS_BLINKING(priv, chan, LED_GREEN))
- MARK_BLINK(priv,chan,LED_GREEN,0);
+ MARK_BLINK(priv, chan, LED_GREEN, 0);
}
return ret;
}
@@ -779,19 +798,6 @@ HANDLER_DEF(FXS, SIG_CHANGED)
priv = xpd->priv;
DBG("%s/%s: (PHONE) sig_toggles=0x%04X sig_status=0x%04X\n", xbus->busname, xpd->xpdname, sig_toggles, sig_status);
#if 0
- /*
- * Not needed anymore. update_line_status() returns immediately
- * if !SPAN_REGISTERED(). Now we maintain good status even if
- * we are not registered.
- *
- * FIXME: Need to notify zaptel later (when registering).
- */
- if(!SPAN_REGISTERED(xpd)) {
- NOTICE("%s: %s/%s is not registered. Skipping.\n", __FUNCTION__, xbus->busname, xpd->xpdname);
- return -ENODEV;
- }
-#endif
-#if 0
Is this needed?
for_each_line(xpd, i) {
if(IS_SET(sig_toggles, i))
@@ -804,14 +810,14 @@ HANDLER_DEF(FXS, SIG_CHANGED)
continue;
if(IS_SET(sig_toggles, i)) {
xpd->ringing[i] = 0; // No more ringing...
- MARK_BLINK(priv,i,LED_GREEN,0);
+ MARK_BLINK(priv, i, LED_GREEN, 0);
if(IS_SET(sig_status, i)) {
DBG("%s/%s/%d: OFFHOOK\n", xbus->busname, xpd->xpdname, i);
- MARK_LED(priv,i,LED_GREEN,LED_ON);
+ MARK_ON(priv, i, LED_GREEN);
update_line_status(xpd, i, 1);
} else {
DBG("%s/%s/%d: ONHOOK\n", xbus->busname, xpd->xpdname, i);
- MARK_LED(priv,i,LED_GREEN,LED_OFF);
+ MARK_OFF(priv, i, LED_GREEN);
update_line_status(xpd, i, 0);
start_stop_vm_led(xbus, xpd, i);
}
@@ -966,10 +972,10 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count, in
if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
len += sprintf(page + len, "%d ", IS_SET(priv->ledcontrol[led], i));
}
- len += sprintf(page + len, "\n\t%-17s: ", "blinking");
+ len += sprintf(page + len, "\n\t%-17s: ", "led_counter");
for_each_line(xpd, i) {
if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
- len += sprintf(page + len, "%d ", IS_BLINKING(priv,i,led));
+ len += sprintf(page + len, "%d ", LED_COUNTER(priv,i,led));
}
len += sprintf(page + len, "\n");
}