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