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