Source code of Windows XP (NT5)
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.

674 lines
18 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Philips Semiconductors-CSU 1999
  4. // All rights are reserved. Reproduction in whole or in part is prohibited
  5. // without the written consent of the copyright owner.
  6. //
  7. // Philips reserves the right to make changes without notice at any time.
  8. // Philips makes no warranty, expressed, implied or statutory, including but
  9. // not limited to any implied warranty of merchantibility or fitness for any
  10. // particular purpose, or that the use will not infringe any third party
  11. // patent, copyright or trademark. Philips must not be liable for any loss
  12. // or damage arising from its use.
  13. //
  14. // VSBBASE.CPP
  15. //////////////////////////////////////////////////////////////////////////////
  16. #include "philtune.h"
  17. #include "vsbbase.h"
  18. /*
  19. * CVSBDemod()
  20. * Input :
  21. * Output: TRUE - if initialization data can be written to I2C
  22. * FALSE - if there is an I2C error
  23. * Description: CVSBDemod Constructor.
  24. */
  25. CVSBDemod::CVSBDemod(CI2CScript *p_I2CScript, BoardInfoType *p_BoardInfo, NTSTATUS *p_Status)
  26. :m_RegisterLock(1)
  27. {
  28. m_pI2CScript = p_I2CScript;
  29. m_ucVsbDemodAddress = VSB_I2C_ADDRESS;
  30. }
  31. /*
  32. * SetRegisterList()
  33. * Input:
  34. * Output:
  35. * Description:
  36. */
  37. UINT CVSBDemod::SetRegisterList(RegisterType *p_Registers, UINT uiNumRegisters)
  38. {
  39. return SetControlRegister(p_Registers, uiNumRegisters);
  40. }
  41. /*
  42. * GetRegisterList()
  43. * Input:
  44. * Output:
  45. * Description:
  46. */
  47. UINT CVSBDemod::GetRegisterList(RegisterType *p_Registers, UINT uiNumRegisters,
  48. UINT uiRegisterType)
  49. {
  50. if(uiRegisterType == CONTROL_REGISTER)
  51. {
  52. return GetControlRegister(p_Registers, uiNumRegisters);
  53. }
  54. else if(uiRegisterType == STATUS_REGISTER)
  55. {
  56. return GetStatusRegister(p_Registers, uiNumRegisters);
  57. }
  58. else{}
  59. return WDMMINI_INVALIDPARAM;
  60. }
  61. /*
  62. * SetCoeff()
  63. * Input:VsbCoeffType *p_Coeff - pointer to the coefficients register
  64. * structure
  65. * UINT uiNumCoeff - Number of coefficients
  66. * Output : UINT - Error code
  67. * Description: Lock register access and Set the coefficients into the chip
  68. */
  69. UINT CVSBDemod::SetCoeff(VsbCoeffType *p_Coeff, UINT uiNumRegisters)
  70. {
  71. UINT uiResult;
  72. UINT i;
  73. // Lock the Register control handle
  74. m_RegisterLock.Lock();
  75. VsbCoeffType *pp_TempCoeff[MAX_VSB_COEFF];
  76. UCHAR ucEnable = 0;
  77. if (p_Coeff != NULL)
  78. {
  79. for (i = 0; i < uiNumRegisters; i++)
  80. {
  81. pp_TempCoeff[i] = &p_Coeff[i];
  82. ucEnable |= p_Coeff[i].uiID;
  83. }
  84. if(!EnableCoefficients(ucEnable))
  85. {
  86. uiResult = WDMMINI_HARDWAREFAILURE;
  87. goto errexit;
  88. }
  89. uiResult = WriteCoeff(pp_TempCoeff, uiNumRegisters);
  90. if(!DisableCoefficients())
  91. {
  92. uiResult = WDMMINI_HARDWAREFAILURE;
  93. goto errexit;
  94. }
  95. }
  96. else
  97. {
  98. _DbgPrintF( DEBUGLVL_ERROR,("CVSBDemod::WriteCoeff() No Coeff !!! \n"));
  99. uiResult = WDMMINI_INVALIDPARAM;
  100. }
  101. errexit:
  102. m_RegisterLock.Unlock();
  103. return uiResult;
  104. }
  105. /*
  106. * GetCoeff()
  107. * Input:VsbCoeffType *p_Coeff - pointer to the coefficients register
  108. * structure
  109. * UINT uiNumCoeff - Number of coefficients
  110. * Output : UINT - Error code
  111. * Description: Lock register access and Get the coefficients from the chip
  112. */
  113. UINT CVSBDemod::GetCoeff(VsbCoeffType *p_Coeff, UINT uiNumRegisters)
  114. {
  115. UINT uiResult;
  116. UINT i;
  117. UCHAR ucEnable = 0;
  118. // Lock the Register control handle
  119. m_RegisterLock.Lock();
  120. VsbCoeffType *pp_TempCoeff[MAX_VSB_COEFF];
  121. if (p_Coeff != NULL)
  122. {
  123. for (i = 0; i < uiNumRegisters; i++)
  124. {
  125. pp_TempCoeff[i] = &p_Coeff[i];
  126. ucEnable |= p_Coeff[i].uiID;
  127. }
  128. if(!EnableCoefficients(ucEnable))
  129. {
  130. uiResult = WDMMINI_HARDWAREFAILURE;
  131. goto errexit;
  132. }
  133. uiResult = ReadCoeff(pp_TempCoeff, uiNumRegisters);
  134. if(!DisableCoefficients())
  135. {
  136. uiResult = WDMMINI_HARDWAREFAILURE;
  137. goto errexit;
  138. }
  139. }
  140. else
  141. {
  142. _DbgPrintF( DEBUGLVL_ERROR,("CVSBDemod::ReadAndCreateRegisters() No Coeff !!! \n"));
  143. uiResult = WDMMINI_INVALIDPARAM;
  144. }
  145. errexit:
  146. m_RegisterLock.Unlock();
  147. return uiResult;
  148. }
  149. /*
  150. * SetControlRegister()
  151. * Input:
  152. * Output:
  153. * Description:
  154. */
  155. UINT CVSBDemod::SetControlRegister(RegisterType *p_Registers,
  156. UINT uiNumRegisters)
  157. {
  158. int i;
  159. UINT uiResult;
  160. UINT uiPrevAddress = 0;
  161. m_RegisterLock.Lock();
  162. uiResult = WriteControlReg(p_Registers, uiNumRegisters, TRUE);
  163. m_RegisterLock.Unlock();
  164. return uiResult;
  165. }
  166. /*
  167. * GetControlRegister()
  168. * Input:
  169. * Output:
  170. * Description:
  171. */
  172. UINT CVSBDemod::GetControlRegister(RegisterType *p_Registers,
  173. UINT uiNumRegisters)
  174. {
  175. UINT i, a, b;
  176. RegisterType Temp;
  177. UINT uiResult = WDMMINI_NOERROR;
  178. // This read operation is a shadow operation. The values in the control
  179. // regsiter (in memory) is passed back
  180. // Lock the Register control handle
  181. m_RegisterLock.Lock();
  182. // Write data into control registers (memory)
  183. for (i = 0; i < uiNumRegisters; i++)
  184. {
  185. // Check to see that the address is within the specified
  186. // range for the chip
  187. UINT uiAddr = p_Registers[i].uiAddress;
  188. if ( uiAddr <= m_uiMaxControlRegisterAddress)
  189. {
  190. // Copy the register values from the control register
  191. // in memory
  192. MemoryCopy(p_Registers[i].p_ucBuffer, &m_ucControlReg[uiAddr],
  193. p_Registers[i].uiLength);
  194. }
  195. else
  196. {
  197. uiResult = WDMMINI_INVALIDPARAM;
  198. break;
  199. }
  200. }
  201. m_RegisterLock.Unlock();
  202. return uiResult;
  203. }
  204. /*
  205. * GetStatusRegister()
  206. * Input:
  207. * Output:
  208. * Description:
  209. */
  210. UINT CVSBDemod::GetStatusRegister(RegisterType *p_Registers,
  211. UINT uiNumRegisters)
  212. {
  213. UINT uiResult;
  214. // Lock the Register control handle
  215. m_RegisterLock.Lock();
  216. uiResult = ReadStatusReg(p_Registers, uiNumRegisters);
  217. m_RegisterLock.Unlock();
  218. return uiResult;
  219. }
  220. /*
  221. * WriteControlReg()
  222. * Input:RegisterType *p_reg_list- Register list to be written to control registers
  223. int i_num_reg - Number of registers in the list
  224. * Output : UINT - Error code
  225. * Description: Update the control registers and write to chip
  226. */
  227. UINT CVSBDemod::WriteControlReg(RegisterType *p_Registers, UINT uiNumRegisters,
  228. BOOL bWrite)
  229. {
  230. UINT uiResult = WDMMINI_NOERROR;
  231. UINT i;
  232. UINT uiPrevAddress;
  233. UINT uiLastAddress;
  234. UINT uiAddress;
  235. uiPrevAddress = p_Registers[0].uiAddress;
  236. // Write data into control registers (memory)
  237. for (i = 0; i < uiNumRegisters; i++)
  238. {
  239. // Check to see that the address is within the specified
  240. // range for the chip
  241. uiAddress = p_Registers[i].uiAddress;
  242. uiLastAddress = uiAddress + p_Registers[i].uiLength - 1;
  243. if ( (uiLastAddress)<= m_uiMaxControlRegisterAddress)
  244. {
  245. // Copy the register values into the control register
  246. //memory
  247. MemoryCopy(&m_ucControlReg[uiAddress], p_Registers[i].p_ucBuffer,
  248. p_Registers[i].uiLength);
  249. }
  250. else
  251. {
  252. uiResult = WDMMINI_INVALIDPARAM;
  253. return uiResult ;
  254. }
  255. // Find the highest address
  256. if(uiPrevAddress < uiLastAddress)
  257. uiPrevAddress = uiLastAddress;
  258. if (bWrite)
  259. {
  260. if((uiResult = Write(m_ucControlReg, (uiPrevAddress + 1), 0)) !=
  261. WDMMINI_NOERROR)
  262. {
  263. _DbgPrintF( DEBUGLVL_ERROR,("CVSBDemod::WriteControlReg() Error in Write !!! \n"));
  264. return uiResult;
  265. }
  266. }
  267. }
  268. _DbgPrintF( DEBUGLVL_VERBOSE,("CVSBDemod::WriteControlReg() Write !!! ------------ \n"));
  269. return uiResult;
  270. }
  271. /*
  272. * ReadStatusReg()
  273. * Input:RegisterType *p_reg_list- Register list to be written to control registers
  274. int i_num_reg - Number of registers in the list
  275. * Output : UINT - Error code
  276. * Description: Update the control registers and write to chip
  277. */
  278. UINT CVSBDemod::ReadStatusReg(RegisterType *p_Registers, UINT uiNumRegisters)
  279. {
  280. UINT uiResult = WDMMINI_NOERROR;
  281. UINT i;
  282. UINT uiPrevAddress;
  283. UINT uiLastAddress;
  284. UINT uiAddress;
  285. uiPrevAddress = p_Registers[0].uiAddress;
  286. // Write data into control registers (memory)
  287. for (i = 0; i < uiNumRegisters; i++)
  288. {
  289. // Check to see that the address is within the specified
  290. // range for the chip
  291. uiAddress = p_Registers[i].uiAddress;
  292. uiLastAddress = uiAddress + p_Registers[i].uiLength - 1;
  293. if (uiLastAddress <= m_uiMaxStatusRegisterAddress)
  294. {
  295. // Find the highest address
  296. if(uiPrevAddress < uiLastAddress)
  297. uiPrevAddress = uiLastAddress;
  298. }
  299. else
  300. {
  301. _DbgPrintF( DEBUGLVL_ERROR,("CVSBDemod::ReadStatusReg() Error: Too many values !!! \n"));
  302. return(WDMMINI_INVALIDPARAM);
  303. }
  304. }
  305. // Read I2C data
  306. if((uiResult = Read(m_ucI2CBuffer, uiPrevAddress + 1, 0)) !=
  307. WDMMINI_NOERROR)
  308. {
  309. _DbgPrintF( DEBUGLVL_ERROR,("CVSBDemod::ReadStatusReg() Error in Read !!! \n"));
  310. return uiResult;
  311. }
  312. // Read data from status registers (memory)
  313. for (i = 0; i < uiNumRegisters; i++)
  314. {
  315. // Copy the register values into the control register
  316. //memory
  317. MemoryCopy(p_Registers[i].p_ucBuffer, &m_ucI2CBuffer[p_Registers[i].uiAddress],
  318. p_Registers[i].uiLength);
  319. }
  320. _DbgPrintF( DEBUGLVL_VERBOSE,("CVSBDemod::ReadStatusReg() Read !!! ------------ \n"));
  321. return uiResult;
  322. }
  323. /*
  324. * WriteCoeff()
  325. * Input:VsbCoeffType **pp_Coeff -pointer to an array of pointers pointing to
  326. * coefficients register structure
  327. * UINT uiNumCoeff - Number of coefficient pointers
  328. * Output : UINT - Error code
  329. * Description: Write the coefficients into the chip
  330. */
  331. UINT CVSBDemod::WriteCoeff(VsbCoeffType **pp_Coeff, UINT uiNumCoeff)
  332. {
  333. UINT uiResult = WDMMINI_NOERROR;
  334. UINT uiStart = 0;
  335. UINT uiCurrentPos = 0;
  336. UINT uiNumValues = 0;
  337. UINT uiIndex = 0;
  338. UINT i, j;
  339. VsbCoeffType *p_TempCoeff;
  340. uiCurrentPos = 0;
  341. p_TempCoeff = pp_Coeff[0];
  342. // Find the least address coefficient.
  343. // Fill up the output buffer with control register values upto
  344. // this least coefficient.
  345. // Write the coefficient values.
  346. // Find the next least address coefficient.
  347. // Write the control register values between the previous coefficient end
  348. // and this coefficient beginning.
  349. for (i = 0; i < uiNumCoeff; i++)
  350. {
  351. p_TempCoeff = pp_Coeff[i];
  352. uiIndex = i;
  353. for(j = i; j < uiNumCoeff; j++)
  354. {
  355. if(pp_Coeff[j]->uiAddress < p_TempCoeff->uiAddress)
  356. {
  357. p_TempCoeff = pp_Coeff[j];
  358. uiIndex = j;
  359. }
  360. }
  361. pp_Coeff[uiIndex] = pp_Coeff[i];
  362. pp_Coeff[i] = p_TempCoeff;
  363. // Number of control registers to be copied into the I2C buffer before
  364. // the coefficient array
  365. uiNumValues = p_TempCoeff->uiAddress - uiStart;
  366. // Copy the partial control registers
  367. MemoryCopy(&m_ucI2CBuffer[uiCurrentPos], &m_ucControlReg[uiStart], uiNumValues) ;
  368. // position the pointer to the next position in the i2C buffer
  369. uiCurrentPos += uiNumValues;
  370. // Position the pointer to the next control register
  371. uiStart += uiNumValues + 1;
  372. // Write 0 to coefficient write trigger point. It is not necessary to write 0,
  373. // but as the document does not say what value should be written, its better to
  374. // write 0. In VSB1, writing to the coefficient trigger point freezes the Equalizer
  375. // thats the reason for keeping the write to trigger point a separate operation
  376. m_ucI2CBuffer[uiCurrentPos] = 0;
  377. // position the pointer to the next position in the i2C buffer
  378. uiCurrentPos += 1;
  379. // Copy the coefficient values into the I2C control buffer
  380. MemoryCopy(&m_ucI2CBuffer[uiCurrentPos],
  381. p_TempCoeff->p_ucBuffer, p_TempCoeff->uiLength);
  382. // Update i2C buffer position pointer
  383. uiCurrentPos += p_TempCoeff->uiLength;
  384. }
  385. // Copy control register values to I2C buffer and write
  386. //to chip
  387. if((uiResult = Write(m_ucI2CBuffer, uiCurrentPos, 0))
  388. != WDMMINI_NOERROR)
  389. {
  390. _DbgPrintF( DEBUGLVL_ERROR,("CVSBDemod::WriteCoeff() Error in Write !!! \n"));
  391. }
  392. else
  393. {
  394. _DbgPrintF( DEBUGLVL_VERBOSE,("CVSBDemod::WriteCoeff() Write !!! \n"));
  395. }
  396. return uiResult;
  397. }
  398. /*
  399. * ReadCoeff()
  400. * Input:VsbCoeffType **pp_Coeff - pointer to an array of pointers pointing to
  401. * coefficients register structure
  402. * UINT uiNumCoeff - Number of coefficient pointers
  403. * Output : UINT - Error code
  404. * Description:Read the coefficients from the chip
  405. */
  406. UINT CVSBDemod::ReadCoeff(VsbCoeffType **pp_Coeff, UINT uiNumCoeff)
  407. {
  408. UINT uiResult = WDMMINI_NOERROR;
  409. UINT uiStart = 0;
  410. UINT uiCurrentPos = 0;
  411. UINT uiNumValues = 0;
  412. UINT i, j;
  413. UINT uiLength = 0;
  414. UINT uiIndex = 0;
  415. VsbCoeffType *p_TempCoeff;
  416. p_TempCoeff = pp_Coeff[0];
  417. UINT uiTempAdd = p_TempCoeff->uiAddress;
  418. for (i = 0; i < uiNumCoeff; i++)
  419. {
  420. if(uiTempAdd < pp_Coeff[i]->uiAddress)
  421. {
  422. uiTempAdd = pp_Coeff[i]->uiAddress;
  423. }
  424. uiLength += pp_Coeff[i]->uiLength;
  425. }
  426. uiLength += uiTempAdd + 1;
  427. // Read I2C data
  428. if((uiResult = Read(m_ucI2CBuffer, uiLength, 0)) != WDMMINI_NOERROR)
  429. {
  430. _DbgPrintF( DEBUGLVL_ERROR,("CVSBDemod::ReadAndCreateRegisters() Error in Read !!! \n"));
  431. return uiResult;
  432. }
  433. else
  434. _DbgPrintF( DEBUGLVL_VERBOSE,("CVSBDemod::ReadAndCreateRegisters() Read !!! \n"));
  435. // Sort Array
  436. for (i = 0; i < uiNumCoeff; i++)
  437. {
  438. p_TempCoeff = pp_Coeff[i];
  439. uiIndex = i;
  440. for(j = i; j < uiNumCoeff; j++)
  441. {
  442. if(pp_Coeff[j]->uiAddress < p_TempCoeff->uiAddress)
  443. {
  444. p_TempCoeff = pp_Coeff[j];
  445. uiIndex = j;
  446. }
  447. }
  448. pp_Coeff[uiIndex] = pp_Coeff[i];
  449. pp_Coeff[i] = p_TempCoeff;
  450. // Number of values to be ignored includes the coefficient-read trigger point
  451. uiNumValues = p_TempCoeff->uiAddress - uiStart + 1;
  452. // Update i2C buffer pointer position
  453. uiCurrentPos += uiNumValues;
  454. // Update status register pointer position
  455. uiStart += uiNumValues;
  456. // Copy the coefficient values
  457. MemoryCopy(p_TempCoeff->p_ucBuffer, &m_ucI2CBuffer[uiCurrentPos],
  458. p_TempCoeff->uiLength);
  459. uiCurrentPos += p_TempCoeff->uiLength;
  460. }
  461. return uiResult;
  462. }
  463. /*
  464. * Write()
  465. * Input:UCHAR *p_ucBuffer - buffer to be written
  466. * int uiNumReg - Number of registers to be written
  467. * UINT uiStartAddr - start address
  468. * Output : UINT - Error code
  469. * Description: Write data to chip
  470. */
  471. UINT CVSBDemod::Write(UCHAR *p_ucBuffer, UINT uiNumReg, UINT uiStartAddr)
  472. {
  473. UINT uiResult = WDMMINI_NOERROR;
  474. // The present versions of the chip do not support sub-addressing, hence
  475. // uiStartAddr is not used.
  476. // write to chip
  477. //$REVIEW - Should change function decl to make uiNumReg be USHORT - TCP
  478. if(!m_pI2CScript->WriteSeq(m_ucVsbDemodAddress, p_ucBuffer,
  479. (USHORT) uiNumReg))
  480. uiResult = WDMMINI_HARDWAREFAILURE;
  481. return uiResult;
  482. }
  483. /*
  484. * Read()
  485. * Input:UCHAR *p_ucBuffer - buffer to be filled
  486. * int uiNumReg - Number of registers to be read
  487. * UINT uiStartAddr - start address
  488. * Output : UINT - Error code
  489. * Description: Read data from chip
  490. */
  491. UINT CVSBDemod::Read(UCHAR *p_ucBuffer, UINT uiNumReg, UINT uiStartAddr)
  492. {
  493. UINT uiResult = WDMMINI_NOERROR;
  494. // The present versions of the chip do not support sub-addressing, hence
  495. // uiStartAddr is not used.
  496. // write to chip
  497. //$REVIEW - Should change function decl to make uiNumReg be USHORT - TCP
  498. if(!m_pI2CScript->ReadSeq(m_ucVsbDemodAddress, p_ucBuffer, (USHORT) uiNumReg))
  499. uiResult = WDMMINI_HARDWAREFAILURE;
  500. return uiResult;
  501. }
  502. /*
  503. * IsVSBLocked()
  504. * Input :
  505. * Output: TRUE - if chip is locked
  506. * FALSE - if chip is not locked
  507. * Description: Check if chip is locked ( equalizer lock )
  508. */
  509. BOOL CVSBDemod::IsVSBLocked()
  510. {
  511. BOOL bLocked = FALSE;
  512. UCHAR ucByte = 0;
  513. RegisterType Status;
  514. Status.uiLength = 1;
  515. Status.uiAddress = VSB_REG_STATE;
  516. Status.p_ucBuffer = &ucByte;
  517. if(GetStatusRegister(&Status, 1) !=WDMMINI_NOERROR)
  518. return FALSE;
  519. bLocked = ((ucByte & 0x7) == 0x7) ? 1 : 0;
  520. if (bLocked)
  521. {
  522. _DbgPrintF( DEBUGLVL_TERSE,("CVSBDemod: 8VSB LOCKED !!! ------------ \n"));
  523. }
  524. else
  525. {
  526. _DbgPrintF( DEBUGLVL_TERSE,("CVSBDemod: 8VSB not locked %x!!!\n", ucByte));
  527. }
  528. return(bLocked);
  529. }
  530. /*
  531. * SoftwareReset()
  532. * Input: Reset control
  533. * Output :
  534. * Description: Reset chip
  535. */
  536. BOOL CVSBDemod::SoftwareReset(ULONG ulResetCtrl)
  537. {
  538. RegisterType Control;
  539. UCHAR ucMask;
  540. UCHAR ucReset = m_ucControlReg[VSB_REG_RESET];
  541. if(ulResetCtrl & VSB_GENERAL_RESET)
  542. ucMask = VSB_GENERAL_RESET;
  543. else if(ulResetCtrl & VSB_INITIAL_RESET)
  544. ucMask = VSB_INITIAL_RESET;
  545. else
  546. return FALSE;
  547. ucReset |= ucMask;
  548. Control.uiAddress = VSB_REG_RESET;
  549. Control.uiLength = 1;
  550. Control.p_ucBuffer = &ucReset;
  551. // Reset chip
  552. SetControlRegister(&Control, 1);
  553. ucReset &= ~ucMask;
  554. //50ms delay
  555. Delay(500000);
  556. // Remove reset
  557. SetControlRegister(&Control, 1);
  558. //50ms delay
  559. Delay(500000);
  560. // Initialize VSB if INITIAL RESET is done
  561. if(ulResetCtrl & VSB_INITIAL_RESET)
  562. if(!InitVSB())
  563. return FALSE;
  564. return TRUE;
  565. }