4 #include "ddk750_sii164.h"
5 #include "ddk750_hwi2c.h"
7 /* I2C Address of each SII164 chip */
8 #define SII164_I2C_ADDRESS 0x70
10 /* Define this definition to use hardware i2c. */
14 #define i2cWriteReg sm750_hw_i2c_write_reg
15 #define i2cReadReg sm750_hw_i2c_read_reg
17 #define i2cWriteReg sm750_sw_i2c_write_reg
18 #define i2cReadReg sm750_sw_i2c_read_reg
21 /* SII164 Vendor and Device ID */
22 #define SII164_VENDOR_ID 0x0001
23 #define SII164_DEVICE_ID 0x0006
25 #ifdef SII164_FULL_FUNCTIONS
26 /* Name of the DVI Controller chip */
27 static char *gDviCtrlChipName = "Silicon Image SiI 164";
32 * This function gets the vendor ID of the DVI controller chip.
37 unsigned short sii164GetVendorID(void)
39 unsigned short vendorID;
41 vendorID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_HIGH) << 8) |
42 (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_LOW);
49 * This function gets the device ID of the DVI controller chip.
54 unsigned short sii164GetDeviceID(void)
56 unsigned short deviceID;
58 deviceID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_HIGH) << 8) |
59 (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_LOW);
66 /* DVI.C will handle all SiI164 chip stuffs and try it best to make code minimal and useful */
70 * This function initialize and detect the DVI controller chip.
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
93 * deskewSetting - De-skewing Setting (increment of 260psec)
94 * 0 = 1 step --> minimum setup / maximum hold
101 * 7 = 8 step --> maximum setup / minimum hold
102 * continuousSyncEnable- SYNC Continuous:
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)
115 long sii164InitChip(unsigned char edgeSelect,
116 unsigned char busSelect,
117 unsigned char dualEdgeClkSelect,
118 unsigned char hsyncEnable,
119 unsigned char vsyncEnable,
120 unsigned char deskewEnable,
121 unsigned char deskewSetting,
122 unsigned char continuousSyncEnable,
123 unsigned char pllFilterEnable,
124 unsigned char pllFilterValue)
126 unsigned char config;
128 /* Initialize the i2c bus */
131 sm750_hw_i2c_init(1);
133 sm750_sw_i2c_init(DEFAULT_I2C_SCL, DEFAULT_I2C_SDA);
136 /* Check if SII164 Chip exists */
137 if ((sii164GetVendorID() == SII164_VENDOR_ID) && (sii164GetDeviceID() == SII164_DEVICE_ID)) {
139 * Initialize SII164 controller chip.
142 /* Select the edge */
144 config = SII164_CONFIGURATION_LATCH_FALLING;
146 config = SII164_CONFIGURATION_LATCH_RISING;
148 /* Select bus wide */
150 config |= SII164_CONFIGURATION_BUS_12BITS;
152 config |= SII164_CONFIGURATION_BUS_24BITS;
154 /* Select Dual/Single Edge Clock */
155 if (dualEdgeClkSelect == 0)
156 config |= SII164_CONFIGURATION_CLOCK_SINGLE;
158 config |= SII164_CONFIGURATION_CLOCK_DUAL;
160 /* Select HSync Enable */
161 if (hsyncEnable == 0)
162 config |= SII164_CONFIGURATION_HSYNC_FORCE_LOW;
164 config |= SII164_CONFIGURATION_HSYNC_AS_IS;
166 /* Select VSync Enable */
167 if (vsyncEnable == 0)
168 config |= SII164_CONFIGURATION_VSYNC_FORCE_LOW;
170 config |= SII164_CONFIGURATION_VSYNC_AS_IS;
172 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
175 * De-skew enabled with default 111b value.
176 * This fixes some artifacts problem in some mode on board 2.2.
177 * Somehow this fix does not affect board 2.1.
179 if (deskewEnable == 0)
180 config = SII164_DESKEW_DISABLE;
182 config = SII164_DESKEW_ENABLE;
184 switch (deskewSetting) {
186 config |= SII164_DESKEW_1_STEP;
189 config |= SII164_DESKEW_2_STEP;
192 config |= SII164_DESKEW_3_STEP;
195 config |= SII164_DESKEW_4_STEP;
198 config |= SII164_DESKEW_5_STEP;
201 config |= SII164_DESKEW_6_STEP;
204 config |= SII164_DESKEW_7_STEP;
207 config |= SII164_DESKEW_8_STEP;
210 i2cWriteReg(SII164_I2C_ADDRESS, SII164_DESKEW, config);
212 /* Enable/Disable Continuous Sync. */
213 if (continuousSyncEnable == 0)
214 config = SII164_PLL_FILTER_SYNC_CONTINUOUS_DISABLE;
216 config = SII164_PLL_FILTER_SYNC_CONTINUOUS_ENABLE;
218 /* Enable/Disable PLL Filter */
219 if (pllFilterEnable == 0)
220 config |= SII164_PLL_FILTER_DISABLE;
222 config |= SII164_PLL_FILTER_ENABLE;
224 /* Set the PLL Filter value */
225 config |= ((pllFilterValue & 0x07) << 1);
227 i2cWriteReg(SII164_I2C_ADDRESS, SII164_PLL, config);
229 /* Recover from Power Down and enable output. */
230 config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
231 config |= SII164_CONFIGURATION_POWER_NORMAL;
232 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
237 /* Return -1 if initialization fails. */
245 /* below sii164 function is not necessary */
247 #ifdef SII164_FULL_FUNCTIONS
251 * This function resets the DVI Controller Chip.
253 void sii164ResetChip(void)
261 * sii164GetChipString
262 * This function returns a char string name of the current DVI Controller chip.
263 * It's convenient for application need to display the chip name.
265 char *sii164GetChipString(void)
267 return gDviCtrlChipName;
272 * This function sets the power configuration of the DVI Controller Chip.
275 * powerUp - Flag to set the power down or up
277 void sii164SetPower(unsigned char powerUp)
279 unsigned char config;
281 config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
283 /* Power up the chip */
284 config &= ~SII164_CONFIGURATION_POWER_MASK;
285 config |= SII164_CONFIGURATION_POWER_NORMAL;
286 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
288 /* Power down the chip */
289 config &= ~SII164_CONFIGURATION_POWER_MASK;
290 config |= SII164_CONFIGURATION_POWER_DOWN;
291 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
296 * sii164SelectHotPlugDetectionMode
297 * This function selects the mode of the hot plug detection.
299 static void sii164SelectHotPlugDetectionMode(sii164_hot_plug_mode_t hotPlugMode)
301 unsigned char detectReg;
303 detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) &
304 ~SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG;
305 switch (hotPlugMode) {
306 case SII164_HOTPLUG_DISABLE:
307 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH;
309 case SII164_HOTPLUG_USE_MDI:
310 detectReg &= ~SII164_DETECT_INTERRUPT_MASK;
311 detectReg |= SII164_DETECT_INTERRUPT_BY_HTPLG_PIN;
312 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI;
314 case SII164_HOTPLUG_USE_RSEN:
315 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN;
317 case SII164_HOTPLUG_USE_HTPLG:
318 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG;
322 i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg);
326 * sii164EnableHotPlugDetection
327 * This function enables the Hot Plug detection.
329 * enableHotPlug - Enable (=1) / disable (=0) Hot Plug detection
331 void sii164EnableHotPlugDetection(unsigned char enableHotPlug)
333 unsigned char detectReg;
335 detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
337 /* Depending on each DVI controller, need to enable the hot plug based on each
338 * individual chip design.
340 if (enableHotPlug != 0)
341 sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_USE_MDI);
343 sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_DISABLE);
348 * Check if the DVI Monitor is connected.
354 unsigned char sii164IsConnected(void)
356 unsigned char hotPlugValue;
358 hotPlugValue = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) &
359 SII164_DETECT_HOT_PLUG_STATUS_MASK;
360 if (hotPlugValue == SII164_DETECT_HOT_PLUG_STATUS_ON)
367 * sii164CheckInterrupt
368 * Checks if interrupt has occurred.
372 * 1 - Interrupt occurs
374 unsigned char sii164CheckInterrupt(void)
376 unsigned char detectReg;
378 detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) &
379 SII164_DETECT_MONITOR_STATE_MASK;
380 if (detectReg == SII164_DETECT_MONITOR_STATE_CHANGE)
387 * sii164ClearInterrupt
388 * Clear the hot plug interrupt.
390 void sii164ClearInterrupt(void)
392 unsigned char detectReg;
394 /* Clear the MDI interrupt */
395 detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
396 i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT,
397 detectReg | SII164_DETECT_MONITOR_STATE_CLEAR);