root/drivers/staging/sm750fb/ddk750_sii164.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sii164GetVendorID
  2. sii164GetDeviceID
  3. sii164InitChip
  4. sii164ResetChip
  5. sii164GetChipString
  6. sii164SetPower
  7. sii164SelectHotPlugDetectionMode
  8. sii164EnableHotPlugDetection
  9. sii164IsConnected
  10. sii164CheckInterrupt
  11. sii164ClearInterrupt

   1 // SPDX-License-Identifier: GPL-2.0
   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
  15     #define i2cWriteReg sm750_hw_i2c_write_reg
  16     #define i2cReadReg  sm750_hw_i2c_read_reg
  17 #else
  18     #define i2cWriteReg sm750_sw_i2c_write_reg
  19     #define i2cReadReg  sm750_sw_i2c_read_reg
  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 */
  28 static 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  */
  38 unsigned short sii164GetVendorID(void)
  39 {
  40         unsigned short vendorID;
  41 
  42         vendorID = ((unsigned short)i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_HIGH) << 8) |
  43                     (unsigned short)i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_LOW);
  44 
  45         return vendorID;
  46 }
  47 
  48 /*
  49  *  sii164GetDeviceID
  50  *      This function gets the device ID of the DVI controller chip.
  51  *
  52  *  Output:
  53  *      Device ID
  54  */
  55 unsigned short sii164GetDeviceID(void)
  56 {
  57         unsigned short deviceID;
  58 
  59         deviceID = ((unsigned short)i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_HIGH) << 8) |
  60                     (unsigned short)i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_LOW);
  61 
  62         return deviceID;
  63 }
  64 
  65 /* DVI.C will handle all SiI164 chip stuffs and try it best to make code minimal and useful */
  66 
  67 /*
  68  *  sii164InitChip
  69  *      This function initialize and detect the DVI controller chip.
  70  *
  71  *  Input:
  72  *      edge_select           - Edge Select:
  73  *                               0 = Input data is falling edge latched (falling
  74  *                                   edge latched first in dual edge mode)
  75  *                               1 = Input data is rising edge latched (rising
  76  *                                   edge latched first in dual edge mode)
  77  *      bus_select            - Input Bus Select:
  78  *                               0 = Input data bus is 12-bits wide
  79  *                               1 = Input data bus is 24-bits wide
  80  *      dual_edge_clk_select  - Dual Edge Clock Select
  81  *                               0 = Input data is single edge latched
  82  *                               1 = Input data is dual edge latched
  83  *      hsync_enable          - Horizontal Sync Enable:
  84  *                               0 = HSYNC input is transmitted as fixed LOW
  85  *                               1 = HSYNC input is transmitted as is
  86  *      vsync_enable          - Vertical Sync Enable:
  87  *                               0 = VSYNC input is transmitted as fixed LOW
  88  *                               1 = VSYNC input is transmitted as is
  89  *      deskew_enable         - De-skewing Enable:
  90  *                               0 = De-skew disabled
  91  *                               1 = De-skew enabled
  92  *      deskew_setting        - De-skewing Setting (increment of 260psec)
  93  *                               0 = 1 step --> minimum setup / maximum hold
  94  *                               1 = 2 step
  95  *                               2 = 3 step
  96  *                               3 = 4 step
  97  *                               4 = 5 step
  98  *                               5 = 6 step
  99  *                               6 = 7 step
 100  *                               7 = 8 step --> maximum setup / minimum hold
 101  *      continuous_sync_enable- SYNC Continuous:
 102  *                               0 = Disable
 103  *                               1 = Enable
 104  *      pll_filter_enable     - PLL Filter Enable
 105  *                               0 = Disable PLL Filter
 106  *                               1 = Enable PLL Filter
 107  *      pll_filter_value      - PLL Filter characteristics:
 108  *                               0~7 (recommended value is 4)
 109  *
 110  *  Output:
 111  *      0   - Success
 112  *     -1   - Fail.
 113  */
 114 long sii164InitChip(unsigned char edge_select,
 115                     unsigned char bus_select,
 116                     unsigned char dual_edge_clk_select,
 117                     unsigned char hsync_enable,
 118                     unsigned char vsync_enable,
 119                     unsigned char deskew_enable,
 120                     unsigned char deskew_setting,
 121                     unsigned char continuous_sync_enable,
 122                     unsigned char pll_filter_enable,
 123                     unsigned char pll_filter_value)
 124 {
 125         unsigned char config;
 126 
 127         /* Initialize the i2c bus */
 128 #ifdef USE_HW_I2C
 129         /* Use fast mode. */
 130         sm750_hw_i2c_init(1);
 131 #else
 132         sm750_sw_i2c_init(DEFAULT_I2C_SCL, DEFAULT_I2C_SDA);
 133 #endif
 134 
 135         /* Check if SII164 Chip exists */
 136         if ((sii164GetVendorID() == SII164_VENDOR_ID) && (sii164GetDeviceID() == SII164_DEVICE_ID)) {
 137                 /*
 138                  *  Initialize SII164 controller chip.
 139                  */
 140 
 141                 /* Select the edge */
 142                 if (edge_select == 0)
 143                         config = SII164_CONFIGURATION_LATCH_FALLING;
 144                 else
 145                         config = SII164_CONFIGURATION_LATCH_RISING;
 146 
 147                 /* Select bus wide */
 148                 if (bus_select == 0)
 149                         config |= SII164_CONFIGURATION_BUS_12BITS;
 150                 else
 151                         config |= SII164_CONFIGURATION_BUS_24BITS;
 152 
 153                 /* Select Dual/Single Edge Clock */
 154                 if (dual_edge_clk_select == 0)
 155                         config |= SII164_CONFIGURATION_CLOCK_SINGLE;
 156                 else
 157                         config |= SII164_CONFIGURATION_CLOCK_DUAL;
 158 
 159                 /* Select HSync Enable */
 160                 if (hsync_enable == 0)
 161                         config |= SII164_CONFIGURATION_HSYNC_FORCE_LOW;
 162                 else
 163                         config |= SII164_CONFIGURATION_HSYNC_AS_IS;
 164 
 165                 /* Select VSync Enable */
 166                 if (vsync_enable == 0)
 167                         config |= SII164_CONFIGURATION_VSYNC_FORCE_LOW;
 168                 else
 169                         config |= SII164_CONFIGURATION_VSYNC_AS_IS;
 170 
 171                 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
 172 
 173                 /*
 174                  * De-skew enabled with default 111b value.
 175                  * This fixes some artifacts problem in some mode on board 2.2.
 176                  * Somehow this fix does not affect board 2.1.
 177                  */
 178                 if (deskew_enable == 0)
 179                         config = SII164_DESKEW_DISABLE;
 180                 else
 181                         config = SII164_DESKEW_ENABLE;
 182 
 183                 switch (deskew_setting) {
 184                 case 0:
 185                         config |= SII164_DESKEW_1_STEP;
 186                         break;
 187                 case 1:
 188                         config |= SII164_DESKEW_2_STEP;
 189                         break;
 190                 case 2:
 191                         config |= SII164_DESKEW_3_STEP;
 192                         break;
 193                 case 3:
 194                         config |= SII164_DESKEW_4_STEP;
 195                         break;
 196                 case 4:
 197                         config |= SII164_DESKEW_5_STEP;
 198                         break;
 199                 case 5:
 200                         config |= SII164_DESKEW_6_STEP;
 201                         break;
 202                 case 6:
 203                         config |= SII164_DESKEW_7_STEP;
 204                         break;
 205                 case 7:
 206                         config |= SII164_DESKEW_8_STEP;
 207                         break;
 208                 }
 209                 i2cWriteReg(SII164_I2C_ADDRESS, SII164_DESKEW, config);
 210 
 211                 /* Enable/Disable Continuous Sync. */
 212                 if (continuous_sync_enable == 0)
 213                         config = SII164_PLL_FILTER_SYNC_CONTINUOUS_DISABLE;
 214                 else
 215                         config = SII164_PLL_FILTER_SYNC_CONTINUOUS_ENABLE;
 216 
 217                 /* Enable/Disable PLL Filter */
 218                 if (pll_filter_enable == 0)
 219                         config |= SII164_PLL_FILTER_DISABLE;
 220                 else
 221                         config |= SII164_PLL_FILTER_ENABLE;
 222 
 223                 /* Set the PLL Filter value */
 224                 config |= ((pll_filter_value & 0x07) << 1);
 225 
 226                 i2cWriteReg(SII164_I2C_ADDRESS, SII164_PLL, config);
 227 
 228                 /* Recover from Power Down and enable output. */
 229                 config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
 230                 config |= SII164_CONFIGURATION_POWER_NORMAL;
 231                 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
 232 
 233                 return 0;
 234         }
 235 
 236         /* Return -1 if initialization fails. */
 237         return -1;
 238 }
 239 
 240 /* below sii164 function is not necessary */
 241 
 242 #ifdef SII164_FULL_FUNCTIONS
 243 
 244 /*
 245  *  sii164ResetChip
 246  *      This function resets the DVI Controller Chip.
 247  */
 248 void sii164ResetChip(void)
 249 {
 250         /* Power down */
 251         sii164SetPower(0);
 252         sii164SetPower(1);
 253 }
 254 
 255 /*
 256  * sii164GetChipString
 257  *      This function returns a char string name of the current DVI Controller chip.
 258  *      It's convenient for application need to display the chip name.
 259  */
 260 char *sii164GetChipString(void)
 261 {
 262         return gDviCtrlChipName;
 263 }
 264 
 265 /*
 266  *  sii164SetPower
 267  *      This function sets the power configuration of the DVI Controller Chip.
 268  *
 269  *  Input:
 270  *      powerUp - Flag to set the power down or up
 271  */
 272 void sii164SetPower(unsigned char powerUp)
 273 {
 274         unsigned char config;
 275 
 276         config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
 277         if (powerUp == 1) {
 278                 /* Power up the chip */
 279                 config &= ~SII164_CONFIGURATION_POWER_MASK;
 280                 config |= SII164_CONFIGURATION_POWER_NORMAL;
 281                 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
 282         } else {
 283                 /* Power down the chip */
 284                 config &= ~SII164_CONFIGURATION_POWER_MASK;
 285                 config |= SII164_CONFIGURATION_POWER_DOWN;
 286                 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
 287         }
 288 }
 289 
 290 /*
 291  *  sii164SelectHotPlugDetectionMode
 292  *      This function selects the mode of the hot plug detection.
 293  */
 294 static
 295 void sii164SelectHotPlugDetectionMode(enum sii164_hot_plug_mode hotPlugMode)
 296 {
 297         unsigned char detectReg;
 298 
 299         detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) &
 300                     ~SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG;
 301         switch (hotPlugMode) {
 302         case SII164_HOTPLUG_DISABLE:
 303                 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH;
 304                 break;
 305         case SII164_HOTPLUG_USE_MDI:
 306                 detectReg &= ~SII164_DETECT_INTERRUPT_MASK;
 307                 detectReg |= SII164_DETECT_INTERRUPT_BY_HTPLG_PIN;
 308                 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI;
 309                 break;
 310         case SII164_HOTPLUG_USE_RSEN:
 311                 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN;
 312                 break;
 313         case SII164_HOTPLUG_USE_HTPLG:
 314                 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG;
 315                 break;
 316         }
 317 
 318         i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg);
 319 }
 320 
 321 /*
 322  *  sii164EnableHotPlugDetection
 323  *      This function enables the Hot Plug detection.
 324  *
 325  *  enableHotPlug   - Enable (=1) / disable (=0) Hot Plug detection
 326  */
 327 void sii164EnableHotPlugDetection(unsigned char enableHotPlug)
 328 {
 329         unsigned char detectReg;
 330 
 331         detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
 332 
 333         /* Depending on each DVI controller, need to enable the hot plug based on each
 334          * individual chip design.
 335          */
 336         if (enableHotPlug != 0)
 337                 sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_USE_MDI);
 338         else
 339                 sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_DISABLE);
 340 }
 341 
 342 /*
 343  *  sii164IsConnected
 344  *      Check if the DVI Monitor is connected.
 345  *
 346  *  Output:
 347  *      0   - Not Connected
 348  *      1   - Connected
 349  */
 350 unsigned char sii164IsConnected(void)
 351 {
 352         unsigned char hotPlugValue;
 353 
 354         hotPlugValue = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) &
 355                        SII164_DETECT_HOT_PLUG_STATUS_MASK;
 356         if (hotPlugValue == SII164_DETECT_HOT_PLUG_STATUS_ON)
 357                 return 1;
 358         else
 359                 return 0;
 360 }
 361 
 362 /*
 363  *  sii164CheckInterrupt
 364  *      Checks if interrupt has occurred.
 365  *
 366  *  Output:
 367  *      0   - No interrupt
 368  *      1   - Interrupt occurs
 369  */
 370 unsigned char sii164CheckInterrupt(void)
 371 {
 372         unsigned char detectReg;
 373 
 374         detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) &
 375                     SII164_DETECT_MONITOR_STATE_MASK;
 376         if (detectReg == SII164_DETECT_MONITOR_STATE_CHANGE)
 377                 return 1;
 378         else
 379                 return 0;
 380 }
 381 
 382 /*
 383  *  sii164ClearInterrupt
 384  *      Clear the hot plug interrupt.
 385  */
 386 void sii164ClearInterrupt(void)
 387 {
 388         unsigned char detectReg;
 389 
 390         /* Clear the MDI interrupt */
 391         detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
 392         i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT,
 393                     detectReg | SII164_DETECT_MONITOR_STATE_CLEAR);
 394 }
 395 
 396 #endif
 397 
 398 #endif

/* [<][>][^][v][top][bottom][index][help] */