xf86-video-intel: src/i830_dvo.c src/ivch/ivch.c

Kristian Høgsberg krh at kemper.freedesktop.org
Thu Apr 26 01:14:04 EEST 2007


 src/i830_dvo.c  |    6 +---
 src/ivch/ivch.c |   75 ++++++++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 61 insertions(+), 20 deletions(-)

New commits:
diff-tree 0cd524e5411e35c8483c02ecc5062625809e6fc6 (from 880314aabe6326ed56517034940f0e10fb16e866)
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Wed Apr 25 18:09:10 2007 -0400

    Implement the custom I2C protocol used by the ivch DVO.
    
    The ihch DVO uses a modified I2C addressing scheme as described
    in section 5.2 of the data sheet.  Implement this by over-riding
    the I2C read and write word routines.

diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 0bb25bd..4b37228 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -45,13 +45,11 @@ static const char *CH7xxxSymbols[] = {
     "CH7xxxVidOutput",
     NULL
 };
-
-#if 0
 static const char *ivch_symbols[] = {
     "ivch_methods",
     NULL
 };
-#endif
+
 #if 0
 static const char *ch7017_symbols[] = {
     "ch7017_methods",
@@ -66,9 +64,9 @@ struct _I830DVODriver i830_dvo_drivers[]
      (SIL164_ADDR_1<<1), SIL164Symbols, NULL , NULL, NULL},
     {I830_DVO_CHIP_TMDS | I830_DVO_CHIP_TVOUT, "ch7xxx", "CH7xxxVidOutput",
      (CH7xxx_ADDR_1<<1), CH7xxxSymbols, NULL , NULL, NULL},
-    /*
     {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
      0x04, ivch_symbols, NULL, NULL, NULL},
+    /*
     {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
      0x44, ivch_symbols, NULL, NULL, NULL},
     {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
diff --git a/src/ivch/ivch.c b/src/ivch/ivch.c
index 71f41f5..efc74f8 100644
--- a/src/ivch/ivch.c
+++ b/src/ivch/ivch.c
@@ -60,26 +60,69 @@ ivch_dump_regs(I2CDevPtr d);
 static Bool
 ivch_read(struct ivch_priv *priv, int addr, CARD16 *data)
 {
-    if (!xf86I2CReadWord(&priv->d, addr, data)) {
-	xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
-		   "Unable to read register 0x%02x from %s:%d.\n",
-		   addr, priv->d.pI2CBus->BusName, priv->d.SlaveAddr);
-	return FALSE;
-    }
+    I2CBusPtr b = priv->d.pI2CBus;
+    I2CByte *p = (I2CByte *) data;
+
+    if (!b->I2CStart(b, priv->d.StartTimeout))
+	goto fail;
+
+    if (!b->I2CPutByte(&priv->d, priv->d.SlaveAddr | 1))
+	goto fail;
+
+    if (!b->I2CPutByte(&priv->d, addr))
+	goto fail;
+
+    if (!b->I2CGetByte(&priv->d, p++, FALSE))
+	goto fail;
+
+    if (!b->I2CGetByte(&priv->d, p++, TRUE))
+	goto fail;
+
+    b->I2CStop(&priv->d);
+
     return TRUE;
-}
 
+ fail:
+    xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
+	       "ivch: Unable to read register 0x%02x from %s:%02x.\n",
+	       addr, priv->d.pI2CBus->BusName, priv->d.SlaveAddr);
+    b->I2CStop(&priv->d);
+
+    return FALSE;
+}
+ 
 /** Writes a 16-bit register on the ivch */
 static Bool
 ivch_write(struct ivch_priv *priv, int addr, CARD16 data)
 {
-    if (!xf86I2CWriteWord(&priv->d, addr, data)) {
-	xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
-		   "Unable to write register 0x%02x to %s:%d.\n",
-		   addr, priv->d.pI2CBus->BusName, priv->d.SlaveAddr);
-	return FALSE;
-    }
+    I2CBusPtr b = priv->d.pI2CBus;
+
+    if (!b->I2CStart(b, priv->d.StartTimeout))
+	goto fail;
+
+    if (!b->I2CPutByte(&priv->d, priv->d.SlaveAddr))
+	goto fail;
+
+    if (!b->I2CPutByte(&priv->d, addr))
+	goto fail;
+
+    if (!b->I2CPutByte(&priv->d, data & 0xff))
+	goto fail;
+
+    if (!b->I2CPutByte(&priv->d, data >> 8))
+	goto fail;
+
+    b->I2CStop(&priv->d);
+
     return TRUE;
+
+ fail:
+    b->I2CStop(&priv->d);
+    xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
+	       "Unable to write register 0x%02x to %s:%d.\n",
+	       addr, priv->d.pI2CBus->BusName, priv->d.SlaveAddr);
+
+    return FALSE;
 }
 
 /** Probes the given bus and slave address for an ivch */
@@ -104,18 +147,18 @@ ivch_init(I2CBusPtr b, I2CSlaveAddr addr
     priv->d.ByteTimeout = b->ByteTimeout;
     priv->d.DriverPrivate.ptr = priv;
 
-    if (!xf86I2CReadWord(&priv->d, VR00, &temp))
+    if (!ivch_read(priv, VR00, &temp))
 	goto out;
 
     /* Since the identification bits are probably zeroes, which doesn't seem
      * very unique, check that the value in the base address field matches
      * the address it's responding on.
      */
-    if ((temp & VR00_BASE_ADDRESS_MASK) != priv->d.SlaveAddr) {
+    if ((temp & VR00_BASE_ADDRESS_MASK) != (priv->d.SlaveAddr >> 1)) {
 	xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
 		   "ivch detect failed due to address mismatch "
 		   "(%d vs %d)\n",
-		   (temp & VR00_BASE_ADDRESS_MASK), priv->d.SlaveAddr);
+		   (temp & VR00_BASE_ADDRESS_MASK), priv->d.SlaveAddr >> 1);
     }
 
     if (!xf86I2CDevInit(&priv->d)) {



More information about the xorg-commit mailing list