Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1192 lines
34 KiB

  1. //
  2. // TOSHIBA CORPORATION PROPRIETARY INFORMATION
  3. // This software is supplied under the terms of a license agreement or
  4. // nondisclosure agreement with TOSHIBA Corporation and may not be copied
  5. // or disclosed except in accordance with the terms of that agreement.
  6. // Copyright (c) 1997 TOSHIBA Corporation. All Rights Reserved.
  7. //
  8. // Workfile: BERT.C
  9. //
  10. // Purpose:
  11. //
  12. // Contents:
  13. //
  14. #include "strmini.h"
  15. #include "ksmedia.h"
  16. #include "capmain.h"
  17. #include "capdebug.h"
  18. #include "bert.h"
  19. #include "image.h"
  20. #ifdef TOSHIBA // '99-01-20 Added
  21. extern ULONG CurrentOSType;
  22. ULONG ulConfigAddress;
  23. #endif//TOSHIBA
  24. //--------------------------------------------------------------------
  25. // ReadRegUlong
  26. //--------------------------------------------------------------------
  27. ULONG
  28. ReadRegUlong(PHW_DEVICE_EXTENSION pHwDevExt, ULONG offset)
  29. {
  30. PUCHAR pBase = (PUCHAR)(pHwDevExt->ioBaseLocal);
  31. #ifndef TOSHIBA
  32. if (!pHwDevExt->IsCardIn) return 0L;
  33. #endif//TOSHIBA
  34. return *(PULONG)(pBase + offset);
  35. }
  36. //--------------------------------------------------------------------
  37. // WriteRegUlong
  38. //--------------------------------------------------------------------
  39. VOID
  40. WriteRegUlong(PHW_DEVICE_EXTENSION pHwDevExt, ULONG offset, ULONG data)
  41. {
  42. ULONG volatile *temp;
  43. PUCHAR pBase = (PUCHAR)(pHwDevExt->ioBaseLocal);
  44. #ifndef TOSHIBA
  45. if (!pHwDevExt->IsCardIn) return;
  46. #endif//TOSHIBA
  47. temp = (PULONG)(pBase + offset);
  48. *temp = data;
  49. }
  50. //--------------------------------------------------------------------
  51. // ReadModifyWriteRegUlong
  52. //--------------------------------------------------------------------
  53. VOID
  54. ReadModifyWriteRegUlong(PHW_DEVICE_EXTENSION pHwDevExt,
  55. ULONG offset,
  56. ULONG a_mask,
  57. ULONG o_mask)
  58. {
  59. ULONG tdata;
  60. ULONG volatile *temp;
  61. PUCHAR pBase = (PUCHAR)(pHwDevExt->ioBaseLocal);
  62. #ifndef TOSHIBA
  63. if (!pHwDevExt->IsCardIn) return;
  64. #endif//TOSHIBA
  65. temp = (PULONG)(pBase + offset);
  66. tdata = *temp;
  67. tdata = (tdata & a_mask) | o_mask;
  68. *temp = tdata;
  69. }
  70. BOOL
  71. BertIsCardIn(
  72. IN PHW_DEVICE_EXTENSION pHwDevExt
  73. )
  74. {
  75. DWORD value;
  76. value = ReadRegUlong(pHwDevExt, BERT_CAPSTAT_REG);
  77. if ((value == 0) || (value == 0xffffffff))
  78. return FALSE;
  79. else
  80. return TRUE;
  81. }
  82. //--------------------------------------------------------------------
  83. // BertInterruptEnable
  84. //--------------------------------------------------------------------
  85. VOID
  86. BertInterruptEnable(
  87. IN PHW_DEVICE_EXTENSION pHwDevExt,
  88. IN BOOL bStatus
  89. )
  90. {
  91. WriteRegUlong(pHwDevExt, BERT_INTRST_REG , 0xFFFF);
  92. if (!bStatus)
  93. {
  94. ReadModifyWriteRegUlong(pHwDevExt, BERT_INTSTAT_REG, (ULONG)~ACTIVE_CAPTURE_IRQS, 0);
  95. }
  96. else
  97. {
  98. ReadModifyWriteRegUlong(pHwDevExt, BERT_INTSTAT_REG, ~0UL, (ULONG)ACTIVE_CAPTURE_IRQS);
  99. }
  100. }
  101. //--------------------------------------------------------------------
  102. // BertDMAEnable
  103. //--------------------------------------------------------------------
  104. VOID
  105. BertDMAEnable(
  106. IN PHW_DEVICE_EXTENSION pHwDevExt,
  107. IN BOOL bStatus
  108. )
  109. {
  110. DWORD dwAddr;
  111. if (bStatus) // Turn On Video Transfer.
  112. {
  113. dwAddr = (DWORD)pHwDevExt->pPhysRpsDMABuf.LowPart;
  114. #if 0
  115. dwAddr = (dwAddr + 0x1FFF) & 0xFFFFE000;
  116. #endif
  117. WriteRegUlong(pHwDevExt, BERT_RPSADR_REG, dwAddr);
  118. WriteRegUlong(pHwDevExt, BERT_RPSPAGE_REG, dwAddr);
  119. BertVsncSignalWait(pHwDevExt);
  120. // Let the RPS turn on/off EBMV
  121. WriteRegUlong(pHwDevExt, BERT_CAPSTAT_REG, (ERPS | CKRE | CKMD)); // mod passive_enable -> ERPS 97-03-15(Sat) Mod 97-05-08(Thu)
  122. }
  123. else // Turn Off Video Transfer.
  124. {
  125. if (ReadRegUlong(pHwDevExt, BERT_CAPSTAT_REG) & ERPS)
  126. {
  127. ReadModifyWriteRegUlong(pHwDevExt, BERT_CAPSTAT_REG, (ULONG)~ERPS, 0UL);
  128. }
  129. if (!BertIsCAPSTATReady(pHwDevExt))
  130. {
  131. ReadModifyWriteRegUlong(pHwDevExt, BERT_CAPSTAT_REG, (ULONG)~EBMV, 0UL);
  132. }
  133. if (ReadRegUlong(pHwDevExt, BERT_CAPSTAT_REG) & RPSS)
  134. {
  135. pHwDevExt->NeedHWInit = TRUE;
  136. }
  137. }
  138. }
  139. //--------------------------------------------------------------------
  140. // BertIsLocked
  141. //--------------------------------------------------------------------
  142. BOOL
  143. BertIsLocked(
  144. IN PHW_DEVICE_EXTENSION pHwDevExt
  145. )
  146. /*++
  147. Routine Description :
  148. Check if the decoder has been locked or not.
  149. Arguments :
  150. pDevInfo - Device Info for the driver
  151. Return Value :
  152. TRUE - configuration success
  153. --*/
  154. {
  155. return ((ReadRegUlong(pHwDevExt, BERT_CAPSTAT_REG) & LOCK) != 0);
  156. }
  157. //--------------------------------------------------------------------
  158. // BertFifoConfig
  159. //--------------------------------------------------------------------
  160. BOOL
  161. BertFifoConfig(
  162. IN PHW_DEVICE_EXTENSION pHwDevExt,
  163. IN ULONG ulFormat
  164. )
  165. /*++
  166. Routine Description :
  167. Configure the BERT fifo for the format choosen.
  168. Arguments :
  169. pDevInfo - Device Info for the driver
  170. dwFormat - format index as defined in wally.h
  171. Return Value :
  172. TRUE - configuration success
  173. --*/
  174. {
  175. DWORD dwFifo;
  176. switch (ulFormat)
  177. {
  178. case FmtYUV12:
  179. dwFifo = 0xe;
  180. break;
  181. case FmtYUV9:
  182. dwFifo = 0xd;
  183. break;
  184. default:
  185. return FALSE;
  186. }
  187. dwFifo=(dwFifo<<24)| 0x100000l; // Modify 97-04-02
  188. WriteRegUlong(pHwDevExt, BERT_FIFOCFG_REG, dwFifo);
  189. WriteRegUlong(pHwDevExt, BERT_BURST_LEN, 0x00000002);
  190. // DATA=8 DWORD, RPS=2DWORD
  191. WriteRegUlong(pHwDevExt, BERT_YSTRIDE_REG, pHwDevExt->Ystride);
  192. WriteRegUlong(pHwDevExt, BERT_USTRIDE_REG, pHwDevExt->Ustride);
  193. WriteRegUlong(pHwDevExt, BERT_VSTRIDE_REG, pHwDevExt->Vstride);
  194. return TRUE;
  195. }
  196. //--------------------------------------------------------------------
  197. // BertInitializeHardware
  198. //--------------------------------------------------------------------
  199. BOOL
  200. BertInitializeHardware(
  201. IN PHW_DEVICE_EXTENSION pHwDevExt
  202. )
  203. /*++
  204. Routine Description :
  205. This function initializes the bert asic to the default values.
  206. Arguments :
  207. pDevInfo - Device Info for the driver
  208. pHw - pointer to hardware info data structure
  209. Return Value :
  210. TRUE - initialization success
  211. --*/
  212. {
  213. WriteRegUlong(pHwDevExt, BERT_CAPSTAT_REG, (CAMARA_OFF | CKRE | CKMD)); // Mod 97-05-08(Thu)
  214. return TRUE;
  215. }
  216. //--------------------------------------------------------------------
  217. // BertEnableRps
  218. //--------------------------------------------------------------------
  219. VOID
  220. BertEnableRps(
  221. IN PHW_DEVICE_EXTENSION pHwDevExt
  222. )
  223. /*++
  224. Routine Description :
  225. enable the rps execution by setting ERPS and EROO bits
  226. in the CAPSTAT reg
  227. Arguments :
  228. pDevInfo - Device Info for the driver
  229. Return Value :
  230. None
  231. --*/
  232. {
  233. ReadModifyWriteRegUlong(pHwDevExt, BERT_CAPSTAT_REG, 0xf0ffffff, 0x08000000); // MOD 97-03-17(Mon)
  234. }
  235. //--------------------------------------------------------------------
  236. // BertDisableRps
  237. //--------------------------------------------------------------------
  238. VOID
  239. BertDisableRps(
  240. IN PHW_DEVICE_EXTENSION pHwDevExt
  241. )
  242. /*++
  243. Routine Description :
  244. disable the rps execution by reseting the ERPS bit
  245. in the CAPSTAT reg
  246. Arguments :
  247. pDevInfo - Device Info for the driver
  248. Return Value :
  249. None
  250. --*/
  251. {
  252. ReadModifyWriteRegUlong(pHwDevExt, BERT_CAPSTAT_REG, (ULONG)~ERPS, 0L);
  253. }
  254. BOOL
  255. BertIsCAPSTATReady(PHW_DEVICE_EXTENSION pHwDevExt)
  256. {
  257. LARGE_INTEGER CurrentTime;
  258. LARGE_INTEGER StartTime;
  259. KeQuerySystemTime( &StartTime );
  260. // Wait until EBMV is cleared by the RPS
  261. while (ReadRegUlong(pHwDevExt, BERT_CAPSTAT_REG) & EBMV)
  262. {
  263. KeQuerySystemTime( &CurrentTime );
  264. if ((CurrentTime.QuadPart - StartTime.QuadPart) > EBMV_TIMEOUT)
  265. {
  266. return FALSE;
  267. }
  268. }
  269. return TRUE;
  270. }
  271. VOID
  272. BertVsncSignalWait(PHW_DEVICE_EXTENSION pHwDevExt)
  273. {
  274. ULONG ulCount;
  275. // Wait until VSNC is low
  276. for (ulCount = 0; ulCount < 500; ulCount++ )
  277. {
  278. if (!(ReadRegUlong(pHwDevExt, BERT_VINSTAT_REG) & VSNC)) break;
  279. VC_Delay(2);
  280. }
  281. }
  282. VOID
  283. BertDMARestart(
  284. IN PHW_DEVICE_EXTENSION pHwDevExt
  285. )
  286. {
  287. DWORD dwAddr;
  288. dwAddr = (DWORD)pHwDevExt->pPhysRpsDMABuf.LowPart;
  289. #if 0
  290. dwAddr = (dwAddr + 0x1FFF) & 0xFFFFE000;
  291. #endif
  292. WriteRegUlong(pHwDevExt, BERT_RPSADR_REG, dwAddr);
  293. WriteRegUlong(pHwDevExt, BERT_RPSPAGE_REG, dwAddr);
  294. WriteRegUlong(pHwDevExt, BERT_CAPSTAT_REG, (ERPS | CKRE | CKMD));
  295. }
  296. void
  297. ActiveField(
  298. IN PHW_DEVICE_EXTENSION pHwDevExt,
  299. IN DWORD *addr,
  300. IN DWORD *PhysAddr, /* Insert BUN 97-03-25(Tue) */
  301. IN DWORD bNoCopy,
  302. IN DWORD *y_DMA_addr,
  303. IN DWORD *v_DMA_addr,
  304. IN DWORD *u_DMA_addr,
  305. IN DWORD *nextRPSaddr,
  306. IN DWORD *readRegAddr,
  307. IN BOOL genIRQ /* = FALSE */,
  308. IN DWORD fieldsToCapture /* = CAPTURE_BOTH */ )
  309. {
  310. // Set DmaActive flag right away since this is the indicator register for whether DMA is pending.
  311. // If the DmaActive flag is zero, it is safe to copy the DMA frame buffer. The YPTR register is
  312. // used as a scratch register to be read into the DmaActive flag.
  313. *addr++ = RPS_CONTINUE_CMD | BERT_YPTR_REG;
  314. *addr++ = (DWORD)y_DMA_addr; // Address of y DMA buffer.
  315. *addr++ = RPS_CONTINUE_CMD | ((genIRQ) ? RPS_INT_CMD : 0) | BERT_RPSPAGE_REG;
  316. *addr++ = (pHwDevExt->s_physDmaActiveFlag-0x1860); // Page s_DmaActiveFlag is on mod BUN
  317. *addr++ = RPS_CONTINUE_CMD | BERT_VPTR_REG;
  318. *addr++ = (DWORD)v_DMA_addr; // Address of v DMA buffer.
  319. *addr++ = RPS_CONTINUE_CMD | BERT_UPTR_REG;
  320. *addr++ = (DWORD)u_DMA_addr; // Address of u DMA buffer.
  321. *addr++ = BERT_CAPSTAT_REG; // LAST RPS command this VSYNC
  322. *addr++ = fieldsToCapture; // Switch on bus master bit.
  323. *addr++ = RPS_CONTINUE_CMD | BERT_RPSADR_REG;
  324. *addr = (DWORD)nextRPSaddr; // Address of next RPS.
  325. }
  326. //
  327. // SKIP_FIELD_RPS is the size of a RPS node that skips a field.
  328. // Skip frame is programmed as follows:
  329. // DWORD -- RPS command register
  330. // DWORD -- Value of register programming.
  331. //---------------- Actual RPS for Skip Frame ------------------------
  332. // RPS_CONTINUE_CMD | CAPSTAT - RPS, read next RPS, select CAPSTAT
  333. // ERPS | EROO | GO0 - Enable RPS & Power to camara (off bus master)
  334. // INTSTAT - Don't continue & select INITSTAT register.
  335. // m_passive_cap_IRQs - Don't interrupt end of field.
  336. // RPS_CONTINUE_CMD | RPSADDR - Set up address
  337. // Address field - Program at init for next field.
  338. //-------------------------------------------------------------------
  339. //
  340. VOID
  341. SkipField(
  342. IN PHW_DEVICE_EXTENSION pHwDevExt,
  343. IN DWORD *addr,
  344. IN DWORD *PhysAddr, /* Insert BUN 97-03-25(Tue) */
  345. IN DWORD *nextRPSaddr,
  346. IN DWORD *readRegAddr,
  347. IN BOOL genIRQ /* = FALSE */,
  348. IN DWORD fieldToSkip /* = SKIP_BOTH */ )
  349. {
  350. // Set YPTR right away since this is the indicator register for whether DMA is pending.
  351. // If DmaActive flag is zero, it is safe to copy the DMA frame buffer.
  352. *addr++ = RPS_CONTINUE_CMD | BERT_YPTR_REG;
  353. *addr++ = (DWORD)PhysAddr;
  354. *addr++ = RPS_CONTINUE_CMD | ((genIRQ) ? RPS_INT_CMD : 0) | BERT_RPSPAGE_REG;
  355. *addr++ = (pHwDevExt->s_physDmaActiveFlag-0x1860); // Page s_physDmaActiveFlag is on MOD bun
  356. *addr++ = BERT_CAPSTAT_REG; /* mod BUN 97-04-16(Wed) */
  357. *addr++ = fieldToSkip; // Switch off bus master bit.
  358. *addr++ = RPS_CONTINUE_CMD | BERT_RPSADR_REG;
  359. *addr = (DWORD)nextRPSaddr; // Address of next RPS.
  360. }
  361. BOOL
  362. BertBuildNodes(
  363. IN PHW_DEVICE_EXTENSION pHwDevExt
  364. )
  365. {
  366. DWORD* addr;
  367. DWORD* physAddr;
  368. DWORD* physBase;
  369. ULONG ulTemp;
  370. unsigned framesPerSecond;
  371. unsigned f;
  372. unsigned max_rps;
  373. BOOL lastOneActive = FALSE;
  374. framesPerSecond = pHwDevExt->uiFramePerSecond;
  375. max_rps = DEF_RPS_FRAMES;
  376. ulTemp = (ULONG)pHwDevExt->pRpsDMABuf;
  377. #if 0
  378. ulTemp = (ulTemp + 0x1FFF) & 0xFFFFE000;
  379. #endif
  380. addr = (DWORD *)ulTemp;
  381. ulTemp = (ULONG)pHwDevExt->pPhysRpsDMABuf.LowPart;
  382. #if 0
  383. ulTemp = (ulTemp + 0x1FFF) & 0xFFFFE000;
  384. #endif
  385. physAddr = (DWORD *)ulTemp;
  386. physBase = physAddr;
  387. if (addr == NULL) return FALSE;
  388. // Build an RPS per frame.
  389. // Building 2 nodes per iteration when capturing both fields, so always
  390. // go thru only DEF_RPS_FRAMES iterations.
  391. for (f = max_rps ; f >= 1 ; f-- )
  392. {
  393. if (((framesPerSecond * f) % DEF_RPS_FRAMES) < framesPerSecond)
  394. {
  395. ActiveField(pHwDevExt,addr,(DWORD *)0,
  396. TRUE, // No buffer copying during the processing of this node
  397. (DWORD *)((BYTE *)pHwDevExt->pPhysCaptureBufferY.LowPart + pHwDevExt->YoffsetOdd), // Position Y data.
  398. (DWORD *)((BYTE *)pHwDevExt->pPhysCaptureBufferV.LowPart + pHwDevExt->VoffsetOdd), // Position V data.
  399. (DWORD *)((BYTE *)pHwDevExt->pPhysCaptureBufferU.LowPart + pHwDevExt->UoffsetOdd), // Position U data.
  400. ((f == 1 )
  401. ? physBase
  402. : physAddr + 0x1A),
  403. physAddr + 0x19, // Put the read value at the end of the list.
  404. lastOneActive,
  405. (CAPTURE_ODD | CKRE | CKMD)); // Mod 97-05-08(Thu)
  406. lastOneActive = TRUE;
  407. }
  408. else
  409. {
  410. // Don't generate interrupts for skipped frames
  411. SkipField(pHwDevExt,addr,
  412. (DWORD *)((BYTE *)pHwDevExt->pPhysCapBuf2Y.LowPart + pHwDevExt->YoffsetOdd),
  413. ((f == 1 )
  414. ? physBase
  415. : physAddr + 0x1A),
  416. physAddr + 0x19, // Put the read value at the end of the list.
  417. lastOneActive,
  418. (SKIP_ODD | CKRE | CKMD)); // Mod 97-05-08(Thu)
  419. lastOneActive = FALSE;
  420. }
  421. addr += 0x1A;
  422. physAddr += 0x1A;
  423. }
  424. return TRUE;
  425. }
  426. BOOL
  427. BertTriBuildNodes(
  428. IN PHW_DEVICE_EXTENSION pHwDevExt
  429. )
  430. {
  431. DWORD* addr;
  432. DWORD* physAddr;
  433. DWORD* physBase;
  434. ULONG ulTemp;
  435. unsigned framesPerSecond;
  436. unsigned f;
  437. unsigned max_rps;
  438. BOOL lastOneActive = FALSE;
  439. DWORD* CapphysAddrY;
  440. DWORD* CapphysAddrV;
  441. DWORD* CapphysAddrU;
  442. framesPerSecond = pHwDevExt->uiFramePerSecond;
  443. max_rps = DEF_RPS_FRAMES;
  444. ulTemp = (ULONG)pHwDevExt->pRpsDMABuf;
  445. #if 0
  446. ulTemp = (ulTemp + 0x1FFF) & 0xFFFFE000;
  447. #endif
  448. addr = (DWORD *)ulTemp;
  449. ulTemp = (ULONG)pHwDevExt->pPhysRpsDMABuf.LowPart;
  450. #if 0
  451. ulTemp = (ulTemp + 0x1FFF) & 0xFFFFE000;
  452. #endif
  453. physAddr = (DWORD *)ulTemp;
  454. physBase = physAddr;
  455. if (addr == NULL) return FALSE;
  456. // Build an RPS per frame.
  457. // Building 2 nodes per iteration when capturing both fields, so always
  458. // go thru only DEF_RPS_FRAMES iterations.
  459. lastOneActive = ( ((framesPerSecond*1)%DEF_RPS_FRAMES) < framesPerSecond ) ? TRUE : FALSE ;
  460. for (f = max_rps ; f >= 1 ; f-- )
  461. {
  462. if( f%2 ){
  463. CapphysAddrY=(DWORD *)pHwDevExt->pPhysCapBuf2Y.LowPart;
  464. CapphysAddrV=(DWORD *)pHwDevExt->pPhysCapBuf2V.LowPart;
  465. CapphysAddrU=(DWORD *)pHwDevExt->pPhysCapBuf2U.LowPart;
  466. }
  467. else{
  468. CapphysAddrY=(DWORD *)pHwDevExt->pPhysCaptureBufferY.LowPart;
  469. CapphysAddrV=(DWORD *)pHwDevExt->pPhysCaptureBufferV.LowPart;
  470. CapphysAddrU=(DWORD *)pHwDevExt->pPhysCaptureBufferU.LowPart;
  471. }
  472. if (((framesPerSecond * f) % DEF_RPS_FRAMES) < framesPerSecond)
  473. {
  474. ActiveField(pHwDevExt,addr,(DWORD *)0,
  475. TRUE, // No buffer copying during the processing of this node
  476. (DWORD *)((BYTE *)CapphysAddrY + pHwDevExt->YoffsetOdd), // Position Y data.
  477. (DWORD *)((BYTE *)CapphysAddrV + pHwDevExt->VoffsetOdd), // Position V data.
  478. (DWORD *)((BYTE *)CapphysAddrU + pHwDevExt->UoffsetOdd), // Position U data.
  479. ((f == 1 )
  480. ? physBase
  481. : physAddr + 0x1A),
  482. physAddr + 0x19, // Put the read value at the end of the list.
  483. lastOneActive,
  484. (CAPTURE_ODD | CKRE | CKMD)); // Mod 97-05-08(Thu)
  485. lastOneActive = TRUE;
  486. }
  487. else
  488. {
  489. // Don't generate interrupts for skipped frames
  490. SkipField(pHwDevExt,addr,(DWORD *)((BYTE *)CapphysAddrY + pHwDevExt->YoffsetOdd),
  491. ((f == 1 )
  492. ? physBase
  493. : physAddr + 0x1A),
  494. physAddr + 0x19, // Put the read value at the end of the list.
  495. lastOneActive,
  496. (SKIP_ODD | CKRE | CKMD)); // Mod 97-05-08(Thu)
  497. lastOneActive = FALSE;
  498. }
  499. addr += 0x1A;
  500. physAddr += 0x1A;
  501. }
  502. return TRUE;
  503. }
  504. //--------------------------------------------------------------------
  505. // BertSetDMCHE
  506. //--------------------------------------------------------------------
  507. VOID
  508. BertSetDMCHE(IN PHW_DEVICE_EXTENSION pHwDevExt)
  509. {
  510. switch(pHwDevExt->dwAsicRev){
  511. case 0: // Pistachio #1
  512. case 1: // Pistachio #2
  513. case 2: // Pistachio #3
  514. WriteRegUlong(pHwDevExt, BERT_P_SUP3_REG, 0x00);
  515. break;
  516. default: // Pistachio #4~
  517. WriteRegUlong(pHwDevExt, BERT_P_SUP3_REG, 0x0100);
  518. break;
  519. }
  520. }
  521. VOID
  522. HW_ApmResume(PHW_DEVICE_EXTENSION pHwDevExt)
  523. {
  524. BertSetDMCHE(pHwDevExt);
  525. CameraChkandON(pHwDevExt, MODE_VFW);
  526. BertInitializeHardware(pHwDevExt);
  527. pHwDevExt->NeedHWInit = TRUE;
  528. pHwDevExt->IsRPSReady = FALSE;
  529. }
  530. VOID
  531. HW_ApmSuspend(PHW_DEVICE_EXTENSION pHwDevExt)
  532. {
  533. BertInterruptEnable(pHwDevExt, FALSE);
  534. BertDMAEnable(pHwDevExt, FALSE);
  535. pHwDevExt->bRequestDpc = FALSE;
  536. CameraChkandOFF(pHwDevExt, MODE_VFW);
  537. }
  538. VOID
  539. HW_SetFilter(PHW_DEVICE_EXTENSION pHwDevExt, BOOL bFlag)
  540. {
  541. if( bFlag )
  542. {
  543. ImageFilterON(pHwDevExt);
  544. }
  545. else
  546. {
  547. ImageFilterOFF(pHwDevExt);
  548. }
  549. }
  550. ULONG
  551. HW_ReadFilter(PHW_DEVICE_EXTENSION pHwDevExt, BOOL bFlag)
  552. {
  553. ULONG ulRet;
  554. if( bFlag )
  555. {
  556. ulRet = ImageGetFilteringAvailable(pHwDevExt);
  557. }
  558. else
  559. {
  560. ulRet = ImageGetFilterInfo(pHwDevExt);
  561. }
  562. return ulRet;
  563. }
  564. BOOL
  565. HWInit(PHW_DEVICE_EXTENSION pHwDevExt)
  566. {
  567. if (pHwDevExt->NeedHWInit == FALSE) return TRUE;
  568. // reset hardware to power up state
  569. if ( !BertInitializeHardware(pHwDevExt) ) // MOD 97-03-31(Fri)
  570. {
  571. return FALSE;
  572. }
  573. else
  574. {
  575. pHwDevExt->NeedHWInit = FALSE;
  576. }
  577. return TRUE;
  578. }
  579. #ifdef TOSHIBA // '99-01-20 Added
  580. //--------------------------------------------------------------------
  581. // InitConfigAddress
  582. //--------------------------------------------------------------------
  583. VOID
  584. InitConfigAddress( PHW_DEVICE_EXTENSION pHwDevExt )
  585. {
  586. ULONG OldPort;
  587. ULONG Id;
  588. ULONG Data;
  589. ULONG i, j;
  590. ulConfigAddress = 0xFFFFFFFF;
  591. #ifdef TOSHIBA // '99-02-05 Modified
  592. return;
  593. #else //TOSHIBA
  594. if ( CurrentOSType ) return; // NT5.0
  595. if ( !StreamClassReadWriteConfig(
  596. pHwDevExt,
  597. TRUE, // indicates a READ
  598. (PVOID)&Id,
  599. 0, // this is the offset into the PCI space
  600. 4 // this is the # of bytes to read.
  601. )) {
  602. return;
  603. }
  604. if ( Id == 0 || Id == 0xFFFFFFFF ) return;
  605. OldPort = READ_PORT_ULONG( (PULONG)0xCF8 );
  606. for ( i = 0 ; i < 256; i++ ) { // PCI_MAX_BRIDGE_NUMBER
  607. for ( j = 0 ; j < 32; j++ ) {// PCI_MAX_DEVICE
  608. WRITE_PORT_ULONG( (PULONG)0xCF8, (i << 16) | (j << 11) | 0x80000000 );
  609. Data = READ_PORT_ULONG( (PULONG)0xCFC );
  610. if ( Data == Id ) {
  611. ulConfigAddress = (i << 16) | (j << 11) | 0x80000000;
  612. break;
  613. }
  614. }
  615. if ( Data == Id ) break;
  616. }
  617. WRITE_PORT_ULONG( (PULONG)0xCF8, OldPort );
  618. #endif//TOSHIBA
  619. }
  620. #endif//TOSHIBA
  621. //--------------------------------------------------------------------
  622. // InitializeConfigDefaults
  623. //--------------------------------------------------------------------
  624. VOID
  625. InitializeConfigDefaults(PHW_DEVICE_EXTENSION pHwDevExt)
  626. {
  627. ULONG ImageSize;
  628. #ifdef TOSHIBA // '99-01-20 Added
  629. InitConfigAddress( pHwDevExt );
  630. #endif//TOSHIBA
  631. #ifndef TOSHIBA
  632. pHwDevExt->VideoStd = NTSC;
  633. #endif//TOSHIBA
  634. pHwDevExt->Format = FmtYUV9;
  635. pHwDevExt->ulWidth = 320;
  636. pHwDevExt->ulHeight = 240;
  637. pHwDevExt->MaxRect.right = NTSC_MAX_PIXELS_PER_LINE;
  638. pHwDevExt->MaxRect.bottom = NTSC_MAX_LINES_PER_FIELD * 2; // Mod 97-04-08(Tue)
  639. pHwDevExt->SrcRect = pHwDevExt->MaxRect;
  640. #ifdef TOSHIBA
  641. pHwDevExt->Hue = 0x80;
  642. pHwDevExt->Contrast = 0x80;
  643. pHwDevExt->Brightness = 0x80;
  644. pHwDevExt->Saturation = 0x80;
  645. ImageSetChangeColorAvail(pHwDevExt, IMAGE_CHGCOL_AVAIL);
  646. #else //TOSHIBA
  647. pHwDevExt->ulHue = 0x80;
  648. pHwDevExt->ulContrast = 0x80;
  649. pHwDevExt->ulBrightness = 0x80;
  650. pHwDevExt->ulSaturation = 0x80;
  651. ImageSetChangeColorAvail(pHwDevExt, IMAGE_CHGCOL_NOTAVAIL);
  652. #endif//TOSHIBA
  653. }
  654. BOOL SetupPCILT( PHW_DEVICE_EXTENSION pHwDevExt )
  655. {
  656. BYTE byte_buffer;
  657. ULONG ulCommand;
  658. #define PCI_LTIME_OFFSET 0x0d /* offset of Latency timer from PCI base */
  659. #define PCI_CACHELINE_OFFSET 0x0c /* offset of cache line size from PCI base */
  660. #define PCI_STATUSorCOMMAND 0x04 /* offset of Pistachio Status and Command regster */
  661. byte_buffer = 255;
  662. VC_SetPCIRegister(pHwDevExt,
  663. PCI_LTIME_OFFSET,
  664. &byte_buffer,
  665. 0x01);
  666. byte_buffer=(BYTE) 0;
  667. VC_SetPCIRegister(pHwDevExt,
  668. PCI_CACHELINE_OFFSET,
  669. &byte_buffer,
  670. 0x01);
  671. ulCommand = 0x02000006;
  672. VC_SetPCIRegister(pHwDevExt,
  673. PCI_STATUSorCOMMAND,
  674. &ulCommand,
  675. 0x04);
  676. ulCommand = IGNORE100msec ; // Set ignore time for chattering
  677. VC_SetPCIRegister(pHwDevExt,
  678. PCI_Wake_Up,
  679. &ulCommand,
  680. 0x04);
  681. return TRUE;
  682. }
  683. BOOL CameraChkandON( PHW_DEVICE_EXTENSION pHwDevExt, ULONG ulMode )
  684. {
  685. ULONG dd_buffer;
  686. if (!VC_GetPCIRegister(pHwDevExt,
  687. PCI_Wake_Up,
  688. &dd_buffer,
  689. 0x04) )
  690. {
  691. return FALSE;
  692. }
  693. if( (dd_buffer&0x10000l) == 0)
  694. {
  695. return TRUE;
  696. }
  697. dd_buffer = IGNORE100msec | 0x101l; // Set Wake Up enable
  698. if (!VC_SetPCIRegister(pHwDevExt,
  699. PCI_Wake_Up,
  700. &dd_buffer,
  701. 0x04) )
  702. {
  703. return FALSE;
  704. }
  705. switch(ulMode){
  706. case MODE_VFW:
  707. dd_buffer = CAVCE_CFGPAT | CADTE_CFGPAT | PXCCE_CFGPAT | PXCSE_CFGPAT
  708. | PCIFE_CFGPAT | PCIME_CFGPAT | PCIDS_CFGPAT | GPB_CFGPAT; // Mod 97-05-06(Tue)
  709. break;
  710. case MODE_ZV:
  711. dd_buffer = CAVCE_CFGPAT | CADTE_CFGPAT | PXCCE_CFGPAT | PCIFE_CFGPAT
  712. | PCIME_CFGPAT | PCIDS_CFGPAT | GPB_CFGPAT; // Add 97-05-06(Tue)
  713. break;
  714. }
  715. // Power ON to camera.
  716. if (!VC_SetPCIRegister(pHwDevExt,
  717. PCI_DATA_PATH,
  718. &dd_buffer,
  719. 0x04) )
  720. {
  721. return FALSE;
  722. }
  723. return TRUE;
  724. }
  725. BOOL CameraChkandOFF( PHW_DEVICE_EXTENSION pHwDevExt, ULONG ulMode )
  726. {
  727. DWORD dwBuffer;
  728. DWORD dwSystemWait; // Add 97-05-06(Tue)
  729. switch(ulMode){
  730. case MODE_VFW:
  731. break;
  732. case MODE_ZV:
  733. SetZVControl(pHwDevExt, ZV_DISABLE);
  734. break;
  735. }
  736. dwBuffer = GPB_CFGPAT; // Camera Power Off
  737. if (!VC_SetPCIRegister(pHwDevExt,
  738. PCI_CFGPAT,
  739. &dwBuffer,
  740. 0x04) )
  741. {
  742. return FALSE;
  743. }
  744. return TRUE;
  745. }
  746. BOOL CheckCameraStatus(PHW_DEVICE_EXTENSION pHwDevExt) // Add 97-05-06(Tue)
  747. {
  748. DWORD dwBuffer;
  749. BOOL crStatus;
  750. if (!VC_GetPCIRegister(pHwDevExt,
  751. PCI_CFGPAT,
  752. &dwBuffer,
  753. 0x04) )
  754. {
  755. return FALSE;
  756. }
  757. if(dwBuffer & CAVCE_CFGPAT){
  758. crStatus = TRUE;
  759. }
  760. else{
  761. crStatus = FALSE;
  762. }
  763. return crStatus;
  764. }
  765. BOOL SetZVControl(PHW_DEVICE_EXTENSION pHwDevExt, ULONG ulZVStatus) // Add 97-05-02(Fri)
  766. {
  767. DWORD dwBuffer, dwBuffer2;
  768. BOOL crStatus = TRUE;
  769. if (!VC_GetPCIRegister(pHwDevExt,
  770. PCI_CFGPAT,
  771. &dwBuffer,
  772. 0x04) )
  773. {
  774. return FALSE;
  775. }
  776. if (!VC_GetPCIRegister(pHwDevExt,
  777. PCI_CFGWAK,
  778. &dwBuffer2,
  779. 0x04) )
  780. {
  781. return FALSE;
  782. }
  783. if(!(dwBuffer2 & CASL_CFGWAK)) // Camera Not Connect
  784. {
  785. return FALSE;
  786. }
  787. switch(ulZVStatus){
  788. case ZV_ENABLE:
  789. if(!(dwBuffer & CAVCE_CFGPAT)){ // Check CAVCE Status
  790. crStatus = CameraChkandON(pHwDevExt, MODE_ZV);
  791. if(!crStatus){
  792. return FALSE;
  793. }
  794. }
  795. case ZV_DISABLE:
  796. dwBuffer = (dwBuffer & 0xfffffffe) | ulZVStatus;
  797. if (!VC_SetPCIRegister(pHwDevExt,
  798. PCI_CFGPAT,
  799. &dwBuffer,
  800. 0x04) )
  801. {
  802. return FALSE;
  803. }
  804. crStatus = TRUE;
  805. break;
  806. case ZV_GETSTATUS:
  807. if(dwBuffer & ZV_ENABLE){
  808. crStatus = TRUE;
  809. }
  810. else{
  811. crStatus = FALSE;
  812. }
  813. break;
  814. }
  815. return crStatus;
  816. }
  817. BOOL SetASICRev(PHW_DEVICE_EXTENSION pHwDevExt) // Add 97-05-12(Mon)
  818. {
  819. DWORD dwBuffer;
  820. DWORD dwAsicRev;
  821. if (!VC_GetPCIRegister(pHwDevExt,
  822. PCI_CFGCCR,
  823. &dwBuffer,
  824. 0x04) )
  825. {
  826. return FALSE;
  827. }
  828. dwAsicRev = dwBuffer & 0x0f;
  829. pHwDevExt->dwAsicRev = dwAsicRev;
  830. return TRUE;
  831. }
  832. BOOL
  833. Alloc_TriBuffer(PHW_DEVICE_EXTENSION pHwDevExt)
  834. {
  835. ULONG ulSize;
  836. PUCHAR puTemp;
  837. ulSize = pHwDevExt->BufferSize;
  838. puTemp = (PUCHAR)pHwDevExt->pCaptureBufferY;
  839. pHwDevExt->pCapBuf2Y = puTemp + ulSize;
  840. puTemp = (PUCHAR)pHwDevExt->pCaptureBufferU;
  841. pHwDevExt->pCapBuf2U = puTemp + ulSize;
  842. puTemp = (PUCHAR)pHwDevExt->pCaptureBufferV;
  843. pHwDevExt->pCapBuf2V = puTemp + ulSize;
  844. pHwDevExt->pPhysCapBuf2Y.LowPart = pHwDevExt->pPhysCaptureBufferY.LowPart + ulSize;
  845. pHwDevExt->pPhysCapBuf2U.LowPart = pHwDevExt->pPhysCaptureBufferU.LowPart + ulSize;
  846. pHwDevExt->pPhysCapBuf2V.LowPart = pHwDevExt->pPhysCaptureBufferV.LowPart + ulSize;
  847. return TRUE;
  848. }
  849. BOOL
  850. Free_TriBuffer(PHW_DEVICE_EXTENSION pHwDevExt)
  851. {
  852. pHwDevExt->pCapBuf2Y = NULL;
  853. pHwDevExt->pCapBuf2U = NULL;
  854. pHwDevExt->pCapBuf2V = NULL;
  855. pHwDevExt->pPhysCapBuf2Y.LowPart = 0;
  856. pHwDevExt->pPhysCapBuf2U.LowPart = 0;
  857. pHwDevExt->pPhysCapBuf2V.LowPart = 0;
  858. return TRUE;
  859. }
  860. BOOL
  861. VC_GetPCIRegister(
  862. PHW_DEVICE_EXTENSION pHwDevExt,
  863. ULONG ulOffset,
  864. PVOID pData,
  865. ULONG ulLength)
  866. {
  867. #ifdef TOSHIBA // '99-01-20 Added
  868. if( ulConfigAddress != 0xFFFFFFFF ) {
  869. ULONG OldPort;
  870. ULONG DataPort;
  871. OldPort = READ_PORT_ULONG( (PULONG)0xCF8 );
  872. WRITE_PORT_ULONG( (PULONG)0xCF8, ( ulConfigAddress | ulOffset) & 0xFFFFFFFC );
  873. DataPort = 0xCFC + (ulOffset % 4);
  874. switch ( ulLength ) {
  875. case 1:
  876. *((PUCHAR)pData) = READ_PORT_UCHAR( (PUCHAR)DataPort );
  877. break;
  878. case 2:
  879. *((PUSHORT)pData) = READ_PORT_USHORT( (PUSHORT)DataPort );
  880. break;
  881. case 4:
  882. *((PULONG)pData) = READ_PORT_ULONG( (PULONG)DataPort );
  883. break;
  884. }
  885. WRITE_PORT_ULONG( (PULONG)0xCF8, OldPort );
  886. return TRUE;
  887. }
  888. #endif//TOSHIBA
  889. if( StreamClassReadWriteConfig(
  890. pHwDevExt,
  891. TRUE, // indicates a READ
  892. pData,
  893. ulOffset, // this is the offset into the PCI space
  894. ulLength // this is the # of bytes to read.
  895. )) {
  896. return TRUE;
  897. } else {
  898. return FALSE;
  899. }
  900. }
  901. BOOL
  902. VC_SetPCIRegister(
  903. PHW_DEVICE_EXTENSION pHwDevExt,
  904. ULONG ulOffset,
  905. PVOID pData,
  906. ULONG ulLength)
  907. {
  908. #ifdef TOSHIBA // '99-01-20 Added
  909. if( ulConfigAddress != 0xFFFFFFFF ) {
  910. ULONG OldPort;
  911. ULONG DataPort;
  912. OldPort = READ_PORT_ULONG( (PULONG)0xCF8 );
  913. WRITE_PORT_ULONG( (PULONG)0xCF8, ( ulConfigAddress | ulOffset) & 0xFFFFFFFC );
  914. DataPort = 0xCFC + (ulOffset % 4);
  915. switch ( ulLength ) {
  916. case 1:
  917. WRITE_PORT_UCHAR( (PUCHAR)DataPort, *((PUCHAR)pData) );
  918. break;
  919. case 2:
  920. WRITE_PORT_USHORT( (PUSHORT)DataPort, *((PUSHORT)pData) );
  921. break;
  922. case 4:
  923. WRITE_PORT_ULONG( (PULONG)DataPort, *((PULONG)pData) );
  924. break;
  925. }
  926. WRITE_PORT_ULONG( (PULONG)0xCF8, OldPort );
  927. return TRUE;
  928. }
  929. #endif//TOSHIBA
  930. if( StreamClassReadWriteConfig(
  931. pHwDevExt,
  932. FALSE, // indicates a WRITE
  933. pData,
  934. ulOffset, // this is the offset into the PCI space
  935. ulLength // this is the # of bytes to read.
  936. )) {
  937. return TRUE;
  938. } else {
  939. return FALSE;
  940. }
  941. }
  942. /*
  943. * delay for a number of milliseconds. This is accurate only to
  944. * +- 15msecs at best.
  945. */
  946. VOID
  947. VC_Delay(int nMillisecs)
  948. {
  949. LARGE_INTEGER Delay;
  950. /*
  951. * relative times are negative, in units of 100 nanosecs
  952. */
  953. // first wait for the minimum length of time - this ensures that
  954. // our wait is never less than nMillisecs.
  955. Delay = RtlConvertLongToLargeInteger(-1);
  956. KeDelayExecutionThread(KernelMode,
  957. FALSE, //non-alertable
  958. &Delay);
  959. // now wait for the requested time.
  960. Delay = RtlConvertLongToLargeInteger(-(nMillisecs * 10000));
  961. KeDelayExecutionThread(KernelMode,
  962. FALSE, //non-alertable
  963. &Delay);
  964. }
  965. #if DBG
  966. void
  967. DbgDumpPciRegister( PHW_DEVICE_EXTENSION pHwDevExt )
  968. {
  969. ULONG i;
  970. ULONG data;
  971. DbgPrint("\n+++++ PCI Config Register +++++\n");
  972. for( i=0; i<0x48; i+=4 )
  973. {
  974. if (VC_GetPCIRegister(pHwDevExt,
  975. i,
  976. &data,
  977. 0x04) )
  978. {
  979. DbgPrint("0x%02X: 0x%08X\n", i, data);
  980. }
  981. else
  982. {
  983. DbgPrint("0x%02X: Read Error.\n", i);
  984. }
  985. }
  986. }
  987. void
  988. DbgDumpCaptureRegister( PHW_DEVICE_EXTENSION pHwDevExt )
  989. {
  990. ULONG i;
  991. ULONG data;
  992. DbgPrint("\n+++++ Capture Register +++++\n");
  993. for( i=0; i<0xA4; i+=4 )
  994. {
  995. data = ReadRegUlong(pHwDevExt, i);
  996. DbgPrint("0x%02X: 0x%08X\n", i, data);
  997. }
  998. }
  999. #endif
  1000.