1c06b6b69Smrg
2c06b6b69Smrg#ifdef HAVE_CONFIG_H
3c06b6b69Smrg#include "config.h"
4c06b6b69Smrg#endif
5c06b6b69Smrg
6c06b6b69Smrg/* All drivers should typically include these */
7c06b6b69Smrg#include "xf86.h"
8c06b6b69Smrg#include "xf86_OSproc.h"
9c06b6b69Smrg
10c06b6b69Smrg/* Everything using inb/outb, etc needs "compiler.h" */
11c06b6b69Smrg#include "compiler.h"
12c06b6b69Smrg
13c06b6b69Smrg/* Drivers that need to access the PCI config space directly need this */
14c06b6b69Smrg#include "xf86Pci.h"
15c06b6b69Smrg
16c06b6b69Smrg#include "ct_driver.h"
17c06b6b69Smrg
18c06b6b69Smrgstatic Bool chips_TestI2C(int scrnIndex);
19c06b6b69Smrgstatic Bool chips_setI2CBits(I2CBusPtr I2CPtr, ScrnInfoPtr pScrn);
20c06b6b69Smrg
21c06b6b69Smrgstatic unsigned int
22c06b6b69Smrgchips_ddc1Read(ScrnInfoPtr pScrn)
23c06b6b69Smrg{
24c06b6b69Smrg    unsigned char ddc_mask = ((CHIPSPtr)pScrn->driverPrivate)->ddc_mask;
25c06b6b69Smrg    CHIPSPtr cPtr = CHIPSPTR(pScrn);
26c06b6b69Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
27c06b6b69Smrg
28c06b6b69Smrg    register unsigned int tmp;
29c06b6b69Smrg
30c06b6b69Smrg    while ((hwp->readST01(hwp)) & 0x08){};
313699b6c4Smrg    while (!((hwp->readST01(hwp)) & 0x08)){};
32c06b6b69Smrg    tmp = cPtr->readXR(cPtr, 0x63);
33c06b6b69Smrg    return (tmp & ddc_mask);
34c06b6b69Smrg}
35c06b6b69Smrg
367a5ec427Smrgstatic void
377a5ec427Smrgchips_ddc1SetSpeed(ScrnInfoPtr pScrn, xf86ddcSpeed speed)
387a5ec427Smrg{
397a5ec427Smrg    vgaHWddc1SetSpeed(pScrn, speed);
407a5ec427Smrg}
417a5ec427Smrg
42c06b6b69Smrgvoid
43c06b6b69Smrgchips_ddc1(ScrnInfoPtr pScrn)
44c06b6b69Smrg{
45c06b6b69Smrg    unsigned char FR0B, FR0C, XR62;
46c06b6b69Smrg    unsigned char mask_c = 0x00;
47c06b6b69Smrg    unsigned char val, tmp_val = 0;
48c06b6b69Smrg    int i;
49c06b6b69Smrg    CHIPSPtr cPtr = CHIPSPTR(pScrn);
50c06b6b69Smrg
51c06b6b69Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Probing for DDC1\n");
52c06b6b69Smrg
53c06b6b69Smrg    FR0C = cPtr->readFR(cPtr, 0x0C);
54c06b6b69Smrg    XR62 = cPtr->readXR(cPtr, 0x62);
55c06b6b69Smrg    switch (cPtr->Chipset) {
56c06b6b69Smrg    case CHIPS_CT65550:
57c06b6b69Smrg	cPtr->ddc_mask = 0x1F;         /* GPIO 0-4 */
58c06b6b69Smrg	FR0B = cPtr->readFR(cPtr, 0x0B);
59c06b6b69Smrg	if (!(FR0B & 0x10))      /* GPIO 2 is used as 32 kHz input */
60c06b6b69Smrg	    cPtr->ddc_mask &= 0xFB;
61c06b6b69Smrg	if (cPtr->Bus == ChipsVLB) /* GPIO 3-7 are used as address bits */
62c06b6b69Smrg	    cPtr->ddc_mask &= 0x07;
63c06b6b69Smrg	break;
64c06b6b69Smrg    case CHIPS_CT65554:
65c06b6b69Smrg    case CHIPS_CT65555:
66c06b6b69Smrg    case CHIPS_CT68554:
67c06b6b69Smrg	cPtr->ddc_mask = 0x0F;        /* GPIO 0-3 */
68c06b6b69Smrg	break;
69c06b6b69Smrg    case CHIPS_CT69000:
70c06b6b69Smrg    case CHIPS_CT69030:
71c06b6b69Smrg	cPtr->ddc_mask = 0x9F;        /* GPIO 0-4,7? */
72c06b6b69Smrg	break;
73c06b6b69Smrg    default:
74c06b6b69Smrg	cPtr->ddc_mask = 0x0C;       /* GPIO 2,3 */
75c06b6b69Smrg	break;
76c06b6b69Smrg    }
77c06b6b69Smrg    if (!(FR0C & 0x80)) {       /* GPIO 1 is not available */
78c06b6b69Smrg	mask_c |= 0xC0;
79c06b6b69Smrg	cPtr->ddc_mask &= 0xFE;
80c06b6b69Smrg    }
81c06b6b69Smrg    if (!(FR0C & 0x10)) {       /* GPIO 0 is not available */
82c06b6b69Smrg	mask_c |= 0x18;
83c06b6b69Smrg	cPtr->ddc_mask &= 0xFD;
84c06b6b69Smrg    }
85c06b6b69Smrg
86c06b6b69Smrg    /* set GPIO 0,1 to read if available */
87c06b6b69Smrg    cPtr->writeFR(cPtr, 0x0C, (FR0C & mask_c) | (~mask_c & 0x90));
88c06b6b69Smrg    /* set remaining GPIO to read */
89c06b6b69Smrg    cPtr->writeXR(cPtr, 0x62, 0x00);
90c06b6b69Smrg
91c06b6b69Smrg    val = chips_ddc1Read(pScrn);
92c06b6b69Smrg    for (i = 0; i < 70; i++) {
93c06b6b69Smrg	tmp_val = chips_ddc1Read(pScrn);
94c06b6b69Smrg	if (tmp_val != val)
95c06b6b69Smrg	    break;
96c06b6b69Smrg    }
97c06b6b69Smrg    cPtr->ddc_mask = val ^ tmp_val;
98c06b6b69Smrg    if (cPtr->ddc_mask)
99c06b6b69Smrg	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DDC1 found\n");
100c06b6b69Smrg    else return;
101c06b6b69Smrg
1027a5ec427Smrg    xf86PrintEDID(xf86DoEDID_DDC1(XF86_SCRN_ARG(pScrn), chips_ddc1SetSpeed,
103c06b6b69Smrg				  chips_ddc1Read));
104c06b6b69Smrg
105c06b6b69Smrg    /* restore */
106c06b6b69Smrg    cPtr->writeFR(cPtr, 0x0C, FR0C);
107c06b6b69Smrg    cPtr->writeXR(cPtr, 0x62, XR62);
108c06b6b69Smrg}
109c06b6b69Smrg
110c06b6b69Smrgstatic void
111c06b6b69Smrgchips_I2CGetBits(I2CBusPtr b, int *clock, int *data)
112c06b6b69Smrg{
113c06b6b69Smrg    CHIPSI2CPtr pI2C_c = (CHIPSI2CPtr) (b->DriverPrivate.ptr);
114c06b6b69Smrg    unsigned char FR0C, XR62, val;
115c06b6b69Smrg
116c06b6b69Smrg    FR0C = pI2C_c->cPtr->readFR(pI2C_c->cPtr, 0x0C);
117c06b6b69Smrg    if (pI2C_c->i2cDataBit & 0x01 || pI2C_c->i2cClockBit & 0x01)
118c06b6b69Smrg	FR0C = (FR0C & 0xE7) | 0x10;
119c06b6b69Smrg    if (pI2C_c->i2cDataBit & 0x02 || pI2C_c->i2cClockBit & 0x02)
120c06b6b69Smrg	FR0C = (FR0C & 0x3F) | 0x80;
121c06b6b69Smrg    XR62 = pI2C_c->cPtr->readXR(pI2C_c->cPtr, 0x62);
122c06b6b69Smrg    XR62 &= (~pI2C_c->i2cDataBit) & (~pI2C_c->i2cClockBit);
123c06b6b69Smrg    pI2C_c->cPtr->writeFR(pI2C_c->cPtr, 0x0C, FR0C);
124c06b6b69Smrg    pI2C_c->cPtr->writeXR(pI2C_c->cPtr, 0x62, XR62);
125c06b6b69Smrg    val = pI2C_c->cPtr->readXR(pI2C_c->cPtr, 0x63);
126c06b6b69Smrg    *clock = (val & pI2C_c->i2cClockBit) != 0;
127c06b6b69Smrg    *data  = (val & pI2C_c->i2cDataBit) != 0;
128c06b6b69Smrg}
129c06b6b69Smrg
130c06b6b69Smrgstatic void
131c06b6b69Smrgchips_I2CPutBits(I2CBusPtr b, int clock, int data)
132c06b6b69Smrg{
133c06b6b69Smrg    CHIPSI2CPtr pI2C_c = (CHIPSI2CPtr) (b->DriverPrivate.ptr);
134c06b6b69Smrg    unsigned char FR0C, XR62, val;
135c06b6b69Smrg
136c06b6b69Smrg    FR0C = pI2C_c->cPtr->readFR(pI2C_c->cPtr, 0x0C);
137c06b6b69Smrg    if (((pI2C_c->i2cDataBit & 0x01) && data)
138c06b6b69Smrg	|| ((pI2C_c->i2cClockBit & 0x01) && clock))
139c06b6b69Smrg	FR0C |=  0x18;
140c06b6b69Smrg    else if ((pI2C_c->i2cDataBit & 0x01)
141c06b6b69Smrg	|| (pI2C_c->i2cClockBit & 0x01))
142c06b6b69Smrg	FR0C |=  0x10;
143c06b6b69Smrg    if (((pI2C_c->i2cDataBit & 0x02) && data)
144c06b6b69Smrg	|| ((pI2C_c->i2cClockBit & 0x02) && clock))
145c06b6b69Smrg	FR0C |=  0xC0;
146c06b6b69Smrg    else if ((pI2C_c->i2cDataBit & 0x02)
147c06b6b69Smrg	     || (pI2C_c->i2cClockBit & 0x02))
148c06b6b69Smrg	FR0C |=  0x80;
149c06b6b69Smrg    XR62 = pI2C_c->cPtr->readXR(pI2C_c->cPtr, 0x62);
150c06b6b69Smrg    XR62 = (XR62 & ~pI2C_c->i2cClockBit) | (clock ? pI2C_c->i2cClockBit : 0);
151c06b6b69Smrg    XR62 = (XR62 & ~pI2C_c->i2cDataBit) | (data ? pI2C_c->i2cDataBit : 0);
152c06b6b69Smrg    pI2C_c->cPtr->writeFR(pI2C_c->cPtr, 0x0C, FR0C);
153c06b6b69Smrg    pI2C_c->cPtr->writeXR(pI2C_c->cPtr, 0x62, XR62);
154c06b6b69Smrg    val = pI2C_c->cPtr->readXR(pI2C_c->cPtr, 0x63);
155c06b6b69Smrg    val = (val & ~pI2C_c->i2cClockBit) | (clock ? pI2C_c->i2cClockBit : 0);
156c06b6b69Smrg    val = (val & ~pI2C_c->i2cDataBit) | (data ? pI2C_c->i2cDataBit : 0);
157c06b6b69Smrg    pI2C_c->cPtr->writeXR(pI2C_c->cPtr, 0x63, val);
158c06b6b69Smrg}
159c06b6b69Smrg
160c06b6b69Smrg
161c06b6b69SmrgBool
162c06b6b69Smrgchips_i2cInit(ScrnInfoPtr pScrn)
163c06b6b69Smrg{
164c06b6b69Smrg    CHIPSPtr cPtr = CHIPSPTR(pScrn);
165c06b6b69Smrg    I2CBusPtr I2CPtr;
166c06b6b69Smrg
167c06b6b69Smrg    I2CPtr = xf86CreateI2CBusRec();
168c06b6b69Smrg    if(!I2CPtr) return FALSE;
169c06b6b69Smrg
170c06b6b69Smrg    cPtr->I2C = I2CPtr;
171c06b6b69Smrg
172c06b6b69Smrg    I2CPtr->BusName    = "DDC";
173c06b6b69Smrg    I2CPtr->scrnIndex  = pScrn->scrnIndex;
174c06b6b69Smrg    I2CPtr->I2CPutBits = chips_I2CPutBits;
175c06b6b69Smrg    I2CPtr->I2CGetBits = chips_I2CGetBits;
1763699b6c4Smrg    I2CPtr->DriverPrivate.ptr = malloc(sizeof(CHIPSI2CRec));
177c06b6b69Smrg    ((CHIPSI2CPtr)(I2CPtr->DriverPrivate.ptr))->cPtr = cPtr;
178c06b6b69Smrg
179c06b6b69Smrg    if (!xf86I2CBusInit(I2CPtr))
180c06b6b69Smrg	return FALSE;
181c06b6b69Smrg
182c06b6b69Smrg    if (!chips_setI2CBits(I2CPtr, pScrn))
183c06b6b69Smrg	return FALSE;
184c06b6b69Smrg
185c06b6b69Smrg    return TRUE;
186c06b6b69Smrg}
187c06b6b69Smrg
188c06b6b69Smrgstatic Bool
189c06b6b69Smrgchips_setI2CBits(I2CBusPtr b, ScrnInfoPtr pScrn)
190c06b6b69Smrg{
191c06b6b69Smrg    CHIPSPtr cPtr = CHIPSPTR(pScrn);
192c06b6b69Smrg    CHIPSI2CPtr pI2C_c = (CHIPSI2CPtr) (b->DriverPrivate.ptr);
193c06b6b69Smrg    unsigned char FR0B, FR0C;
194c06b6b69Smrg    unsigned char bits, data_bits, clock_bits;
195c06b6b69Smrg    int i,j;
196c06b6b69Smrg
197c06b6b69Smrg    FR0C = cPtr->readFR(cPtr, 0x0C);
198c06b6b69Smrg    switch (cPtr->Chipset) {
199c06b6b69Smrg    case CHIPS_CT65550:
200c06b6b69Smrg	bits = 0x1F;         /* GPIO 0-4 */
201c06b6b69Smrg	FR0B = cPtr->readFR(cPtr, 0x0B);
202c06b6b69Smrg	if (!(FR0B & 0x10))      /* GPIO 2 is used as 32 kHz input */
203c06b6b69Smrg	    bits &= 0xFB;
204c06b6b69Smrg	pI2C_c->i2cDataBit = 0x01;
205c06b6b69Smrg	pI2C_c->i2cClockBit = 0x02;
206c06b6b69Smrg	if (cPtr->Bus == ChipsVLB) /* GPIO 3-7 are used as address bits */
207c06b6b69Smrg	    bits &= 0x07;
208c06b6b69Smrg	break;
209c06b6b69Smrg    case CHIPS_CT65554:
210c06b6b69Smrg    case CHIPS_CT65555:
211c06b6b69Smrg    case CHIPS_CT68554:
212c06b6b69Smrg	bits = 0x0F;        /* GPIO 0-3 */
213c06b6b69Smrg	pI2C_c->i2cDataBit = 0x04;
214c06b6b69Smrg	pI2C_c->i2cClockBit = 0x08;
215c06b6b69Smrg	break;
216c06b6b69Smrg    case CHIPS_CT69000:
217c06b6b69Smrg    case CHIPS_CT69030:
218c06b6b69Smrg	bits = 0x9F;        /* GPIO 0-4,7? */
219c06b6b69Smrg	pI2C_c->i2cDataBit = 0x04;
220c06b6b69Smrg	pI2C_c->i2cClockBit = 0x08;
221c06b6b69Smrg	break;
222c06b6b69Smrg    default:
223c06b6b69Smrg	bits = 0x0C;       /* GPIO 2,3 */
224c06b6b69Smrg	pI2C_c->i2cDataBit = 0x04;
225c06b6b69Smrg	pI2C_c->i2cClockBit = 0x08;
226c06b6b69Smrg	break;
227c06b6b69Smrg    }
228c06b6b69Smrg    if (!(FR0C & 0x80)) {       /* GPIO 1 is not available */
229c06b6b69Smrg	bits &= 0xFE;
230c06b6b69Smrg    }
231c06b6b69Smrg    if (!(FR0C & 0x10)) {       /* GPIO 0 is not available */
232c06b6b69Smrg	bits &= 0xFD;
233c06b6b69Smrg    }
234c06b6b69Smrg    pI2C_c->i2cClockBit &= bits;
235c06b6b69Smrg    pI2C_c->i2cDataBit &= bits;
236c06b6b69Smrg    /*
237c06b6b69Smrg     * first we test out the "favorite" GPIO bits ie. the ones suggested
238c06b6b69Smrg     * by the data book; if we don't succeed test all other combinations
239c06b6b69Smrg     * of possible GPIO pins as data/clock lines as the manufacturer might
240c06b6b69Smrg     * have its own ideas.
241c06b6b69Smrg     */
242c06b6b69Smrg    if (chips_TestI2C(pScrn->scrnIndex)) return TRUE;
243c06b6b69Smrg
244c06b6b69Smrg    data_bits = bits;
245c06b6b69Smrg    pI2C_c->i2cDataBit = 0x01;
246c06b6b69Smrg    for (i = 0; i<8; i++) {
247c06b6b69Smrg	if (data_bits & 0x01) {
248c06b6b69Smrg	    clock_bits = bits;
249c06b6b69Smrg	    pI2C_c->i2cClockBit = 0x01;
250c06b6b69Smrg	    for (j = 0; j<8; j++) {
251c06b6b69Smrg		if (clock_bits & 0x01)
252c06b6b69Smrg		    if (chips_TestI2C(pScrn->scrnIndex)) return TRUE;
253c06b6b69Smrg		clock_bits >>= 1;
254c06b6b69Smrg		pI2C_c->i2cClockBit <<= 1;
255c06b6b69Smrg	    }
256c06b6b69Smrg	}
257c06b6b69Smrg	data_bits >>= 1;
258c06b6b69Smrg	pI2C_c->i2cDataBit <<= 1;
259c06b6b69Smrg    }
260c06b6b69Smrg    /*
261c06b6b69Smrg     * We haven't found a valid clock/data line combination - that
262c06b6b69Smrg     * doesn't mean there aren't any. We just haven't received an
263c06b6b69Smrg     * answer from the relevant DDC I2C addresses. We'll have to wait
264c06b6b69Smrg     * and see, if this is too restrictive (eg one wants to use I2C
265c06b6b69Smrg     * for something else than DDC we might have to probe more addresses
266c06b6b69Smrg     * or just fall back to the "favorite" GPIO lines.
267c06b6b69Smrg     */
268c06b6b69Smrg    return FALSE;
269c06b6b69Smrg}
270c06b6b69Smrg
271c06b6b69Smrgstatic Bool
272c06b6b69Smrgchips_TestI2C(int scrnIndex)
273c06b6b69Smrg{
274c06b6b69Smrg    int i;
275c06b6b69Smrg    I2CBusPtr b;
276c06b6b69Smrg
277c06b6b69Smrg    b = xf86I2CFindBus(scrnIndex, "DDC");
278c06b6b69Smrg    if (b == NULL) return FALSE;
279c06b6b69Smrg    else {
280c06b6b69Smrg	for(i = 0xA0; i < 0xA8; i += 2)
281c06b6b69Smrg	    if(xf86I2CProbeAddress(b, i))
282c06b6b69Smrg		return TRUE;
283c06b6b69Smrg    }
284c06b6b69Smrg    return FALSE;
285c06b6b69Smrg}
286c06b6b69Smrg
287c06b6b69Smrg
288