[svn-commits] tzafrir: trunk r1280 - /trunk/xpp/card_fxo.c

svn-commits at lists.digium.com svn-commits at lists.digium.com
Wed Aug 9 19:40:45 MST 2006


Author: tzafrir
Date: Wed Aug  9 21:40:45 2006
New Revision: 1280

URL: http://svn.digium.com/view/zaptel?rev=1280&view=rev
Log:
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()

Modified:
    trunk/xpp/card_fxo.c

Modified: trunk/xpp/card_fxo.c
URL: http://svn.digium.com/view/zaptel/trunk/xpp/card_fxo.c?rev=1280&r1=1279&r2=1280&view=diff
==============================================================================
--- trunk/xpp/card_fxo.c (original)
+++ trunk/xpp/card_fxo.c Wed Aug  9 21:40:45 2006
@@ -77,13 +77,24 @@
 	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 @@
 
 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 @@
 		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 @@
 					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 @@
 	xbus_t			*xbus;
 	struct FXO_priv_data	*priv;
 	int			i;
-	unsigned long		flags;
 
 	BUG_ON(!xpd);
 	xbus = xpd->xbus;
@@ -300,11 +314,9 @@
 		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);
-	for_each_line(xpd, i) {
-		do_led(xpd, i, LED_GREEN, LED_ON);
+	MARK_LED(xpd, ALL_LINES, LED_GREEN, LED_OFF);
+	for_each_line(xpd, i) {
+		MARK_LED(xpd, i, LED_GREEN, LED_ON);
 		mdelay(50);
 	}
 	return 0;
@@ -323,7 +335,7 @@
 	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 @@
 	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 /* 0x0F */ HOSTCMD(FXO, CHAN_ENABLE, xpp_line_t lines, bool on)
 {
-	unsigned long		flags;
 	int	ret = 0;
 	int	i;
 
@@ -486,15 +497,11 @@
 	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 @@
 	// 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 @@
 	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 @@
 			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);
 			}
 		}
 	}
@@ -750,6 +761,11 @@
 	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->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) {



More information about the svn-commits mailing list