ddk750_sii164.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. #define USE_DVICHIP
  2. #ifdef USE_DVICHIP
  3. #include "ddk750_sii164.h"
  4. #include "ddk750_hwi2c.h"
  5. /* I2C Address of each SII164 chip */
  6. #define SII164_I2C_ADDRESS 0x70
  7. /* Define this definition to use hardware i2c. */
  8. #define USE_HW_I2C
  9. #ifdef USE_HW_I2C
  10. #define i2cWriteReg sm750_hw_i2c_write_reg
  11. #define i2cReadReg sm750_hw_i2c_read_reg
  12. #else
  13. #define i2cWriteReg swI2CWriteReg
  14. #define i2cReadReg swI2CReadReg
  15. #endif
  16. /* SII164 Vendor and Device ID */
  17. #define SII164_VENDOR_ID 0x0001
  18. #define SII164_DEVICE_ID 0x0006
  19. #ifdef SII164_FULL_FUNCTIONS
  20. /* Name of the DVI Controller chip */
  21. static char *gDviCtrlChipName = "Silicon Image SiI 164";
  22. #endif
  23. /*
  24. * sii164GetVendorID
  25. * This function gets the vendor ID of the DVI controller chip.
  26. *
  27. * Output:
  28. * Vendor ID
  29. */
  30. unsigned short sii164GetVendorID(void)
  31. {
  32. unsigned short vendorID;
  33. vendorID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_HIGH) << 8) |
  34. (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_LOW);
  35. return vendorID;
  36. }
  37. /*
  38. * sii164GetDeviceID
  39. * This function gets the device ID of the DVI controller chip.
  40. *
  41. * Output:
  42. * Device ID
  43. */
  44. unsigned short sii164GetDeviceID(void)
  45. {
  46. unsigned short deviceID;
  47. deviceID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_HIGH) << 8) |
  48. (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_LOW);
  49. return deviceID;
  50. }
  51. /* DVI.C will handle all SiI164 chip stuffs and try it best to make code minimal and useful */
  52. /*
  53. * sii164InitChip
  54. * This function initialize and detect the DVI controller chip.
  55. *
  56. * Input:
  57. * edgeSelect - Edge Select:
  58. * 0 = Input data is falling edge latched (falling edge
  59. * latched first in dual edge mode)
  60. * 1 = Input data is rising edge latched (rising edge
  61. * latched first in dual edge mode)
  62. * busSelect - Input Bus Select:
  63. * 0 = Input data bus is 12-bits wide
  64. * 1 = Input data bus is 24-bits wide
  65. * dualEdgeClkSelect - Dual Edge Clock Select
  66. * 0 = Input data is single edge latched
  67. * 1 = Input data is dual edge latched
  68. * hsyncEnable - Horizontal Sync Enable:
  69. * 0 = HSYNC input is transmitted as fixed LOW
  70. * 1 = HSYNC input is transmitted as is
  71. * vsyncEnable - Vertical Sync Enable:
  72. * 0 = VSYNC input is transmitted as fixed LOW
  73. * 1 = VSYNC input is transmitted as is
  74. * deskewEnable - De-skewing Enable:
  75. * 0 = De-skew disabled
  76. * 1 = De-skew enabled
  77. * deskewSetting - De-skewing Setting (increment of 260psec)
  78. * 0 = 1 step --> minimum setup / maximum hold
  79. * 1 = 2 step
  80. * 2 = 3 step
  81. * 3 = 4 step
  82. * 4 = 5 step
  83. * 5 = 6 step
  84. * 6 = 7 step
  85. * 7 = 8 step --> maximum setup / minimum hold
  86. * continuousSyncEnable- SYNC Continuous:
  87. * 0 = Disable
  88. * 1 = Enable
  89. * pllFilterEnable - PLL Filter Enable
  90. * 0 = Disable PLL Filter
  91. * 1 = Enable PLL Filter
  92. * pllFilterValue - PLL Filter characteristics:
  93. * 0~7 (recommended value is 4)
  94. *
  95. * Output:
  96. * 0 - Success
  97. * -1 - Fail.
  98. */
  99. long sii164InitChip(
  100. unsigned char edgeSelect,
  101. unsigned char busSelect,
  102. unsigned char dualEdgeClkSelect,
  103. unsigned char hsyncEnable,
  104. unsigned char vsyncEnable,
  105. unsigned char deskewEnable,
  106. unsigned char deskewSetting,
  107. unsigned char continuousSyncEnable,
  108. unsigned char pllFilterEnable,
  109. unsigned char pllFilterValue
  110. )
  111. {
  112. unsigned char config;
  113. /* Initialize the i2c bus */
  114. #ifdef USE_HW_I2C
  115. /* Use fast mode. */
  116. sm750_hw_i2c_init(1);
  117. #else
  118. sm750_sw_i2c_init(DEFAULT_I2C_SCL, DEFAULT_I2C_SDA);
  119. #endif
  120. /* Check if SII164 Chip exists */
  121. if ((sii164GetVendorID() == SII164_VENDOR_ID) && (sii164GetDeviceID() == SII164_DEVICE_ID)) {
  122. /*
  123. * Initialize SII164 controller chip.
  124. */
  125. /* Select the edge */
  126. if (edgeSelect == 0)
  127. config = SII164_CONFIGURATION_LATCH_FALLING;
  128. else
  129. config = SII164_CONFIGURATION_LATCH_RISING;
  130. /* Select bus wide */
  131. if (busSelect == 0)
  132. config |= SII164_CONFIGURATION_BUS_12BITS;
  133. else
  134. config |= SII164_CONFIGURATION_BUS_24BITS;
  135. /* Select Dual/Single Edge Clock */
  136. if (dualEdgeClkSelect == 0)
  137. config |= SII164_CONFIGURATION_CLOCK_SINGLE;
  138. else
  139. config |= SII164_CONFIGURATION_CLOCK_DUAL;
  140. /* Select HSync Enable */
  141. if (hsyncEnable == 0)
  142. config |= SII164_CONFIGURATION_HSYNC_FORCE_LOW;
  143. else
  144. config |= SII164_CONFIGURATION_HSYNC_AS_IS;
  145. /* Select VSync Enable */
  146. if (vsyncEnable == 0)
  147. config |= SII164_CONFIGURATION_VSYNC_FORCE_LOW;
  148. else
  149. config |= SII164_CONFIGURATION_VSYNC_AS_IS;
  150. i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
  151. /* De-skew enabled with default 111b value.
  152. This will fix some artifacts problem in some mode on board 2.2.
  153. Somehow this fix does not affect board 2.1.
  154. */
  155. if (deskewEnable == 0)
  156. config = SII164_DESKEW_DISABLE;
  157. else
  158. config = SII164_DESKEW_ENABLE;
  159. switch (deskewSetting) {
  160. case 0:
  161. config |= SII164_DESKEW_1_STEP;
  162. break;
  163. case 1:
  164. config |= SII164_DESKEW_2_STEP;
  165. break;
  166. case 2:
  167. config |= SII164_DESKEW_3_STEP;
  168. break;
  169. case 3:
  170. config |= SII164_DESKEW_4_STEP;
  171. break;
  172. case 4:
  173. config |= SII164_DESKEW_5_STEP;
  174. break;
  175. case 5:
  176. config |= SII164_DESKEW_6_STEP;
  177. break;
  178. case 6:
  179. config |= SII164_DESKEW_7_STEP;
  180. break;
  181. case 7:
  182. config |= SII164_DESKEW_8_STEP;
  183. break;
  184. }
  185. i2cWriteReg(SII164_I2C_ADDRESS, SII164_DESKEW, config);
  186. /* Enable/Disable Continuous Sync. */
  187. if (continuousSyncEnable == 0)
  188. config = SII164_PLL_FILTER_SYNC_CONTINUOUS_DISABLE;
  189. else
  190. config = SII164_PLL_FILTER_SYNC_CONTINUOUS_ENABLE;
  191. /* Enable/Disable PLL Filter */
  192. if (pllFilterEnable == 0)
  193. config |= SII164_PLL_FILTER_DISABLE;
  194. else
  195. config |= SII164_PLL_FILTER_ENABLE;
  196. /* Set the PLL Filter value */
  197. config |= ((pllFilterValue & 0x07) << 1);
  198. i2cWriteReg(SII164_I2C_ADDRESS, SII164_PLL, config);
  199. /* Recover from Power Down and enable output. */
  200. config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
  201. config |= SII164_CONFIGURATION_POWER_NORMAL;
  202. i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
  203. return 0;
  204. }
  205. /* Return -1 if initialization fails. */
  206. return (-1);
  207. }
  208. /* below sii164 function is not necessary */
  209. #ifdef SII164_FULL_FUNCTIONS
  210. /*
  211. * sii164ResetChip
  212. * This function resets the DVI Controller Chip.
  213. */
  214. void sii164ResetChip(void)
  215. {
  216. /* Power down */
  217. sii164SetPower(0);
  218. sii164SetPower(1);
  219. }
  220. /*
  221. * sii164GetChipString
  222. * This function returns a char string name of the current DVI Controller chip.
  223. * It's convenient for application need to display the chip name.
  224. */
  225. char *sii164GetChipString(void)
  226. {
  227. return gDviCtrlChipName;
  228. }
  229. /*
  230. * sii164SetPower
  231. * This function sets the power configuration of the DVI Controller Chip.
  232. *
  233. * Input:
  234. * powerUp - Flag to set the power down or up
  235. */
  236. void sii164SetPower(
  237. unsigned char powerUp
  238. )
  239. {
  240. unsigned char config;
  241. config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
  242. if (powerUp == 1) {
  243. /* Power up the chip */
  244. config &= ~SII164_CONFIGURATION_POWER_MASK;
  245. config |= SII164_CONFIGURATION_POWER_NORMAL;
  246. i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
  247. } else {
  248. /* Power down the chip */
  249. config &= ~SII164_CONFIGURATION_POWER_MASK;
  250. config |= SII164_CONFIGURATION_POWER_DOWN;
  251. i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
  252. }
  253. }
  254. /*
  255. * sii164SelectHotPlugDetectionMode
  256. * This function selects the mode of the hot plug detection.
  257. */
  258. static void sii164SelectHotPlugDetectionMode(
  259. sii164_hot_plug_mode_t hotPlugMode
  260. )
  261. {
  262. unsigned char detectReg;
  263. detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & ~SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG;
  264. switch (hotPlugMode) {
  265. case SII164_HOTPLUG_DISABLE:
  266. detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH;
  267. break;
  268. case SII164_HOTPLUG_USE_MDI:
  269. detectReg &= ~SII164_DETECT_INTERRUPT_MASK;
  270. detectReg |= SII164_DETECT_INTERRUPT_BY_HTPLG_PIN;
  271. detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI;
  272. break;
  273. case SII164_HOTPLUG_USE_RSEN:
  274. detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN;
  275. break;
  276. case SII164_HOTPLUG_USE_HTPLG:
  277. detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG;
  278. break;
  279. }
  280. i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg);
  281. }
  282. /*
  283. * sii164EnableHotPlugDetection
  284. * This function enables the Hot Plug detection.
  285. *
  286. * enableHotPlug - Enable (=1) / disable (=0) Hot Plug detection
  287. */
  288. void sii164EnableHotPlugDetection(
  289. unsigned char enableHotPlug
  290. )
  291. {
  292. unsigned char detectReg;
  293. detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
  294. /* Depending on each DVI controller, need to enable the hot plug based on each
  295. individual chip design. */
  296. if (enableHotPlug != 0)
  297. sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_USE_MDI);
  298. else
  299. sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_DISABLE);
  300. }
  301. /*
  302. * sii164IsConnected
  303. * Check if the DVI Monitor is connected.
  304. *
  305. * Output:
  306. * 0 - Not Connected
  307. * 1 - Connected
  308. */
  309. unsigned char sii164IsConnected(void)
  310. {
  311. unsigned char hotPlugValue;
  312. hotPlugValue = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & SII164_DETECT_HOT_PLUG_STATUS_MASK;
  313. if (hotPlugValue == SII164_DETECT_HOT_PLUG_STATUS_ON)
  314. return 1;
  315. else
  316. return 0;
  317. }
  318. /*
  319. * sii164CheckInterrupt
  320. * Checks if interrupt has occurred.
  321. *
  322. * Output:
  323. * 0 - No interrupt
  324. * 1 - Interrupt occurs
  325. */
  326. unsigned char sii164CheckInterrupt(void)
  327. {
  328. unsigned char detectReg;
  329. detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & SII164_DETECT_MONITOR_STATE_MASK;
  330. if (detectReg == SII164_DETECT_MONITOR_STATE_CHANGE)
  331. return 1;
  332. else
  333. return 0;
  334. }
  335. /*
  336. * sii164ClearInterrupt
  337. * Clear the hot plug interrupt.
  338. */
  339. void sii164ClearInterrupt(void)
  340. {
  341. unsigned char detectReg;
  342. /* Clear the MDI interrupt */
  343. detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
  344. i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg | SII164_DETECT_MONITOR_STATE_CLEAR);
  345. }
  346. #endif
  347. #endif