// // TOSHIBA CORPORATION PROPRIETARY INFORMATION // This software is supplied under the terms of a license agreement or // nondisclosure agreement with TOSHIBA Corporation and may not be copied // or disclosed except in accordance with the terms of that agreement. // Copyright (c) 1997 TOSHIBA Corporation. All Rights Reserved. // // Workfile: BERT.C // // Purpose: // // Contents: // #include "strmini.h" #include "ksmedia.h" #include "capmain.h" #include "capdebug.h" #include "bert.h" #include "image.h" #ifdef TOSHIBA // '99-01-20 Added extern ULONG CurrentOSType; ULONG ulConfigAddress; #endif//TOSHIBA //-------------------------------------------------------------------- // ReadRegUlong //-------------------------------------------------------------------- ULONG ReadRegUlong(PHW_DEVICE_EXTENSION pHwDevExt, ULONG offset) { PUCHAR pBase = (PUCHAR)(pHwDevExt->ioBaseLocal); #ifndef TOSHIBA if (!pHwDevExt->IsCardIn) return 0L; #endif//TOSHIBA return *(PULONG)(pBase + offset); } //-------------------------------------------------------------------- // WriteRegUlong //-------------------------------------------------------------------- VOID WriteRegUlong(PHW_DEVICE_EXTENSION pHwDevExt, ULONG offset, ULONG data) { ULONG volatile *temp; PUCHAR pBase = (PUCHAR)(pHwDevExt->ioBaseLocal); #ifndef TOSHIBA if (!pHwDevExt->IsCardIn) return; #endif//TOSHIBA temp = (PULONG)(pBase + offset); *temp = data; } //-------------------------------------------------------------------- // ReadModifyWriteRegUlong //-------------------------------------------------------------------- VOID ReadModifyWriteRegUlong(PHW_DEVICE_EXTENSION pHwDevExt, ULONG offset, ULONG a_mask, ULONG o_mask) { ULONG tdata; ULONG volatile *temp; PUCHAR pBase = (PUCHAR)(pHwDevExt->ioBaseLocal); #ifndef TOSHIBA if (!pHwDevExt->IsCardIn) return; #endif//TOSHIBA temp = (PULONG)(pBase + offset); tdata = *temp; tdata = (tdata & a_mask) | o_mask; *temp = tdata; } BOOL BertIsCardIn( IN PHW_DEVICE_EXTENSION pHwDevExt ) { DWORD value; value = ReadRegUlong(pHwDevExt, BERT_CAPSTAT_REG); if ((value == 0) || (value == 0xffffffff)) return FALSE; else return TRUE; } //-------------------------------------------------------------------- // BertInterruptEnable //-------------------------------------------------------------------- VOID BertInterruptEnable( IN PHW_DEVICE_EXTENSION pHwDevExt, IN BOOL bStatus ) { WriteRegUlong(pHwDevExt, BERT_INTRST_REG , 0xFFFF); if (!bStatus) { ReadModifyWriteRegUlong(pHwDevExt, BERT_INTSTAT_REG, (ULONG)~ACTIVE_CAPTURE_IRQS, 0); } else { ReadModifyWriteRegUlong(pHwDevExt, BERT_INTSTAT_REG, ~0UL, (ULONG)ACTIVE_CAPTURE_IRQS); } } //-------------------------------------------------------------------- // BertDMAEnable //-------------------------------------------------------------------- VOID BertDMAEnable( IN PHW_DEVICE_EXTENSION pHwDevExt, IN BOOL bStatus ) { DWORD dwAddr; if (bStatus) // Turn On Video Transfer. { dwAddr = (DWORD)pHwDevExt->pPhysRpsDMABuf.LowPart; #if 0 dwAddr = (dwAddr + 0x1FFF) & 0xFFFFE000; #endif WriteRegUlong(pHwDevExt, BERT_RPSADR_REG, dwAddr); WriteRegUlong(pHwDevExt, BERT_RPSPAGE_REG, dwAddr); BertVsncSignalWait(pHwDevExt); // Let the RPS turn on/off EBMV WriteRegUlong(pHwDevExt, BERT_CAPSTAT_REG, (ERPS | CKRE | CKMD)); // mod passive_enable -> ERPS 97-03-15(Sat) Mod 97-05-08(Thu) } else // Turn Off Video Transfer. { if (ReadRegUlong(pHwDevExt, BERT_CAPSTAT_REG) & ERPS) { ReadModifyWriteRegUlong(pHwDevExt, BERT_CAPSTAT_REG, (ULONG)~ERPS, 0UL); } if (!BertIsCAPSTATReady(pHwDevExt)) { ReadModifyWriteRegUlong(pHwDevExt, BERT_CAPSTAT_REG, (ULONG)~EBMV, 0UL); } if (ReadRegUlong(pHwDevExt, BERT_CAPSTAT_REG) & RPSS) { pHwDevExt->NeedHWInit = TRUE; } } } //-------------------------------------------------------------------- // BertIsLocked //-------------------------------------------------------------------- BOOL BertIsLocked( IN PHW_DEVICE_EXTENSION pHwDevExt ) /*++ Routine Description : Check if the decoder has been locked or not. Arguments : pDevInfo - Device Info for the driver Return Value : TRUE - configuration success --*/ { return ((ReadRegUlong(pHwDevExt, BERT_CAPSTAT_REG) & LOCK) != 0); } //-------------------------------------------------------------------- // BertFifoConfig //-------------------------------------------------------------------- BOOL BertFifoConfig( IN PHW_DEVICE_EXTENSION pHwDevExt, IN ULONG ulFormat ) /*++ Routine Description : Configure the BERT fifo for the format choosen. Arguments : pDevInfo - Device Info for the driver dwFormat - format index as defined in wally.h Return Value : TRUE - configuration success --*/ { DWORD dwFifo; switch (ulFormat) { case FmtYUV12: dwFifo = 0xe; break; case FmtYUV9: dwFifo = 0xd; break; default: return FALSE; } dwFifo=(dwFifo<<24)| 0x100000l; // Modify 97-04-02 WriteRegUlong(pHwDevExt, BERT_FIFOCFG_REG, dwFifo); WriteRegUlong(pHwDevExt, BERT_BURST_LEN, 0x00000002); // DATA=8 DWORD, RPS=2DWORD WriteRegUlong(pHwDevExt, BERT_YSTRIDE_REG, pHwDevExt->Ystride); WriteRegUlong(pHwDevExt, BERT_USTRIDE_REG, pHwDevExt->Ustride); WriteRegUlong(pHwDevExt, BERT_VSTRIDE_REG, pHwDevExt->Vstride); return TRUE; } //-------------------------------------------------------------------- // BertInitializeHardware //-------------------------------------------------------------------- BOOL BertInitializeHardware( IN PHW_DEVICE_EXTENSION pHwDevExt ) /*++ Routine Description : This function initializes the bert asic to the default values. Arguments : pDevInfo - Device Info for the driver pHw - pointer to hardware info data structure Return Value : TRUE - initialization success --*/ { WriteRegUlong(pHwDevExt, BERT_CAPSTAT_REG, (CAMARA_OFF | CKRE | CKMD)); // Mod 97-05-08(Thu) return TRUE; } //-------------------------------------------------------------------- // BertEnableRps //-------------------------------------------------------------------- VOID BertEnableRps( IN PHW_DEVICE_EXTENSION pHwDevExt ) /*++ Routine Description : enable the rps execution by setting ERPS and EROO bits in the CAPSTAT reg Arguments : pDevInfo - Device Info for the driver Return Value : None --*/ { ReadModifyWriteRegUlong(pHwDevExt, BERT_CAPSTAT_REG, 0xf0ffffff, 0x08000000); // MOD 97-03-17(Mon) } //-------------------------------------------------------------------- // BertDisableRps //-------------------------------------------------------------------- VOID BertDisableRps( IN PHW_DEVICE_EXTENSION pHwDevExt ) /*++ Routine Description : disable the rps execution by reseting the ERPS bit in the CAPSTAT reg Arguments : pDevInfo - Device Info for the driver Return Value : None --*/ { ReadModifyWriteRegUlong(pHwDevExt, BERT_CAPSTAT_REG, (ULONG)~ERPS, 0L); } BOOL BertIsCAPSTATReady(PHW_DEVICE_EXTENSION pHwDevExt) { LARGE_INTEGER CurrentTime; LARGE_INTEGER StartTime; KeQuerySystemTime( &StartTime ); // Wait until EBMV is cleared by the RPS while (ReadRegUlong(pHwDevExt, BERT_CAPSTAT_REG) & EBMV) { KeQuerySystemTime( &CurrentTime ); if ((CurrentTime.QuadPart - StartTime.QuadPart) > EBMV_TIMEOUT) { return FALSE; } } return TRUE; } VOID BertVsncSignalWait(PHW_DEVICE_EXTENSION pHwDevExt) { ULONG ulCount; // Wait until VSNC is low for (ulCount = 0; ulCount < 500; ulCount++ ) { if (!(ReadRegUlong(pHwDevExt, BERT_VINSTAT_REG) & VSNC)) break; VC_Delay(2); } } VOID BertDMARestart( IN PHW_DEVICE_EXTENSION pHwDevExt ) { DWORD dwAddr; dwAddr = (DWORD)pHwDevExt->pPhysRpsDMABuf.LowPart; #if 0 dwAddr = (dwAddr + 0x1FFF) & 0xFFFFE000; #endif WriteRegUlong(pHwDevExt, BERT_RPSADR_REG, dwAddr); WriteRegUlong(pHwDevExt, BERT_RPSPAGE_REG, dwAddr); WriteRegUlong(pHwDevExt, BERT_CAPSTAT_REG, (ERPS | CKRE | CKMD)); } void ActiveField( IN PHW_DEVICE_EXTENSION pHwDevExt, IN DWORD *addr, IN DWORD *PhysAddr, /* Insert BUN 97-03-25(Tue) */ IN DWORD bNoCopy, IN DWORD *y_DMA_addr, IN DWORD *v_DMA_addr, IN DWORD *u_DMA_addr, IN DWORD *nextRPSaddr, IN DWORD *readRegAddr, IN BOOL genIRQ /* = FALSE */, IN DWORD fieldsToCapture /* = CAPTURE_BOTH */ ) { // Set DmaActive flag right away since this is the indicator register for whether DMA is pending. // If the DmaActive flag is zero, it is safe to copy the DMA frame buffer. The YPTR register is // used as a scratch register to be read into the DmaActive flag. *addr++ = RPS_CONTINUE_CMD | BERT_YPTR_REG; *addr++ = (DWORD)y_DMA_addr; // Address of y DMA buffer. *addr++ = RPS_CONTINUE_CMD | ((genIRQ) ? RPS_INT_CMD : 0) | BERT_RPSPAGE_REG; *addr++ = (pHwDevExt->s_physDmaActiveFlag-0x1860); // Page s_DmaActiveFlag is on mod BUN *addr++ = RPS_CONTINUE_CMD | BERT_VPTR_REG; *addr++ = (DWORD)v_DMA_addr; // Address of v DMA buffer. *addr++ = RPS_CONTINUE_CMD | BERT_UPTR_REG; *addr++ = (DWORD)u_DMA_addr; // Address of u DMA buffer. *addr++ = BERT_CAPSTAT_REG; // LAST RPS command this VSYNC *addr++ = fieldsToCapture; // Switch on bus master bit. *addr++ = RPS_CONTINUE_CMD | BERT_RPSADR_REG; *addr = (DWORD)nextRPSaddr; // Address of next RPS. } // // SKIP_FIELD_RPS is the size of a RPS node that skips a field. // Skip frame is programmed as follows: // DWORD -- RPS command register // DWORD -- Value of register programming. //---------------- Actual RPS for Skip Frame ------------------------ // RPS_CONTINUE_CMD | CAPSTAT - RPS, read next RPS, select CAPSTAT // ERPS | EROO | GO0 - Enable RPS & Power to camara (off bus master) // INTSTAT - Don't continue & select INITSTAT register. // m_passive_cap_IRQs - Don't interrupt end of field. // RPS_CONTINUE_CMD | RPSADDR - Set up address // Address field - Program at init for next field. //------------------------------------------------------------------- // VOID SkipField( IN PHW_DEVICE_EXTENSION pHwDevExt, IN DWORD *addr, IN DWORD *PhysAddr, /* Insert BUN 97-03-25(Tue) */ IN DWORD *nextRPSaddr, IN DWORD *readRegAddr, IN BOOL genIRQ /* = FALSE */, IN DWORD fieldToSkip /* = SKIP_BOTH */ ) { // Set YPTR right away since this is the indicator register for whether DMA is pending. // If DmaActive flag is zero, it is safe to copy the DMA frame buffer. *addr++ = RPS_CONTINUE_CMD | BERT_YPTR_REG; *addr++ = (DWORD)PhysAddr; *addr++ = RPS_CONTINUE_CMD | ((genIRQ) ? RPS_INT_CMD : 0) | BERT_RPSPAGE_REG; *addr++ = (pHwDevExt->s_physDmaActiveFlag-0x1860); // Page s_physDmaActiveFlag is on MOD bun *addr++ = BERT_CAPSTAT_REG; /* mod BUN 97-04-16(Wed) */ *addr++ = fieldToSkip; // Switch off bus master bit. *addr++ = RPS_CONTINUE_CMD | BERT_RPSADR_REG; *addr = (DWORD)nextRPSaddr; // Address of next RPS. } BOOL BertBuildNodes( IN PHW_DEVICE_EXTENSION pHwDevExt ) { DWORD* addr; DWORD* physAddr; DWORD* physBase; ULONG ulTemp; unsigned framesPerSecond; unsigned f; unsigned max_rps; BOOL lastOneActive = FALSE; framesPerSecond = pHwDevExt->uiFramePerSecond; max_rps = DEF_RPS_FRAMES; ulTemp = (ULONG)pHwDevExt->pRpsDMABuf; #if 0 ulTemp = (ulTemp + 0x1FFF) & 0xFFFFE000; #endif addr = (DWORD *)ulTemp; ulTemp = (ULONG)pHwDevExt->pPhysRpsDMABuf.LowPart; #if 0 ulTemp = (ulTemp + 0x1FFF) & 0xFFFFE000; #endif physAddr = (DWORD *)ulTemp; physBase = physAddr; if (addr == NULL) return FALSE; // Build an RPS per frame. // Building 2 nodes per iteration when capturing both fields, so always // go thru only DEF_RPS_FRAMES iterations. for (f = max_rps ; f >= 1 ; f-- ) { if (((framesPerSecond * f) % DEF_RPS_FRAMES) < framesPerSecond) { ActiveField(pHwDevExt,addr,(DWORD *)0, TRUE, // No buffer copying during the processing of this node (DWORD *)((BYTE *)pHwDevExt->pPhysCaptureBufferY.LowPart + pHwDevExt->YoffsetOdd), // Position Y data. (DWORD *)((BYTE *)pHwDevExt->pPhysCaptureBufferV.LowPart + pHwDevExt->VoffsetOdd), // Position V data. (DWORD *)((BYTE *)pHwDevExt->pPhysCaptureBufferU.LowPart + pHwDevExt->UoffsetOdd), // Position U data. ((f == 1 ) ? physBase : physAddr + 0x1A), physAddr + 0x19, // Put the read value at the end of the list. lastOneActive, (CAPTURE_ODD | CKRE | CKMD)); // Mod 97-05-08(Thu) lastOneActive = TRUE; } else { // Don't generate interrupts for skipped frames SkipField(pHwDevExt,addr, (DWORD *)((BYTE *)pHwDevExt->pPhysCapBuf2Y.LowPart + pHwDevExt->YoffsetOdd), ((f == 1 ) ? physBase : physAddr + 0x1A), physAddr + 0x19, // Put the read value at the end of the list. lastOneActive, (SKIP_ODD | CKRE | CKMD)); // Mod 97-05-08(Thu) lastOneActive = FALSE; } addr += 0x1A; physAddr += 0x1A; } return TRUE; } BOOL BertTriBuildNodes( IN PHW_DEVICE_EXTENSION pHwDevExt ) { DWORD* addr; DWORD* physAddr; DWORD* physBase; ULONG ulTemp; unsigned framesPerSecond; unsigned f; unsigned max_rps; BOOL lastOneActive = FALSE; DWORD* CapphysAddrY; DWORD* CapphysAddrV; DWORD* CapphysAddrU; framesPerSecond = pHwDevExt->uiFramePerSecond; max_rps = DEF_RPS_FRAMES; ulTemp = (ULONG)pHwDevExt->pRpsDMABuf; #if 0 ulTemp = (ulTemp + 0x1FFF) & 0xFFFFE000; #endif addr = (DWORD *)ulTemp; ulTemp = (ULONG)pHwDevExt->pPhysRpsDMABuf.LowPart; #if 0 ulTemp = (ulTemp + 0x1FFF) & 0xFFFFE000; #endif physAddr = (DWORD *)ulTemp; physBase = physAddr; if (addr == NULL) return FALSE; // Build an RPS per frame. // Building 2 nodes per iteration when capturing both fields, so always // go thru only DEF_RPS_FRAMES iterations. lastOneActive = ( ((framesPerSecond*1)%DEF_RPS_FRAMES) < framesPerSecond ) ? TRUE : FALSE ; for (f = max_rps ; f >= 1 ; f-- ) { if( f%2 ){ CapphysAddrY=(DWORD *)pHwDevExt->pPhysCapBuf2Y.LowPart; CapphysAddrV=(DWORD *)pHwDevExt->pPhysCapBuf2V.LowPart; CapphysAddrU=(DWORD *)pHwDevExt->pPhysCapBuf2U.LowPart; } else{ CapphysAddrY=(DWORD *)pHwDevExt->pPhysCaptureBufferY.LowPart; CapphysAddrV=(DWORD *)pHwDevExt->pPhysCaptureBufferV.LowPart; CapphysAddrU=(DWORD *)pHwDevExt->pPhysCaptureBufferU.LowPart; } if (((framesPerSecond * f) % DEF_RPS_FRAMES) < framesPerSecond) { ActiveField(pHwDevExt,addr,(DWORD *)0, TRUE, // No buffer copying during the processing of this node (DWORD *)((BYTE *)CapphysAddrY + pHwDevExt->YoffsetOdd), // Position Y data. (DWORD *)((BYTE *)CapphysAddrV + pHwDevExt->VoffsetOdd), // Position V data. (DWORD *)((BYTE *)CapphysAddrU + pHwDevExt->UoffsetOdd), // Position U data. ((f == 1 ) ? physBase : physAddr + 0x1A), physAddr + 0x19, // Put the read value at the end of the list. lastOneActive, (CAPTURE_ODD | CKRE | CKMD)); // Mod 97-05-08(Thu) lastOneActive = TRUE; } else { // Don't generate interrupts for skipped frames SkipField(pHwDevExt,addr,(DWORD *)((BYTE *)CapphysAddrY + pHwDevExt->YoffsetOdd), ((f == 1 ) ? physBase : physAddr + 0x1A), physAddr + 0x19, // Put the read value at the end of the list. lastOneActive, (SKIP_ODD | CKRE | CKMD)); // Mod 97-05-08(Thu) lastOneActive = FALSE; } addr += 0x1A; physAddr += 0x1A; } return TRUE; } //-------------------------------------------------------------------- // BertSetDMCHE //-------------------------------------------------------------------- VOID BertSetDMCHE(IN PHW_DEVICE_EXTENSION pHwDevExt) { switch(pHwDevExt->dwAsicRev){ case 0: // Pistachio #1 case 1: // Pistachio #2 case 2: // Pistachio #3 WriteRegUlong(pHwDevExt, BERT_P_SUP3_REG, 0x00); break; default: // Pistachio #4~ WriteRegUlong(pHwDevExt, BERT_P_SUP3_REG, 0x0100); break; } } VOID HW_ApmResume(PHW_DEVICE_EXTENSION pHwDevExt) { BertSetDMCHE(pHwDevExt); CameraChkandON(pHwDevExt, MODE_VFW); BertInitializeHardware(pHwDevExt); pHwDevExt->NeedHWInit = TRUE; pHwDevExt->IsRPSReady = FALSE; } VOID HW_ApmSuspend(PHW_DEVICE_EXTENSION pHwDevExt) { BertInterruptEnable(pHwDevExt, FALSE); BertDMAEnable(pHwDevExt, FALSE); pHwDevExt->bRequestDpc = FALSE; CameraChkandOFF(pHwDevExt, MODE_VFW); } VOID HW_SetFilter(PHW_DEVICE_EXTENSION pHwDevExt, BOOL bFlag) { if( bFlag ) { ImageFilterON(pHwDevExt); } else { ImageFilterOFF(pHwDevExt); } } ULONG HW_ReadFilter(PHW_DEVICE_EXTENSION pHwDevExt, BOOL bFlag) { ULONG ulRet; if( bFlag ) { ulRet = ImageGetFilteringAvailable(pHwDevExt); } else { ulRet = ImageGetFilterInfo(pHwDevExt); } return ulRet; } BOOL HWInit(PHW_DEVICE_EXTENSION pHwDevExt) { if (pHwDevExt->NeedHWInit == FALSE) return TRUE; // reset hardware to power up state if ( !BertInitializeHardware(pHwDevExt) ) // MOD 97-03-31(Fri) { return FALSE; } else { pHwDevExt->NeedHWInit = FALSE; } return TRUE; } #ifdef TOSHIBA // '99-01-20 Added //-------------------------------------------------------------------- // InitConfigAddress //-------------------------------------------------------------------- VOID InitConfigAddress( PHW_DEVICE_EXTENSION pHwDevExt ) { ULONG OldPort; ULONG Id; ULONG Data; ULONG i, j; ulConfigAddress = 0xFFFFFFFF; #ifdef TOSHIBA // '99-02-05 Modified return; #else //TOSHIBA if ( CurrentOSType ) return; // NT5.0 if ( !StreamClassReadWriteConfig( pHwDevExt, TRUE, // indicates a READ (PVOID)&Id, 0, // this is the offset into the PCI space 4 // this is the # of bytes to read. )) { return; } if ( Id == 0 || Id == 0xFFFFFFFF ) return; OldPort = READ_PORT_ULONG( (PULONG)0xCF8 ); for ( i = 0 ; i < 256; i++ ) { // PCI_MAX_BRIDGE_NUMBER for ( j = 0 ; j < 32; j++ ) {// PCI_MAX_DEVICE WRITE_PORT_ULONG( (PULONG)0xCF8, (i << 16) | (j << 11) | 0x80000000 ); Data = READ_PORT_ULONG( (PULONG)0xCFC ); if ( Data == Id ) { ulConfigAddress = (i << 16) | (j << 11) | 0x80000000; break; } } if ( Data == Id ) break; } WRITE_PORT_ULONG( (PULONG)0xCF8, OldPort ); #endif//TOSHIBA } #endif//TOSHIBA //-------------------------------------------------------------------- // InitializeConfigDefaults //-------------------------------------------------------------------- VOID InitializeConfigDefaults(PHW_DEVICE_EXTENSION pHwDevExt) { ULONG ImageSize; #ifdef TOSHIBA // '99-01-20 Added InitConfigAddress( pHwDevExt ); #endif//TOSHIBA #ifndef TOSHIBA pHwDevExt->VideoStd = NTSC; #endif//TOSHIBA pHwDevExt->Format = FmtYUV9; pHwDevExt->ulWidth = 320; pHwDevExt->ulHeight = 240; pHwDevExt->MaxRect.right = NTSC_MAX_PIXELS_PER_LINE; pHwDevExt->MaxRect.bottom = NTSC_MAX_LINES_PER_FIELD * 2; // Mod 97-04-08(Tue) pHwDevExt->SrcRect = pHwDevExt->MaxRect; #ifdef TOSHIBA pHwDevExt->Hue = 0x80; pHwDevExt->Contrast = 0x80; pHwDevExt->Brightness = 0x80; pHwDevExt->Saturation = 0x80; ImageSetChangeColorAvail(pHwDevExt, IMAGE_CHGCOL_AVAIL); #else //TOSHIBA pHwDevExt->ulHue = 0x80; pHwDevExt->ulContrast = 0x80; pHwDevExt->ulBrightness = 0x80; pHwDevExt->ulSaturation = 0x80; ImageSetChangeColorAvail(pHwDevExt, IMAGE_CHGCOL_NOTAVAIL); #endif//TOSHIBA } BOOL SetupPCILT( PHW_DEVICE_EXTENSION pHwDevExt ) { BYTE byte_buffer; ULONG ulCommand; #define PCI_LTIME_OFFSET 0x0d /* offset of Latency timer from PCI base */ #define PCI_CACHELINE_OFFSET 0x0c /* offset of cache line size from PCI base */ #define PCI_STATUSorCOMMAND 0x04 /* offset of Pistachio Status and Command regster */ byte_buffer = 255; VC_SetPCIRegister(pHwDevExt, PCI_LTIME_OFFSET, &byte_buffer, 0x01); byte_buffer=(BYTE) 0; VC_SetPCIRegister(pHwDevExt, PCI_CACHELINE_OFFSET, &byte_buffer, 0x01); ulCommand = 0x02000006; VC_SetPCIRegister(pHwDevExt, PCI_STATUSorCOMMAND, &ulCommand, 0x04); ulCommand = IGNORE100msec ; // Set ignore time for chattering VC_SetPCIRegister(pHwDevExt, PCI_Wake_Up, &ulCommand, 0x04); return TRUE; } BOOL CameraChkandON( PHW_DEVICE_EXTENSION pHwDevExt, ULONG ulMode ) { ULONG dd_buffer; if (!VC_GetPCIRegister(pHwDevExt, PCI_Wake_Up, &dd_buffer, 0x04) ) { return FALSE; } if( (dd_buffer&0x10000l) == 0) { return TRUE; } dd_buffer = IGNORE100msec | 0x101l; // Set Wake Up enable if (!VC_SetPCIRegister(pHwDevExt, PCI_Wake_Up, &dd_buffer, 0x04) ) { return FALSE; } switch(ulMode){ case MODE_VFW: dd_buffer = CAVCE_CFGPAT | CADTE_CFGPAT | PXCCE_CFGPAT | PXCSE_CFGPAT | PCIFE_CFGPAT | PCIME_CFGPAT | PCIDS_CFGPAT | GPB_CFGPAT; // Mod 97-05-06(Tue) break; case MODE_ZV: dd_buffer = CAVCE_CFGPAT | CADTE_CFGPAT | PXCCE_CFGPAT | PCIFE_CFGPAT | PCIME_CFGPAT | PCIDS_CFGPAT | GPB_CFGPAT; // Add 97-05-06(Tue) break; } // Power ON to camera. if (!VC_SetPCIRegister(pHwDevExt, PCI_DATA_PATH, &dd_buffer, 0x04) ) { return FALSE; } return TRUE; } BOOL CameraChkandOFF( PHW_DEVICE_EXTENSION pHwDevExt, ULONG ulMode ) { DWORD dwBuffer; DWORD dwSystemWait; // Add 97-05-06(Tue) switch(ulMode){ case MODE_VFW: break; case MODE_ZV: SetZVControl(pHwDevExt, ZV_DISABLE); break; } dwBuffer = GPB_CFGPAT; // Camera Power Off if (!VC_SetPCIRegister(pHwDevExt, PCI_CFGPAT, &dwBuffer, 0x04) ) { return FALSE; } return TRUE; } BOOL CheckCameraStatus(PHW_DEVICE_EXTENSION pHwDevExt) // Add 97-05-06(Tue) { DWORD dwBuffer; BOOL crStatus; if (!VC_GetPCIRegister(pHwDevExt, PCI_CFGPAT, &dwBuffer, 0x04) ) { return FALSE; } if(dwBuffer & CAVCE_CFGPAT){ crStatus = TRUE; } else{ crStatus = FALSE; } return crStatus; } BOOL SetZVControl(PHW_DEVICE_EXTENSION pHwDevExt, ULONG ulZVStatus) // Add 97-05-02(Fri) { DWORD dwBuffer, dwBuffer2; BOOL crStatus = TRUE; if (!VC_GetPCIRegister(pHwDevExt, PCI_CFGPAT, &dwBuffer, 0x04) ) { return FALSE; } if (!VC_GetPCIRegister(pHwDevExt, PCI_CFGWAK, &dwBuffer2, 0x04) ) { return FALSE; } if(!(dwBuffer2 & CASL_CFGWAK)) // Camera Not Connect { return FALSE; } switch(ulZVStatus){ case ZV_ENABLE: if(!(dwBuffer & CAVCE_CFGPAT)){ // Check CAVCE Status crStatus = CameraChkandON(pHwDevExt, MODE_ZV); if(!crStatus){ return FALSE; } } case ZV_DISABLE: dwBuffer = (dwBuffer & 0xfffffffe) | ulZVStatus; if (!VC_SetPCIRegister(pHwDevExt, PCI_CFGPAT, &dwBuffer, 0x04) ) { return FALSE; } crStatus = TRUE; break; case ZV_GETSTATUS: if(dwBuffer & ZV_ENABLE){ crStatus = TRUE; } else{ crStatus = FALSE; } break; } return crStatus; } BOOL SetASICRev(PHW_DEVICE_EXTENSION pHwDevExt) // Add 97-05-12(Mon) { DWORD dwBuffer; DWORD dwAsicRev; if (!VC_GetPCIRegister(pHwDevExt, PCI_CFGCCR, &dwBuffer, 0x04) ) { return FALSE; } dwAsicRev = dwBuffer & 0x0f; pHwDevExt->dwAsicRev = dwAsicRev; return TRUE; } BOOL Alloc_TriBuffer(PHW_DEVICE_EXTENSION pHwDevExt) { ULONG ulSize; PUCHAR puTemp; ulSize = pHwDevExt->BufferSize; puTemp = (PUCHAR)pHwDevExt->pCaptureBufferY; pHwDevExt->pCapBuf2Y = puTemp + ulSize; puTemp = (PUCHAR)pHwDevExt->pCaptureBufferU; pHwDevExt->pCapBuf2U = puTemp + ulSize; puTemp = (PUCHAR)pHwDevExt->pCaptureBufferV; pHwDevExt->pCapBuf2V = puTemp + ulSize; pHwDevExt->pPhysCapBuf2Y.LowPart = pHwDevExt->pPhysCaptureBufferY.LowPart + ulSize; pHwDevExt->pPhysCapBuf2U.LowPart = pHwDevExt->pPhysCaptureBufferU.LowPart + ulSize; pHwDevExt->pPhysCapBuf2V.LowPart = pHwDevExt->pPhysCaptureBufferV.LowPart + ulSize; return TRUE; } BOOL Free_TriBuffer(PHW_DEVICE_EXTENSION pHwDevExt) { pHwDevExt->pCapBuf2Y = NULL; pHwDevExt->pCapBuf2U = NULL; pHwDevExt->pCapBuf2V = NULL; pHwDevExt->pPhysCapBuf2Y.LowPart = 0; pHwDevExt->pPhysCapBuf2U.LowPart = 0; pHwDevExt->pPhysCapBuf2V.LowPart = 0; return TRUE; } BOOL VC_GetPCIRegister( PHW_DEVICE_EXTENSION pHwDevExt, ULONG ulOffset, PVOID pData, ULONG ulLength) { #ifdef TOSHIBA // '99-01-20 Added if( ulConfigAddress != 0xFFFFFFFF ) { ULONG OldPort; ULONG DataPort; OldPort = READ_PORT_ULONG( (PULONG)0xCF8 ); WRITE_PORT_ULONG( (PULONG)0xCF8, ( ulConfigAddress | ulOffset) & 0xFFFFFFFC ); DataPort = 0xCFC + (ulOffset % 4); switch ( ulLength ) { case 1: *((PUCHAR)pData) = READ_PORT_UCHAR( (PUCHAR)DataPort ); break; case 2: *((PUSHORT)pData) = READ_PORT_USHORT( (PUSHORT)DataPort ); break; case 4: *((PULONG)pData) = READ_PORT_ULONG( (PULONG)DataPort ); break; } WRITE_PORT_ULONG( (PULONG)0xCF8, OldPort ); return TRUE; } #endif//TOSHIBA if( StreamClassReadWriteConfig( pHwDevExt, TRUE, // indicates a READ pData, ulOffset, // this is the offset into the PCI space ulLength // this is the # of bytes to read. )) { return TRUE; } else { return FALSE; } } BOOL VC_SetPCIRegister( PHW_DEVICE_EXTENSION pHwDevExt, ULONG ulOffset, PVOID pData, ULONG ulLength) { #ifdef TOSHIBA // '99-01-20 Added if( ulConfigAddress != 0xFFFFFFFF ) { ULONG OldPort; ULONG DataPort; OldPort = READ_PORT_ULONG( (PULONG)0xCF8 ); WRITE_PORT_ULONG( (PULONG)0xCF8, ( ulConfigAddress | ulOffset) & 0xFFFFFFFC ); DataPort = 0xCFC + (ulOffset % 4); switch ( ulLength ) { case 1: WRITE_PORT_UCHAR( (PUCHAR)DataPort, *((PUCHAR)pData) ); break; case 2: WRITE_PORT_USHORT( (PUSHORT)DataPort, *((PUSHORT)pData) ); break; case 4: WRITE_PORT_ULONG( (PULONG)DataPort, *((PULONG)pData) ); break; } WRITE_PORT_ULONG( (PULONG)0xCF8, OldPort ); return TRUE; } #endif//TOSHIBA if( StreamClassReadWriteConfig( pHwDevExt, FALSE, // indicates a WRITE pData, ulOffset, // this is the offset into the PCI space ulLength // this is the # of bytes to read. )) { return TRUE; } else { return FALSE; } } /* * delay for a number of milliseconds. This is accurate only to * +- 15msecs at best. */ VOID VC_Delay(int nMillisecs) { LARGE_INTEGER Delay; /* * relative times are negative, in units of 100 nanosecs */ // first wait for the minimum length of time - this ensures that // our wait is never less than nMillisecs. Delay = RtlConvertLongToLargeInteger(-1); KeDelayExecutionThread(KernelMode, FALSE, //non-alertable &Delay); // now wait for the requested time. Delay = RtlConvertLongToLargeInteger(-(nMillisecs * 10000)); KeDelayExecutionThread(KernelMode, FALSE, //non-alertable &Delay); } #if DBG void DbgDumpPciRegister( PHW_DEVICE_EXTENSION pHwDevExt ) { ULONG i; ULONG data; DbgPrint("\n+++++ PCI Config Register +++++\n"); for( i=0; i<0x48; i+=4 ) { if (VC_GetPCIRegister(pHwDevExt, i, &data, 0x04) ) { DbgPrint("0x%02X: 0x%08X\n", i, data); } else { DbgPrint("0x%02X: Read Error.\n", i); } } } void DbgDumpCaptureRegister( PHW_DEVICE_EXTENSION pHwDevExt ) { ULONG i; ULONG data; DbgPrint("\n+++++ Capture Register +++++\n"); for( i=0; i<0xA4; i+=4 ) { data = ReadRegUlong(pHwDevExt, i); DbgPrint("0x%02X: 0x%08X\n", i, data); } } #endif