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