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