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)
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
128 unsigned char config;
130 /* Initialize the i2c bus */
133 sm750_hw_i2c_init(1);
135 sm750_sw_i2c_init(DEFAULT_I2C_SCL, DEFAULT_I2C_SDA);
138 /* Check if SII164 Chip exists */
139 if ((sii164GetVendorID() == SII164_VENDOR_ID) && (sii164GetDeviceID() == SII164_DEVICE_ID)) {
141 * Initialize SII164 controller chip.
144 /* Select the edge */
146 config = SII164_CONFIGURATION_LATCH_FALLING;
148 config = SII164_CONFIGURATION_LATCH_RISING;
150 /* Select bus wide */
152 config |= SII164_CONFIGURATION_BUS_12BITS;
154 config |= SII164_CONFIGURATION_BUS_24BITS;
156 /* Select Dual/Single Edge Clock */
157 if (dualEdgeClkSelect == 0)
158 config |= SII164_CONFIGURATION_CLOCK_SINGLE;
160 config |= SII164_CONFIGURATION_CLOCK_DUAL;
162 /* Select HSync Enable */
163 if (hsyncEnable == 0)
164 config |= SII164_CONFIGURATION_HSYNC_FORCE_LOW;
166 config |= SII164_CONFIGURATION_HSYNC_AS_IS;
168 /* Select VSync Enable */
169 if (vsyncEnable == 0)
170 config |= SII164_CONFIGURATION_VSYNC_FORCE_LOW;
172 config |= SII164_CONFIGURATION_VSYNC_AS_IS;
174 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
177 * De-skew enabled with default 111b value.
178 * This fixes some artifacts problem in some mode on board 2.2.
179 * Somehow this fix does not affect board 2.1.
181 if (deskewEnable == 0)
182 config = SII164_DESKEW_DISABLE;
184 config = SII164_DESKEW_ENABLE;
186 switch (deskewSetting) {
188 config |= SII164_DESKEW_1_STEP;
191 config |= SII164_DESKEW_2_STEP;
194 config |= SII164_DESKEW_3_STEP;
197 config |= SII164_DESKEW_4_STEP;
200 config |= SII164_DESKEW_5_STEP;
203 config |= SII164_DESKEW_6_STEP;
206 config |= SII164_DESKEW_7_STEP;
209 config |= SII164_DESKEW_8_STEP;
212 i2cWriteReg(SII164_I2C_ADDRESS, SII164_DESKEW, config);
214 /* Enable/Disable Continuous Sync. */
215 if (continuousSyncEnable == 0)
216 config = SII164_PLL_FILTER_SYNC_CONTINUOUS_DISABLE;
218 config = SII164_PLL_FILTER_SYNC_CONTINUOUS_ENABLE;
220 /* Enable/Disable PLL Filter */
221 if (pllFilterEnable == 0)
222 config |= SII164_PLL_FILTER_DISABLE;
224 config |= SII164_PLL_FILTER_ENABLE;
226 /* Set the PLL Filter value */
227 config |= ((pllFilterValue & 0x07) << 1);
229 i2cWriteReg(SII164_I2C_ADDRESS, SII164_PLL, config);
231 /* Recover from Power Down and enable output. */
232 config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
233 config |= SII164_CONFIGURATION_POWER_NORMAL;
234 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
239 /* Return -1 if initialization fails. */
247 /* below sii164 function is not necessary */
249 #ifdef SII164_FULL_FUNCTIONS
253 * This function resets the DVI Controller Chip.
255 void sii164ResetChip(void)
264 * sii164GetChipString
265 * This function returns a char string name of the current DVI Controller chip.
266 * It's convenient for application need to display the chip name.
268 char *sii164GetChipString(void)
270 return gDviCtrlChipName;
276 * This function sets the power configuration of the DVI Controller Chip.
279 * powerUp - Flag to set the power down or up
282 unsigned char powerUp
285 unsigned char config;
287 config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
289 /* Power up the chip */
290 config &= ~SII164_CONFIGURATION_POWER_MASK;
291 config |= SII164_CONFIGURATION_POWER_NORMAL;
292 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
294 /* Power down the chip */
295 config &= ~SII164_CONFIGURATION_POWER_MASK;
296 config |= SII164_CONFIGURATION_POWER_DOWN;
297 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
303 * sii164SelectHotPlugDetectionMode
304 * This function selects the mode of the hot plug detection.
306 static void sii164SelectHotPlugDetectionMode(
307 sii164_hot_plug_mode_t hotPlugMode
310 unsigned char detectReg;
312 detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & ~SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG;
313 switch (hotPlugMode) {
314 case SII164_HOTPLUG_DISABLE:
315 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH;
317 case SII164_HOTPLUG_USE_MDI:
318 detectReg &= ~SII164_DETECT_INTERRUPT_MASK;
319 detectReg |= SII164_DETECT_INTERRUPT_BY_HTPLG_PIN;
320 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI;
322 case SII164_HOTPLUG_USE_RSEN:
323 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN;
325 case SII164_HOTPLUG_USE_HTPLG:
326 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG;
330 i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg);
334 * sii164EnableHotPlugDetection
335 * This function enables the Hot Plug detection.
337 * enableHotPlug - Enable (=1) / disable (=0) Hot Plug detection
339 void sii164EnableHotPlugDetection(
340 unsigned char enableHotPlug
343 unsigned char detectReg;
345 detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
347 /* Depending on each DVI controller, need to enable the hot plug based on each
348 * individual chip design.
350 if (enableHotPlug != 0)
351 sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_USE_MDI);
353 sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_DISABLE);
358 * Check if the DVI Monitor is connected.
364 unsigned char sii164IsConnected(void)
366 unsigned char hotPlugValue;
368 hotPlugValue = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & SII164_DETECT_HOT_PLUG_STATUS_MASK;
369 if (hotPlugValue == SII164_DETECT_HOT_PLUG_STATUS_ON)
376 * sii164CheckInterrupt
377 * Checks if interrupt has occurred.
381 * 1 - Interrupt occurs
383 unsigned char sii164CheckInterrupt(void)
385 unsigned char detectReg;
387 detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & SII164_DETECT_MONITOR_STATE_MASK;
388 if (detectReg == SII164_DETECT_MONITOR_STATE_CHANGE)
395 * sii164ClearInterrupt
396 * Clear the hot plug interrupt.
398 void sii164ClearInterrupt(void)
400 unsigned char detectReg;
402 /* Clear the MDI interrupt */
403 detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
404 i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg | SII164_DETECT_MONITOR_STATE_CLEAR);