http://downloads.netgear.com/files/GPL/GPL_Source_V361j_DM111PSP_series_consumer_rele...
[bcm963xx.git] / bcmdrivers / opensource / char / board / bcm963xx / impl1 / bcm63xx_led.c
index 8de0f91..9b8858c 100755 (executable)
@@ -25,7 +25,7 @@
  *
  *    To use it, do the following
  *
- *    1). define in the board.c the following led mappping (this is for 6345GW board):
+ *    1). define in the board.c the following led mappping
  *        const LED_MAP_PAIR cLedMapping45GW[] =
  *        {   // led name     Initial state       physical pin (ledMask)
  *            {kLedUsb,       kLedStateOff,       GPIO_LED_PIN_7}, 
@@ -66,9 +66,9 @@
 #include <bcm_map_part.h>
 #include <board.h>
 
-#define k100ms              (HZ / 10)     // ~100 ms
-#define kFastBlinkCount     0             // ~100ms
-#define kSlowBlinkCount     5             // ~600ms
+#define k125ms              (HZ / 8)   // ~125 ms
+#define kFastBlinkCount     0          // ~125ms
+#define kSlowBlinkCount     1          // ~250ms
 
 #define MAX_VIRT_LEDS       12
 
 //#define DEBUG_LED
 
 // global variables:
-struct timer_list gLedTimer;
+struct timer_list gLedTimer, gBlinkOnceTimer;
 int gTimerOn = FALSE;
+int gBlinkOnceTimerOn = FALSE;
 int gLedCount = 0;
 
 typedef struct ledinfo
 {
-    unsigned short ledMask;         // mask for led: ie. giop 10 = 0x0400
+    unsigned long ledMask;          // mask for led: ie. giop 10 = 0x0400
     unsigned short ledActiveLow;    // GPIO bit reset to turn on LED
-    unsigned short ledMaskFail;     // mask for led: ie. giop 10 = 0x0400
+    unsigned short ledSerial;       // indicated that LED is driven via serial output
+    unsigned long ledMaskFail;      // mask for led: ie. giop 10 = 0x0400
     unsigned short ledActiveLowFail;// GPIO bit reset to turn on LED
+    unsigned short ledSerialFail;   // indicated that LED is driven via serial output
     BOARD_LED_STATE ledState;       // current led state
     BOARD_LED_STATE savedLedState;  // used in blink once for restore to the orignal ledState
     int blinkCountDown;             // if == 0, do blink (toggle).  Is assgined value and dec by 1 at each timer.
@@ -96,14 +99,7 @@ static PLED_INFO gpVirtLeds[MAX_VIRT_LEDS];
 static HANDLE_LED_FUNC gLedHwFunc[MAX_VIRT_LEDS];
 static HANDLE_LED_FUNC gLedHwFailFunc[MAX_VIRT_LEDS];
 
-#if 0 /* BROKEN */
-#if defined(CONFIG_BCM96348) || defined(CONFIG_BCM96338)
-static int gLedOffInBridgeMode = 1;
-#elif defined(CONFIG_BCM96345)
-static int gLedOffInBridgeMode = 0;
-#endif
-#endif
-
+void blinkOnceTimerExpire(void); // Keven
 void ledTimerExpire(void);
 int initLedInfo( PLED_MAP_PAIR pCurMap, PLED_INFO pCurLed );
 
@@ -116,11 +112,22 @@ void ledOn(PLED_INFO pLed)
 {
     if( pLed->ledMask )
     {
-        GPIO->GPIODir |= pLed->ledMask;         // turn on the direction bit in case was turned off by some one
-        if( pLed->ledActiveLow )
-            GPIO->GPIOio  &= ~pLed->ledMask;    // turn on the led
-        else
-            GPIO->GPIOio  |= pLed->ledMask;     // turn on the led
+        if (pLed->ledSerial) {
+#if defined(CONFIG_BCM96358)
+            while (GPIO->SerialLedCtrl & SER_LED_BUSY);
+            if( pLed->ledActiveLow )
+                GPIO->SerialLed  &= ~pLed->ledMask;    // turn on the led
+            else
+                GPIO->SerialLed  |= pLed->ledMask;     // turn on the led
+#endif
+        }
+        else {
+            GPIO->GPIODir |= pLed->ledMask;         // turn on the direction bit in case was turned off by some one
+            if( pLed->ledActiveLow )
+                GPIO->GPIOio  &= ~pLed->ledMask;    // turn on the led
+            else
+                GPIO->GPIOio  |= pLed->ledMask;     // turn on the led
+        }
         pLed->ledState = pLed->savedLedState = kLedStateOn;
     }
 }
@@ -131,11 +138,22 @@ void ledOff(PLED_INFO pLed)
 {
     if( pLed->ledMask )
     {
-        GPIO->GPIODir |= pLed->ledMask;         // turn on the direction bit in case was turned off by some one
-        if( pLed->ledActiveLow )
-            GPIO->GPIOio  |= pLed->ledMask;     // turn off the led
-        else
-            GPIO->GPIOio  &= ~pLed->ledMask;    // turn off the led
+        if (pLed->ledSerial) {
+#if defined(CONFIG_BCM96358)
+            while (GPIO->SerialLedCtrl & SER_LED_BUSY);
+            if( pLed->ledActiveLow )
+                GPIO->SerialLed  |= pLed->ledMask;     // turn off the led
+            else
+                GPIO->SerialLed  &= ~pLed->ledMask;    // turn off the led
+#endif
+        }
+        else {
+            GPIO->GPIODir |= pLed->ledMask;         // turn on the direction bit in case was turned off by some one
+            if( pLed->ledActiveLow )
+                GPIO->GPIOio  |= pLed->ledMask;     // turn off the led
+            else
+                GPIO->GPIOio  &= ~pLed->ledMask;    // turn off the led
+        }
         pLed->ledState = pLed->savedLedState = kLedStateOff;
     }
 }
@@ -145,11 +163,22 @@ void ledOnFail(PLED_INFO pLed)
 {
     if( pLed->ledMaskFail )
     {
-        GPIO->GPIODir |= pLed->ledMaskFail;     // turn on the direction bit in case was turned off by some one
-        if( pLed->ledActiveLowFail )
-            GPIO->GPIOio  &= ~pLed->ledMaskFail;// turn on the led
-        else
-            GPIO->GPIOio  |= pLed->ledMaskFail; // turn on the led
+        if (pLed->ledSerialFail) {
+#if defined(CONFIG_BCM96358)
+            while (GPIO->SerialLedCtrl & SER_LED_BUSY);
+            if( pLed->ledActiveLowFail )
+                GPIO->SerialLed  &= ~pLed->ledMaskFail;    // turn on the led
+            else
+                GPIO->SerialLed  |= pLed->ledMaskFail;     // turn on the led
+#endif
+        }
+        else {
+            GPIO->GPIODir |= pLed->ledMaskFail;     // turn on the direction bit in case was turned off by some one
+            if( pLed->ledActiveLowFail )
+                GPIO->GPIOio  &= ~pLed->ledMaskFail;// turn on the led
+            else
+                GPIO->GPIOio  |= pLed->ledMaskFail; // turn on the led
+        }
         pLed->ledState = pLed->savedLedState = kLedStateFail;
     }
 }
@@ -160,11 +189,22 @@ void ledOffFail(PLED_INFO pLed)
 {
     if( pLed->ledMaskFail )
     {
-        GPIO->GPIODir |= pLed->ledMaskFail;     // turn on the direction bit in case was turned off by some one
-        if( pLed->ledActiveLowFail )
-            GPIO->GPIOio  |= pLed->ledMaskFail; // turn off the led
-        else
-            GPIO->GPIOio  &= ~pLed->ledMaskFail;// turn off the led
+        if (pLed->ledSerialFail) {
+#if defined(CONFIG_BCM96358)
+            while (GPIO->SerialLedCtrl & SER_LED_BUSY);
+            if( pLed->ledActiveLowFail )
+                GPIO->SerialLed  |= pLed->ledMaskFail;     // turn off the led
+            else
+                GPIO->SerialLed  &= ~pLed->ledMaskFail;    // turn off the led
+#endif
+        }
+        else {
+            GPIO->GPIODir |= pLed->ledMaskFail;     // turn on the direction bit in case was turned off by some one
+            if( pLed->ledActiveLowFail )
+                GPIO->GPIOio  |= pLed->ledMaskFail; // turn off the led
+            else
+                GPIO->GPIOio  &= ~pLed->ledMaskFail;// turn off the led
+        }
         pLed->ledState = pLed->savedLedState = kLedStateOff;
     }
 }
@@ -173,19 +213,53 @@ void ledOffFail(PLED_INFO pLed)
 // toggle the led and return the current ledState
 BOARD_LED_STATE ledToggle(PLED_INFO pLed)
 {
-    GPIO->GPIODir |= pLed->ledMask;         // turn on the direction bit in case was turned off by some one
-    if (GPIO->GPIOio & pLed->ledMask)
-    {
-        GPIO->GPIOio &= ~(pLed->ledMask);
-        return( (pLed->ledActiveLow) ? kLedStateOn : kLedStateOff );
+    if (pLed->ledSerial) {
+#if defined(CONFIG_BCM96358)
+        while (GPIO->SerialLedCtrl & SER_LED_BUSY);
+        if (GPIO->SerialLed & pLed->ledMask)
+        {
+            GPIO->SerialLed &= ~(pLed->ledMask);
+            return( (pLed->ledActiveLow) ? kLedStateOn : kLedStateOff );
+        }
+        else
+        {
+            GPIO->SerialLed |= pLed->ledMask;
+            return( (pLed->ledActiveLow) ? kLedStateOff : kLedStateOn );
+        }
+#endif
     }
-    else
-    {
-        GPIO->GPIOio |= pLed->ledMask;
-        return( (pLed->ledActiveLow) ? kLedStateOff : kLedStateOn );
+    else {
+        GPIO->GPIODir |= pLed->ledMask;         // turn on the direction bit in case was turned off by some one
+        if (GPIO->GPIOio & pLed->ledMask)
+        {
+            GPIO->GPIOio &= ~(pLed->ledMask);
+            return( (pLed->ledActiveLow) ? kLedStateOn : kLedStateOff );
+        }
+        else
+        {
+            GPIO->GPIOio |= pLed->ledMask;
+            return( (pLed->ledActiveLow) ? kLedStateOff : kLedStateOn );
+        }
     }
 }   
 
+// Keven -- LED BlinkOnce timer 
+void blinkOnceTimerStart(void)
+{
+    if(gBlinkOnceTimerOn)
+       return;
+
+    init_timer(&gBlinkOnceTimer);
+    gBlinkOnceTimer.function = (void*)blinkOnceTimerExpire;
+    gBlinkOnceTimer.expires = jiffies + k125ms; 
+    add_timer(&gBlinkOnceTimer);
+    gBlinkOnceTimerOn = TRUE;
+}
+
+void blinkOnceTimerExpire(void)
+{
+    gBlinkOnceTimerOn = FALSE;
+}
 
 // led timer.  Will return if timer is already on
 void ledTimerStart(void)
@@ -199,7 +273,7 @@ void ledTimerStart(void)
 
     init_timer(&gLedTimer);
     gLedTimer.function = (void*)ledTimerExpire;
-    gLedTimer.expires = jiffies + k100ms;        // timer expires in ~100ms
+    gLedTimer.expires = jiffies + k125ms;        // timer expires in ~100ms
     add_timer (&gLedTimer);
     gTimerOn = TRUE;
 } 
@@ -228,6 +302,7 @@ void ledTimerExpire(void)
                 break;
 
             case kLedStateBlinkOnce:
+                blinkOnceTimerStart();                            // Keven -- Start BlinkOnceTimer
                 ledToggle(pCurLed);
                 pCurLed->blinkCountDown = 0;                      // reset to 0
                 pCurLed->ledState = pCurLed->savedLedState;
@@ -268,10 +343,52 @@ void __init boardLedInit(PLED_MAP_PAIR cLedMapping)
     int needTimer = FALSE;
     int alreadyUsed = 0;
 
-#if defined(CONFIG_BCM96348) || defined(CONFIG_BCM96338)
+#if defined(CONFIG_BCM96348) || defined(CONFIG_BCM96338) || defined(CONFIG_BCM96358)
     /* Set blink rate for BCM6348/BCM6338 hardware LEDs. */
     GPIO->LEDCtrl &= ~LED_INTERVAL_SET_MASK;
     GPIO->LEDCtrl |= LED_INTERVAL_SET_80MS;
+#endif
+#if defined(CONFIG_BCM96358)
+#ifdef BRCM_ORIGINAL   //swda modify,05/30/2006
+    /* Enable LED Outputs */
+    GPIO->GPIOMode |= GPIO_MODE_LED_OVERLAY;
+    GPIO->GPIODir |= 0x000f;
+    /* Enable Serial LED Outputs */
+    GPIO->GPIOMode |= GPIO_MODE_SERIAL_LED_OVERLAY;
+    GPIO->GPIODir |= 0x00c0;
+#elif defined(IAD_VDSL_6358)
+       /* Disable LED Outputs, use standard GPIO defination */
+       GPIO->GPIOMode &= (~GPIO_MODE_LED_OVERLAY);
+    /* Enable Serial LED Outputs */
+    GPIO->GPIOMode |= GPIO_MODE_SERIAL_LED_OVERLAY;
+    GPIO->GPIODir |= 0x00c0;//gpio6,7 were used to control serial led, so set gpio 6,7 as output pins
+       //turn off VOIP Led,SLIC_ACT1 Led,SLIC_ACT2 Led : Serial LED GPIO 5,6,7(active low)
+       while (GPIO->SerialLedCtrl & SER_LED_BUSY);
+       GPIO->SerialLed  |= 0x000000e0;
+#elif defined(IAD_GPON_6358)
+       /* Disable LED Outputs, use standard GPIO defination */
+       GPIO->GPIOMode &= (~GPIO_MODE_LED_OVERLAY);
+       /* Disable Serial LED Outputs, use standard GPIO defination */
+       GPIO->GPIOMode &= (~GPIO_MODE_SERIAL_LED_OVERLAY);
+#else
+       /* Disable LED Outputs, use standard GPIO defination */
+       GPIO->GPIOMode &= (~GPIO_MODE_LED_OVERLAY);
+       /* Disable Serial LED Outputs, use standard GPIO defination */
+       GPIO->GPIOMode &= (~GPIO_MODE_SERIAL_LED_OVERLAY);
+       printk("GPIO->GPIOMode = 0x%08X\n",GPIO->GPIOMode);
+       //turn off FXO Led  : GPIO 7(active low)
+       GPIO->GPIODir |= GPIO_NUM_TO_MASK(7);
+       GPIO->GPIOio |= GPIO_NUM_TO_MASK(7); 
+       //turn off VOIP Led : GPIO 15(active low)
+       GPIO->GPIODir |= GPIO_NUM_TO_MASK(15);
+       GPIO->GPIOio |= GPIO_NUM_TO_MASK(15);
+       //turn off SLIC_ACT1 Led: GPIO 26(active low)
+       GPIO->GPIODir |= GPIO_NUM_TO_MASK(26);
+       GPIO->GPIOio |= GPIO_NUM_TO_MASK(26);
+       //turn off SLIC_ACT2 Led: GPIO 6(active low)
+       GPIO->GPIODir |= GPIO_NUM_TO_MASK(6);
+       GPIO->GPIOio |= GPIO_NUM_TO_MASK(6);
+#endif //swda modify end
 #endif
 
     memset( gpVirtLeds, 0x00, sizeof(gpVirtLeds) );
@@ -349,11 +466,13 @@ void __init boardLedInit(PLED_MAP_PAIR cLedMapping)
                     {
                         pLed->ledMask = p1->ledMask;
                         pLed->ledActiveLow = p1->ledActiveLow;
+                        pLed->ledSerial = p1->ledSerial;
                     }
                     if( p1->ledMaskFail )
                     {
                         pLed->ledMaskFail = p1->ledMaskFail;
                         pLed->ledActiveLowFail = p1->ledActiveLowFail;
+                        pLed->ledSerialFail = p1->ledSerialFail;
                     }
                     gpVirtLeds[(int) p1->ledName] = pLed;
                     break;
@@ -382,8 +501,10 @@ int initLedInfo( PLED_MAP_PAIR pCurMap, PLED_INFO pCurLed )
     pCurLed->ledState = pCurLed->savedLedState = pCurMap->ledInitState;
     pCurLed->ledMask = pCurMap->ledMask;
     pCurLed->ledActiveLow = pCurMap->ledActiveLow;
+    pCurLed->ledSerial = pCurMap->ledSerial;
     pCurLed->ledMaskFail = pCurMap->ledMaskFail;
     pCurLed->ledActiveLowFail = pCurMap->ledActiveLowFail;
+    pCurLed->ledSerialFail = pCurMap->ledSerialFail;
 
     switch (pCurLed->ledState)
     {
@@ -418,34 +539,6 @@ int initLedInfo( PLED_MAP_PAIR pCurMap, PLED_INFO pCurLed )
     return( needTimer );
 }
 
-#if 0 /* BROKEN */
-// Determines if there is at least one interface in bridge mode.  Bridge mode
-// is determined by the cfm convention of naming bridge interfaces nas17
-// through nas24.
-static int isBridgedProtocol(void)
-{
-    extern int dev_get(const char *name);
-    const int firstBridgeId = 17;
-    const int lastBridgeId = 24;
-    int i;
-    int ret = FALSE;
-    char name[16];
-
-    for( i = firstBridgeId; i <= lastBridgeId; i++ )
-    {
-        sprintf( name, "nas%d", i );
-
-        if( dev_get(name) )
-        {
-            ret = TRUE;
-            break;
-        }
-    }
-
-    return(ret);
-}
-#endif
-
 // led ctrl.  Maps the ledName to the corresponding ledInfoPtr and perform the led operation
 void boardLedCtrl(BOARD_LED_NAME ledName, BOARD_LED_STATE ledState)
 {
@@ -457,42 +550,42 @@ void boardLedCtrl(BOARD_LED_NAME ledName, BOARD_LED_STATE ledState)
     else
         ledInfoPtr = NULL;
 
-    if (ledInfoPtr == NULL)
-        return;
-
     if( ledState != kLedStateFail && gLedHwFunc[(int) ledName] )
     {
+        // First, turn off the complimentary (failure) LED.
+        if( gLedHwFailFunc[(int) ledName] )
+            (*gLedHwFailFunc[(int) ledName]) (ledName, kLedStateOff);
+        else
+            if( ledInfoPtr )
+                ledOffFail(ledInfoPtr);
+
+        // Call function to handle hardware LED.
         (*gLedHwFunc[(int) ledName]) (ledName, ledState);
-        ledOffFail(ledInfoPtr);
         return;
     }
     else
         if( ledState == kLedStateFail && gLedHwFailFunc[(int) ledName] )
         {
+            // First, turn off the complimentary (normal) LED.
+            if( gLedHwFunc[(int) ledName] )
+                (*gLedHwFunc[(int) ledName]) (ledName, kLedStateOff);
+            else
+                if( ledInfoPtr )
+                    ledOff(ledInfoPtr);
+
+            // Call function to handle hardware LED.
             (*gLedHwFailFunc[(int) ledName]) (ledName, ledState);
-            ledOff(ledInfoPtr);
             return;
         }
 
-#if 0 /* BROKEN */
-    // Do not blink the WAN Data LED if at least one interface is in bridge mode.
-    if(gLedOffInBridgeMode == 1 && (ledName == kLedWanData || ledName == kLedPPP))
-    {
-        static int BridgedProtocol = -1;
-
-        if( BridgedProtocol == -1 )
-            BridgedProtocol = isBridgedProtocol();
-
-        if( BridgedProtocol == TRUE )
-            return;
-    }
-#endif
+    if (ledInfoPtr == NULL)
+        return;
 
     // If the state is kLedStateFail and there is not a failure LED defined
-    // in the board parameters, change the state to kLedStateFastBlinkContinues.
+    // in the board parameters, change the state to kLedStateSlowBlinkContinues.
     if( ledState == kLedStateFail && ledInfoPtr->ledMaskFail == 0 )
-        ledState = kLedStateFastBlinkContinues;
-
+        //ledState = kLedStateSlowBlinkContinues;//swda remove,05/03/2005
+        ledState = kLedStateOff;//swda add,05/03/2005
     switch (ledState)
     {
         case kLedStateOn:
@@ -538,7 +631,10 @@ void boardLedCtrl(BOARD_LED_NAME ledName, BOARD_LED_STATE ledState)
                 ;
             else
             {
-                if (ledInfoPtr->blinkCountDown == 0)  // skip the call if it is 1
+                if ( ledInfoPtr->blinkCountDown ||  // skip the call if it is 1
+                     gBlinkOnceTimerOn            ) // Keven -- skip the call if BlinkOnceTimer is on
+                    ;
+                else
                 {
                     ledToggle(ledInfoPtr);
                     ledInfoPtr->blinkCountDown = 1;  // it will be reset to 0 when timer expires