Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial
[deliverable/linux.git] / drivers / staging / sm750fb / ddk750_sii164.c
CommitLineData
81dee67e
SM
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
6bdbe62b 14 #define i2cWriteReg sm750_hw_i2c_write_reg
5ccf7340 15 #define i2cReadReg sm750_hw_i2c_read_reg
81dee67e 16#else
9a357143
MR
17 #define i2cWriteReg sm750_sw_i2c_write_reg
18 #define i2cReadReg sm750_sw_i2c_read_reg
81dee67e
SM
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 */
6fa7db83 37unsigned short sii164GetVendorID(void)
81dee67e 38{
78376535 39 unsigned short vendorID;
81dee67e 40
78376535
JL
41 vendorID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_HIGH) << 8) |
42 (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_LOW);
81dee67e 43
78376535 44 return vendorID;
81dee67e
SM
45}
46
47/*
48 * sii164GetDeviceID
49 * This function gets the device ID of the DVI controller chip.
50 *
51 * Output:
52 * Device ID
53 */
6fa7db83 54unsigned short sii164GetDeviceID(void)
81dee67e 55{
78376535 56 unsigned short deviceID;
81dee67e 57
78376535
JL
58 deviceID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_HIGH) << 8) |
59 (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_LOW);
81dee67e 60
78376535 61 return deviceID;
81dee67e
SM
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(
78376535
JL
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
81dee67e
SM
126)
127{
81dee67e 128 unsigned char config;
81dee67e 129
78376535 130 /* Initialize the i2c bus */
81dee67e 131#ifdef USE_HW_I2C
78376535 132 /* Use fast mode. */
19f70eae 133 sm750_hw_i2c_init(1);
81dee67e 134#else
f2ea7733 135 sm750_sw_i2c_init(DEFAULT_I2C_SCL, DEFAULT_I2C_SDA);
81dee67e
SM
136#endif
137
78376535 138 /* Check if SII164 Chip exists */
259fef35 139 if ((sii164GetVendorID() == SII164_VENDOR_ID) && (sii164GetDeviceID() == SII164_DEVICE_ID)) {
78376535
JL
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
259fef35 185 switch (deskewSetting) {
78376535
JL
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. */
732053a0 239 return -1;
81dee67e
SM
240}
241
242
243
244
245
69e98df7 246/* below sii164 function is not necessary */
81dee67e
SM
247
248#ifdef SII164_FULL_FUNCTIONS
249
250/*
251 * sii164ResetChip
252 * This function resets the DVI Controller Chip.
253 */
6fa7db83 254void sii164ResetChip(void)
81dee67e 255{
78376535
JL
256 /* Power down */
257 sii164SetPower(0);
258 sii164SetPower(1);
81dee67e
SM
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 */
6fa7db83 267char *sii164GetChipString(void)
81dee67e 268{
78376535 269 return gDviCtrlChipName;
81dee67e
SM
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(
78376535 281 unsigned char powerUp
81dee67e
SM
282)
283{
78376535
JL
284 unsigned char config;
285
286 config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
259fef35 287 if (powerUp == 1) {
78376535
JL
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);
259fef35 292 } else {
78376535
JL
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 }
81dee67e
SM
298}
299
300
301/*
302 * sii164SelectHotPlugDetectionMode
303 * This function selects the mode of the hot plug detection.
304 */
305static void sii164SelectHotPlugDetectionMode(
78376535 306 sii164_hot_plug_mode_t hotPlugMode
81dee67e
SM
307)
308{
78376535
JL
309 unsigned char detectReg;
310
311 detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & ~SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG;
259fef35 312 switch (hotPlugMode) {
78376535
JL
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);
81dee67e
SM
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(
78376535 339 unsigned char enableHotPlug
81dee67e
SM
340)
341{
78376535 342 unsigned char detectReg;
40403c1b 343
78376535
JL
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);
81dee67e
SM
352}
353
354/*
355 * sii164IsConnected
356 * Check if the DVI Monitor is connected.
357 *
358 * Output:
359 * 0 - Not Connected
360 * 1 - Connected
361 */
6fa7db83 362unsigned char sii164IsConnected(void)
81dee67e 363{
78376535 364 unsigned char hotPlugValue;
81dee67e 365
78376535
JL
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;
81dee67e
SM
371}
372
373/*
374 * sii164CheckInterrupt
69e98df7 375 * Checks if interrupt has occurred.
81dee67e
SM
376 *
377 * Output:
378 * 0 - No interrupt
379 * 1 - Interrupt occurs
380 */
6fa7db83 381unsigned char sii164CheckInterrupt(void)
81dee67e 382{
78376535 383 unsigned char detectReg;
81dee67e 384
78376535
JL
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;
81dee67e
SM
390}
391
392/*
393 * sii164ClearInterrupt
394 * Clear the hot plug interrupt.
395 */
6fa7db83 396void sii164ClearInterrupt(void)
81dee67e 397{
78376535 398 unsigned char detectReg;
81dee67e 399
78376535
JL
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);
81dee67e
SM
403}
404
405#endif
406
407#endif
408
409
This page took 0.639737 seconds and 5 git commands to generate.