diff options
author | Luc Verhaegen <libv@skynet.be> | 2009-02-26 15:22:34 +0100 |
---|---|---|
committer | Luc Verhaegen <libv@skynet.be> | 2009-02-26 15:22:34 +0100 |
commit | 4fb6d0279cad8a0e4469b20259b494303cd68b0b (patch) | |
tree | 4ccb9132ea74799a277a834cd9e6c79ff642623c | |
parent | 653c2d7d9a5138d80acad750679959a002645ff3 (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.c | 225 |
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); } |