diff options
author | faith <faith> | 2000-01-06 12:41:09 +0000 |
---|---|---|
committer | faith <faith> | 2000-01-06 12:41:09 +0000 |
commit | 3d576da17fb981de56b63eb26cdbb868336b18d0 (patch) | |
tree | 06179a3b32e09aedd9d5ac062411160438e72517 /xc/programs/Xserver/hw/xfree86/drivers/cirrus/alp_i2c.c | |
parent | 880ca0ce0a60b42b4ab20fcce44e8eb5af757cc2 (diff) |
Initial revision
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86/drivers/cirrus/alp_i2c.c')
-rw-r--r-- | xc/programs/Xserver/hw/xfree86/drivers/cirrus/alp_i2c.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cirrus/alp_i2c.c b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/alp_i2c.c new file mode 100644 index 000000000..515382f6c --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/alp_i2c.c @@ -0,0 +1,124 @@ +/* (c) Itai Nahshon */ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/alp_i2c.c,v 1.1 1999/12/26 18:24:16 robin Exp $ */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "compiler.h" + +#include "xf86Pci.h" +#include "xf86PciInfo.h" + +#include "vgaHW.h" + +#include "cir.h" +#include "alp.h" + +/* + * Switch between internal I2C bus and external (DDC) bus. + * There is one I2C port controlled bu SR08 and the programmable + * outputs control a multiplexer. + */ +static Bool +AlpI2CSwitchToBus(I2CBusPtr b) +{ + AlpPtr pAlp = ((AlpPtr)b->DriverPrivate.ptr); + vgaHWPtr hwp = VGAHWPTR(pAlp->CirRec.pScrn); + if (b == pAlp->CirRec.I2CPtr1) { + if ((pAlp->ModeReg.ExtVga[GR17] & 0x60) == 0) + return TRUE; + pAlp->ModeReg.ExtVga[GR17] &= ~0x60; + } else if (b == pAlp->CirRec.I2CPtr2) { + if ((pAlp->ModeReg.ExtVga[GR17] & 0x60) != 0) + return TRUE; + pAlp->ModeReg.ExtVga[GR17] |= 0x60; + } else + return FALSE; + + /* ErrorF("AlpI2CSwitchToBus: \"%s\"\n", b->BusName); */ + hwp->writeGr(hwp, 0x17, pAlp->ModeReg.ExtVga[GR17]); + return TRUE; +} + +static void +AlpI2CPutBits(I2CBusPtr b, int clock, int data) +{ + unsigned int reg = 0xfc; + AlpPtr pAlp = ((AlpPtr)b->DriverPrivate.ptr); + vgaHWPtr hwp = VGAHWPTR(pAlp->CirRec.pScrn); + + if (!AlpI2CSwitchToBus(b)) + return; + + if (clock) reg |= 1; + if (data) reg |= 2; + hwp->writeSeq(hwp, 0x08, reg); + /* ErrorF("AlpI2CPutBits: %d %d\n", clock, data); */ +} + +static void +AlpI2CGetBits(I2CBusPtr b, int *clock, int *data) +{ + unsigned int reg; + AlpPtr pAlp = ((AlpPtr)b->DriverPrivate.ptr); + vgaHWPtr hwp = VGAHWPTR(pAlp->CirRec.pScrn); + + if (!AlpI2CSwitchToBus(b)) + return; + + reg = hwp->readSeq(hwp, 0x08); + *clock = (reg & 0x04) != 0; + *data = (reg & 0x80) != 0; + /* ErrorF("AlpI2CGetBits: %d %d\n", *clock, *data); */ +} + +Bool +AlpI2CInit(ScrnInfoPtr pScrn) +{ + AlpPtr pAlp = ALPPTR(pScrn); + I2CBusPtr I2CPtr; + +#ifdef ALP_DEBUG + ErrorF("AlpI2CInit\n"); +#endif + + switch(pAlp->CirRec.Chipset) { + case PCI_CHIP_GD5446: + case PCI_CHIP_GD5480: + break; + default: + return FALSE; + } + + + I2CPtr = xf86CreateI2CBusRec(); + if (!I2CPtr) return FALSE; + + pAlp->CirRec.I2CPtr1 = I2CPtr; + + I2CPtr->BusName = "I2C bus 1"; + I2CPtr->scrnIndex = pScrn->scrnIndex; + I2CPtr->I2CPutBits = AlpI2CPutBits; + I2CPtr->I2CGetBits = AlpI2CGetBits; + I2CPtr->DriverPrivate.ptr = pAlp; + + if (!xf86I2CBusInit(I2CPtr)) + return FALSE; + + I2CPtr = xf86CreateI2CBusRec(); + if (!I2CPtr) return FALSE; + + pAlp->CirRec.I2CPtr2 = I2CPtr; + + I2CPtr->BusName = "I2C bus 2"; + I2CPtr->scrnIndex = pScrn->scrnIndex; + I2CPtr->I2CPutBits = AlpI2CPutBits; + I2CPtr->I2CGetBits = AlpI2CGetBits; + I2CPtr->DriverPrivate.ptr = pAlp; + + if (!xf86I2CBusInit(I2CPtr)) + return FALSE; + + return TRUE; +} |