diff options
Diffstat (limited to 'xpp/card_fxs.c')
-rw-r--r-- | xpp/card_fxs.c | 90 |
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"); } |