1 /* (c) Itai Nahshon */
2
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
6
7 #include "xf86.h"
8 #include "xf86_OSproc.h"
9 #include "compiler.h"
10
11 #include "xf86Pci.h"
12
13 #include "vgaHW.h"
14
15 #include "cir.h"
16 #define _ALP_PRIVATE_
17 #include "alp.h"
18
19 /*
20 * Switch between internal I2C bus and external (DDC) bus.
21 * There is one I2C port controlled bu SR08 and the programmable
22 * outputs control a multiplexer.
23 */
24 static Bool
AlpI2CSwitchToBus(I2CBusPtr b)25 AlpI2CSwitchToBus(I2CBusPtr b)
26 {
27 CirPtr pCir = ((CirPtr)b->DriverPrivate.ptr);
28 vgaHWPtr hwp = VGAHWPTR(pCir->pScrn);
29 CARD8 reg = hwp->readGr(hwp, 0x17);
30 if (b == pCir->I2CPtr1) {
31 if ((reg & 0x60) == 0)
32 return TRUE;
33 reg &= ~0x60;
34 }
35 else if(b == pCir->I2CPtr2) {
36 if ((reg & 0x60) != 0)
37 return TRUE;
38 reg |= 0x60;
39 } else return FALSE;
40
41 /* ErrorF("AlpI2CSwitchToBus: \"%s\"\n", b->BusName); */
42 hwp->writeGr(hwp, 0x17, reg);
43 return TRUE;
44 }
45
46 static void
AlpI2CPutBits(I2CBusPtr b,int clock,int data)47 AlpI2CPutBits(I2CBusPtr b, int clock, int data)
48 {
49 unsigned int reg = 0xfc;
50 CirPtr pCir = ((CirPtr)b->DriverPrivate.ptr);
51 vgaHWPtr hwp = VGAHWPTR(pCir->pScrn);
52
53 if (!AlpI2CSwitchToBus(b))
54 return;
55
56 if (clock) reg |= 1;
57 if (data) reg |= 2;
58 hwp->writeSeq(hwp, 0x08, reg);
59 /* ErrorF("AlpI2CPutBits: %d %d\n", clock, data); */
60 }
61
62 static void
AlpI2CGetBits(I2CBusPtr b,int * clock,int * data)63 AlpI2CGetBits(I2CBusPtr b, int *clock, int *data)
64 {
65 unsigned int reg;
66 CirPtr pCir = ((CirPtr)b->DriverPrivate.ptr);
67 vgaHWPtr hwp = VGAHWPTR(pCir->pScrn);
68
69 if (!AlpI2CSwitchToBus(b))
70 return;
71
72 reg = hwp->readSeq(hwp, 0x08);
73 *clock = (reg & 0x04) != 0;
74 *data = (reg & 0x80) != 0;
75 /* ErrorF("AlpI2CGetBits: %d %d\n", *clock, *data); */
76 }
77
78 Bool
AlpI2CInit(ScrnInfoPtr pScrn)79 AlpI2CInit(ScrnInfoPtr pScrn)
80 {
81 CirPtr pCir = CIRPTR(pScrn);
82 I2CBusPtr I2CPtr;
83
84 #ifdef ALP_DEBUG
85 ErrorF("AlpI2CInit\n");
86 #endif
87
88 switch(pCir->Chipset) {
89 case PCI_CHIP_GD5446:
90 case PCI_CHIP_GD5480:
91 break;
92 default:
93 return FALSE;
94 }
95
96
97 I2CPtr = xf86CreateI2CBusRec();
98 if (!I2CPtr) return FALSE;
99
100 pCir->I2CPtr1 = I2CPtr;
101
102 I2CPtr->BusName = "I2C bus 1";
103 I2CPtr->scrnIndex = pScrn->scrnIndex;
104 I2CPtr->I2CPutBits = AlpI2CPutBits;
105 I2CPtr->I2CGetBits = AlpI2CGetBits;
106 I2CPtr->DriverPrivate.ptr = pCir;
107
108 if (!xf86I2CBusInit(I2CPtr))
109 return FALSE;
110
111 I2CPtr = xf86CreateI2CBusRec();
112 if (!I2CPtr) return FALSE;
113
114 pCir->I2CPtr2 = I2CPtr;
115
116 I2CPtr->BusName = "I2C bus 2";
117 I2CPtr->scrnIndex = pScrn->scrnIndex;
118 I2CPtr->I2CPutBits = AlpI2CPutBits;
119 I2CPtr->I2CGetBits = AlpI2CGetBits;
120 I2CPtr->DriverPrivate.ptr = pCir;
121
122 if (!xf86I2CBusInit(I2CPtr))
123 return FALSE;
124
125 return TRUE;
126 }
127