117a48c7cSmrg 217a48c7cSmrg#ifdef HAVE_CONFIG_H 317a48c7cSmrg#include "config.h" 417a48c7cSmrg#endif 517a48c7cSmrg 617a48c7cSmrg#include "apm.h" 717a48c7cSmrg#include "apm_regs.h" 817a48c7cSmrg 917a48c7cSmrg/* Inline functions */ 1017a48c7cSmrgstatic __inline__ void 1117a48c7cSmrgWaitForFifo(ApmPtr pApm, int slots) 1217a48c7cSmrg{ 1317a48c7cSmrg if (!pApm->UsePCIRetry) { 1417a48c7cSmrg volatile int i; 1517a48c7cSmrg#define MAXLOOP 1000000 1617a48c7cSmrg 1717a48c7cSmrg for(i = 0; i < MAXLOOP; i++) { 1817a48c7cSmrg if ((STATUS_IOP() & STATUS_FIFO) >= slots) 1917a48c7cSmrg break; 2017a48c7cSmrg } 2117a48c7cSmrg if (i == MAXLOOP) { 2217a48c7cSmrg unsigned int status = STATUS_IOP(); 2317a48c7cSmrg 2417a48c7cSmrg WRXB_IOP(0x1FF, 0); 2517a48c7cSmrg FatalError("Hung in WaitForFifo() (Status = 0x%08X)\n", status); 2617a48c7cSmrg } 2717a48c7cSmrg } 2817a48c7cSmrg} 2917a48c7cSmrg 3017a48c7cSmrgstatic void 3117a48c7cSmrgApmI2CPutBits(I2CBusPtr b, int clock, int data) 3217a48c7cSmrg{ 3317a48c7cSmrg unsigned int reg; 3417a48c7cSmrg unsigned char lock; 3517a48c7cSmrg ApmPtr pApm = ((ApmPtr)b->DriverPrivate.ptr); 3617a48c7cSmrg 3717a48c7cSmrg lock = rdinx(pApm->xport, 0x10); 3817a48c7cSmrg wrinx(pApm->xport, 0x10, 0x12); 3917a48c7cSmrg WaitForFifo(pApm, 2); 4017a48c7cSmrg reg = (RDXB_IOP(0xD0) & 0x07) | 0x60; 4117a48c7cSmrg if(clock) reg |= 0x08; 4217a48c7cSmrg if(data) reg |= 0x10; 4317a48c7cSmrg WRXB_IOP(0xD0, reg); 4417a48c7cSmrg if (lock) 4517a48c7cSmrg wrinx(pApm->xport, 0x10, 0); 4617a48c7cSmrg} 4717a48c7cSmrg 4817a48c7cSmrgstatic void 4917a48c7cSmrgApmI2CGetBits(I2CBusPtr b, int *clock, int *data) 5017a48c7cSmrg{ 5117a48c7cSmrg unsigned int reg; 5217a48c7cSmrg unsigned char lock; 5317a48c7cSmrg ApmPtr pApm = ((ApmPtr)b->DriverPrivate.ptr); 5417a48c7cSmrg unsigned char tmp; 5517a48c7cSmrg 5617a48c7cSmrg lock = rdinx(pApm->xport, 0x10); 5717a48c7cSmrg wrinx(pApm->xport, 0x10, 0x12); 5817a48c7cSmrg WaitForFifo(pApm, 2); 5917a48c7cSmrg tmp = RDXB_IOP(0xD0); 6017a48c7cSmrg WRXB_IOP(0xD0, tmp & 0x07); 6117a48c7cSmrg reg = STATUS_IOP(); 6217a48c7cSmrg *clock = (reg & STATUS_SCL) != 0; 6317a48c7cSmrg *data = (reg & STATUS_SDA) != 0; 6417a48c7cSmrg if (lock) 6517a48c7cSmrg wrinx(pApm->xport, 0x10, 0); 6617a48c7cSmrg} 6717a48c7cSmrg 6817a48c7cSmrgBool 6917a48c7cSmrgApmI2CInit(ScrnInfoPtr pScrn) 7017a48c7cSmrg{ 7117a48c7cSmrg APMDECL(pScrn); 7217a48c7cSmrg I2CBusPtr I2CPtr; 7317a48c7cSmrg 7417a48c7cSmrg I2CPtr = xf86CreateI2CBusRec(); 7517a48c7cSmrg if(!I2CPtr) return FALSE; 7617a48c7cSmrg 7717a48c7cSmrg pApm->I2CPtr = I2CPtr; 7817a48c7cSmrg 7917a48c7cSmrg I2CPtr->BusName = "Alliance bus"; 8017a48c7cSmrg I2CPtr->scrnIndex = pScrn->scrnIndex; 8117a48c7cSmrg I2CPtr->I2CPutBits = ApmI2CPutBits; 8217a48c7cSmrg I2CPtr->I2CGetBits = ApmI2CGetBits; 8317a48c7cSmrg I2CPtr->DriverPrivate.ptr = pApm; 8417a48c7cSmrg 8517a48c7cSmrg if(!xf86I2CBusInit(I2CPtr)) 8617a48c7cSmrg return FALSE; 8717a48c7cSmrg 8817a48c7cSmrg return TRUE; 8917a48c7cSmrg} 90