summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2009-02-26 15:22:34 +0100
committerLuc Verhaegen <libv@skynet.be>2009-02-26 15:22:34 +0100
commit4fb6d0279cad8a0e4469b20259b494303cd68b0b (patch)
tree4ccb9132ea74799a277a834cd9e6c79ff642623c
parent653c2d7d9a5138d80acad750679959a002645ff3 (diff)
i2c: properly fix up Bus 3 support.
The original code was written 4.5years ago, and brought VIAs crappy non-xf86i2c code into the proper infrastructure. It was painstakingly tested remotely on Terry Lewis his acer aspire 135x, and the best i could do at the time. Now things are sane and trivial and cool in this code, finally.
-rw-r--r--src/via_i2c.c225
1 files changed, 37 insertions, 188 deletions
diff --git a/src/via_i2c.c b/src/via_i2c.c
index 7f99003..d722541 100644
--- a/src/via_i2c.c
+++ b/src/via_i2c.c
@@ -40,14 +40,14 @@
/*
*
- * CRT I2C
+ * I2C Bus 1 at SR26.
*
*/
/*
*
*/
static void
-ViaI2C1PutBits(I2CBusPtr Bus, int clock, int data)
+I2CBus1PutBits(I2CBusPtr Bus, int clock, int data)
{
vgaHWPtr hwp = VGAHWPTR(xf86Screens[Bus->scrnIndex]);
CARD8 value = 0x01; /* Enable */
@@ -65,7 +65,7 @@ ViaI2C1PutBits(I2CBusPtr Bus, int clock, int data)
*
*/
static void
-ViaI2C1GetBits(I2CBusPtr Bus, int *clock, int *data)
+I2CBus1GetBits(I2CBusPtr Bus, int *clock, int *data)
{
vgaHWPtr hwp = VGAHWPTR(xf86Screens[Bus->scrnIndex]);
CARD8 value = hwp->readSeq(hwp, 0x26);
@@ -78,17 +78,17 @@ ViaI2C1GetBits(I2CBusPtr Bus, int *clock, int *data)
*
*/
static I2CBusPtr
-ViaI2CBus1Init(int scrnIndex)
+I2CBus1Init(int scrnIndex)
{
I2CBusPtr pI2CBus = xf86CreateI2CBusRec();
if (!pI2CBus)
return NULL;
- pI2CBus->BusName = "I2C bus 1";
+ pI2CBus->BusName = "Bus 1";
pI2CBus->scrnIndex = scrnIndex;
- pI2CBus->I2CPutBits = ViaI2C1PutBits;
- pI2CBus->I2CGetBits = ViaI2C1GetBits;
+ pI2CBus->I2CPutBits = I2CBus1PutBits;
+ pI2CBus->I2CGetBits = I2CBus1GetBits;
if (!xf86I2CBusInit(pI2CBus)) {
xf86DestroyI2CBusRec(pI2CBus, TRUE, FALSE);
@@ -100,14 +100,14 @@ ViaI2CBus1Init(int scrnIndex)
/*
*
- * First data bus I2C: tends to have TV-encoders
+ * I2C Bus 2 at SR31.
*
*/
/*
*
*/
static void
-ViaI2C2PutBits(I2CBusPtr Bus, int clock, int data)
+I2CBus2PutBits(I2CBusPtr Bus, int clock, int data)
{
vgaHWPtr hwp = VGAHWPTR(xf86Screens[Bus->scrnIndex]);
CARD8 value = 0x01; /* Enable */
@@ -125,7 +125,7 @@ ViaI2C2PutBits(I2CBusPtr Bus, int clock, int data)
*
*/
static void
-ViaI2C2GetBits(I2CBusPtr Bus, int *clock, int *data)
+I2CBus2GetBits(I2CBusPtr Bus, int *clock, int *data)
{
vgaHWPtr hwp = VGAHWPTR(xf86Screens[Bus->scrnIndex]);
CARD8 value = hwp->readSeq(hwp, 0x31);
@@ -138,17 +138,17 @@ ViaI2C2GetBits(I2CBusPtr Bus, int *clock, int *data)
*
*/
static I2CBusPtr
-ViaI2CBus2Init(int scrnIndex)
+I2CBus2Init(int scrnIndex)
{
I2CBusPtr pI2CBus = xf86CreateI2CBusRec();
if (!pI2CBus)
return NULL;
- pI2CBus->BusName = "I2C bus 2";
+ pI2CBus->BusName = "Bus 2";
pI2CBus->scrnIndex = scrnIndex;
- pI2CBus->I2CPutBits = ViaI2C2PutBits;
- pI2CBus->I2CGetBits = ViaI2C2GetBits;
+ pI2CBus->I2CPutBits = I2CBus2PutBits;
+ pI2CBus->I2CGetBits = I2CBus2GetBits;
if (!xf86I2CBusInit(pI2CBus)) {
xf86DestroyI2CBusRec(pI2CBus, TRUE, FALSE);
@@ -159,211 +159,60 @@ ViaI2CBus2Init(int scrnIndex)
}
/*
- * A third I2C bus implemented by a few IO pins.
- * Requires higher level functions to be used properly.
- * Former via_gpioi2c.
*
- */
-/*
+ * I2C Bus 3 at SR2C.
*
*/
-static Bool
-ViaI2C3Start(I2CBusPtr b, int timeout)
-{
- vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]);
-
- ViaSeqMask(hwp, 0x2C, 0xF0, 0xF0);
- b->I2CUDelay(b, b->RiseFallTime);
-
- ViaSeqMask(hwp, 0x2C, 0x00, 0x10);
- b->I2CUDelay(b, b->HoldTime);
- ViaSeqMask(hwp, 0x2C, 0x00, 0x20);
- b->I2CUDelay(b, b->HoldTime);
-
- return TRUE;
-}
-
-/*
- *
- */
-static Bool
-ViaI2C3Address(I2CDevPtr d, I2CSlaveAddr addr)
-{
- I2CBusPtr b = d->pI2CBus;
-
-#ifdef X_NEED_I2CSTART
- if (b->I2CStart(d->pI2CBus, d->StartTimeout)) {
-#else
- if (ViaI2C3Start(d->pI2CBus, d->StartTimeout)) {
-#endif
- if (b->I2CPutByte(d, addr & 0xFF)) {
- if ((addr & 0xF8) != 0xF0 &&
- (addr & 0xFE) != 0x00)
- return TRUE;
-
- if (b->I2CPutByte(d, (addr >> 8) & 0xFF))
- return TRUE;
- }
-
- b->I2CStop(d);
- }
-
- return FALSE;
-}
-
/*
*
*/
static void
-ViaI2C3Stop(I2CDevPtr d)
+I2CBus3PutBits(I2CBusPtr Bus, int clock, int data)
{
- I2CBusPtr b = d->pI2CBus;
- vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]);
-
- ViaSeqMask(hwp, 0x2C, 0xC0, 0xF0);
- b->I2CUDelay(b, b->RiseFallTime);
+ vgaHWPtr hwp = VGAHWPTR(xf86Screens[Bus->scrnIndex]);
+ CARD8 value = 0xC0; /* enable control lines for sda/scl */
- ViaSeqMask(hwp, 0x2C, 0x20, 0x20);
- b->I2CUDelay(b, b->HoldTime);
+ if (clock)
+ value |= SCL_WRITE;
- ViaSeqMask(hwp, 0x2C, 0x10, 0x10);
- b->I2CUDelay(b, b->HoldTime);
+ if (data)
+ value |= SDA_WRITE;
- ViaSeqMask(hwp, 0x2C, 0x00, 0x20);
- b->I2CUDelay(b, b->HoldTime);
+ ViaSeqMask(hwp, 0x2C, value, 0xC0 | SCL_WRITE | SDA_WRITE);
}
/*
*
*/
static void
-ViaI2C3PutBit(I2CBusPtr b, Bool sda, int timeout)
-{
- vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]);
-
- if (sda)
- ViaSeqMask(hwp, 0x2C, 0x50, 0x50);
- else
- ViaSeqMask(hwp, 0x2C, 0x40, 0x50);
- b->I2CUDelay(b, b->RiseFallTime/5);
-
- ViaSeqMask(hwp, 0x2C, 0xA0, 0xA0);
- b->I2CUDelay(b, b->HoldTime);
- b->I2CUDelay(b, timeout);
-
- ViaSeqMask(hwp, 0x2C, 0x80, 0xA0);
- b->I2CUDelay(b, b->RiseFallTime/5);
-}
-
-/*
- *
- */
-static Bool
-ViaI2C3PutByte(I2CDevPtr d, I2CByte data)
+I2CBus3GetBits(I2CBusPtr Bus, int *clock, int *data)
{
- I2CBusPtr b = d->pI2CBus;
- vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]);
- Bool ret;
- int i;
-
- for (i = 7; i >= 0; i--)
- ViaI2C3PutBit(b, (data >> i) & 0x01, b->BitTimeout);
-
- /* raise first to avoid false positives */
- ViaSeqMask(hwp, 0x2C, 0x50, 0x50);
- ViaSeqMask(hwp, 0x2C, 0x00, 0x40);
- b->I2CUDelay(b, b->RiseFallTime);
- ViaSeqMask(hwp, 0x2C, 0xA0, 0xA0);
-
- if (hwp->readSeq(hwp, 0x2C) & 0x04)
- ret = FALSE;
- else
- ret = TRUE;
-
- ViaSeqMask(hwp, 0x2C, 0x80, 0xA0);
- b->I2CUDelay(b, b->RiseFallTime);
-
- return ret;
-}
-
-/*
- *
- */
-static Bool
-ViaI2C3GetBit(I2CBusPtr b, int timeout)
-{
- vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]);
- Bool ret;
-
- ViaSeqMask(hwp, 0x2C, 0x00, 0x40);
- b->I2CUDelay(b, b->RiseFallTime/5);
-
- ViaSeqMask(hwp, 0x2C, 0xA0, 0xA0);
-
- if (hwp->readSeq(hwp, 0x2C) & 0x04)
- ret = TRUE;
- else
- ret = FALSE;
-
- ViaSeqMask(hwp, 0x2C, 0x80, 0xA0);
- b->I2CUDelay(b, b->RiseFallTime/5);
-
- return ret;
-}
-
-/*
- *
- */
-static Bool
-ViaI2C3GetByte(I2CDevPtr d, I2CByte *data, Bool last)
-{
- I2CBusPtr b = d->pI2CBus;
- vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]);
- int i;
-
- *data = 0x00;
-
- for (i = 7; i >= 0; i--)
- if (ViaI2C3GetBit(b, b->BitTimeout))
- *data |= 0x01 << i;
-
- if (last) /* send NACK */
- ViaSeqMask(hwp, 0x2C, 0x50, 0x50);
- else /* send ACK */
- ViaSeqMask(hwp, 0x2C, 0x40, 0x50);
-
- ViaSeqMask(hwp, 0x2C, 0xA0, 0xA0);
- b->I2CUDelay(b, b->HoldTime);
-
- ViaSeqMask(hwp, 0x2C, 0x80, 0xA0);
+ vgaHWPtr hwp = VGAHWPTR(xf86Screens[Bus->scrnIndex]);
+ CARD8 value = hwp->readSeq(hwp, 0x2C);
- return TRUE;
+ *clock = (value & SCL_READ) != 0;
+ *data = (value & SDA_READ) != 0;
}
/*
*
*/
static I2CBusPtr
-ViaI2CBus3Init(int scrnIndex)
+I2CBus3Init(int scrnIndex)
{
I2CBusPtr pI2CBus = xf86CreateI2CBusRec();
if (!pI2CBus)
return NULL;
- pI2CBus->BusName = "I2C bus 3";
+ pI2CBus->BusName = "Bus 3";
pI2CBus->scrnIndex = scrnIndex;
- pI2CBus->I2CAddress = ViaI2C3Address;
-#ifdef X_NEED_I2CSTART
- pI2CBus->I2CStart = ViaI2C3Start;
-#endif
- pI2CBus->I2CStop = ViaI2C3Stop;
- pI2CBus->I2CPutByte = ViaI2C3PutByte;
- pI2CBus->I2CGetByte = ViaI2C3GetByte;
+ pI2CBus->I2CPutBits = I2CBus3PutBits;
+ pI2CBus->I2CGetBits = I2CBus3GetBits;
if (!xf86I2CBusInit(pI2CBus)) {
- xf86DestroyI2CBusRec(pI2CBus, TRUE, FALSE);
- return NULL;
+ xf86DestroyI2CBusRec(pI2CBus, TRUE, FALSE);
+ return NULL;
}
return pI2CBus;
@@ -379,7 +228,7 @@ ViaI2CInit(ScrnInfoPtr pScrn)
VIAFUNC(pScrn);
- pVia->pI2CBus1 = ViaI2CBus1Init(pScrn->scrnIndex);
- pVia->pI2CBus2 = ViaI2CBus2Init(pScrn->scrnIndex);
- pVia->pI2CBus3 = ViaI2CBus3Init(pScrn->scrnIndex);
+ pVia->pI2CBus1 = I2CBus1Init(pScrn->scrnIndex);
+ pVia->pI2CBus2 = I2CBus2Init(pScrn->scrnIndex);
+ pVia->pI2CBus3 = I2CBus3Init(pScrn->scrnIndex);
}