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 hwI2CWriteReg
15     #define i2cReadReg  hwI2CReadReg
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 */
27 static 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  */
sii164GetVendorID(void)37 unsigned 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  */
sii164GetDeviceID(void)54 unsigned 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  */
sii164InitChip(unsigned char edgeSelect,unsigned char busSelect,unsigned char dualEdgeClkSelect,unsigned char hsyncEnable,unsigned char vsyncEnable,unsigned char deskewEnable,unsigned char deskewSetting,unsigned char continuousSyncEnable,unsigned char pllFilterEnable,unsigned char pllFilterValue)115 long 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 ucRegIndex, ucRegValue;
129     //unsigned char ucDeviceAddress,
130 	unsigned char config;
131     //unsigned long delayCount;
132 
133     /* Initialize the i2c bus */
134 #ifdef USE_HW_I2C
135     /* Use fast mode. */
136     hwI2CInit(1);
137 #else
138     swI2CInit(DEFAULT_I2C_SCL, DEFAULT_I2C_SDA);
139 #endif
140 
141     /* Check if SII164 Chip exists */
142     if ((sii164GetVendorID() == SII164_VENDOR_ID) && (sii164GetDeviceID() == SII164_DEVICE_ID))
143     {
144 
145 #ifdef DDKDEBUG
146         //sii164PrintRegisterValues();
147 #endif
148         /*
149          *  Initialize SII164 controller chip.
150          */
151 
152         /* Select the edge */
153         if (edgeSelect == 0)
154             config = SII164_CONFIGURATION_LATCH_FALLING;
155         else
156             config = SII164_CONFIGURATION_LATCH_RISING;
157 
158         /* Select bus wide */
159         if (busSelect == 0)
160             config |= SII164_CONFIGURATION_BUS_12BITS;
161         else
162             config |= SII164_CONFIGURATION_BUS_24BITS;
163 
164         /* Select Dual/Single Edge Clock */
165         if (dualEdgeClkSelect == 0)
166             config |= SII164_CONFIGURATION_CLOCK_SINGLE;
167         else
168             config |= SII164_CONFIGURATION_CLOCK_DUAL;
169 
170         /* Select HSync Enable */
171         if (hsyncEnable == 0)
172             config |= SII164_CONFIGURATION_HSYNC_FORCE_LOW;
173         else
174             config |= SII164_CONFIGURATION_HSYNC_AS_IS;
175 
176         /* Select VSync Enable */
177         if (vsyncEnable == 0)
178             config |= SII164_CONFIGURATION_VSYNC_FORCE_LOW;
179         else
180             config |= SII164_CONFIGURATION_VSYNC_AS_IS;
181 
182         i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
183 
184         /* De-skew enabled with default 111b value.
185            This will fix some artifacts problem in some mode on board 2.2.
186            Somehow this fix does not affect board 2.1.
187          */
188         if (deskewEnable == 0)
189             config = SII164_DESKEW_DISABLE;
190         else
191             config = SII164_DESKEW_ENABLE;
192 
193         switch (deskewSetting)
194         {
195             case 0:
196                 config |= SII164_DESKEW_1_STEP;
197                 break;
198             case 1:
199                 config |= SII164_DESKEW_2_STEP;
200                 break;
201             case 2:
202                 config |= SII164_DESKEW_3_STEP;
203                 break;
204             case 3:
205                 config |= SII164_DESKEW_4_STEP;
206                 break;
207             case 4:
208                 config |= SII164_DESKEW_5_STEP;
209                 break;
210             case 5:
211                 config |= SII164_DESKEW_6_STEP;
212                 break;
213             case 6:
214                 config |= SII164_DESKEW_7_STEP;
215                 break;
216             case 7:
217                 config |= SII164_DESKEW_8_STEP;
218                 break;
219         }
220         i2cWriteReg(SII164_I2C_ADDRESS, SII164_DESKEW, config);
221 
222         /* Enable/Disable Continuous Sync. */
223         if (continuousSyncEnable == 0)
224             config = SII164_PLL_FILTER_SYNC_CONTINUOUS_DISABLE;
225         else
226             config = SII164_PLL_FILTER_SYNC_CONTINUOUS_ENABLE;
227 
228         /* Enable/Disable PLL Filter */
229         if (pllFilterEnable == 0)
230             config |= SII164_PLL_FILTER_DISABLE;
231         else
232             config |= SII164_PLL_FILTER_ENABLE;
233 
234         /* Set the PLL Filter value */
235         config |= ((pllFilterValue & 0x07) << 1);
236 
237         i2cWriteReg(SII164_I2C_ADDRESS, SII164_PLL, config);
238 
239         /* Recover from Power Down and enable output. */
240         config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
241         config |= SII164_CONFIGURATION_POWER_NORMAL;
242         i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
243 
244 #ifdef DDKDEBUG
245         //sii164PrintRegisterValues();
246 #endif
247 
248         return 0;
249     }
250 
251     /* Return -1 if initialization fails. */
252     return (-1);
253 }
254 
255 
256 
257 
258 
259 /* below sii164 function is not neccessary */
260 
261 #ifdef SII164_FULL_FUNCTIONS
262 
263 /*
264  *  sii164ResetChip
265  *      This function resets the DVI Controller Chip.
266  */
sii164ResetChip(void)267 void sii164ResetChip(void)
268 {
269     /* Power down */
270     sii164SetPower(0);
271     sii164SetPower(1);
272 }
273 
274 
275 /*
276  * sii164GetChipString
277  *      This function returns a char string name of the current DVI Controller chip.
278  *      It's convenient for application need to display the chip name.
279  */
sii164GetChipString(void)280 char *sii164GetChipString(void)
281 {
282     return gDviCtrlChipName;
283 }
284 
285 
286 /*
287  *  sii164SetPower
288  *      This function sets the power configuration of the DVI Controller Chip.
289  *
290  *  Input:
291  *      powerUp - Flag to set the power down or up
292  */
sii164SetPower(unsigned char powerUp)293 void sii164SetPower(
294     unsigned char powerUp
295 )
296 {
297     unsigned char config;
298 
299     config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
300     if (powerUp == 1)
301     {
302         /* Power up the chip */
303         config &= ~SII164_CONFIGURATION_POWER_MASK;
304         config |= SII164_CONFIGURATION_POWER_NORMAL;
305         i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
306     }
307     else
308     {
309         /* Power down the chip */
310         config &= ~SII164_CONFIGURATION_POWER_MASK;
311         config |= SII164_CONFIGURATION_POWER_DOWN;
312         i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
313     }
314 }
315 
316 
317 /*
318  *  sii164SelectHotPlugDetectionMode
319  *      This function selects the mode of the hot plug detection.
320  */
sii164SelectHotPlugDetectionMode(sii164_hot_plug_mode_t hotPlugMode)321 static void sii164SelectHotPlugDetectionMode(
322     sii164_hot_plug_mode_t hotPlugMode
323 )
324 {
325     unsigned char detectReg;
326 
327     detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & ~SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG;
328     switch (hotPlugMode)
329     {
330         case SII164_HOTPLUG_DISABLE:
331             detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH;
332             break;
333         case SII164_HOTPLUG_USE_MDI:
334             detectReg &= ~SII164_DETECT_INTERRUPT_MASK;
335             detectReg |= SII164_DETECT_INTERRUPT_BY_HTPLG_PIN;
336             detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI;
337             break;
338         case SII164_HOTPLUG_USE_RSEN:
339             detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN;
340             break;
341         case SII164_HOTPLUG_USE_HTPLG:
342             detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG;
343             break;
344     }
345 
346     i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg);
347 }
348 
349 /*
350  *  sii164EnableHotPlugDetection
351  *      This function enables the Hot Plug detection.
352  *
353  *  enableHotPlug   - Enable (=1) / disable (=0) Hot Plug detection
354  */
sii164EnableHotPlugDetection(unsigned char enableHotPlug)355 void sii164EnableHotPlugDetection(
356     unsigned char enableHotPlug
357 )
358 {
359     unsigned char detectReg;
360     detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
361 
362     /* Depending on each DVI controller, need to enable the hot plug based on each
363        individual chip design. */
364     if (enableHotPlug != 0)
365         sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_USE_MDI);
366     else
367         sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_DISABLE);
368 }
369 
370 /*
371  *  sii164IsConnected
372  *      Check if the DVI Monitor is connected.
373  *
374  *  Output:
375  *      0   - Not Connected
376  *      1   - Connected
377  */
sii164IsConnected(void)378 unsigned char sii164IsConnected(void)
379 {
380     unsigned char hotPlugValue;
381 
382     hotPlugValue = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & SII164_DETECT_HOT_PLUG_STATUS_MASK;
383     if (hotPlugValue == SII164_DETECT_HOT_PLUG_STATUS_ON)
384         return 1;
385     else
386         return 0;
387 }
388 
389 /*
390  *  sii164CheckInterrupt
391  *      Checks if interrupt has occured.
392  *
393  *  Output:
394  *      0   - No interrupt
395  *      1   - Interrupt occurs
396  */
sii164CheckInterrupt(void)397 unsigned char sii164CheckInterrupt(void)
398 {
399     unsigned char detectReg;
400 
401     detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & SII164_DETECT_MONITOR_STATE_MASK;
402     if (detectReg == SII164_DETECT_MONITOR_STATE_CHANGE)
403         return 1;
404     else
405         return 0;
406 }
407 
408 /*
409  *  sii164ClearInterrupt
410  *      Clear the hot plug interrupt.
411  */
sii164ClearInterrupt(void)412 void sii164ClearInterrupt(void)
413 {
414     unsigned char detectReg;
415 
416     /* Clear the MDI interrupt */
417     detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
418     i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg | SII164_DETECT_MONITOR_STATE_CLEAR);
419 }
420 
421 #endif
422 
423 #endif
424 
425 
426