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