apm_i2c.c revision 17a48c7c
1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/apm/apm_i2c.c,v 1.6.4.1 2001/11/28 22:35:13 tsi Exp $ */ 2 3#ifdef HAVE_CONFIG_H 4#include "config.h" 5#endif 6 7#include "apm.h" 8#include "apm_regs.h" 9 10/* Inline functions */ 11static __inline__ void 12WaitForFifo(ApmPtr pApm, int slots) 13{ 14 if (!pApm->UsePCIRetry) { 15 volatile int i; 16#define MAXLOOP 1000000 17 18 for(i = 0; i < MAXLOOP; i++) { 19 if ((STATUS_IOP() & STATUS_FIFO) >= slots) 20 break; 21 } 22 if (i == MAXLOOP) { 23 unsigned int status = STATUS_IOP(); 24 25 WRXB_IOP(0x1FF, 0); 26 FatalError("Hung in WaitForFifo() (Status = 0x%08X)\n", status); 27 } 28 } 29} 30 31static void 32ApmI2CPutBits(I2CBusPtr b, int clock, int data) 33{ 34 unsigned int reg; 35 unsigned char lock; 36 ApmPtr pApm = ((ApmPtr)b->DriverPrivate.ptr); 37 38 lock = rdinx(pApm->xport, 0x10); 39 wrinx(pApm->xport, 0x10, 0x12); 40 WaitForFifo(pApm, 2); 41 reg = (RDXB_IOP(0xD0) & 0x07) | 0x60; 42 if(clock) reg |= 0x08; 43 if(data) reg |= 0x10; 44 WRXB_IOP(0xD0, reg); 45 if (lock) 46 wrinx(pApm->xport, 0x10, 0); 47} 48 49static void 50ApmI2CGetBits(I2CBusPtr b, int *clock, int *data) 51{ 52 unsigned int reg; 53 unsigned char lock; 54 ApmPtr pApm = ((ApmPtr)b->DriverPrivate.ptr); 55 unsigned char tmp; 56 57 lock = rdinx(pApm->xport, 0x10); 58 wrinx(pApm->xport, 0x10, 0x12); 59 WaitForFifo(pApm, 2); 60 tmp = RDXB_IOP(0xD0); 61 WRXB_IOP(0xD0, tmp & 0x07); 62 reg = STATUS_IOP(); 63 *clock = (reg & STATUS_SCL) != 0; 64 *data = (reg & STATUS_SDA) != 0; 65 if (lock) 66 wrinx(pApm->xport, 0x10, 0); 67} 68 69Bool 70ApmI2CInit(ScrnInfoPtr pScrn) 71{ 72 APMDECL(pScrn); 73 I2CBusPtr I2CPtr; 74 75 I2CPtr = xf86CreateI2CBusRec(); 76 if(!I2CPtr) return FALSE; 77 78 pApm->I2CPtr = I2CPtr; 79 80 I2CPtr->BusName = "Alliance bus"; 81 I2CPtr->scrnIndex = pScrn->scrnIndex; 82 I2CPtr->I2CPutBits = ApmI2CPutBits; 83 I2CPtr->I2CGetBits = ApmI2CGetBits; 84 I2CPtr->DriverPrivate.ptr = pApm; 85 86 if(!xf86I2CBusInit(I2CPtr)) 87 return FALSE; 88 89 return TRUE; 90} 91