summaryrefslogtreecommitdiff
path: root/xpp/card_fxo.c
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-08-10 02:40:45 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-08-10 02:40:45 +0000
commit6a04e6704a129a6efc6dcad0c8a513d2fafea579 (patch)
tree1b495553b760d2e5a4788c4262e96d69d7b899fa /xpp/card_fxo.c
parent99a3ccdba4500df334460bf45b1955d0d663b238 (diff)
Better LED handling for fxo (copied from fxs):
- Fix both branches/RELEASE-1.1.0 and trunk/ - Use a ledcontrol bitmask to mark led on/off - Actuall led commands are send only from handle_fxo_leds() git-svn-id: http://svn.digium.com/svn/zaptel/trunk@1280 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp/card_fxo.c')
-rw-r--r--xpp/card_fxo.c60
1 files changed, 38 insertions, 22 deletions
diff --git a/xpp/card_fxo.c b/xpp/card_fxo.c
index ae7c06f..2627e21 100644
--- a/xpp/card_fxo.c
+++ b/xpp/card_fxo.c
@@ -77,13 +77,24 @@ struct FXO_priv_data {
slic_reply_t last_reply;
xpp_line_t battery;
xpp_line_t ledstate[NUM_LEDS]; /* 0 - OFF, 1 - ON */
+ xpp_line_t ledcontrol[NUM_LEDS]; /* 0 - OFF, 1 - ON */
int blinking[NUM_LEDS][CHANNELS_PERXPD];
};
/*---------------- FXO: Static functions ----------------------------------*/
#define IS_BLINKING(priv,pos,color) ((priv)->blinking[color][pos] != 0)
-#define DO_BLINK(priv,pos,color,val) ((priv)->blinking[color][pos] = (val))
+#define MARK_BLINK(priv,pos,color,val) ((priv)->blinking[color][pos] = (val))
+
+void MARK_LED(xpd_t *xpd, lineno_t pos, byte color, bool on)
+{
+ struct FXO_priv_data *priv = xpd->priv;
+
+ if(on)
+ BIT_SET(priv->ledcontrol[color], pos);
+ else
+ BIT_CLR(priv->ledcontrol[color], pos);
+}
/*
* LED control is done via DAA register 0x20
@@ -130,10 +141,10 @@ out:
static void handle_fxo_leds(xpd_t *xpd)
{
- int i;
- unsigned long flags;
+ int i;
+ unsigned long flags;
const enum fxo_leds color = LED_GREEN;
- unsigned int timer_count;
+ unsigned int timer_count;
struct FXO_priv_data *priv;
BUG_ON(!xpd);
@@ -146,7 +157,7 @@ static void handle_fxo_leds(xpd_t *xpd)
if(IS_BLINKING(priv,i,color)) {
// led state is toggled
if((timer_count % LED_BLINK_PERIOD) == 0) {
- DBG("%s/%s/%d: led_state=%s\n", xpd->xbus->busname, xpd->xpdname, i,
+ 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)) {
do_led(xpd, i, color, 1);
@@ -154,6 +165,10 @@ static void handle_fxo_leds(xpd_t *xpd)
do_led(xpd, i, color, 0);
}
}
+ } else if(IS_SET(priv->ledcontrol[color], i) && !IS_SET(priv->ledstate[color], i)) {
+ do_led(xpd, i, color, 1);
+ } else if(!IS_SET(priv->ledcontrol[color], i) && IS_SET(priv->ledstate[color], i)) {
+ do_led(xpd, i, color, 0);
}
}
spin_unlock_irqrestore(&xpd->lock, flags);
@@ -282,7 +297,6 @@ static int FXO_card_zaptel_preregistration(xpd_t *xpd, bool on)
xbus_t *xbus;
struct FXO_priv_data *priv;
int i;
- unsigned long flags;
BUG_ON(!xpd);
xbus = xpd->xbus;
@@ -300,11 +314,9 @@ static int FXO_card_zaptel_preregistration(xpd_t *xpd, bool on)
cur_chan->pvt = xpd;
cur_chan->sigcap = FXO_DEFAULT_SIGCAP;
}
- spin_lock_irqsave(&xpd->lock, flags);
- do_led(xpd, ALL_LINES, LED_GREEN, LED_OFF);
- spin_unlock_irqrestore(&xpd->lock, flags);
+ MARK_LED(xpd, ALL_LINES, LED_GREEN, LED_OFF);
for_each_line(xpd, i) {
- do_led(xpd, i, LED_GREEN, LED_ON);
+ MARK_LED(xpd, i, LED_GREEN, LED_ON);
mdelay(50);
}
return 0;
@@ -323,7 +335,7 @@ static int FXO_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) {
- do_led(xpd, i, LED_GREEN, LED_OFF);
+ MARK_LED(xpd, i, LED_GREEN, LED_OFF);
mdelay(50);
}
return 0;
@@ -433,7 +445,7 @@ static int FXO_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
int i,ret;
BUG_ON(!xpd);
- DBG("cmd: 0x%x, expecting: 0x%lx, pos=%d.\n", cmd, WCTDM_SET_ECHOTUNE, pos);
+ DBG("cmd: 0x%X, expecting: 0x%X, pos=%d.\n", cmd, WCTDM_SET_ECHOTUNE, pos);
switch (cmd) {
case WCTDM_SET_ECHOTUNE:
DBG("-- Setting echo registers: \n");
@@ -474,7 +486,6 @@ static int FXO_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
static /* 0x0F */ HOSTCMD(FXO, CHAN_ENABLE, xpp_line_t lines, bool on)
{
- unsigned long flags;
int ret = 0;
int i;
@@ -486,15 +497,11 @@ static /* 0x0F */ HOSTCMD(FXO, CHAN_ENABLE, xpp_line_t lines, bool on)
DBG("Channel Activation: 0x%4X %s\n", lines, (on) ? "on" : "off");
if(on) {
for_each_line(xpd, i) {
- spin_lock_irqsave(&xpd->lock, flags);
- do_led(xpd, i, LED_GREEN, LED_ON);
- spin_unlock_irqrestore(&xpd->lock, flags);
+ MARK_LED(xpd, i, LED_GREEN, LED_ON);
mdelay(20);
}
for_each_line(xpd, i) {
- spin_lock_irqsave(&xpd->lock, flags);
- do_led(xpd, i, LED_GREEN, LED_OFF);
- spin_unlock_irqrestore(&xpd->lock, flags);
+ MARK_LED(xpd, i, LED_GREEN, LED_OFF);
mdelay(20);
}
}
@@ -554,12 +561,12 @@ static /* 0x0F */ HOSTCMD(FXO, SETHOOK, int pos, bool offhook)
// value |= BIT(3); /* Bit 3 is for CID */
DBG("%s/%s/%d: SETHOOK: value=0x%02X %s\n", xbus->busname, xpd->xpdname, pos, value, (offhook)?"OFFHOOK":"ONHOOK");
spin_lock_irqsave(&xpd->lock, flags);
+ MARK_LED(xpd, pos, LED_GREEN, (offhook)?LED_ON:LED_OFF);
XPACKET_NEW(pack, xbus, FXO, DAA_WRITE, xpd->id);
sc = &RPACKET_FIELD(pack, FXO, DAA_WRITE, slic_cmd);
len = slic_cmd_direct_write(sc, BIT(pos), 0x05, value);
pack->datalen = len;
packet_send(xbus, pack);
- do_led(xpd, pos, LED_GREEN, (offhook)?LED_ON:LED_OFF);
if(!offhook)
xpd->ringing[pos] = 0;
spin_unlock_irqrestore(&xpd->lock, flags);
@@ -599,12 +606,15 @@ HANDLER_DEF(FXO, SIG_CHANGED)
xpp_line_t sig_toggles = RPACKET_FIELD(pack, FXO, SIG_CHANGED, sig_toggles);
unsigned long flags;
int i;
+ struct FXO_priv_data *priv;
if(!xpd) {
NOTICE("%s: received %s for non-existing xpd: %d\n",
__FUNCTION__, cmd->name, XPD_NUM(pack->content.addr));
return -EPROTO;
}
+ priv = xpd->priv;
+ BUG_ON(!priv);
DBG("%s/%s: (PSTN) sig_toggles=0x%04X sig_status=0x%04X\n", xpd->xbus->busname, xpd->xpdname, sig_toggles, sig_status);
spin_lock_irqsave(&xpd->lock, flags);
for_each_line(xpd, i) {
@@ -614,11 +624,12 @@ HANDLER_DEF(FXO, SIG_CHANGED)
if(IS_SET(sig_status, i)) {
DBG("%s/%s/%d: RING-ON\n", xbus->busname, xpd->xpdname, chan->channo);
xpd->ringing[i] = 1;
- do_led(xpd, i, LED_GREEN, LED_ON);
+ MARK_BLINK(priv, i, LED_GREEN, LED_BLINK);
} else {
DBG("%s/%s/%d: RING-OFF\n", xbus->busname, xpd->xpdname, chan->channo);
xpd->ringing[i] = 0;
- do_led(xpd, i, LED_GREEN, LED_OFF);
+ if(IS_BLINKING(priv, i, LED_GREEN))
+ MARK_BLINK(priv, i, LED_GREEN, 0);
}
}
}
@@ -751,6 +762,11 @@ static int proc_fxo_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->ledstate[LED_GREEN], i));
}
+ len += sprintf(page + len, "\n\t%-17s: ", "ledcontrol");
+ for_each_line(xpd, i) {
+ if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
+ len += sprintf(page + len, "%d ", IS_SET(priv->ledcontrol[LED_GREEN], i));
+ }
len += sprintf(page + len, "\n\t%-17s: ", "blinking");
for_each_line(xpd, i) {
if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))