This source file includes following definitions.
- ch7xxx_get_id
- ch7xxx_get_did
- ch7xxx_readb
- ch7xxx_writeb
- ch7xxx_init
- ch7xxx_detect
- ch7xxx_mode_valid
- ch7xxx_mode_set
- ch7xxx_dpms
- ch7xxx_get_hw_state
- ch7xxx_dump_regs
- ch7xxx_destroy
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 #include "intel_display_types.h"
  30 #include "intel_dvo_dev.h"
  31 
  32 #define CH7xxx_REG_VID          0x4a
  33 #define CH7xxx_REG_DID          0x4b
  34 
  35 #define CH7011_VID              0x83 
  36 #define CH7010B_VID             0x05
  37 #define CH7009A_VID             0x84
  38 #define CH7009B_VID             0x85
  39 #define CH7301_VID              0x95
  40 
  41 #define CH7xxx_VID              0x84
  42 #define CH7xxx_DID              0x17
  43 #define CH7010_DID              0x16
  44 
  45 #define CH7xxx_NUM_REGS         0x4c
  46 
  47 #define CH7xxx_CM               0x1c
  48 #define CH7xxx_CM_XCM           (1<<0)
  49 #define CH7xxx_CM_MCP           (1<<2)
  50 #define CH7xxx_INPUT_CLOCK      0x1d
  51 #define CH7xxx_GPIO             0x1e
  52 #define CH7xxx_GPIO_HPIR        (1<<3)
  53 #define CH7xxx_IDF              0x1f
  54 
  55 #define CH7xxx_IDF_HSP          (1<<3)
  56 #define CH7xxx_IDF_VSP          (1<<4)
  57 
  58 #define CH7xxx_CONNECTION_DETECT 0x20
  59 #define CH7xxx_CDET_DVI         (1<<5)
  60 
  61 #define CH7301_DAC_CNTL         0x21
  62 #define CH7301_HOTPLUG          0x23
  63 #define CH7xxx_TCTL             0x31
  64 #define CH7xxx_TVCO             0x32
  65 #define CH7xxx_TPCP             0x33
  66 #define CH7xxx_TPD              0x34
  67 #define CH7xxx_TPVT             0x35
  68 #define CH7xxx_TLPF             0x36
  69 #define CH7xxx_TCT              0x37
  70 #define CH7301_TEST_PATTERN     0x48
  71 
  72 #define CH7xxx_PM               0x49
  73 #define CH7xxx_PM_FPD           (1<<0)
  74 #define CH7301_PM_DACPD0        (1<<1)
  75 #define CH7301_PM_DACPD1        (1<<2)
  76 #define CH7301_PM_DACPD2        (1<<3)
  77 #define CH7xxx_PM_DVIL          (1<<6)
  78 #define CH7xxx_PM_DVIP          (1<<7)
  79 
  80 #define CH7301_SYNC_POLARITY    0x56
  81 #define CH7301_SYNC_RGB_YUV     (1<<0)
  82 #define CH7301_SYNC_POL_DVI     (1<<5)
  83 
  84 
  85 
  86 
  87 
  88 static struct ch7xxx_id_struct {
  89         u8 vid;
  90         char *name;
  91 } ch7xxx_ids[] = {
  92         { CH7011_VID, "CH7011" },
  93         { CH7010B_VID, "CH7010B" },
  94         { CH7009A_VID, "CH7009A" },
  95         { CH7009B_VID, "CH7009B" },
  96         { CH7301_VID, "CH7301" },
  97 };
  98 
  99 static struct ch7xxx_did_struct {
 100         u8 did;
 101         char *name;
 102 } ch7xxx_dids[] = {
 103         { CH7xxx_DID, "CH7XXX" },
 104         { CH7010_DID, "CH7010B" },
 105 };
 106 
 107 struct ch7xxx_priv {
 108         bool quiet;
 109 };
 110 
 111 static char *ch7xxx_get_id(u8 vid)
 112 {
 113         int i;
 114 
 115         for (i = 0; i < ARRAY_SIZE(ch7xxx_ids); i++) {
 116                 if (ch7xxx_ids[i].vid == vid)
 117                         return ch7xxx_ids[i].name;
 118         }
 119 
 120         return NULL;
 121 }
 122 
 123 static char *ch7xxx_get_did(u8 did)
 124 {
 125         int i;
 126 
 127         for (i = 0; i < ARRAY_SIZE(ch7xxx_dids); i++) {
 128                 if (ch7xxx_dids[i].did == did)
 129                         return ch7xxx_dids[i].name;
 130         }
 131 
 132         return NULL;
 133 }
 134 
 135 
 136 static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, u8 *ch)
 137 {
 138         struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
 139         struct i2c_adapter *adapter = dvo->i2c_bus;
 140         u8 out_buf[2];
 141         u8 in_buf[2];
 142 
 143         struct i2c_msg msgs[] = {
 144                 {
 145                         .addr = dvo->slave_addr,
 146                         .flags = 0,
 147                         .len = 1,
 148                         .buf = out_buf,
 149                 },
 150                 {
 151                         .addr = dvo->slave_addr,
 152                         .flags = I2C_M_RD,
 153                         .len = 1,
 154                         .buf = in_buf,
 155                 }
 156         };
 157 
 158         out_buf[0] = addr;
 159         out_buf[1] = 0;
 160 
 161         if (i2c_transfer(adapter, msgs, 2) == 2) {
 162                 *ch = in_buf[0];
 163                 return true;
 164         }
 165 
 166         if (!ch7xxx->quiet) {
 167                 DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
 168                           addr, adapter->name, dvo->slave_addr);
 169         }
 170         return false;
 171 }
 172 
 173 
 174 static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, u8 ch)
 175 {
 176         struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
 177         struct i2c_adapter *adapter = dvo->i2c_bus;
 178         u8 out_buf[2];
 179         struct i2c_msg msg = {
 180                 .addr = dvo->slave_addr,
 181                 .flags = 0,
 182                 .len = 2,
 183                 .buf = out_buf,
 184         };
 185 
 186         out_buf[0] = addr;
 187         out_buf[1] = ch;
 188 
 189         if (i2c_transfer(adapter, &msg, 1) == 1)
 190                 return true;
 191 
 192         if (!ch7xxx->quiet) {
 193                 DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
 194                           addr, adapter->name, dvo->slave_addr);
 195         }
 196 
 197         return false;
 198 }
 199 
 200 static bool ch7xxx_init(struct intel_dvo_device *dvo,
 201                         struct i2c_adapter *adapter)
 202 {
 203         
 204         struct ch7xxx_priv *ch7xxx;
 205         u8 vendor, device;
 206         char *name, *devid;
 207 
 208         ch7xxx = kzalloc(sizeof(struct ch7xxx_priv), GFP_KERNEL);
 209         if (ch7xxx == NULL)
 210                 return false;
 211 
 212         dvo->i2c_bus = adapter;
 213         dvo->dev_priv = ch7xxx;
 214         ch7xxx->quiet = true;
 215 
 216         if (!ch7xxx_readb(dvo, CH7xxx_REG_VID, &vendor))
 217                 goto out;
 218 
 219         name = ch7xxx_get_id(vendor);
 220         if (!name) {
 221                 DRM_DEBUG_KMS("ch7xxx not detected; got VID 0x%02x from %s slave %d.\n",
 222                               vendor, adapter->name, dvo->slave_addr);
 223                 goto out;
 224         }
 225 
 226 
 227         if (!ch7xxx_readb(dvo, CH7xxx_REG_DID, &device))
 228                 goto out;
 229 
 230         devid = ch7xxx_get_did(device);
 231         if (!devid) {
 232                 DRM_DEBUG_KMS("ch7xxx not detected; got DID 0x%02x from %s slave %d.\n",
 233                               device, adapter->name, dvo->slave_addr);
 234                 goto out;
 235         }
 236 
 237         ch7xxx->quiet = false;
 238         DRM_DEBUG_KMS("Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n",
 239                   name, vendor, device);
 240         return true;
 241 out:
 242         kfree(ch7xxx);
 243         return false;
 244 }
 245 
 246 static enum drm_connector_status ch7xxx_detect(struct intel_dvo_device *dvo)
 247 {
 248         u8 cdet, orig_pm, pm;
 249 
 250         ch7xxx_readb(dvo, CH7xxx_PM, &orig_pm);
 251 
 252         pm = orig_pm;
 253         pm &= ~CH7xxx_PM_FPD;
 254         pm |= CH7xxx_PM_DVIL | CH7xxx_PM_DVIP;
 255 
 256         ch7xxx_writeb(dvo, CH7xxx_PM, pm);
 257 
 258         ch7xxx_readb(dvo, CH7xxx_CONNECTION_DETECT, &cdet);
 259 
 260         ch7xxx_writeb(dvo, CH7xxx_PM, orig_pm);
 261 
 262         if (cdet & CH7xxx_CDET_DVI)
 263                 return connector_status_connected;
 264         return connector_status_disconnected;
 265 }
 266 
 267 static enum drm_mode_status ch7xxx_mode_valid(struct intel_dvo_device *dvo,
 268                                               struct drm_display_mode *mode)
 269 {
 270         if (mode->clock > 165000)
 271                 return MODE_CLOCK_HIGH;
 272 
 273         return MODE_OK;
 274 }
 275 
 276 static void ch7xxx_mode_set(struct intel_dvo_device *dvo,
 277                             const struct drm_display_mode *mode,
 278                             const struct drm_display_mode *adjusted_mode)
 279 {
 280         u8 tvco, tpcp, tpd, tlpf, idf;
 281 
 282         if (mode->clock <= 65000) {
 283                 tvco = 0x23;
 284                 tpcp = 0x08;
 285                 tpd = 0x16;
 286                 tlpf = 0x60;
 287         } else {
 288                 tvco = 0x2d;
 289                 tpcp = 0x06;
 290                 tpd = 0x26;
 291                 tlpf = 0xa0;
 292         }
 293 
 294         ch7xxx_writeb(dvo, CH7xxx_TCTL, 0x00);
 295         ch7xxx_writeb(dvo, CH7xxx_TVCO, tvco);
 296         ch7xxx_writeb(dvo, CH7xxx_TPCP, tpcp);
 297         ch7xxx_writeb(dvo, CH7xxx_TPD, tpd);
 298         ch7xxx_writeb(dvo, CH7xxx_TPVT, 0x30);
 299         ch7xxx_writeb(dvo, CH7xxx_TLPF, tlpf);
 300         ch7xxx_writeb(dvo, CH7xxx_TCT, 0x00);
 301 
 302         ch7xxx_readb(dvo, CH7xxx_IDF, &idf);
 303 
 304         idf &= ~(CH7xxx_IDF_HSP | CH7xxx_IDF_VSP);
 305         if (mode->flags & DRM_MODE_FLAG_PHSYNC)
 306                 idf |= CH7xxx_IDF_HSP;
 307 
 308         if (mode->flags & DRM_MODE_FLAG_PVSYNC)
 309                 idf |= CH7xxx_IDF_VSP;
 310 
 311         ch7xxx_writeb(dvo, CH7xxx_IDF, idf);
 312 }
 313 
 314 
 315 static void ch7xxx_dpms(struct intel_dvo_device *dvo, bool enable)
 316 {
 317         if (enable)
 318                 ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_DVIL | CH7xxx_PM_DVIP);
 319         else
 320                 ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_FPD);
 321 }
 322 
 323 static bool ch7xxx_get_hw_state(struct intel_dvo_device *dvo)
 324 {
 325         u8 val;
 326 
 327         ch7xxx_readb(dvo, CH7xxx_PM, &val);
 328 
 329         if (val & (CH7xxx_PM_DVIL | CH7xxx_PM_DVIP))
 330                 return true;
 331         else
 332                 return false;
 333 }
 334 
 335 static void ch7xxx_dump_regs(struct intel_dvo_device *dvo)
 336 {
 337         int i;
 338 
 339         for (i = 0; i < CH7xxx_NUM_REGS; i++) {
 340                 u8 val;
 341                 if ((i % 8) == 0)
 342                         DRM_DEBUG_KMS("\n %02X: ", i);
 343                 ch7xxx_readb(dvo, i, &val);
 344                 DRM_DEBUG_KMS("%02X ", val);
 345         }
 346 }
 347 
 348 static void ch7xxx_destroy(struct intel_dvo_device *dvo)
 349 {
 350         struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
 351 
 352         if (ch7xxx) {
 353                 kfree(ch7xxx);
 354                 dvo->dev_priv = NULL;
 355         }
 356 }
 357 
 358 const struct intel_dvo_dev_ops ch7xxx_ops = {
 359         .init = ch7xxx_init,
 360         .detect = ch7xxx_detect,
 361         .mode_valid = ch7xxx_mode_valid,
 362         .mode_set = ch7xxx_mode_set,
 363         .dpms = ch7xxx_dpms,
 364         .get_hw_state = ch7xxx_get_hw_state,
 365         .dump_regs = ch7xxx_dump_regs,
 366         .destroy = ch7xxx_destroy,
 367 };