]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/staging/sm750fb/ddk750_sii164.c
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[mirror_ubuntu-artful-kernel.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
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 */
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
SM
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 */
6fa7db83 54unsigned short sii164GetDeviceID(void)
81dee67e
SM
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 */
115long 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 */
6fa7db83 267void sii164ResetChip(void)
81dee67e
SM
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 */
6fa7db83 280char *sii164GetChipString(void)
81dee67e
SM
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 */
293void 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 */
321static 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 */
355void 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 */
6fa7db83 378unsigned char sii164IsConnected(void)
81dee67e
SM
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 */
6fa7db83 397unsigned char sii164CheckInterrupt(void)
81dee67e
SM
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 */
6fa7db83 412void sii164ClearInterrupt(void)
81dee67e
SM
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