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