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 */
10 static __inline__ void
WaitForFifo(ApmPtr pApm,int slots)11 WaitForFifo(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 
30 static void
ApmI2CPutBits(I2CBusPtr b,int clock,int data)31 ApmI2CPutBits(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 
48 static void
ApmI2CGetBits(I2CBusPtr b,int * clock,int * data)49 ApmI2CGetBits(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 
68 Bool
ApmI2CInit(ScrnInfoPtr pScrn)69 ApmI2CInit(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