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