OMAP: Serial: Define OMAP uart MDR1 reg and remove magic numbers
[linux-2.6.git] / drivers / staging / bcm / led_control.c
blob97adaae7dfc0c4fef031a24854c9223ad3bf0610
1 #include "headers.h"
3 #define STATUS_IMAGE_CHECKSUM_MISMATCH -199
4 #define EVENT_SIGNALED 1
6 static B_UINT16 CFG_CalculateChecksum(B_UINT8 *pu8Buffer, B_UINT32 u32Size)
8 B_UINT16 u16CheckSum=0;
9 while(u32Size--) {
10 u16CheckSum += (B_UINT8)~(*pu8Buffer);
11 pu8Buffer++;
13 return u16CheckSum;
15 BOOLEAN IsReqGpioIsLedInNVM(PMINI_ADAPTER Adapter, UINT gpios)
17 INT Status ;
18 Status = (Adapter->gpioBitMap & gpios) ^ gpios ;
19 if(Status)
20 return FALSE;
21 else
22 return TRUE;
25 static INT LED_Blink(PMINI_ADAPTER Adapter, UINT GPIO_Num, UCHAR uiLedIndex, ULONG timeout, INT num_of_time, LedEventInfo_t currdriverstate)
27 int Status = STATUS_SUCCESS;
28 BOOLEAN bInfinite = FALSE;
30 /*Check if num_of_time is -ve. If yes, blink led in infinite loop*/
31 if(num_of_time < 0)
33 bInfinite = TRUE;
34 num_of_time = 1;
36 while(num_of_time)
39 if(currdriverstate == Adapter->DriverState)
40 TURN_ON_LED(GPIO_Num, uiLedIndex);
42 /*Wait for timeout after setting on the LED*/
43 Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
44 currdriverstate != Adapter->DriverState || kthread_should_stop(),
45 msecs_to_jiffies(timeout));
47 if(kthread_should_stop())
49 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
50 Adapter->LEDInfo.led_thread_running= BCM_LED_THREAD_DISABLED;
51 TURN_OFF_LED(GPIO_Num, uiLedIndex);
52 Status=EVENT_SIGNALED;
53 break;
55 if(Status)
57 TURN_OFF_LED(GPIO_Num, uiLedIndex);
58 Status=EVENT_SIGNALED;
59 break;
62 TURN_OFF_LED(GPIO_Num, uiLedIndex);
63 Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
64 currdriverstate!= Adapter->DriverState || kthread_should_stop(),
65 msecs_to_jiffies(timeout));
66 if(bInfinite == FALSE)
67 num_of_time--;
69 return Status;
72 static INT ScaleRateofTransfer(ULONG rate)
74 if(rate <= 3)
75 return rate;
76 else if((rate > 3) && (rate <= 100))
77 return 5;
78 else if((rate > 100) && (rate <= 200))
79 return 6;
80 else if((rate > 200) && (rate <= 300))
81 return 7;
82 else if((rate > 300) && (rate <= 400))
83 return 8;
84 else if((rate > 400) && (rate <= 500))
85 return 9;
86 else if((rate > 500) && (rate <= 600))
87 return 10;
88 else
89 return MAX_NUM_OF_BLINKS;
94 static INT LED_Proportional_Blink(PMINI_ADAPTER Adapter, UCHAR GPIO_Num_tx,
95 UCHAR uiTxLedIndex, UCHAR GPIO_Num_rx, UCHAR uiRxLedIndex, LedEventInfo_t currdriverstate)
97 /* Initial values of TX and RX packets*/
98 ULONG64 Initial_num_of_packts_tx = 0, Initial_num_of_packts_rx = 0;
99 /*values of TX and RX packets after 1 sec*/
100 ULONG64 Final_num_of_packts_tx = 0, Final_num_of_packts_rx = 0;
101 /*Rate of transfer of Tx and Rx in 1 sec*/
102 ULONG64 rate_of_transfer_tx = 0, rate_of_transfer_rx = 0;
103 int Status = STATUS_SUCCESS;
104 INT num_of_time = 0, num_of_time_tx = 0, num_of_time_rx = 0;
105 UINT remDelay = 0;
106 BOOLEAN bBlinkBothLED = TRUE;
107 //UINT GPIO_num = DISABLE_GPIO_NUM;
108 ulong timeout = 0;
110 /*Read initial value of packets sent/received */
111 Initial_num_of_packts_tx = atomic_read(&Adapter->TxTotalPacketCount);
112 Initial_num_of_packts_rx = atomic_read(&Adapter->GoodRxPktCount);
113 /*Scale the rate of transfer to no of blinks.*/
114 num_of_time_tx= ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
115 num_of_time_rx= ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
117 while((Adapter->device_removed == FALSE))
119 #if 0
120 if(0 == num_of_time_tx && 0 == num_of_time_rx)
122 timeout = 1000;
123 Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
124 currdriverstate!= Adapter->DriverState || kthread_should_stop(),
125 msecs_to_jiffies (timeout));
126 if(kthread_should_stop())
128 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
129 Adapter->LEDInfo.led_thread_running= BCM_LED_THREAD_DISABLED;
130 return EVENT_SIGNALED;
132 if(Status)
133 return EVENT_SIGNALED;
136 #endif
138 timeout = 50;
139 #if 0
140 /*Turn on LED if Tx is high bandwidth*/
141 if(num_of_time_tx > MAX_NUM_OF_BLINKS)
143 TURN_ON_LED(1<<GPIO_Num_tx, uiTxLedIndex);
144 num_of_time_tx = 0;
145 bBlinkBothLED = FALSE;
146 num_of_time = num_of_time_rx;
148 /*Turn on LED if Rx is high bandwidth*/
149 if(num_of_time_rx > MAX_NUM_OF_BLINKS)
151 TURN_ON_LED(1<<GPIO_Num_rx, uiRxLedIndex);
152 num_of_time_rx = 0;
153 bBlinkBothLED = FALSE;
154 num_of_time = num_of_time_tx;
156 #endif
157 /*Blink Tx and Rx LED when both Tx and Rx is in normal bandwidth*/
158 if(bBlinkBothLED)
160 /*Assign minimum number of blinks of either Tx or Rx.*/
161 if(num_of_time_tx > num_of_time_rx)
162 num_of_time = num_of_time_rx;
163 else
164 num_of_time = num_of_time_tx;
165 if(num_of_time > 0)
167 /*Blink both Tx and Rx LEDs*/
168 if(LED_Blink(Adapter, 1<<GPIO_Num_tx, uiTxLedIndex, timeout, num_of_time,currdriverstate)
169 == EVENT_SIGNALED)
171 return EVENT_SIGNALED;
173 if(LED_Blink(Adapter, 1<<GPIO_Num_rx, uiRxLedIndex, timeout, num_of_time,currdriverstate)
174 == EVENT_SIGNALED)
176 return EVENT_SIGNALED;
181 if(num_of_time == num_of_time_tx)
183 /*Blink pending rate of Rx*/
184 if(LED_Blink(Adapter, (1 << GPIO_Num_rx), uiRxLedIndex, timeout,
185 num_of_time_rx-num_of_time,currdriverstate) == EVENT_SIGNALED)
187 return EVENT_SIGNALED;
189 num_of_time = num_of_time_rx;
191 else
193 /*Blink pending rate of Tx*/
194 if(LED_Blink(Adapter, 1<<GPIO_Num_tx, uiTxLedIndex, timeout,
195 num_of_time_tx-num_of_time,currdriverstate) == EVENT_SIGNALED)
197 return EVENT_SIGNALED;
199 num_of_time = num_of_time_tx;
202 else
204 if(num_of_time == num_of_time_tx)
206 /*Blink pending rate of Rx*/
207 if(LED_Blink(Adapter, 1<<GPIO_Num_tx, uiTxLedIndex, timeout, num_of_time,currdriverstate)
208 == EVENT_SIGNALED)
210 return EVENT_SIGNALED;
213 else
215 /*Blink pending rate of Tx*/
216 if(LED_Blink(Adapter, 1<<GPIO_Num_rx, uiRxLedIndex, timeout,
217 num_of_time,currdriverstate) == EVENT_SIGNALED)
219 return EVENT_SIGNALED;
223 /* If Tx/Rx rate is less than maximum blinks per second,
224 * wait till delay completes to 1 second
226 remDelay = MAX_NUM_OF_BLINKS - num_of_time;
227 if(remDelay > 0)
229 timeout= 100 * remDelay;
230 Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
231 currdriverstate!= Adapter->DriverState ||kthread_should_stop() ,
232 msecs_to_jiffies (timeout));
234 if(kthread_should_stop())
236 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
237 Adapter->LEDInfo.led_thread_running= BCM_LED_THREAD_DISABLED;
238 return EVENT_SIGNALED;
240 if(Status)
241 return EVENT_SIGNALED;
244 /*Turn off both Tx and Rx LEDs before next second*/
245 TURN_OFF_LED(1<<GPIO_Num_tx, uiTxLedIndex);
246 TURN_OFF_LED(1<<GPIO_Num_rx, uiTxLedIndex);
249 * Read the Tx & Rx packets transmission after 1 second and
250 * calculate rate of transfer
252 Final_num_of_packts_tx = atomic_read(&Adapter->TxTotalPacketCount);
253 rate_of_transfer_tx = Final_num_of_packts_tx - Initial_num_of_packts_tx;
254 Final_num_of_packts_rx = atomic_read(&Adapter->GoodRxPktCount);
255 rate_of_transfer_rx = Final_num_of_packts_rx - Initial_num_of_packts_rx;
257 /*Read initial value of packets sent/received */
258 Initial_num_of_packts_tx = Final_num_of_packts_tx;
259 Initial_num_of_packts_rx = Final_num_of_packts_rx ;
261 /*Scale the rate of transfer to no of blinks.*/
262 num_of_time_tx= ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
263 num_of_time_rx= ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
266 return Status;
270 //-----------------------------------------------------------------------------
271 // Procedure: ValidateDSDParamsChecksum
273 // Description: Reads DSD Params and validates checkusm.
275 // Arguments:
276 // Adapter - Pointer to Adapter structure.
277 // ulParamOffset - Start offset of the DSD parameter to be read and validated.
278 // usParamLen - Length of the DSD Parameter.
280 // Returns:
281 // <OSAL_STATUS_CODE>
282 //-----------------------------------------------------------------------------
284 static INT ValidateDSDParamsChecksum(
285 PMINI_ADAPTER Adapter,
286 ULONG ulParamOffset,
287 USHORT usParamLen )
289 INT Status = STATUS_SUCCESS;
290 PUCHAR puBuffer = NULL;
291 USHORT usChksmOrg = 0;
292 USHORT usChecksumCalculated = 0;
294 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X",ulParamOffset, usParamLen);
296 puBuffer = OsalMemAlloc(usParamLen,"!MEM");
297 if(!puBuffer)
299 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum Allocation failed");
300 return -ENOMEM;
305 // Read the DSD data from the parameter offset.
307 if(STATUS_SUCCESS != BeceemNVMRead(Adapter,(PUINT)puBuffer,ulParamOffset,usParamLen))
309 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
310 Status=STATUS_IMAGE_CHECKSUM_MISMATCH;
311 goto exit;
315 // Calculate the checksum of the data read from the DSD parameter.
317 usChecksumCalculated = CFG_CalculateChecksum(puBuffer,usParamLen);
318 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: usCheckSumCalculated = 0x%x\n", usChecksumCalculated);
321 // End of the DSD parameter will have a TWO bytes checksum stored in it. Read it and compare with the calculated
322 // Checksum.
324 if(STATUS_SUCCESS != BeceemNVMRead(Adapter,(PUINT)&usChksmOrg,ulParamOffset+usParamLen,2))
326 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
327 Status=STATUS_IMAGE_CHECKSUM_MISMATCH;
328 goto exit;
330 usChksmOrg = ntohs(usChksmOrg);
331 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: usChksmOrg = 0x%x", usChksmOrg);
334 // Compare the checksum calculated with the checksum read from DSD section
336 if(usChecksumCalculated ^ usChksmOrg)
338 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum: Checksums don't match");
339 Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
340 goto exit;
343 exit:
344 if(puBuffer)
346 OsalMemFree(puBuffer, usParamLen);
348 return Status;
352 //-----------------------------------------------------------------------------
353 // Procedure: ValidateHWParmStructure
355 // Description: Validates HW Parameters.
357 // Arguments:
358 // Adapter - Pointer to Adapter structure.
359 // ulHwParamOffset - Start offset of the HW parameter Section to be read and validated.
361 // Returns:
362 // <OSAL_STATUS_CODE>
363 //-----------------------------------------------------------------------------
365 static INT ValidateHWParmStructure(PMINI_ADAPTER Adapter, ULONG ulHwParamOffset)
368 INT Status = STATUS_SUCCESS ;
369 USHORT HwParamLen = 0;
370 // Add DSD start offset to the hwParamOffset to get the actual address.
371 ulHwParamOffset += DSD_START_OFFSET;
373 /*Read the Length of HW_PARAM structure*/
374 BeceemNVMRead(Adapter,(PUINT)&HwParamLen,ulHwParamOffset,2);
375 HwParamLen = ntohs(HwParamLen);
376 if(0==HwParamLen || HwParamLen > Adapter->uiNVMDSDSize)
378 return STATUS_IMAGE_CHECKSUM_MISMATCH;
381 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread:HwParamLen = 0x%x", HwParamLen);
382 Status =ValidateDSDParamsChecksum(Adapter,ulHwParamOffset,HwParamLen);
383 return Status;
384 } /* ValidateHWParmStructure() */
386 static int ReadLEDInformationFromEEPROM(PMINI_ADAPTER Adapter, UCHAR GPIO_Array[])
388 int Status = STATUS_SUCCESS;
390 ULONG dwReadValue = 0;
391 USHORT usHwParamData = 0;
392 USHORT usEEPROMVersion = 0;
393 UCHAR ucIndex = 0;
394 UCHAR ucGPIOInfo[32] = {0};
396 BeceemNVMRead(Adapter,(PUINT)&usEEPROMVersion,EEPROM_VERSION_OFFSET,2);
398 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"usEEPROMVersion: Minor:0x%X Major:0x%x",usEEPROMVersion&0xFF, ((usEEPROMVersion>>8)&0xFF));
401 if(((usEEPROMVersion>>8)&0xFF) < EEPROM_MAP5_MAJORVERSION)
403 BeceemNVMRead(Adapter,(PUINT)&usHwParamData,EEPROM_HW_PARAM_POINTER_ADDRESS,2);
404 usHwParamData = ntohs(usHwParamData);
405 dwReadValue = usHwParamData;
407 else
410 // Validate Compatibility section and then read HW param if compatibility section is valid.
412 Status = ValidateDSDParamsChecksum(Adapter,
413 DSD_START_OFFSET,
414 COMPATIBILITY_SECTION_LENGTH_MAP5);
416 if(Status != STATUS_SUCCESS)
418 return Status;
420 BeceemNVMRead(Adapter,(PUINT)&dwReadValue,EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5,4);
421 dwReadValue = ntohl(dwReadValue);
425 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: Start address of HW_PARAM structure = 0x%lx",dwReadValue);
428 // Validate if the address read out is within the DSD.
429 // Adapter->uiNVMDSDSize gives whole DSD size inclusive of Autoinit.
430 // lower limit should be above DSD_START_OFFSET and
431 // upper limit should be below (Adapter->uiNVMDSDSize-DSD_START_OFFSET)
433 if(dwReadValue < DSD_START_OFFSET ||
434 dwReadValue > (Adapter->uiNVMDSDSize-DSD_START_OFFSET))
436 return STATUS_IMAGE_CHECKSUM_MISMATCH;
439 Status = ValidateHWParmStructure(Adapter, dwReadValue);
440 if(Status){
441 return Status;
445 Add DSD_START_OFFSET to the offset read from the EEPROM.
446 This will give the actual start HW Parameters start address.
447 To read GPIO section, add GPIO offset further.
450 dwReadValue += DSD_START_OFFSET; // = start address of hw param section.
451 dwReadValue += GPIO_SECTION_START_OFFSET; // = GPIO start offset within HW Param section.
453 /* Read the GPIO values for 32 GPIOs from EEPROM and map the function
454 * number to GPIO pin number to GPIO_Array
456 BeceemNVMRead(Adapter, (UINT *)ucGPIOInfo,dwReadValue,32);
457 for(ucIndex = 0; ucIndex < 32; ucIndex++)
460 switch(ucGPIOInfo[ucIndex])
462 case RED_LED:
464 GPIO_Array[RED_LED] = ucIndex;
465 Adapter->gpioBitMap |= (1<<ucIndex);
466 break;
468 case BLUE_LED:
470 GPIO_Array[BLUE_LED] = ucIndex;
471 Adapter->gpioBitMap |= (1<<ucIndex);
472 break;
474 case YELLOW_LED:
476 GPIO_Array[YELLOW_LED] = ucIndex;
477 Adapter->gpioBitMap |= (1<<ucIndex);
478 break;
480 case GREEN_LED:
482 GPIO_Array[GREEN_LED] = ucIndex;
483 Adapter->gpioBitMap |= (1<<ucIndex);
484 break;
486 default:
487 break;
491 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"GPIO's bit map correspond to LED :0x%X",Adapter->gpioBitMap);
492 return Status;
496 static int ReadConfigFileStructure(PMINI_ADAPTER Adapter, BOOLEAN *bEnableThread)
498 int Status = STATUS_SUCCESS;
499 UCHAR GPIO_Array[NUM_OF_LEDS+1]; /*Array to store GPIO numbers from EEPROM*/
500 #ifndef BCM_SHM_INTERFACE
501 UINT uiIndex = 0;
502 UINT uiNum_of_LED_Type = 0;
503 PUCHAR puCFGData = NULL;
504 UCHAR bData = 0;
505 #endif
506 memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1);
508 if(!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams))
510 BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Target Params not Avail.\n");
511 return -ENOENT;
514 /*Populate GPIO_Array with GPIO numbers for LED functions*/
515 /*Read the GPIO numbers from EEPROM*/
516 Status = ReadLEDInformationFromEEPROM(Adapter, GPIO_Array);
517 if(Status == STATUS_IMAGE_CHECKSUM_MISMATCH)
519 *bEnableThread = FALSE;
520 return STATUS_SUCCESS;
522 else if(Status)
524 *bEnableThread = FALSE;
525 return Status;
527 #ifdef BCM_SHM_INTERFACE
528 *bEnableThread = FALSE;
529 return Status ;
530 #else
532 * CONFIG file read successfully. Deallocate the memory of
533 * uiFileNameBufferSize
535 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: Config file read successfully\n");
536 puCFGData = (PUCHAR) &Adapter->pstargetparams->HostDrvrConfig1;
539 * Offset for HostDrvConfig1, HostDrvConfig2, HostDrvConfig3 which
540 * will have the information of LED type, LED on state for different
541 * driver state and LED blink state.
544 for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
546 bData = *puCFGData;
548 /*Check Bit 8 for polarity. If it is set, polarity is reverse polarity*/
549 if(bData & 0x80)
551 Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 0;
552 /*unset the bit 8*/
553 bData = bData & 0x7f;
556 Adapter->LEDInfo.LEDState[uiIndex].LED_Type = bData;
557 if(bData <= NUM_OF_LEDS)
558 Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num = GPIO_Array[bData];
559 else
560 Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num = DISABLE_GPIO_NUM;
562 puCFGData++;
563 bData = *puCFGData;
564 Adapter->LEDInfo.LEDState[uiIndex].LED_On_State = bData;
565 puCFGData++;
566 bData = *puCFGData;
567 Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State= bData;
568 puCFGData++;
571 /*Check if all the LED settings are disabled. If it is disabled, dont launch the LED control thread.*/
572 for(uiIndex = 0; uiIndex<NUM_OF_LEDS; uiIndex++)
574 if((Adapter->LEDInfo.LEDState[uiIndex].LED_Type == DISABLE_GPIO_NUM) ||
575 (Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0x7f) ||
576 (Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0))
577 uiNum_of_LED_Type++;
579 if(uiNum_of_LED_Type >= NUM_OF_LEDS)
580 *bEnableThread = FALSE;
581 #endif
583 #if 0
584 for(uiIndex=0; uiIndex<NUM_OF_LEDS; uiIndex++)
586 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].LED_Type = %x\n", uiIndex,
587 Adapter->LEDInfo.LEDState[uiIndex].LED_Type);
588 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].LED_On_State = %x\n", uiIndex,
589 Adapter->LEDInfo.LEDState[uiIndex].LED_On_State);
590 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].LED_Blink_State = %x\n", uiIndex,
591 Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State);
592 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].GPIO_Num = %x\n", uiIndex,
593 Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num);
595 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: Polarity = %d\n",
596 Adapter->LEDInfo.BitPolarty);
597 #endif
598 return Status;
600 //--------------------------------------------------------------------------
601 // Procedure: LedGpioInit
603 // Description: Initializes LED GPIOs. Makes the LED GPIOs to OUTPUT mode and make the
604 // initial state to be OFF.
606 // Arguments:
607 // Adapter - Pointer to MINI_ADAPTER structure.
609 // Returns: VOID
611 //-----------------------------------------------------------------------------
613 static VOID LedGpioInit(PMINI_ADAPTER Adapter)
615 UINT uiResetValue = 0;
616 UINT uiIndex = 0;
618 /* Set all LED GPIO Mode to output mode */
619 if(rdmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, sizeof(uiResetValue)) <0)
620 BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: RDM Failed\n");
621 for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
623 if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
624 uiResetValue |= (1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num);
625 TURN_OFF_LED(1<<Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num,uiIndex);
627 if(wrmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, sizeof(uiResetValue)) < 0)
628 BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: WRM Failed\n");
630 Adapter->LEDInfo.bIdle_led_off = FALSE;
632 //-----------------------------------------------------------------------------
634 static INT BcmGetGPIOPinInfo(PMINI_ADAPTER Adapter, UCHAR *GPIO_num_tx, UCHAR *GPIO_num_rx ,UCHAR *uiLedTxIndex, UCHAR *uiLedRxIndex,LedEventInfo_t currdriverstate)
636 UINT uiIndex = 0;
638 *GPIO_num_tx = DISABLE_GPIO_NUM;
639 *GPIO_num_rx = DISABLE_GPIO_NUM;
641 for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
644 if((currdriverstate == NORMAL_OPERATION)||
645 (currdriverstate == IDLEMODE_EXIT)||
646 (currdriverstate == FW_DOWNLOAD))
648 if(Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State & currdriverstate)
650 if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
652 if(*GPIO_num_tx == DISABLE_GPIO_NUM)
654 *GPIO_num_tx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
655 *uiLedTxIndex = uiIndex;
657 else
659 *GPIO_num_rx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
660 *uiLedRxIndex = uiIndex;
665 else
667 if(Adapter->LEDInfo.LEDState[uiIndex].LED_On_State & currdriverstate)
669 if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
671 *GPIO_num_tx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
672 *uiLedTxIndex = uiIndex;
677 return STATUS_SUCCESS ;
679 static VOID LEDControlThread(PMINI_ADAPTER Adapter)
681 UINT uiIndex = 0;
682 UCHAR GPIO_num = 0;
683 UCHAR uiLedIndex = 0 ;
684 UINT uiResetValue = 0;
685 LedEventInfo_t currdriverstate = 0;
686 ulong timeout = 0;
688 INT Status = 0;
690 UCHAR dummyGPIONum = 0;
691 UCHAR dummyIndex = 0;
693 //currdriverstate = Adapter->DriverState;
694 Adapter->LEDInfo.bIdleMode_tx_from_host = FALSE;
696 /*Wait till event is triggered*/
697 //wait_event(Adapter->LEDInfo.notify_led_event,
698 // currdriverstate!= Adapter->DriverState);
700 GPIO_num = DISABLE_GPIO_NUM ;
702 while(TRUE)
704 /*Wait till event is triggered*/
705 if( (GPIO_num == DISABLE_GPIO_NUM)
707 ((currdriverstate != FW_DOWNLOAD) &&
708 (currdriverstate != NORMAL_OPERATION) &&
709 (currdriverstate != LOWPOWER_MODE_ENTER))
711 (currdriverstate == LED_THREAD_INACTIVE) )
713 Status = wait_event_interruptible(Adapter->LEDInfo.notify_led_event,
714 currdriverstate != Adapter->DriverState || kthread_should_stop());
717 if(kthread_should_stop() || Adapter->device_removed )
719 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
720 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
721 TURN_OFF_LED(1<<GPIO_num, uiLedIndex);
722 return ;//STATUS_FAILURE;
724 #if 0
725 if(Adapter->device_removed)
727 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"Device removed hence exiting from Led Thread..");
728 return ; //-ENODEV;
730 #endif
731 #if 0
732 if((GPIO_num != DISABLE_GPIO_NUM) &&
733 ((currdriverstate != FW_DOWNLOAD) &&
734 (currdriverstate != NORMAL_OPERATION) &&
735 (currdriverstate != IDLEMODE_EXIT)))
736 TURN_OFF_LED(1<<GPIO_num, uiLedIndex);
737 #endif
739 if(GPIO_num != DISABLE_GPIO_NUM)
741 TURN_OFF_LED(1<<GPIO_num, uiLedIndex);
744 if(Adapter->LEDInfo.bLedInitDone == FALSE)
746 LedGpioInit(Adapter);
747 Adapter->LEDInfo.bLedInitDone = TRUE;
750 switch(Adapter->DriverState)
752 case DRIVER_INIT:
754 currdriverstate = DRIVER_INIT;//Adapter->DriverState;
755 #if 0
756 LedGpioInit(Adapter);
757 Adapter->LEDInfo.bLedInitDone = TRUE;
758 #endif
759 BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate);
761 if(GPIO_num != DISABLE_GPIO_NUM)
763 TURN_ON_LED(1<<GPIO_num, uiLedIndex);
766 break;
767 case FW_DOWNLOAD:
769 //BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: FW_DN_DONE called\n");
770 currdriverstate = FW_DOWNLOAD;
771 #if 0
772 if(Adapter->LEDInfo.bLedInitDone == FALSE)
774 LedGpioInit(Adapter);
775 Adapter->LEDInfo.bLedInitDone = TRUE;
777 #endif
778 BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate);
780 if(GPIO_num != DISABLE_GPIO_NUM)
782 timeout = 50;
783 LED_Blink(Adapter, 1<<GPIO_num, uiLedIndex, timeout, -1,currdriverstate);
786 break;
787 case FW_DOWNLOAD_DONE:
789 currdriverstate = FW_DOWNLOAD_DONE;
790 BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex,currdriverstate);
791 if(GPIO_num != DISABLE_GPIO_NUM)
793 TURN_ON_LED(1<<GPIO_num, uiLedIndex);
796 break;
798 case SHUTDOWN_EXIT:
799 #if 0
800 if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN)
802 LedGpioInit(Adapter);
804 #endif
805 //no break, continue to NO_NETWORK_ENTRY state as well.
807 case NO_NETWORK_ENTRY:
809 currdriverstate = NO_NETWORK_ENTRY;
810 BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex,&dummyGPIONum,currdriverstate);
811 if(GPIO_num != DISABLE_GPIO_NUM)
813 TURN_ON_LED(1<<GPIO_num, uiLedIndex);
816 break;
817 case NORMAL_OPERATION:
819 UCHAR GPIO_num_tx = DISABLE_GPIO_NUM;
820 UCHAR GPIO_num_rx = DISABLE_GPIO_NUM;
821 UCHAR uiLEDTx = 0;
822 UCHAR uiLEDRx = 0;
823 currdriverstate = NORMAL_OPERATION;
824 Adapter->LEDInfo.bIdle_led_off = FALSE;
826 BcmGetGPIOPinInfo(Adapter, &GPIO_num_tx, &GPIO_num_rx, &uiLEDTx,&uiLEDRx,currdriverstate);
827 if((GPIO_num_tx == DISABLE_GPIO_NUM) && (GPIO_num_rx == DISABLE_GPIO_NUM))
829 GPIO_num = DISABLE_GPIO_NUM ;
831 else
833 /*If single LED is selected, use same for both Tx and Rx*/
834 if(GPIO_num_tx == DISABLE_GPIO_NUM)
836 GPIO_num_tx = GPIO_num_rx;
837 uiLEDTx = uiLEDRx;
839 else if(GPIO_num_rx == DISABLE_GPIO_NUM)
841 GPIO_num_rx = GPIO_num_tx;
842 uiLEDRx = uiLEDTx;
844 /*Blink the LED in proportionate to Tx and Rx transmissions.*/
845 LED_Proportional_Blink(Adapter, GPIO_num_tx, uiLEDTx, GPIO_num_rx, uiLEDRx,currdriverstate);
848 break;
849 case LOWPOWER_MODE_ENTER:
851 currdriverstate = LOWPOWER_MODE_ENTER;
852 if( DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING == Adapter->ulPowerSaveMode)
854 /* Turn OFF all the LED */
855 uiResetValue = 0;
856 for(uiIndex =0; uiIndex < NUM_OF_LEDS; uiIndex++)
858 if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
859 TURN_OFF_LED((1<<Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num),uiIndex);
863 /* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */
864 Adapter->LEDInfo.bLedInitDone = FALSE;
865 Adapter->LEDInfo.bIdle_led_off = TRUE;
866 wake_up(&Adapter->LEDInfo.idleModeSyncEvent);
867 GPIO_num = DISABLE_GPIO_NUM;
868 break;
870 case IDLEMODE_CONTINUE:
872 currdriverstate = IDLEMODE_CONTINUE;
873 GPIO_num = DISABLE_GPIO_NUM;
875 break;
876 case IDLEMODE_EXIT:
878 #if 0
879 UCHAR GPIO_num_tx = DISABLE_GPIO_NUM;
880 UCHAR GPIO_num_rx = DISABLE_GPIO_NUM;
881 UCHAR uiTxLedIndex = 0;
882 UCHAR uiRxLedIndex = 0;
884 currdriverstate = IDLEMODE_EXIT;
885 if(DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN == Adapter->ulPowerSaveMode)
887 LedGpioInit(Adapter);
889 BcmGetGPIOPinInfo(Adapter, &GPIO_num_tx, &GPIO_num_rx, &uiTxLedIndex,&uiRxLedIndex,currdriverstate);
891 Adapter->LEDInfo.bIdle_led_off = FALSE;
893 if((GPIO_num_tx == DISABLE_GPIO_NUM) && (GPIO_num_rx == DISABLE_GPIO_NUM))
895 GPIO_num = DISABLE_GPIO_NUM ;
897 else
899 timeout = 50;
900 if(Adapter->LEDInfo.bIdleMode_tx_from_host)
901 LED_Blink(Adapter, 1<<GPIO_num_tx, uiTxLedIndex, timeout, -1,currdriverstate);
902 else
903 LED_Blink(Adapter, 1<<GPIO_num_rx, uiRxLedIndex, timeout, -1,currdriverstate);
905 #endif
907 break;
908 case DRIVER_HALT:
910 currdriverstate = DRIVER_HALT;
911 GPIO_num = DISABLE_GPIO_NUM;
912 for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
914 if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num !=
915 DISABLE_GPIO_NUM)
916 TURN_OFF_LED((1<<Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num),uiIndex);
918 //Adapter->DriverState = DRIVER_INIT;
920 break;
921 case LED_THREAD_INACTIVE :
923 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"InActivating LED thread...");
924 currdriverstate = LED_THREAD_INACTIVE;
925 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_INACTIVELY ;
926 Adapter->LEDInfo.bLedInitDone = FALSE ;
927 //disable ALL LED
928 for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
930 if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num !=
931 DISABLE_GPIO_NUM)
932 TURN_OFF_LED((1<<Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num),uiIndex);
935 break;
936 case LED_THREAD_ACTIVE :
938 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"Activating LED thread again...");
939 if(Adapter->LinkUpStatus == FALSE)
940 Adapter->DriverState = NO_NETWORK_ENTRY;
941 else
942 Adapter->DriverState = NORMAL_OPERATION;
944 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_ACTIVELY ;
946 break;
947 //return;
948 default:
949 break;
952 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
955 int InitLedSettings(PMINI_ADAPTER Adapter)
957 int Status = STATUS_SUCCESS;
958 BOOLEAN bEnableThread = TRUE;
959 UCHAR uiIndex = 0;
961 /*Initially set BitPolarity to normal polarity. The bit 8 of LED type
962 * is used to change the polarity of the LED.*/
964 for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
965 Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 1;
968 /*Read the LED settings of CONFIG file and map it to GPIO numbers in EEPROM*/
969 Status = ReadConfigFileStructure(Adapter, &bEnableThread);
970 if(STATUS_SUCCESS != Status)
972 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: FAILED in ReadConfigFileStructure\n");
973 return Status;
976 if(Adapter->LEDInfo.led_thread_running)
978 if(bEnableThread)
980 else
982 Adapter->DriverState = DRIVER_HALT;
983 wake_up(&Adapter->LEDInfo.notify_led_event);
984 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
989 else if(bEnableThread)
991 /*Create secondary thread to handle the LEDs*/
992 init_waitqueue_head(&Adapter->LEDInfo.notify_led_event);
993 init_waitqueue_head(&Adapter->LEDInfo.idleModeSyncEvent);
994 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_ACTIVELY;
995 Adapter->LEDInfo.bIdle_led_off = FALSE;
996 Adapter->LEDInfo.led_cntrl_threadid = kthread_run((int (*)(void *))
997 LEDControlThread, Adapter, "led_control_thread");
998 if(IS_ERR(Adapter->LEDInfo.led_cntrl_threadid))
1000 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Not able to spawn Kernel Thread\n");
1001 Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
1002 return PTR_ERR(Adapter->LEDInfo.led_cntrl_threadid);
1005 return Status;