]> git.ipfire.org Git - thirdparty/kernel/linux.git/blame - drivers/staging/sm750fb/ddk750_sii164.c
License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[thirdparty/kernel/linux.git] / drivers / staging / sm750fb / ddk750_sii164.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
81dee67e
SM
2#define USE_DVICHIP
3#ifdef USE_DVICHIP
4
5#include "ddk750_sii164.h"
6#include "ddk750_hwi2c.h"
7
8/* I2C Address of each SII164 chip */
9#define SII164_I2C_ADDRESS 0x70
10
11/* Define this definition to use hardware i2c. */
12#define USE_HW_I2C
13
14#ifdef USE_HW_I2C
6bdbe62b 15 #define i2cWriteReg sm750_hw_i2c_write_reg
5ccf7340 16 #define i2cReadReg sm750_hw_i2c_read_reg
81dee67e 17#else
9a357143
MR
18 #define i2cWriteReg sm750_sw_i2c_write_reg
19 #define i2cReadReg sm750_sw_i2c_read_reg
81dee67e
SM
20#endif
21
22/* SII164 Vendor and Device ID */
23#define SII164_VENDOR_ID 0x0001
24#define SII164_DEVICE_ID 0x0006
25
26#ifdef SII164_FULL_FUNCTIONS
27/* Name of the DVI Controller chip */
28static char *gDviCtrlChipName = "Silicon Image SiI 164";
29#endif
30
31/*
32 * sii164GetVendorID
33 * This function gets the vendor ID of the DVI controller chip.
34 *
35 * Output:
36 * Vendor ID
37 */
6fa7db83 38unsigned short sii164GetVendorID(void)
81dee67e 39{
78376535 40 unsigned short vendorID;
81dee67e 41
78376535
JL
42 vendorID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_HIGH) << 8) |
43 (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_LOW);
81dee67e 44
78376535 45 return vendorID;
81dee67e
SM
46}
47
48/*
49 * sii164GetDeviceID
50 * This function gets the device ID of the DVI controller chip.
51 *
52 * Output:
53 * Device ID
54 */
6fa7db83 55unsigned short sii164GetDeviceID(void)
81dee67e 56{
78376535 57 unsigned short deviceID;
81dee67e 58
78376535
JL
59 deviceID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_HIGH) << 8) |
60 (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_LOW);
81dee67e 61
78376535 62 return deviceID;
81dee67e
SM
63}
64
65
66
67/* DVI.C will handle all SiI164 chip stuffs and try it best to make code minimal and useful */
68
69/*
70 * sii164InitChip
71 * This function initialize and detect the DVI controller chip.
72 *
73 * Input:
74 * edgeSelect - Edge Select:
75 * 0 = Input data is falling edge latched (falling edge
76 * latched first in dual edge mode)
77 * 1 = Input data is rising edge latched (rising edge
78 * latched first in dual edge mode)
79 * busSelect - Input Bus Select:
80 * 0 = Input data bus is 12-bits wide
81 * 1 = Input data bus is 24-bits wide
82 * dualEdgeClkSelect - Dual Edge Clock Select
83 * 0 = Input data is single edge latched
84 * 1 = Input data is dual edge latched
85 * hsyncEnable - Horizontal Sync Enable:
86 * 0 = HSYNC input is transmitted as fixed LOW
87 * 1 = HSYNC input is transmitted as is
88 * vsyncEnable - Vertical Sync Enable:
89 * 0 = VSYNC input is transmitted as fixed LOW
90 * 1 = VSYNC input is transmitted as is
91 * deskewEnable - De-skewing Enable:
92 * 0 = De-skew disabled
93 * 1 = De-skew enabled
94 * deskewSetting - De-skewing Setting (increment of 260psec)
95 * 0 = 1 step --> minimum setup / maximum hold
96 * 1 = 2 step
97 * 2 = 3 step
98 * 3 = 4 step
99 * 4 = 5 step
100 * 5 = 6 step
101 * 6 = 7 step
102 * 7 = 8 step --> maximum setup / minimum hold
103 * continuousSyncEnable- SYNC Continuous:
104 * 0 = Disable
105 * 1 = Enable
106 * pllFilterEnable - PLL Filter Enable
107 * 0 = Disable PLL Filter
108 * 1 = Enable PLL Filter
109 * pllFilterValue - PLL Filter characteristics:
110 * 0~7 (recommended value is 4)
111 *
112 * Output:
113 * 0 - Success
114 * -1 - Fail.
115 */
c9750456
MD
116long sii164InitChip(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 126{
81dee67e 127 unsigned char config;
81dee67e 128
78376535 129 /* Initialize the i2c bus */
81dee67e 130#ifdef USE_HW_I2C
78376535 131 /* Use fast mode. */
19f70eae 132 sm750_hw_i2c_init(1);
81dee67e 133#else
f2ea7733 134 sm750_sw_i2c_init(DEFAULT_I2C_SCL, DEFAULT_I2C_SDA);
81dee67e
SM
135#endif
136
78376535 137 /* Check if SII164 Chip exists */
259fef35 138 if ((sii164GetVendorID() == SII164_VENDOR_ID) && (sii164GetDeviceID() == SII164_DEVICE_ID)) {
78376535
JL
139 /*
140 * Initialize SII164 controller chip.
141 */
142
143 /* Select the edge */
144 if (edgeSelect == 0)
145 config = SII164_CONFIGURATION_LATCH_FALLING;
146 else
147 config = SII164_CONFIGURATION_LATCH_RISING;
148
149 /* Select bus wide */
150 if (busSelect == 0)
151 config |= SII164_CONFIGURATION_BUS_12BITS;
152 else
153 config |= SII164_CONFIGURATION_BUS_24BITS;
154
155 /* Select Dual/Single Edge Clock */
156 if (dualEdgeClkSelect == 0)
157 config |= SII164_CONFIGURATION_CLOCK_SINGLE;
158 else
159 config |= SII164_CONFIGURATION_CLOCK_DUAL;
160
161 /* Select HSync Enable */
162 if (hsyncEnable == 0)
163 config |= SII164_CONFIGURATION_HSYNC_FORCE_LOW;
164 else
165 config |= SII164_CONFIGURATION_HSYNC_AS_IS;
166
167 /* Select VSync Enable */
168 if (vsyncEnable == 0)
169 config |= SII164_CONFIGURATION_VSYNC_FORCE_LOW;
170 else
171 config |= SII164_CONFIGURATION_VSYNC_AS_IS;
172
173 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
174
f5016082
ES
175 /*
176 * De-skew enabled with default 111b value.
35e4d8ca
EF
177 * This fixes some artifacts problem in some mode on board 2.2.
178 * Somehow this fix does not affect board 2.1.
78376535
JL
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
81dee67e
SM
261/*
262 * sii164GetChipString
263 * This function returns a char string name of the current DVI Controller chip.
264 * It's convenient for application need to display the chip name.
265 */
6fa7db83 266char *sii164GetChipString(void)
81dee67e 267{
78376535 268 return gDviCtrlChipName;
81dee67e
SM
269}
270
81dee67e
SM
271/*
272 * sii164SetPower
273 * This function sets the power configuration of the DVI Controller Chip.
274 *
275 * Input:
276 * powerUp - Flag to set the power down or up
277 */
c9750456 278void sii164SetPower(unsigned char powerUp)
81dee67e 279{
78376535
JL
280 unsigned char config;
281
282 config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
259fef35 283 if (powerUp == 1) {
78376535
JL
284 /* Power up the chip */
285 config &= ~SII164_CONFIGURATION_POWER_MASK;
286 config |= SII164_CONFIGURATION_POWER_NORMAL;
287 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
259fef35 288 } else {
78376535
JL
289 /* Power down the chip */
290 config &= ~SII164_CONFIGURATION_POWER_MASK;
291 config |= SII164_CONFIGURATION_POWER_DOWN;
292 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
293 }
81dee67e
SM
294}
295
81dee67e
SM
296/*
297 * sii164SelectHotPlugDetectionMode
298 * This function selects the mode of the hot plug detection.
299 */
c9750456 300static void sii164SelectHotPlugDetectionMode(sii164_hot_plug_mode_t hotPlugMode)
81dee67e 301{
78376535
JL
302 unsigned char detectReg;
303
c9750456
MD
304 detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) &
305 ~SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG;
259fef35 306 switch (hotPlugMode) {
78376535
JL
307 case SII164_HOTPLUG_DISABLE:
308 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH;
309 break;
310 case SII164_HOTPLUG_USE_MDI:
311 detectReg &= ~SII164_DETECT_INTERRUPT_MASK;
312 detectReg |= SII164_DETECT_INTERRUPT_BY_HTPLG_PIN;
313 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI;
314 break;
315 case SII164_HOTPLUG_USE_RSEN:
316 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN;
317 break;
318 case SII164_HOTPLUG_USE_HTPLG:
319 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG;
320 break;
321 }
322
323 i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg);
81dee67e
SM
324}
325
326/*
327 * sii164EnableHotPlugDetection
328 * This function enables the Hot Plug detection.
329 *
330 * enableHotPlug - Enable (=1) / disable (=0) Hot Plug detection
331 */
c9750456 332void sii164EnableHotPlugDetection(unsigned char enableHotPlug)
81dee67e 333{
78376535 334 unsigned char detectReg;
40403c1b 335
78376535
JL
336 detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
337
338 /* Depending on each DVI controller, need to enable the hot plug based on each
35e4d8ca
EF
339 * individual chip design.
340 */
78376535
JL
341 if (enableHotPlug != 0)
342 sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_USE_MDI);
343 else
344 sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_DISABLE);
81dee67e
SM
345}
346
347/*
348 * sii164IsConnected
349 * Check if the DVI Monitor is connected.
350 *
351 * Output:
352 * 0 - Not Connected
353 * 1 - Connected
354 */
6fa7db83 355unsigned char sii164IsConnected(void)
81dee67e 356{
78376535 357 unsigned char hotPlugValue;
81dee67e 358
c9750456
MD
359 hotPlugValue = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) &
360 SII164_DETECT_HOT_PLUG_STATUS_MASK;
78376535
JL
361 if (hotPlugValue == SII164_DETECT_HOT_PLUG_STATUS_ON)
362 return 1;
363 else
364 return 0;
81dee67e
SM
365}
366
367/*
368 * sii164CheckInterrupt
69e98df7 369 * Checks if interrupt has occurred.
81dee67e
SM
370 *
371 * Output:
372 * 0 - No interrupt
373 * 1 - Interrupt occurs
374 */
6fa7db83 375unsigned char sii164CheckInterrupt(void)
81dee67e 376{
78376535 377 unsigned char detectReg;
81dee67e 378
c9750456
MD
379 detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) &
380 SII164_DETECT_MONITOR_STATE_MASK;
78376535
JL
381 if (detectReg == SII164_DETECT_MONITOR_STATE_CHANGE)
382 return 1;
383 else
384 return 0;
81dee67e
SM
385}
386
387/*
388 * sii164ClearInterrupt
389 * Clear the hot plug interrupt.
390 */
6fa7db83 391void sii164ClearInterrupt(void)
81dee67e 392{
78376535 393 unsigned char detectReg;
81dee67e 394
78376535
JL
395 /* Clear the MDI interrupt */
396 detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
c9750456
MD
397 i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT,
398 detectReg | SII164_DETECT_MONITOR_STATE_CLEAR);
81dee67e
SM
399}
400
401#endif
402
403#endif
404
405